diff --git a/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIClusterPseudoJetGetter.h b/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIClusterPseudoJetGetter.h
deleted file mode 100644
index 7ec03231a96debe4b90b41e9c565b1ff4a942d68..0000000000000000000000000000000000000000
--- a/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIClusterPseudoJetGetter.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef HIJETREC_HICLUSTERPSEUDOJETGETTER_H
-#define HIJETREC_HICLUSTERPSEUDOJETGETTER_H
-////////////////////////////////////////////
-/// \class HIClusterPseudoJetGetter
-///
-/// Specialized PseudoJetGetter for HIClusters, handles neg E/ghosts in way needed for HI jets
-/// \author Aaron Angerami
-//////////////////////////////////////////////////
-
-#include "JetRec/PseudoJetGetter.h"
-
-
-class HIClusterPseudoJetGetter : public PseudoJetGetter {
-  ASG_TOOL_CLASS(HIClusterPseudoJetGetter, IPseudoJetGetter)
-public:
-  HIClusterPseudoJetGetter(const std::string &name);
-
-  // virtual int appendTo(PseudoJetVector& psjs, const LabelIndex* pli) const;
-
-};
-
-#endif
diff --git a/Reconstruction/HeavyIonRec/HIJetRec/Root/HIClusterPseudoJetGetter.cxx b/Reconstruction/HeavyIonRec/HIJetRec/Root/HIClusterPseudoJetGetter.cxx
deleted file mode 100644
index d832aabcfb524aef6ee985d1a7fcfa35caaf6a25..0000000000000000000000000000000000000000
--- a/Reconstruction/HeavyIonRec/HIJetRec/Root/HIClusterPseudoJetGetter.cxx
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "HIJetRec/HIClusterPseudoJetGetter.h"
-
-HIClusterPseudoJetGetter::HIClusterPseudoJetGetter(const std::string &name) : PseudoJetGetter(name)
-{
-
-}
-
-/*
-int HIClusterPseudoJetGetter::appendTo(PseudoJetVector& psjs, const LabelIndex* pli) const
-{
-  bool doGhosts=bool(m_ghostscale)&!m_negEnergyAsGhosts;
-  ATH_MSG_DEBUG("Entering appendTo(PseudoJetVector)...");
-
-  if ( evtStore()->contains<xAOD::IParticleContainer>(m_incoll) )
-  {
-    ATH_MSG_DEBUG("Retrieving xAOD container " << m_incoll << ", ghost scale="
-                  << m_ghostscale  <<  ", isGhost=" << doGhosts);
-    const xAOD::IParticleContainer* ppars = 0;
-    ppars = evtStore()->retrieve<const xAOD::IParticleContainer>(m_incoll);
-    if ( ppars != 0 )
-    {
-      //for now direct copy/paste of PseudoJetGetter::append method with local mods
-      //explicitly using IParticle instead of templated version
-      const xAOD::IParticleContainer& inputs=*ppars;
-      int nskip = 0;
-      jet::IConstituentUserInfo::Index labidx = 0;
-      if ( pli != 0 ) labidx = pli->index(m_label);
-      else ATH_MSG_WARNING("Index-to-label map is not supplied.");
-      if ( doGhosts ) labidx = -labidx;
-      ATH_MSG_DEBUG( "Ghost scale =  " << m_ghostscale << "; idx = " << labidx );
-
-      /// Loop over input, buid CUI and PseudoJets
-      for ( auto iinp=inputs.begin(); iinp!=inputs.end(); ++iinp )
-      {
-	auto ppar = *iinp; // IParticle pointer
-	if ( ppar == 0 || (m_skipNegativeEnergy && ppar->e() <= 0.0) )
-	{
-	  if ( ppar == 0 ) ATH_MSG_DEBUG("NUll object!");
-	  else ATH_MSG_VERBOSE("Skipping cluster with E = " << ppar->e());
-	  ++nskip;
-	  continue;
-	}
-	// Take momentum from IParticle.
-	fastjet::PseudoJet psj(ppar->p4());
-	// Form EM scale, use uncalibrated four-vector.
-	if ( m_emtopo )
-	{
-	  const xAOD::CaloCluster* pclu = dynamic_cast<const xAOD::CaloCluster*>(ppar);
-	  if ( pclu == 0 ) {
-	    ATH_MSG_WARNING("EM particle is not type CaloCluster");
-	    continue;
-	  }
-	  psj.reset(pclu->p4(xAOD::CaloCluster::UNCALIBRATED));
-	}
-	if(m_negEnergyAsGhosts)
-	{
-	  if(ppar->e() <=0.)
-	  {
-	    psj.reset_momentum(psj.px(), psj.py(), psj.pz(), std::abs(ppar->e()));
-	    psj*=m_ghostscale;
-	  }
-	}
-	else if ( doGhosts ) psj *= m_ghostscale;
-
-	bool show = psjs.size() < 20;
-	if ( show ) ATH_MSG_VERBOSE("index/label: " << labidx << "/" << m_label);
-	if ( show ) ATH_MSG_VERBOSE("old/p4/new"
-				    << " pt: "   << ppar->pt()  << "/" << ppar->p4().Pt()  << "/" << psj.pt()
-				    << ", pz: /"                       << ppar->p4().Pz()  << "/" << psj.pz()
-				    << ", p: /"                        << ppar->p4().P()   << "/"
-				    << ", E: "   << ppar->e()   << "/" << ppar->p4().E()   << "/" << psj.e()
-				    << ", m: "   << ppar->m()   << "/" << ppar->p4().M()   << "/" << psj.m()
-				    << ", eta: " << ppar->eta() << "/" << ppar->p4().Eta() << "/" << psj.eta()
-				    );
-	if ( pli != 0 )
-	{
-	  jet::IConstituentUserInfo* pcui = this->buildCUI(ppar, labidx, pli);
-	  psj.set_user_info(pcui);
-	  if ( show ) ATH_MSG_VERBOSE("User info particle: " << pcui->particle());
-	}
-	psjs.push_back(psj);
-      } // end loop over input
-      if ( nskip ) ATH_MSG_DEBUG("Skipped constituent count: " << nskip);
-      ATH_MSG_DEBUG("After append, PseudoJet count is " << psjs.size());
-      return 0;
-    }
-  }
-  ATH_MSG_ERROR("Unable to find input collection: " << m_incoll);
-  return 1;
-}
-*/
diff --git a/Reconstruction/HeavyIonRec/HIJetRec/python/HIJetRecTools.py b/Reconstruction/HeavyIonRec/HIJetRec/python/HIJetRecTools.py
index fbebcf188ea4d0ab78c074fd8594ae8d424889a5..89a8a323c15276b86a13648b56585dbb0eff606b 100644
--- a/Reconstruction/HeavyIonRec/HIJetRec/python/HIJetRecTools.py
+++ b/Reconstruction/HeavyIonRec/HIJetRec/python/HIJetRecTools.py
@@ -8,10 +8,10 @@ import AthenaCommon.SystemOfUnits as Units
 #configuring getter tools
 #selection for track jets
 from InDetTrackSelectionTool.InDetTrackSelectionToolConf import InDet__InDetTrackSelectionTool
-from JetRecTools.JetRecToolsConf import TrackPseudoJetGetter
 from JetRecTools.JetRecToolsConf import JetTrackSelectionTool
 from JetRecTools.JetRecToolsConf import SimpleJetTrackSelectionTool
 from JetRecTools.JetRecToolsConf import TrackVertexAssociationTool
+from JetRecTools.JetRecToolsConf import PseudoJetAlgorithm
 from JetMomentTools.JetMomentToolsConf import JetCaloQualityTool
 from JetMomentTools.JetMomentToolsConf import JetCaloCellQualityTool
 
@@ -41,7 +41,7 @@ if HIJetFlags.UseHITracks() :
                                   MaxLongitudinalDistance = 1.0e7,
                                   MaxZ0SinTheta = 1.5)
     #build PJ getter
-    jtm += TrackPseudoJetGetter("trackget_HI",
+    jtm += PseudoJetAlgorithm("trackget_HI",
                                 InputContainer = jtm.tracksel_HI.OutputContainer,
                                 Label = "Track",
                                 OutputContainer = "PseudoJetTracks_HI",
@@ -63,7 +63,7 @@ if HIJetFlags.UseHITracks() :
                                   Selector        = jtm.trk_gtracksel_HI)
 
 
-    jtm += TrackPseudoJetGetter("gtrackget_HI",
+    jtm += PseudoJetAlgorithm("gtrackget_HI",
                                 InputContainer = jtm.gtracksel_HI.OutputContainer,
                                 Label = "GhostTrack",
                                 OutputContainer = "PseudoJetGhostTracks_HI_ghost",
@@ -81,11 +81,9 @@ if HIJetFlags.UseHITracks() :
     jtm.trkmoms.lock()
 
 
-from JetRec.JetRecConf import PseudoJetGetter
 ClusterKey=HIJetFlags.HIClusterKey()
 
-from HIJetRec.HIJetRecConf import HIClusterPseudoJetGetter
-jtm += HIClusterPseudoJetGetter("get_HI",
+jtm += PseudoJetAlgorithm("get_HI",
                                 InputContainer = ClusterKey,
                                 Label = "LCTopo", #Label = "Tower",
                                 OutputContainer = "PseudoJet" + ClusterKey,
@@ -94,7 +92,7 @@ jtm += HIClusterPseudoJetGetter("get_HI",
                                 GhostScale = 1.e-20
                                 )
 
-jtm += PseudoJetGetter("gakt4trackget_HI",
+jtm += PseudoJetAlgorithm("gakt4trackget_HI",
                        InputContainer = HIJetFlags.TrackJetContainerName(),
                        Label = "Ghost" + HIJetFlags.TrackJetContainerName(),
                        SkipNegativeEnergy = True,
diff --git a/Reconstruction/HeavyIonRec/HIJetRec/src/components/HIJetRec_entries.cxx b/Reconstruction/HeavyIonRec/HIJetRec/src/components/HIJetRec_entries.cxx
index 13c26e6a2f9caa660fc8b755b53e7b6c8f940b5b..ac457b88e17794efd6b3fc80df057d6b3ac1e5a0 100644
--- a/Reconstruction/HeavyIonRec/HIJetRec/src/components/HIJetRec_entries.cxx
+++ b/Reconstruction/HeavyIonRec/HIJetRec/src/components/HIJetRec_entries.cxx
@@ -13,7 +13,6 @@
 #include "HIJetRec/HIJetDiscriminatorTool.h"
 #include "HIJetRec/HIJetSignificanceTool.h"
 #include "HIJetRec/HIUEModulatorTool.h"
-#include "HIJetRec/HIClusterPseudoJetGetter.h"
 
 #ifndef XAOD_ANALYSIS
 DECLARE_COMPONENT( HIClusterMaker )
@@ -31,5 +30,4 @@ DECLARE_COMPONENT( HIJetMaxOverMeanTool )
 DECLARE_COMPONENT( HIJetDiscriminatorTool )
 DECLARE_COMPONENT( HIJetSignificanceTool )
 DECLARE_COMPONENT( HIUEModulatorTool )
-DECLARE_COMPONENT( HIClusterPseudoJetGetter )
 
diff --git a/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetIsolationTool.h b/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetIsolationTool.h
index 0a55cf2178ae6246ecf38d8689a49bbf2e59fb78..c3855d1fc3a391f879c37d05504cb05a545adb1d 100644
--- a/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetIsolationTool.h
+++ b/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetIsolationTool.h
@@ -71,11 +71,10 @@
 ///////////////////////////////////////////////////////////////////////
 
 #include "AsgTools/AsgTool.h"
-#include "AsgTools/ToolHandle.h"
 #include "JetRec/JetModifierBase.h"
 #include "JetUtils/TiledEtaPhiMap.h"
-#include "JetInterface/IPseudoJetGetter.h"
 #include "fastjet/PseudoJet.hh"
+#include "JetRec/PseudoJetContainer.h"
 #include "JetEDM/IConstituentUserInfo.h"
 
 namespace jet {
@@ -145,7 +144,7 @@ public:
 private: 
 
   std::vector<std::string> m_isolationCodes;
-  ToolHandle<IPseudoJetGetter> m_hpjg;
+  SG::ReadHandleKey<PseudoJetContainer> m_pjsin{this, "PseudoJetsIn", "", "PseudoJetContainer to read"};
 
   /// the list of isolation calculation objects (they are actually used
   /// only as template objects from which the actual calculators are build
diff --git a/Reconstruction/Jet/JetMomentTools/src/JetIsolationTool.cxx b/Reconstruction/Jet/JetMomentTools/src/JetIsolationTool.cxx
index 10dd27ba4ccd9bd7f37d796e6a034cf350ea7712..71f805d17f0599cb2c0c5d3e1f8a49de1fb8e15b 100644
--- a/Reconstruction/Jet/JetMomentTools/src/JetIsolationTool.cxx
+++ b/Reconstruction/Jet/JetMomentTools/src/JetIsolationTool.cxx
@@ -7,7 +7,6 @@
 #include "JetMomentTools/JetIsolationTool.h"
 #include "xAODCaloEvent/CaloCluster.h"
 #include "JetUtils/JetDistances.h"
-#include "JetRec/PseudoJetGetterRegistry.h"
 #include <sstream>
 
 using std::string;
@@ -236,9 +235,8 @@ using namespace jet::JetIsolation;
 //**********************************************************************
 
 JetIsolationTool::JetIsolationTool(const string& name) 
-: JetModifierBase(name), m_hpjg("") {
+: JetModifierBase(name) {
   declareProperty( "IsolationCalculations", m_isolationCodes);
-  declareProperty("PseudoJetGetter", m_hpjg);
 }
 
 //**********************************************************************
@@ -282,10 +280,12 @@ StatusCode JetIsolationTool::initialize() {
   }
 
   ATH_MSG_INFO("Initialized JetIsolationTool " << name());
-  if ( m_hpjg.empty() ) {
-    ATH_MSG_INFO("  Pseudojet getter will found using JetInput");
+  if ( m_pjsin.empty() ) {
+    ATH_MSG_ERROR("  No input pseudojet collection supplied");
+    return StatusCode::FAILURE;
   } else {
-    ATH_MSG_INFO("  Pseudojet getter: " << m_hpjg->name());
+    ATH_MSG_INFO("  Input pseudojet collection: " << m_pjsin.key());
+    ATH_CHECK(m_pjsin.initialize());
   }
   ATH_MSG_INFO("  Isolation calculations: " << m_isolationCodes);
 
@@ -299,33 +299,9 @@ StatusCode JetIsolationTool::modify(xAOD::JetContainer& jets) const {
   ATH_MSG_DEBUG("Modifying jets in container with size " << jets.size());
   if ( jets.empty() ) return StatusCode::SUCCESS;
 
-  // Find the pseudojet getter.
-  // If one is not supplied, the InputType field for the first jet is used
-  // to locate the appropriate tool.
-  const IPseudoJetGetter* ppjg = nullptr;
-  int iinp = -1;
-  if ( m_hpjg.empty() ) {
-    iinp = jets[0]->getAttribute<int>("InputType");
-    auto iiinp = static_cast<xAOD::JetInput::Type>(iinp);
-    string sinp = xAOD::JetInput::typeName(iiinp);
-    ATH_MSG_DEBUG("Jet input type is " << sinp);
-    ppjg = PseudoJetGetterRegistry::find(sinp);
-    if ( ppjg == nullptr ) {
-      ATH_MSG_WARNING("Unable to retrieve pseudojet getter for input index/name "
-                      << iinp << "/" << sinp);
-      return StatusCode::FAILURE;
-    }
-    ATH_MSG_DEBUG("Found pseudojet getter " << ppjg->name());
-  } else {
-    ppjg = &*m_hpjg;
-  }
-  if ( ppjg == nullptr ) {
-    ATH_MSG_WARNING("Unable to retrieve pseudojet getter.");
-    return StatusCode::FAILURE;
-  }
-    
   // Fetch the input pseudojets.
-  const PseudoJetVector* inputConstits = ppjg->get();
+  auto pjsin = SG::makeHandle(m_pjsin);
+  const PseudoJetContainer* inputConstits = pjsin.get();
   ATH_MSG_DEBUG("Retrieved input count is " << inputConstits->size());
 
   // adapt the calculators to these jets (radius, input type, etc...)
@@ -341,11 +317,10 @@ StatusCode JetIsolationTool::modify(xAOD::JetContainer& jets) const {
   for ( xAOD::Jet* pjet : jets ) {
 
     // Check this jet has the same inputs.
-    int jinp = pjet->getAttribute<int>("InputType");
-    if ( m_hpjg.empty() && jinp != iinp ) {
-      ATH_MSG_WARNING("Jets have inconsistent inputs: " << iinp << " and " << jinp);
-      continue;
-    }
+    // int jinp = pjet->getAttribute<int>("InputType");
+    // This needs to be reimplemented when we decide how to better
+    // encode this information -- right now this can't be matched
+    // to the input PseudoJetContainer
 
     // Create jet position.
     jet::ParticlePosition jetPos(pjet);
@@ -358,7 +333,7 @@ StatusCode JetIsolationTool::modify(xAOD::JetContainer& jets) const {
 
     ATH_MSG_VERBOSE("Jet eta=" << jetPos.x() << ", phi=" << jetPos.y());
     for ( unsigned int ippj=0; ippj<inputConstits->size(); ++ippj ) {
-      const PseudoJet* ppj = &(inputConstits->at(ippj));
+      const PseudoJet* ppj = &(inputConstits->casVectorPseudoJet()->at(ippj));
       const xAOD::IParticle* ppar = nullptr;
       string label = "none";
       if ( ppj->has_user_info<jet::IConstituentUserInfo>() ) {
diff --git a/Reconstruction/Jet/JetRec/JetRec/JetRecDict.h b/Reconstruction/Jet/JetRec/JetRec/JetRecDict.h
index 8f11b692ae839ddc1ab7ee36dfc9ee5e85e138af..ca7763e79c998f70df282baf189ff8387f198552 100644
--- a/Reconstruction/Jet/JetRec/JetRec/JetRecDict.h
+++ b/Reconstruction/Jet/JetRec/JetRec/JetRecDict.h
@@ -23,9 +23,6 @@
 #include "JetRec/JetSplitter.h"
 #include "JetRec/JetToolRunner.h"
 #include "JetRec/JetTrimmer.h"
-#include "JetRec/MuonSegmentPseudoJetGetter.h"
-#include "JetRec/PseudoJetGetter.h"
-#include "JetRec/PseudoJetGetterRegistry.h"
 
 
 #endif
diff --git a/Reconstruction/Jet/JetRec/JetRec/MuonSegmentPseudoJetGetter.h b/Reconstruction/Jet/JetRec/JetRec/MuonSegmentPseudoJetGetter.h
deleted file mode 100644
index 4e19d91c993de1b10c0dcdf91523e7ca61e0f89f..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRec/JetRec/MuonSegmentPseudoJetGetter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// MuonSegmentPseudoJetGetter.h
-
-#ifndef MuonSegmentPseudoJetGetter_H
-#define MuonSegmentPseudoJetGetter_H
-
-// David Adams
-// January 2014
-
-/// MuonSegmentPseudoJetGetter is a dual-use tool to retrieve and build the pseudojet
-/// inputs from muon segments.
-///
-/// Tool Properties:
-///  - InputCollection: Name of the input collection.
-///  - OutputCollection: Name of the output collection of pseudojets.
-///  - Label: Label for the constituents. See note below.
-///  - SkipNegativeEnergy: Flag indicating that inputs with negative energy
-/// should be ignored.
-///  - Pt : The pT set on the MS ghosts
-
-#include "AsgTools/AsgTool.h"
-#include "JetInterface/IPseudoJetGetter.h"
-#include "fastjet/PseudoJet.hh"
-#include "xAODMuon/MuonSegmentContainer.h"
-#include "JetEDM/PseudoJetVector.h"
-#include "JetRec/PseudoJetContainer.h"
-
-
-class MuonSegmentPseudoJetGetter
-:  public asg::AsgTool,
-  virtual public IPseudoJetGetter {
-  ASG_TOOL_CLASS(MuonSegmentPseudoJetGetter, IPseudoJetGetter)
-
-public:
-
-  typedef jet::PseudoJetVector PseudoJetVector;
-
-  /// Constructor from tool name.
-  MuonSegmentPseudoJetGetter(const std::string& myname);
-
-  /// Initialization.
-  /// Can be skipped.
-  virtual StatusCode initialize();
-
-  /// Method to construct the PseudoJetVector and record in StoreGate
-  StatusCode createAndRecord() const;
-
-  /// Returns the pseudojet collection.
-  /// If already existing, the collection in the event store is returned.
-  /// If not, an new collection is created and filled by calling @c appendTo.
-  /// Returns null if the collection cannot be created.
-  const PseudoJetContainer* getC() const;
-
-  /// Return the label for these pseudojets.
-  std::string label() const;
-
-  /// Dump to properties to the log.
-  void print() const;
-
-protected:  //data
-
-  // Job options.
-  SG::ReadHandleKey<xAOD::MuonSegmentContainer> m_incoll;        /// Input collection name.
-  SG::WriteHandleKey<PseudoJetContainer> m_outcoll;      /// Output collection name.
-
-  std::string m_label;              /// Label for the collection.
-  double m_pt;                      /// PT assiged to the pseudojets.
-
-
- private:
-  std::vector<fastjet::PseudoJet> 
-    createPseudoJets(const xAOD::MuonSegmentContainer*) const; 
-
-};
-
-#endif
diff --git a/Reconstruction/Jet/JetRec/JetRec/PseudoJetAlgorithm.h b/Reconstruction/Jet/JetRec/JetRec/PseudoJetAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..9eb80acde4f98b6cf2991fec1fb2a9387a3bb1ef
--- /dev/null
+++ b/Reconstruction/Jet/JetRec/JetRec/PseudoJetAlgorithm.h
@@ -0,0 +1,84 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+// PseudoJetAlgorithm.h 
+
+/// PseudoJetAlgorithm retrieves and builds the pseudojet inputs used in jet finding
+///
+/// Alg Properties:
+///  - InputCollection: Name of the input collection.
+///  - OutputCollection: Name of the output collection of pseudojets.
+///  - Label: Label for the constituents. See note below.
+///  - SkipNegativeEnergy: Flag indicating that inputs with negative energy
+/// should be ignored.
+///  - GhostScale : If nonzero, the pseudojets are labeled as ghosts and
+/// their four-momenta are scaled by this factor.
+///
+/// Note: The label is attached to the CUI (constituent user info) associated with
+/// created pseudojet and is used to name jet moments that point to the PJs,
+/// and in rare cases (EMTopo, PFlow) to toggle special treatments.
+
+#ifndef PseudoJetAlgorithm_H
+#define PseudoJetAlgorithm_H
+
+#include <memory>
+#include "fastjet/PseudoJet.hh"
+#include "JetRec/PseudoJetContainer.h"
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+
+class PseudoJetAlgorithm : public AthReentrantAlgorithm { 
+
+public: 
+
+  // No need for a specialised constructor
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
+
+  /// Athena algorithm's Hooks
+  virtual StatusCode  initialize() override;
+  virtual StatusCode  finalize() override {};
+
+  // Standard execute, forwards to createAndRecord
+  virtual StatusCode  execute(const EventContext& ctx) const override final;
+
+private: 
+
+  /// Method to construct the PseudoJetContainer and record in StoreGate
+  virtual std::unique_ptr<PseudoJetContainer> createPJContainer(const xAOD::IParticleContainer& cont) const;
+
+  /// Dump to properties to the log.
+  virtual void print() const;
+
+  std::vector<fastjet::PseudoJet> 
+  createPseudoJets(const xAOD::IParticleContainer* ) const;
+
+private:
+
+  /// Input collection name.
+  SG::ReadHandleKey<xAOD::IParticleContainer> m_incoll{"InputContainer", "", "The input IParticleContainer name"};
+
+  /// Output collection name.
+  SG::WriteHandleKey<PseudoJetContainer> m_outcoll{"OutputContainer", "", "The output PseudoJetContainer name"};
+
+  /// Label for the collection.
+  Gaudi::Property<std::string> m_label{"Label", "", "String label identifying the pseudojet type"};
+
+  /// Flag indicating to skip objects with E<0.
+  Gaudi::Property<bool> m_skipNegativeEnergy{"SkipNegativeEnergy", false, "Whether to skip negative energy inputs"};
+
+  /// Ghost scale factor.
+  Gaudi::Property<double> m_ghostscale{"GhostScale", 0.0, "Scale factor to convert PJs into ghosts that don't affect jet kinematics"};
+
+  /// Flag indicating to treat objects with E<0 as ghosts  (useful for HI)
+  Gaudi::Property<bool> m_negEnergyAsGhosts{"TreatNegativeEnergyAsGhost", false, "Whether to convert negative energy inputs into ghosts"};
+
+  /// Internal steering flags
+  /// Set in initialize()
+  bool m_isGhost{false}; /// Determinines whether the PJs should be made ghosts
+  bool m_emtopo;         /// True if inputs are EM-scale topo clusters.
+  bool m_pflow;          /// True if inputs are PFlow
+
+}; 
+
+#endif
diff --git a/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetter.h b/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetter.h
index fd4fd02d6af6f6a9f6c0c21890dc2d126f9adaf4..eebbc0592fb27c0bb2f328b90f7ec180b4ef7d86 100644
--- a/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetter.h
+++ b/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetter.h
@@ -1,130 +1,166 @@
-// this file is -*- C++ -*-
-
 /*
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
-// PseudoJetGetter.h
-
-#ifndef PseudoJetGetter_H
-#define PseudoJetGetter_H
+/// Implementations of concrete input-to-PseudoJet conversions
+/// Separated from PseudoJetAlgorithm for readability
+///
+/// IParticle is the generic type that is normally assumed.
+/// Special treatment is needed for two cases:
+///   * EMTopo clusters will be converted at the uncalibrated
+///     cluster scale -- this is mostly obsolete in offline reco
+///     but used by trigger for the moment
+///   * ParticleFlowObjects that are charged will be filtered
+///     out if they are not matched to the primary vertex
 
-// David Adams
-// January 2014
+#ifndef PSEUDOJETGETTER_H
+#define PSEUDOJETGETTER_H
 
-/// PseudoJetGetter is a dual-use tool to retrieve and build the pseudojet
-/// inputs used in jet finding.
-///
-/// Tool Properties:
-///  - InputCollection: Name of the input collection.
-///  - OutputCollection: Name of the output collection of pseudojets.
-///  - Label: Label for the constituents. See note below.
-///  - SkipNegativeEnergy: Flag indicating that inputs with negative energy
-/// should be ignored.
-///  - GhostScale : If nonzero, the pseudojets are labeled as ghosts and
-/// their four-momenta are scaled by this factor.
-///
-/// Note: The label is attached to the CUI (constituent user info) associated with
-/// created pseudojet and should be unique for each set of pseuodjets used as input
-/// for finding a particular collection of jets.
-///
-/// The label for a primary pseudojet getter (the first in the vector presented
-/// to JetRecTool) is used to deduce the input type and must be one of the
-/// following: LCTopo, EMTopo, TopoTower, Tower, Truth, Track, PFlow.
-/// Names beginning with "EM" are assumed to correspond to uncalibrated clusters.
-
-#include "AsgTools/AsgTool.h"
-#include "JetRec/PseudoJetContainer.h"
-#include "JetInterface/IPseudoJetGetter.h"
 #include "fastjet/PseudoJet.hh"
-#include "JetEDM/PseudoJetVector.h"
+#include "xAODBase/IParticle.h"
 
+#ifndef GENERATIONBASE
+#include "xAODCaloEvent/CaloCluster.h"
+#include "xAODPFlow/PFO.h"
+#endif
 
-class PseudoJetGetter
-:  public asg::AsgTool,
-  virtual public IPseudoJetGetter {
-  ASG_TOOL_CLASS(PseudoJetGetter, IPseudoJetGetter)
+namespace PseudoJetGetter {
 
-public:
+  struct IParticleRejecter{
+    bool null{false};
+    bool negativeE{false};
+    bool skipNegativeEnergy{false};
+  
+    IParticleRejecter(bool skip): skipNegativeEnergy(skip){
+    }
 
-  typedef jet::PseudoJetVector PseudoJetVector;
+    bool operator()(const xAOD::IParticle* ip) {
+      null = (ip == 0);
+      negativeE = skipNegativeEnergy && ip->e() <= 0.0;
+      return (null || negativeE);
+    }
+  };
 
-  /// Constructor from tool name.
-  PseudoJetGetter(const std::string& myname);
 
-  /// Initialization.
-  /// Can be skipped.
-  virtual StatusCode initialize() override;
+  std::vector<fastjet::PseudoJet> 
+  IParticlesToPJs(const xAOD::IParticleContainer& ips, bool skipNegativeEnergy) {
 
-  /// Method to construct the PseudoJetVector and record in StoreGate
-  virtual StatusCode createAndRecord() const override;
+    IParticleRejecter rejecter(skipNegativeEnergy);
 
-  // Kept for backward compatibity
-  virtual const PseudoJetVector* get() const override;
+    std::vector<fastjet::PseudoJet> vpj;
+    int index = -1;
 
-  /// Return the label for these pseudojets.
-  virtual std::string label() const override;
+    // loop over the input iparticles, select and  convert to pseudojets
+    for(const xAOD::IParticle* ip: ips) {
+      ++index;
+      if(rejecter(ip)){continue;}
+    
+      // Create a Pseudojet with the momentum of the selected IParticles.
+      fastjet::PseudoJet psj(ip->p4());
 
-  /// Dump to properties to the log.
-  virtual void print() const override;
+      // user index is used to identify the xAOD object used for the PseudoJet
+      psj.set_user_index(index); 
+      vpj.push_back(psj);
 
-  /// Method to return the list of input containers.
-  /// The names of required input containers are appended to connames.
-  /// Returns nonzero for error.
-  /// Default returns 0 and adds no names.
-  virtual int inputContainerNames(std::vector<std::string>& connames) override;
+    }
+    return vpj;
+  }
 
-  /// Method to return the list of output containers.
-  /// The names of produced output containers are appended to connames.
-  /// Returns nonzero for error.
-  /// Default returns 0 and adds no names.
-  virtual int outputContainerNames(std::vector<std::string>& connames) override;
+  //**********************************************************************
 
-protected:  // data
+#ifndef GENERATIONBASE
 
-  // Job options.
+  struct EMTopoRejecter{
+    const xAOD::CaloCluster* cluster{0};
 
-  /// Input collection name.
-  SG::ReadHandleKey<xAOD::IParticleContainer> m_incoll;        
+    bool operator()(const xAOD::IParticle* ip){
+      cluster = dynamic_cast<const xAOD::CaloCluster*>(ip);
+      return cluster == 0;  // reject if not a cluster
+    }
+  };
 
-  /// Output collection name.
-  SG::WriteHandleKey<PseudoJetContainer> m_outcoll;      
+  std::vector<fastjet::PseudoJet> 
+  EMToposToPJs(const xAOD::IParticleContainer& ips, bool skipNegativeEnergy) {
 
-  /// Label for the collection.
-  std::string m_label;
+    // helper objects for selecting iparticles to be converted to pseudojets
+    IParticleRejecter ipRejecter(skipNegativeEnergy);
+    EMTopoRejecter emRejecter;
+  
+    std::vector<fastjet::PseudoJet> vpj;
+    int index = -1;
+
+    // loop over iparticles, select and  convert to pseudojets
+
+    for(const xAOD::IParticle* ip: ips) {
+      ++index;
+      if(ipRejecter(ip) or emRejecter(ip)){continue;}
+    
+      // Create a Pseudojet with the momentum of the cluster.
+      fastjet::PseudoJet 
+	psj(emRejecter.cluster->p4(xAOD::CaloCluster::UNCALIBRATED));
+    
+      // user index is used to identify the xAOD object used for the PseudoJet
+      psj.set_user_index(index); 
+      vpj.push_back(psj);
+    }
+    return vpj;
+  }
+
+  //**********************************************************************
+
+  struct PFlowRejecter{
+
+    bool skipNegativeEnergy{false};
+  
+    PFlowRejecter(bool skip): skipNegativeEnergy(skip){
+    }
+
+    bool operator()(const xAOD::IParticle* ip){
+    
+      const xAOD::PFO* pfo = dynamic_cast<const xAOD::PFO*>(ip);
+    
+      // keep charged PFOs with energy==0 because for MET TST with PFlow, 
+      // there may be high pt 
+      // charged PFOs that receive a weight of 0 due to being in dense 
+      // showers, but need to be present for overlap removal, because they 
+      // don't retain these weights when added to the TST      
+
+      if( pfo->isCharged() ) {
+	    const static SG::AuxElement::ConstAccessor<char> 
+	    PVMatchedAcc("matchedToPV");
+	    return  !PVMatchedAcc(*pfo);
+      }
+    
+      return skipNegativeEnergy && pfo->e()<FLT_MIN;
+    }
+  };
 
-  /// Flag indicating to skip objects with E<0.
-  bool m_skipNegativeEnergy;
 
-  /// Ghost scale factor.
-  double m_ghostscale;
+  std::vector<fastjet::PseudoJet> 
+  PFlowsToPJs(const xAOD::IParticleContainer& ips, bool skipNegativeEnergy) {
 
-  /// Flag indicating to treat objects with E<0 as ghosts  (useful for HI)
-  bool m_negEnergyAsGhosts;
+    PFlowRejecter rejecter(skipNegativeEnergy);
+    std::vector<fastjet::PseudoJet> vpj;
+    int index = -1;
 
-  bool m_emtopo;        /// True if inputs are EM-scale topo clusters.
-  bool m_pflow;         /// True if inputs are PFlow
+    // loop over the input iparticles, select and  convert to pseudojets
 
-private:
+    for(const xAOD::IParticle* ip: ips) {
+      ++index;
+      if(rejecter(ip)){continue;}
+    
+      // Create a PSeudojet with the momentum of the selected IParticles.
+      fastjet::PseudoJet psj(ip->p4());
 
-  /// Returns the pseudojet collection.
-  /// If it already exists, the collection in the event store is returned.
-  /// If not, an new collection is created and filled by calling @c appendTo.
-  /// Returns null if the collection cannot be created.
-  const PseudoJetContainer* getC() const;
+      // user index is used to identify the xAOD object used for the PSeudoJet
+      psj.set_user_index(index);
 
+      vpj.push_back(psj);
+    }
+    return vpj;
+  }
+#endif
 
-  std::vector<fastjet::PseudoJet> 
-  createPseudoJets(const xAOD::IParticleContainer* ) const;
+}
 
-  std::vector<fastjet::PseudoJet> 
-  IParticlesToPJs(const xAOD::IParticleContainer*) const;
-  
-  std::vector<fastjet::PseudoJet> 
-  EMToposToPJs(const xAOD::IParticleContainer*) const;
-#ifndef GENERATIONBASE
-  std::vector<fastjet::PseudoJet>
-  PFlowsToPJs(const xAOD::IParticleContainer*) const;
-#endif
-};
 #endif
diff --git a/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetterRegistry.h b/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetterRegistry.h
deleted file mode 100644
index b3b359d1a1e5dd35956231c31d9bf319e92a0d1e..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRec/JetRec/PseudoJetGetterRegistry.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// PseudoJetGetterRegistry.h
-
-#ifndef PseudoJetGetterRegistry_H
-#define PseudoJetGetterRegistry_H
-
-// David Adams
-// February 2015
-//
-// Class to hold pseudojet getters indexed by label.
-// Each pseudojet getter is expected to register itself here.
-// JetIsolationtool uses this to find the appropriate getter
-// for a given jet.
-
-#include <string>
-#include <map>
-#include "JetInterface/IPseudoJetGetter.h"
-
-class PseudoJetGetterRegistry {
-
-public:
-
-  typedef std::string Label;
-  typedef std::map<std::string, const IPseudoJetGetter*> Map;
-
-  // Add a getter.
-  // Overwrites existing value.
-  // Returns 0 for success.
-  static int add(Label lab, const IPseudoJetGetter* ptool);
-  static int add(const IPseudoJetGetter* ptool);
-
-  // Return if a getter is registered.
-  static bool has(Label lab);
-
-  // Return the getter.
-  static const IPseudoJetGetter* find(Label lab);
-
-private:
-
-  static Map m_map;
-
-};
-  
-#endif
diff --git a/Reconstruction/Jet/JetRec/Root/MuonSegmentPseudoJetGetter.cxx b/Reconstruction/Jet/JetRec/Root/MuonSegmentPseudoJetGetter.cxx
deleted file mode 100644
index 9b2960c589a925be79db9ac38c7012d558015368..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRec/Root/MuonSegmentPseudoJetGetter.cxx
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// MuonSegmentPseudoJetGetter.cxx
-
-#include "JetRec/MuonSegmentPseudoJetGetter.h"
-#ifdef USE_BOOST_AUTO
-#include <boost/typeof/typeof.hpp>
-#endif
-#include "JetEDM/PseudoJetVector.h"
-#include "JetEDM/IndexedTConstituentUserInfo.h"
-
-#include "JetRec/PseudoJetContainer.h"
-#include "JetRec/MuonSegmentExtractor.h"
-#include "JetRec/PseudoJetContainer.h"
-
-using std::string;
-using jet::PseudoJetVector;
-using fastjet::PseudoJet;
-
-//**********************************************************************
-
-MuonSegmentPseudoJetGetter::MuonSegmentPseudoJetGetter(const std::string& name)
-: AsgTool(name) {
-  declareProperty("InputContainer", m_incoll);
-  declareProperty("OutputContainer", m_outcoll);
-  declareProperty("Label", m_label);
-  declareProperty("Pt", m_pt =1.e-10);
-}
-
-//**********************************************************************
-
-StatusCode MuonSegmentPseudoJetGetter::initialize() {
-  ATH_MSG_DEBUG("Initializing...");
-  print();
-
-  ATH_CHECK( m_incoll.initialize() );
-  ATH_CHECK( m_outcoll.initialize() );
-
-  return StatusCode::SUCCESS;
-}
-
-//**********************************************************************
-
-StatusCode MuonSegmentPseudoJetGetter::createAndRecord() const {
-  // Use const pointer for now, but can change to unique pointer when
-  // we move to DataVector and when MR 2431 is complete:
-  // https://gitlab.cern.ch/atlas/athena/merge_requests/2431
-
-  // should rename getC createAndRecord once get() is removed.
-
-  const PseudoJetContainer* pjc = this->getC();
-  if(!pjc) return StatusCode::FAILURE; 
-
-  return StatusCode::SUCCESS;
-}
-
-//**********************************************************************
-
-const PseudoJetContainer* MuonSegmentPseudoJetGetter::getC() const {
-  ATH_MSG_DEBUG("Getting MuonSegmentPseudoJetContainer...");
-  const PseudoJetContainer * pjcont;
-
-  // build and record the container
-  const xAOD::MuonSegmentContainer* cont;
-  auto handle_in = SG::makeHandle(m_incoll);
-  if ( handle_in.isValid() ) {
-    ATH_MSG_DEBUG("Retrieving xAOD container " << m_incoll.key() );
-    // retrieve the input.
-    cont = handle_in.cptr();
-  } else {
-    ATH_MSG_ERROR("Unable to find input collection: " << m_incoll.key());
-    ATH_MSG_ERROR("Error creating pseudojets.");
-    return nullptr;
-  }
-
-  std::vector<PseudoJet> vpj = createPseudoJets(cont);
-    
-  // create an extractor (MuonSegmentExtractors are always ghost extractors)
-  MuonSegmentExtractor* extractor = new MuonSegmentExtractor(cont, m_label);
-
-  // Put the PseudoJetContainer together :
-  pjcont = new PseudoJetContainer(extractor, vpj);
-  std::unique_ptr<const PseudoJetContainer> pjcont_ptr(pjcont);
-  
-  // record
-  SG::WriteHandle<PseudoJetContainer> handle_out(m_outcoll);
-  //ATH_MSG_DEBUG("New PseudoJetContainer in event store with extractor: " 
-  //              << extractor->toString(0));
-
-  // notify
-  if ( ! handle_out.put(std::move(pjcont_ptr))) {
-    ATH_MSG_ERROR("Unable to write new PseudoJetContainer to event store: " 
-                  << m_outcoll.key());
-  } else {
-    ATH_MSG_DEBUG("Created new PseudoJetContainer in event store: " 
-                  << m_outcoll.key());
-  }
-
-  return pjcont;
-}
-
-
-std::vector<PseudoJet> 
-MuonSegmentPseudoJetGetter::createPseudoJets(const xAOD::MuonSegmentContainer* ms) const {
-  
-  std::vector<PseudoJet> vpj;
-  int index=0;
-  for(const xAOD::MuonSegment* part: *ms) {
-    double pt = m_pt;
-    double x = part->x();
-    double y = part->y();
-    double z = part->z();
-    double xy = sqrt(x*x + y*y);
-    double r = sqrt(xy*xy + z*z);
-    double pfac = pt/xy;
-    double px = pfac*x;
-    double py = pfac*y;
-    double pz = pfac*z;
-    double  e = pfac*r;
-    fastjet::PseudoJet psj(px, py, pz, e);
-    ATH_MSG_VERBOSE("Muon segment pseuojet y: " << psj.rap());
-    vpj.push_back(psj);
-    //vpj.push_back( PseudoJet(part->px(),part->py(),part->pz(),part->t0()) );
-    vpj.back().set_user_index(index); // Set the index !!
-    index++;
-  }
-
-  return vpj;
-}
-  
-//**********************************************************************
-
-std::string MuonSegmentPseudoJetGetter::label() const{
-  return m_label;
-}
-
-//**********************************************************************
-
-void MuonSegmentPseudoJetGetter::print() const {
-  ATH_MSG_INFO("Properties for PseudoJetGetter " << name());
-  ATH_MSG_INFO("             Label: " << m_label);
-  ATH_MSG_INFO("   Input container: " << m_incoll.key());
-  ATH_MSG_INFO("  Output container: " << m_outcoll.key());
-  ATH_MSG_INFO("      Pseudojet pT: " << m_pt);
-
-}
-
-//**********************************************************************
diff --git a/Reconstruction/Jet/JetRec/Root/PseudoJetGetter.cxx b/Reconstruction/Jet/JetRec/Root/PseudoJetGetter.cxx
deleted file mode 100644
index db1135f9e95e8af82ed932146a454efb7ab8111a..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRec/Root/PseudoJetGetter.cxx
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-// PseudoJetGetter.cxx
-
-#include "JetRec/PseudoJetGetter.h"
-#include "fastjet/PseudoJet.hh"
-#include "JetRec/PseudoJetContainer.h"
-#include "JetEDM/PseudoJetVector.h"
-
-#include "xAODBase/IParticleContainer.h"
-#include "JetRec/IParticleExtractor.h"
-#include "xAODCaloEvent/CaloClusterContainer.h"
-#ifndef GENERATIONBASE
-#include "xAODPFlow/PFOContainer.h"
-#endif
-
-using std::string;
-using jet::PseudoJetVector;
-using fastjet::PseudoJet;
-
-//**********************************************************************
-
-PseudoJetGetter::PseudoJetGetter(const std::string& name)
-  : AsgTool(name), m_emtopo(false), m_pflow(false) {
-  declareProperty("InputContainer", m_incoll);
-  declareProperty("OutputContainer", m_outcoll);
-  declareProperty("Label", m_label);
-  declareProperty("SkipNegativeEnergy", m_skipNegativeEnergy =false);
-  declareProperty("GhostScale", m_ghostscale =0.0);
-  declareProperty("TreatNegativeEnergyAsGhost", m_negEnergyAsGhosts =false);
-
-}
-
-//**********************************************************************
-
-StatusCode PseudoJetGetter::initialize() {
-  ATH_MSG_DEBUG("Initializing...");
-  // PJG needs to know if this is the basic EMTopo cluster collection
-  // in order to change the cluster signal state.
-  if ( m_label == "EMTopo") m_emtopo = true;
-  if ( m_label == "EMPFlow") m_pflow = true;
-  if ( m_label == "EMNPFlow") m_pflow = true;
-  print();
-
-  ATH_CHECK( m_incoll.initialize() );
-  ATH_CHECK( m_outcoll.initialize() );
-
-  return StatusCode::SUCCESS;
-}
-
-//**********************************************************************
-
-StatusCode PseudoJetGetter::createAndRecord() const {
-  // Use const pointer for now, but can change to unique pointer when
-  // we move to DataVector and when MR 2431 is complete:
-  // https://gitlab.cern.ch/atlas/athena/merge_requests/2431
-
-  // should rename getC createAndRecord once get() is removed.
-  const PseudoJetContainer* pjc = this->getC();
-  if (!pjc) return StatusCode::FAILURE;
-
-  return StatusCode::SUCCESS;
-}
-//**********************************************************************
-const PseudoJetVector* PseudoJetGetter::get() const {
-  // Kept for backward compatibity
-  ATH_MSG_DEBUG("Getting PseudoJetContainer as PseudoJetVector ...");
-  const PseudoJetContainer* cont = this->getC();
-  const PseudoJetVector* vpj = cont->casVectorPseudoJet(); 
-  return vpj;
-}
-
-//**********************************************************************
-
-const PseudoJetContainer* PseudoJetGetter::getC() const {
-  ATH_MSG_DEBUG("Getting PseudoJetContainer...");
-  // build and record the container
-  const xAOD::IParticleContainer* cont;
-  auto handle_in = SG::makeHandle(m_incoll);
-  if ( handle_in.isValid() ) {
-    cont = handle_in.cptr();
-    ATH_MSG_DEBUG("Retrieving xAOD container " << m_incoll.key() << "of size "<<cont->size()
-                  << ", ghost scale=" << m_ghostscale  
-                  <<  ", isGhost=" << bool(m_ghostscale));
-
-
-  } else {
-    ATH_MSG_ERROR("Unable to find input collection: " << m_incoll.key());
-    ATH_MSG_ERROR("Error creating pseudojets.");
-    return nullptr;
-  }
-
-  // create PseudoJets
-  std::vector<PseudoJet> vpj = createPseudoJets(cont);
-
-  // create an extractor
-
-  // "Ghost" in outout collection name? If so is a ghost collection.
-  bool isGhost = (m_outcoll.key()).find("Ghost") != std::string::npos;
-
-  IParticleExtractor* extractor = new IParticleExtractor(cont,
-                                                         m_label,
-                                                         isGhost);
-  ATH_MSG_DEBUG("New  extractor: "  << extractor->toString(0));
-  
-  // ghostify the pseudojets if necessary
-  if(isGhost){
-    for(PseudoJet& pj : vpj) {pj *= 1e-40;}
-  }
-  
-  // Put the PseudoJetContainer together :
-  std::unique_ptr<const PseudoJetContainer> uppjcont(new PseudoJetContainer(extractor, vpj));
-
-  // record
-  
-  SG::WriteHandle<PseudoJetContainer> handle_out(m_outcoll);
-
-
-  ATH_MSG_DEBUG("New PseudoJetContainer size " << uppjcont->size());
-  // notify
-  const PseudoJetContainer* ppjcont = handle_out.put(std::move(uppjcont));
-  if (!ppjcont) {
-    ATH_MSG_ERROR("Unable to write new PseudoJetContainer to event store: " 
-                  << m_outcoll.key());
-  } else {
-    ATH_MSG_DEBUG("Created new PseudoJetContainer in event store: " 
-                  << m_outcoll.key());
-  }
-
-  return ppjcont;  // used by legacy code, looks wrong....
-}
-
-
-std::vector<PseudoJet> 
-PseudoJetGetter::createPseudoJets(const xAOD::IParticleContainer* ips) const{
-#ifndef GENERATIONBASE
-  if (m_pflow) {return PFlowsToPJs(ips);}
-#endif
-  if (m_emtopo) {return EMToposToPJs(ips);}
-  return IParticlesToPJs(ips);
-}
-
-struct IParticleRejecter{
-  bool null{false};
-  bool negativeE{false};
-  bool skipNegativeEnergy{false};
-  
-  IParticleRejecter(bool skip): skipNegativeEnergy(skip){
-  }
-
-  bool operator()(const xAOD::IParticle* ip) {
-    null = (ip == 0);
-    negativeE = skipNegativeEnergy && ip->e() <= 0.0;
-    return (null || negativeE);
-  }
-};
-
-
-std::vector<PseudoJet> 
-PseudoJetGetter::IParticlesToPJs(const xAOD::IParticleContainer* ips) const {
-
-  IParticleRejecter rejecter(m_skipNegativeEnergy);
-
-  std::vector<PseudoJet> vpj;
-  int index = -1;
-
-  // loop over the input iparticles, select and  convert to pseudojets
-  for(const xAOD::IParticle* ip: *ips) {
-    ++index;
-    if(rejecter(ip)){continue;}
-    
-    // Create a PSeudojet with the momentum of the selected IParticles.
-    fastjet::PseudoJet psj(ip->p4());
-
-    // user index is used to identify the xAOD object used for the PseudoJet
-    psj.set_user_index(index); 
-    vpj.push_back(psj);
-
-  }
-  return vpj;
-}
-
-struct EMTopoRejecter{
-  const xAOD::CaloCluster* cluster{0};
-
-  bool operator()(const xAOD::IParticle* ip){
-    cluster = dynamic_cast<const xAOD::CaloCluster*>(ip);
-    return cluster == 0;  // reject if not a cluster
-  }
-};
-
-std::vector<PseudoJet> 
-PseudoJetGetter::EMToposToPJs(const xAOD::IParticleContainer* ips) const {
-
-  // helper objects for selecting iparticles to be converted to pseudojets
-  IParticleRejecter ipRejecter(m_skipNegativeEnergy);
-  EMTopoRejecter emRejecter;
-  
-  std::vector<PseudoJet> vpj;
-  int index = -1;
-
-  // loop over iparticles, select and  convert to pseudojets
-
-  for(const xAOD::IParticle* ip: *ips) {
-    ++index;
-    if(ipRejecter(ip) or emRejecter(ip)){continue;}
-    
-    // Create a Pseudojet with the momentum of the cluster.
-    fastjet::PseudoJet 
-      psj(emRejecter.cluster->p4(xAOD::CaloCluster::UNCALIBRATED));
-    
-    // user index is used to identify the xAOD object used for the PSeudoJet
-    psj.set_user_index(index); 
-    vpj.push_back(psj);
-  }
-  return vpj;
-}
-
-#ifndef GENERATIONBASE
-struct PFlowRejecter{
-
-  bool skipNegativeEnergy{false};
-  
-  PFlowRejecter(bool skip): skipNegativeEnergy(skip){
-  }
-
-  bool operator()(const xAOD::IParticle* ip){
-    
-    const xAOD::PFO* pfo = dynamic_cast<const xAOD::PFO*>(ip);
-    
-    // keep charged PFOs with energy==0 because for MET TST with PFlow, 
-    // there may be high pt 
-    // charged PFOs that receive a weight of 0 due to being in dense 
-    // showers, but need to be present for overlap removal, because they 
-    // don't retain these weights when added to the TST      
-
-    if( fabs(pfo->charge())>FLT_MIN) {
-      const static SG::AuxElement::ConstAccessor<char> 
-        PVMatchedAcc("matchedToPV");
-      return  !PVMatchedAcc(*pfo);
-    }
-    
-    // This also skips 0 energy, which has no effect other than
-    // on memory size, but is used in some workflows for pileup rejection
-    return skipNegativeEnergy && pfo->e()<FLT_MIN;
-  }
-};
-
-std::vector<PseudoJet> 
-PseudoJetGetter::PFlowsToPJs(const xAOD::IParticleContainer* ips) const {
-
-  PFlowRejecter rejecter(m_skipNegativeEnergy);
-  std::vector<PseudoJet> vpj;
-  int index = -1;
-
-  // loop over the input iparticles, select and  convert to pseudojets
-
-  for(const xAOD::IParticle* ip: *ips) {
-    ++index;
-    if(rejecter(ip)){continue;}
-    
-    // Create a PSeudojet with the momentum of the selected IParticles.
-    fastjet::PseudoJet psj(ip->p4());
-
-    // user index is used to identify the xAOD object used for the PSeudoJet
-    psj.set_user_index(index);
-
-    vpj.push_back(psj);
-  }
-  return vpj;
-}
-#endif
-
-//**********************************************************************
-
-
-std::string PseudoJetGetter::label() const{
-  return m_label;
-}
-
-//**********************************************************************
-
-void PseudoJetGetter::print() const {
-  string sskip = m_skipNegativeEnergy ? "true" : "false";
-  ATH_MSG_INFO("Properties for PseudoJetGetter " << name());
-  ATH_MSG_INFO("             Label: " << m_label);
-  ATH_MSG_INFO("   Input container: " << m_incoll.key());
-  ATH_MSG_INFO("  Output container: " << m_outcoll.key());
-  ATH_MSG_INFO("   Skip negative E: " << sskip);
-  ATH_MSG_INFO("         Is EMTopo: " << m_emtopo);
-  ATH_MSG_INFO("          Is PFlow: " << m_pflow);
-  ATH_MSG_INFO(" Treat negative E as ghost: " << m_negEnergyAsGhosts);
-}
-
-//**********************************************************************
-
-int  PseudoJetGetter::inputContainerNames(std::vector<std::string>& connames) {
-  if ( m_incoll.key().size() ) connames.push_back(m_incoll.key());
-  return 0;
-}
-
-//**********************************************************************
-
-int PseudoJetGetter::outputContainerNames(std::vector<std::string>& connames) {
-  if ( m_outcoll.key().size() ) connames.push_back(m_outcoll.key());
-  return 0;
-}
-
-//**********************************************************************
diff --git a/Reconstruction/Jet/JetRec/Root/PseudoJetGetterRegistry.cxx b/Reconstruction/Jet/JetRec/Root/PseudoJetGetterRegistry.cxx
deleted file mode 100644
index 98e2e7f1ea18022a0018436beb3be0f53d5e7306..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRec/Root/PseudoJetGetterRegistry.cxx
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// PseudoJetGetterRegistry.cxx
-
-#include "JetRec/PseudoJetGetterRegistry.h"
-
-PseudoJetGetterRegistry::Map PseudoJetGetterRegistry::m_map;
-
-//**********************************************************************
-
-int PseudoJetGetterRegistry::add(Label lab, const IPseudoJetGetter* ptool) {
-  m_map[lab] = ptool;
-  return 0;
-}
-
-//**********************************************************************
-
-int PseudoJetGetterRegistry::add(const IPseudoJetGetter* ptool) {
-  if ( ptool == nullptr ) return 1;
-  std::string lab = ptool->label();
-  if ( lab.size() == 0 ) return 2;
-  m_map[lab] = ptool;
-  return 0;
-}
-
-//**********************************************************************
-
-bool PseudoJetGetterRegistry::has(Label lab) {
-  return m_map.find(lab) != m_map.end();
-}
-
-//**********************************************************************
-
-const IPseudoJetGetter* PseudoJetGetterRegistry::find(Label lab) {
-  auto ient = m_map.find(lab);
-  if ( ient == m_map.end() ) return nullptr;
-  return ient->second;
-}
-
-//**********************************************************************
diff --git a/Reconstruction/Jet/JetRec/python/JetAlgorithm.py b/Reconstruction/Jet/JetRec/python/JetAlgorithm.py
index 4ca800975b3992a101432541bb78721aa2708da3..6905069617a5bdb71bd82f1b3f50c47ea1a4ee5c 100644
--- a/Reconstruction/Jet/JetRec/python/JetAlgorithm.py
+++ b/Reconstruction/Jet/JetRec/python/JetAlgorithm.py
@@ -155,9 +155,11 @@ def addJetRecoToAlgSequence(job =None, useTruth =None, eventShapeTools =None,
                         Tools=[jtm.jetconstit])
 
   # Add all the PseudoJetAlgorithms now
-  from JetRec.JetRecConf import PseudoJetAlgorithm
+  # To avoid massive refactoring and to preserve familiarity,
+  # kept calling things "getters", but these are already
+  # PseudoJetAlgorithms as we eliminated the wrappers
   for getter in jtm.allGetters:
-    job += PseudoJetAlgorithm("pjalg_"+getter.Label,PJGetter=getter)
+    job += getter
 
   # Then, add all event shape tools in separate algs
   for evstool in jtm.allEDTools:
diff --git a/Reconstruction/Jet/JetRec/python/JetRecStandardTools.py b/Reconstruction/Jet/JetRec/python/JetRecStandardTools.py
index fa89b11bbf2c5fe54cc2039c69e78dc8b7dc4932..93215db951c562a7f3b545fac9ddeb10bb25ec4a 100644
--- a/Reconstruction/Jet/JetRec/python/JetRecStandardTools.py
+++ b/Reconstruction/Jet/JetRec/python/JetRecStandardTools.py
@@ -32,18 +32,10 @@ from MCTruthClassifier.MCTruthClassifierConf import MCTruthClassifier
 from PFlowUtils.PFlowUtilsConf import CP__WeightPFOTool as WeightPFOTool
 from JetRecTools.JetRecToolsConf import CorrectPFOTool
 from JetRecTools.JetRecToolsConf import ChargedHadronSubtractionTool
-from JetRecTools.JetRecToolsConf import TrackPseudoJetGetter
 from JetRecTools.JetRecToolsConf import JetTrackSelectionTool
 from JetRecTools.JetRecToolsConf import JetTrackSelectionTool2
 from JetRecTools.JetRecToolsConf import SimpleJetTrackSelectionTool
 from JetRecTools.JetRecToolsConf import TrackVertexAssociationTool
-# PS 5/12/2017 from JetSimTools.JetSimToolsConf import TruthPseudoJetGetter
-# FIXME JE
-#from JetRecTools.JetRecToolsConf import CorrectPFOTool
-# FIXME JE
-#from JetRecTools.JetRecToolsConf import ChargedHadronSubtractionTool
-# FIXME JE
-#from JetRecTools.JetRecToolsConf import JetConstituentModSequence
 
 try:
   from JetRecCalo.JetRecCaloConf import MissingCellListTool
@@ -53,11 +45,11 @@ except ImportError:
 from JetRec.JetRecConf import JetPseudojetRetriever
 from JetRec.JetRecConf import JetConstituentsRetriever
 from JetRec.JetRecConf import JetRecTool
-from JetRec.JetRecConf import PseudoJetGetter
-from JetRec.JetRecConf import MuonSegmentPseudoJetGetter
 from JetRec.JetRecConf import JetFromPseudojet
 from JetRec.JetRecConf import JetConstitRemover
 from JetRec.JetRecConf import JetSorter
+from JetRec.JetRecConf import PseudoJetAlgorithm
+from JetRec.JetRecConf import MuonSegmentPseudoJetAlgorithm
 from JetMomentTools.JetMomentToolsConf import JetCaloQualityTool
 try:
   from JetMomentTools.JetMomentToolsConf import JetCaloCellQualityTool
@@ -246,7 +238,7 @@ jtm += ctm.buildConstitModifSequence( "JetConstitSeq_EMOrigin",
     InputContainer= 'CaloCalTopoClusters',                                      
     modList = [ 'clus_emscale', 'clus_origin' ] )
 
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "lcoriginget",
   InputContainer = jtm.JetConstitSeq_LCOrigin.OutputContainer,
   Label = "LCTopoOrigin",
@@ -255,7 +247,7 @@ jtm += PseudoJetGetter(
   GhostScale = 0.0
 )
 
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "emoriginget",
   InputContainer = jtm.JetConstitSeq_EMOrigin.OutputContainer,
   Label = "EMTopoOrigin",
@@ -265,7 +257,7 @@ jtm += PseudoJetGetter(
 )
 
 # Clusters.
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "lcget",
   InputContainer = "CaloCalTopoClusters",
   Label = "LCTopo",
@@ -275,7 +267,7 @@ jtm += PseudoJetGetter(
 )
 
 # EM clusters.
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "emget",
   InputContainer = "CaloCalTopoClusters",
   Label = "EMTopo",
@@ -285,29 +277,27 @@ jtm += PseudoJetGetter(
 )
 
 # Tracks.
-jtm += TrackPseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "trackget",
   InputContainer = jtm.trackselloose_trackjets.OutputContainer,
   Label = "Track",
   OutputContainer = "PseudoJetTrack",
-  TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
   SkipNegativeEnergy = True,
   GhostScale = 0.0
 )
 
 # Ghost tracks.
-jtm += TrackPseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "gtrackget",
   InputContainer = jtm.tracksel.OutputContainer,
   Label = "GhostTrack",
   OutputContainer = "PseudoJetGhostTrack",
-  TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
   SkipNegativeEnergy = True,
   GhostScale = ghostScaleFactor
 )
 
 # Muon segments
-jtm += MuonSegmentPseudoJetGetter(
+jtm += MuonSegmentPseudoJetAlgorithm(
   "gmusegget",
   InputContainer = "MuonSegments",
   Label = "GhostMuonSegment",
@@ -370,7 +360,7 @@ jtm += ctm.buildConstitModifSequence( "JetConstitSeq_PFlowCHS",
                                       modList = ['correctPFO', 'chsPFO'] )
 
 # EM-scale pflow.
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "empflowget",
   Label = "EMPFlow",
   InputContainer = "CHSParticleFlowObjects",
@@ -380,7 +370,7 @@ jtm += PseudoJetGetter(
 )
 
 # AntiKt2 track jets.
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "gakt2trackget", # give a unique name
   InputContainer = jetFlags.containerNamePrefix() + "AntiKt2PV0TrackJets", # SG key
   Label = "GhostAntiKt2TrackJet",   # this is the name you'll use to retrieve associated ghosts
@@ -390,7 +380,7 @@ jtm += PseudoJetGetter(
 )
 
 # AntiKt4 track jets.
-jtm += PseudoJetGetter(
+jtm += PseudoJetAlgorithm(
   "gakt4trackget", # give a unique name
   InputContainer = jetFlags.containerNamePrefix() + "AntiKt4PV0TrackJets", # SG key
   Label = "GhostAntiKt4TrackJet",   # this is the name you'll use to retrieve associated ghosts
@@ -401,8 +391,7 @@ jtm += PseudoJetGetter(
 
 # Truth.
 if jetFlags.useTruth and jtm.haveParticleJetTools:
-  # PS 5/1/2017  jtm += TruthPseudoJetGetter(
-  jtm += PseudoJetGetter(
+  jtm += PseudoJetAlgorithm(
     "truthget",
     Label = "Truth",
     InputContainer = jtm.truthpartcopy.OutputName,
@@ -411,8 +400,7 @@ if jetFlags.useTruth and jtm.haveParticleJetTools:
     SkipNegativeEnergy = True,
 
   )
-  # PS 5/1/2017  jtm += TruthPseudoJetGetter(
-  jtm += PseudoJetGetter(
+  jtm += PseudoJetAlgorithm(
     "truthwzget",
     Label = "TruthWZ",
     InputContainer = jtm.truthpartcopywz.OutputName,
@@ -421,8 +409,7 @@ if jetFlags.useTruth and jtm.haveParticleJetTools:
     SkipNegativeEnergy = True,
     
   )
-  # PS 5/1/2017  jtm += TruthPseudoJetGetter(
-  jtm += PseudoJetGetter(
+  jtm += PseudoJetAlgorithm(
     "gtruthget",
     Label = "GhostTruth",
     InputContainer = jtm.truthpartcopy.OutputName,
@@ -433,8 +420,7 @@ if jetFlags.useTruth and jtm.haveParticleJetTools:
 
   # Truth flavor tags.
   for ptype in jetFlags.truthFlavorTags():
-    # PS 5/1/2017  jtm += TruthPseudoJetGetter(
-    jtm += PseudoJetGetter(
+    jtm += PseudoJetAlgorithm(
       "gtruthget_" + ptype,
       InputContainer = "TruthLabel" + ptype,
       Label = "Ghost" + ptype,
@@ -661,7 +647,7 @@ jtm += JetVoronoiMomentsTool(
 #jtm += JetMuonSegmentMomentsTool("muonsegs")
 
 # Isolations.
-# Note absence of PseudoJetGetter property means the jet inputs
+# Note absence of PseudoJetAlgorithm property means the jet inputs
 # are obtained according to the InputType property of the jet.
 jtm += JetIsolationTool(
   "jetisol",
diff --git a/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py b/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py
index 8a162c7e04846b574da8f73911f828994c6ffd4f..ccf56adce351441ca6a7ed2612563a71057e4c76 100755
--- a/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py
+++ b/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py
@@ -77,32 +77,25 @@ def JetInputCfg(ConfigFlags):
     # Add the alg to the sequence in the ComponentAccumulator
     inputcfg.addEventAlgo(jetmodalg,sequencename)
 
-    # Create a PseudoJetGetter & corresponding algorithm
-    constitgetter = CompFactory.PseudoJetGetter(
-        "pjg_LCTopo",
+    # Create a PseudoJetAlgorithm
+
+    constitpjgalg = CompFactory.PseudoJetAlgorithm(
+        "pjgalg_LCTopo",
         InputContainer = "LCOriginTopoClusters",
         OutputContainer = "PseudoJetLCTopo",
         Label = "LCTopo",
         SkipNegativeEnergy=True,
         GhostScale=0.)
 
-    constitpjgalg = CompFactory.PseudoJetAlgorithm(
-        "pjgalg_LCTopo",
-        PJGetter = constitgetter)
-
-    ghostgetter = CompFactory.PseudoJetGetter(
-        "pjg_Truth",
+    ghostpjgalg = CompFactory.PseudoJetAlgorithm(
+        "pjgalg_Truth",
         InputContainer = "TruthParticles",
         OutputContainer = "PseudoJetTruth",
         Label = "Truth",
         SkipNegativeEnergy=True,
         GhostScale=0.)
 
-    ghostpjgalg = CompFactory.PseudoJetAlgorithm(
-        "pjgalg_Truth",
-        PJGetter = ghostgetter)
-
-    pjcs = [constitgetter.OutputContainer,ghostgetter.OutputContainer]
+    pjcs = [constitpjgalg.OutputContainer,ghostpjgalg.OutputContainer]
 
     # Add the algs to the sequence in the ComponentAccumulator
     inputcfg.addEventAlgo(constitpjgalg,sequencename)
@@ -125,15 +118,11 @@ def JetBuildAlgCfg(ConfigFlags,buildjetsname):
     buildcfg.merge(inputcfg)
 
     # Create a merger to build the PseudoJetContainer for this specific jet collection
-    pjmerger = CompFactory.PseudoJetMerger(
-        "pjmerge_"+buildjetsname,
+    mergepjalg = CompFactory.PseudoJetMerger(
+        "pjmergealg_"+buildjetsname,
         InputPJContainers = pjcs,
         OutputContainer = "PseudoJetMerged_"+buildjetsname)
 
-    mergepjalg = CompFactory.PseudoJetAlgorithm(
-        "pjmergealg_"+buildjetsname,
-        PJGetter = pjmerger)
-
     buildcfg.addEventAlgo(mergepjalg)
 
     # Create the JetClusterer, set some standard options
diff --git a/Reconstruction/Jet/JetRec/share/simpleJetRecJobO.py b/Reconstruction/Jet/JetRec/share/simpleJetRecJobO.py
index ed1dd7d89dbb0bb30c5903485f13be54ca16959f..3c8675d7cfa1d3ebc0ac1d6175293e5754d88963 100644
--- a/Reconstruction/Jet/JetRec/share/simpleJetRecJobO.py
+++ b/Reconstruction/Jet/JetRec/share/simpleJetRecJobO.py
@@ -17,7 +17,7 @@ from AthenaCommon import CfgMgr
 # In the midst of this migration, we can only cope with one pseudojet type
 # otherwise we end up trying to update an object in SG, which is not allowed
 # Needs JE's PseudojetContainer developments
-emget = CfgMgr.PseudoJetGetter(
+emget = CfgMgr.PseudoJetAlgorithm(
   "emget",
   InputContainer = "CaloCalTopoClusters",
   Label = "EMTopo",
@@ -26,9 +26,8 @@ emget = CfgMgr.PseudoJetGetter(
   GhostScale = 0.0,
 #  OutputLevel=VERBOSE,
 )
-ToolSvc += emget
 
-topSequence += CfgMgr.PseudoJetAlgorithm("pjalg_EMTopo",PJGetter=emget)
+topSequence += emget
 
 # Set up the jet finder
 JetFinder_AntiKt4 = CfgMgr.JetFinder("MTAntiKt4EMTopoJetsFinder",
@@ -41,24 +40,17 @@ JetFinder_AntiKt4 = CfgMgr.JetFinder("MTAntiKt4EMTopoJetsFinder",
 
 #Then we setup a jet builder to calculate the areas needed for the rho subtraction
 # Actually, we don't really need the areas but we may as well use this one
-from AthenaCommon.AppMgr import ToolSvc
 JetBuilder_AntiKt4 = CfgMgr.JetFromPseudojet("jblda", Attributes = ["ActiveArea", "ActiveArea4vec"],
                                              OutputLevel=VERBOSE)
-ToolSvc += JetBuilder_AntiKt4
 JetFinder_AntiKt4.JetBuilder = JetBuilder_AntiKt4
-ToolSvc += JetFinder_AntiKt4
 
 #Now we setup a JetRecTool which will use the above JetFinder
 JetRecTool = CfgMgr.JetRecTool("MTAntiKt4EMTopoJets",
                                OutputLevel=VERBOSE)
 JetRecTool.JetFinder = JetFinder_AntiKt4
-ToolSvc += JetRecTool
 JetRecTool.InputPseudoJets = [emget.OutputContainer]
 JetRecTool.OutputContainer = "MTAntiKt4EMTopoJets"
 
-#jpjretriever = CfgMgr.JetPseudojetRetriever("jpjretriever")
-#ToolSvc += jpjretriever
-
 topSequence += CfgMgr.JetAlgorithm("MTJetAlg",Tools = [JetRecTool])
 
 write_xAOD = True
diff --git a/Reconstruction/Jet/JetRec/src/MuonSegmentPseudoJetAlgorithm.cxx b/Reconstruction/Jet/JetRec/src/MuonSegmentPseudoJetAlgorithm.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..35a6ae6ea569579088fb0f2bf272cd6b6cc82131
--- /dev/null
+++ b/Reconstruction/Jet/JetRec/src/MuonSegmentPseudoJetAlgorithm.cxx
@@ -0,0 +1,94 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "JetRec/MuonSegmentExtractor.h"
+#include "MuonSegmentPseudoJetAlgorithm.h"
+
+//**********************************************************************
+
+StatusCode MuonSegmentPseudoJetAlgorithm::initialize() {
+  ATH_MSG_INFO("Initializing " << name() << "...");
+
+  print();
+
+  if(m_incoll.key().empty() || m_outcoll.key().empty()) {
+    ATH_MSG_ERROR("Either input or output collection is empty!");
+    return StatusCode::FAILURE;
+  }
+
+  ATH_CHECK( m_incoll.initialize() );
+  ATH_CHECK( m_outcoll.initialize() );
+
+  return StatusCode::SUCCESS;
+}
+
+//**********************************************************************
+
+StatusCode MuonSegmentPseudoJetAlgorithm::execute(const EventContext& ctx) const {
+  ATH_MSG_VERBOSE("Executing " << name() << "...");
+
+  auto incoll = SG::makeHandle<xAOD::MuonSegmentContainer>(m_incoll,ctx);
+  if( !incoll.isValid() ) {
+    // Return SUCCESS to avoid crashing T0 jobs
+    ATH_MSG_WARNING("Failed to retrieve " << m_incoll.key() << " for PseudoJet creation!" );
+    return StatusCode::SUCCESS;
+  }
+  ATH_MSG_DEBUG("Retrieved muon segment container " << m_incoll.key() );
+
+  std::vector<fastjet::PseudoJet> vpj = createPseudoJets(*incoll);
+    
+  // create an extractor (MuonSegmentExtractors are always ghost extractors)
+  auto extractor = std::make_unique<MuonSegmentExtractor>(incoll.cptr(), m_label);
+  ATH_MSG_DEBUG("Created extractor: "  << extractor->toString(0));
+
+  // Put the PseudoJetContainer together
+  auto pjcont = std::make_unique<PseudoJetContainer>(extractor.release(), vpj);
+  
+  auto outcoll = SG::makeHandle<PseudoJetContainer>(m_outcoll,ctx);
+  ATH_CHECK(outcoll.record(std::move(pjcont)));
+  ATH_MSG_DEBUG("New PseudoJetContainer size " << pjcont->size());
+
+  return StatusCode::SUCCESS;
+}
+
+//**********************************************************************
+
+std::vector<fastjet::PseudoJet> 
+MuonSegmentPseudoJetAlgorithm::createPseudoJets(const xAOD::MuonSegmentContainer& ms) const {
+  
+  std::vector<fastjet::PseudoJet> vpj;
+  int index=0;
+  for(const xAOD::MuonSegment* part: ms) {
+    double pt = m_pt;
+    double x = part->x();
+    double y = part->y();
+    double z = part->z();
+    double xy = sqrt(x*x + y*y);
+    double r = sqrt(xy*xy + z*z);
+    double pfac = pt/xy;
+    double px = pfac*x;
+    double py = pfac*y;
+    double pz = pfac*z;
+    double  e = pfac*r;
+    fastjet::PseudoJet psj(px, py, pz, e);
+    ATH_MSG_VERBOSE("Muon segment pseudojet y: " << psj.rap());
+    vpj.push_back(psj);
+    vpj.back().set_user_index(index); // Set the index !!
+    index++;
+  }
+
+  return vpj;
+}
+
+//**********************************************************************
+
+void MuonSegmentPseudoJetAlgorithm::print() const {
+  ATH_MSG_INFO("Properties for MuonSegmentPseudoJetGetter " << name());
+  ATH_MSG_INFO("             Label: " << m_label);
+  ATH_MSG_INFO("   Input container: " << m_incoll.key());
+  ATH_MSG_INFO("  Output container: " << m_outcoll.key());
+  ATH_MSG_INFO("      Pseudojet pT: " << m_pt);
+}
+
+//**********************************************************************
diff --git a/Reconstruction/Jet/JetRec/src/MuonSegmentPseudoJetAlgorithm.h b/Reconstruction/Jet/JetRec/src/MuonSegmentPseudoJetAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..4de9244badb3e7cd70f7b542f7ee076a8898e0a1
--- /dev/null
+++ b/Reconstruction/Jet/JetRec/src/MuonSegmentPseudoJetAlgorithm.h
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+// MuonSegmentPseudoJetAlgorithm.h 
+
+/// A PseudoJetAlgorithm for muon segments (which are not IParticles)
+///
+/// This is needed for the punchthrough calibration correction.
+/// Due to the different configuration properties and limited
+/// code sharing, this does not inherit from PseudoJetAlgorithm
+/// or a common base.
+
+#ifndef MuonSegmentPseudoJetAlgorithm_H
+#define MuonSegmentPseudoJetAlgorithm_H
+
+#include <memory>
+#include "fastjet/PseudoJet.hh"
+#include "JetRec/PseudoJetContainer.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "xAODMuon/MuonSegment.h"
+#include "xAODMuon/MuonSegmentContainer.h"
+
+class MuonSegmentPseudoJetAlgorithm : public AthReentrantAlgorithm { 
+
+public: 
+
+  // No need for a specialised constructor
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
+
+  /// Athena algorithm's Hooks
+  virtual StatusCode  initialize() override final;
+
+  // Standard execute, forwards to createAndRecord
+  virtual StatusCode  execute(const EventContext& ctx) const override final;
+
+private: 
+
+  std::vector<fastjet::PseudoJet> createPseudoJets(const xAOD::MuonSegmentContainer& ms) const;
+
+  /// Dump to properties to the log.
+  virtual void print() const;
+
+private:
+
+  /// Input collection name.
+  SG::ReadHandleKey<xAOD::MuonSegmentContainer> m_incoll{this, "InputContainer", "MuonSegments", "The input MuonSegmentContainer name"};
+
+  /// Output collection name.
+  SG::WriteHandleKey<PseudoJetContainer> m_outcoll{this, "OutputContainer", "PseudoJetGhostMuonSegment", "The output PseudoJetContainer name"};
+
+  /// Label for the collection.
+  Gaudi::Property<std::string> m_label{this, "Label", "GhostMuonSegment", "String label identifying the pseudojet type"};
+
+  Gaudi::Property<float> m_pt{this, "Pt", 1.e-10, "The pT to set for the muon segments"};
+
+}; 
+
+#endif
diff --git a/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.cxx b/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.cxx
index a7408a5781bc200824c68d09c364554d3f98f8f2..425f0a8464157613340296bd555b04e8ebcaf7c5 100644
--- a/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.cxx
+++ b/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.cxx
@@ -1,51 +1,115 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // PseudoJetAlgorithm.cxx 
 
 #include "PseudoJetAlgorithm.h"
-#include "JetInterface/IPseudoJetGetter.h"
-
-using std::string;
+#include "JetRec/PseudoJetGetter.h"
+#include "JetRec/IParticleExtractor.h"
 
 //**********************************************************************
 
-PseudoJetAlgorithm::PseudoJetAlgorithm(const std::string& name, 
-                           ISvcLocator* pSvcLocator )
-  : ::AthReentrantAlgorithm( name, pSvcLocator ),m_pjg(this) {
-  declareProperty( "PJGetter", m_pjg);
-}
+StatusCode PseudoJetAlgorithm::initialize() {
+  ATH_MSG_INFO("Initializing " << name() << "...");
 
-//**********************************************************************
+  // This is horrible, but still necessary for the time being
+  // PJG needs to know if this is the basic EMTopo cluster collection
+  // in order to change the cluster signal state.
+  if ( m_label == "EMTopo") m_emtopo = true;
+  // PFlow containers need to have PV matching applied
+  if ( std::string(m_label).find("PFlow") != std::string::npos ) m_pflow = true;
 
-PseudoJetAlgorithm::~PseudoJetAlgorithm() { }
+  // "Ghost" in output collection name? If so is a ghost collection.
+  m_isGhost = (m_outcoll.key()).find("Ghost") != std::string::npos;
 
-//**********************************************************************
+  print();
 
-StatusCode PseudoJetAlgorithm::initialize() {
-  ATH_MSG_INFO("Initializing " << name() << "...");
-  ATH_MSG_INFO("Retrieving pseudojet getter " << m_pjg->name());
-  ATH_CHECK( m_pjg.retrieve() );
-  m_pjg->print();
-  return StatusCode::SUCCESS;
-}
+  if(m_incoll.key().empty() || m_outcoll.key().empty()) {
+    ATH_MSG_ERROR("Either input or output collection is empty!");
+    return StatusCode::FAILURE;
+  }
 
-//**********************************************************************
+  ATH_CHECK( m_incoll.initialize() );
+  ATH_CHECK( m_outcoll.initialize() );
 
-StatusCode PseudoJetAlgorithm::finalize() {
-  ATH_MSG_INFO ("Finalizing " << name() << "...");
   return StatusCode::SUCCESS;
 }
 
+
 //**********************************************************************
 
-StatusCode PseudoJetAlgorithm::execute(const EventContext& /*ctx*/) const {
+StatusCode PseudoJetAlgorithm::execute(const EventContext& ctx) const {
   ATH_MSG_VERBOSE("Executing " << name() << "...");
 
-  ATH_CHECK( m_pjg->createAndRecord() );
+  // build and record the container
+  auto incoll = SG::makeHandle(m_incoll, ctx);
+  if( !incoll.isValid() ) {
+    // Return SUCCESS to avoid crashing T0 jobs
+    ATH_MSG_WARNING("Failed to retrieve " << m_incoll.key() << " for PseudoJet creation!" );
+    return StatusCode::SUCCESS;
+  }
+  ATH_MSG_DEBUG("Retrieved xAOD container " << m_incoll.key() << "of size " << incoll->size()
+		<< ", ghost scale=" << m_ghostscale  
+		<<  ", isGhost=" << bool(m_ghostscale));
+
+  ATH_MSG_DEBUG("Creating PseudoJetContainer...");
+  std::unique_ptr<PseudoJetContainer> pjcont( createPJContainer(*incoll) );
+
+  auto outcoll = SG::makeHandle(m_outcoll, ctx);
+  ATH_CHECK( outcoll.record(std::move(pjcont)) );
+
+  ATH_MSG_DEBUG("Created new PseudoJetContainer in event store: " 
+		<< m_outcoll.key());
 
   return StatusCode::SUCCESS;
 }
 
+
+std::unique_ptr<PseudoJetContainer> PseudoJetAlgorithm::createPJContainer(const xAOD::IParticleContainer& cont) const {
+  // create PseudoJets
+  std::vector<fastjet::PseudoJet> vpj = createPseudoJets(cont);
+
+  // create an extractor to attach to the PJContainer -- this will be used by clients
+  auto extractor = std::make_unique<IParticleExtractor>(&cont, m_label, m_isGhost);
+  ATH_MSG_DEBUG("Created extractor: "  << extractor->toString(0));
+  
+  // ghostify the pseudojets if necessary
+  if(m_isGhost){
+    for(fastjet::PseudoJet& pj : vpj) {pj *= 1e-40;}
+  }
+  
+  // Put the PseudoJetContainer together
+  auto pjcont = std::make_unique<PseudoJetContainer>(extractor.release(), vpj);
+  ATH_MSG_DEBUG("New PseudoJetContainer size " << pjcont->size());
+
+  return std::move(pjcont);
+}
+
+
+std::vector<fastjet::PseudoJet> 
+PseudoJetAlgorithm::createPseudoJets(const xAOD::IParticleContainer& ips) const{
+#ifndef GENERATIONBASE
+  if (m_pflow) {return PseudoJetGetter::PFlowsToPJs(ips,m_skipNegativeEnergy);}
+  if (m_emtopo) {return PseudoJetGetter::EMToposToPJs(ips,m_skipNegativeEnergy);}
+#endif
+  return PseudoJetGetter::IParticlesToPJs(ips,m_skipNegativeEnergy);
+}
+
+
+//**********************************************************************
+
+void PseudoJetAlgorithm::print() const {
+  std::string sskip = m_skipNegativeEnergy ? "true" : "false";
+  // May want to change to DEBUG
+  ATH_MSG_INFO("Properties for PseudoJetGetter " << name());
+  ATH_MSG_INFO("             Label: " << m_label);
+  ATH_MSG_INFO("   Input container: " << m_incoll.key());
+  ATH_MSG_INFO("  Output container: " << m_outcoll.key());
+  ATH_MSG_INFO("   Skip negative E: " << sskip);
+  ATH_MSG_INFO("         Is EMTopo: " << m_emtopo);
+  ATH_MSG_INFO("          Is PFlow: " << m_pflow);
+  ATH_MSG_INFO(" Treat negative E as ghost: " << m_negEnergyAsGhosts);
+}
+
 //**********************************************************************
diff --git a/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.h b/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.h
index 4d82f4f01fb3e97f43b81ec8d17f3c30ec722da5..760b743160e4febfbe800e00b38d6a36e752fdb1 100644
--- a/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.h
+++ b/Reconstruction/Jet/JetRec/src/PseudoJetAlgorithm.h
@@ -1,41 +1,82 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // PseudoJetAlgorithm.h 
 
+/// PseudoJetAlgorithm retrieves and builds the pseudojet inputs used in jet finding
+///
+/// Alg Properties:
+///  - InputCollection: Name of the input collection.
+///  - OutputCollection: Name of the output collection of pseudojets.
+///  - Label: Label for the constituents. See note below.
+///  - SkipNegativeEnergy: Flag indicating that inputs with negative energy
+/// should be ignored.
+///  - GhostScale : If nonzero, the pseudojets are labeled as ghosts and
+/// their four-momenta are scaled by this factor.
+///
+/// Note: The label is attached to the CUI (constituent user info) associated with
+/// created pseudojet and is used to name jet moments that point to the PJs,
+/// and in rare cases (EMTopo, PFlow) to toggle special treatments.
+
 #ifndef PseudoJetAlgorithm_H
 #define PseudoJetAlgorithm_H
 
-#include "AthenaBaseComps/AthReentrantAlgorithm.h"
-#include "GaudiKernel/ToolHandle.h"
+#include <memory>
+#include "fastjet/PseudoJet.hh"
+#include "JetRec/PseudoJetContainer.h"
 
-class IPseudoJetGetter;
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 
 class PseudoJetAlgorithm : public AthReentrantAlgorithm { 
 
 public: 
 
-  /// Constructor with parameters: 
-  PseudoJetAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
-
-  /// Destructor: 
-  ~PseudoJetAlgorithm(); 
+  // No need for a specialised constructor
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
 
   /// Athena algorithm's Hooks
-  virtual StatusCode  initialize() override;
-  virtual StatusCode  execute(const EventContext& ctx) const override;
-  virtual StatusCode  finalize() override;
+  virtual StatusCode  initialize() override final;
+
+  // Standard execute, forwards to createAndRecord
+  virtual StatusCode  execute(const EventContext& ctx) const override final;
 
 private: 
 
-  /// Default constructor: 
-  PseudoJetAlgorithm();
+  /// Method to construct the PseudoJetContainer and record in StoreGate
+  virtual std::unique_ptr<PseudoJetContainer> createPJContainer(const xAOD::IParticleContainer& cont) const;
+
+  /// Dump to properties to the log.
+  virtual void print() const;
+
+  std::vector<fastjet::PseudoJet> 
+  createPseudoJets(const xAOD::IParticleContainer&) const;
 
 private:
 
-  /// Athena configured tools
-  ToolHandle<IPseudoJetGetter> m_pjg;
+  /// Input collection name.
+  SG::ReadHandleKey<xAOD::IParticleContainer> m_incoll{this, "InputContainer", "", "The input IParticleContainer name"};
+
+  /// Output collection name.
+  SG::WriteHandleKey<PseudoJetContainer> m_outcoll{this, "OutputContainer", "", "The output PseudoJetContainer name"};
+
+  /// Label for the collection.
+  Gaudi::Property<std::string> m_label{this, "Label", "", "String label identifying the pseudojet type"};
+
+  /// Flag indicating to skip objects with E<0.
+  Gaudi::Property<bool> m_skipNegativeEnergy{this, "SkipNegativeEnergy", false, "Whether to skip negative energy inputs"};
+
+  /// Ghost scale factor.
+  Gaudi::Property<double> m_ghostscale{this, "GhostScale", 0.0, "Scale factor to convert PJs into ghosts that don't affect jet kinematics"};
+
+  /// Flag indicating to treat objects with E<0 as ghosts  (useful for HI)
+  Gaudi::Property<bool> m_negEnergyAsGhosts{this, "TreatNegativeEnergyAsGhost", false, "Whether to convert negative energy inputs into ghosts"};
+
+  /// Internal steering flags
+  /// Set in initialize()
+  bool m_isGhost{false}; /// Determinines whether the PJs should be made ghosts
+  bool m_emtopo{false};  /// True if inputs are EM-scale topo clusters.
+  bool m_pflow{false};   /// True if inputs are PFlow
 
 }; 
 
diff --git a/Reconstruction/Jet/JetRec/Root/PseudoJetMerger.cxx b/Reconstruction/Jet/JetRec/src/PseudoJetMerger.cxx
similarity index 62%
rename from Reconstruction/Jet/JetRec/Root/PseudoJetMerger.cxx
rename to Reconstruction/Jet/JetRec/src/PseudoJetMerger.cxx
index c01b497128fdc5002ff6b91544a735a96d11edcb..fdf32d97889a127183db85ad7816f1ee14998adf 100644
--- a/Reconstruction/Jet/JetRec/Root/PseudoJetMerger.cxx
+++ b/Reconstruction/Jet/JetRec/src/PseudoJetMerger.cxx
@@ -1,16 +1,17 @@
 /*
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
-#include "JetRec/PseudoJetMerger.h"
 
-
-PseudoJetMerger::PseudoJetMerger(const std::string& name) : AsgTool(name)  {
-  
-}
+#include "PseudoJetMerger.h"
 
 StatusCode PseudoJetMerger::initialize() {
   ATH_MSG_DEBUG("Initializing...");
 
+  if(m_inputPJC.empty() || m_outcoll.key().empty()) {
+    ATH_MSG_ERROR("Either input or output collection is empty!");
+    return StatusCode::FAILURE;
+  }
+
   ATH_CHECK( m_inputPJC.initialize() );
   ATH_CHECK( m_outcoll.initialize() );
   
@@ -18,27 +19,21 @@ StatusCode PseudoJetMerger::initialize() {
 }
 
 
-StatusCode PseudoJetMerger::createAndRecord() const {
+StatusCode PseudoJetMerger::execute(const EventContext& ctx) const {
 
   auto allPseudoJets = std::make_unique<PseudoJetContainer>();
 
   for (const auto& pjcKey : m_inputPJC) {
-    SG::ReadHandle<PseudoJetContainer> pjcHandle( pjcKey );
+    SG::ReadHandle<PseudoJetContainer> pjcHandle( pjcKey, ctx );
     if(!pjcHandle.isValid()){
       ATH_MSG_ERROR("Can't retrieve PseudoJetContainer "<< pjcKey.key() ); return StatusCode::FAILURE;
     }
     allPseudoJets->append(pjcHandle.get() );
   }
 
-  SG::WriteHandle<PseudoJetContainer> outHandle(m_outcoll);
+  SG::WriteHandle<PseudoJetContainer> outHandle(m_outcoll, ctx);
   ATH_CHECK( outHandle.record(std::move(allPseudoJets)) );
   
   return StatusCode::SUCCESS;
-
 }
 
-
-const PseudoJetVector* PseudoJetMerger::get() const {
-
-  return nullptr; // not supposed to be used anymore (?)
-}
diff --git a/Reconstruction/Jet/JetRec/JetRec/PseudoJetMerger.h b/Reconstruction/Jet/JetRec/src/PseudoJetMerger.h
similarity index 51%
rename from Reconstruction/Jet/JetRec/JetRec/PseudoJetMerger.h
rename to Reconstruction/Jet/JetRec/src/PseudoJetMerger.h
index 8759df3bc5888615040767f487caffc7403b1a85..f77c165c7b8e95e368faea1891e51d457cf1e123 100644
--- a/Reconstruction/Jet/JetRec/JetRec/PseudoJetMerger.h
+++ b/Reconstruction/Jet/JetRec/src/PseudoJetMerger.h
@@ -1,48 +1,49 @@
 // this file is -*- C++ -*-
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
+// PseudoJetMerger.h 
+
+/// PseudoJetMerger collects a set of PseudoJets into a group that can be
+/// put together into a jet collection, combining the consituent collection
+/// with a set of ghost collections.
+///
+/// Alg Properties:
+///  - InputPJContainers: Array of input collections to merge.
+///  - OutputCollection: Name of the merged output pseudojet collection.
+///  - Label: Label for the constituents.
 
 #ifndef JETREC_PSEUDOJETMERGER_H
 #define JETREC_PSEUDOJETMERGER_H
 
 
-#include "AsgTools/AsgTool.h"
+#include <memory>
 #include "JetRec/PseudoJetContainer.h"
-#include "JetInterface/IPseudoJetGetter.h"
 #include "fastjet/PseudoJet.hh"
 #include "JetEDM/PseudoJetVector.h"
 
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 
 class PseudoJetMerger
-:  public asg::AsgTool,
-   virtual public IPseudoJetGetter {
-  ASG_TOOL_CLASS(PseudoJetMerger, IPseudoJetGetter)
+  : public AthReentrantAlgorithm  {
 
 public:
 
   typedef jet::PseudoJetVector PseudoJetVector;
 
-  /// Constructor from tool name.
-  PseudoJetMerger(const std::string& myname);
+  // No need for a specialised constructor
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
 
   /// Initialization.
   /// Can be skipped.
   virtual StatusCode initialize() override;
 
-  /// Method to construct the PseudoJetVector and record in StoreGate
-  virtual StatusCode createAndRecord() const override;
-
-  // Kept for backward compatibity
-  virtual const PseudoJetVector* get() const override;
-
-  /// Return the label for these pseudojets.
-  virtual std::string label() const override {return m_label;};
-
+  // Standard execute, forwards to createAndRecord
+  virtual StatusCode  execute(const EventContext& ctx) const override final;
 
-protected:  // data
+private:  // data
 
   // Job options.
 
diff --git a/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx b/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx
index fe281cd2d77b1e94bd6f1521886ef4ad5125b1f7..87ea18b902ceac02071a4eaa10fbbc5250129603 100644
--- a/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx
+++ b/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx
@@ -1,14 +1,15 @@
 #include "../JetAlgorithm.h"
 #include "../JetRecAlg.h"
 #include "../JetViewAlg.h"
-#include "../PseudoJetAlgorithm.h"
 #include "../JetTrimming.h"
 
+#include "../PseudoJetMerger.h"
+#include "../PseudoJetAlgorithm.h"
+#include "../MuonSegmentPseudoJetAlgorithm.h"
+
 #include "JetRec/JetToolRunner.h"
 #include "JetRec/JetRecTool.h"
 #include "JetRec/JetDumper.h"
-#include "JetRec/PseudoJetGetter.h"
-#include "JetRec/MuonSegmentPseudoJetGetter.h"
 #include "JetRec/JetFromPseudojet.h"
 #include "JetRec/JetFinder.h"
 #include "JetRec/JetByVertexFinder.h"
@@ -17,7 +18,6 @@
 #include "JetRec/JetPruner.h"
 #include "JetRec/JetReclusterer.h"
 #include "JetRec/FastJetInterfaceTool.h"
-#include "JetRec/PseudoJetMerger.h"
 
 #include "JetRec/JetSorter.h"
 #include "JetRec/JetPseudojetRetriever.h"
@@ -32,8 +32,6 @@
 DECLARE_COMPONENT( JetToolRunner )
 DECLARE_COMPONENT( JetRecTool )
 DECLARE_COMPONENT( JetDumper )
-DECLARE_COMPONENT( PseudoJetGetter )
-DECLARE_COMPONENT( MuonSegmentPseudoJetGetter )
 DECLARE_COMPONENT( JetFromPseudojet )
 DECLARE_COMPONENT( JetFinder )
 DECLARE_COMPONENT( JetByVertexFinder )
@@ -57,5 +55,6 @@ DECLARE_COMPONENT( JetAlgorithm )
 DECLARE_COMPONENT( JetRecAlg )
 DECLARE_COMPONENT( JetViewAlg )
 DECLARE_COMPONENT( PseudoJetAlgorithm )
+DECLARE_COMPONENT( MuonSegmentPseudoJetAlgorithm )
 
 DECLARE_COMPONENT( JetTrimming )
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
index 349633428984459e00c69ebb4e42d032e4c731ef..6e6b4644279c1504f5886a818db622fe1c4d800f 100644
--- a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
@@ -65,19 +65,19 @@ def JetRecCfg(jetdef, configFlags, jetnameprefix="",jetnamesuffix="", jetnameove
     # will handle the details. Just merge the components.
     # 
     # To facilitate running in serial mode, we also prepare
-    # the constituent PseudoJetGetter here (needed for rho)
+    # the constituent PseudoJetAlgorithm here (needed for rho)
     inputcomps = JetInputCfg(deps["inputs"], configFlags, sequenceName=jetsfullname)
     constitpjalg = inputcomps.getPrimary()
-    constitpjkey = constitpjalg.PJGetter.OutputContainer
+    constitpjkey = constitpjalg.OutputContainer
 
     components.merge(inputcomps)
     pjs = [constitpjkey]
 
-    # Schedule the ghost PseudoJetGetterAlgs
+    # Schedule the ghost PseudoJetAlgs
     for ghostdef in deps["ghosts"]:
         ghostpjalg = getGhostPJGAlg( ghostdef )
         components.addEventAlgo( ghostpjalg, sequencename )
-        ghostpjkey = ghostpjalg.PJGetter.OutputContainer
+        ghostpjkey = ghostpjalg.OutputContainer
         pjs.append( ghostpjkey )
 
     # Generate a JetAlgorithm to run the jet finding and modifiers
@@ -268,9 +268,9 @@ def JetInputCfg(inputdeps, configFlags, sequenceName):
             if constitalg:
                 components.addEventAlgo(constitalg)
 
-    # Schedule the constituent PseudoJetGetterAlg
+    # Schedule the constituent PseudoJetAlg
     constitpjalg = getConstitPJGAlg( constit )
-    constitpjkey = constitpjalg.PJGetter.OutputContainer
+    constitpjkey = constitpjalg.OutputContainer
     # Mark the constit PJGAlg as the primary so that the caller
     # can access the output container name
     components.addEventAlgo( constitpjalg, primary=True )
@@ -338,7 +338,7 @@ def JetInputCfg(inputdeps, configFlags, sequenceName):
     return components
 
 ########################################################################
-# Functions for generating PseudoJetGetters, including determining
+# Functions for generating PseudoJetAlgorithms, including determining
 # the prerequisites for their operation
 #
 def getConstitPrereqs(basedef):
@@ -368,18 +368,15 @@ def getConstitPJGAlg(basedef):
     full_label = basedef.label
     if basedef.basetype == xAODType.Jet:
         full_label += "_"+basedef.inputname
-    getter = CompFactory.PseudoJetGetter("pjg_"+full_label,
+
+    pjgalg = CompFactory.PseudoJetAlgorithm(
+        "pjgalg_"+basedef.label,
         InputContainer = basedef.inputname,
         OutputContainer = "PseudoJet"+full_label,
         Label = full_label,
         SkipNegativeEnergy=True,
         GhostScale=0.
         )
-
-    pjgalg = CompFactory.PseudoJetAlgorithm(
-        "pjgalg_"+basedef.label,
-        PJGetter = getter
-        )
     return pjgalg
 
 def getGhostPJGAlg(ghostdef):
@@ -391,10 +388,10 @@ def getGhostPJGAlg(ghostdef):
         "GhostScale":         1e-40
         }
 
-    pjgclass = CompFactory.PseudoJetGetter
+    pjaclass = CompFactory.PseudoJetAlgorithm
     if ghostdef.inputtype=="MuonSegment":
         # Muon segments have a specialised type
-        pjgclass = CompFactory.MuonSegmentPseudoJetGetter
+        pjaclass = CompFactory.MuonSegmentPseudoJetAlgorithm
         kwargs = {
             "InputContainer":"MuonSegments",
             "OutputContainer":"PseudoJet"+label,
@@ -411,11 +408,9 @@ def getGhostPJGAlg(ghostdef):
     else:
         raise ValueError("Unhandled ghost type {0} received!".format(ghostdef.inputtype))
 
-    getter = pjgclass("pjg_"+label, **kwargs)
-
-    pjgalg = CompFactory.PseudoJetAlgorithm(
+    pjgalg = pjaclass(
         "pjgalg_"+label,
-        PJGetter = getter
+        **kwargs
         )
     return pjgalg
 
diff --git a/Reconstruction/Jet/JetRecTools/JetRecTools/TrackExtractor.h b/Reconstruction/Jet/JetRecTools/JetRecTools/TrackExtractor.h
deleted file mode 100644
index c519de26dd0daf02a70be904f60208bf5549741c..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRecTools/JetRecTools/TrackExtractor.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// this file is -*- C++ -*-
-
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-
-// TrackExtractor.h
-
-#ifndef TrackExtractor_H
-#define TrackExtractor_H
-
-#include "JetRec/IConstituentExtractor.h"
-#include "xAODJet/Jet.h"
-#include "xAODTracking/TrackParticleContainer.h" 
-#include <string>
-
-class TrackExtractor : public IConstituentExtractor {
-
-public:
-  TrackExtractor(const xAOD::TrackParticleContainer* tps,
-                         const std::string & label,
-                         bool isGhost);
-
-  virtual ~TrackExtractor();
-  virtual TrackExtractor* clone() const override;
-  virtual TrackExtractor* ghostClone() const override;
-  virtual void 
-  addToJet(xAOD::Jet&, const std::vector<int>& indices) const override;
-  virtual std::string toString(int level) const override;
-  virtual bool checkIntegrity() const override;
-
-private:
-  const xAOD::TrackParticleContainer* m_originalParticles;
-  std::string m_label;
-  bool m_isGhost; 
-
-};
-
-#endif
diff --git a/Reconstruction/Jet/JetRecTools/JetRecTools/TrackPseudoJetGetter.h b/Reconstruction/Jet/JetRecTools/JetRecTools/TrackPseudoJetGetter.h
deleted file mode 100644
index 17d882095157410509d0ac06864f94fb89dbef87..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRecTools/JetRecTools/TrackPseudoJetGetter.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// emacs : this file is -*- c++ -*-
-
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef JETRECTOOLS_TRACKPSEUDOJETGETTER_H
-#define JETRECTOOLS_TRACKPSEUDOJETGETTER_H
-////////////////////////////////////////////
-/// \class TrackPseudoJetGetter
-///
-/// Specialized PseudoJetGetter for TrackParticle
-///  The only thing done here is to specialize the templated append method and 
-///  define a property for the TrackVertexAssociation
-/// \author P-A Delsart
-//////////////////////////////////////////////////
-
-#include "JetRec/PseudoJetGetter.h"
-#include "xAODTracking/TrackParticleContainer.h"
-#include "JetRec/PseudoJetContainer.h"
-
-namespace jet{
-  class TrackVertexAssociation;
-}
-
-class TrackPseudoJetGetter : public PseudoJetGetter {
-  ASG_TOOL_CLASS(TrackPseudoJetGetter, IPseudoJetGetter)
-public:
-  TrackPseudoJetGetter(const std::string &name);
-
-  virtual StatusCode initialize() override;
-
-  /// Method to construct the PseudoJetVector and record in StoreGate
-  virtual StatusCode createAndRecord() const override;
-
-protected:
-  /// This will identify the input tracks (and so is templated on TrackParticleContainer).
-  /// We do not declare it as a property to avoid duplication with the base PseudoJetGetter::m_incoll. Instead we'll copy the key from PseudoJetGetter::m_incoll during initialize() (See this function)
-  SG::ReadHandleKey<xAOD::TrackParticleContainer> m_incolltrk;
-
-  SG::ReadHandleKey<jet::TrackVertexAssociation> m_inTVA;
-
-
-private:
-
-  std::vector<fastjet::PseudoJet> 
-  createPseudoJets(const xAOD::TrackParticleContainer*) const;
-
-  const PseudoJetContainer* getC() const;
-
-};
-
-#endif
diff --git a/Reconstruction/Jet/JetRecTools/Root/TrackExtractor.cxx b/Reconstruction/Jet/JetRecTools/Root/TrackExtractor.cxx
deleted file mode 100644
index 12e82f6e52246eb01650501e140a15d8fd57f078..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRecTools/Root/TrackExtractor.cxx
+++ /dev/null
@@ -1,101 +0,0 @@
-// this file is -*- C++ -*-
-
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// MuonSegmentExtractor.cxx
-
-#include "JetRecTools/TrackExtractor.h"
-#include "JetRec/LineFormatter.h" // helper class for debug printing
-#include "xAODJet/Jet.h"
-#include "xAODTracking/TrackParticleContainer.h"
-#include "JetRec/setAssocObjectsSummary.h"
-#include <vector>
-
-TrackExtractor::TrackExtractor(const xAOD::TrackParticleContainer* tps,
-                               const std::string & label,
-                               bool isGhost) : 
-   m_originalParticles(tps), m_label(label), m_isGhost(isGhost){
-}
-
-TrackExtractor::~TrackExtractor(){}
-
-TrackExtractor* TrackExtractor::clone() const {
-  // to be deleted by caller
-  return  new TrackExtractor(*this);
-}
-
-TrackExtractor* TrackExtractor::ghostClone() const {
-  // to be deleted by caller
-  auto clone =  new TrackExtractor(*this);
-  (*clone).m_isGhost = true;
-  return clone;
-}
-
-void TrackExtractor::addToJet(xAOD::Jet& jet, 
-                                  const std::vector<int>& indices) const{
-  //Add a template specialisation for muon segments
-
-  std::vector<const xAOD::TrackParticle*> constituents;
-  constituents.reserve(indices.size());
-  for(auto i : indices){constituents.push_back((*m_originalParticles)[i]);}
-
-  if(m_isGhost) {
-
-    std::vector<const xAOD::IParticle*> constituents;
-    constituents.reserve(indices.size());
-    for(auto i : indices){constituents.push_back((*m_originalParticles)[i]);}
-
-    jet.setAssociatedObjects(m_label, constituents);
-    setAssocObjectsSummary(constituents, m_label, jet);
-
-  } else {
-    // these are constituents
-    std::vector<const xAOD::TrackParticle*> constituents;
-    constituents.reserve(indices.size());
-    for(auto i : indices){constituents.push_back((*m_originalParticles)[i]);}
-    
-    for(auto c: constituents) {
-      jet.addConstituent(c);
-    }
-  }
-}
-
-
-
-bool TrackExtractor::checkIntegrity() const {
-  for(const auto ip: *m_originalParticles){
-    try{
-      ip->e();
-    } catch(...) {
-      return false;
-    }
-  }
-  return true;
-}
-
-
-std::string TrackExtractor::toString(int level) const {
-  std::ostringstream oss{"", std::ios::ate};
-  oss << "TrackExtractor dump level(" << level << ")"
-     << " label " << m_label 
-     << " isGhost: "  << std::boolalpha << m_isGhost 
-     << " No of TrackParticles: " << m_originalParticles->size();
-
-  if (level > 0){
-    oss << "\n TrackParticle energies\n";
-    std::vector<float> energies;
-    energies.reserve(m_originalParticles->size());
-    std::transform(m_originalParticles->begin(),
-                   m_originalParticles->end(),
-                   std::back_inserter(energies),
-                   [](const xAOD::TrackParticle* p){return p->e();});
-
-    LineFormatter formatter(10); // 10 numbers/line
-    oss << formatter(energies);
-  }
-
-  return oss.str();
-}
-
diff --git a/Reconstruction/Jet/JetRecTools/Root/TrackPseudoJetGetter.cxx b/Reconstruction/Jet/JetRecTools/Root/TrackPseudoJetGetter.cxx
deleted file mode 100644
index eeac82f42f84367cc92e1cf77e6cbe3954c39905..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetRecTools/Root/TrackPseudoJetGetter.cxx
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "JetRecTools/TrackPseudoJetGetter.h"
-#include "JetEDM/VertexIndexedConstituentUserInfo.h"
-
-#include "JetEDM/TrackVertexAssociation.h"
-
-#include "JetRec/PseudoJetContainer.h"
-#include "JetRecTools/TrackExtractor.h"
-#include "xAODCaloEvent/CaloClusterContainer.h"
-#include "fastjet/PseudoJet.hh"
-#include "xAODTracking/TrackParticle.h"
-#include "xAODTracking/TrackParticleContainer.h"
-
-
-using fastjet::PseudoJet;
-
-
-TrackPseudoJetGetter::TrackPseudoJetGetter(const std::string &name) 
-  : PseudoJetGetter(name) , m_inTVA("JetTrackVtxAssoc") {
-  declareProperty("TrackVertexAssociation", m_inTVA, "SG key for the TrackVertexAssociation object");
-}
-
-//**********************************************************************
-StatusCode TrackPseudoJetGetter::initialize() {
-  ATH_MSG_DEBUG("Initializing...");
-
-  ATH_CHECK( PseudoJetGetter::initialize() );
-  ATH_CHECK( m_inTVA.initialize() );
-  m_incolltrk = m_incoll.key();
-  ATH_CHECK( m_incolltrk.initialize() );
-  print();
-  
-  return StatusCode::SUCCESS;
-}
-
-//**********************************************************************
-
-StatusCode TrackPseudoJetGetter::createAndRecord() const {
-  // Use const pointer for now, but can change to unique pointer when
-  // we move to DataVector and when MR 2431 is complete:
-  // https://gitlab.cern.ch/atlas/athena/merge_requests/2431
-  const PseudoJetContainer* pjc = this->getC();
-  if (!pjc) return StatusCode::FAILURE;
-
-  return StatusCode::SUCCESS;
-}
-
-//**********************************************************************
-const PseudoJetContainer* TrackPseudoJetGetter::getC() const {
-
-  ATH_MSG_DEBUG("Getting PseudoJetContainer in TrackPseudoJetGetter ...");
-  
-  // build and record the container
-  const xAOD::TrackParticleContainer* cont;
-  auto handle_in = SG::makeHandle(m_incolltrk);
-  if ( handle_in.isValid() ) {
-    ATH_MSG_DEBUG("Retrieving xAOD container " << m_incolltrk.key() << ", ghost scale=" << m_ghostscale  <<  ", isGhost=" << bool(m_ghostscale));
-    // retrieve the input.
-    cont = handle_in.cptr();
-  } else {
-    ATH_MSG_ERROR("Unable to find input collection: " << m_incolltrk.key());
-    ATH_MSG_ERROR("Error creating pseudojets.");
-    return nullptr;
-  }
-
-  SG::ReadHandle<jet::TrackVertexAssociation> h_tva(m_inTVA);
-
-  std::vector<PseudoJet> vpj = createPseudoJets(cont);
-
-  // "Ghost" in outout collection name? If so is a ghost collection.
-  bool isGhost = (m_outcoll.key()).find("Ghost") != std::string::npos;
-
-  // create an extractor
-  TrackExtractor* extractor = new TrackExtractor(cont, m_label, isGhost);
-
-  // ghostify the pseudojets if necessary
-  if(isGhost){
-    for(PseudoJet& pj : vpj) {pj *= 1e-40;}
-  }
-
-  // record
-  // to satisfy legacy code, need to return a bare pointer as well
-  // as write to storegate. so no calls to  make_unique...
-
-  SG::WriteHandle<PseudoJetContainer> handle_out(m_outcoll);
-  PseudoJetContainer*  pjcont = new PseudoJetContainer(extractor, vpj);
-  
-  if(!handle_out.record(std::unique_ptr<PseudoJetContainer>(pjcont))){
-    ATH_MSG_DEBUG("Error storing PseudoJetContainer in event "
-                  << " at key " << m_outcoll.key());
-  } else {
-    //ATH_MSG_DEBUG("PseudoJetContainer in event store with extractor: " 
-    //               << extractor->toString(0)
-    //             << " at key " << m_outcoll.key());
-  }
-
-  return pjcont;
-
-}
-
-std::vector<PseudoJet> 
-TrackPseudoJetGetter::createPseudoJets(const xAOD::TrackParticleContainer* ips) const {
-
-  std::vector<PseudoJet> vpj;
-  // create PseudoJets
-  int index=-1;
-  for(const xAOD::TrackParticle* part: *ips) {
-    index++;
-    
-    if ( part == 0 || (m_skipNegativeEnergy && part->e() <= 0.0) ) {
-      if ( part == 0 ) ATH_MSG_DEBUG("NUll object!");
-      else ATH_MSG_VERBOSE("Skipping cluster with E = " << part->e());
-      //++nskip;
-      continue;
-    }
-    
-    // Take momentum from TrackParticle.
-    fastjet::PseudoJet psj(part->p4());
-    
-    // const xAOD::Vertex* vtx = h_tva->associatedVertex(part);
-    //jet::IConstituentUserInfo* pcui = this->buildCUI(trk, vtx, labidx, pli);
-    //psj.set_user_info(pcui);
-    
-    vpj.push_back( psj );
-    vpj.back().set_user_index(index); // Set the index !!
-  }
-
-  return vpj;
-}
-
-
diff --git a/Reconstruction/Jet/JetRecTools/src/components/JetRecTools_entries.cxx b/Reconstruction/Jet/JetRecTools/src/components/JetRecTools_entries.cxx
index 25344aa54d8a03f55331388e5ebcd43c3f807ba5..8aabec619b260e0358a9bb68f08660464f98becf 100644
--- a/Reconstruction/Jet/JetRecTools/src/components/JetRecTools_entries.cxx
+++ b/Reconstruction/Jet/JetRecTools/src/components/JetRecTools_entries.cxx
@@ -2,8 +2,6 @@
 #include "JetRecTools/JetTrackSelectionTool2.h"
 #include "JetRecTools/SimpleJetTrackSelectionTool.h"
 #include "JetRecTools/TrackVertexAssociationTool.h"
-#include "JetRecTools/TrackPseudoJetGetter.h"
-// #include "JetRecTools/PFlowPseudoJetGetter.h"
 #include "JetRecTools/JetConstituentModSequence.h"
 #include "JetRecTools/JetConstituentModifierBase.h"
 #include "JetRecTools/CaloClusterConstituentsOrigin.h"
@@ -21,8 +19,6 @@ DECLARE_COMPONENT( JetTrackSelectionTool )
 DECLARE_COMPONENT( JetTrackSelectionTool2 )
 DECLARE_COMPONENT( SimpleJetTrackSelectionTool )
 DECLARE_COMPONENT( TrackVertexAssociationTool )
-DECLARE_COMPONENT( TrackPseudoJetGetter )
-// DECLARE_COMPONENT( PFlowPseudoJetGetter )
 DECLARE_COMPONENT( JetConstituentModSequence )
 DECLARE_COMPONENT( JetConstituentModifierBase )
 DECLARE_COMPONENT( CaloClusterConstituentsOrigin )
diff --git a/Reconstruction/Jet/JetSimTools/JetSimTools/TruthParticleExtractor.h b/Reconstruction/Jet/JetSimTools/JetSimTools/TruthParticleExtractor.h
deleted file mode 100644
index 90613f611975b6b7386d219061657a0d4be5ed62..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetSimTools/JetSimTools/TruthParticleExtractor.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// this file is -*- C++ -*-
-// TruthParticleExtractor.h
-
-
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef TruthParticleExtractor_H
-#define TruthParticleExtractor_H
-
-#include "JetRec/IConstituentExtractor.h"
-#include "xAODJet/Jet.h"
-#include "xAODTruth/TruthParticleContainer.h"
-#include <string>
-
-class TruthParticleExtractor : public IConstituentExtractor {
-
-public:
-  TruthParticleExtractor(const xAOD::TruthParticleContainer* tps,
-                         const std::string & label,
-                         bool isGhost);
-
-  virtual ~TruthParticleExtractor();
-  virtual TruthParticleExtractor* clone() const override;
-  virtual TruthParticleExtractor* ghostClone() const override;
-  virtual void 
-  addToJet(xAOD::Jet&, const std::vector<int>& indices) const override;
-  virtual std::string toString(int) const override;
-  virtual bool checkIntegrity() const override;
-
-private:
-  const xAOD::TruthParticleContainer* m_originalParticles;
-  std::string m_label;
-  bool m_isGhost; 
-
-};
-
-#endif
diff --git a/Reconstruction/Jet/JetSimTools/JetSimTools/TruthPseudoJetGetter.h b/Reconstruction/Jet/JetSimTools/JetSimTools/TruthPseudoJetGetter.h
deleted file mode 100644
index ae728fa9e80542429e0da4332cd0d125667e795d..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetSimTools/JetSimTools/TruthPseudoJetGetter.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// emacs this file is -*- c++ -*-
-// this file is -*- C++ -*-
-
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef JETSIMTOOLS_TRUTHPSEUDOJETGETTER_H
-#define JETSIMTOOLS_TRUTHPSEUDOJETGETTER_H
-
-#include "GaudiKernel/ToolHandle.h"
-#include "JetRec/PseudoJetGetter.h"
-#include "JetSimTools/JetTruthParticleSelectorTool.h"
-#include "xAODTruth/TruthParticleContainer.h"
-
-class TruthPseudoJetGetter : public PseudoJetGetter {
-  ASG_TOOL_CLASS(TruthPseudoJetGetter, IPseudoJetGetter)
-public:
-  TruthPseudoJetGetter(const std::string &name);
-  
-
-  virtual StatusCode initialize() override;
-
-  /// Method to construct the PseudoJetVector and record in StoreGate
-  virtual StatusCode createAndRecord() const override;
-
-  // Kept for backward compatibity
-  virtual const PseudoJetVector* get() const override;
-
-
-protected:
-
-  /// Input collection name.
-  SG::ReadHandleKey<xAOD::TruthParticleContainer> m_incolltruth;
-
-  ToolHandle<JetTruthParticleSelectorTool> m_selector;
-
-private:
-  const PseudoJetContainer* getC() const;
-
-};
-
-#endif
diff --git a/Reconstruction/Jet/JetSimTools/Root/TruthParticleExtractor.cxx b/Reconstruction/Jet/JetSimTools/Root/TruthParticleExtractor.cxx
deleted file mode 100644
index 6046c05e1febf15b128c2fa98a2304c731c16777..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetSimTools/Root/TruthParticleExtractor.cxx
+++ /dev/null
@@ -1,92 +0,0 @@
-
-// this file is -*- C++ -*-
-
-
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-
-// TruthParticleExtractor.cxx
-
-#include "JetSimTools/TruthParticleExtractor.h"
-#include "JetRec/LineFormatter.h" // helper class for debug printing
-#include "xAODTruth/TruthParticleContainer.h"
-#include "xAODTruth/TruthParticle.h"
-#include "JetRec/setAssocObjectsSummary.h"
-#include <vector>
-#include <string>
-
-TruthParticleExtractor::TruthParticleExtractor(const xAOD::TruthParticleContainer* tps,
-                                               const std::string & label,
-                                               bool isGhost) : 
-   m_originalParticles(tps), m_label(label), m_isGhost(isGhost){
-}
-
-TruthParticleExtractor::~TruthParticleExtractor(){}
-
-TruthParticleExtractor* TruthParticleExtractor::clone() const {
-  return new TruthParticleExtractor(*this);
-}
-
-TruthParticleExtractor* TruthParticleExtractor::ghostClone() const {
-  // caller to delete 
-  auto clone =  new TruthParticleExtractor(*this);
-  (*clone).m_isGhost = true;
-  return clone;
-}
-
-void TruthParticleExtractor::addToJet(xAOD::Jet& jet, 
-                                  const std::vector<int>& indices) const{
-  //Add a template specialisation for muon segments
-
-  std::vector<const xAOD::IParticle*> constituents;
-  constituents.reserve(indices.size());
-  for(auto i : indices){constituents.push_back((*m_originalParticles)[i]);}
-
-  if(m_isGhost) {
-    jet.setAssociatedObjects(m_label, constituents);
-    setAssocObjectsSummary(constituents, m_label, jet);
-  } else {
-    // these are constituents 
-    for(auto c: constituents) {
-      jet.addConstituent(c);
-    }
-  }
-}
-
-
-std::string TruthParticleExtractor::toString(int level) const {
-  std::ostringstream oss{"", std::ios::ate};
-  oss << "TruthParticleExtractor dump level (" << level << ")"
-
-     << " label " << m_label 
-     << " isGhost: " << std::boolalpha << m_isGhost 
-     << " No of TruthParticles: " << m_originalParticles->size();
-
-  if (level > 0){
-    oss << "\n TruthParticle energies\n";
-    std::vector<float> energies;
-    energies.reserve(m_originalParticles->size());
-    std::transform(m_originalParticles->begin(),
-                   m_originalParticles->end(),
-                   std::back_inserter(energies),
-                   [](const xAOD::TruthParticle* p){return p->e();});
-
-    LineFormatter formatter(10); // 10 numbers/line
-    oss << formatter(energies);
-  }
-
-  return oss.str();
-}
-
-
-bool TruthParticleExtractor::checkIntegrity() const {
-  for(const auto tp: *m_originalParticles){
-    try{
-      tp->e();
-    } catch(...) {
-      return false;
-    }
-  }
-  return true;
-}
diff --git a/Reconstruction/Jet/JetSimTools/Root/TruthPseudoJetGetter.cxx b/Reconstruction/Jet/JetSimTools/Root/TruthPseudoJetGetter.cxx
deleted file mode 100644
index 24a1fd7404334c63f8852cc304394c3f1fe87df9..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetSimTools/Root/TruthPseudoJetGetter.cxx
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-// TruthPseudoJetGetter.cxx
-
-#include "JetSimTools/TruthPseudoJetGetter.h"
-#include "xAODTruth/TruthParticleContainer.h"
-#include "JetRec/PseudoJetContainer.h"
-#include "JetSimTools/TruthParticleExtractor.h"
-
-
-using fastjet::PseudoJet;
-
-
-//**********************************************************************
-
-TruthPseudoJetGetter::TruthPseudoJetGetter(const std::string &name)
-: PseudoJetGetter(name),
-  m_selector("JetTruthParticleSelectorTool") {
-  declareProperty("TruthSelector", m_selector);
-  declareProperty("InputContainer", m_incolltruth);
-  declareProperty("OutputContainer", m_outcoll);
-}
-
-//**********************************************************************
-
-StatusCode TruthPseudoJetGetter::initialize() {
-  
-  StatusCode sc= m_selector.retrieve();
-  if ( sc.isFailure() ) {
-    ATH_MSG_ERROR( "Unable to retrieve TruthSelector.");
-    return sc;
-  }
-  m_incolltruth = m_incoll.key();
-  ATH_CHECK( m_incolltruth.initialize() );
-  ATH_CHECK( m_outcoll.initialize() );
-
-  return StatusCode::SUCCESS;
-
-}
-
-//**********************************************************************
-
-const PseudoJetContainer* TruthPseudoJetGetter::getC() const {
-  ATH_MSG_DEBUG("Getting TruthPseudoJetContainer...");
-  std::vector<PseudoJet> vpj;
-  const PseudoJetContainer * pjcont;
-
-  // build and record the container
-  // retrieve the input.
-  const xAOD::TruthParticleContainer* cont;
-  auto handle_in = SG::makeHandle(m_incolltruth);
-  if ( handle_in.isValid() ) {
-    ATH_MSG_DEBUG("Retrieving xAOD container " << m_incolltruth.key());
-    // retrieve the input.
-    cont = handle_in.cptr();
-  } else {
-    ATH_MSG_ERROR("Unable to find input collection: " << m_incolltruth.key());
-    ATH_MSG_ERROR("Error creating pseudojets.");
-    return nullptr;
-  }
-
-  // create PseudoJets
-  int index=0;
-  for(const xAOD::TruthParticle* part: *cont) {
-    vpj.push_back( PseudoJet(part->p4()));
-    vpj.back().set_user_index(index); // Set the index !!
-    index++;
-  }
-
-
-  // "Ghost" in outout collection name? If so is a ghost collection.
-  bool isGhost = (m_outcoll.key()).find("Ghost") != std::string::npos;
-
-  // create an extractor
-  TruthParticleExtractor* extractor = new TruthParticleExtractor(cont,
-                                                                 m_label, 
-                                                                 isGhost);
-
-  // ghostify the pseudojets if necessary
-  if(isGhost){
-    for(PseudoJet& pj : vpj) {pj *= 1e-40;}
-  }
-
-  // Put the PseudoJetContainer together :
-  pjcont = new PseudoJetContainer(extractor, vpj);
-  std::unique_ptr<const PseudoJetContainer> pjcont_ptr(pjcont);
-  
-  // record
-  SG::WriteHandle<PseudoJetContainer> handle_out(m_outcoll);
-  ATH_MSG_DEBUG("New PseudoJetContainer in event store with extractor: " 
-                << extractor->toString(0));
-  if ( ! handle_out.put(std::move(pjcont_ptr))) {
-    ATH_MSG_ERROR("Unable to write new PseudoJetContainer to event store collection: " << m_outcoll.key());
-  } else {
-    ATH_MSG_DEBUG("Created new PseudoJetContainer in event store collection: " << m_outcoll.key());
-  }
-
-  return pjcont;
-
-}
-
-
-StatusCode TruthPseudoJetGetter::createAndRecord() const {
-  // Use const pointer for now, but can change to unique pointer when
-  // we move to DataVector and when MR 2431 is complete:
-  // https://gitlab.cern.ch/atlas/athena/merge_requests/2431
-
-  // should rename getC createAndRecord once get() is removed.
-  const PseudoJetContainer* pjc = this->getC();
-  if (!pjc) return StatusCode::FAILURE;
-
-  return StatusCode::SUCCESS;
-}
-
-
-const PseudoJetVector* TruthPseudoJetGetter::get() const {
-  // Kept for backward compatibity
-  ATH_MSG_DEBUG("Getting TruthPseudoJetContainer as PseudoJetVector ...");
-  const PseudoJetContainer* cont = this->getC();
-  const PseudoJetVector* vpj = cont->casVectorPseudoJet(); 
-  return vpj;
-}
diff --git a/Reconstruction/Jet/JetSimTools/python/TruthPseudoJetGetterConfig.py b/Reconstruction/Jet/JetSimTools/python/TruthPseudoJetGetterConfig.py
deleted file mode 100644
index 8f375b61bc9e25bfc9eabd49aaacf7681678c26d..0000000000000000000000000000000000000000
--- a/Reconstruction/Jet/JetSimTools/python/TruthPseudoJetGetterConfig.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-from JetSimTools.JetSimToolsConf import TruthPseudoJetGetter, JetTruthParticleSelectorTool
-
-def getJetTruthParticleSelectorTool(selectionMode="StableNoMuonNoNu" , **options):
-    toolName = "JetTruthSelector"+selectionMode
-    selecTool = JetTruthParticleSelectorTool(toolName,
-                                             SelectionMode = selectionMode,
-                                             )
-    from AthenaCommon.AppMgr import ToolSvc
-    ToolSvc += selecTool
-    return selecTool
-
-from AthenaCommon.AppMgr import ToolSvc
-
-ToolSvc += JetTruthParticleSelectorTool("JetTruthSelectorStableNoMuonNoNu",
-                                        SelectionMode = "StableNoMuonNoNu"
-                                        )
-
-
-## def getTruthPseudoJetGetter(input, asGhost, **options):
-
-##     inCont = "TruthParticle"
-
-##     prefix = "Ghost" if asGhost else ""
-
-##     outCont = prefix+"PseudoJet_"+inCont
-
-    
-##     tool = TruthPseudoJetGetter( "PJGetter"+prefix+inCont,
-##                                  InputContainer = inCont,
-##                                  OutputContainer = outCont,
-##                                  TruthSelector = getJetTruthParticleSelectorTool(**options),
-##                                  SkipNegativeEnergy = True)
-
-##     from AthenaCommon.AppMgr import ToolSvc
-##     ToolSvc += tool
-##     return tool
diff --git a/Reconstruction/Jet/JetSimTools/src/components/JetSimTools_entries.cxx b/Reconstruction/Jet/JetSimTools/src/components/JetSimTools_entries.cxx
index 39ef3db22945110569edfd7221708d3b38cf7dfa..ba8cd69467df9f9d4c1d827106490e7aa5afcdbd 100644
--- a/Reconstruction/Jet/JetSimTools/src/components/JetSimTools_entries.cxx
+++ b/Reconstruction/Jet/JetSimTools/src/components/JetSimTools_entries.cxx
@@ -1,8 +1,6 @@
 #include "JetSimTools/JetTruthParticleSelectorTool.h"
-#include "JetSimTools/TruthPseudoJetGetter.h"
 
 
 DECLARE_COMPONENT( JetTruthParticleSelectorTool )
 
-DECLARE_COMPONENT( TruthPseudoJetGetter )
 
diff --git a/Reconstruction/RecoAlgs/IsolationAlgs/python/IsoGetter.py b/Reconstruction/RecoAlgs/IsolationAlgs/python/IsoGetter.py
index 5174c09dcd021f94c91e18a35d79353d9bb68e51..64ca2286f62992615121a64fd2f7534a5408a553 100644
--- a/Reconstruction/RecoAlgs/IsolationAlgs/python/IsoGetter.py
+++ b/Reconstruction/RecoAlgs/IsolationAlgs/python/IsoGetter.py
@@ -41,8 +41,8 @@ if recAlgs.doEFlow() :
                                        name = "PFlowObjectsInConeTool")
 
   from JetRec.JetRecStandard import jtm
-  from JetRec.JetRecConf import PseudoJetGetter
-  emnpflowget = PseudoJetGetter(
+  from JetRec.JetRecConf import PseudoJetAlgorithm
+  emnpflowget = PseudoJetAlgorithm(
     name               = "emnpflowget",
     Label              = "EMNPFlow",
     InputContainer = "CHSNeutralParticleFlowObjects",
@@ -50,13 +50,11 @@ if recAlgs.doEFlow() :
     SkipNegativeEnergy = True,
     )
   jtm += emnpflowget
-  # PseudoJetGetters are now run in their own dedicated algs
-  from JetRec.JetRecConf import PseudoJetAlgorithm
   # EMTopo (non-origin corrected) clusters
-  if not hasattr(topSequence, "pjalg_"+jtm.emget.Label):
-    topSequence += PseudoJetAlgorithm("pjalg_"+jtm.emget.Label,PJGetter=jtm.emget)
+  if not hasattr(topSequence, jtm.emget.name()):
+    topSequence += jtm.emget
   # EM Neutral PFOs
-  topSequence += PseudoJetAlgorithm("pjalg_"+emnpflowget.Label,PJGetter=emnpflowget)
+  topSequence += emnpflowget
 
 # tool to collect topo clusters in cone
 from ParticlesInConeTools.ParticlesInConeToolsConf import xAOD__CaloClustersInConeTool
@@ -87,13 +85,12 @@ def configureEDCorrection(tool):
   try:
     from AthenaCommon.AppMgr import ToolSvc
     from JetRec.JetRecStandard import jtm
-    from JetRec.JetRecConf import PseudoJetAlgorithm
     from EventShapeTools.EventDensityConfig import configEventDensityTool, EventDensityAthAlg
     from AthenaCommon.AlgSequence import AlgSequence
     topSequence = AlgSequence()
     # EMTopo (non-origin corrected) clusters
-    if not hasattr(topSequence, "pjalg_"+jtm.emget.Label):
-      topSequence += PseudoJetAlgorithm("pjalg_"+jtm.emget.Label,PJGetter=jtm.emget)
+    if not hasattr(topSequence, jtm.emget.name()):
+      topSequence += jtm.emget
     if not hasattr(topSequence,'EDtpIsoCentralAlg'):
       tccc = configEventDensityTool("EDtpIsoCentralTool",
                                     inputlabel = jtm.emget.Label,
diff --git a/Trigger/TrigAlgorithms/TrigHIRec/python/TrigHLTHIJetRecConfig.py b/Trigger/TrigAlgorithms/TrigHIRec/python/TrigHLTHIJetRecConfig.py
index 3ddcfaf16cd9345f4f1fea982bb47e8ab7913931..41f793cac704ff2de0869a6a89bfa6898bdebb37 100644
--- a/Trigger/TrigAlgorithms/TrigHIRec/python/TrigHLTHIJetRecConfig.py
+++ b/Trigger/TrigAlgorithms/TrigHIRec/python/TrigHLTHIJetRecConfig.py
@@ -8,7 +8,6 @@ from AthenaCommon.SystemOfUnits import MeV
 from JetRec.JetRecConf import JetRecTool
 from JetRec.JetRecConf import (JetFromPseudojet,
                                JetFinder)
-from JetRec.JetRecConf import PseudoJetGetter 	#added
 from JetRec.JetRecFlags import jetFlags
 from JetRec.JetRecStandard import jtm
 from JetRec.JetRecCalibrationFinder import jrcf
diff --git a/Trigger/TrigAlgorithms/TrigHLTJetRec/TrigHLTJetRec/TriggerPseudoJetGetter.h b/Trigger/TrigAlgorithms/TrigHLTJetRec/TrigHLTJetRec/TriggerPseudoJetGetter.h
index b9a685980e4ccef2f710bbfe49912ae1c04d2d13..38c82fa77b4e604ac769c07f68a5c8774ac627d8 100644
--- a/Trigger/TrigAlgorithms/TrigHLTJetRec/TrigHLTJetRec/TriggerPseudoJetGetter.h
+++ b/Trigger/TrigAlgorithms/TrigHLTJetRec/TrigHLTJetRec/TriggerPseudoJetGetter.h
@@ -18,7 +18,7 @@
 #define TRIGHLTJETREC_TRIGGERPSEUDOJETGETTER_H
 
 #include "TrigHLTJetRec/ITriggerPseudoJetGetter.h"
-#include "JetRec/PseudoJetGetter.h"
+#include "JetInterface/IPseudoJetGetter.h"
 #include "JetEDM/PseudoJetVector.h"
 #include "AsgTools/AsgTool.h"
 
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref
index e7fd62710811777602f8095c27719487a9ffda1d..ef9cd5989cb6344ffcf295485d75af3f0b583740 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref
@@ -224,8 +224,8 @@ TrigSignatureMoniMT                                INFO HLT_j45_ftf_L1J15 #86840
 TrigSignatureMoniMT                                INFO -- #868405538 Events          20         20         19         -          -          -          -          -          19
 TrigSignatureMoniMT                                INFO -- #868405538 Features                              50         -          -          -          -          -
 TrigSignatureMoniMT                                INFO HLT_j45_ftf_csskpf_nojcalib_L1J20 #3533281867
-TrigSignatureMoniMT                                INFO -- #3533281867 Events         19         19         19         -          -          -          -          -          19
-TrigSignatureMoniMT                                INFO -- #3533281867 Features                             64         -          -          -          -          -
+TrigSignatureMoniMT                                INFO -- #3533281867 Events         19         19         15         -          -          -          -          -          15
+TrigSignatureMoniMT                                INFO -- #3533281867 Features                             25         -          -          -          -          -
 TrigSignatureMoniMT                                INFO HLT_j45_ftf_pf_L1J20 #1335156103
 TrigSignatureMoniMT                                INFO -- #1335156103 Events         19         19         16         -          -          -          -          -          16
 TrigSignatureMoniMT                                INFO -- #1335156103 Features                             31         -          -          -          -          -
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
index efe31ef61a6eb148516be9100485eed2d468ec9e..085a0dc22a553240b21dea255500d771a0fe94fa 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
@@ -71,7 +71,7 @@ def jetRecoSequence( dummyFlags, dataSource, RoIs = 'FSJETRoI', **jetRecoDict):
         rcJetDef.modifiers = rcModList
 
         rcConstitPJAlg = getConstitPJGAlg( rcJetDef.inputdef )
-        rcConstitPJKey = rcConstitPJAlg.PJGetter.OutputContainer
+        rcConstitPJKey = rcConstitPJAlg.OutputContainer
         recoSeq += conf2toConfigurable( rcConstitPJAlg )
 
         rcPJs = [rcConstitPJKey]
@@ -144,7 +144,7 @@ def jetRecoSequence( dummyFlags, dataSource, RoIs = 'FSJETRoI', **jetRecoDict):
 
         # Add the PseudoJetGetter alg to the sequence
         constitPJAlg = getConstitPJGAlg( jetDef.inputdef )
-        constitPJKey = constitPJAlg.PJGetter.OutputContainer
+        constitPJKey = constitPJAlg.OutputContainer
         recoSeq += conf2toConfigurable( constitPJAlg )
         # Basic list of PseudoJets is just the constituents
         # Append ghosts (tracks) if desired
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetTrackingConfig.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetTrackingConfig.py
index 62825ec4bbda69578383bc6da9b15a6870631d25..6ba1e551e8f5ed1ad6a3f4b3bd39cae2b67493f8 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetTrackingConfig.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetTrackingConfig.py
@@ -52,19 +52,17 @@ def JetTrackingSequence(dummyFlags,trkopt,RoIs):
 
     label = "GhostTrack_{}".format(trkopt)
     ghosttracksname = "PseudoJet{}".format(label)
-    pjg = CompFactory.PseudoJetGetter("pjg_{}".format(label),
-                                     InputContainer=tracksname,
-                                     OutputContainer=ghosttracksname,
-                                     Label=label,
-                                     SkipNegativeEnergy=True,
-                                     GhostScale=1e-40)
 
     trackcollectionmap[trkopt]["GhostTracks"] = ghosttracksname
     trackcollectionmap[trkopt]["GhostTracksLabel"] = label
 
     pjgalg = CompFactory.PseudoJetAlgorithm(
         "pjgalg_"+label,
-        PJGetter=pjg
+        InputContainer=tracksname,
+        OutputContainer=ghosttracksname,
+        Label=label,
+        SkipNegativeEnergy=True,
+        GhostScale=1e-40
         )
     jetTrkSeq += conf2toConfigurable( pjgalg )