diff --git a/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/SiHitCollectionCnv.h b/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/SiHitCollectionCnv.h
index 36f053cb2db254082f73b48897fa42758a9f36e5..77cfdc51b24bbd43edbf4d319c9966f6b083668f 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/SiHitCollectionCnv.h
+++ b/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/SiHitCollectionCnv.h
@@ -16,10 +16,8 @@
 // Gaudi
 #include "GaudiKernel/MsgStream.h"
 // typedef to the latest persistent version
-//typedef SiHitCollection_p1     SiHitCollection_PERS;
-//typedef SiHitCollectionCnv_p1  SiHitCollectionCnv_PERS;
-typedef SiHitCollection_p2     SiHitCollection_PERS;
-typedef SiHitCollectionCnv_p2  SiHitCollectionCnv_PERS;
+typedef SiHitCollection_p3     SiHitCollection_PERS;
+typedef SiHitCollectionCnv_p3  SiHitCollectionCnv_PERS;
 
 class SiHitCollectionCnv  : public T_AthenaPoolCustomCnv<SiHitCollection, SiHitCollection_PERS > {
   friend class CnvFactory<SiHitCollectionCnv>;
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/TRTUncompressedHitCollectionCnv.h b/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/TRTUncompressedHitCollectionCnv.h
index d8e393186ccd7c00d871d3647e8ba1e05a67e3b0..47405d750d6e9572adcacbbd22b10b1437c7ac58 100755
--- a/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/TRTUncompressedHitCollectionCnv.h
+++ b/InnerDetector/InDetEventCnv/InDetSimEventAthenaPool/src/TRTUncompressedHitCollectionCnv.h
@@ -23,8 +23,10 @@
 //typedef TRT_HitCollectionCnv_p1  TRT_HitCollectionCnv_PERS;
 //typedef TRT_HitCollection_p2     TRT_HitCollection_PERS;
 //typedef TRT_HitCollectionCnv_p2  TRT_HitCollectionCnv_PERS;
-typedef TRT_HitCollection_p3     TRT_HitCollection_PERS;
-typedef TRT_HitCollectionCnv_p3  TRT_HitCollectionCnv_PERS;
+//typedef TRT_HitCollection_p3     TRT_HitCollection_PERS;
+//typedef TRT_HitCollectionCnv_p3  TRT_HitCollectionCnv_PERS;
+typedef TRT_HitCollection_p4     TRT_HitCollection_PERS;
+typedef TRT_HitCollectionCnv_p4  TRT_HitCollectionCnv_PERS;
 
 class TRTUncompressedHitCollectionCnv  : public T_AthenaPoolCustomCnv<TRTUncompressedHitCollection, TRT_HitCollection_PERS > {
   friend class CnvFactory<TRTUncompressedHitCollectionCnv>;
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/CMakeLists.txt b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/CMakeLists.txt
index 4ec1e378fedc53530dd53be0ccbdde53bfede4a7..2fd4f5c476e202374a504b60103e28f731bea51b 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/CMakeLists.txt
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/CMakeLists.txt
@@ -47,6 +47,12 @@ atlas_add_test( SiHitCollectionCnv_p2_test
                 INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
                 LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib GaudiKernel GeneratorObjectsTPCnv InDetSimEvent TestTools StoreGateLib SGtests Identifier InDetSimEventTPCnv )
 
+atlas_add_test( SiHitCollectionCnv_p3_test
+                SOURCES
+                test/SiHitCollectionCnv_p3_test.cxx
+                INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
+                LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib GaudiKernel GeneratorObjectsTPCnv InDetSimEvent TestTools StoreGateLib SGtests Identifier InDetSimEventTPCnv )
+
 atlas_add_test( TRT_HitCnv_p1_test
                 SOURCES
                 test/TRT_HitCnv_p1_test.cxx
@@ -65,3 +71,9 @@ atlas_add_test( TRT_HitCollectionCnv_p3_test
                 INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
                 LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib GaudiKernel GeneratorObjectsTPCnv InDetSimEvent TestTools StoreGateLib SGtests Identifier InDetSimEventTPCnv )
 
+
+atlas_add_test( TRT_HitCollectionCnv_p4_test
+                SOURCES
+                test/TRT_HitCollectionCnv_p4_test.cxx
+                INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
+                LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib GaudiKernel GeneratorObjectsTPCnv InDetSimEvent TestTools StoreGateLib SGtests Identifier InDetSimEventTPCnv )
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/share/SiHitCollectionCnv_p3_test.ref b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/share/SiHitCollectionCnv_p3_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..fe4376f9b7e70f5801e812e27c71878ba71926e3
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/share/SiHitCollectionCnv_p3_test.ref
@@ -0,0 +1,8 @@
+ApplicationMgr       INFO Application Manager Configured successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector"
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+HepMcParticleLink    INFO find_hostkey: Using TruthEvent as McEventCollection key for this job
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/share/TRT_HitCollectionCnv_p4_test.ref b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/share/TRT_HitCollectionCnv_p4_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..8633d8ace9b4883a00f6e29e68937582b9b5e684
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/share/TRT_HitCollectionCnv_p4_test.ref
@@ -0,0 +1,8 @@
+ApplicationMgr       INFO Application Manager Configured successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+HepMcParticleLink    INFO find_hostkey: Using TruthEvent as McEventCollection key for this job 
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p1.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p1.cxx
index 88c7e8f8a79ae6d2cb586e1e92cfe31b75a965cd..a774507874cef45f344b1521bc550a256b585ef7 100755
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p1.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p1.cxx
@@ -11,7 +11,7 @@
 
 
 void
-SiHitCnv_p1::persToTrans(const SiHit_p1* persObj, SiHit* transObj, 
+SiHitCnv_p1::persToTrans(const SiHit_p1* persObj, SiHit* transObj,
 MsgStream &log)
 {
   HepMcParticleLinkCnv_p1 HepMcPLCnv;
@@ -26,14 +26,14 @@ MsgStream &log)
                                                 persObj->m_enZ),
                       persObj->m_energyLoss,
                       persObj->m_meanTime,
-                      link.barcode(),
+                      link,
                       persObj->m_ID
                       );
 }
 
 
 void
-SiHitCnv_p1::transToPers(const SiHit* transObj, SiHit_p1* persObj, 
+SiHitCnv_p1::transToPers(const SiHit* transObj, SiHit_p1* persObj,
 MsgStream &log)
 {
 //     if (log.level() <= MSG::DEBUG) log << MSG::DEBUG << "SiHitCnv_p1::transToPers called " << endmsg;
@@ -52,5 +52,5 @@ MsgStream &log)
    persObj->m_energyLoss  = transObj->energyLoss();
    persObj->m_meanTime    = transObj->meanTime();
    persObj->m_ID          = transObj->identify();
-   HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log);   
+   HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log);
 }
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p2.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p2.cxx
index 4ae7a82cc271d539d25e45c221689fc30cfbd904..cad415780cb19487a043c6f7137b9f12f4ecc2cc 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p2.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCnv_p2.cxx
@@ -25,14 +25,30 @@ SiHitCnv_p2::persToTrans(const SiHit_p2* persObj, SiHit* transObj, MsgStream &lo
                                                 persObj->m_enZ),
                       persObj->m_energyLoss,
                       persObj->m_meanTime,
-                      link.barcode(),
+                      link,
                       persObj->m_ID
                       );
 }
 
 
 void
-SiHitCnv_p2::transToPers(const SiHit*, SiHit_p2*, MsgStream &/*log*/)
+SiHitCnv_p2::transToPers(const SiHit* transObj, SiHit_p2* persObj, MsgStream &log)
 {
-  throw std::runtime_error("SiHitCnv_p2::transToPers is not supported in this release!");
+//     if (log.level() <= MSG::DEBUG) log << MSG::DEBUG << "SiHitCnv_p2::transToPers called " << endmsg;
+   HepMcParticleLinkCnv_p2 HepMcPLCnv;
+
+   HepGeom::Point3D<double> st = transObj->localStartPosition();
+   persObj->m_stX         = st.x();
+   persObj->m_stY         = st.y();
+   persObj->m_stZ         = st.z();
+
+   HepGeom::Point3D<double> en = transObj->localEndPosition();
+   persObj->m_enX         = en.x();
+   persObj->m_enY         = en.y();
+   persObj->m_enZ         = en.z();
+
+   persObj->m_energyLoss  = transObj->energyLoss();
+   persObj->m_meanTime    = transObj->meanTime();
+   persObj->m_ID          = transObj->identify();
+   HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log);
 }
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p2.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p2.cxx
index b6e6c588e555644c793771d287b2a38b6c8f5e51..6469d1be6b15538331f3a6aff428fc325579c1f5 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p2.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p2.cxx
@@ -123,7 +123,7 @@ void SiHitCollectionCnv_p2::transToPers(const SiHitCollection* transCont, SiHitC
       }
     }
 
-    HepGeom::Point3D<double> st = siHit->localStartPosition();    
+    HepGeom::Point3D<double> st = siHit->localStartPosition();
     HepGeom::Point3D<double> en = siHit->localEndPosition();
 
     const double dx = st.x() - lastTransEnd.x();
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p3.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p3.cxx
index 87bc1f3ad9e62540c2b0127452957ad982880f07..1ed44137a468c62bad7c2cd2700b1f0c7d649755 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p3.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/SiHitCollectionCnv_p3.cxx
@@ -6,6 +6,7 @@
 #include "InDetSimEvent/SiHitCollection.h"
 #include "InDetSimEventTPCnv/InDetHits/SiHitCollection_p3.h"
 #include "InDetSimEventTPCnv/InDetHits/SiHitCollectionCnv_p3.h"
+#include "GeneratorObjects/HepMcParticleLink.h"
 
 #include <cmath>
 
@@ -59,9 +60,184 @@ const double SiHitCollectionCnv_p3::m_2bHalfMaximum = pow(2.0, 15.0);
 const int SiHitCollectionCnv_p3::m_2bMaximum = (unsigned short)(-1);
 
 
-void SiHitCollectionCnv_p3::transToPers(const SiHitCollection*, SiHitCollection_p3*, MsgStream &/*log*/)
+void SiHitCollectionCnv_p3::transToPers(const SiHitCollection* transCont, SiHitCollection_p3* persCont, MsgStream &/*log*/)
 {
-  throw std::runtime_error("SiHitCollectionCnv_p3::transToPers is not supported in this release!");
+  // Finds hits belonging to a "string" (in which the end point of one hit is the same as the start point of the next) and
+  // persistifies the end point of each hit plus the start point of the first hit in each string.
+  //
+  // Further compression is achieved by optimising the storage of the position vectors:- start (x,y,z) and (theta,phi) of
+  // first hit are stored as floats, (delta_theta,delta_phi) relative to the fisrst hit are stored as 2 byte numbers and
+  // used to specify the hit direction. All hit lengths are stored as 2 byte numbers.
+  //
+  // Additional savings are achieved by storing the energy loss for each hit as a 2 byte number and only storing the mean
+  // time of the first hit per string.
+  //
+  // See http://indico.cern.ch/getFile.py/access?contribId=11&resId=2&materialId=slides&confId=30893 for more info.
+
+  static const double dRcut = 1.0e-7;
+  static const double dTcut = 1.0;
+
+  const HepMcParticleLink * lastLink=nullptr;
+  int lastId = -1;
+  double stringFirstTheta = 0.0;
+  double stringFirstPhi = 0.0;
+  double lastT = 0.0;
+  double persSumE = 0.0;
+  double transSumE = 0.0;
+  unsigned int idx = 0;
+  unsigned int endBC = 0;
+  unsigned int endId = 0;
+  unsigned int endHit = 0;
+  HepGeom::Point3D<double> lastTransEnd(0.0, 0.0, 0.0);
+  HepGeom::Point3D<double> lastPersEnd(0.0, 0.0, 0.0);
+
+  for (SiHitCollection::const_iterator it = transCont->begin(); it != transCont->end(); ++it) {
+
+    SiHitCollection::const_iterator siHit = it;
+
+
+    if ( !lastLink || (siHit->particleLink() != *lastLink) ) {
+
+      // store barcode once for set of consecutive hits with same barcode
+
+      lastLink = &(siHit->particleLink());
+      persCont->m_barcode.push_back(lastLink->barcode());
+      persCont->m_mcEvtIndex.push_back(lastLink->eventIndex());
+      persCont->m_evtColl.push_back('a');
+
+      if (idx > 0) {
+        persCont->m_nBC.push_back(idx - endBC);
+        endBC = idx;
+      }
+    }
+
+    if ( (int)siHit->identify() != lastId ) {
+
+      // store id once for set of consecutive hits with same barcode
+
+      lastId = siHit->identify();
+      persCont->m_id.push_back(lastId);
+
+      if (idx > 0) {
+        persCont->m_nId.push_back(idx - endId);
+        endId = idx;
+      }
+    }
+
+    HepGeom::Point3D<double> st = siHit->localStartPosition();
+    HepGeom::Point3D<double> en = siHit->localEndPosition();
+
+    const double dx = st.x() - lastTransEnd.x();
+    const double dy = st.y() - lastTransEnd.y();
+    const double dz = st.z() - lastTransEnd.z();
+    const double t = siHit->meanTime();
+
+    const double dRLast = sqrt(dx * dx + dy * dy + dz * dz);  // dR between end of previous hit and start of current one
+    const double dTLast = fabs(t - lastT);
+
+    CLHEP::Hep3Vector direction(0.0, 0.0, 0.0);
+    double theta = 0.0;
+    double phi = 0.0;
+    bool startNewString = false;
+
+    if (dRLast < dRcut && dTLast < dTcut) {
+
+      // hit is part of existing string
+
+      direction = CLHEP::Hep3Vector( en.x() - lastPersEnd.x(), en.y() - lastPersEnd.y(), en.z() - lastPersEnd.z() );
+
+      theta = direction.theta();
+      phi = phicorr( direction.phi() );
+
+      const int dTheta_2b = (int)( (theta - stringFirstTheta) / m_persAngUnit + m_2bHalfMaximum + 0.5 );
+      const int dPhi_2b = (int)( (cycle(phi, stringFirstPhi) - stringFirstPhi) / m_persAngUnit + m_2bHalfMaximum + 0.5 );
+
+      if ( dTheta_2b < m_2bMaximum && dTheta_2b >= 0 && dPhi_2b < m_2bMaximum && dPhi_2b >= 0) {
+        persCont->m_dTheta.push_back(dTheta_2b);
+        persCont->m_dPhi.push_back(dPhi_2b);
+        theta = stringFirstTheta + ( (double)dTheta_2b - m_2bHalfMaximum ) * m_persAngUnit;
+        phi = stringFirstPhi + ( (double)dPhi_2b - m_2bHalfMaximum ) * m_persAngUnit;
+        phi = phicorr(phi);
+      }
+      else {
+        startNewString = true;
+      }
+    }
+
+    if (startNewString || dRLast >= dRcut || dTLast >= dTcut) {
+
+      // begin new hit string
+
+      direction = CLHEP::Hep3Vector( en.x() - st.x(), en.y() - st.y(), en.z() - st.z() );
+
+      theta = direction.theta();
+      phi = phicorr( direction.phi() );
+
+      persCont->m_hit1_meanTime.push_back(t);
+      persCont->m_hit1_x0.push_back(st.x());
+      persCont->m_hit1_y0.push_back(st.y());
+      persCont->m_hit1_z0.push_back(st.z());
+      persCont->m_hit1_theta.push_back(theta);
+      persCont->m_hit1_phi.push_back(phi);
+
+      lastPersEnd = HepGeom::Point3D<double>(st.x(), st.y(), st.z());
+
+      stringFirstTheta = theta;
+      stringFirstPhi = phi;
+
+      if (idx > 0) {
+        persCont->m_nHits.push_back(idx - endHit);
+        endHit = idx;
+      }
+    }
+
+    lastTransEnd = HepGeom::Point3D<double>(en.x(), en.y(), en.z());
+    transSumE += siHit->energyLoss();
+
+    const int eneLoss_2b = (int)((transSumE - persSumE) / m_persEneUnit + 0.5);  // calculated to allow recovery sum over
+                                                                                 // whole hit string to chosen precision
+
+    const int hitLength_2b = (int)(direction.mag() / m_persLenUnit + 0.5);  // calculated to give the correct position to
+                                                                            // the chosen precision, NOT the length of the
+                                                                            // hit (small difference in practice).
+    double eneLoss = 0.0;
+
+    if (eneLoss_2b >= m_2bMaximum) {
+      eneLoss = siHit->energyLoss();
+      persCont->m_hitEne_2b.push_back(m_2bMaximum);
+      persCont->m_hitEne_4b.push_back(eneLoss);
+    }
+    else {
+      eneLoss = eneLoss_2b * m_persEneUnit;
+      persCont->m_hitEne_2b.push_back(eneLoss_2b);
+    }
+
+    double length = 0.0;
+
+    if (hitLength_2b >= m_2bMaximum) {
+      length = direction.mag();
+      persCont->m_hitLength_2b.push_back(m_2bMaximum);
+      persCont->m_hitLength_4b.push_back(direction.mag());
+    }
+    else {
+      length = hitLength_2b * m_persLenUnit;
+      persCont->m_hitLength_2b.push_back(hitLength_2b);
+    }
+
+    CLHEP::Hep3Vector persDir(length, 0.0, 0.0);
+    persDir.setTheta(theta);
+    persDir.setPhi(phi);
+
+    lastPersEnd = (CLHEP::Hep3Vector)lastPersEnd + persDir;
+    persSumE += eneLoss;
+    lastT = t;
+
+    ++idx;
+  }
+
+  persCont->m_nBC.push_back(idx - endBC);
+  persCont->m_nId.push_back(idx - endId);
+  persCont->m_nHits.push_back(idx - endHit);
 }
 
 
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p1.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p1.cxx
index cc375fbef784f282d583dae7117cb19f77063220..7c7356d7e6d00290437eeed3bac59b0c2dbb2af0 100755
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p1.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p1.cxx
@@ -11,47 +11,47 @@
 
 
 void
-TRT_HitCnv_p1::persToTrans(const TRT_Hit_p1* persObj, TRTUncompressedHit* transObj, 
-MsgStream &log)
+TRT_HitCnv_p1::persToTrans(const TRT_Hit_p1* persObj, TRTUncompressedHit* transObj,
+                           MsgStream &log)
 {
   HepMcParticleLinkCnv_p1 HepMcPLCnv;
   HepMcParticleLink link;
-  HepMcPLCnv.persToTrans(&(persObj->m_partLink),&link, log);   
-
-   *transObj = TRTUncompressedHit (persObj-> hitID,
-                                   link.barcode(),
-                                   persObj->particleEncoding,
-                                   persObj->kineticEnergy,
-                                   persObj->energyDeposit,
-                                   persObj->preStepX,
-                                   persObj->preStepY,
-                                   persObj->preStepZ,
-                                   persObj->postStepX,
-                                   persObj->postStepY,
-                                   persObj->postStepZ,
-                                   persObj->globalTime);
+  HepMcPLCnv.persToTrans(&(persObj->m_partLink),&link, log);
+
+  *transObj = TRTUncompressedHit (persObj-> hitID,
+                                  link,
+                                  persObj->particleEncoding,
+                                  persObj->kineticEnergy,
+                                  persObj->energyDeposit,
+                                  persObj->preStepX,
+                                  persObj->preStepY,
+                                  persObj->preStepZ,
+                                  persObj->postStepX,
+                                  persObj->postStepY,
+                                  persObj->postStepZ,
+                                  persObj->globalTime);
 }
 
 
 void
-TRT_HitCnv_p1::transToPers(const TRTUncompressedHit* transObj, TRT_Hit_p1* persObj, 
-MsgStream &log)
+TRT_HitCnv_p1::transToPers(const TRTUncompressedHit* transObj, TRT_Hit_p1* persObj,
+                           MsgStream &log)
 {
-//    if (log.level() <= MSG::DEBUG)  log << MSG::DEBUG << "TRT_HitCnv_p1::transToPers called " << endmsg;
-   HepMcParticleLinkCnv_p1 HepMcPLCnv;
-   persObj->hitID         = transObj-> GetHitID();
-   HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log);   
-   persObj->particleEncoding = transObj->GetParticleEncoding();
-   persObj->kineticEnergy = transObj->GetKineticEnergy();
-   persObj->energyDeposit = transObj->GetEnergyDeposit();
-
-   persObj->preStepX      = transObj->GetPreStepX();
-   persObj->preStepY      = transObj->GetPreStepY();
-   persObj->preStepZ      = transObj->GetPreStepZ();
-
-   persObj->postStepX     = transObj->GetPostStepX();
-   persObj->postStepY     = transObj->GetPostStepY();
-   persObj->postStepZ     = transObj->GetPostStepZ();
-   persObj->globalTime    = transObj->GetGlobalTime();
+  //    if (log.level() <= MSG::DEBUG)  log << MSG::DEBUG << "TRT_HitCnv_p1::transToPers called " << endmsg;
+  HepMcParticleLinkCnv_p1 HepMcPLCnv;
+  persObj->hitID         = transObj-> GetHitID();
+  HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log);
+  persObj->particleEncoding = transObj->GetParticleEncoding();
+  persObj->kineticEnergy = transObj->GetKineticEnergy();
+  persObj->energyDeposit = transObj->GetEnergyDeposit();
+
+  persObj->preStepX      = transObj->GetPreStepX();
+  persObj->preStepY      = transObj->GetPreStepY();
+  persObj->preStepZ      = transObj->GetPreStepZ();
+
+  persObj->postStepX     = transObj->GetPostStepX();
+  persObj->postStepY     = transObj->GetPostStepY();
+  persObj->postStepZ     = transObj->GetPostStepZ();
+  persObj->globalTime    = transObj->GetGlobalTime();
 
 }
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p2.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p2.cxx
index e1b896bc390d57f059c57f948651578af1bb4b42..431d95f20c3d55b6aacdecae5171e22536cee6a0 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p2.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCnv_p2.cxx
@@ -19,7 +19,7 @@ TRT_HitCnv_p2::persToTrans(const TRT_Hit_p2* persObj, TRTUncompressedHit* transO
   HepMcPLCnv.persToTrans(&(persObj->m_partLink),&link, log);
 
   *transObj = TRTUncompressedHit (persObj-> hitID,
-                                  link.barcode(),
+                                  link,
                                   persObj->particleEncoding,
                                   persObj->kineticEnergy,
                                   persObj->energyDeposit,
@@ -34,7 +34,23 @@ TRT_HitCnv_p2::persToTrans(const TRT_Hit_p2* persObj, TRTUncompressedHit* transO
 
 
 void
-TRT_HitCnv_p2::transToPers(const TRTUncompressedHit*, TRT_Hit_p2*, MsgStream &/*log*/)
+TRT_HitCnv_p2::transToPers(const TRTUncompressedHit* transObj, TRT_Hit_p2* persObj,
+                           MsgStream &log)
 {
-  throw std::runtime_error("TRT_HitCnv_p2::transToPers is not supported in this release!");
+  //    if (log.level() <= MSG::DEBUG)  log << MSG::DEBUG << "TRT_HitCnv_p2::transToPers called " << endmsg;
+  HepMcParticleLinkCnv_p2 HepMcPLCnv;
+  persObj->hitID         = transObj-> GetHitID();
+  HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log);
+  persObj->particleEncoding = transObj->GetParticleEncoding();
+  persObj->kineticEnergy = transObj->GetKineticEnergy();
+  persObj->energyDeposit = transObj->GetEnergyDeposit();
+
+  persObj->preStepX      = transObj->GetPreStepX();
+  persObj->preStepY      = transObj->GetPreStepY();
+  persObj->preStepZ      = transObj->GetPreStepZ();
+
+  persObj->postStepX     = transObj->GetPostStepX();
+  persObj->postStepY     = transObj->GetPostStepY();
+  persObj->postStepZ     = transObj->GetPostStepZ();
+  persObj->globalTime    = transObj->GetGlobalTime();
 }
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCollectionCnv_p4.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCollectionCnv_p4.cxx
index 464bd7a101d7d3c541cf255e00077ac950ac64b7..1d5e3a5d5633404ed16fa0894cab8fdf630a7023 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCollectionCnv_p4.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/src/InDetHits/TRT_HitCollectionCnv_p4.cxx
@@ -20,9 +20,262 @@
 #include "StoreGate/StoreGateSvc.h"
 
 // Transient(Geant) to Persistent(Disk)
-void TRT_HitCollectionCnv_p4::transToPers(const TRTUncompressedHitCollection*, TRT_HitCollection_p4*, MsgStream &/*log*/)
+void TRT_HitCollectionCnv_p4::transToPers(const TRTUncompressedHitCollection* transCont, TRT_HitCollection_p4* persCont, MsgStream &log)
 {
-  throw std::runtime_error("TRT_HitCollectionCnv_p4::transToPers is not supported in this release!");
+
+  /*
+    Spring 2009
+    Andrew Beddall - lossy TRT G4hit compression [p3]
+
+    In p1, p2 versions, GEANT hits are persistified on disk as floats.
+    In the p3 version, floats are compressed to "integers"/"short-floats" before persistifying.
+    In the p4 version, HepMcParticleLink_p2 can identify the event index and collection.
+    The saving is about 75%; see http://cern.ch/beddall/TRThitCompression/
+
+    Spring 2008
+    Rob Duxfield - lossless TRT G4hit compression [p2]
+
+    Finds hits belonging to a "string" (in which the end point of one hit is
+    the same as the start point of the next) and persistifies the end point
+    of each hit plus the start point of the first hit in each string.
+  */
+
+  //  The original units from the hit simulation are indicated in comments;
+  //  they are all in CLHEP units except for hitEne which is in keV.
+  //  I sometimes make use of CLHEP scales *CLHEP::mm and *CLHEP::ns (both=1) for clarity (I hope!).
+  //  See also https://twiki.cern.ch/twiki/bin/view/Atlas/TrtSoftware#Production_of_Hits
+
+  static const double dRcut = 1.0e-7*CLHEP::mm;
+  static const double dTcut = 1.0*CLHEP::ns; // redundant?
+
+  //    if (log.level() <= MSG::DEBUG) log << MSG::DEBUG << "In TRT_HitCollectionCnv_p4::transToPers()" << endmsg;
+
+  const HepMcParticleLink * lastLink=NULL;
+  int lastId = -1;
+  double lastT = 0.0*CLHEP::ns;
+  unsigned int idx = 0;
+  unsigned int endBC = 0;
+  unsigned int endId = 0;
+  unsigned int endHit = 0;
+  HepGeom::Point3D<double> lastEnd(0.0, 0.0, 0.0); // mm
+
+  for (TRTUncompressedHitCollection::const_iterator it = transCont->begin(); it != transCont->end(); ++it) {
+
+    TRTUncompressedHitCollection::const_iterator trtHit = it;
+
+    if ( !lastLink || (trtHit->particleLink() != *lastLink)  ||  (idx - endBC > 65500)) {   // max unsigned short =  65535;
+      // store barcode once for set of consecutive hits with same barcode
+      lastLink = &(trtHit->particleLink());
+      persCont->m_barcode.push_back(lastLink->barcode());
+      persCont->m_mcEvtIndex.push_back(lastLink->eventIndex());
+      persCont->m_evtColl.push_back('a');
+
+      if ( idx > 0 ) {
+        persCont->m_nBC.push_back(idx - endBC);
+        endBC = idx;
+      }
+    }
+
+    if ( (int)trtHit->GetParticleEncoding() != lastId || idx - endId >  65500) { // max unsigned short =  65535;
+      // store id once for set of consecutive hits with same id
+      lastId = trtHit->GetParticleEncoding();
+      persCont->m_id.push_back(lastId);
+      if ( idx > 0 ) {
+        persCont->m_nId.push_back(idx - endId);
+        endId = idx;
+      }
+    }
+
+    const HepGeom::Point3D<double> hitStart(trtHit->GetPreStepX(), trtHit->GetPreStepY(), trtHit->GetPreStepZ()); // mm
+
+    const double meanTime = trtHit->GetGlobalTime(); // ns  // Time of flight from the I.P. to the center of the hit.
+    const double dTLast = fabs(meanTime - lastT);      // |d(meantime)| between the previous hit and the current one.
+    const double dRLast = lastEnd.distance(hitStart);  // Distance between end of previous hit and start of current one;
+    // this is zero if the hit is a continuation of the same particle in the same straw.
+
+    // Begin a new string if the current and previous hits are disconnected;
+    // it looks like dTcut is redundant (but not sure about this).
+    if ( dRLast >= dRcut || dTLast >= dTcut ) {
+
+      // if ( dRLast < dRcut) std::cout << "AJBdTLastTriggeredNewString " << dRLast << " " << dTLast << std::endl;
+
+      ////////////////////
+      // new hit string //
+      ////////////////////
+
+      //
+      // Persistify string *strawId* using 24 bits.
+      // Assumes 0 <= strawId <= 16,777,215 (strawId appears to be < 4,000,000)
+      //
+      const unsigned int strawId = trtHit->GetHitID();
+      persCont->m_strawId1b.push_back(  (unsigned char)(strawId % 256) ); //  8 bits
+      persCont->m_strawId2b.push_back( (unsigned short)(strawId / 256) ); // 16 bits
+      if ( strawId>16777215 )
+        log << MSG::WARNING << "TRT_HitCollectionCnv: strawId > 2^24-1 cannot be persistified correctly! " << endmsg;
+
+      //
+      // Persistify string start radius using 1 bit (istartRflag) or 8 bits (startR)
+      // Note that the smallest value of R is the wire radius (0.0155 mm)
+      //
+      // R will be flagged as 2 mm if it is within 0.1 um of the straw wall => max error = 0.1 um,
+      // otherwise compress with 8 bits => max error = 3.9 um (0.078 ns), RMS error = 1.1 um (0.022 ns)
+      //
+      const double startR = sqrt( hitStart.x()*hitStart.x() + hitStart.y()*hitStart.y() ); // mm
+      unsigned short istartRflag;
+      if ( startR > 1.9999*CLHEP::mm ) {
+        istartRflag=1; // persistify as a 1-bit flag
+      }
+      else {
+        istartRflag=0; // compress to 8 bits with a span of 2 mm
+        persCont->m_startR.push_back( (unsigned char)(startR/(2.0*CLHEP::mm)*256.0) );
+      }
+
+      //
+      // Persistify string *startPhi* using 8 bits (min=-pi, max=+pi)
+      // Max. error = 12 mrad (< 24 um, 0.48 ns); RMS error = 7 mrad (< 14 um, 0.28 ns)
+      //
+      const double startPhi = atan2( hitStart.y(), hitStart.x() ); // returns range -pi to +pi rad
+      persCont->m_startPhi.push_back( (unsigned char)( (startPhi+M_PI)/(2.0*M_PI)*256.0 ) );
+
+      //
+      // Persistify *startZ* using a 4 bits (min = -365 mm, max= +365 mm)
+      // Max. error = 25 mm (25e-3/(0.75c) = 0.111 ns * 2 reflect = 0.222 ns)
+      // RMS  error = 14 mm (14e-3/(0.75c) = 0.062 ns * 2 reflect = 0.124 ns)
+      // Also the 1-bit *istartRflag* is packed into this variable.
+      //
+      // Note:
+      // In the digi code we need to allow for something like 22.5 mm outside straw.
+      // Also because we have short straws,
+      // short straws are about < +-180 mm, long straws are about < +-350 mm
+      // The following compressions can give a large "out of straw" value;
+      // *don't* use these: (2.0), 32.0, 128.0, 256.0.
+
+      unsigned char istartZ = (unsigned char)( (hitStart.z()+365.0*CLHEP::mm)/(730.0*CLHEP::mm)*16.0 );
+      istartZ = (istartZ << 1) | istartRflag;
+      persCont->m_startZ.push_back( istartZ );
+
+      if ( idx > 0 ) {
+        persCont->m_nHits.push_back( idx - endHit );
+        endHit = idx;
+      }
+      /*
+      // Validation output
+      std::cout.precision(15);
+      std::cout << "AJBTtoPstrawId "    << strawId      << std::endl;
+      std::cout << "AJBTtoPstartR "     << startR       << std::endl;
+      std::cout << "AJBTtoPstartPhi "   << startPhi     << std::endl;
+      std::cout << "AJBTtoPstartX "     << hitStart.x() << std::endl;
+      std::cout << "AJBTtoPstartY "     << hitStart.y() << std::endl;
+      std::cout << "AJBTtoPstartZ "     << hitStart.z() << std::endl;
+      */
+    } // end of "begin new hit string"
+
+    //////////////////////////
+    // Now for the end hits //
+    //////////////////////////
+
+    const HepGeom::Point3D<double> hitEnd(trtHit->GetPostStepX(), trtHit->GetPostStepY(), trtHit->GetPostStepZ()); // mm
+    const HepGeom::Point3D<double> hitLength = (hitEnd - hitStart);
+
+    //
+    // Here both *kinEne* (kinetic energy of the particle causing the hit) and
+    // *steplength* (g4hit length) are persistified using a 15-bit "short float"
+    // (9 bit unsigned mantissa, 6 bit unsigned exponent).
+    // This stores values in the range 0.51*2^0 = 0.51 to 1.00*2^63 = 9.2e18.
+    // I enforce the limits 1.0 and 9.0e18; see below.
+    // Max relative error = 0.0010, RMS = 0.0004
+    //
+    // Notes:
+    //
+    //  - G4 gives kinEne in MeV; I sometimes see values ~ 1e-7 MeV (100 meV) [float round-off?]
+    //    So I multiply by 1e9 and store in units of meV => range 1.0 meV to 9.0e18 meV (9000 TeV!)
+    //  - About 1 in 10000 hits have steplength ~ 1e-7 mm [float round-off?]
+    //    so again I multiply by 1e9 and store in units of pm => range 1.0 pm to 9.0e18 pm (9000 km)
+    //  - The mantissa has maximum 9 bits, the exponent has maximum 6 bits,
+    //    Note: a rare condition causes an 10-bit mantissa (mantissa=512).
+    //
+    double kinEne = trtHit->GetKineticEnergy()    * 1.0e9;  // nano Mev = meV.
+    double steplength = hitLength.distance() * 1.0e9;  // nano mm  = pm.
+    if ( kinEne     < 1.0 )        kinEne=1.0;         // Keep  the value
+    if ( steplength < 1.0 )    steplength=1.0;         // well within the
+    if ( kinEne     > 9.0e18 )     kinEne=9.0e18;      // range  of   the
+    if ( steplength > 9.0e18 ) steplength=9.0e18;      // short    float.
+    const unsigned int kexponent = (unsigned int)ceil(log10(kinEne)/0.30102999566398);
+    const unsigned int sexponent = (unsigned int)ceil(log10(steplength)/0.30102999566398);
+    const unsigned int kmantissa = (unsigned int)(kinEne/pow(2.0,kexponent)*1024) - 512;
+    const unsigned int smantissa = (unsigned int)(steplength/pow(2.0,sexponent)*1024) - 512;
+    persCont->m_kinEne.push_back(     (kmantissa << 6) | kexponent );
+    persCont->m_steplength.push_back( (smantissa << 6) | sexponent );
+
+    //
+    // Persistify hit end radius using 1 bit (iendRflag) or 8 bits (endR).
+    // Note that the smallest value of R is the wire radius (0.0155 mm)
+    //
+    // R will be flagged as 2 mm if it is within 0.1 um of the straw wall => max error = 0.1 um,
+    // otherwise compress with 8 bits. The errors are as for startR, but can increased greatly
+    // after steplength preservation in PtoT.
+    //
+    const double endR = sqrt( hitEnd.x()*hitEnd.x() + hitEnd.y()*hitEnd.y() ); // mm
+    unsigned short iendRflag;
+    if ( endR > 1.9999*CLHEP::mm ) {
+      iendRflag=1; // persistify as a 1-bit flag
+    }
+    else {
+      iendRflag=0; // compress to 8 bits with a span of 2 mm
+      persCont->m_endR.push_back( (unsigned char)(endR/(2.0*CLHEP::mm)*256.0) );
+    }
+
+    //
+    // Persistify string *endPhi* using 8 bits (min=-pi, max=+pi)
+    // The errors are as for startPhi, but are very different after steplength
+    // preservation in PtoT.
+    //
+    const double endPhi = atan2( hitEnd.y(), hitEnd.x() ); // returns range -pi to +pi rad
+    persCont->m_endPhi.push_back( (unsigned char)( (endPhi+M_PI)/(2.0*M_PI)*256.0 ) );
+
+    //
+    // Persistify hit *meanTime* using 10 bits (min=0.,span=75 ns)
+    // with float overflow for meanTime >= 75ns (the tail of the distribution).
+    // Max. error = 0.037 ns; RMS error = 0.021 ns.
+    // Also the 1-bit *iendRflag* and 1-bit *idZsign* are packed into this variable.
+    //
+    unsigned short idZsign = (hitLength.z()>0.0) ? 1 : 0; // flag the sign of dZ
+    unsigned short imeanTime = ( meanTime < 75.0*CLHEP::ns ) ? (unsigned short)(meanTime/(75.0*CLHEP::ns)*1024.0) : 1023;
+    if ( imeanTime == 1023 ) persCont->m_meanTimeof.push_back( (float)meanTime ); // "overflow flag"
+    imeanTime = (imeanTime << 2) | (idZsign << 1) | iendRflag;
+    persCont->m_meanTime.push_back( imeanTime );
+
+    //
+    // Persistify hit *hitEne* (the energy deposited by the hit in keV) using a float but only for photons
+    // (relatively very few of these). Digitisation does not use hitEne for charged particles.
+    //
+    if ( lastId == 22 ||
+         (int)(abs(lastId)/100000) == 41 ||
+         (int)(abs(lastId)/10000000) == 1
+         ) persCont->m_hitEne.push_back( (float)(trtHit->GetEnergyDeposit()) );  // keV
+
+    lastEnd = hitEnd;
+    lastT = meanTime;
+    ++idx;
+    /*
+    // Validation output
+    std::cout.precision(15);
+    std::cout << "AJBTtoPendR "     << endR                  << std::endl;
+    std::cout << "AJBTtoPendPhi "   << endPhi                << std::endl;
+    std::cout << "AJBTtoPendX "     << hitEnd.x()            << std::endl;
+    std::cout << "AJBTtoPendY "     << hitEnd.y()            << std::endl;
+    std::cout << "AJBTtoPendZ "     << hitEnd.z()            << std::endl;
+    std::cout << "AJBTtoPmeanTime " << meanTime              << std::endl;
+    std::cout << "AJBTtoPkinEne "   << trtHit->GetKineticEnergy() << std::endl;
+    std::cout << "AJBTtoPhitEne "   << trtHit->GetEnergyDeposit() << std::endl;
+    std::cout << "AJBTtoPsteplength " << hitLength.distance() << std::endl;
+    */
+  }
+
+  persCont->m_nBC.push_back(idx - endBC);
+  persCont->m_nId.push_back(idx - endId);
+  persCont->m_nHits.push_back( idx - endHit );
+
 } // transToPers
 
 
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCnv_p1_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCnv_p1_test.cxx
index 92e6c59857a8252ea2fa7adf49d25b106bddb4ae..ec9f652ac9aa6b5fa95530ced7cb4c491e26bad0 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCnv_p1_test.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCnv_p1_test.cxx
@@ -68,7 +68,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   Athena_test::Leakcheck check;
 
   const HepMC::GenParticle *pGenParticle = genPartVector.at(0);
-  HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+  HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
   SiHit trans1 (HepGeom::Point3D<double> (10.5, 11.5, 12.5),
                 HepGeom::Point3D<double> (13.5, 14.5, 15.5),
                 16.5,
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p2_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p2_test.cxx
index a40a88c30cc43536b92c8133c58a5088c3aac868..a76ade72d4e415316ecf86f8a3f3c7889d8bcab2 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p2_test.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p2_test.cxx
@@ -82,7 +82,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   SiHitCollection trans1 ("coll");
   for (int i=0; i < 10; i++) {
     const HepMC::GenParticle* pGenParticle = genPartVector.at(i);
-    HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+    HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
     int o = i*100;
     trans1.Emplace (HepGeom::Point3D<double> (10.5+o, 11.5+o, 12.5+o),
                     HepGeom::Point3D<double> (13.5+o, 14.5+o, 15.5+o),
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p3_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p3_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..018678ed82468ffe0c752b3d595c9786c225890a
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/SiHitCollectionCnv_p3_test.cxx
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file InDetSimEventTPCnv/test/SiHitCollectionCnv_p3_test.cxx
+ * @date Feb, 2018
+ * @brief Tests for SiHitCollectionCnv_p3.
+ */
+
+
+#undef NDEBUG
+#include "InDetSimEventTPCnv/InDetHits/SiHitCollectionCnv_p3.h"
+#include <cassert>
+#include <iostream>
+
+#include "GeneratorObjectsTPCnv/initMcEventCollection.h"
+#include "HepMC/GenParticle.h"
+#include "HepMC/GenEvent.h"
+
+
+void compare (const HepMcParticleLink& p1,
+              const HepMcParticleLink& p2)
+{
+  assert ( p1.isValid() == p2.isValid() );
+  assert ( p1.barcode() == p2.barcode() );
+  assert ( p1.eventIndex() == p2.eventIndex() );
+  assert ( p1.cptr() == p2.cptr() );
+  assert ( p1 == p2 );
+}
+
+void compare (const SiHit& p1,
+              const SiHit& p2)
+{
+  assert (p1.localStartPosition() == p2.localStartPosition());
+  assert (p1.localEndPosition() == p2.localEndPosition());
+  assert (p1.energyLoss() == p2.energyLoss());
+  assert (p1.meanTime() == p2.meanTime());
+  compare(p1.particleLink(), p2.particleLink());
+  assert (p1.particleLink() == p2.particleLink());
+  assert (p1.identify() == p2.identify());
+}
+
+
+void compare (const SiHitCollection& p1,
+              const SiHitCollection& p2)
+{
+  //assert (p1.Name() == p2.Name());
+  assert (p1.size() == p2.size());
+  for (size_t i = 0; i < p1.size(); i++)
+    compare (p1[i], p2[i]);
+}
+
+
+void testit (const SiHitCollection& trans1)
+{
+  MsgStream log (0, "test");
+  SiHitCollectionCnv_p3 cnv;
+  SiHitCollection_p3 pers;
+  cnv.transToPers (&trans1, &pers, log);
+  SiHitCollection trans2;
+  cnv.persToTrans (&pers, &trans2, log);
+
+  compare (trans1, trans2);
+}
+
+
+void test1(std::vector<HepMC::GenParticle*>& genPartVector)
+{
+  std::cout << "test1\n";
+
+  SiHitCollection trans1 ("coll");
+  for (int i=0; i < 10; i++) {
+    const HepMC::GenParticle* pGenParticle = genPartVector.at(i);
+    HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
+    int o = i*100;
+    trans1.Emplace (HepGeom::Point3D<double> (10.5+o, 11.5+o, 12.5+o),
+                    HepGeom::Point3D<double> (13.5+o, 14.5+o, 15.5+o),
+                    16.5+o,
+                    17.5+o,
+                    trkLink,
+                    19+o);
+
+  }
+
+  testit (trans1);
+}
+
+
+int main()
+{
+  ISvcLocator* pSvcLoc = nullptr;
+  std::vector<HepMC::GenParticle*> genPartVector;
+  if (!Athena_test::initMcEventCollection(pSvcLoc, genPartVector)) {
+    std::cerr << "This test can not be run" << std::endl;
+    return 0;
+  }
+
+  test1(genPartVector);
+  return 0;
+}
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCnv_p1_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCnv_p1_test.cxx
index ed12d1912c8e8a3d56e5e3f270a0e4ead9a39e42..51e940d34444397cb6929ebae53482f7d80600c1 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCnv_p1_test.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCnv_p1_test.cxx
@@ -73,7 +73,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   Athena_test::Leakcheck check;
 
   const HepMC::GenParticle *pGenParticle = genPartVector.at(0);
-  HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+  HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
   TRTUncompressedHit trans1 (101, trkLink, pGenParticle->pdg_id(),
                              104.5, 105.5,
                              106.5, 107.5, 108.5,
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p2_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p2_test.cxx
index 887a2dcfb342c74f753c1e6d7ff2380cd657f867..b1d7173bab0c06361a63765825a645f8c68249de 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p2_test.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p2_test.cxx
@@ -88,7 +88,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   for (int i=0; i < 10; i++) {
     int o = i*100;
     const HepMC::GenParticle* pGenParticle = genPartVector.at(0);
-    HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+    HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
     trans1.Emplace (101+o, trkLink, pGenParticle->pdg_id(),
                     104.5+o, 105.5+o,
                     (106.5+o)/1000, (107.5+o)/1000, 108.5+o,
@@ -97,7 +97,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   }
   // Special case for photons
   const HepMC::GenParticle* pGenParticle = genPartVector.at(10);
-  HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+  HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
   trans1.Emplace (131, trkLink, 22,
                   134.5, 135.5,
                   10, 3, 138.5,
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p3_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p3_test.cxx
index 5319e538c7ef0ca14b371fd9ca034ffa647f4f72..07a7fc570dfb146b15e1c889daa953beb061bf25 100644
--- a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p3_test.cxx
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p3_test.cxx
@@ -108,7 +108,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   for (int i=0; i < 10; i++) {
     int o = i*100;
     const HepMC::GenParticle* pGenParticle = genPartVector.at(0);
-    HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+    HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
     trans1.Emplace (101+o, trkLink, 20+o,
                     104.5+o, 105.5+o,
                     (106.5+o)/1000, (107.5+o)/1000, 108.5+o,
@@ -117,7 +117,7 @@ void test1(std::vector<HepMC::GenParticle*>& genPartVector)
   }
   // Special case for photons
   const HepMC::GenParticle* pGenParticle = genPartVector.at(10);
-  HepMcParticleLink trkLink(pGenParticle->barcode(),0);
+  HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
   trans1.Emplace (131, trkLink, 22,
                   134.5, 135.5,
                   10, 3, 138.5,
diff --git a/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p4_test.cxx b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p4_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..df80d0fbb8e533ef0989dacbdee8ad4250be3b9e
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p4_test.cxx
@@ -0,0 +1,134 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file InDetSimEventTPCnv/test/TRT_HitCollectionCnv_p4_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Feb, 2016
+ * @brief Tests for TRT_HitCollectionCnv_p4.
+ */
+
+
+#undef NDEBUG
+#include "InDetSimEventTPCnv/InDetHits/TRT_HitCollectionCnv_p4.h"
+#include "TestTools/FLOATassert.h"
+#include <cassert>
+#include <iostream>
+#include <cmath>
+
+#include "GeneratorObjectsTPCnv/initMcEventCollection.h"
+#include "HepMC/GenParticle.h"
+#include "HepMC/GenEvent.h"
+
+using Athena_test::isEqual;
+using std::atan2;
+
+
+void compare (const HepMcParticleLink& p1,
+              const HepMcParticleLink& p2)
+{
+  assert ( p1.isValid() == p2.isValid() );
+  assert ( p1.barcode() == p2.barcode() );
+  assert ( p1.eventIndex() == p2.eventIndex() );
+  assert ( p1.cptr() == p2.cptr() );
+  assert ( p1 == p2 );
+}
+
+void compare (const TRTUncompressedHit& p1,
+              const TRTUncompressedHit& p2)
+{
+  assert (p1.GetHitID() == p2.GetHitID());
+  compare(p1.particleLink(), p2.particleLink());
+  assert (p1.particleLink() == p2.particleLink());
+  assert (p1.GetParticleEncoding() == p2.GetParticleEncoding());
+  assert (isEqual (p1.GetKineticEnergy(), p2.GetKineticEnergy(), 5e-4));
+  if (p1.GetParticleEncoding() == 22)
+    assert (p1.GetEnergyDeposit() == p2.GetEnergyDeposit());
+  else
+    assert (0 == p2.GetEnergyDeposit());
+  if (p1.GetPreStepX() > 2) {
+    const double phi1 = atan2 (p1.GetPreStepY(), p1.GetPreStepX());
+    assert (isEqual (2*cos(phi1), p2.GetPreStepX(), 1e-2));
+    assert (isEqual (2*sin(phi1), p2.GetPreStepY(), 2e-2));
+
+    const double phi2 = atan2 (p1.GetPostStepY(), p1.GetPostStepX());
+    assert (isEqual (2*cos(phi2), p2.GetPostStepX(), 2e-2));
+    assert (isEqual (2*sin(phi2), p2.GetPostStepY(), 1e-2));
+  }
+  else {
+    assert (isEqual (p1.GetPreStepX(), p2.GetPreStepX(), 1e-2));
+    assert (isEqual (p1.GetPreStepY(), p2.GetPreStepY(), 1e-2));
+    assert (isEqual (p1.GetPostStepX(), p2.GetPostStepX(), 2e-2));
+    assert (isEqual (p1.GetPostStepY(), p2.GetPostStepY(), 2e-2));
+  }
+  assert (isEqual (p1.GetPreStepZ(), p2.GetPreStepZ(), 0.1));
+  assert (isEqual (p1.GetPostStepZ(), p2.GetPostStepZ(), 0.1));
+  assert (p1.GetGlobalTime() == p2.GetGlobalTime());
+}
+
+
+void compare (const TRTUncompressedHitCollection& p1,
+              const TRTUncompressedHitCollection& p2)
+{
+  //assert (p1.Name() == p2.Name());
+  assert (p1.size() == p2.size());
+  for (size_t i = 0; i < p1.size(); i++)
+    compare (p1[i], p2[i]);
+}
+
+
+void testit (const TRTUncompressedHitCollection& trans1)
+{
+  MsgStream log (0, "test");
+  TRT_HitCollectionCnv_p4 cnv;
+  TRT_HitCollection_p4 pers;
+  cnv.transToPers (&trans1, &pers, log);
+  TRTUncompressedHitCollection trans2;
+  cnv.persToTrans (&pers, &trans2, log);
+
+  compare (trans1, trans2);
+}
+
+
+void test1(std::vector<HepMC::GenParticle*>& genPartVector)
+{
+  std::cout << "test1\n";
+
+  TRTUncompressedHitCollection trans1 ("coll");
+  for (int i=0; i < 10; i++) {
+    int o = i*100;
+    const HepMC::GenParticle* pGenParticle = genPartVector.at(0);
+    HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
+    trans1.Emplace (101+o, trkLink, 20+o,
+                    104.5+o, 105.5+o,
+                    (106.5+o)/1000, (107.5+o)/1000, 108.5+o,
+                    (109.5+o)/1000, (110.5+o)/1000, 111.5+o,
+                    112.5+o);
+  }
+  // Special case for photons
+  const HepMC::GenParticle* pGenParticle = genPartVector.at(10);
+  HepMcParticleLink trkLink(pGenParticle->barcode(),pGenParticle->parent_event()->event_number());
+  trans1.Emplace (131, trkLink, 22,
+                  134.5, 135.5,
+                  10, 3, 138.5,
+                  3, 10, 148.5,
+                  142.5);
+
+  testit (trans1);
+}
+
+
+int main()
+{
+  ISvcLocator* pSvcLoc = nullptr;
+  std::vector<HepMC::GenParticle*> genPartVector;
+  if (!Athena_test::initMcEventCollection(pSvcLoc, genPartVector)) {
+    std::cerr << "This test can not be run" << std::endl;
+    return 0;
+  }
+
+  test1(genPartVector);
+  return 0;
+}