diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/CMakeLists.txt b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5e9de9c0e9090aee90b1aeefac69ce74419034eb
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+# Declare the package name:
+atlas_subdir( InDetSecVtxTruthMatchTool )
+
+# External(s):
+find_package( ROOT COMPONENTS Core RIO Hist MathCore )
+
+atlas_add_library( InDetSecVtxTruthMatchToolLib
+   InDetSecVtxTruthMatchTool/*.h Root/*.h Root/*.cxx
+   PUBLIC_HEADERS InDetSecVtxTruthMatchTool
+   LINK_LIBRARIES PATCoreLib AsgAnalysisInterfaces xAODTracking xAODTruth)
+
+if( NOT XAOD_STANDALONE )
+   atlas_add_component( InDetSecVtxTruthMatchTool
+      src/components/*.cxx
+      LINK_LIBRARIES GaudiKernel AthenaBaseComps xAODTracking xAODTruth
+      InDetSecVtxTruthMatchToolLib)
+endif()
+
+atlas_add_dictionary( InDetSecVtxTruthMatchToolDict
+   InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchToolDict.h
+   InDetSecVtxTruthMatchTool/selection.xml
+   LINK_LIBRARIES InDetSecVtxTruthMatchToolLib )
diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..4633f3803ed1117421017158787e508751d3ba84
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool
\ No newline at end of file
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/IInDetSecVertexTruthMatchTool.h b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/IInDetSecVtxTruthMatchTool.h
similarity index 55%
rename from InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/IInDetSecVertexTruthMatchTool.h
rename to InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/IInDetSecVtxTruthMatchTool.h
index c12297efffd74c3537989950a0d403a83b23a930..eb4c813c22a0f09cd4cea5ff715698626ed049b8 100644
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/IInDetSecVertexTruthMatchTool.h
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/IInDetSecVtxTruthMatchTool.h
@@ -2,8 +2,8 @@
   Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifndef IInDetSecVertexTruthMatchTool_h
-#define IInDetSecVertexTruthMatchTool_h
+#ifndef IInDetSecVtxTruthMatchTool_h
+#define IInDetSecVtxTruthMatchTool_h
 
 // Framework include(s):
 #include "AsgTools/IAsgTool.h"
@@ -19,17 +19,16 @@
  * Categorize reconstructed vertices depending on their composition.
  */
 
-class IInDetSecVertexTruthMatchTool : public virtual asg::IAsgTool {
+class IInDetSecVtxTruthMatchTool : public virtual asg::IAsgTool {
 
-ASG_TOOL_INTERFACE( IInDetSecVertexTruthMatchTool )
+ASG_TOOL_INTERFACE( IInDetSecVtxTruthMatchTool )
 
 public:
 
 //take const collection of vertices, match them, and decorate with matching info
- virtual StatusCode matchVertices( const xAOD::VertexContainer & vtxContainer,
-                                   const xAOD::TruthVertexContainer & truthVtxContainer ) = 0;
-
- virtual StatusCode labelTruthVertices( const xAOD::TruthVertexContainer & truthVtxContainer ) = 0;
+ virtual StatusCode matchVertices(  std::vector<const xAOD::Vertex*> recoVerticesToMatch, 
+                                    std::vector<const xAOD::TruthVertex*> truthVerticesToMatch, 
+                                    const xAOD::TrackParticleContainer* trackParticles ) = 0;
 
 };
 
diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4422b42ed44fb79941686e0bd9aad1dcd0db7e8
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h
@@ -0,0 +1,124 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef InDetSecVtxTruthMatchTool_h
+#define InDetSecVtxTruthMatchTool_h
+
+// Framework include(s):
+#include "AsgTools/AsgTool.h"
+#include "AsgTools/PropertyWrapper.h"
+
+// EDM include(s):
+#include "xAODTracking/VertexContainerFwd.h"
+#include "xAODTruth/TruthParticleFwd.h"
+#include "xAODTruth/TruthVertexFwd.h"
+#include "xAODTruth/TruthVertexContainer.h"
+#include "InDetSecVtxTruthMatchTool/IInDetSecVtxTruthMatchTool.h"
+
+// standard includes
+#include<vector>
+
+namespace InDetSecVtxTruthMatchUtils {
+
+  //Namespace for useful analysis things on the truth matching decorations applied to the VertexContainer
+
+  //How the matching info is stored; link to the truth vertex, a float with its contribution to the relative track weight, and a float with its contribution to the track sumpt2 of the truth vertex
+  typedef std::tuple<ElementLink<xAOD::TruthVertexContainer>, float, float> VertexTruthMatchInfo;
+
+  //type codes for vertex matching on all vertices
+  enum VertexMatchType {
+    Matched=0, // > threshold (default 50%) from one truth interaction
+    Merged,    // not matched
+    Split,     // highest weight truth interaction contributes to >1 vtx (vtx with highest fraction of sumpT2 remains matched/merged)
+    Fake,      // highest contribution is fake (if pile-up MC info not present those tracks end up as "fakes")
+    Other
+  };
+
+  //type codes for truth vertices
+  //NOTE: types are subsets of subsequent types
+  enum TruthVertexMatchType {
+    Reconstructable=0, // fiducial cuts, >= 2 charged daughters
+    Accepted,          // >= 2 reco tracks
+    Seeded,            // tracks pass cuts
+    Reconstructed,     // matched to reco vtx
+    ReconstructedSplit // matched to multiple vtx
+  };
+
+  inline bool isMatched(int matchInfo) {
+    if (matchInfo & (0x1 << Matched)) return true;
+    return false;
+  }
+  inline bool isMerged(int matchInfo) {
+    if (matchInfo & (0x1 << Merged)) return true;
+    return false;
+  }
+  inline bool isSplit(int matchInfo) {
+    if (matchInfo & (0x1 << Split)) return true;
+    return false;
+  }
+  inline bool isFake(int matchInfo) {
+    if (matchInfo & (0x1 << Fake)) return true;
+    return false;
+  }
+  inline bool isOther(int matchInfo) {
+    if (matchInfo & (0x1 << Other)) return true;
+    return false;
+  }
+
+  inline bool isReconstructable(int matchInfo) {
+    if (matchInfo & (0x1 << Reconstructable)) return true;
+    return false;
+  }
+  inline bool isAccepted(int matchInfo) {
+    if (matchInfo & (0x1 << Accepted)) return true;
+    return false;
+  }
+  inline bool isSeeded(int matchInfo) {
+    if (matchInfo & (0x1 << Seeded)) return true;
+    return false;
+  }
+  inline bool isReconstructed(int matchInfo) {
+    if (matchInfo & (0x1 << Reconstructed)) return true;
+    return false;
+  }
+  inline bool isReconstructedSplit(int matchInfo) {
+    if (matchInfo & (0x1 << ReconstructedSplit)) return true;
+    return false;
+  }
+}
+
+/** Class for vertex truth matching.
+ * Match reconstructed vertices to truth level decay vertices
+ * Categorize reconstructed vertices depending on their composition.
+ */
+class InDetSecVtxTruthMatchTool : public virtual IInDetSecVtxTruthMatchTool,
+                                     public asg::AsgTool {
+
+  ASG_TOOL_CLASS( InDetSecVtxTruthMatchTool, IInDetSecVtxTruthMatchTool )
+
+ public:
+
+  InDetSecVtxTruthMatchTool( const std::string & name );
+
+  virtual StatusCode initialize() override final;
+
+  // take collection of vertices, match them, and decorate with matching info
+  virtual StatusCode matchVertices( std::vector<const xAOD::Vertex*> recoVerticesToMatch, std::vector<const xAOD::TruthVertex*> truthVerticesToMatch, const xAOD::TrackParticleContainer* trackParticles ) override;
+
+ private:
+
+  Gaudi::Property<float> m_trkMatchProb{this, "trackMatchProb", 0.5, "Required MC match probability to consider track a good match" };
+  Gaudi::Property<float> m_vxMatchWeight{this, "vertexMatchWeight", 0.5, "Relative weight threshold to consider vertex matched"};
+  Gaudi::Property<float> m_trkPtCut{this, "trackPtCut", 1000., "pt cut to apply on tracks"};
+  Gaudi::Property<std::string> m_selectedTrackFlag{this, "selectedTrackFlag", "is_selected", "Aux decoration on tracks for seeding efficiencies"};
+
+  //private methods to check if particles are good to use
+  //returns barcode of LLP production truth vertex
+  int checkProduction( const xAOD::TruthParticle& truthPart, std::vector<const xAOD::TruthVertex*> truthVerticesToMatch ) const;
+  void countReconstructibleDescendentParticles(const xAOD::TruthVertex& signalTruthVertex,
+                                               std::vector<const xAOD::TruthParticle*>& set, int counter) const;
+  std::vector<int> checkParticle( const xAOD::TruthParticle& part, const xAOD::TrackParticleContainer* tkCont ) const;
+};
+
+#endif
diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchToolDict.h b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchToolDict.h
new file mode 100644
index 0000000000000000000000000000000000000000..69cbdf1a526275ae71d631b1fc84a7432caf420e
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchToolDict.h
@@ -0,0 +1,16 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef INDETSECVTXTRUTHMATCHTOOL_INDETSECVTXTRUTHMATCHTOOLDICT_H
+#define INDETSECVTXTRUTHMATCHTOOL_INDETSECVTXTRUTHMATCHTOOLDICT_H
+
+#if defined(__GCCXML__) and not defined(EIGEN_DONT_VECTORIZE)
+#define EIGEN_DONT_VECTORIZE
+#endif // __GCCXML__
+
+#include "InDetSecVtxTruthMatchTool/IInDetSecVtxTruthMatchTool.h"
+#include "InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h"
+
+#endif // not INDETSECVTXTRUTHMATCHTOOL_INDETSECVTXTRUTHMATCHTOOLDICT_H
+
diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/selection.xml b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/selection.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a78768e094a96dd2bf40707c7d5dc0888fa16822
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool/selection.xml
@@ -0,0 +1,5 @@
+<lcgdict>
+  <class name="IInDetSecVtxTruthMatchTool" />
+  <class name="InDetSecVtxTruthMatchTool" />
+</lcgdict>
+
diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/Root/InDetSecVtxTruthMatchTool.cxx b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/Root/InDetSecVtxTruthMatchTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cac1fa704cfd568f4de3a74c0670a229082c3268
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/Root/InDetSecVtxTruthMatchTool.cxx
@@ -0,0 +1,422 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+#include "InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h"
+
+#include "xAODTracking/TrackParticleContainer.h"
+#include "xAODTruth/TruthEventContainer.h"
+
+using namespace InDetSecVtxTruthMatchUtils;
+
+InDetSecVtxTruthMatchTool::InDetSecVtxTruthMatchTool( const std::string & name ) : asg::AsgTool(name) {}
+
+StatusCode InDetSecVtxTruthMatchTool::initialize() {
+  ATH_MSG_INFO("Initializing InDetSecVtxTruthMatchTool");
+
+
+  return StatusCode::SUCCESS;
+}
+
+namespace {
+//Helper methods for this file only
+
+//In the vector of match info, find the element corresponding to link and return its index; create a new one if necessary
+size_t indexOfMatchInfo( std::vector<VertexTruthMatchInfo> & matches, const ElementLink<xAOD::TruthVertexContainer> & link ) {
+  for ( size_t i = 0; i < matches.size(); ++i ) {
+    if ( link.key() == std::get<0>(matches[i]).key() && link.index() == std::get<0>(matches[i]).index() )
+      return i;
+  }
+  // This is the first time we've seen this truth vertex, so make a new entry
+  matches.emplace_back( link, 0., 0. );
+  return matches.size() - 1;
+}
+
+}
+
+StatusCode InDetSecVtxTruthMatchTool::matchVertices( std::vector<const xAOD::Vertex*> recoVerticesToMatch,
+                                                        std::vector<const xAOD::TruthVertex*> truthVerticesToMatch,
+                                                        const xAOD::TrackParticleContainer* trackParticles) {
+
+  ATH_MSG_DEBUG("Start vertex matching");
+
+  //setup decorators for truth matching info
+  static const xAOD::Vertex::Decorator<std::vector<VertexTruthMatchInfo> > matchInfoDecor("truthVertexMatchingInfos");
+  static const xAOD::Vertex::Decorator<int> recoMatchTypeDecor("vertexMatchType");
+  static const xAOD::Vertex::Decorator<std::vector<ElementLink<xAOD::VertexContainer> > > splitPartnerDecor("splitPartners");
+
+  const xAOD::Vertex::Decorator<float> fakeScoreDecor("fakeScore");
+  const xAOD::Vertex::Decorator<float> otherScoreDecor("otherScore");
+
+  //setup accessors
+  // can switch to built in method in xAOD::Vertex once don't have to deal with changing names anymore
+  xAOD::Vertex::ConstAccessor<xAOD::Vertex::TrackParticleLinks_t> trkAcc("trackParticleLinks");
+  xAOD::Vertex::ConstAccessor<std::vector<float> > weightAcc("trackWeights");
+
+  xAOD::TrackParticle::ConstAccessor<ElementLink<xAOD::TruthParticleContainer> > trk_truthPartAcc("truthParticleLink");
+  xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
+
+  ATH_MSG_DEBUG("Starting Loop on Vertices");
+
+  //=============================================================================
+  //First loop over vertices: get tracks, then TruthParticles, and store relative
+  //weights from each TruthVertex
+  //=============================================================================
+  for ( const xAOD::Vertex* vtx : recoVerticesToMatch ) {
+
+    //create the vector we will add as matching info decoration later
+    std::vector<VertexTruthMatchInfo> matchinfo;
+
+    const xAOD::Vertex::TrackParticleLinks_t & trkParts = trkAcc( *vtx );
+    size_t ntracks = trkParts.size();
+    const std::vector<float> & trkWeights = weightAcc( *vtx );
+
+    //if don't have track particles
+    if (!trkAcc.isAvailable(*vtx) || !weightAcc.isAvailable(*vtx) ) {
+      ATH_MSG_WARNING("trackParticles or trackWeights not available, vertex is missing info");
+      continue;
+    }
+    if ( trkWeights.size() != ntracks ) {
+      ATH_MSG_WARNING("Vertex without same number of tracks and trackWeights, vertex is missing info");
+      continue;
+    }
+
+    ATH_MSG_DEBUG("Matching new vertex at (" << vtx->x() << ", " << vtx->y() << ", " << vtx->z() << ")" << " with " << ntracks << " tracks, at index: " << vtx->index());
+
+    float totalWeight = 0.;
+    float totalPt = 0; 
+    float otherPt = 0;
+    float fakePt = 0;
+
+    //loop over the tracks in the vertex
+    for ( size_t t = 0; t < ntracks; ++t ) {
+
+      ATH_MSG_DEBUG("Checking track number " << t);
+
+      if (!trkParts[t].isValid()) {
+         ATH_MSG_DEBUG("Track " << t << " is bad!");
+         continue;
+      }
+      const xAOD::TrackParticle & trk = **trkParts[t];
+
+      // store the contribution to total weight and pT
+      totalWeight += trkWeights[t];
+      totalPt += trk.pt();
+
+      // get the linked truth particle
+      if (!trk_truthPartAcc.isAvailable(trk)) {
+        ATH_MSG_DEBUG("The truth particle link decoration isn't available.");
+        continue;
+      }  
+      const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc( trk );
+      float prob = trk_truthProbAcc( trk );
+      ATH_MSG_DEBUG("Truth prob: " << prob);
+
+      // check the truth particle origin
+      if (truthPartLink.isValid()  && prob > m_trkMatchProb) {
+        const xAOD::TruthParticle & truthPart = **truthPartLink;
+
+        int barcode =  checkProduction(truthPart, truthVerticesToMatch);
+
+        //check if the truth particle is "good"
+        if ( barcode != -1 ) {
+          //track in vertex is linked to LLP descendant
+          //create link to truth vertex and add to matchInfo
+          auto it = std::find_if(truthVerticesToMatch.begin(), truthVerticesToMatch.end(), 
+            [&](const auto& ele){ return ele->barcode() == barcode;} );
+
+          if(it == truthVerticesToMatch.end()) {
+            ATH_MSG_WARNING("Truth vertex with barcode " << barcode << " not found!");
+          }
+          else {
+            ElementLink<xAOD::TruthVertexContainer> elLink;
+            elLink.setElement(*it); 
+            elLink.setStorableObject( *dynamic_cast<const xAOD::TruthVertexContainer*>( (*it)->container()  ) );
+            size_t matchIdx = indexOfMatchInfo( matchinfo, elLink );
+
+            std::get<1>(matchinfo[matchIdx]) += trkWeights[t];
+            std::get<2>(matchinfo[matchIdx]) += trk.pt();
+          }
+        } else {
+          //truth particle failed cuts
+          ATH_MSG_DEBUG("Truth particle not from LLP decay.");
+          otherPt += trk.pt();
+        }
+      } else {
+        //not valid or low matching probability
+        ATH_MSG_DEBUG("Invalid or low prob truth link!");
+        fakePt += trk.pt();
+      }
+    }//end loop over tracks in vertex
+
+    // normalize by total weight and pT
+    std::for_each( matchinfo.begin(), matchinfo.end(), [&](VertexTruthMatchInfo& link)
+    {
+      std::get<1>(link) /= totalWeight;
+      std::get<2>(link) /= totalPt;
+    });
+
+    float fakeScore = fakePt/totalPt;
+    float otherScore = otherPt/totalPt;
+
+    matchInfoDecor ( *vtx ) = matchinfo;
+    fakeScoreDecor ( *vtx ) = fakeScore;
+    otherScoreDecor( *vtx ) = otherScore;
+  }
+
+  //After first loop, all vertices have been decorated with their vector of match info (link to TruthVertex paired with weight)
+  //now we want to use that information from the whole collection to assign types
+  //keep track of whether a type is assigned
+  //useful since looking for splits involves a double loop, and then setting types ahead in the collection
+  std::vector<bool> assignedType( recoVerticesToMatch.size(), false );
+  static const xAOD::TruthVertex::Decorator<bool> isMatched("matchedToRecoVertex");
+  static const xAOD::TruthVertex::Decorator<bool> isSplit("vertexSplit");
+
+  for ( size_t i = 0; i < recoVerticesToMatch.size(); ++i ) {
+
+    int recoVertexMatchType = 0;
+
+    if ( assignedType[i] ) {
+      ATH_MSG_DEBUG("Vertex already defined as split.");
+      continue; // make sure we don't reclassify vertices already found in the split loop below
+    }
+
+    std::vector<VertexTruthMatchInfo> & info = matchInfoDecor( *recoVerticesToMatch[i] );
+    float fakeScore  = fakeScoreDecor( *recoVerticesToMatch[i] );
+
+    if(fakeScore > m_vxMatchWeight) {
+      ATH_MSG_DEBUG("Vertex is fake.");
+      recoVertexMatchType = recoVertexMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Fake);
+    } else if (info.size() == 1) {
+      if(std::get<2>(info[0]) > m_vxMatchWeight ) { // one truth matched vertex, sufficient weight
+        ATH_MSG_DEBUG("One true decay vertices matched with sufficient weight. Vertex is matched.");
+        recoVertexMatchType = recoVertexMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Matched);
+        isMatched(**std::get<0>(info[0])) = true;
+      }
+      else {
+        ATH_MSG_DEBUG("One true decay vertices matched with insufficient weight. Vertex is other.");
+        recoVertexMatchType = recoVertexMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Other);
+      }
+    } else if (info.size() >= 2 ) {                        // more than one true deacy vertices matched
+      ATH_MSG_DEBUG("Multiple true decay vertices matched. Vertex is merged.");
+      recoVertexMatchType = recoVertexMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Merged);
+      std::for_each( info.begin(), info.end(), [](VertexTruthMatchInfo& link)
+      {
+        isMatched(**std::get<0>(link)) = true;
+      });
+    } else {                                // zero truth matched vertices, but not fake 
+      ATH_MSG_DEBUG("Vertex is neither fake nor LLP. Marking as OTHER.");
+      recoVertexMatchType = recoVertexMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Other);
+    }
+
+    recoMatchTypeDecor(*recoVerticesToMatch[i]) = recoVertexMatchType;
+
+    //check for splitting
+    if ( InDetSecVtxTruthMatchUtils::isMatched(recoMatchTypeDecor(*recoVerticesToMatch[i])) || 
+         InDetSecVtxTruthMatchUtils::isMerged(recoMatchTypeDecor(*recoVerticesToMatch[i])) ) {
+      std::vector<size_t> foundSplits;
+      for ( size_t j = i + 1; j < recoVerticesToMatch.size(); ++j ) {
+        std::vector<VertexTruthMatchInfo> & info2 = matchInfoDecor( *recoVerticesToMatch[j] );
+        //check second vertex is not dummy or fake, and that it has same elementlink as first vertex
+        //equality test is in code but doesnt seem to work for ElementLinks that I have?
+        //so i am just checking that the contianer key hash and the index are the same
+        if (recoMatchTypeDecor( *recoVerticesToMatch[j] ) & (0x1 << InDetSecVtxTruthMatchUtils::Fake)) continue;
+        if (!info2.empty() && std::get<0>(info2[0]).isValid() && std::get<0>(info[0]).key() == std::get<0>(info2[0]).key() && std::get<0>(info[0]).index() == std::get<0>(info2[0]).index() ) {
+          //add split links; first between first one found and newest one
+          ElementLink<xAOD::VertexContainer> splitLink_ij;
+          splitLink_ij.setElement( recoVerticesToMatch[j] ); 
+          splitLink_ij.setStorableObject( *dynamic_cast<const xAOD::VertexContainer*>(recoVerticesToMatch[j]->container()));
+          splitPartnerDecor( *recoVerticesToMatch[i] ).emplace_back(splitLink_ij);
+
+          ElementLink<xAOD::VertexContainer> splitLink_ji;
+          splitLink_ji.setElement( recoVerticesToMatch[i] ); 
+          splitLink_ji.setStorableObject( *dynamic_cast<const xAOD::VertexContainer*>(recoVerticesToMatch[i]->container()));
+          splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_ji);
+
+          //then between any others we found along the way
+          for ( auto k : foundSplits ) { //k is a size_t in the vector of splits
+            ElementLink<xAOD::VertexContainer> splitLink_kj;
+            splitLink_kj.setElement( recoVerticesToMatch[j] ); 
+            splitLink_kj.setStorableObject( *dynamic_cast<const xAOD::VertexContainer*>(recoVerticesToMatch[j]->container()));
+            splitPartnerDecor( *recoVerticesToMatch[k] ).emplace_back(splitLink_kj);
+
+            ElementLink<xAOD::VertexContainer> splitLink_jk;
+            splitLink_jk.setElement( recoVerticesToMatch[k] );
+            splitLink_jk.setStorableObject( *dynamic_cast<const xAOD::VertexContainer*>(recoVerticesToMatch[k]->container()));
+            splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_jk);
+          }
+          //then keep track that we found this one
+          foundSplits.push_back(j);
+          recoMatchTypeDecor( *recoVerticesToMatch[i] ) = recoMatchTypeDecor( *recoVerticesToMatch[i] ) | (0x1 << InDetSecVtxTruthMatchUtils::Split);
+          recoMatchTypeDecor( *recoVerticesToMatch[j] ) = recoMatchTypeDecor( *recoVerticesToMatch[j] ) | (0x1 << InDetSecVtxTruthMatchUtils::Split);
+          isSplit(**std::get<0>(info[0])) = true;
+          assignedType[j] = true;
+        } //if the two vertices match to same TruthVertex
+      }//inner loop over vertices
+    } //if matched or merged
+
+  } //outer loop
+
+  // now label truth vertices
+
+  ATH_MSG_DEBUG("Labeling truth vertices");
+
+  static const xAOD::TruthVertex::Decorator<int> truthMatchTypeDecor("truthVertexMatchType");
+
+  for(const xAOD::TruthVertex* truthVtx : truthVerticesToMatch) {
+
+    std::vector<const xAOD::TruthParticle*> reconstructibleParticles;
+    int counter = 0;
+    countReconstructibleDescendentParticles( *truthVtx, reconstructibleParticles, counter );
+
+    // hacky solution for keeping track of particles in the vertex
+    std::vector<int> particleInfo = {0,0,0};
+    std::vector<int> vertexInfo = {0,0,0};
+
+    for(size_t n = 0; n < reconstructibleParticles.size(); n++){
+      ATH_MSG_DEBUG("Checking daughter no. " << n);
+      const xAOD::TruthParticle* outPart = reconstructibleParticles.at(n);
+      
+      if (trackParticles){
+        particleInfo = checkParticle(*outPart, trackParticles);
+      
+        for(size_t h = 0; h < particleInfo.size(); h++){
+          vertexInfo.at(h) += particleInfo.at(h);
+        }
+      }
+    }
+      
+    int truthMatchType = 0;
+    if( vertexInfo.at(0) > 1 &&  truthVtx->perp() <  320 && abs(truthVtx->z()) < 1500){
+      ATH_MSG_DEBUG("Vertex is reconstructable and in Inner Det region");
+      truthMatchType = truthMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Reconstructable);
+    }
+    if( InDetSecVtxTruthMatchUtils::isReconstructable(truthMatchType) and vertexInfo.at(1) > 1){
+      ATH_MSG_DEBUG("Vertex has at least two tracks");
+      truthMatchType = truthMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Accepted);
+    }
+    if(InDetSecVtxTruthMatchUtils::isAccepted(truthMatchType) and vertexInfo.at(2) > 1){
+      ATH_MSG_DEBUG("Vertex is has at least two tracks passing track selection: " << vertexInfo.at(2));
+      truthMatchType = truthMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Seeded);
+    }
+    if(InDetSecVtxTruthMatchUtils::isSeeded(truthMatchType) and isMatched(*truthVtx)){
+      ATH_MSG_DEBUG("Vertex is matched to a reconstructed secVtx");
+      truthMatchType = truthMatchType | (0x1 << InDetSecVtxTruthMatchUtils::Reconstructed);
+    }
+    if(InDetSecVtxTruthMatchUtils::isSeeded(truthMatchType) and isSplit(*truthVtx)){
+      ATH_MSG_DEBUG("Vertex is matched to multiple secVtx");
+      truthMatchType = truthMatchType | (0x1 << InDetSecVtxTruthMatchUtils::ReconstructedSplit);
+    }
+    truthMatchTypeDecor(*truthVtx) = truthMatchType;
+  }
+  ATH_MSG_DEBUG("Done labeling truth vertices");
+
+  return StatusCode::SUCCESS;
+
+}
+
+std::vector<int> InDetSecVtxTruthMatchTool::checkParticle(const xAOD::TruthParticle &truthPart, const xAOD::TrackParticleContainer* trkCont) const {
+
+  xAOD::TrackParticle::ConstAccessor<char>  trackPass(m_selectedTrackFlag);
+  xAOD::TrackParticle::ConstAccessor<ElementLink<xAOD::TruthParticleContainer> > trk_truthPartAcc("truthParticleLink");
+  xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
+
+  if(truthPart.pt() < m_trkPtCut){
+    ATH_MSG_DEBUG("Insufficient pt to reconstruct the particle");
+    return {0,0,0};
+  }
+  else{
+
+    for(const xAOD::TrackParticle* trkPart : *trkCont){
+      const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc( *trkPart );
+      float matchProb = trk_truthProbAcc( *trkPart );
+
+      if(truthPartLink.isValid() && matchProb > m_trkMatchProb) {
+        const xAOD::TruthParticle& tmpPart = **truthPartLink;
+        if(tmpPart.barcode() == truthPart.barcode()) {
+          if(trackPass.isAvailable( *trkPart )) {
+            if(trackPass( *trkPart )) {
+              ATH_MSG_DEBUG("Particle has a track that passes track selection.");
+              return {1,1,1};
+            } else {
+              ATH_MSG_DEBUG("Particle has a track, but did not pass track selection.");
+              return {1,1,0};
+            }
+          } else {
+            ATH_MSG_DEBUG("Track selection decoration not available, calling the track selected");
+            return {1,1,1};
+          }
+        }
+      }
+    }
+    ATH_MSG_DEBUG("Particle has enough pt.");
+    return {1,0,0};
+    
+  }
+  return {0,0,0};
+}
+
+// check if truth particle originated from decay of particle in the pdgIdList
+int InDetSecVtxTruthMatchTool::checkProduction( const xAOD::TruthParticle & truthPart, std::vector<const xAOD::TruthVertex*> truthVerticesToMatch ) const {
+
+  if (truthPart.nParents() == 0){
+    ATH_MSG_DEBUG("Particle has no parents (end of loop)");
+    return -1;
+  } 
+  else{
+    const xAOD::TruthParticle * parent = truthPart.parent(0);
+    if(not parent) {
+      ATH_MSG_DEBUG("Particle parent is null");
+      return -1;
+    }
+    ATH_MSG_DEBUG("Parent ID: " << parent->pdgId());
+
+    const xAOD::TruthVertex* parentVertex = parent->decayVtx();
+    if(std::find(truthVerticesToMatch.begin(), truthVerticesToMatch.end(), parentVertex) != truthVerticesToMatch.end()) {
+      ATH_MSG_DEBUG("Found LLP decay.");
+      return parentVertex->barcode();
+    }
+    // recurse on parent
+    return checkProduction(*parent, truthVerticesToMatch);
+  }
+  return -1;
+}
+
+void InDetSecVtxTruthMatchTool::countReconstructibleDescendentParticles(const xAOD::TruthVertex& signalTruthVertex,
+                                                                           std::vector<const xAOD::TruthParticle*>& set, int counter) const {
+
+  counter++;
+
+  for( size_t itrk = 0; itrk < signalTruthVertex.nOutgoingParticles(); itrk++) {
+    const auto* particle = signalTruthVertex.outgoingParticle( itrk );
+    if( !particle ) continue;
+    // Recursively add descendents
+    if( particle->hasDecayVtx() ) {
+      
+      TVector3 decayPos( particle->decayVtx()->x(), particle->decayVtx()->y(), particle->decayVtx()->z() );
+      TVector3 prodPos ( particle->prodVtx()->x(),  particle->prodVtx()->y(),  particle->prodVtx()->z()  );
+      
+      auto isInside  = []( TVector3& v ) { return ( v.Perp() < 300. && std::abs( v.z() ) < 1500. ); };
+      auto isOutside = []( TVector3& v ) { return ( v.Perp() > 563. || std::abs( v.z() ) > 2720. ); };
+      
+      const auto distance = (decayPos - prodPos).Mag();
+
+      if (counter > 100) {
+        ATH_MSG_WARNING("Vetoing particle that may be added recursively infinitely (potential loop in generator record");
+        break;
+      }
+      
+      // consider track reconstructible if it travels at least 10mm
+      if( distance < 10.0 ) {
+        countReconstructibleDescendentParticles( *particle->decayVtx(), set , counter);
+      } else if( isInside ( prodPos  )  && isOutside( decayPos )  && particle->isCharged() ) {
+        set.push_back( particle );
+      } else if( particle->isElectron() || particle->isMuon() ) {
+        set.push_back( particle );
+      }
+    } else {
+      if( !(particle->isCharged()) ) continue;
+      set.push_back( particle );
+    }
+  }
+  
+  }
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/Root/LinkDef.h b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/Root/LinkDef.h
similarity index 52%
rename from InnerDetector/InDetValidation/InDetSecVertexValidation/Root/LinkDef.h
rename to InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/Root/LinkDef.h
index 0c34221b64a4f21f9b86b8090546dfd31f69d83d..7aac8d43f6a4ce79011eb00ee5ef3ac4e0a1a695 100644
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/Root/LinkDef.h
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/Root/LinkDef.h
@@ -2,10 +2,10 @@
   Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifndef INDETRUTHSECVERTEXVALIDATION_LINKDEF_H
-#define INDETRUTHSECVERTEXVALIDATION_LINKDEF_H
+#ifndef INDETRUTHSECVTXTRUTHMATCHTOOL_LINKDEF_H
+#define INDETRUTHSECVTXTRUTHMATCHTOOL_LINKDEF_H
 
-#include "InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h"
+#include "InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h"
 
 #ifdef __CINT__
 
@@ -14,7 +14,7 @@
 #pragma link off all functions;
 #pragma link C++ nestedclass;
 
-#pragma link C++ class InDetSecVertexTruthMatchTool;
+#pragma link C++ class InDetSecVtxTruthMatchTool;
 
 #endif
 
diff --git a/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/src/components/InDetSecVtxTruthMatchTool_entries.cxx b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/src/components/InDetSecVtxTruthMatchTool_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b7e8fa3992a177ce2e1156fb690562ef608b7a12
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool/src/components/InDetSecVtxTruthMatchTool_entries.cxx
@@ -0,0 +1,11 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Gaudi/Athena include(s):
+//#include "GaudiKernel/DeclareFactoryEntries.h"
+
+// Local include(s):
+#include "InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h"
+
+DECLARE_COMPONENT( InDetSecVtxTruthMatchTool )
\ No newline at end of file
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/CMakeLists.txt b/InnerDetector/InDetValidation/InDetSecVertexValidation/CMakeLists.txt
index 4c66ee1e5a94fe6ef304642b63def6db115629b8..a8745449ecb0564b9d4bc6ff5368bc8459530640 100644
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/CMakeLists.txt
+++ b/InnerDetector/InDetValidation/InDetSecVertexValidation/CMakeLists.txt
@@ -14,30 +14,11 @@ endif()
 # External dependencies:
 find_package( ROOT COMPONENTS Core Tree Hist RIO )
 
-# Generate a CINT dictionary source file:
-atlas_add_root_dictionary( InDetSecVertexValidationLib _cintDictSource
-   ROOT_HEADERS InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h Root/LinkDef.h
-   EXTERNAL_PACKAGES ROOT )
-
-# Component(s) in the package:
-atlas_add_library( InDetSecVertexValidationLib
-                   Root/*.cxx ${_cintDictSource}
-                   PUBLIC_HEADERS InDetSecVertexValidation
-                   PRIVATE_LINK_LIBRARIES ${extra_libs}
-                   LINK_LIBRARIES AsgTools xAODTracking xAODTruth )
-
 if( NOT XAOD_STANDALONE )
     atlas_add_component( InDetSecVertexValidation
                          src/*.cxx src/*.h
                          src/components/*.cxx
-                         LINK_LIBRARIES ${extra_libs} GaudiKernel xAODTracking AthenaBaseComps AsgTools InDetSecVertexValidationLib AthenaMonitoringLib TrkValHistUtils )
-endif()
-
-if( XAOD_STANDALONE )
-    atlas_add_executable( SecVertexTruthMatchTest
-                      util/SecVertexTruthMatchTest.cxx
-                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                      LINK_LIBRARIES InDetSecVertexValidationLib xAODTracking xAODEventInfo xAODRootAccess AthenaMonitoringLib TrkValHistUtils ${ROOT_LIBRARIES} ${extra_libs} )
+                         LINK_LIBRARIES ${extra_libs} GaudiKernel xAODTracking AthenaBaseComps AsgTools AthenaMonitoringLib TrkValHistUtils )
 endif()
 
 atlas_install_python_modules(python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8})
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/ATLAS_CHECK_THREAD_SAFETY
deleted file mode 100644
index c4b6ab6470835418aab6f71fd8e2c2a842cef9e8..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/ATLAS_CHECK_THREAD_SAFETY
+++ /dev/null
@@ -1 +0,0 @@
-InnerDetector/InDetValidation/InDetSecVertexValidation
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h b/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h
deleted file mode 100644
index b26bbce5ea206c57ccc3961bde8f3946eebd4c21..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef InDetSecVertexTruthMatchTool_h
-#define InDetSecVertexTruthMatchTool_h
-
-// Framework include(s):
-#include "AsgTools/AsgTool.h"
-#include "GaudiKernel/ITHistSvc.h"
-
-
-
-// EDM include(s):
-#include "xAODTracking/VertexContainerFwd.h"
-#include "xAODTruth/TruthParticleFwd.h"
-#include "xAODTruth/TruthVertexFwd.h"
-#include "xAODTruth/TruthVertexContainer.h"
-#include "InDetSecVertexValidation/IInDetSecVertexTruthMatchTool.h"
-
-// standard includes
-#include<vector>
-#include <TH1.h>
-#include <TH2.h>
-#include <TH3.h>
-
-
-
-namespace InDetSecVertexTruthMatchUtils {
-
-  //Namespace for useful analysis things on the truth matching decorations applied to the VertexContainer
-
-  //How the matching info is stored; link to the truth vertex, a float with its contribution to the relative track weight, and a float with its contribution to the track sumpt2 of the truth vertex
-  typedef std::tuple<ElementLink<xAOD::TruthVertexContainer>, float, float> VertexTruthMatchInfo;
-
-  //type codes for vertex matching on all vertices
-  enum VertexMatchType {
-    MATCHED, // > threshold (default 70%) from one truth interaction
-    MERGED,  // not matched
-    SPLIT,   // highest weight truth interaction contributes to >1 vtx (vtx with highest fraction of sumpT2 remains matched/merged)
-    FAKE,    // highest contribution is fake (if pile-up MC info not present those tracks end up as "fakes")
-    LLP,
-    OTHER,
-    ALL,
-    NTYPES   // access to number of types
-  };
-
-  constexpr std::initializer_list<VertexMatchType> allTypes = { MATCHED, MERGED, SPLIT, FAKE, LLP, OTHER, ALL };
-
-
-  //type codes for truth vertices
-  //NOTE: types are subsets of subsequent types
-  enum TruthVertexMatchType {
-    INCLUSIVE, // all vertices
-    RECONSTRUCTABLE, // fiducial cuts, >= 2 charged daughters
-    ACCEPTED, // >= 2 reco tracks
-    SEEDED, // tracks pass cuts
-    RECONSTRUCTED, // matched to reco vtx
-    RECONSTRUCTEDSPLIT, // matched to multiple vtx
-  };
-
-}
-
-/** Class for vertex truth matching.
- * Match reconstructed vertices to truth level decay vertices
- * Categorize reconstructed vertices depending on their composition.
- */
-class InDetSecVertexTruthMatchTool : public virtual IInDetSecVertexTruthMatchTool,
-                                     public asg::AsgTool {
-
-  ASG_TOOL_CLASS( InDetSecVertexTruthMatchTool, IInDetSecVertexTruthMatchTool )
-
- public:
-
-  InDetSecVertexTruthMatchTool( const std::string & name );
-
-  virtual StatusCode initialize() override final;
-  virtual StatusCode finalize() override;
-
-  //take const collection of vertices, match them, and decorate with matching info
-  virtual StatusCode matchVertices( const xAOD::VertexContainer& vtxContainer, const xAOD::TruthVertexContainer& truthVtxContainer ) override;
-  //take const collection of truth vertices and decorate with type info
-  virtual StatusCode labelTruthVertices( const xAOD::TruthVertexContainer & truthVtxContainer ) override;
-
- private:
-
-  //required MC match probability to consider track a good match
-  float m_trkMatchProb;
-  //relative weight threshold to consider vertex matched
-  float m_vxMatchWeight;
-  //pt cut to use on tracks
-  float m_trkPtCut;
-  //comma separated list of pdgids to consider in the matchiing
-  std::string m_pdgIds;
-  //turn on/off histogram output
-  bool m_fillHist;
-  //Augmentation string to add to the end of patterns.
-  std::string m_AugString;
-
-  //private methods to check if particles are good to use
-  //returns barcode of LLP production truth vertex
-  int checkProduction( const xAOD::TruthParticle& truthPart ) const;
-  void countReconstructibleDescendentParticles(const xAOD::TruthVertex& signalTruthVertex,
-                                               std::vector<const xAOD::TruthParticle*>& set, int counter) const;
-  std::vector<int> checkParticle( const xAOD::TruthParticle& part, const xAOD::TrackParticleContainer &tkCont ) const;
-
-  // (optional) write out histograms
-  StatusCode fillRecoPlots( const xAOD::Vertex& secVtx );
-  StatusCode fillTruthPlots( const xAOD::TruthVertex& truthVtx );
-
-  //private internal variables (not properties)
-  std::vector<int> m_pdgIdList;
-
-  //histograms
-  ITHistSvc* m_thistSvc{nullptr};
-  TH1F* m_matchType = nullptr;
-  TH1F* m_truth_Ntrk = nullptr;
-
-  TH1F* m_truthInclusive_r = nullptr;
-  TH1F* m_truthReconstructable_r = nullptr;
-  TH1F* m_truthAccepted_r = nullptr;
-  TH1F* m_truthSeeded_r = nullptr;
-  TH1F* m_truthReconstructed_r = nullptr;
-  TH1F* m_truthSplit_r = nullptr;
-
-  TH1F* m_truthReconstructable_trkSel = nullptr;
-  TH1F* m_truthReconstructed_trkSel = nullptr;
-
-  std::map<std::string,TH1F*> m_positionRes_R;
-  std::map<std::string,TH1F*> m_positionRes_Z;
-  std::map<std::string,TH1F*> m_recoX;
-  std::map<std::string,TH1F*> m_recoY;
-  std::map<std::string,TH1F*> m_recoZ;
-  std::map<std::string,TH1F*> m_recoR;
-  std::map<std::string,TH1F*> m_recodistFromPV;
-  std::map<std::string,TH1F*> m_recoPt;
-  std::map<std::string,TH1F*> m_recoEta;
-  std::map<std::string,TH1F*> m_recoPhi;
-  std::map<std::string,TH1F*> m_recoMass;
-  std::map<std::string,TH1F*> m_recoMu;
-  std::map<std::string,TH1F*> m_recoChi2;
-  std::map<std::string,TH1F*> m_recoDir;
-  std::map<std::string,TH1F*> m_recoCharge;
-  std::map<std::string,TH1F*> m_recoH;
-  std::map<std::string,TH1F*> m_recoHt;
-  std::map<std::string,TH1F*> m_recoMinOpAng;
-  std::map<std::string,TH1F*> m_recoMaxOpAng;
-  std::map<std::string,TH1F*> m_recoMaxDR;
-  std::map<std::string,TH1F*> m_recoMinD0;
-  std::map<std::string,TH1F*> m_recoMaxD0;
-  std::map<std::string,TH1F*> m_recoNtrk;
-
-  std::map<std::string,TH1F*> m_recoTrk_qOverP;
-  std::map<std::string,TH1F*> m_recoTrk_theta; 
-  std::map<std::string,TH1F*> m_recoTrk_E; 
-  std::map<std::string,TH1F*> m_recoTrk_M; 
-  std::map<std::string,TH1F*> m_recoTrk_Pt;  
-  std::map<std::string,TH1F*> m_recoTrk_Px; 
-  std::map<std::string,TH1F*> m_recoTrk_Py; 
-  std::map<std::string,TH1F*> m_recoTrk_Pz;  
-  std::map<std::string,TH1F*> m_recoTrk_Eta; 
-  std::map<std::string,TH1F*> m_recoTrk_Phi;
-  std::map<std::string,TH1F*> m_recoTrk_D0; 
-  std::map<std::string,TH1F*> m_recoTrk_Z0;
-  std::map<std::string,TH1F*> m_recoTrk_errD0; 
-  std::map<std::string,TH1F*> m_recoTrk_errZ0; 
-  std::map<std::string,TH1F*> m_recoTrk_Chi2;
-  std::map<std::string,TH1F*> m_recoTrk_nDoF; 
-  std::map<std::string,TH1F*> m_recoTrk_charge;
-
-  std::map<std::string,TH1F*> m_matchScore_weight;
-  std::map<std::string,TH1F*> m_matchScore_pt;
-  std::map<std::string,TH1F*> m_matchedTruthID;  
-  
-  TH1F* m_truthX = nullptr;  
-  TH1F* m_truthY = nullptr;
-  TH1F* m_truthZ = nullptr;  
-  TH1F* m_truthR = nullptr;
-  TH1F* m_truthdistFromPV = nullptr; 
-  TH1F* m_truthEta = nullptr;  
-  TH1F* m_truthPhi = nullptr; 
-  TH1F* m_truthNtrk_out = nullptr;
-  TH1F* m_truthParent_E = nullptr;
-  TH1F* m_truthParent_M = nullptr; 
-  TH1F* m_truthParent_Pt = nullptr;
-  TH1F* m_truthParent_Eta = nullptr; 
-  TH1F* m_truthParent_Phi = nullptr;
-  TH1F* m_truthParent_charge = nullptr; 
-  TH1F* m_truthParentProdX = nullptr; 
-  TH1F* m_truthParentProdY = nullptr; 
-  TH1F* m_truthParentProdZ = nullptr; 
-  TH1F* m_truthParentProdR = nullptr;
-  TH1F* m_truthParentProddistFromPV = nullptr;
-  TH1F* m_truthParentProdEta = nullptr; 
-  TH1F* m_truthParentProdPhi = nullptr;
-  
-
-};
-
-#endif
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/Root/InDetSecVertexTruthMatchTool.cxx b/InnerDetector/InDetValidation/InDetSecVertexValidation/Root/InDetSecVertexTruthMatchTool.cxx
deleted file mode 100644
index 576c83d92663f240d9402a5f9506bcf8cd32072c..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/Root/InDetSecVertexTruthMatchTool.cxx
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
-  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-*/
-#include "AthenaKernel/Units.h"
-
-#include "InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h"
-
-#include "xAODTracking/TrackParticleContainer.h"
-#include "xAODTruth/TruthEventContainer.h"
-
-using namespace InDetSecVertexTruthMatchUtils;
-using Athena::Units::GeV;
-
-InDetSecVertexTruthMatchTool::InDetSecVertexTruthMatchTool( const std::string & name ) : asg::AsgTool(name) {
-  declareProperty("trackMatchProb", m_trkMatchProb = 0.5 );
-  declareProperty("vertexMatchWeight", m_vxMatchWeight = 0.5 );
-  declareProperty("trackPtCut", m_trkPtCut = 1000. );
-  declareProperty("pdgIds", m_pdgIds = "36" );
-  declareProperty("fillHist", m_fillHist = true );
-  declareProperty("AugString", m_AugString = "" );
-}
-
-StatusCode InDetSecVertexTruthMatchTool::initialize() {
-  ATH_MSG_INFO("Initializing InDetSecVertexTruthMatchTool");
-
-  // build the vector of pdgIds from the input string
-  std::stringstream ss(m_pdgIds);
-  for (int i; ss >> i;) {
-      m_pdgIdList.push_back(i);    
-      if (ss.peek() == ',')
-          ss.ignore();
-  }
-
-  // histograms
-  ATH_CHECK( service("THistSvc",m_thistSvc) );
-
-  ////////////////////////////////////////////
-  ////// Seconvery Vertex Histograms /////////
-  ////////////////////////////////////////////
-  m_matchType                 = new TH1F("reco_matchType","Vertex Match Type",8,-0.5,7.5);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/matchType", m_matchType));
-
-  for(auto type : allTypes) {
-    std::string vertexType = "";
-    switch (type)
-    {
-    case MATCHED:
-      vertexType = "Matched";
-      break;
-    case MERGED:
-      vertexType = "Merged";
-      break;
-    case SPLIT:
-      vertexType = "Split";
-      break;
-    case LLP:
-      vertexType = "LLP";
-      break;
-    case OTHER:
-      vertexType = "Other";
-      break;
-    case FAKE:
-      vertexType = "Fake";
-      break;
-    case ALL:
-      vertexType = "All";
-      break;
-    default:
-      break;
-    }
-
-
-    m_recoX[vertexType]                  = new TH1F(("recoZ" + vertexType).c_str(),"Reco vertex x [mm]",500,0,500); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/X", m_recoX[vertexType]));
-    m_recoY[vertexType]                  = new TH1F(("recoY" + vertexType).c_str(),"Reco vertex y [mm]",500,0,500); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Y", m_recoY[vertexType]));
-    m_recoZ[vertexType]                  = new TH1F(("recoZ" + vertexType).c_str(),"Reco vertex z [mm]",500,0,500); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Z", m_recoZ[vertexType]));
-    m_recoR[vertexType]                  = new TH1F(("recoR" + vertexType).c_str(),"Reco vertex r [mm]",500,0,500); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/R", m_recoR[vertexType]));
-    m_recoPt[vertexType]                 = new TH1F(("recoPt" + vertexType).c_str(),"Reco vertex Pt [GeV]",100,0,100); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Pt", m_recoPt[vertexType]));
-    m_recoEta[vertexType]                = new TH1F(("recoEta" + vertexType).c_str(),"Reco vertex Eta ",100,-5,5); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Eta", m_recoEta[vertexType]));
-    m_recoPhi[vertexType]                = new TH1F(("recoPhi" + vertexType).c_str(),"Reco vertex Phi ",64,-3.2,3.2);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Phi", m_recoPhi[vertexType]));
-    m_recoMass[vertexType]               = new TH1F(("recoMass" + vertexType).c_str(),"Reco vertex Mass [GeV]",500,0,100);
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Mass", m_recoMass[vertexType]));
-    m_recoMu[vertexType]                 = new TH1F(("recoMu" + vertexType).c_str(),"Reco vertex Red. Mass [GeV]",500,0,100); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Mu", m_recoMu[vertexType]));
-    m_recoChi2[vertexType]               = new TH1F(("recoChi2" + vertexType).c_str(),"Reco vertex recoChi2",100,0,10); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Chi2", m_recoChi2[vertexType]));
-    m_recoDir[vertexType]                = new TH1F(("recoDir" + vertexType).c_str(),"Reco vertex recoDirection",100,-1,1);
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Dir", m_recoDir[vertexType]));
-    m_recoCharge[vertexType]             = new TH1F(("recoCharge" + vertexType).c_str(),"Reco vertex recoCharge",20,-10,10);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Charge", m_recoCharge[vertexType]));
-    m_recoH[vertexType]                  = new TH1F(("recoH" + vertexType).c_str(),"Reco vertex H [GeV]",100,0,100); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/H", m_recoH[vertexType]));
-    m_recoHt[vertexType]                 = new TH1F(("recoHt" + vertexType).c_str(),"Reco vertex Mass [GeV]",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Ht", m_recoHt[vertexType]));
-    m_recoMinOpAng[vertexType]           = new TH1F(("recoMinOpAng" + vertexType).c_str(),"Reco vertex minOpAng",100,-1,1); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/MinOpAng", m_recoMinOpAng[vertexType]));
-    m_recoMaxOpAng[vertexType]           = new TH1F(("recoMaxOpAng" + vertexType).c_str(),"Reco vertex MaxOpAng",100,-1,1); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/MaxOpAng", m_recoMaxOpAng[vertexType]));
-    m_recoMaxDR[vertexType]              = new TH1F(("recoMaxDR" + vertexType).c_str(),"Reco vertex maxDR",100,0,10);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/MaxDR", m_recoMaxDR[vertexType]));
-    m_recoMinD0[vertexType]              = new TH1F(("recoMinD0" + vertexType).c_str(),"Reco vertex min d0 [mm]",100,0,100); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/MinD0", m_recoMinD0[vertexType]));
-    m_recoMaxD0[vertexType]              = new TH1F(("recoMaxD0" + vertexType).c_str(),"Reco vertex max d0 [mm]",100,0,100); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/MaxD0", m_recoMaxD0[vertexType]));
-    m_recoNtrk[vertexType]               = new TH1F(("recoNtrk" + vertexType).c_str(),"Reco vertex n tracks",30,0,30);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Ntrk", m_recoNtrk[vertexType]));
-
-    m_positionRes_R[vertexType]             = new TH1F(("positionRes_R" + vertexType).c_str(),"Position resolution for vertices matched to truth  decays",400,-20,20);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/positionRes_R", m_positionRes_R[vertexType]));
-    m_positionRes_Z[vertexType]             = new TH1F(("positionRes_Z" + vertexType).c_str(),"Position resolution for vertices matched to truth  decays",400,-20,20);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/positionRes_Z", m_positionRes_Z[vertexType]));
-    m_matchScore_weight[vertexType]          = new TH1F(("matchScore_weight" + vertexType).c_str(),"Vertex Match Score (weight)",101,0,1.01);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/matchScore_weight", m_matchScore_weight[vertexType]));
-    m_matchScore_pt[vertexType]             = new TH1F(("matchScore_pt" + vertexType).c_str(),"Vertex Match Score (pT)",101,0,1.01);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/matchScore_pt", m_matchScore_pt[vertexType]));
-    m_matchedTruthID[vertexType]            = new TH1F(("matchedTruthID" + vertexType).c_str(),"Vertex Truth Match ID",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/matchedTruthID", m_matchedTruthID[vertexType]));
-
-    // tracks
-    m_recoTrk_qOverP[vertexType]            = new TH1F(("recoTrk_qOverP" + vertexType).c_str(),"Reco track qOverP ",100,0,.01);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_qOverP", m_recoTrk_qOverP[vertexType]));
-    m_recoTrk_theta[vertexType]             = new TH1F(("recoTrk_theta" + vertexType).c_str(),"Reco track theta ",64,0,3.2);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_theta", m_recoTrk_theta[vertexType]));
-    m_recoTrk_E[vertexType]                 = new TH1F(("recoTrk_E" + vertexType).c_str(),"Reco track E ",100,0,100); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_E", m_recoTrk_E[vertexType]));
-    m_recoTrk_M[vertexType]                 = new TH1F(("recoTrk_M" + vertexType).c_str(),"Reco track M ",100,0,10);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_M", m_recoTrk_M[vertexType]));
-    m_recoTrk_Pt[vertexType]                = new TH1F(("recoTrk_Pt" + vertexType).c_str(),"Reco track Pt ",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Pt", m_recoTrk_Pt[vertexType]));
-    m_recoTrk_Px[vertexType]                = new TH1F(("recoTrk_Px" + vertexType).c_str(),"Reco track Px ",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Px", m_recoTrk_Px[vertexType]));
-    m_recoTrk_Py[vertexType]                = new TH1F(("recoTrk_Py" + vertexType).c_str(),"Reco track Py ",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Py", m_recoTrk_Py[vertexType]));
-    m_recoTrk_Pz[vertexType]                = new TH1F(("recoTrk_Pz" + vertexType).c_str(),"Reco track Pz ",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Pz", m_recoTrk_Pz[vertexType]));
-    m_recoTrk_Eta[vertexType]               = new TH1F(("recoTrk_Eta" + vertexType).c_str(),"Reco track Eta ",100,-5,5);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Eta", m_recoTrk_Eta[vertexType]));
-    m_recoTrk_Phi[vertexType]               = new TH1F(("recoTrk_Phi" + vertexType).c_str(),"Reco track Phi ",63,-3.2,3.2); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Phi", m_recoTrk_Phi[vertexType]));
-    m_recoTrk_D0[vertexType]                = new TH1F(("recoTrk_D0" + vertexType).c_str(),"Reco track D0 ",300,-300,300); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_D0", m_recoTrk_D0[vertexType]));
-    m_recoTrk_Z0[vertexType]                = new TH1F(("recoTrk_Z0" + vertexType).c_str(),"Reco track Z0 ",500,-500,500); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Z0", m_recoTrk_Z0[vertexType]));
-    m_recoTrk_errD0[vertexType]             = new TH1F(("recoTrk_errD0" + vertexType).c_str(),"Reco track errD0 ",300,0,30);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_errD0", m_recoTrk_errD0[vertexType]));
-    m_recoTrk_errZ0[vertexType]             = new TH1F(("recoTrk_errZ0" + vertexType).c_str(),"Reco track errZ0 ",500,0,50);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_errZ0", m_recoTrk_errZ0[vertexType]));
-    m_recoTrk_Chi2[vertexType]              = new TH1F(("recoTrk_Chi2" + vertexType).c_str(),"Reco track Chi2 ",100,0,10); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_Chi2", m_recoTrk_Chi2[vertexType]));
-    m_recoTrk_nDoF[vertexType]              = new TH1F(("recoTrk_nDoF" + vertexType).c_str(),"Reco track nDoF ",100,0,100);  
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_nDoF", m_recoTrk_nDoF[vertexType]));
-    m_recoTrk_charge[vertexType]            = new TH1F(("recoTrk_charge" + vertexType).c_str(),"Reco track charge ",3,-1.5,1.5); 
-    ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/SecondaryVertex/" + vertexType + "/Trk_charge", m_recoTrk_charge[vertexType]));
-
-  }
-
-  ////////////////////////////////////////////
-  //////// Truth Vertex Histograms ///////////
-  ////////////////////////////////////////////
-  m_truthX                    = new TH1F("truth_X","truth vertex x [mm]",500,-500,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthX", m_truthX));
-  m_truthY                    = new TH1F("truth_Y","truth vertex y [mm]",500,-500,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthY", m_truthY));
-  m_truthZ                    = new TH1F("truth_Z","truth vertex z [mm]",500,-500,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthZ", m_truthZ));
-  m_truthR                    = new TH1F("truth_R","truth vertex r [mm]",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthR", m_truthR));
-  m_truthdistFromPV           = new TH1F("truth_distFromPV","truth vertex distFromPV [mm]",500,0,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthdistFromPV", m_truthdistFromPV));
-  m_truthEta                  = new TH1F("truth_Eta","truth veEtatex Eta ",100,-5,5);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthEta", m_truthEta));
-  m_truthPhi                  = new TH1F("truth_Phi","truth vePhitex Phi ",64,-3.2,3.2); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthPhi", m_truthPhi));
-  m_truthNtrk_out             = new TH1F("truth_Ntrk_out","truth vertex n outgoing tracks",100,0,100);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthNtrk_out", m_truthNtrk_out));
-  m_truthParent_E             = new TH1F("truth_Parent_E","Reco track E ",100,0,100); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParent_E", m_truthParent_E));    
-  m_truthParent_M             = new TH1F("truth_Parent_M","Reco track M ",500,0,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParent_M", m_truthParent_M));
-  m_truthParent_Pt            = new TH1F("truth_Parent_Pt","Reco track Pt ",100,0,100);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParent_Pt", m_truthParent_Pt));
-  m_truthParent_Eta           = new TH1F("truth_Parent_Eta","Reco track Eta ",100,-5,5);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParent_Eta", m_truthParent_Eta));
-  m_truthParent_Phi           = new TH1F("truth_Parent_Phi","Reco track Phi ",63,-3.2,3.2); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParent_Phi", m_truthParent_Phi));
-  m_truthParent_charge        = new TH1F("truth_Parent_charge","Reco track charge ",3,-1,1); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParent_charge", m_truthParent_charge));
-  m_truthParentProdX          = new TH1F("truth_ParentProdX","truthParentProd vertex x [mm]",500,-500,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProdX", m_truthParentProdX));
-  m_truthParentProdY          = new TH1F("truth_ParentProdY","truthParentProd vertex y [mm]",500,-500,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProdY", m_truthParentProdY));
-  m_truthParentProdZ          = new TH1F("truth_ParentProdZ","truthParentProd vertex z [mm]",500,-500,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProdZ", m_truthParentProdZ));
-  m_truthParentProdR          = new TH1F("truth_ParentProdR","truthParentProd vertex r [mm]",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProdR", m_truthParentProdR));
-  m_truthParentProddistFromPV = new TH1F("truth_ParentProddistFromPV","truthParentProd vertex distFromPV [mm]",500,0,500);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProddistFromPV", m_truthParentProddistFromPV));
-  m_truthParentProdEta        = new TH1F("truth_ParentProdEta","truthParentProd veEtatex Eta ",100,-5,5);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProdEta", m_truthParentProdEta));
-  m_truthParentProdPhi        = new TH1F("truth_ParentProdPhi","truthParentProd vePhitex Phi ",64,-3.2,3.2); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/truthParentProdPhi", m_truthParentProdPhi));
-
-  m_truthInclusive_r            = new TH1F("truth_R_Inclusive","Reconstructable Truth Vertices",6000,0,600); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Inclusive/R", m_truthInclusive_r));
-  m_truthReconstructable_r      = new TH1F("truth_R_Reconstructable","Truth Vertices in detector acceptance",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Reconstructable/R", m_truthReconstructable_r));
-  m_truthAccepted_r             = new TH1F("truth_R_Accepted","Truth Vertices in detector acceptance",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Accepted/R", m_truthAccepted_r));
-  m_truthSeeded_r               = new TH1F("truth_R_Seeded","Seedable Truth Vertices",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Seeded/R", m_truthSeeded_r));
-  m_truthReconstructed_r        = new TH1F("truth_R_Reconstructed","Vertex with Match Score > 0.5",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Reconstructed/R", m_truthReconstructed_r));
-  m_truthSplit_r                = new TH1F("truth_R_Split","Split Vertex",6000,0,600);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Split/R", m_truthSplit_r));
-
-  // TODO: implement these plots
-  m_truth_Ntrk                  = new TH1F("truth_Ntrk","Truth vertex n track pass tracks",30,0,30);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Inclusive/Ntrk", m_truth_Ntrk));
-  m_truthReconstructable_trkSel = new TH1F("truth_Ntrk_Seeded","Seedable Truth Vertices",30,0,30); 
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Reconstructable/Ntrk", m_truthReconstructable_trkSel));
-  m_truthReconstructed_trkSel   = new TH1F("truth_Ntrk_Reconstructed","Vertex with Match Score > 0.5",30,0,30);  
-  ATH_CHECK( m_thistSvc->regHist("/VTXPLOTS/" + name() + "/TruthVertex/Reconstructed/Ntrk", m_truthReconstructed_trkSel));
-  return StatusCode::SUCCESS;
-}
-
-StatusCode InDetSecVertexTruthMatchTool::finalize()
-{
-
-  ATH_MSG_INFO("Finalizing InDetSecVertexTruthMatchTool");
-  return StatusCode::SUCCESS;
-}
-
-namespace {
-//Helper methods for this file only
-
-//In the vector of match info, find the element corresponding to link and return its index; create a new one if necessary
-size_t indexOfMatchInfo( std::vector<VertexTruthMatchInfo> & matches, const ElementLink<xAOD::TruthVertexContainer> & link ) {
-  for ( size_t i = 0; i < matches.size(); ++i ) {
-    if ( link.key() == std::get<0>(matches[i]).key() && link.index() == std::get<0>(matches[i]).index() )
-      return i;
-  }
-  // This is the first time we've seen this truth vertex, so make a new entry
-  matches.emplace_back( link, 0., 0. );
-  return matches.size() - 1;
-}
-
-}
-
-StatusCode InDetSecVertexTruthMatchTool::matchVertices( const xAOD::VertexContainer & vtxContainer,
-                                                        const xAOD::TruthVertexContainer & truthVtxContainer) {
-
-  ATH_MSG_DEBUG("Start vertex matching");
-
-  //setup decorators for truth matching info
-  static const xAOD::Vertex::Decorator<std::vector<VertexTruthMatchInfo> > matchInfoDecor("TruthVertexMatchingInfos");
-  static const xAOD::Vertex::Decorator<VertexMatchType> matchTypeDecor("VertexMatchType");
-  static const xAOD::Vertex::Decorator<std::vector<ElementLink<xAOD::VertexContainer> > > splitPartnerDecor("SplitPartners");
-  static const xAOD::Vertex::Decorator<ElementLink<xAOD::TruthVertexContainer> > backLinkDecor("RecoToTruthLink");
-
-  const xAOD::Vertex::Decorator<float> fakeScoreDecor("FakeScore");
-  const xAOD::Vertex::Decorator<float> otherScoreDecor("OtherScore");
-
-  //setup accessors
-  // can switch to built in method in xAOD::Vertex once don't have to deal with changing names anymore
-  xAOD::Vertex::ConstAccessor<xAOD::Vertex::TrackParticleLinks_t> trkAcc("trackParticleLinks");
-  xAOD::Vertex::ConstAccessor<std::vector<float> > weightAcc("trackWeights");
-
-  xAOD::TrackParticle::ConstAccessor<ElementLink<xAOD::TruthParticleContainer> > trk_truthPartAcc("truthParticleLink");
-  xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
-
-  //some variables to store
-  size_t ntracks;
-  xAOD::VxType::VertexType vtxType;
-
-  ATH_MSG_DEBUG("Starting Loop on Vertices");
-
-  //=============================================================================
-  //First loop over vertices: get tracks, then TruthParticles, and store relative
-  //weights from each TruthVertex
-  //=============================================================================
-  size_t vtxEntry = 0;
-
-  for ( const xAOD::Vertex* vtx : vtxContainer ) {
-
-    vtxEntry++;
-    ATH_MSG_DEBUG("Matching vertex number: " << vtxEntry << ".");
-
-    vtxType = static_cast<xAOD::VxType::VertexType>( vtx->vertexType() );
-
-    if(vtxType != xAOD::VxType::SecVtx ){
-      ATH_MSG_DEBUG("Vertex not labeled as secondary");
-      continue;
-    }
-
-    //create the vector we will add as matching info decoration later
-    std::vector<VertexTruthMatchInfo> matchinfo;
-
-    const xAOD::Vertex::TrackParticleLinks_t & trkParts = trkAcc( *vtx );
-    ntracks = trkParts.size();
-    const std::vector<float> & trkWeights = weightAcc( *vtx );
-
-    //if don't have track particles
-    if (!trkAcc.isAvailable(*vtx) || !weightAcc.isAvailable(*vtx) ) {
-      ATH_MSG_WARNING("trackParticles or trackWeights not available, vertex is missing info");
-      continue;
-    }
-    if ( trkWeights.size() != ntracks ) {
-      ATH_MSG_WARNING("Vertex without same number of tracks and trackWeights, vertex is missing info");
-      continue;
-    }
-
-    ATH_MSG_DEBUG("Matching new vertex at (" << vtx->x() << ", " << vtx->y() << ", " << vtx->z() << ")" << " with " << ntracks << " tracks, at index: " << vtx->index());
-
-    float totalWeight = 0.;
-    float totalPt = 0; 
-    float otherPt = 0;
-    float fakePt = 0;
-
-    //loop over the tracks in the vertex
-    for ( size_t t = 0; t < ntracks; ++t ) {
-
-      ATH_MSG_DEBUG("Checking track number " << t);
-
-      if (!trkParts[t].isValid()) {
-         ATH_MSG_DEBUG("Track " << t << " is bad!");
-         continue;
-      }
-      const xAOD::TrackParticle & trk = **trkParts[t];
-
-      // store the contribution to total weight and pT
-      totalWeight += trkWeights[t];
-      totalPt += trk.pt();
-
-      // get the linked truth particle
-      if (!trk_truthPartAcc.isAvailable(trk)) {
-        ATH_MSG_DEBUG("The truth particle link decoration isn't available.");
-        continue;
-      }  
-      const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc( trk );
-      float prob = trk_truthProbAcc( trk );
-      ATH_MSG_DEBUG("Truth prob: " << prob);
-
-      // check the truth particle origin
-      if (truthPartLink.isValid()  && prob > m_trkMatchProb) {
-        const xAOD::TruthParticle & truthPart = **truthPartLink;
-
-        int barcode =  checkProduction(truthPart);
-
-        //check if the truth particle is "good"
-        if ( barcode != -1 ) {
-          //track in vertex is linked to LLP descendant
-          //create link to truth vertex and add to matchInfo
-          auto it = std::find_if(truthVtxContainer.begin(), truthVtxContainer.end(), 
-            [&](const auto& ele){ return ele->barcode() == barcode;} );
-
-          if(it == truthVtxContainer.end()) {
-            ATH_MSG_DEBUG("Truth vertex with barcode " << barcode << " not found!");
-          }
-
-          // get index for the elementLink
-          size_t index = it - truthVtxContainer.begin();
-
-          const ElementLink<xAOD::TruthVertexContainer> elLink = ElementLink<xAOD::TruthVertexContainer>( truthVtxContainer, index );
-
-          size_t matchIdx = indexOfMatchInfo( matchinfo, elLink );
-
-          std::get<1>(matchinfo[matchIdx]) += trkWeights[t];
-          std::get<2>(matchinfo[matchIdx]) += trk.pt();
-        } else {
-          //truth particle failed cuts
-          ATH_MSG_DEBUG("Truth particle not from LLP decay.");
-          otherPt += trk.pt();
-        }
-      } else {
-        //not valid or low matching probability
-        ATH_MSG_DEBUG("Invalid or low prob truth link!");
-        fakePt += trk.pt();
-      }
-    }//end loop over tracks in vertex
-
-    
-
-    // normalize by total weight and pT
-    std::for_each( matchinfo.begin(), matchinfo.end(), [&](VertexTruthMatchInfo& link)
-    {
-      std::get<1>(link) /= totalWeight;
-      std::get<2>(link) /= totalPt;
-    });
-
-    float fakeScore = fakePt/totalPt;
-    float otherScore = otherPt/totalPt;
-
-    matchInfoDecor ( *vtx ) = matchinfo;
-    fakeScoreDecor ( *vtx ) = fakeScore;
-    otherScoreDecor( *vtx ) = otherScore;
-  }
-
-  //After first loop, all vertices have been decorated with their vector of match info (link to TruthVertex paired with weight)
-  //now we want to use that information from the whole collection to assign types
-  //keep track of whether a type is assigned
-  //useful since looking for splits involves a double loop, and then setting types ahead in the collection
-  std::vector<bool> assignedType( vtxContainer.size(), false );
-  static const xAOD::TruthVertex::Decorator<bool> isMatched("VertexMatchedToTruth");
-  static const xAOD::TruthVertex::Decorator<bool> isSplit("VertexSplit");
-
-  for ( size_t i = 0; i < vtxContainer.size(); ++i ) {
-
-    if ( assignedType[i] ) {
-      ATH_MSG_DEBUG("Vertex already defined as split.");
-      if(m_fillHist) {
-        ATH_CHECK( fillRecoPlots( *vtxContainer[i] ) );
-      }
-      continue; // make sure we don't reclassify vertices already found in the split loop below
-    }
-
-    std::vector<VertexTruthMatchInfo> & info = matchInfoDecor( *vtxContainer[i] );
-    float fakeScore  = fakeScoreDecor( *vtxContainer[i] );
-
-    if(fakeScore > m_vxMatchWeight) {
-      ATH_MSG_DEBUG("Vertex is fake.");
-      matchTypeDecor( *vtxContainer[i] ) = FAKE;
-    } else if (info.size() == 1) {
-      if(std::get<2>(info[0]) > m_vxMatchWeight ) { // one truth matched vertex, sufficient weight
-        ATH_MSG_DEBUG("One true decay vertices matched with sufficient weight. Vertex is matched.");
-        matchTypeDecor( *vtxContainer[i] ) = MATCHED;
-        isMatched(**std::get<0>(info[0])) = true;
-      }
-      else {
-        ATH_MSG_DEBUG("One true decay vertices matched with insufficient weight. Vertex is other.");
-        matchTypeDecor( *vtxContainer[i] ) = OTHER;
-      }
-    } else if (info.size() >= 2 ) {                        // more than one true deacy vertices matched
-      ATH_MSG_DEBUG("Multiple true decay vertices matched. Vertex is merged.");
-      matchTypeDecor( *vtxContainer[i] ) = MERGED;
-      std::for_each( info.begin(), info.end(), [](VertexTruthMatchInfo& link)
-      {
-        isMatched(**std::get<0>(link)) = true;
-      });
-    } else {                                // zero truth matched vertices, but not fake 
-      ATH_MSG_DEBUG("Vertex is neither fake nor LLP. Marking as OTHER.");
-      matchTypeDecor( *vtxContainer[i] ) = OTHER;
-    }
-
-    //check for splitting
-    // TODO: decorate linked truth vertices with isSplit
-    if ( matchTypeDecor( *vtxContainer[i] ) == MATCHED || matchTypeDecor( *vtxContainer[i] ) == MERGED ) {
-      std::vector<size_t> foundSplits;
-      for ( size_t j = i + 1; j < vtxContainer.size(); ++j ) {
-        std::vector<VertexTruthMatchInfo> & info2 = matchInfoDecor( *vtxContainer[j] );
-        //check second vertex is not dummy or fake, and that it has same elementlink as first vertex
-        //equality test is in code but doesnt seem to work for ElementLinks that I have?
-        //so i am just checking that the contianer key hash and the index are the same
-        if (matchTypeDecor( *vtxContainer[j] ) == FAKE) continue;
-        if (!info2.empty() && std::get<0>(info2[0]).isValid() && std::get<0>(info[0]).key() == std::get<0>(info2[0]).key() && std::get<0>(info[0]).index() == std::get<0>(info2[0]).index() ) {
-          //add split links; first between first one found and newest one
-          splitPartnerDecor( *vtxContainer[i] ).emplace_back( vtxContainer, j );
-          splitPartnerDecor( *vtxContainer[j] ).emplace_back( vtxContainer, i );
-          //then between any others we found along the way
-          for ( auto k : foundSplits ) { //k is a size_t in the vector of splits
-            splitPartnerDecor( *vtxContainer[k] ).emplace_back( vtxContainer, j );
-            splitPartnerDecor( *vtxContainer[j] ).emplace_back( vtxContainer, k );
-          }
-          //then keep track that we found this one
-          foundSplits.push_back(j);
-          matchTypeDecor( *vtxContainer[i] ) = SPLIT;
-          matchTypeDecor( *vtxContainer[j] ) = SPLIT;
-          isSplit(**std::get<0>(info[0])) = true;
-          assignedType[j] = true;
-        } //if the two vertices match to same TruthVertex
-      }//inner loop over vertices
-    } //if matched or merged
-
-    if(m_fillHist) {
-      ATH_CHECK( fillRecoPlots( *vtxContainer[i] ) );
-    }
-  } //outer loop
-
-  return StatusCode::SUCCESS;
-
-}
-
-StatusCode InDetSecVertexTruthMatchTool::labelTruthVertices( const xAOD::TruthVertexContainer & truthVtxContainer) {
-  
-  ATH_MSG_DEBUG("Labeling truth vertices");
-
-  const xAOD::TrackParticleContainer * trackPartCont = nullptr;
-  const xAOD::TrackParticleContainer * largeD0TrackPartCont = nullptr;
-
-  ATH_CHECK( evtStore()->retrieve( trackPartCont, "InDetTrackParticles" ) );
-  if ( evtStore()->contains<xAOD::TrackParticleContainer>( "InDetLargeD0TrackParticles" ) )
-    ATH_CHECK( evtStore()->retrieve( largeD0TrackPartCont, "InDetLargeD0TrackParticles" ) );
-  else
-    ATH_MSG_WARNING("No LRT container in input! Using standard tracks only.");
-
-
-  static const xAOD::Vertex::Decorator<TruthVertexMatchType> matchTypeDecor("TruthVertexMatchType");
-  xAOD::TruthVertex::Decorator<bool> isMatched("VertexMatchedToTruth");
-  xAOD::TruthVertex::Decorator<bool> isSplit("VertexSplit");
-
-  for(const xAOD::TruthVertex* truthVtx : truthVtxContainer) {
-
-    if(truthVtx->nIncomingParticles() != 1){continue;}
-    const xAOD::TruthParticle* truthPart = truthVtx->incomingParticle(0);
-    if(not truthPart) continue;
-    if(std::find(m_pdgIdList.begin(), m_pdgIdList.end(), std::abs(truthPart->pdgId())) == m_pdgIdList.end()) continue;
-    if(truthVtx->nOutgoingParticles()<2){continue;} //Skipping vertices with only 1 outgoing particle.
-    ATH_MSG_DEBUG("Analysing Truth Vertex " << truthVtx );
-    std::vector<const xAOD::TruthParticle*> reconstructibleParticles;
-    int counter = 0;
-    countReconstructibleDescendentParticles( *truthVtx, reconstructibleParticles, counter );
-
-    // temporary solution for keeping track of particles in the vertex
-    std::vector<int> particleInfo = {0,0,0};
-    std::vector<int> vertexInfo = {0,0,0};
-
-    for(size_t n = 0; n < reconstructibleParticles.size(); n++){
-      ATH_MSG_DEBUG("Checking daughter no. " << n);
-      const xAOD::TruthParticle* outPart = reconstructibleParticles.at(n);
-      
-      if (trackPartCont){
-        particleInfo = checkParticle(*outPart, *trackPartCont);
-        ATH_MSG_DEBUG(particleInfo);
-      
-        for(size_t h = 0; h < particleInfo.size(); h++){
-          vertexInfo.at(h) += particleInfo.at(h);
-        }
-      }
-      if (largeD0TrackPartCont){
-        particleInfo = checkParticle(*outPart, *largeD0TrackPartCont);
-        ATH_MSG_DEBUG(particleInfo);
-        
-        // skip first value in the tuple, we already counted it
-        // in the first loop
-        for(size_t h = 1; h < particleInfo.size(); h++){
-          vertexInfo.at(h) += particleInfo.at(h);
-        }
-      }
-    }
-      
-    ATH_MSG_DEBUG("Info for this LLP decay: " << vertexInfo);
-
-    matchTypeDecor(*truthVtx) = INCLUSIVE;
-    if( vertexInfo.at(0) > 1 &&  truthVtx->perp() <  320 && abs(truthVtx->z()) < 1500){
-      ATH_MSG_DEBUG("Vertex is reconstructable and in Inner Det region");
-      matchTypeDecor(*truthVtx) = RECONSTRUCTABLE;
-    }
-    if( matchTypeDecor(*truthVtx) == RECONSTRUCTABLE and vertexInfo.at(1) > 1){
-      ATH_MSG_DEBUG("Vertex has at least two tracks");
-      matchTypeDecor(*truthVtx) = ACCEPTED;
-    }
-    if(matchTypeDecor(*truthVtx) == ACCEPTED and vertexInfo.at(2) > 1){
-      ATH_MSG_DEBUG("Vertex is has at least two tracks passing track selection: " << vertexInfo.at(2));
-      matchTypeDecor(*truthVtx) = SEEDED;
-    }
-    if(matchTypeDecor(*truthVtx) == SEEDED and isMatched(*truthVtx)){
-      ATH_MSG_DEBUG("Vertex is matched to a reconstructed secVtx");
-      matchTypeDecor(*truthVtx) = RECONSTRUCTED;
-    }
-    if(matchTypeDecor(*truthVtx) == SEEDED and isSplit(*truthVtx)){
-      ATH_MSG_DEBUG("Vertex is matched to multiple secVtx");
-      matchTypeDecor(*truthVtx) = RECONSTRUCTEDSPLIT;
-    }
-
-    if(m_fillHist) {
-      ATH_CHECK( fillTruthPlots(*truthVtx) );
-    }
-
-  }
-  ATH_MSG_DEBUG("Done labeling truth vertices");
-
-  return StatusCode::SUCCESS;
-}
-
-std::vector<int> InDetSecVertexTruthMatchTool::checkParticle(const xAOD::TruthParticle &truthPart, const xAOD::TrackParticleContainer &trkCont) const {
-
-  xAOD::TrackParticle::ConstAccessor<char>  trackPass("is_selected"+m_AugString);
-  xAOD::TrackParticle::ConstAccessor<ElementLink<xAOD::TruthParticleContainer> > trk_truthPartAcc("truthParticleLink");
-  xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
-
-  if(truthPart.pt() < m_trkPtCut){
-    ATH_MSG_DEBUG("Insufficient pt to reconstruct the particle");
-    return {0,0,0};
-  }
-  else{
-
-    for(const xAOD::TrackParticle* trkPart : trkCont){
-      const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc( *trkPart );
-      float matchProb = trk_truthProbAcc( *trkPart );
-
-      if(truthPartLink.isValid() && matchProb > m_trkMatchProb) {
-        const xAOD::TruthParticle& tmpPart = **truthPartLink;
-        if(tmpPart.barcode() == truthPart.barcode()) {
-          if(trackPass.isAvailable( *trkPart ) and trackPass( *trkPart )) {
-            ATH_MSG_DEBUG("Particle has a track that passes track selection.");
-            return {1,1,1};
-          }
-          else {
-            ATH_MSG_DEBUG("Particle has a track, but did not pass track selection.");
-            return {1,1,0};
-          }
-        }
-      }
-    }
-    ATH_MSG_DEBUG("Particle has enough pt.");
-    return {1,0,0};
-    
-  }
-  return {0,0,0};
-}
-
-StatusCode InDetSecVertexTruthMatchTool::fillRecoPlots( const xAOD::Vertex& secVtx ) {
-  
-  // set of accessors for tracks and weights
-  xAOD::Vertex::ConstAccessor<xAOD::Vertex::TrackParticleLinks_t> trkAcc("trackParticleLinks");
-  xAOD::Vertex::ConstAccessor<std::vector<float> > weightAcc("trackWeights");
-  
-  // set of decorators for truth matching info
-  const xAOD::Vertex::Decorator<VertexMatchType> matchTypeDecor("VertexMatchType");
-  const xAOD::Vertex::Decorator<std::vector<VertexTruthMatchInfo> > matchInfoDecor("TruthVertexMatchingInfos");
-
-  std::string vertexType = "";
-  switch (matchTypeDecor(secVtx))
-  {
-  case MATCHED:
-    vertexType = "Matched";
-    break;
-  case MERGED:
-    vertexType = "Merged";
-    break;
-  case SPLIT:
-    vertexType = "Split";
-    break;
-  case OTHER:
-    vertexType = "Other";
-    break;
-  case FAKE:
-    vertexType = "Fake";
-    break;
-  default:
-    break;
-  }
-
-  m_matchType->Fill(matchTypeDecor(secVtx));
-
-  TVector3 reco_pos(secVtx.x(), secVtx.y(), secVtx.z());
-  float reco_r = reco_pos.Perp();
-
-
-  size_t ntracks;
-  const xAOD::Vertex::TrackParticleLinks_t & trkParts = trkAcc( secVtx );
-  ntracks = trkParts.size();
-
-  TLorentzVector sumP4(0,0,0,0);
-  double H = 0.0;
-  double HT = 0.0;
-  int charge = 0;
-  double minOpAng = -1.0* 1.e10;
-  double maxOpAng =  1.0* 1.e10;
-  double minD0 = 1.0* 1.e10;
-  double maxD0 = 0.0;
-  double maxDR = 0.0;
-
-  xAOD::TrackParticle::ConstAccessor< std::vector< float > > accCovMatrixDiag( "definingParametersCovMatrixDiag" );
-
-  ATH_MSG_DEBUG("Loop over tracks");
-  for(size_t t = 0; t < ntracks; t++){
-    if(!trkParts[t].isValid()){
-      ATH_MSG_DEBUG("Track " << t << " is bad!");
-      continue;
-    }
-    const xAOD::TrackParticle & trk = **trkParts[t];
-
-    double trk_d0 = std::abs(trk.definingParameters()[0]);
-    double trk_z0 = std::abs(trk.definingParameters()[1]);
-
-    if(trk_d0 < minD0){ minD0 = trk_d0; }
-    if(trk_d0 > maxD0){ maxD0 = trk_d0; }
-
-    TLorentzVector vv;
-    // TODO: use values computed w.r.t SV
-    vv.SetPtEtaPhiM(trk.pt(),trk.eta(), trk.phi0(), trk.m());
-    sumP4 += vv;
-    H += vv.Vect().Mag();
-    HT += vv.Pt();
-
-    TLorentzVector v_minus_iv(0,0,0,0);
-    for(size_t j = 0; j < ntracks; j++){
-      if (j == t){ continue; }
-      if(!trkParts[j].isValid()){
-        ATH_MSG_DEBUG("Track " << j << " is bad!");
-        continue;
-      }
-
-      const xAOD::TrackParticle & trk_2 = **trkParts[j];
-
-      TLorentzVector tmp;
-      // TODO: use values computed w.r.t. SV
-      tmp.SetPtEtaPhiM(trk_2.pt(),trk_2.eta(), trk_2.phi0(), trk_2.m());
-      v_minus_iv += tmp;
-
-      if( j > t ) {
-        double tm = vv * tmp / ( vv.Mag() * tmp.Mag() );
-        if( minOpAng < tm ) minOpAng = tm;
-        if( maxOpAng > tm ) maxOpAng = tm;
-      }
-    }
-
-    double DR = vv.DeltaR(v_minus_iv);
-    if( DR > maxDR ){ maxDR = DR;}
-
-    charge += trk.charge();
-
-    xAOD::TrackParticle::ConstAccessor<float> Trk_Chi2("chiSquared");
-    xAOD::TrackParticle::ConstAccessor<float> Trk_nDoF("numberDoF");
-
-    if ( Trk_Chi2.isAvailable(trk) && Trk_Chi2(trk) && Trk_nDoF.isAvailable(trk) && Trk_nDoF(trk) )  {
-      m_recoTrk_Chi2[vertexType]->Fill( Trk_Chi2(trk) / Trk_nDoF(trk));
-      m_recoTrk_nDoF[vertexType]->Fill( Trk_nDoF(trk) ); 
-    }
-    m_recoTrk_charge[vertexType]->Fill(trk.charge());
-    m_recoTrk_errD0[vertexType]->Fill(trk.definingParametersCovMatrix()(0,0));
-    m_recoTrk_errZ0[vertexType]->Fill(trk.definingParametersCovMatrix()(1,1));
-
-    m_recoTrk_theta[vertexType]->Fill(trk.definingParameters()[3]);
-    m_recoTrk_qOverP[vertexType]->Fill(trk.definingParameters()[4]);
-    m_recoTrk_E[vertexType]->Fill(trk.e()/GeV);
-    m_recoTrk_M[vertexType]->Fill(trk.m()/GeV);
-    m_recoTrk_Pt[vertexType]->Fill(trk.pt()/GeV);
-
-    m_recoTrk_Px[vertexType]->Fill(trk.p4().Px()/GeV);
-    m_recoTrk_Py[vertexType]->Fill(trk.p4().Py()/GeV);
-    m_recoTrk_Pz[vertexType]->Fill(trk.p4().Pz()/GeV);
-
-    m_recoTrk_Eta[vertexType]->Fill(trk.eta());
-    m_recoTrk_Phi[vertexType]->Fill(trk.phi0());
-
-    m_recoTrk_D0[vertexType]->Fill(trk_d0);
-    m_recoTrk_Z0[vertexType]->Fill(trk_z0);
-  } // end loop over tracks
-
-  const double dir  = sumP4.Vect().Dot( reco_pos ) / sumP4.Vect().Mag() / reco_pos.Mag();
-
-  xAOD::Vertex::ConstAccessor<float> Chi2("chiSquared");
-  xAOD::Vertex::ConstAccessor<float> nDoF("numberDoF");
-  m_recoX[vertexType]->Fill(secVtx.x());
-  m_recoY[vertexType]->Fill(secVtx.y());
-  m_recoZ[vertexType]->Fill(secVtx.z());
-  m_recoR[vertexType]->Fill(reco_r);
-  m_recoNtrk[vertexType]->Fill(ntracks);
-  m_recoPt[vertexType]->Fill(sumP4.Pt() / GeV);
-  m_recoEta[vertexType]->Fill(sumP4.Eta());
-  m_recoPhi[vertexType]->Fill(sumP4.Phi());
-  m_recoMass[vertexType]->Fill(sumP4.M() / GeV);
-  m_recoMu[vertexType]->Fill(sumP4.M()/maxDR / GeV);
-  m_recoChi2[vertexType]->Fill(Chi2(secVtx)/nDoF(secVtx));
-  m_recoDir[vertexType]->Fill(dir);
-  m_recoCharge[vertexType]->Fill(charge);
-  m_recoH[vertexType]->Fill(H / GeV);
-  m_recoHt[vertexType]->Fill(HT / GeV);
-  m_recoMinOpAng[vertexType]->Fill(minOpAng);
-  m_recoMaxOpAng[vertexType]->Fill(maxOpAng); 
-  m_recoMinD0[vertexType]->Fill(minD0);
-  m_recoMaxD0[vertexType]->Fill(maxD0); 
-  m_recoMaxDR[vertexType]->Fill(maxDR); 
-
-  m_recoX["All"]->Fill(secVtx.x());
-  m_recoY["All"]->Fill(secVtx.y());
-  m_recoZ["All"]->Fill(secVtx.z());
-  m_recoR["All"]->Fill(reco_r);
-  m_recoNtrk["All"]->Fill(ntracks);
-  m_recoPt["All"]->Fill(sumP4.Pt() / GeV);
-  m_recoEta["All"]->Fill(sumP4.Eta());
-  m_recoPhi["All"]->Fill(sumP4.Phi());
-  m_recoMass["All"]->Fill(sumP4.M() / GeV);
-  m_recoMu["All"]->Fill(sumP4.M()/maxDR / GeV);
-  m_recoChi2["All"]->Fill(Chi2(secVtx)/nDoF(secVtx));
-  m_recoDir["All"]->Fill(dir);
-  m_recoCharge["All"]->Fill(charge);
-  m_recoH["All"]->Fill(H / GeV);
-  m_recoHt["All"]->Fill(HT / GeV);
-  m_recoMinOpAng["All"]->Fill(minOpAng);
-  m_recoMaxOpAng["All"]->Fill(maxOpAng); 
-  m_recoMinD0["All"]->Fill(minD0);
-  m_recoMaxD0["All"]->Fill(maxD0); 
-  m_recoMaxDR["All"]->Fill(maxDR); 
-
-  std::vector<VertexTruthMatchInfo> truthmatchinfo;
-  truthmatchinfo = matchInfoDecor(secVtx);
-
-  // This includes all matched vertices, including splits
-  if(not truthmatchinfo.empty()){
-    float matchScore_weight = std::get<1>(truthmatchinfo.at(0));
-    float matchScore_pt     = std::get<2>(truthmatchinfo.at(0));
-
-    m_matchScore_weight[vertexType]->Fill(matchScore_weight);
-    m_matchScore_pt[vertexType]->Fill(matchScore_pt);
-
-    ATH_MSG_DEBUG("Match Score and probability: " << matchScore_weight << " " << matchScore_pt/0.01);
-
-    const ElementLink<xAOD::TruthVertexContainer>& truthVertexLink = std::get<0>(truthmatchinfo.at(0));
-    const xAOD::TruthVertex& truthVtx = **truthVertexLink ;
-
-    m_positionRes_R[vertexType]->Fill(reco_r - truthVtx.perp());
-    m_positionRes_Z[vertexType]->Fill(secVtx.z() - truthVtx.z());
-
-    m_recoX["LLP"]->Fill(secVtx.x());
-    m_recoY["LLP"]->Fill(secVtx.y());
-    m_recoZ["LLP"]->Fill(secVtx.z());
-    m_recoR["LLP"]->Fill(reco_r);
-    m_recoNtrk["LLP"]->Fill(ntracks);
-    m_recoPt["LLP"]->Fill(sumP4.Pt() / GeV);
-    m_recoEta["LLP"]->Fill(sumP4.Eta());
-    m_recoPhi["LLP"]->Fill(sumP4.Phi());
-    m_recoMass["LLP"]->Fill(sumP4.M() / GeV);
-    m_recoMu["LLP"]->Fill(sumP4.M()/maxDR / GeV);
-    m_recoChi2["LLP"]->Fill(Chi2(secVtx)/nDoF(secVtx));
-    m_recoDir["LLP"]->Fill(dir);
-    m_recoCharge["LLP"]->Fill(charge);
-    m_recoH["LLP"]->Fill(H / GeV);
-    m_recoHt["LLP"]->Fill(HT / GeV);
-    m_recoMinOpAng["LLP"]->Fill(minOpAng);
-    m_recoMaxOpAng["LLP"]->Fill(maxOpAng); 
-    m_recoMinD0["LLP"]->Fill(minD0);
-    m_recoMaxD0["LLP"]->Fill(maxD0); 
-    m_recoMaxDR["LLP"]->Fill(maxDR); 
-
-    m_positionRes_R["LLP"]->Fill(reco_r - truthVtx.perp());
-    m_positionRes_Z["LLP"]->Fill(secVtx.z() - truthVtx.z());
-    m_matchScore_weight["LLP"]->Fill(matchScore_weight);
-    m_matchScore_pt["LLP"]->Fill(matchScore_pt);
-  }
-  
-  return StatusCode::SUCCESS;
-}
-
-StatusCode InDetSecVertexTruthMatchTool::fillTruthPlots( const xAOD::TruthVertex& truthVtx) {
-  
-  ATH_MSG_DEBUG("Plotting truth vertex");
-
-  m_truthX->Fill(truthVtx.x());
-  m_truthY->Fill(truthVtx.y());
-  m_truthZ->Fill(truthVtx.z());
-  m_truthR->Fill(truthVtx.perp());
-  m_truthEta->Fill(truthVtx.eta());
-  m_truthPhi->Fill(truthVtx.phi());
-  m_truthNtrk_out->Fill(truthVtx.nOutgoingParticles());
-
-  ATH_MSG_DEBUG("Plotting truth parent");
-  const xAOD::TruthParticle& truthPart = *truthVtx.incomingParticle(0);
-
-  m_truthParent_E->Fill(truthPart.e() / GeV);
-  m_truthParent_M->Fill(truthPart.m() / GeV);
-  m_truthParent_Pt->Fill(truthPart.pt() / GeV);
-  m_truthParent_Phi->Fill(truthPart.phi());
-  m_truthParent_Eta->Fill(truthPart.eta());
-  m_truthParent_charge->Fill(truthPart.charge());
-
-  ATH_MSG_DEBUG("Plotting truth prod vtx");
-  if(truthPart.hasProdVtx()){
-    const xAOD::TruthVertex & vertex = *truthPart.prodVtx();
-
-    m_truthParentProdX->Fill(vertex.x());
-    m_truthParentProdY->Fill(vertex.y());
-    m_truthParentProdZ->Fill(vertex.z());
-    m_truthParentProdR->Fill(vertex.perp());
-    m_truthParentProdEta->Fill(vertex.eta());
-    m_truthParentProdPhi->Fill(vertex.phi());
-  }
-
-  ATH_MSG_DEBUG("Plotting match types");
-  static const xAOD::Vertex::Decorator<TruthVertexMatchType> matchTypeDecor("TruthVertexMatchType");
-  
-  m_truthInclusive_r->Fill(truthVtx.perp());
-
-  if(matchTypeDecor(truthVtx) >= RECONSTRUCTABLE){
-    m_truthReconstructable_r->Fill(truthVtx.perp());
-  }
-  if(matchTypeDecor(truthVtx) >= ACCEPTED){
-    m_truthAccepted_r->Fill(truthVtx.perp());
-  }
-  if(matchTypeDecor(truthVtx) >= SEEDED){
-    m_truthSeeded_r->Fill(truthVtx.perp());
-  }
-  if(matchTypeDecor(truthVtx) >= RECONSTRUCTED){
-    m_truthReconstructed_r->Fill(truthVtx.perp());
-  }
-  if(matchTypeDecor(truthVtx) >= RECONSTRUCTEDSPLIT){
-    m_truthSplit_r->Fill(truthVtx.perp());
-  }
-  return StatusCode::SUCCESS;
-}
-
-
-// check if truth particle originated from decay of particle in the pdgIdList
-int InDetSecVertexTruthMatchTool::checkProduction( const xAOD::TruthParticle & truthPart ) const {
-
-  if (truthPart.nParents() == 0){
-    ATH_MSG_DEBUG("Particle has no parents (end of loop)");
-    return -1;
-  } 
-  else{
-    const xAOD::TruthParticle * parent = truthPart.parent(0);
-    if(not parent) {
-      ATH_MSG_DEBUG("Particle parent is null");
-      return -1;
-    }
-    ATH_MSG_DEBUG("Parent ID: " << parent->pdgId());
-        
-    if(std::find(m_pdgIdList.begin(), m_pdgIdList.end(), std::abs(parent->pdgId())) != m_pdgIdList.end()) {
-        ATH_MSG_DEBUG("Found LLP decay.");
-        const xAOD::TruthVertex* vertex = parent->decayVtx();
-        return vertex->barcode();
-    }
-    // recurse on parent
-    return checkProduction(*parent);
-  }
-  return -1;
-}
-
-void InDetSecVertexTruthMatchTool::countReconstructibleDescendentParticles(const xAOD::TruthVertex& signalTruthVertex,
-                                                                           std::vector<const xAOD::TruthParticle*>& set, int counter) const {
-
-  counter++;
-
-  for( size_t itrk = 0; itrk < signalTruthVertex.nOutgoingParticles(); itrk++) {
-    const auto* particle = signalTruthVertex.outgoingParticle( itrk );
-    if( !particle ) continue;
-    // Recursively add descendents
-    if( particle->hasDecayVtx() ) {
-      
-      TVector3 decayPos( particle->decayVtx()->x(), particle->decayVtx()->y(), particle->decayVtx()->z() );
-      TVector3 prodPos ( particle->prodVtx()->x(),  particle->prodVtx()->y(),  particle->prodVtx()->z()  );
-      
-      auto isInside  = []( TVector3& v ) { return ( v.Perp() < 300. && std::abs( v.z() ) < 1500. ); };
-      auto isOutside = []( TVector3& v ) { return ( v.Perp() > 563. || std::abs( v.z() ) > 2720. ); };
-      
-      const auto distance = (decayPos - prodPos).Mag();
-
-      if (counter > 100) {
-        ATH_MSG_WARNING("Vetoing particle that may be added recursively infinitely (potential loop in generator record");
-        break;
-      }
-      
-      // consider track reconstructible if it travels at least 10mm
-      if( distance < 10.0 ) {
-        countReconstructibleDescendentParticles( *particle->decayVtx(), set , counter);
-      } else if( isInside ( prodPos  )  && isOutside( decayPos )  && particle->isCharged() ) {
-        set.push_back( particle );
-      } else if( particle->isElectron() || particle->isMuon() ) {
-        set.push_back( particle );
-      }
-    } else {
-      if( !(particle->isCharged()) ) continue;
-      set.push_back( particle );
-    }
-  }
-  
-  }
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/src/InDetSecVertexTruthMatchAlgorithm.cxx b/InnerDetector/InDetValidation/InDetSecVertexValidation/src/InDetSecVertexTruthMatchAlgorithm.cxx
deleted file mode 100644
index 157c24ef731fb6bcb4f5d132200430743643afc1..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/src/InDetSecVertexTruthMatchAlgorithm.cxx
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "InDetSecVertexTruthMatchAlgorithm.h"
-
-#include "xAODTracking/VertexContainer.h"
-#include "xAODTruth/TruthVertexContainer.h"
-
-
-InDetSecVertexTruthMatchAlgorithm::InDetSecVertexTruthMatchAlgorithm( const std::string& name, ISvcLocator* svcLoc )
-   : AthAlgorithm( name, svcLoc ),
-     m_matchTool( "InDetSecVertexTruthMatchTool/InDetSecVertexTruthMatchTool", this ) {
-
-   declareProperty( "SecVertexSGKey", m_secVtxSGKey = "VrtSecInclusive_SecondaryVertices" );
-   declareProperty( "TruthVertexSGKey", m_truthVtxSGKey = "TruthBSMWithDecayVertices" );
-   declareProperty( "VertexTruthMatchTool", m_matchTool );
-}
-
-StatusCode InDetSecVertexTruthMatchAlgorithm::initialize() {
-
-   // Greet the user:
-   ATH_MSG_INFO( "Initialising" );
-   ATH_MSG_DEBUG( "SecVertexSGKey = " << m_secVtxSGKey );
-   ATH_MSG_DEBUG( "TruthVertexSGKey = " << m_truthVtxSGKey );
-
-   // Retrieve the tools:
-   ATH_CHECK( m_matchTool.retrieve() );
-
-   // Return gracefully:
-   return StatusCode::SUCCESS;
-}
-
-StatusCode InDetSecVertexTruthMatchAlgorithm::execute() {
-
-  //Retrieve the vertices:
-  const xAOD::VertexContainer * inSecVert = nullptr;
-  ATH_CHECK( evtStore()->retrieve( inSecVert, m_secVtxSGKey ) );
-
-  //Retrieve truth vertices:
-  const xAOD::TruthVertexContainer * inTruthVert = nullptr;
-  ATH_CHECK( evtStore()->retrieve( inTruthVert, m_truthVtxSGKey ) );
-
-  //pass to the tool for decoration:
-  ATH_CHECK( m_matchTool->matchVertices( *inSecVert, *inTruthVert ) );
-  ATH_CHECK( m_matchTool->labelTruthVertices( *inTruthVert ) );
-
-  return StatusCode::SUCCESS;
-
-}
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/src/InDetSecVertexTruthMatchAlgorithm.h b/InnerDetector/InDetValidation/InDetSecVertexValidation/src/InDetSecVertexTruthMatchAlgorithm.h
deleted file mode 100644
index 664b5e56d6c84961f4d6893fee0714bb35791b78..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/src/InDetSecVertexTruthMatchAlgorithm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef INDETSECVERTEXTRUTHMATCHALGORITHM_H
-#define INDETSECVERTEXTRUTHMATCHALGORITHM_H
-
-// Gaudi/Athena include(s):
-#include "AthenaBaseComps/AthAlgorithm.h"
-#include "AsgTools/ToolHandle.h"
-
-// Local include(s):
-#include "InDetSecVertexValidation/IInDetSecVertexTruthMatchTool.h"
-
-class InDetSecVertexTruthMatchAlgorithm : public AthAlgorithm {
-
- public:
-  /// Regular Algorithm constructor
-  InDetSecVertexTruthMatchAlgorithm( const std::string& name, ISvcLocator* svcLoc );
-
-  /// Function initialising the algorithm
-  virtual StatusCode initialize() override final;
-  /// Function executing the algorithm
-  virtual StatusCode execute() override final;
-
- private:
-  /// StoreGate key for the vertex container to investigate
-  std::string m_secVtxSGKey;
-  std::string m_truthVtxSGKey;
-  
-  ToolHandle<IInDetSecVertexTruthMatchTool> m_matchTool;
-
-};
-
-#endif
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/src/components/InDetSecVertexValidation_entries.cxx b/InnerDetector/InDetValidation/InDetSecVertexValidation/src/components/InDetSecVertexValidation_entries.cxx
index 7aa7e5189c52599b8bcc3d83de11cb59a2ac3a58..fbbbc38f6c2b3a9ca28723b2dded8092e8d6acca 100644
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/src/components/InDetSecVertexValidation_entries.cxx
+++ b/InnerDetector/InDetValidation/InDetSecVertexValidation/src/components/InDetSecVertexValidation_entries.cxx
@@ -1,15 +1,11 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // Gaudi/Athena include(s):
 //#include "GaudiKernel/DeclareFactoryEntries.h"
 
 // Local include(s):
-#include "InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h"
-#include "../InDetSecVertexTruthMatchAlgorithm.h"
 #include "../PhysValSecVtx.h"
 
-DECLARE_COMPONENT( InDetSecVertexTruthMatchTool )
-DECLARE_COMPONENT( InDetSecVertexTruthMatchAlgorithm )
 DECLARE_COMPONENT( PhysValSecVtx )
\ No newline at end of file
diff --git a/InnerDetector/InDetValidation/InDetSecVertexValidation/util/VertexTruthMatchTest.cxx b/InnerDetector/InDetValidation/InDetSecVertexValidation/util/VertexTruthMatchTest.cxx
deleted file mode 100644
index 5874e20cc7e154a6afb0dbc16b813e72d892fe53..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetValidation/InDetSecVertexValidation/util/VertexTruthMatchTest.cxx
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
-*/
-
-//ROOT
-#include <TFile.h>
-#include <TH1.h>
-
-#ifdef ROOTCORE
-#include "xAODRootAccess/Init.h"
-#include "xAODRootAccess/TEvent.h"
-#include "xAODRootAccess/TStore.h"
-#endif
-
-#include "xAODEventInfo/EventInfo.h"
-#include "xAODTracking/VertexContainer.h"
-#include "xAODTracking/TrackParticleContainer.h"
-
-#include "InDetSecVertexValidation/InDetSecVertexTruthMatchTool.h"
-#include "InDetSecVertexValidation/InDetSecVertexTruthMatchUtils.h"
-
-#include "AsgMessaging/MessageCheck.h"
-
-int main( int argc, char* argv[] ) {
-
-  using namespace asg::msgUserCode;
-
-  const char * APP_NAME = argv[0];
-
-  //check for filename
-  if( argc < 2 ) {
-    Error( APP_NAME, "No file name argument" );
-    Error( APP_NAME, "  Usage: %s xAOD_file_name [nEntries]",APP_NAME );
-    return 1;
-  }
-
-  //init app
-  bool result = xAOD::Init( APP_NAME );
-  if(!result) {
-    Error( APP_NAME, "Failed to init");
-    return 1;
-  }
-
-  //open file
-  const char * fileName = argv[1];
-  Info(APP_NAME, "Opening file: %s", fileName );
-  TFile * file = new TFile(fileName,"READ");
-
-  xAOD::TEvent event( xAOD::TEvent::kClassAccess );
-  result = event.readFrom( file );
-  if(!result) {
-    Error( APP_NAME, "Failed to have TEvent read file");
-    return 1;
-  }
-
-  //create transient object store
-  xAOD::TStore store;
-
-  Long64_t entries = event.getEntries();
-  if( argc > 2 ) {
-    const Long64_t e = atoll( argv[2] );
-    if( e < entries )
-      entries = e;
-  }
-
-  //Tool to test
-  InDetSecVertexTruthMatchTool matchTool("VertexTruthMatchTool");
-
-  //config
-  matchTool.msg().setLevel( MSG::DEBUG );
-  ATH_CHECK( matchTool.setProperty( "trackMatchProb", 0.7 ) );
-  ATH_CHECK( matchTool.setProperty( "vertexMatchWeight", 0.5 ) );
-  ATH_CHECK( matchTool.setProperty( "pdgIds", "36" ) );
-  ATH_CHECK( matchTool.initialize() );
-
-  TFile fout("output.root","RECREATE");
-  fout.cd();
-  
-  //some inclusive test plots
-  TH1F * h_cat = new TH1F("vertexMatchTypes","Number of vertices of each type",4,-0.5,3.5);
-  h_cat->GetXaxis()->SetBinLabel(1, "Matched");
-  h_cat->GetXaxis()->SetBinLabel(2, "Merged");
-  h_cat->GetXaxis()->SetBinLabel(3, "Split");
-  h_cat->GetXaxis()->SetBinLabel(4, "Fake");
-
-
-  //Loop
-  for( Long64_t entry = 0; entry < entries; ++entry ) {
-
-    event.getEntry( entry );
-
-    const xAOD::EventInfo * ei = nullptr;
-    result = event.retrieve( ei, "EventInfo" );
-    if(!result) {
-      Error( APP_NAME, "Failed to retrieve EventInfo on entry %i", static_cast<int>(entry));
-      return 1;
-    }
-
-    if( entry % 100 == 0 ) {
-      Info( APP_NAME, 
-            "===Start event %i, run %i; %i events processed so far===",
-            static_cast<int>( ei->eventNumber() ),
-            static_cast<int>( ei->runNumber() ),
-            static_cast<int>( entry ) );
-    }
-
-    //get vertices
-    const xAOD::VertexContainer * vxContainer = nullptr;
-    result = event.retrieve( vxContainer, "VrtSecInclusive_SecondaryVertices" );
-    if(!result) {
-      Error( APP_NAME, "Failed to retrieve VrtSecInclusive_SecondaryVertices on entry %i", static_cast<int>(entry));
-      return 1;
-    }
-    const xAOD::TruthVertexContainer * tvxContainer = nullptr;
-    result = event.retrieve( tvxContainer, "TruthVertices" );
-    if(!result) {
-      Error( APP_NAME, "Failed to retrieve TruthVertices on entry %i", static_cast<int>(entry));
-      return 1;
-    }
-
-    int status = matchTool.matchVertices( *vxContainer, *tvxContainer );
-    if(!status) {
-      Error( APP_NAME, "Bad status from matching tool on entry %i", static_cast<int>(entry));
-      continue;
-    }
-
-    //accessor for the matching type
-    xAOD::Vertex::Decorator<InDetSecVertexTruthMatchUtils::VertexMatchType> matchTypeDecor("VertexMatchType");
-
-    //fill the category histogram for all vertices
-    for( auto vxit : *vxContainer ) {
-      h_cat->Fill( matchTypeDecor( *vxit ) );
-    }
-    
-  }
-
-  h_cat->Write();
-  fout.Close();
-
-  delete h_cat;
-
-  return 0;
-}
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/CMakeLists.txt b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/CMakeLists.txt
index 14040b7af0d90b0c3af87827cce12ec1df08eb95..244484d5775a8c5409663356de1013b7ca1dd64b 100644
--- a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/CMakeLists.txt
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/CMakeLists.txt
@@ -7,7 +7,7 @@ atlas_subdir( TrackingAnalysisAlgorithms )
 atlas_add_library( TrackingAnalysisAlgorithmsLib
    TrackingAnalysisAlgorithms/*.h Root/*.cxx
    PUBLIC_HEADERS TrackingAnalysisAlgorithms
-   LINK_LIBRARIES AnaAlgorithmLib EventBookkeeperToolsLib xAODTracking
+   LINK_LIBRARIES AnaAlgorithmLib EventBookkeeperToolsLib xAODTracking InDetSecVtxTruthMatchToolLib
    AsgDataHandlesLib AsgTools AthContainers )
 
 atlas_add_dictionary( TrackingAnalysisAlgorithmsDict
@@ -20,3 +20,6 @@ if( NOT XAOD_STANDALONE )
       src/*.h src/*.cxx src/components/*.cxx
       LINK_LIBRARIES GaudiKernel TrackingAnalysisAlgorithmsLib )
 endif()
+
+atlas_install_python_modules( python/*.py )
+atlas_install_runtime( scripts/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/Root/SecVertexTruthMatchAlg.cxx b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/Root/SecVertexTruthMatchAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5dd3c17368d70688cf4bf1de491c3c604018f998
--- /dev/null
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/Root/SecVertexTruthMatchAlg.cxx
@@ -0,0 +1,412 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrackingAnalysisAlgorithms/SecVertexTruthMatchAlg.h"
+#include "InDetSecVtxTruthMatchTool/InDetSecVtxTruthMatchTool.h"
+#include "xAODTruth/TruthParticle.h"
+
+#include "TMath.h"
+#include "TH1.h"
+#include "TEfficiency.h"
+
+const float GeV = 1000.;
+
+namespace CP {
+
+  SecVertexTruthMatchAlg::SecVertexTruthMatchAlg( const std::string& name, ISvcLocator* svcLoc )
+    : EL::AnaAlgorithm( name, svcLoc ) {}
+
+  StatusCode SecVertexTruthMatchAlg::initialize() {
+
+    // Initializing Keys
+    ATH_CHECK(m_secVtxContainerKey.initialize());
+    ATH_CHECK(m_truthVtxContainerKey.initialize());
+    ATH_CHECK(m_trackParticleContainerKey.initialize());
+
+    // Retrieving the tool
+    ATH_CHECK(m_matchTool.retrieve());
+
+    if(m_writeHistograms) {
+      std::vector<std::string> recoTypes{"All", "Matched", "Merged", "Fake", "Split", "Other"};
+      std::vector<std::string> truthTypes{"Inclusive", "Reconstructable", "Accepted", "Seeded", "Reconstructed", "ReconstructedSplit"};
+
+      ANA_CHECK (book(TH1F("RecoVertex/matchType", "Vertex Match Type", 8, -0.5, 7.5)));
+
+      for(const auto& recoType : recoTypes) {
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_x").c_str(), "Reco vertex x [mm]", 1000, -500, 500)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_y").c_str(), "Reco vertex y [mm]", 1000, -500, 500)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_z").c_str(), "Reco vertex z [mm]", 1000, -500, 500)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Lxy").c_str(), "Reco vertex L_{xy} [mm]", 500, 0, 500)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_pT").c_str(), "Reco vertex p_{T} [GeV]", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_eta").c_str(), "Reco vertex #eta", 100, -5, 5)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_phi").c_str(), "Reco vertex #phi", 100, -TMath::Pi(), TMath::Pi())));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_mass").c_str(), "Reco vertex mass [GeV]", 500, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_mu").c_str(), "Reco vertex Red. Mass [GeV]", 500, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_chi2").c_str(), "Reco vertex recoChi2", 100, 0, 10)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_dir").c_str(), "Reco vertex recoDirection", 100, -1, 1)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_charge").c_str(), "Reco vertex recoCharge", 20, -10, 10)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_H").c_str(), "Reco vertex H [GeV]", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_HT").c_str(), "Reco vertex Mass [GeV]", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_minOpAng").c_str(), "Reco vertex minOpAng", 100, -1, 1)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_maxOpAng").c_str(), "Reco vertex maxOpAng", 100, -1, 1)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_maxdR").c_str(), "Reco vertex maxDR", 100, 0, 10)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_mind0").c_str(), "Reco vertex min d0 [mm]", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_maxd0").c_str(), "Reco vertex max d0 [mm]", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_ntrk").c_str(), "Reco vertex n tracks", 30, 0, 30)));
+
+        // tracks
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_qOverP").c_str(), "Reco track qOverP ", 100, 0, .01)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_theta").c_str(), "Reco track theta ", 64, 0, 3.2)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_E").c_str(), "Reco track E ", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_M").c_str(), "Reco track M ", 100, 0, 10)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Pt").c_str(), "Reco track Pt ", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Px").c_str(), "Reco track Px ", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Py").c_str(), "Reco track Py ", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Pz").c_str(), "Reco track Pz ", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Eta").c_str(), "Reco track Eta ", 100, -5, 5)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Phi").c_str(), "Reco track Phi ", 63, -3.2, 3.2)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_D0").c_str(), "Reco track D0 ", 300, -300, 300)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Z0").c_str(), "Reco track Z0 ", 500, -500, 500)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_errD0").c_str(), "Reco track errD0 ", 300, 0, 30)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_errZ0").c_str(), "Reco track errZ0 ", 500, 0, 50)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_Chi2").c_str(), "Reco track Chi2 ", 100, 0, 10)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_nDoF").c_str(), "Reco track nDoF ", 100, 0, 100)));
+        ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_Trk_charge").c_str(), "Reco track charge ", 3, -1.5, 1.5)));
+
+        // truth matching -- don't book for non-matched vertices
+        if ( recoType != "Inclusive" and recoType != "Fake" ) {
+          ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_positionRes_R").c_str(), "Position resolution for vertices matched to truth decays", 400, -20, 20)));
+          ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_positionRes_Z").c_str(), "Position resolution for vertices matched to truth decays", 400, -20, 20)));
+          ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_matchScore_weight").c_str(), "Vertex Match Score (weight)", 101, 0, 1.01)));
+          ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_matchScore_pt").c_str(), "Vertex Match Score (pT)", 101, 0, 1.01)));
+          ANA_CHECK (book(TH1F(("RecoVertex/" + recoType + "_matchedTruthID").c_str(), "Vertex Truth Match ID", 100, 0, 100)));
+        }
+      }
+      for(const auto& truthType : truthTypes) {
+        ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_x").c_str(), "Truth vertex x [mm]", 1000, -500, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_y").c_str(), "Truth vertex y [mm]", 500, -500, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_z").c_str(), "Truth vertex z [mm]", 500, -500, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_R").c_str(), "Truth vertex r [mm]", 6000, 0, 600)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_distFromPV").c_str(), "Truth vertex distFromPV [mm]", 500, 0, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Eta").c_str(), "Truth vertex Eta", 100, -5, 5)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Phi").c_str(), "Truth vertex Phi", 64, -3.2, 3.2)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Ntrk_out").c_str(), "Truth vertex n outgoing tracks", 100, 0, 100)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Parent_E").c_str(), "Reco track E", 100, 0, 100)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Parent_M").c_str(), "Reco track M", 500, 0, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Parent_Pt").c_str(), "Reco track Pt", 100, 0, 100)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Parent_Eta").c_str(), "Reco track Eta", 100, -5, 5)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Parent_Phi").c_str(), "Reco track Phi", 63, -3.2, 3.2)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_Parent_charge").c_str(), "Reco track charge", 3, -1, 1)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProdX").c_str(), "truthParentProd vertex x [mm]", 500, -500, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProdY").c_str(), "truthParentProd vertex y [mm]", 500, -500, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProdZ").c_str(), "truthParentProd vertex z [mm]", 500, -500, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProdR").c_str(), "truthParentProd vertex r [mm]", 6000, 0, 600)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProddistFromPV").c_str(), "truthParentProd vertex distFromPV [mm]", 500, 0, 500)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProdEta").c_str(), "truthParentProd vertex Eta", 100, -5, 5)));
+				ANA_CHECK (book(TH1F(("TruthVertex/" + truthType + "_ParentProdPhi").c_str(), "truthParentProd vertex Phi", 64, -3.2, 3.2)));
+			}
+			// now add the efficiencies
+      Double_t bins[] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 125, 150, 200, 300, 500}; 
+      size_t nbins = sizeof(bins)/sizeof(bins[0])-1;
+			ANA_CHECK (book(TEfficiency("Acceptance", "Acceptance", nbins, bins)));
+			ANA_CHECK (book(TEfficiency("eff_seed", "Seed efficiency", nbins, bins)));
+			ANA_CHECK (book(TEfficiency("eff_core", "Core efficiency", nbins, bins)));
+			ANA_CHECK (book(TEfficiency("eff_total", "Total efficiency", nbins, bins)));
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode SecVertexTruthMatchAlg::execute() {
+
+    //Retrieve the vertices:
+    SG::ReadHandle<xAOD::VertexContainer> recoVertexContainer(m_secVtxContainerKey);
+    SG::ReadHandle<xAOD::TruthVertexContainer> truthVertexContainer(m_truthVtxContainerKey);
+    SG::ReadHandle<xAOD::TrackParticleContainer> trackParticleContainer(m_trackParticleContainerKey);
+
+    std::vector<const xAOD::Vertex*> recoVerticesToMatch;
+    std::vector<const xAOD::TruthVertex*> truthVerticesToMatch;
+
+    for(const auto &recoVertex : *recoVertexContainer) {
+      xAOD::VxType::VertexType vtxType = static_cast<xAOD::VxType::VertexType>( recoVertex->vertexType() );
+
+      if(vtxType != xAOD::VxType::SecVtx ){
+        ATH_MSG_DEBUG("Vertex not labeled as secondary");
+        continue;
+      }
+      recoVerticesToMatch.push_back(recoVertex);
+    }
+
+    for(const auto &truthVertex : *truthVertexContainer) {
+      if(truthVertex->nIncomingParticles() != 1) {
+        continue;
+      }
+      const xAOD::TruthParticle* truthPart = truthVertex->incomingParticle(0);
+      if(not truthPart) {
+        continue;
+      }
+      if(std::find(m_targetPDGIDs.begin(), m_targetPDGIDs.end(), std::abs(truthPart->pdgId())) == m_targetPDGIDs.end()) {
+        continue;
+      }
+      if(truthVertex->nOutgoingParticles() < 2) {
+        continue;
+      }
+      truthVerticesToMatch.push_back(truthVertex);
+    }
+
+    //pass to the tool for decoration:
+    ATH_CHECK( m_matchTool->matchVertices( recoVerticesToMatch, truthVerticesToMatch, trackParticleContainer.cptr() ) );
+
+    if(m_writeHistograms) {
+      static const xAOD::Vertex::Decorator<int> matchTypeDecor("vertexMatchType");
+      for(const auto& secVtx : recoVerticesToMatch) {
+        int matchTypeBitset = matchTypeDecor(*secVtx);
+        hist("RecoVertex/matchType")->Fill(matchTypeBitset);
+
+        if(InDetSecVtxTruthMatchUtils::isMatched(matchTypeBitset)) {
+          fillRecoHistograms(secVtx, "Matched");
+        }
+        if(InDetSecVtxTruthMatchUtils::isMerged(matchTypeBitset)) {
+          fillRecoHistograms(secVtx, "Merged");
+        }
+        if(InDetSecVtxTruthMatchUtils::isFake(matchTypeBitset)) {
+          fillRecoHistograms(secVtx, "Fake");
+        }
+        if(InDetSecVtxTruthMatchUtils::isSplit(matchTypeBitset)) {
+          fillRecoHistograms(secVtx, "Split");
+        }
+        if(InDetSecVtxTruthMatchUtils::isOther(matchTypeBitset)) {
+          fillRecoHistograms(secVtx, "Other");
+        }
+        fillRecoHistograms(secVtx, "All");
+      }
+
+      static const xAOD::Vertex::Decorator<int> truthTypeDecor("truthVertexMatchType");
+      for(const auto& truthVtx : truthVerticesToMatch) {
+        int truthTypeBitset = truthTypeDecor(*truthVtx);
+        if(InDetSecVtxTruthMatchUtils::isReconstructable(truthTypeBitset)) {
+          fillTruthHistograms(truthVtx, "Reconstructable");
+
+          // fill efficiencies
+          efficiency("Acceptance")->Fill(InDetSecVtxTruthMatchUtils::isAccepted(truthTypeBitset), truthVtx->perp());
+          efficiency("eff_total")->Fill(InDetSecVtxTruthMatchUtils::isReconstructed(truthTypeBitset), truthVtx->perp());
+        }
+        if(InDetSecVtxTruthMatchUtils::isAccepted(truthTypeBitset)) {
+          fillTruthHistograms(truthVtx, "Accepted");
+          efficiency("eff_seed")->Fill(InDetSecVtxTruthMatchUtils::isSeeded(truthTypeBitset), truthVtx->perp());
+        }
+        if(InDetSecVtxTruthMatchUtils::isSeeded(truthTypeBitset)) {
+          fillTruthHistograms(truthVtx, "Seeded");
+          efficiency("eff_core")->Fill(InDetSecVtxTruthMatchUtils::isReconstructed(truthTypeBitset), truthVtx->perp());
+        }
+        if(InDetSecVtxTruthMatchUtils::isReconstructed(truthTypeBitset)) {
+          fillTruthHistograms(truthVtx, "Reconstructed");
+        }
+        if(InDetSecVtxTruthMatchUtils::isReconstructedSplit(truthTypeBitset)) {
+          fillTruthHistograms(truthVtx, "ReconstructedSplit");
+        }
+        fillTruthHistograms(truthVtx, "Inclusive");
+
+      }
+    }
+
+    return StatusCode::SUCCESS;
+
+  }
+  void SecVertexTruthMatchAlg::fillRecoHistograms(const xAOD::Vertex* secVtx, std::string matchType) {
+
+		// set of accessors for tracks and weights
+		xAOD::Vertex::ConstAccessor<xAOD::Vertex::TrackParticleLinks_t> trkAcc("trackParticleLinks");
+		xAOD::Vertex::ConstAccessor<std::vector<float> > weightAcc("trackWeights");
+		
+		// set of decorators for truth matching info
+		const xAOD::Vertex::Decorator<std::vector<InDetSecVtxTruthMatchUtils::VertexTruthMatchInfo> > matchInfoDecor("truthVertexMatchingInfos");
+    
+    TVector3 reco_pos(secVtx->x(), secVtx->y(), secVtx->z());
+    float Lxy = reco_pos.Perp();
+
+    size_t ntracks;
+    const xAOD::Vertex::TrackParticleLinks_t & trkParts = trkAcc( *secVtx );
+    ntracks = trkParts.size();
+
+    TLorentzVector sumP4(0,0,0,0);
+    double H = 0.0;
+    double HT = 0.0;
+    int charge = 0;
+    double minOpAng = -1.0* 1.e10;
+    double maxOpAng =  1.0* 1.e10;
+    double minD0 = 1.0* 1.e10;
+    double maxD0 = 0.0;
+    double maxDR = 0.0;
+
+    xAOD::TrackParticle::ConstAccessor< std::vector< float > > accCovMatrixDiag( "definingParametersCovMatrixDiag" );
+
+    ATH_MSG_DEBUG("Loop over tracks");
+    for(size_t t = 0; t < ntracks; t++){
+      if(!trkParts[t].isValid()){
+        ATH_MSG_DEBUG("Track " << t << " is bad!");
+        continue;
+      }
+      const xAOD::TrackParticle & trk = **trkParts[t];
+
+      double trk_d0 = std::abs(trk.definingParameters()[0]);
+      double trk_z0 = std::abs(trk.definingParameters()[1]);
+
+      if(trk_d0 < minD0){ minD0 = trk_d0; }
+      if(trk_d0 > maxD0){ maxD0 = trk_d0; }
+
+      TLorentzVector vv;
+      // TODO: use values computed w.r.t SV
+      vv.SetPtEtaPhiM(trk.pt(),trk.eta(), trk.phi0(), trk.m());
+      sumP4 += vv;
+      H += vv.Vect().Mag();
+      HT += vv.Pt();
+
+      TLorentzVector v_minus_iv(0,0,0,0);
+      for(size_t j = 0; j < ntracks; j++){
+        if (j == t){ continue; }
+        if(!trkParts[j].isValid()){
+          ATH_MSG_DEBUG("Track " << j << " is bad!");
+          continue;
+        }
+
+        const xAOD::TrackParticle & trk_2 = **trkParts[j];
+
+        TLorentzVector tmp;
+        // TODO: use values computed w.r.t. SV
+        tmp.SetPtEtaPhiM(trk_2.pt(),trk_2.eta(), trk_2.phi0(), trk_2.m());
+        v_minus_iv += tmp;
+
+        if( j > t ) {
+          double tm = vv * tmp / ( vv.Mag() * tmp.Mag() );
+          if( minOpAng < tm ) minOpAng = tm;
+          if( maxOpAng > tm ) maxOpAng = tm;
+        }
+      }
+      double DR = vv.DeltaR(v_minus_iv);
+      if( DR > maxDR ){ maxDR = DR;}
+
+      charge += trk.charge();
+
+      xAOD::TrackParticle::ConstAccessor<float> Trk_Chi2("chiSquared");
+      xAOD::TrackParticle::ConstAccessor<float> Trk_nDoF("numberDoF");
+
+      if ( Trk_Chi2.isAvailable(trk) && Trk_Chi2(trk) && Trk_nDoF.isAvailable(trk) && Trk_nDoF(trk) )  {
+        hist("RecoVertex/" + matchType + "_Trk_Chi2")->Fill(Trk_Chi2(trk) / Trk_nDoF(trk));
+        hist("RecoVertex/" + matchType + "_Trk_nDoF")->Fill(Trk_nDoF(trk));
+      }
+      hist("RecoVertex/" + matchType + "_Trk_D0")->Fill(trk_d0);
+      hist("RecoVertex/" + matchType + "_Trk_Z0")->Fill(trk_z0);
+      hist("RecoVertex/" + matchType + "_Trk_theta")->Fill(trk.definingParameters()[3]);
+      hist("RecoVertex/" + matchType + "_Trk_qOverP")->Fill(trk.definingParameters()[4]);
+      hist("RecoVertex/" + matchType + "_Trk_Eta")->Fill(trk.eta());
+      hist("RecoVertex/" + matchType + "_Trk_Phi")->Fill(trk.phi0());
+      hist("RecoVertex/" + matchType + "_Trk_E")->Fill(trk.e() / GeV);
+      hist("RecoVertex/" + matchType + "_Trk_M")->Fill(trk.m() / GeV);
+      hist("RecoVertex/" + matchType + "_Trk_Pt")->Fill(trk.pt() / GeV);
+      hist("RecoVertex/" + matchType + "_Trk_Px")->Fill(trk.p4().Px() / GeV);
+      hist("RecoVertex/" + matchType + "_Trk_Py")->Fill(trk.p4().Py() / GeV);
+      hist("RecoVertex/" + matchType + "_Trk_Pz")->Fill(trk.p4().Pz() / GeV);
+      hist("RecoVertex/" + matchType + "_Trk_charge")->Fill(trk.charge());
+      hist("RecoVertex/" + matchType + "_Trk_errD0")->Fill(trk.definingParametersCovMatrix()(0,0));
+      hist("RecoVertex/" + matchType + "_Trk_errZ0")->Fill(trk.definingParametersCovMatrix()(1,1));
+    } // end loop over tracks
+
+    const double dir  = sumP4.Vect().Dot( reco_pos ) / sumP4.Vect().Mag() / reco_pos.Mag();
+
+    xAOD::Vertex::ConstAccessor<float> Chi2("chiSquared");
+    xAOD::Vertex::ConstAccessor<float> nDoF("numberDoF");
+
+    hist("RecoVertex/" + matchType + "_x")->Fill(secVtx->x());
+    hist("RecoVertex/" + matchType + "_y")->Fill(secVtx->y());
+    hist("RecoVertex/" + matchType + "_z")->Fill(secVtx->z());
+    hist("RecoVertex/" + matchType + "_Lxy")->Fill(Lxy);
+    hist("RecoVertex/" + matchType + "_ntrk")->Fill(ntracks);
+    hist("RecoVertex/" + matchType + "_pT")->Fill(sumP4.Pt() / GeV);
+    hist("RecoVertex/" + matchType + "_eta")->Fill(sumP4.Eta());
+    hist("RecoVertex/" + matchType + "_phi")->Fill(sumP4.Phi());
+    hist("RecoVertex/" + matchType + "_mass")->Fill(sumP4.M() / GeV);
+    hist("RecoVertex/" + matchType + "_mu")->Fill(sumP4.M()/maxDR / GeV);
+    hist("RecoVertex/" + matchType + "_chi2")->Fill(Chi2(*secVtx)/nDoF(*secVtx));
+    hist("RecoVertex/" + matchType + "_dir")->Fill(dir);
+    hist("RecoVertex/" + matchType + "_charge")->Fill(charge);
+    hist("RecoVertex/" + matchType + "_H")->Fill(H / GeV);
+    hist("RecoVertex/" + matchType + "_HT")->Fill(HT / GeV);
+    hist("RecoVertex/" + matchType + "_minOpAng")->Fill(minOpAng);
+    hist("RecoVertex/" + matchType + "_maxOpAng")->Fill(maxOpAng);
+    hist("RecoVertex/" + matchType + "_mind0")->Fill(minD0);
+    hist("RecoVertex/" + matchType + "_maxd0")->Fill(maxD0);
+    hist("RecoVertex/" + matchType + "_maxdR")->Fill(maxDR);
+
+    std::vector<InDetSecVtxTruthMatchUtils::VertexTruthMatchInfo> truthmatchinfo;
+    truthmatchinfo = matchInfoDecor(*secVtx);
+
+    // This includes all matched vertices, including splits
+    if(not truthmatchinfo.empty()){
+      float matchScore_weight = std::get<1>(truthmatchinfo.at(0));
+      float matchScore_pt     = std::get<2>(truthmatchinfo.at(0));
+
+      ATH_MSG_DEBUG("Match Score and probability: " << matchScore_weight << " " << matchScore_pt/0.01);
+
+      const ElementLink<xAOD::TruthVertexContainer>& truthVertexLink = std::get<0>(truthmatchinfo.at(0));
+      const xAOD::TruthVertex& truthVtx = **truthVertexLink ;
+
+      hist("RecoVertex/" + matchType + "_positionRes_R")->Fill(Lxy - truthVtx.perp());
+      hist("RecoVertex/" + matchType + "_positionRes_Z")->Fill(secVtx->z() - truthVtx.z());
+      hist("RecoVertex/" + matchType + "_matchScore_weight")->Fill(matchScore_weight);
+      hist("RecoVertex/" + matchType + "_matchScore_pt")->Fill(matchScore_pt);
+    }
+  }
+
+  void SecVertexTruthMatchAlg::fillTruthHistograms(const xAOD::TruthVertex* truthVtx, std::string truthType) {
+
+    hist("TruthVertex/" + truthType + "_x")->Fill(truthVtx->x());
+    hist("TruthVertex/" + truthType + "_y")->Fill(truthVtx->y());
+    hist("TruthVertex/" + truthType + "_z")->Fill(truthVtx->z());
+    hist("TruthVertex/" + truthType + "_R")->Fill(truthVtx->perp());
+    hist("TruthVertex/" + truthType + "_Eta")->Fill(truthVtx->eta());
+    hist("TruthVertex/" + truthType + "_Phi")->Fill(truthVtx->phi());
+    hist("TruthVertex/" + truthType + "_Ntrk_out")->Fill(truthVtx->nOutgoingParticles());
+
+    ATH_MSG_DEBUG("Plotting truth parent");
+    const xAOD::TruthParticle& truthPart = *truthVtx->incomingParticle(0);
+
+    hist("TruthVertex/" + truthType + "_Parent_E")->Fill(truthPart.e() / GeV);
+    hist("TruthVertex/" + truthType + "_Parent_M")->Fill(truthPart.m() / GeV);
+    hist("TruthVertex/" + truthType + "_Parent_Pt")->Fill(truthPart.pt() / GeV);
+    hist("TruthVertex/" + truthType + "_Parent_Phi")->Fill(truthPart.phi());
+    hist("TruthVertex/" + truthType + "_Parent_Eta")->Fill(truthPart.eta());
+    hist("TruthVertex/" + truthType + "_Parent_charge")->Fill(truthPart.charge());
+
+    ATH_MSG_DEBUG("Plotting truth prod vtx");
+    if(truthPart.hasProdVtx()){
+      const xAOD::TruthVertex & vertex = *truthPart.prodVtx();
+
+      hist("TruthVertex/" + truthType + "_ParentProdX")->Fill(vertex.x());
+      hist("TruthVertex/" + truthType + "_ParentProdY")->Fill(vertex.y());
+      hist("TruthVertex/" + truthType + "_ParentProdZ")->Fill(vertex.z());
+      hist("TruthVertex/" + truthType + "_ParentProdR")->Fill(vertex.perp());
+      hist("TruthVertex/" + truthType + "_ParentProdEta")->Fill(vertex.eta());
+      hist("TruthVertex/" + truthType + "_ParentProdPhi")->Fill(vertex.phi());
+    }
+    // m_truthInclusive_r->Fill(truthVtx.perp());
+
+    // if(matchTypeDecor(truthVtx) >= RECONSTRUCTABLE){
+    //   m_truthReconstructable_r->Fill(truthVtx.perp());
+    // }
+    // if(matchTypeDecor(truthVtx) >= ACCEPTED){
+    //   m_truthAccepted_r->Fill(truthVtx.perp());
+    // }
+    // if(matchTypeDecor(truthVtx) >= SEEDED){
+    //   m_truthSeeded_r->Fill(truthVtx.perp());
+    // }
+    // if(matchTypeDecor(truthVtx) >= RECONSTRUCTED){
+    //   m_truthReconstructed_r->Fill(truthVtx.perp());
+    // }
+    // if(matchTypeDecor(truthVtx) >= RECONSTRUCTEDSPLIT){
+    //   m_truthSplit_r->Fill(truthVtx.perp());
+    // }
+    // 
+	}
+} // namespace CP
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/SecVertexTruthMatchAlg.h b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/SecVertexTruthMatchAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e70b277bc0f2b301b6c21bc1cc219955ae200c8
--- /dev/null
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/SecVertexTruthMatchAlg.h
@@ -0,0 +1,61 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRACKINGANALYSISALGORITHMS_SECVERTEXTRUTHMATCHALG_H
+#define TRACKINGANALYSISALGORITHMS_SECVERTEXTRUTHMATCHALG_H
+
+// Gaudi/Athena include(s):
+#include "AnaAlgorithm/AnaAlgorithm.h"
+#include "AsgTools/ToolHandle.h"
+
+// SG includes
+#include "xAODTracking/VertexContainer.h"
+#include "xAODTracking/TrackParticleContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
+
+// Local include(s):
+#include "InDetSecVtxTruthMatchTool/IInDetSecVtxTruthMatchTool.h"
+
+// Asg includes
+#include <AsgTools/PropertyWrapper.h>
+#include <AsgDataHandles/ReadHandleKey.h>
+#include <AsgDataHandles/ReadHandle.h>
+
+namespace CP {
+
+   /// Algorithm to perform truth matching on secondary vertices
+   ///
+   /// @author Jackson Burzynski <jackson.carl.burzynski@cern.ch>
+   ///
+  class SecVertexTruthMatchAlg final : public EL::AnaAlgorithm {
+
+  public:
+    /// Regular Algorithm constructor
+    SecVertexTruthMatchAlg( const std::string& name, ISvcLocator* svcLoc );
+    virtual StatusCode initialize() override;
+    virtual StatusCode execute() override;
+
+  private:
+    // Input (reco) Secondary Vertices
+    SG::ReadHandleKey<xAOD::VertexContainer> m_secVtxContainerKey{this, "SecondaryVertexContainer", "VrtSecInclusive_SecondaryVertices",
+                                                                "Secondary vertex container"};
+    // Input Truth Vertices
+    SG::ReadHandleKey<xAOD::TruthVertexContainer> m_truthVtxContainerKey{this, "TruthVertexContainer", "TruthVertices",
+                                                                        "Truth vertex container"};
+    // Input Tracks
+    SG::ReadHandleKey<xAOD::TrackParticleContainer> m_trackParticleContainerKey{this, "TrackParticleContainer", "InDetTrackParticles",
+                                                                "Track container"};
+                                                                        
+    Gaudi::Property<std::vector<int>> m_targetPDGIDs{this, "TargetPDGIDs", {}, "List of PDGIDs to select for matching"};
+
+    Gaudi::Property<bool> m_writeHistograms{this, "WriteHistograms", true, "Write histograms"};
+    
+    ToolHandle<IInDetSecVtxTruthMatchTool> m_matchTool{this, "MatchTool", "InDetSecVtxTruthMatchTool"};
+
+    void fillRecoHistograms(const xAOD::Vertex* secVtx, std::string matchType);
+    void fillTruthHistograms(const xAOD::TruthVertex* truthVtx, std::string truthType);
+
+  };
+} // namespace CP
+#endif
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithmsDict.h b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithmsDict.h
index b1168f430529624e4f03d2a3d787269fd712ed3f..40f074f015a9c2b5fa6a18050d2e62d18431baad 100644
--- a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithmsDict.h
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithmsDict.h
@@ -1,6 +1,6 @@
 // Dear emacs, this is -*- c++ -*-
 //
-// Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+// Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 //
 #ifndef TRACKINGANALYSISALGORITHMS_TRACKINGANALYSISALGORITHMSDICT_H
 #define TRACKINGANALYSISALGORITHMS_TRACKINGANALYSISALGORITHMSDICT_H
@@ -8,5 +8,6 @@
 // Local include(s):
 #include "TrackingAnalysisAlgorithms/VertexSelectionAlg.h"
 #include "TrackingAnalysisAlgorithms/TrackParticleMergerAlg.h"
+#include "TrackingAnalysisAlgorithms/SecVertexTruthMatchAlg.h"
 
 #endif // TRACKINGANALYSISALGORITHMS_TRACKINGANALYSISALGORITHMSDICT_H
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/selection.xml b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/selection.xml
index 0713cd73938555d2f016d02620f1c70c5bdfb1e6..a86b756c4f14ce0914f09ad84c22e1e6b70b8be5 100644
--- a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/selection.xml
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/TrackingAnalysisAlgorithms/selection.xml
@@ -1,7 +1,8 @@
-<!-- Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration -->
+<!-- Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration -->
 <lcgdict>
 
   <class name="CP::VertexSelectionAlg" />
   <class name="CP::TrackParticleMergerAlg" />
+  <class name="CP::SecVertexTruthMatchAlg" />
 
 </lcgdict>
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/python/TrackingAnalysisAlgorithmsConfig.py b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/python/TrackingAnalysisAlgorithmsConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..d5c56f4f43e069e67641effbdbbf6aa41b95bf0e
--- /dev/null
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/python/TrackingAnalysisAlgorithmsConfig.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+
+def InDetSecVtxTruthMatchToolCfg(flags, name="InDetSecVtxTruthMatchTool", **kwargs):
+    acc = ComponentAccumulator()
+    acc.setPrivateTools(CompFactory.InDetSecVtxTruthMatchTool(**kwargs))
+    return acc
+
+def SecVertexTruthMatchAlgCfg(flags, name="SecVertexTruthMatchAlg", useLRTTracks = False, **kwargs):
+
+    acc = ComponentAccumulator()
+
+    if useLRTTracks:
+        from DerivationFrameworkInDet.InDetToolsConfig import InDetLRTMergeCfg
+        acc.merge(InDetLRTMergeCfg(flags))
+        kwargs.setdefault("TrackParticleContainer", "InDetWithLRTTrackParticles")
+
+    kwargs.setdefault("TruthVertexContainer", "TruthVertices")
+    kwargs.setdefault("SecondaryVertexContainer", "VrtSecInclusive_SecondaryVertices")
+    kwargs.setdefault("TargetPDGIDs", [511,521])
+    kwargs.setdefault("MatchTool", acc.popToolsAndMerge(InDetSecVtxTruthMatchToolCfg(flags)))
+
+    truthMatchAlg = CompFactory.CP.SecVertexTruthMatchAlg(name, **kwargs)
+
+    acc.addEventAlgo(truthMatchAlg)
+    acc.addService(CompFactory.THistSvc(Output = [f"ANALYSIS DATAFILE='{flags.Output.HISTFileName}' OPT='RECREATE'"]))
+    acc.setAppProperty("HistogramPersistency","ROOT")
+    return acc
+
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/scripts/runSecVtxTruthMatching.py b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/scripts/runSecVtxTruthMatching.py
new file mode 100755
index 0000000000000000000000000000000000000000..1b022212f93e892b1e99305f4376716af0c54fbc
--- /dev/null
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/scripts/runSecVtxTruthMatching.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+from glob import glob
+
+def get_args():
+    from argparse import ArgumentParser
+    parser = ArgumentParser(description='Parser for SecVertexTruthMatching configuration')
+    parser.add_argument("--filesInput", required=True)
+    parser.add_argument("--maxEvents", help="Limit number of events. Default: all input events", default=-1, type=int)
+    parser.add_argument("--skipEvents", help="Skip this number of events. Default: no events are skipped", default=0, type=int)
+    parser.add_argument("--mergeLargeD0Tracks", help='Consider LRT tracks in the matching', action='store_true', default=False)
+    parser.add_argument("--outputFile", help='Name of output file',default="TruthMatchHists.root")
+    parser.add_argument("--pdgIds", help='List of pdgIds to match', nargs='+', type=int, default=[36,51])
+    parser.add_argument("--vertexContainer", help='SG key of secondary vertex container',default='VrtSecInclusive_SecondaryVertices')
+    parser.add_argument("--truthVertexContainer", help='SG key of truth vertex container',default='TruthVertices')
+    return parser.parse_args()
+
+if __name__=='__main__':
+
+    args = get_args()
+
+    from AthenaConfiguration.AllConfigFlags import initConfigFlags
+    flags = initConfigFlags()
+
+    flags.Input.Files = []
+    for path in args.filesInput.split(','):
+        flags.Input.Files += glob(path)
+    flags.Output.HISTFileName = args.outputFile
+                                    
+    flags.Exec.SkipEvents = args.skipEvents
+    flags.Exec.MaxEvents = args.maxEvents
+
+    flags.lock()
+
+    from AthenaConfiguration.MainServicesConfig import MainServicesCfg
+    acc = MainServicesCfg(flags)
+    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+    acc.merge(PoolReadCfg(flags))
+    
+    from TrackingAnalysisAlgorithms.TrackingAnalysisAlgorithmsConfig import SecVertexTruthMatchAlgCfg
+    acc.merge(SecVertexTruthMatchAlgCfg(flags, 
+                                        useLRTTracks = args.mergeLargeD0Tracks, 
+                                        TargetPDGIDs = args.pdgIds,
+                                        SecondaryVertexContainer = args.vertexContainer,
+                                        TruthVertexContainer = args.truthVertexContainer
+                                        )
+    )
+
+    acc.printConfig(withDetails=True)
+
+    # Execute and finish
+    sc = acc.run()
+
+    # Success should be 0
+    import sys
+    sys.exit(not sc.isSuccess())
diff --git a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/src/components/TrackingAnalysisAlgorithms_entries.cxx b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/src/components/TrackingAnalysisAlgorithms_entries.cxx
index f254ab815a274580e695e22a7ba2028c973b6f53..2af979ddd3710f0861f907a97bbcc4f8f3909697 100644
--- a/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/src/components/TrackingAnalysisAlgorithms_entries.cxx
+++ b/PhysicsAnalysis/Algorithms/TrackingAnalysisAlgorithms/src/components/TrackingAnalysisAlgorithms_entries.cxx
@@ -5,9 +5,11 @@
 // Local include(s):
 #include "TrackingAnalysisAlgorithms/VertexSelectionAlg.h"
 #include "TrackingAnalysisAlgorithms/TrackParticleMergerAlg.h"
+#include "TrackingAnalysisAlgorithms/SecVertexTruthMatchAlg.h"
 
 
 // Declare the component(s) of the package:
 DECLARE_COMPONENT( CP::VertexSelectionAlg )
 DECLARE_COMPONENT( CP::TrackParticleMergerAlg )
+DECLARE_COMPONENT( CP::SecVertexTruthMatchAlg )
 
diff --git a/Projects/AnalysisBase/package_filters.txt b/Projects/AnalysisBase/package_filters.txt
index 06a700c85111361ded0a5b92ab6f1c58c349d6da..15a47ef25a8b607c78d0b018c7591280cda44205 100644
--- a/Projects/AnalysisBase/package_filters.txt
+++ b/Projects/AnalysisBase/package_filters.txt
@@ -55,6 +55,7 @@
 + Generators/TruthUtils
 + InnerDetector/InDetRecTools/InDetTrackSelectionTool
 + InnerDetector/InDetRecTools/TrackVertexAssociationTool
++ InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool
 + MuonSpectrometer/MuonStationIndex
 + PhysicsAnalysis/Algorithms/.*
 + PhysicsAnalysis/AnalysisCommon/AssociationUtils
diff --git a/Projects/AthAnalysis/package_filters.txt b/Projects/AthAnalysis/package_filters.txt
index a4287407eb2104b09d9a966ead6cd92ee7371cf0..206a9134fde7b2f4bcabb0909969cd126cd06610 100644
--- a/Projects/AthAnalysis/package_filters.txt
+++ b/Projects/AthAnalysis/package_filters.txt
@@ -50,6 +50,7 @@
 + Generators/TruthUtils
 + InnerDetector/InDetRecTools/InDetTrackSelectionTool
 + InnerDetector/InDetRecTools/TrackVertexAssociationTool
++ InnerDetector/InDetRecTools/InDetSecVtxTruthMatchTool
 + MuonSpectrometer/MuonStationIndex
 - PhysicsAnalysis/Algorithms/StandaloneAnalysisAlgorithms
 + PhysicsAnalysis/Algorithms/.*