diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py
index d19db4f14131f75282acb4df1e218dacf875639c..b2ff431f05e69dfd5a58906e35630479278ab0cf 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py
@@ -1,9 +1,9 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
 AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent = [
 "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
-"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
-"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m", "AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Tau4_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.ThrustMaj.L2.L3",
 "AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.Parent.DetectorEta.DetectorY",
 "AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.R10TruthLabel_R21Consolidated.R10TruthLabel_R21Precision",
 "AntiKt10UFOCSSKJets",
diff --git a/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h b/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h
index 860fe55e4f433970766b2870b5bc18cd0a8f23bb..c24c3fd1cfb99ac4c11b7979b6a7916e6c0d3ded 100644
--- a/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h
+++ b/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h
@@ -123,6 +123,7 @@ private:
   std::string m_vertexContainerName;
   bool m_insituCombMassCalib;
   std::vector<TString> m_insituCombMassConfig;
+  std::string m_rhoKey_config;
 
   //TEnv to hold the global text config
   TEnv * m_globalConfig;
diff --git a/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx b/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx
index 54bd7b8aaf336647d54192198acba837f5ab59ff..2c5a51c56daad8ea4f7c3c458bda205cade3f999 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx
+++ b/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx
@@ -153,6 +153,9 @@ StatusCode JetCalibrationTool::initializeTool(const std::string& name) {
   m_originCorrectedClusters = m_globalConfig->GetValue("OriginCorrectedClusters",false);
   m_doSetDetectorEta = m_globalConfig->GetValue("SetDetectorEta",true);
 
+  // Rho key specified in the config file?
+  m_rhoKey_config = m_globalConfig->GetValue("RhoKey", "None");
+
   // Get name of vertex container
   m_vertexContainerName = m_globalConfig->GetValue("VertexContainerName","PrimaryVertices");
   
@@ -161,7 +164,7 @@ StatusCode JetCalibrationTool::initializeTool(const std::string& name) {
     m_doJetArea = false;
     m_doResidual = false;
   } else if ( calibSeq.Contains("JetArea") ) {
-    if ( m_rhoKey.compare("auto") == 0 ) {
+    if ( m_rhoKey.compare("auto") == 0 && m_rhoKey_config.compare("None") == 0) {
       if(!m_originCorrectedClusters){
         if ( m_jetScale == EM ) m_rhoKey = "Kt4EMTopoEventShape";
         else if ( m_jetScale == LC ) m_rhoKey = "Kt4LCTopoEventShape";
@@ -172,6 +175,9 @@ StatusCode JetCalibrationTool::initializeTool(const std::string& name) {
         else if ( m_jetScale == PFLOW ) m_rhoKey = "Kt4EMPFlowEventShape";
       }
     }
+    else if(m_rhoKey_config.compare("None") != 0 && m_rhoKey.compare("auto") == 0){
+      m_rhoKey = m_rhoKey_config;
+    }
     ATH_CHECK( m_rhkRhoKey.assign(m_rhoKey)) ;  // set in `initializeTool'
     ATH_CHECK( m_rhkRhoKey.initialize() );
     if ( !calibSeq.Contains("Residual") ) m_doResidual = false;
diff --git a/Reconstruction/Jet/JetCalibTools/Root/JetPileupCorrection.cxx b/Reconstruction/Jet/JetCalibTools/Root/JetPileupCorrection.cxx
index de311bb209163b98fdb0abe8bfb0fe267ad90687..1ed73b9ad86ebbc7b0ffff859d939ea41bad69d4 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/JetPileupCorrection.cxx
+++ b/Reconstruction/Jet/JetCalibTools/Root/JetPileupCorrection.cxx
@@ -3,6 +3,7 @@
 */
 
 #include "JetCalibTools/CalibrationMethods/JetPileupCorrection.h"
+#include "PathResolver/PathResolver.h"
 #include "PUResidual3DCorrection.h"
 
 JetPileupCorrection::JetPileupCorrection()
@@ -118,13 +119,30 @@ StatusCode JetPileupCorrection::initializeTool(const std::string& name) {
 
   if(m_do3Dcorrection){
     m_residual3DCorr.reset( new PUCorrection::PU3DCorrectionHelper() ) ;
-    m_residual3DCorr->loadParameters(m_config->GetValue("PU3DCorrection.constants", "pu3DResidualsConstants.root") );
+
+    TString PUCalibFile3D = m_config->GetValue("PU3DCorrection.constants", "pu3DResidualsConstants.root");
+
+    if(m_dev){
+      //Currently hard coded that we remove "JetCalibTools/CalibrationFactors/" from the string in dev mode
+      //Same implementation as in other JetCalibTools classes for now, will be changed everywhere during major overhaul of package for r22
+      PUCalibFile3D.Remove(0,33);
+      PUCalibFile3D.Insert(0,"JetCalibTools/");
+    }
+    else{
+      PUCalibFile3D.Insert(14,m_calibAreaTag);
+    }
+
+    const std::string calibFilePU = PathResolverFindCalibFile(PUCalibFile3D.Data());
+
+    m_residual3DCorr->loadParameters(calibFilePU);
     m_residual3DCorr->m_rhoEnergyScale = m_config->GetValue("PU3DCorrection.rhoEnergyScale", 0.001);
     m_residual3DCorr->m_pTEnergyScale = m_config->GetValue("PU3DCorrection.pTEnergyScale", 0.001);
+    m_residual3DCorr->m_applyDeltaPtTerm = m_config->GetValue("PU3DCorrection.applyDeltaPtTerm", true);
     ATH_MSG_INFO("Pile-up 3D correction. Configured with :");
     ATH_MSG_INFO("  calib constants file="<< m_config->GetValue("PU3DCorrection.constants", "pu3DResidualsConstants.root") );
     ATH_MSG_INFO("  rho scale ="<<m_residual3DCorr->m_rhoEnergyScale );
     ATH_MSG_INFO("  pT scale ="<<m_residual3DCorr->m_pTEnergyScale);
+    ATH_MSG_INFO("  apply deltaPt term = " << m_residual3DCorr->m_applyDeltaPtTerm);
   } else if ( m_doResidual ) {
     std::string suffix = "_Residual";
     m_residualOffsetCorr = new ResidualOffsetCorrection(name+suffix,m_config,m_jetAlgo,m_calibAreaTag,m_isData,m_dev);
@@ -174,6 +192,8 @@ StatusCode JetPileupCorrection::calibrateImpl(xAOD::Jet& jet, JetEventInfo& jetE
     double pt_calib= m_residual3DCorr->correctedPt(pT_det,  eta_det, jetareaP4.Pt(), rho, mu, NPV ) ;
     double scaleF = pt_calib < 0 ? 0.01*m_GeV/pT_det : pt_calib/pT_det;
     xAOD::JetFourMom_t calibP4 = jetStartP4 * scaleF;
+    jet.setAttribute<int>("PileupCorrected",true);
+    jet.setAttribute<xAOD::JetFourMom_t>("JetPileupScaleMomentum",calibP4);
     jet.setJetP4( calibP4 );
 
   } else if (m_useFull4vectorArea) {
diff --git a/Reconstruction/Jet/JetCalibTools/Root/JetSmearingCorrection.cxx b/Reconstruction/Jet/JetCalibTools/Root/JetSmearingCorrection.cxx
index 94ccbab3cd766e292ff1fdb4f49cc3de539712b1..798ba63ab1a28d1246cb378136c922f167a9fae5 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/JetSmearingCorrection.cxx
+++ b/Reconstruction/Jet/JetCalibTools/Root/JetSmearingCorrection.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "JetCalibTools/CalibrationMethods/JetSmearingCorrection.h"
@@ -424,7 +424,10 @@ StatusCode JetSmearingCorrection::calibrateImpl(xAOD::Jet& jet, JetEventInfo&) c
         return StatusCode::FAILURE;
 
     // Set the random seed deterministically using jet phi
-    m_rand.SetSeed(1.e+5*(1.+fabs(jet.phi())));
+    unsigned long seed = static_cast<unsigned long>(1.e5*fabs(jet.phi()));
+    // SetSeed(0) uses the clock, so avoid this
+    if(seed == 0) seed = 45583453; // arbitrary number which the seed couldn't otherwise be
+    m_rand.SetSeed(seed);
 
     // Get the Gaussian-distributed random number
     // Force this to be a positive value
diff --git a/Reconstruction/Jet/JetCalibTools/Root/PUResidual3DCorrection.h b/Reconstruction/Jet/JetCalibTools/Root/PUResidual3DCorrection.h
index 1a2aa328bfea1c707311527fb826318841b77567..c98487b9e0a5035cba55d1eea8c631cc97f3e5b1 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/PUResidual3DCorrection.h
+++ b/Reconstruction/Jet/JetCalibTools/Root/PUResidual3DCorrection.h
@@ -40,7 +40,10 @@ namespace PUCorrection {
 					 mu,
 					 NPV);
       pt_ref =  pt_ref - areaCorr - calibration3D;
-      float deltaPt = deltaPtCorrection( pt_ref, eta );
+      float deltaPt = 0.0;
+      if(m_applyDeltaPtTerm){
+        deltaPt = deltaPtCorrection( pt_ref, eta );
+      }
 
       return (pt*m_pTEnergyScale -areaCorr - calibration3D + deltaPt)/m_pTEnergyScale;      
     }
@@ -196,6 +199,8 @@ namespace PUCorrection {
     float m_rhoEnergyScale = 0.001; // 0.001 when rho is given in MeV. 
     float m_pTEnergyScale = 0.001; // 0.001 when pT is given in MeV. 
 
+    bool m_applyDeltaPtTerm = true; //boolean to switch on/off the deltaPt correction
+    
     // ***************
     // 
     std::vector< std::vector<int> > m_closestNonEmpty;
diff --git a/Reconstruction/Jet/JetUncertainties/Root/JetUncertaintiesTool.cxx b/Reconstruction/Jet/JetUncertainties/Root/JetUncertaintiesTool.cxx
index 872693bc71384d90bdd4c4f6cb6cc131a5fd8b1d..a41612df7602933a6670814407b68385669875e4 100644
--- a/Reconstruction/Jet/JetUncertainties/Root/JetUncertaintiesTool.cxx
+++ b/Reconstruction/Jet/JetUncertainties/Root/JetUncertaintiesTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 // General package includes