diff --git a/.gitmodules b/.gitmodules
index 42b63331cc616564ed0bd04bfc1da56a40feb28a..b9128e9d8db9680f212d39e2f8cfa6d441becb67 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
-[submodule "BJetCalibrationTool"]
-	path = BJetCalibrationTool
-	url = https://gitlab.cern.ch/r3hh-public/b-jet-energy-corrections.git
 [submodule "KinematicFitTool"]
 	path = KinematicFitTool
 	url = https://gitlab.cern.ch/r3hh-public/KinematicFit.git
diff --git a/.mypy.ini b/.mypy.ini
index 753886c2d378426bc51881c198ca63a7f372cab9..de2d817de72241b98c35eebf59eec5e5b3168ef5 100644
--- a/.mypy.ini
+++ b/.mypy.ini
@@ -2,4 +2,3 @@
 # Permit imports that do not have type hints or stubs
 # We don't want to impose full checks on Athena packages
 ignore_missing_imports = True
-exclude = CalcGenericMT2/
diff --git a/BJetCalibrationTool b/BJetCalibrationTool
deleted file mode 160000
index cdf47363c10f71b55d3f445c37a26c9415bc21ef..0000000000000000000000000000000000000000
--- a/BJetCalibrationTool
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit cdf47363c10f71b55d3f445c37a26c9415bc21ef
diff --git a/EasyjetHub/python/algs/calibration/jets.py b/EasyjetHub/python/algs/calibration/jets.py
index a3edcc5cf60cb14da1fbec14df36f967e41e8f4f..8b3f998a500527b23e7711ddab8620c1c3c38545 100644
--- a/EasyjetHub/python/algs/calibration/jets.py
+++ b/EasyjetHub/python/algs/calibration/jets.py
@@ -2,8 +2,6 @@ from AnalysisAlgorithmsConfig.ConfigSequence import ConfigSequence
 from AnalysisAlgorithmsConfig.ConfigFactory import ConfigFactory
 from AthenaConfiguration.Enums import LHCPeriod
 
-from BJetCalibrationTool.BJetPtCorrectionConfig import makeBJetPtCalibrationConfig
-
 from EasyjetHub.steering.utils.name_helper import drop_sys
 
 
@@ -142,19 +140,12 @@ def jet_sequence(
                 configSeq.setOptionValue('.bTagCalibFile', bTagCalibFile)
 
         if jet_flags.runBJetPtCalib:
-            # Pick a reasonable b-tag selection?
-            makeBJetPtCalibrationConfig(
-                configSeq,
-                calib_name,
-            )
-            configSeq.setOptionValue(
-                '.muonName',
-                flags.Analysis.container_names.output.muons
-            )
-            configSeq.setOptionValue(
-                '.btagSelDecor',
-                "ftag_select_" + jet_flags.btag_wp,
-            )
+            configSeq += makeConfig(
+                'Jets.BJetCalib',
+                jetContainerName=calib_name,
+                muonContainerName=drop_sys(flags.Analysis.container_names.output.muons))
+            configSeq.setOptionValue('.jetPreselection', jet_flags.btag_wp)
+            configSeq.setOptionValue('.muonPreselection', "forBJetCalib")
 
         for tagger_wp in btag_wps:
             tagger, btag_wp = tagger_wp.split("_", 1)
@@ -214,14 +205,11 @@ def lr_jet_sequence(flags, lr_jet_type, configAcc):
 
     # Optional muon-in-jet correction for large-R jets
     if flags.Analysis.Large_R_jet.runMuonJetPtCorr:
-        makeBJetPtCalibrationConfig(
-            configSeq,
-            output_name,
-        )
-        configSeq.setOptionValue(
-            '.muonName',
-            flags.Analysis.container_names.output.muons
-        )
+        configSeq += makeConfig(
+            'Jets.BJetCalib',
+            jetContainerName=output_name,
+            muonContainerName=drop_sys(flags.Analysis.container_names.output.muons))
+        configSeq.setOptionValue('.muonPreselection', "forBJetCalib")
         # Disable small-R b-jet pT reco
         configSeq.setOptionValue('.doPtCorr', False)
 
diff --git a/EasyjetHub/python/algs/calibration/muons.py b/EasyjetHub/python/algs/calibration/muons.py
index 8ad6e047273d6f5cbe05fab0de72ead284831e28..93540a9ed1da767e18610527168f62827b2a3335 100644
--- a/EasyjetHub/python/algs/calibration/muons.py
+++ b/EasyjetHub/python/algs/calibration/muons.py
@@ -20,6 +20,7 @@ def muon_sequence(flags, configAcc):
     # The config sequence will deal with the systematics suffix
     output_name = drop_sys(flags.Analysis.container_names.output.muons)
     configSeq += makeConfig('Muons', containerName=output_name)
+    configSeq.setOptionValue('.minPt', flags.Analysis.Muon.min_pT)
     configSeq.setOptionValue('.maxEta', flags.Analysis.Muon.max_eta)
 
     # PID configuration
@@ -36,6 +37,14 @@ def muon_sequence(flags, configAcc):
         configSeq.setOptionValue('.maxDeltaZ0SinTheta',
                                  flags.Analysis.Muon.maxDeltaZ0SinTheta)
 
+    if flags.Analysis.Small_R_jet.runBJetPtCalib or \
+       flags.Analysis.Large_R_jet.runMuonJetPtCorr:
+        configSeq += makeConfig('Muons.WorkingPoint', containerName=output_name,
+                                selectionName='forBJetCalib')
+        configSeq.setOptionValue('.quality', 'Medium')
+        configSeq.setOptionValue('.isolation', 'NonIso')
+        configSeq.setOptionValue('.trackSelection', False)
+
     # Muon trigger SF
     trigSF_flags = flags.Analysis.Trigger.scale_factor
     if trigSF_flags.doSF and hasattr(trigSF_flags, 'Muon'):
diff --git a/EasyjetHub/python/algs/postprocessing/SelectorAlgConfig.py b/EasyjetHub/python/algs/postprocessing/SelectorAlgConfig.py
index bb1e684d4e7a08cf7cc8b767b0e5b97eddfa1be7..2f4d891f1a633c65692b1963e327825b17088227 100644
--- a/EasyjetHub/python/algs/postprocessing/SelectorAlgConfig.py
+++ b/EasyjetHub/python/algs/postprocessing/SelectorAlgConfig.py
@@ -77,6 +77,9 @@ def JetSelectorAlgCfg(flags, name="JetSelectorAlg", **kwargs):
     kwargs.setdefault("checkOR", flags.Analysis.do_overlap_removal)
     if kwargs.get("bTagWPDecorName", ""):
         kwargs.setdefault("bjetAmount", flags.Analysis.Small_R_jet.amount_bjet)
+    if (isSmallRJet and flags.Analysis.Small_R_jet.runBJetPtCalib) or \
+       (not isSmallRJet and flags.Analysis.Large_R_jet.runMuonJetPtCorr):
+        kwargs.setdefault("nmuons", "n_muons_%SYS%")
 
     cfg.addEventAlgo(CompFactory.Easyjet.JetSelectorAlg(name, **kwargs))
     return cfg
diff --git a/EasyjetHub/python/output/ttree/large_R_jets.py b/EasyjetHub/python/output/ttree/large_R_jets.py
index acfcb328c013a84d6c50b07b0976280bdd403167..6a2380cd929a4cf004b5c44259a46b70cb5e68e0 100644
--- a/EasyjetHub/python/output/ttree/large_R_jets.py
+++ b/EasyjetHub/python/output/ttree/large_R_jets.py
@@ -40,7 +40,7 @@ def get_large_R_jet_branches(
             large_R_jet_branches.variables += ["passesOR_%SYS%"]
 
     if flags.Analysis.Large_R_jet.runMuonJetPtCorr:
-        large_R_jet_branches.variables += ["uncorrPt", "n_muons"]
+        large_R_jet_branches.variables += ["n_muons_%SYS%"]
 
     if flags.Input.isMC and tree_flags.collection_options.large_R_jets.truth_labels:
         large_R_jet_branches.variables += [
diff --git a/EasyjetHub/python/output/ttree/small_R_jets.py b/EasyjetHub/python/output/ttree/small_R_jets.py
index c2c32b2b764632add97fd90b48a717ffdf4010f2..ec77a0b23b5c391cb7beed79b33a4260ea30a48b 100644
--- a/EasyjetHub/python/output/ttree/small_R_jets.py
+++ b/EasyjetHub/python/output/ttree/small_R_jets.py
@@ -73,16 +73,20 @@ def get_small_R_jet_branches(
                         f"ftag_effSF_{btag_wp}_%SYS%"
                     ]
 
-        if flags.Analysis.Small_R_jet.runBJetPtCalib \
-           and tree_flags.collection_options.small_R_jets.no_bjet_calib_p4:
-            small_R_jet_branches.variables += ["muonCorrPt", "n_muons"]
+        if flags.Analysis.Small_R_jet.runBJetPtCalib:
+            small_R_jet_branches.variables += ["n_muons_%SYS%"]
             if flags.Input.isMC:
                 small_R_jet_branches.variables += ["bJetTruthPt", "bJetTruthDR"]
 
-            small_R_jet_branches.variables += [
-                f"NoBJetCalibMomentum_{var}"
-                for var in ["pt", "eta", "phi", "m"]
-            ]
+            if tree_flags.collection_options.small_R_jets.no_bjet_calib_p4:
+                small_R_jet_branches.variables += [
+                    f"NoBJetCalibMomentum_{var}"
+                    for var in ["pt", "eta", "phi", "m"]
+                ]
+                small_R_jet_branches.variables += [
+                    f"MuonCorrMomentum_{var}"
+                    for var in ["pt", "eta", "phi", "m"]
+                ]
 
         if tree_flags.collection_options.small_R_jets.JVT_details:
             small_R_jet_branches.variables += [
diff --git a/EasyjetHub/src/JetSelectorAlg.cxx b/EasyjetHub/src/JetSelectorAlg.cxx
index e8ff8fc7af71511127f24470e614ff9c3eeeb774..62e51cf549caa41aef1e4a2d0956a4b83a22084a 100644
--- a/EasyjetHub/src/JetSelectorAlg.cxx
+++ b/EasyjetHub/src/JetSelectorAlg.cxx
@@ -48,6 +48,10 @@ namespace Easyjet
 
     if(m_useJVT) ATH_CHECK (m_jvtselection.initialize(m_systematicsList, m_inHandle));
     if(m_useFJVT) ATH_CHECK (m_fjvtselection.initialize(m_systematicsList, m_inHandle));
+    if(!m_nmuons_in.empty()){
+      ATH_CHECK (m_nmuons_in.initialize(m_systematicsList, m_inHandle));
+      ATH_CHECK (m_nmuons_out.initialize(m_systematicsList, m_outHandle));
+    }
 
     // Intialise syst list (must come after all syst-aware inputs and outputs)
     ATH_CHECK (m_systematicsList.initialize());
@@ -137,6 +141,7 @@ namespace Easyjet
           isSelected = true;
         }
         if (PCBTaggiven) workContainer_pcbt[jet] = m_PCBT.get(*jet, sys);
+        if(!m_nmuons_in.empty()) m_nmuons_out.set(*jet, m_nmuons_in.get(*jet, sys), sys);
         m_isSelectedJet.set(*jet, isSelected, sys);
       }
       
diff --git a/EasyjetHub/src/JetSelectorAlg.h b/EasyjetHub/src/JetSelectorAlg.h
index 389c0ea7360b7f6b56491ca66920cb214ac794c6..7a6ea1a65311426411da7f809e87815544c046f0 100644
--- a/EasyjetHub/src/JetSelectorAlg.h
+++ b/EasyjetHub/src/JetSelectorAlg.h
@@ -57,6 +57,10 @@ private:
     CP::SysReadDecorHandle<char> m_jvtselection {"jvt_selection", this};
     CP::SysReadDecorHandle<char> m_fjvtselection {"fjvt_selection", this};
 
+    CP::SysReadDecorHandle<int> m_nmuons_in{this, "nmuons", "",
+	"Number of muons from muon-in-jet correction"};
+    CP::SysWriteDecorHandle<int> m_nmuons_out{"n_muons_%SYS%", this};
+
     /// \brief Setup syst-aware output container handles
     CP::SysWriteHandle<ConstDataVector<xAOD::JetContainer>>
     m_outHandle{ this, "containerOutKey", "",   "Jet container to write" };
diff --git a/bbllAnalysis/src/BaselineVarsbbllAlg.cxx b/bbllAnalysis/src/BaselineVarsbbllAlg.cxx
index 206f4061379faa1aacaa4119a3a304da65dd76e6..db826c11751044e3e1ae861997f7d88e34d73e27 100644
--- a/bbllAnalysis/src/BaselineVarsbbllAlg.cxx
+++ b/bbllAnalysis/src/BaselineVarsbbllAlg.cxx
@@ -60,6 +60,7 @@ namespace HHBBLL
       m_PCBTs.emplace(var, rhandle);
       ATH_CHECK (m_PCBTs.at(var).initialize(m_systematicsList, m_jetHandle));
     };
+    ATH_CHECK (m_nmuons.initialize(m_systematicsList, m_jetHandle));
 
     ATH_CHECK (m_met_sig.initialize(m_systematicsList, m_metHandle));
 
@@ -106,9 +107,6 @@ namespace HHBBLL
       }
       
       static const SG::AuxElement::ConstAccessor<int>  HadronConeExclTruthLabelID("HadronConeExclTruthLabelID");
-      static const SG::AuxElement::ConstAccessor<int> cacc_NMu("n_muons");
-      static const SG::AuxElement::ConstAccessor<float> cacc_UncorrPt("uncorrPt");
-      static const SG::AuxElement::ConstAccessor<float> cacc_MuonCorrPt("muonCorrPt");
 
       TLorentzVector Leading_lep;
       TLorentzVector Subleading_lep;
@@ -279,9 +277,12 @@ namespace HHBBLL
           new_var.erase(new_var.length() - 11, new_var.length());
           m_Ibranches.at(prefix+"_pcbt_"+new_var).set(*event, m_PCBTs.at(var).get(*bjets->at(i), sys), sys);
         }
-	m_Ibranches.at(prefix+"_nmuons").set(*event, cacc_NMu(*bjets->at(i)), sys);
-	m_Fbranches.at(prefix+"_uncorrPt").set(*event, cacc_UncorrPt(*bjets->at(i)), sys);
-	m_Fbranches.at(prefix+"_muonCorrPt").set(*event, cacc_MuonCorrPt(*bjets->at(i)), sys);
+	m_Ibranches.at(prefix+"_nmuons").set
+	  (*event, m_nmuons.get(*bjets->at(i), sys), sys);
+	float uncorrPt = bjets->at(i)->jetP4("NoBJetCalibMomentum").Pt();
+	m_Fbranches.at(prefix+"_uncorrPt").set(*event, uncorrPt, sys);
+	float muonCorrPt = bjets->at(i)->jetP4("MuonCorrMomentum").Pt();
+	m_Fbranches.at(prefix+"_muonCorrPt").set(*event, muonCorrPt, sys);
       }
 
       if (bjets->size()>=2) {
diff --git a/bbllAnalysis/src/BaselineVarsbbllAlg.h b/bbllAnalysis/src/BaselineVarsbbllAlg.h
index a91d1acd0c99d91f627a762ffe92898b1e93359d..78407a6011cb747660e43d89b1bcd8ff160f94f1 100644
--- a/bbllAnalysis/src/BaselineVarsbbllAlg.h
+++ b/bbllAnalysis/src/BaselineVarsbbllAlg.h
@@ -74,9 +74,10 @@ private:
     CP::SysReadDecorHandle<char> 
     m_isBtag {this, "bTagWPDecorName", "", "Name of input dectorator for b-tagging"};
     Gaudi::Property<std::vector<std::string>> m_PCBTnames
-          {this, "PCBTDecorList", {}, "Name list of pseudo-continuous b-tagging decorator"};
-    std::unordered_map<std::string, CP::SysReadDecorHandle<int>>
-        m_PCBTs;
+      {this, "PCBTDecorList", {}, "Name list of pseudo-continuous b-tagging decorator"};
+    std::unordered_map<std::string, CP::SysReadDecorHandle<int>> m_PCBTs;
+
+    CP::SysReadDecorHandle<int> m_nmuons{"n_muons_%SYS%", this};
 
     Gaudi::Property<std::vector<std::string>> m_floatVariables
           {this, "floatVariableList", {}, "Name list of floating variables"};
diff --git a/bbttAnalysis/src/BaselineVarsbbttAlg.cxx b/bbttAnalysis/src/BaselineVarsbbttAlg.cxx
index 235bc44e439a44992e25c01e88505346f30d6b42..3c50b16dc4b5ece92895204c148c7ca41637a816 100644
--- a/bbttAnalysis/src/BaselineVarsbbttAlg.cxx
+++ b/bbttAnalysis/src/BaselineVarsbbttAlg.cxx
@@ -74,6 +74,7 @@ namespace HHBBTT
     if (m_isMC) {
       ATH_CHECK (m_truthFlav.initialize(m_systematicsList, m_jetHandle));
     }
+    ATH_CHECK (m_nmuons.initialize(m_systematicsList, m_jetHandle));
 
     ATH_CHECK (m_IDTau.initialize(m_systematicsList, m_tauHandle));
     ATH_CHECK (m_antiTau.initialize(m_systematicsList, m_tauHandle));
@@ -134,10 +135,6 @@ namespace HHBBTT
         m_Ibranches.at(var).set(*event, -99, sys);
       }
 
-      static const SG::AuxElement::ConstAccessor<int> cacc_NMu("n_muons");
-      static const SG::AuxElement::ConstAccessor<float> cacc_UncorrPt("uncorrPt");
-      static const SG::AuxElement::ConstAccessor<float> cacc_MuonCorrPt("muonCorrPt");
-
       static const SG::AuxElement::ConstAccessor<char> cacc_EleRNNLoose("EleRNNLoose_v1");
       static const SG::AuxElement::ConstAccessor<char> cacc_EleRNNMedium("EleRNNMedium_v1");
       static const SG::AuxElement::ConstAccessor<char> cacc_EleRNNTight("EleRNNTight_v1");
@@ -290,9 +287,12 @@ namespace HHBBTT
             new_var.erase(new_var.length() - 11, new_var.length()); // remove '_Continuous' from var name
             m_Ibranches.at(prefix+"_pcbt_"+new_var).set(*event, m_PCBTs.at(var).get(*bjets->at(i), sys), sys);
           }
-          m_Ibranches.at(prefix+"_nmuons").set(*event, cacc_NMu(*bjets->at(i)), sys);
-	  m_Fbranches.at(prefix+"_uncorrPt").set(*event, cacc_UncorrPt(*bjets->at(i)), sys);
-	  m_Fbranches.at(prefix+"_muonCorrPt").set(*event, cacc_MuonCorrPt(*bjets->at(i)), sys);
+          m_Ibranches.at(prefix+"_nmuons").set
+	    (*event, m_nmuons.get(*bjets->at(i), sys), sys);
+          float uncorrPt = bjets->at(i)->jetP4("NoBJetCalibMomentum").Pt();
+          m_Fbranches.at(prefix+"_uncorrPt").set(*event, uncorrPt, sys);
+          float muonCorrPt = bjets->at(i)->jetP4("MuonCorrMomentum").Pt();
+          m_Fbranches.at(prefix+"_muonCorrPt").set(*event, muonCorrPt, sys);
         }
 
         TLorentzVector b1 = bjets->at(0)->p4();
diff --git a/bbttAnalysis/src/BaselineVarsbbttAlg.h b/bbttAnalysis/src/BaselineVarsbbttAlg.h
index c106bb507d1692bf12e56054b10acd0ca912e6fb..adc63f0802db253d87822d465ccb9825218632a1 100644
--- a/bbttAnalysis/src/BaselineVarsbbttAlg.h
+++ b/bbttAnalysis/src/BaselineVarsbbttAlg.h
@@ -118,6 +118,7 @@ private:
 
     CP::SysReadDecorHandle<int>
       m_truthFlav{ this, "truthFlav", "HadronConeExclTruthLabelID", "Jet truth flavor" };
+    CP::SysReadDecorHandle<int> m_nmuons{"n_muons_%SYS%", this};
 
     CP::SysReadDecorHandle<unsigned int> m_year{this, "year", "dataTakingYear", ""};
 
diff --git a/bbyyAnalysis/src/BaselineVarsbbyyAlg.cxx b/bbyyAnalysis/src/BaselineVarsbbyyAlg.cxx
index 8ae0788e46a699c2c33428fb6b0a0987caedb404..76aab032ed51b0d94a7f31f0a587402588e6a1a8 100644
--- a/bbyyAnalysis/src/BaselineVarsbbyyAlg.cxx
+++ b/bbyyAnalysis/src/BaselineVarsbbyyAlg.cxx
@@ -35,6 +35,7 @@ namespace HHBBYY
     if (!m_PCBT.empty()) {
       ATH_CHECK (m_PCBT.initialize(m_systematicsList, m_jetHandle));
     }
+    ATH_CHECK (m_nmuons.initialize(m_systematicsList, m_jetHandle));
 
     ATH_CHECK (m_photonHandle.initialize(m_systematicsList));
     ATH_CHECK (m_electronHandle.initialize(m_systematicsList));
@@ -548,16 +549,16 @@ namespace HHBBYY
       const xAOD::Jet* jet = Hbb_jets[i];
 
       static const SG::AuxElement::ConstAccessor<int>  HadronConeExclTruthLabelID("HadronConeExclTruthLabelID");
-      static const SG::AuxElement::ConstAccessor<int> cacc_NMu("n_muons");
-      static const SG::AuxElement::ConstAccessor<float> cacc_UncorrPt("uncorrPt");
-      static const SG::AuxElement::ConstAccessor<float> cacc_MuonCorrPt("muonCorrPt");
 
       bool PCBTgiven = !m_PCBT.empty();
 
       std::string prefix_bjet = prefix + "HbbCandidate_Jet"+std::to_string(i+1);
-      m_Ibranches.at(prefix_bjet+"_n_muons").set(*event, cacc_NMu(*jet), sys);
-      m_Fbranches.at(prefix_bjet+"_uncorrPt").set(*event, cacc_UncorrPt(*jet), sys);
-      m_Fbranches.at(prefix_bjet+"_muonCorrPt").set(*event, cacc_MuonCorrPt(*jet), sys);
+      m_Ibranches.at(prefix_bjet+"_n_muons").set
+	(*event, m_nmuons.get(*jet, sys), sys);
+      float uncorrPt = jet->jetP4("NoBJetCalibMomentum").Pt();
+      m_Fbranches.at(prefix_bjet+"_uncorrPt").set(*event, uncorrPt, sys);
+      float muonCorrPt = jet->jetP4("MuonCorrMomentum").Pt();
+      m_Fbranches.at(prefix_bjet+"_muonCorrPt").set(*event, muonCorrPt, sys);
 
       TLorentzVector jet_tlv = jet->p4();
       m_Fbranches.at(prefix_bjet+"_pt").set(*event, jet_tlv.Pt(), sys);
diff --git a/bbyyAnalysis/src/BaselineVarsbbyyAlg.h b/bbyyAnalysis/src/BaselineVarsbbyyAlg.h
index c2c5237fae7ad27a15015a3ae92a4a920e57f685..e3d8716bdb54fd07782016d7a996566790e86b5c 100644
--- a/bbyyAnalysis/src/BaselineVarsbbyyAlg.h
+++ b/bbyyAnalysis/src/BaselineVarsbbyyAlg.h
@@ -179,6 +179,9 @@ namespace HHBBYY
     CP::SysReadDecorHandle<int> 
     m_PCBT {this, "PCBTDecorName", "", "Name of pseudo-continuous b-tagging decorator"};
 
+    CP::SysReadDecorHandle<int>
+    m_nmuons{ this, "nmuons", "n_muons_%SYS%", "Number of muons from muon-in-jet correction"};
+
     CP::SysReadHandle<xAOD::PhotonContainer>
     m_photonHandle{ this, "photons", "bbyyAnalysisPhotons_%SYS%", "Photons container to read" };
 
diff --git a/setup.cfg b/setup.cfg
index f59d5fb2cc1d94f78a1fd9de99a34c1fee2b94ad..da39fe0328d0a53bd91d5cbbce39802bc4b42ef1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -3,5 +3,5 @@ ignore = E203, E241, E266, W503
 max-line-length = 88
 select = B,C,E,F,W,T4
 darglint-ignore-regex = *
-exclude = .gitlab, BJetCalibrationTool, KinematicFitTool, CalcGenericMT2, athena
+exclude = .gitlab, KinematicFitTool, athena
 per-file-ignores = hub.py:F401