From 1a56b1a6e62b425c01240a421a58335ad90d2d40 Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Mon, 13 May 2024 19:59:51 +0200
Subject: [PATCH 1/7] Revive the Muon effi SF tester macro

---
 .../MuonSFTestHelper.h                        | 111 +++++++-----------
 .../Root/MuonSFTestHelper.cxx                 |  47 ++++----
 .../Root/MuonTriggerScaleFactors.cxx          |   2 +-
 .../src/MuonEfficiencyCorrections_TestAlg.cxx |  33 +-----
 .../src/MuonEfficiencyCorrections_TestAlg.h   |  36 +++---
 5 files changed, 81 insertions(+), 148 deletions(-)

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h
index 603820ca1856..ec25aa1478ca 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h
@@ -1,7 +1,7 @@
 /*
  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
  */
-
+#ifndef XAOD_STANDALONE 
 #ifndef MUONEFFICIENCYCORRECTION_MUONSFTESTHELPER_H
 #define MUONEFFICIENCYCORRECTION_MUONSFTESTHELPER_H
 
@@ -13,12 +13,11 @@
 #include <MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h>
 #include <MuonAnalysisInterfaces/IMuonSelectionTool.h>
 
+#include <MuonTesterTree/MuonTesterBranch.h>
+#include <MuonTesterTree/ScalarBranch.h>
+#include <MuonTesterTree/MuonTesterTree.h>
 
-#include <AsgTools/ToolHandle.h>
-#include <AsgTools/AnaToolHandle.h>
-
-#include <AsgTools/IAsgTool.h>
-#include <AsgTools/AsgTool.h>
+#include <GaudiKernel/ToolHandle.h>
 
 //General includes
 #include <memory>
@@ -28,79 +27,53 @@
 #include <TFile.h>
 //Helper class to test the Muon efficiency SFs plus their systematics
 namespace TestMuonSF {
-    //########################################
-    //      Template class to connect the    #
-    //      Variables with the TTree         #
-    //########################################
-    class SFBranches {
-        public:
-            SFBranches(TTree* tree);
-            virtual ~SFBranches()= default;
-            virtual std::string name() const =0;
-            virtual bool init()=0;
-        protected:
-            template<typename T> bool initBranch(T& Var, const std::string& Syst) {
-                std::string bName = name() + (Syst.empty() ? std::string("") : std::string("_")) + Syst;
-                if (m_tree->FindBranch(bName.c_str())) {
-                    Error("SFBranches::initBranch()", "The branch %s already exists in TTree %s", bName.c_str(), m_tree->GetName());
-                    return false;
-                }
-                if (m_tree->Branch(bName.c_str(), &Var) == nullptr) {
-                    Error("SFBranches::initBranch()", "Could not create the branch %s in TTree %s", bName.c_str(), m_tree->GetName());
-                    return false;
-                } else Info("SFBranches::initBranch()", "Created the branch %s in TTree %s", bName.c_str(), m_tree->GetName());
-                return true;
-            }
-        private:
-            TTree* m_tree;
-
-    };
     //####################################################
     //      Helper class to write ntuples to test the    #
     //      MuonTriggerScaleFactors                      #
     //####################################################
-    class TriggerSFBranches: public SFBranches {
+   
+    class TriggerSFBranches: public MuonVal::MuonTesterBranch {
         public:
-            TriggerSFBranches(TTree* tree, const ToolHandle<CP::IMuonTriggerScaleFactors>& Handle, const std::string& Trigger);
+            TriggerSFBranches(MuonVal::MuonTesterTree& tree, 
+                              const ToolHandle<CP::IMuonTriggerScaleFactors>& Handle, 
+                              const std::string& muonContainer,
+                              const std::string& Trigger);
             virtual ~TriggerSFBranches() = default;
-            CP::CorrectionCode fill(const xAOD::MuonContainer* Muons);
-            virtual bool init();
-            virtual std::string name() const;
+            
+            bool fill(const EventContext& ctx) override final;
+            bool init() override final;
+          
         private:
             CP::CorrectionCode getSF(const xAOD::MuonContainer* muons, double &Var, const CP::SystematicVariation &syst);
-            ToolHandle<CP::IMuonTriggerScaleFactors> m_handle;
-            std::string m_trigger;
-            double m_nominal_SF;
-            double m_stat_up_SF;
-            double m_stat_down_SF;
-            double m_sys_up_SF;
-            double m_sys_down_SF;
-    };
-    typedef std::unique_ptr<TriggerSFBranches> TriggerSFBranch_Ptr;
-
-    //###################################################
-    //      General interface for the Reconstruction    #
-    //      Isolation / TTVA scalefactors               #
-    //###################################################
-    class MuonEffiBranches: public SFBranches {
-        public:
-            MuonEffiBranches(TTree* tree);
-            virtual CP::CorrectionCode fill(const xAOD::Muon& muon)=0;
-            ~MuonEffiBranches() = default;
 
+            SG::ReadHandleKey<xAOD::MuonContainer> m_key{};
+            
+            ToolHandle<CP::IMuonTriggerScaleFactors> m_handle{};
+            std::string m_trigger{};
+            MuonVal::ScalarBranch<double> m_nominal_SF{tree(), name()+"_Nominal"};
+            MuonVal::ScalarBranch<double> m_stat_up_SF{tree(), name()+"_STAT_UP"};
+            MuonVal::ScalarBranch<double> m_stat_down_SF{tree(), name()+"_STAT_DN"};
+            MuonVal::ScalarBranch<double> m_sys_up_SF{tree(), name()+"_SYS_UP"};
+            MuonVal::ScalarBranch<double> m_sys_down_SF{tree(), name()+"_SYS_DN"};
     };
-    typedef std::unique_ptr<MuonEffiBranches> EffiBranch_Ptr;
+
     //###################################################################
     //      Helper class to write the scale-factor ntuples to test the  #
     //      MuonReconstruction/ Isolation/ TTVA scalefactors            #
     //###################################################################
-    class MuonSFBranches: public MuonEffiBranches {
+    class MuonSFBranches: public MuonVal::VectorBranch<double>, 
+                          public MuonVal::IParticleDecorationBranch {
         public:
-             MuonSFBranches(TTree* tree, const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, const std::string& rel_name = "");
-             CP::CorrectionCode fill(const xAOD::Muon& muon) override;
+             MuonSFBranches(MuonVal::MuonTesterTree& tree, 
+                            const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, 
+                            const std::string& rel_name = "");
+             
+             
+             void push_back(const xAOD::IParticle* part) override final;
+             void push_back(const xAOD::IParticle& part) override final;
+             void operator+=(const xAOD::IParticle& part) override final;
+             void operator+=(const xAOD::IParticle* part) override final;
              virtual ~MuonSFBranches() = default;
-             bool init() override;
-             std::string name() const override;
         private:
             ToolHandle<CP::IMuonEfficiencyScaleFactors> m_handle;
             bool m_uncorrelate_sys;
@@ -108,12 +81,10 @@ namespace TestMuonSF {
 
             //SF's
             struct SFSet {
-                    SFSet() {
-                        scale_factor = mc_eff = data_eff = 1.;
-                    }
-                    float scale_factor;
-                    float mc_eff;
-                    float data_eff;
+                    SFSet() = default;
+                    float scale_factor{1.f};
+                    float mc_eff{1.f};
+                    float data_eff{1.f};
             };
             
             CP::CorrectionCode fill_systematic(const xAOD::Muon muon, std::pair<const CP::SystematicSet, MuonSFBranches::SFSet>& set);
@@ -205,5 +176,5 @@ namespace TestMuonSF {
     };
 
 }
-
+#endif
 #endif
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
index 500207767dc5..5abf977d558d 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
@@ -25,24 +25,30 @@ namespace TestMuonSF {
         return prop;
     }
 
-    //###########################################################
-    //                       SFBranches
-    //###########################################################
-    SFBranches::SFBranches(TTree* tree) :
-                m_tree(tree) {
-    }
     //############################################################
     //                   TriggerSFBranches
     //############################################################
-    TriggerSFBranches::TriggerSFBranches(TTree* tree, const ToolHandle<CP::IMuonTriggerScaleFactors>& Handle, const std::string& Trigger) :
-                SFBranches(tree),
-                m_handle(Handle),
-                m_trigger(Trigger),
-                m_nominal_SF(1.),
-                m_stat_up_SF(1.),
-                m_stat_down_SF(1.),
-                m_sys_up_SF(1.),
-                m_sys_down_SF(1.) {
+              
+    bool TriggerSFBranches::fill(const EventContext& ctx){
+        return true;
+    }
+    bool TriggerSFBranches::init() {
+        if (!declare_dependency(m_key)) return false;
+        if (!m_nominal_SF.init()) return false;
+        if (!m_stat_up_SF.init()) return false;
+        if (!m_stat_down_SF.init()) return false;
+        if (!m_sys_up_SF.init()) return false;
+        if (!m_sys_down_SF.init()) return false; 
+        return true;
+    }
+    TriggerSFBranches::TriggerSFBranches(MuonVal::MuonTesterTree& tree, 
+                                         const ToolHandle<CP::IMuonTriggerScaleFactors>& Handle, 
+                                         const std::string& muonContainer,
+                                         const std::string& Trigger):
+        MuonVall::MuonTesterBranch{tree, "MuTriggerSF_" +Trigger},
+        m_key{muonContainer},            
+        m_handle{Handle},
+        m_trigger{Trigger}{
     }
     CP::CorrectionCode TriggerSFBranches::fill(const xAOD::MuonContainer* muons) {
         if (getSF(muons, m_nominal_SF, CP::SystematicVariation("", 0)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
@@ -52,17 +58,6 @@ namespace TestMuonSF {
         if (getSF(muons, m_sys_down_SF, CP::SystematicVariation("MUON_EFF_TrigSystUncertainty", -1)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
         return CP::CorrectionCode::Ok;
     }
-    bool TriggerSFBranches::init() {
-        if (!initBranch(m_nominal_SF, "")) return false;
-        if (!initBranch(m_stat_up_SF, "STAT_UP")) return false;
-        if (!initBranch(m_stat_down_SF, "STAT_DOWN")) return false;
-        if (!initBranch(m_sys_up_SF, "SYS_UP")) return false;
-        if (!initBranch(m_sys_down_SF, "SYS_DOWN")) return false;
-        return true;
-    }
-    std::string TriggerSFBranches::name() const {
-        return m_trigger;
-    }
     CP::CorrectionCode TriggerSFBranches::getSF(const xAOD::MuonContainer* muons, double &Var, const CP::SystematicVariation &syst) {
         if (muons->empty()) {
             return CP::CorrectionCode::Ok;
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonTriggerScaleFactors.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonTriggerScaleFactors.cxx
index 8bacdf7738bf..089ac08f3d66 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonTriggerScaleFactors.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonTriggerScaleFactors.cxx
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
  */
 
 #include <sstream>
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx
index 2b0cf05fbcb4..9d5efeaeb855 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx
@@ -13,36 +13,7 @@
 namespace CP {
 
     MuonEfficiencyCorrections_TestAlg::MuonEfficiencyCorrections_TestAlg(const std::string& name, ISvcLocator* svcLoc) :
-                AthAlgorithm(name, svcLoc),
-                m_sgKey("Muons"),
-                m_histSvc("THistSvc/THistSvc", name),
-                m_effi_SF_tools(),
-                m_comparison_tools(),
-                m_prw_Tool("CP::PileupReweighting/PileupReweightingTool"),
-                m_sel_tool("CP::MuonSelectionTool/SelectionTool"),
-                m_test_helper(),
-                m_comparison_helper(),
-                m_first_release_name("First"),
-                m_second_release_name("Second"),                
-                m_pt_cut(-1),
-                m_eta_cut(-1),
-                m_muon_quality(xAOD::Muon::Loose),
-                m_evNumber(0) {
-        declareProperty("SGKey", m_sgKey = "Muons");
-        // prepare the handle
-        declareProperty("PileupReweightingTool", m_prw_Tool);
-        declareProperty("MuonSelectionTool", m_sel_tool);
-        
-        declareProperty("EfficiencyTools", m_effi_SF_tools);
-        declareProperty("EfficiencyToolsForComparison", m_comparison_tools);
-
-        declareProperty("DefaultRelease", m_first_release_name);
-        declareProperty("ValidationRelease", m_second_release_name);
-
-        declareProperty("MinPt", m_pt_cut);
-        declareProperty("MaxEta", m_eta_cut);
-        declareProperty("MinQuality", m_muon_quality);
-        
+                AthHistogramAlgorithm(name, svcLoc) {
         // force strict checking of return codes
         CP::CorrectionCode::enableFailure();
     }
@@ -81,7 +52,7 @@ namespace CP {
             ATH_MSG_FATAL("Failed to initialize");
             return StatusCode::FAILURE;
         }
-        ATH_CHECK(m_histSvc->regTree(std::string("/MUONEFFTESTER/") + m_test_helper->tree()->GetName(), m_test_helper->tree()));
+        ATH_CHECK(histSvc()->regTree(std::string("/MUONEFFTESTER/") + m_test_helper->tree()->GetName(), m_test_helper->tree()));
         return StatusCode::SUCCESS;
     }
 
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h
index e82c0569a6fc..5314a2dd218d 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h
@@ -1,19 +1,15 @@
 /*
- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
  */
 
 #ifndef CPTOOLTESTS_MuonEfficiencyCorrections_TESTALG
 #define CPTOOLTESTS_MuonEfficiencyCorrections_TESTALG
 
 // Gaudi/Athena include(s):
-#include "AthenaBaseComps/AthAlgorithm.h"
-#include "GaudiKernel/ITHistSvc.h"
-#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthHistogramAlgorithm.h"
 #include "StoreGate/ReadHandleKey.h"
 #include "xAODEventInfo/EventInfo.h"
 
-#include "AsgTools/ToolHandleArray.h"
-
 #include "MuonEfficiencyCorrections/MuonSFTestHelper.h"
 
 #include "MuonAnalysisInterfaces/IMuonEfficiencyScaleFactors.h"
@@ -25,7 +21,7 @@ namespace CP {
 
 /// small test algorithm to quickly test/demonstrate the usage of the MuonEfficiencyCorrections code within athena
 
-    class MuonEfficiencyCorrections_TestAlg: public AthAlgorithm {
+    class MuonEfficiencyCorrections_TestAlg: public AthHistogramAlgorithm {
 
         public:
             /// Regular Algorithm constructor
@@ -40,25 +36,25 @@ namespace CP {
         private:
             SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo{this, "EventInfoContName", "EventInfo", "event info key"};
             /// muon container
-            std::string m_sgKey;
-            ServiceHandle<ITHistSvc> m_histSvc;
+            SG::ReadHandleKey<xAOD::MuonContainer> m_sgKey{this, "SGKey", "Muons"};
 
-            ToolHandleArray<IMuonEfficiencyScaleFactors> m_effi_SF_tools;
-            ToolHandleArray<IMuonEfficiencyScaleFactors> m_comparison_tools;
+            ToolHandleArray<IMuonEfficiencyScaleFactors> m_effi_SF_tools{this, "EfficiencyTools", {}};
+            ToolHandleArray<IMuonEfficiencyScaleFactors> m_comparison_tools{this, "EfficiencyToolsForComparison", {}};
 
             /// Scale factor tool
-            ToolHandle<IPileupReweightingTool> m_prw_Tool;
-            ToolHandle<IMuonSelectionTool> m_sel_tool;
+            ToolHandle<IPileupReweightingTool> m_prw_Tool{this, "PileupReweightingTool", ""};
+            ToolHandle<IMuonSelectionTool> m_sel_tool{this, "MuonSelectionTool", ""};
+
+            std::unique_ptr<TestMuonSF::MuonSFTestHelper> m_test_helper{};
+            std::unique_ptr<TestMuonSF::MuonSFTestHelper> m_comparison_helper{};
 
-            std::unique_ptr<TestMuonSF::MuonSFTestHelper> m_test_helper;
-            std::unique_ptr<TestMuonSF::MuonSFTestHelper> m_comparison_helper;
 
-            std::string m_first_release_name;
-            std::string m_second_release_name;
+            Gaudi::Property<std::string> m_first_release_name{this, "DefaultRelease", ""};
+            Gaudi::Property<std::string> m_second_release_name{this, "ValidationRelease", ""};
             
-            float m_pt_cut;
-            float m_eta_cut;
-            int m_muon_quality;
+            Gaudi::Property<float> m_pt_cut{this, "MinPt", -1.};
+            Gaudi::Property<float> m_eta_cut{this, "MaxEta", -1.};
+            Gaudi::Property<int> m_muon_quality{this, "MinQuality", xAOD::Muon::Loose};
             
             unsigned long long m_evNumber;
     };
-- 
GitLab


From 0a03b4c007c9d90007c91a6aff93f2d06c443124 Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Tue, 14 May 2024 11:15:10 +0200
Subject: [PATCH 2/7] Clean up the tester algos

---
 .../MuonEfficiencyCorrections/CMakeLists.txt  |  10 +-
 .../MuonSFTestHelper.h                        | 160 +++----
 .../Root/MuonSFTestHelper.cxx                 | 404 ++++++------------
 .../src/MuonEfficiencyCorrections_TestAlg.cxx |  87 ----
 .../src/MuonScaleFactorTestAlg.cxx            |  93 ++++
 ...ons_TestAlg.h => MuonScaleFactorTestAlg.h} |  34 +-
 .../src/MuonTriggerSF_TestAlg.cxx             |  85 ----
 .../src/MuonTriggerSF_TestAlg.h               |  48 ---
 .../src/TestTrigSF.cxx                        | 302 -------------
 .../src/TestTrigSF.h                          |  99 -----
 .../MuonEfficiencyCorrections_entries.cxx     |  15 +-
 11 files changed, 335 insertions(+), 1002 deletions(-)
 delete mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx
 create mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx
 rename PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/{MuonEfficiencyCorrections_TestAlg.h => MuonScaleFactorTestAlg.h} (59%)
 delete mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.cxx
 delete mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.h
 delete mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.cxx
 delete mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.h

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
index d83ecc53b4d0..64057a7d8168 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( MuonEfficiencyCorrections )
@@ -6,12 +6,18 @@ atlas_subdir( MuonEfficiencyCorrections )
 # External dependencies:
 find_package( ROOT COMPONENTS Core Tree RIO Hist Physics )
 
+set (extra_libs)
+if( NOT XAOD_STANDALONE )
+   set (extra_libs MuonTesterTreeLib)
+endif()
+
 # Libraries in the package:
 atlas_add_library( MuonEfficiencyCorrectionsLib
    MuonEfficiencyCorrections/*.h Root/*.cxx
    PUBLIC_HEADERS MuonEfficiencyCorrections
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODMuon xAODEventInfo MuonAnalysisInterfacesLib PATInterfaces AsgDataHandlesLib
+   LINK_LIBRARIES ${ROOT_LIBRARIES} ${extra_libs} AsgTools xAODMuon xAODEventInfo MuonAnalysisInterfacesLib 
+                  PATInterfaces AsgDataHandlesLib
    PRIVATE_LINK_LIBRARIES FourMomUtils xAODTrigger PathResolver )
 
 if( NOT XAOD_STANDALONE )
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h
index ec25aa1478ca..78450bb3c5a8 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/MuonEfficiencyCorrections/MuonSFTestHelper.h
@@ -44,137 +44,105 @@ namespace TestMuonSF {
             bool init() override final;
           
         private:
-            CP::CorrectionCode getSF(const xAOD::MuonContainer* muons, double &Var, const CP::SystematicVariation &syst);
+            CP::CorrectionCode getSF(const xAOD::MuonContainer* muons, 
+                                     MuonVal::ScalarBranch<double> &Var, 
+                                     const CP::SystematicVariation &syst);
 
             SG::ReadHandleKey<xAOD::MuonContainer> m_key{};
             
             ToolHandle<CP::IMuonTriggerScaleFactors> m_handle{};
             std::string m_trigger{};
-            MuonVal::ScalarBranch<double> m_nominal_SF{tree(), name()+"_Nominal"};
-            MuonVal::ScalarBranch<double> m_stat_up_SF{tree(), name()+"_STAT_UP"};
-            MuonVal::ScalarBranch<double> m_stat_down_SF{tree(), name()+"_STAT_DN"};
-            MuonVal::ScalarBranch<double> m_sys_up_SF{tree(), name()+"_SYS_UP"};
-            MuonVal::ScalarBranch<double> m_sys_down_SF{tree(), name()+"_SYS_DN"};
+            MuonVal::ScalarBranch<double> m_nominal_SF{tree(), name(), 1.};
+            MuonVal::ScalarBranch<double> m_stat_up_SF{tree(), name()+"_STAT_UP", 1.};
+            MuonVal::ScalarBranch<double> m_stat_down_SF{tree(), name()+"_STAT_DN", 1.};
+            MuonVal::ScalarBranch<double> m_sys_up_SF{tree(), name()+"_SYS_UP", 1.};
+            MuonVal::ScalarBranch<double> m_sys_down_SF{tree(), name()+"_SYS_DN", 1.};
     };
 
+    
+    class MuonEffiBranch{
+        public:
+            virtual void setMuon(const xAOD::Muon& muon) = 0;
+    };
     //###################################################################
     //      Helper class to write the scale-factor ntuples to test the  #
     //      MuonReconstruction/ Isolation/ TTVA scalefactors            #
     //###################################################################
-    class MuonSFBranches: public MuonVal::VectorBranch<double>, 
-                          public MuonVal::IParticleDecorationBranch {
+    class MuonSFBranches: public MuonVal::MuonTesterBranch, public MuonEffiBranch {
         public:
              MuonSFBranches(MuonVal::MuonTesterTree& tree, 
                             const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, 
                             const std::string& rel_name = "");
              
-             
-             void push_back(const xAOD::IParticle* part) override final;
-             void push_back(const xAOD::IParticle& part) override final;
-             void operator+=(const xAOD::IParticle& part) override final;
-             void operator+=(const xAOD::IParticle* part) override final;
              virtual ~MuonSFBranches() = default;
+
+
+             void setMuon(const xAOD::Muon& muon) override final;
+
+             bool fill(const EventContext& ctx) override final;
+
+             bool init() override final;
+
+            /// Dummy helper function that encodes the systname set
+            static std::string systName(const CP::SystematicSet& set) {
+                return set.name().empty() ? std::string("") : std::string("__") + set.name();
+            }
+
         private:
-            ToolHandle<CP::IMuonEfficiencyScaleFactors> m_handle;
-            bool m_uncorrelate_sys;
-            std::string m_release;
+            ToolHandle<CP::IMuonEfficiencyScaleFactors> m_handle{};
+            bool m_uncorrelate_sys{false};
 
-            //SF's
+            /// Helper struct to store scale factor, data efficiency + mc efficiency
+            /// for each systematic variation
             struct SFSet {
-                    SFSet() = default;
-                    float scale_factor{1.f};
-                    float mc_eff{1.f};
-                    float data_eff{1.f};
+                    SFSet(const CP::SystematicSet& _cpSet,
+                          MuonSFBranches& _parent):
+                    cpSet{_cpSet}, parent{_parent}{}
+                    /// Initialization of the branches
+                    bool init() {
+                        return scaleFactor.init() && mcEff.init() && dataEff.init();
+                    }
+                    /// check that all branches are set properly
+                    bool fill(const EventContext& ctx) {
+                        return scaleFactor.fill(ctx) && mcEff.fill(ctx) && dataEff.fill(ctx);
+                    }
+                    /// Systematic set
+                    const CP::SystematicSet cpSet{};
+                    /// Parent from which the TTree pointer & name is retrieved
+                    MuonSFBranches& parent;
+                    /// Actual branches storing scaleFactor & mcEff & dataEff
+                    MuonVal::ScalarBranch<float> scaleFactor{parent.tree(),parent.name()+"SF" + systName(cpSet), 1.f};
+                    MuonVal::ScalarBranch<float> mcEff{parent.tree(),parent.name()+"MCEff" + systName(cpSet), 1.f};
+                    MuonVal::ScalarBranch<float> dataEff{parent.tree(),parent.name()+"DataEff" + systName(cpSet),1.f};
             };
             
-            CP::CorrectionCode fill_systematic(const xAOD::Muon muon, std::pair<const CP::SystematicSet, MuonSFBranches::SFSet>& set);
-            bool AddToTree(const CP::SystematicSet& syst, MuonSFBranches::SFSet& ScaleFactor);
-
-            std::map<CP::SystematicSet, SFSet> m_SFs;
+            CP::CorrectionCode fillSystematic(const xAOD::Muon& muon, SFSet& set);
+    
+            std::vector<std::unique_ptr<SFSet>> m_SFs{};
 
     };
     //#######################################################
     //          Helper class for writing                    #
     //          scale-factor replicas to the test-ntuples   #
     //#######################################################
-    class MuonReplicaBranches: public MuonEffiBranches {
+    
+    class MuonReplicaBranches: public MuonVal::MuonTesterBranch, public MuonEffiBranch {
         public:
-            MuonReplicaBranches(TTree* tree, const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, const std::string& rel_name = "");
-            CP::CorrectionCode fill(const xAOD::Muon& muon) override;
+            MuonReplicaBranches(MuonVal::MuonTesterTree& tree, 
+                                const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, 
+                                const std::string& rel_name = "");
+            
+            void setMuon(const xAOD::Muon& muon) override final;
 
             bool init() override;
-            std::string name() const override;
-        private:
-            ToolHandle<CP::IMuonEfficiencyScaleFactors> m_handle;
-            std::string m_release;
-            std::map<CP::SystematicSet, std::vector<float>> m_SFs;
-    };
-
-    //###################################################
-    //      Helper class to write                       #
-    //      The muon properties for the efficiency sfs  #
-    //###################################################
-    class MuonInfoBranches: public MuonEffiBranches {
-        public:
-            MuonInfoBranches(TTree* tree, const ToolHandle<CP::IMuonSelectionTool>& sel_tool);
-            virtual ~MuonInfoBranches() = default;
-            bool init() override;
-            std::string name() const override;
-            CP::CorrectionCode fill(const xAOD::Muon& muon) override;
-
-        private:
-            const ToolHandle<CP::IMuonSelectionTool>& m_selection_tool;
-            float m_pt;
-            float m_eta;
-            float m_phi;
-            unsigned int m_quality;
-            unsigned int m_author;
-            unsigned int m_type;
-            bool m_passLowPt;
-            bool m_passHighPt;
-            uint8_t m_precLayers;
-    };
-
-    class MuonSFTestHelper {
-        public:
-
-            //Standalone constructor if only one SF release is asked for
-            MuonSFTestHelper(const std::string& release_name = "", bool HasOwnerShip = false);
-            // Constructor for the comparisons between two releases
-            MuonSFTestHelper(std::shared_ptr<TTree> Tree, const std::string& release_name = "");
-            MuonSFTestHelper(TTree*Tree, const std::string& release_name = "");
-
-            MuonSFTestHelper(const MuonSFTestHelper&) = delete;
-            MuonSFTestHelper& operator=(const MuonSFTestHelper&) = delete;
-
-            ~MuonSFTestHelper() = default;
-
-            //Initialize the tool
-            bool init();
-            void addTool(const asg::AnaToolHandle<CP::IMuonEfficiencyScaleFactors> &handle);
-            void addTool(const ToolHandle<CP::IMuonEfficiencyScaleFactors>& handle);
-
-            void addReplicaTool(const asg::AnaToolHandle<CP::IMuonEfficiencyScaleFactors> &handle);
-            void addReplicaTool(const ToolHandle<CP::IMuonEfficiencyScaleFactors>& handle);
-
-            void setSelectionTool(const asg::AnaToolHandle<CP::IMuonSelectionTool> & sel_tool);
-            void setSelectionTool(const ToolHandle<CP::IMuonSelectionTool> & sel_tool);
             
-            TTree* tree();
-            std::shared_ptr<TTree> tree_shared();
-            CP::CorrectionCode fill(const xAOD::MuonContainer* muons);
-            CP::CorrectionCode fill(const xAOD::Muon* mu);
-            CP::CorrectionCode fill(const xAOD::Muon& mu);
-            void fillTree();
+            bool fill(const EventContext& ctx) override;
 
         private:
-            std::string m_name;
-            std::shared_ptr<TTree> m_tree;
-            TTree* m_tree_raw_ptr;
-            std::vector<EffiBranch_Ptr> m_Branches;
-            ToolHandle<CP::IMuonSelectionTool> m_sel_tool;
+            ToolHandle<CP::IMuonEfficiencyScaleFactors> m_handle{};
+            
+            std::map<CP::SystematicSet, std::shared_ptr<MuonVal::VectorBranch<float>>> m_SFs{};
     };
-
 }
 #endif
 #endif
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
index 5abf977d558d..6173393d30c4 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
  */
 
 #include "MuonEfficiencyCorrections/MuonSFTestHelper.h"
@@ -8,13 +8,10 @@
 
 
 #include "PATInterfaces/SystematicsUtil.h"
-#include <TH1D.h>
-#define CHECK_CPCorr(Arg) \
-    if (Arg.code() == CP::CorrectionCode::Error){    \
-        Error(#Arg,"Correction Code 'Error' (returned in line %i) ",__LINE__); \
-        return CP::CorrectionCode::Error;   \
-    } 
 
+namespace {
+    constexpr double MeVtoGeV = 1.e-3;
+}
 namespace TestMuonSF {
         template<typename T> T getProperty(const asg::IAsgTool* interface_tool, const std::string& prop_name) {
         const asg::AsgTool* asg_tool = dynamic_cast<const asg::AsgTool*>(interface_tool);
@@ -28,9 +25,14 @@ namespace TestMuonSF {
     //############################################################
     //                   TriggerSFBranches
     //############################################################
-              
-    bool TriggerSFBranches::fill(const EventContext& ctx){
-        return true;
+    TriggerSFBranches::TriggerSFBranches(MuonVal::MuonTesterTree& tree, 
+                                         const ToolHandle<CP::IMuonTriggerScaleFactors>& Handle, 
+                                         const std::string& muonContainer,
+                                         const std::string& Trigger):
+        MuonVal::MuonTesterBranch{tree, "MuTriggerSF_" +Trigger},
+        m_key{muonContainer},            
+        m_handle{Handle},
+        m_trigger{Trigger}{
     }
     bool TriggerSFBranches::init() {
         if (!declare_dependency(m_key)) return false;
@@ -41,24 +43,30 @@ namespace TestMuonSF {
         if (!m_sys_down_SF.init()) return false; 
         return true;
     }
-    TriggerSFBranches::TriggerSFBranches(MuonVal::MuonTesterTree& tree, 
-                                         const ToolHandle<CP::IMuonTriggerScaleFactors>& Handle, 
-                                         const std::string& muonContainer,
-                                         const std::string& Trigger):
-        MuonVall::MuonTesterBranch{tree, "MuTriggerSF_" +Trigger},
-        m_key{muonContainer},            
-        m_handle{Handle},
-        m_trigger{Trigger}{
-    }
-    CP::CorrectionCode TriggerSFBranches::fill(const xAOD::MuonContainer* muons) {
-        if (getSF(muons, m_nominal_SF, CP::SystematicVariation("", 0)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-        if (getSF(muons, m_stat_up_SF, CP::SystematicVariation("MUON_EFF_TrigStatUncertainty", +1)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-        if (getSF(muons, m_stat_down_SF, CP::SystematicVariation("MUON_EFF_TrigStatUncertainty", -1)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-        if (getSF(muons, m_sys_up_SF, CP::SystematicVariation("MUON_EFF_TrigSystUncertainty", +1)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-        if (getSF(muons, m_sys_down_SF, CP::SystematicVariation("MUON_EFF_TrigSystUncertainty", -1)) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-        return CP::CorrectionCode::Ok;
+
+    bool TriggerSFBranches::fill(const EventContext& ctx) {
+        SG::ReadHandle<xAOD::MuonContainer> readHandle{m_key, ctx};
+        if (!readHandle.isPresent()) {
+            ATH_MSG_FATAL("Failed to retrieve muon container "<<m_key.fullKey());
+            return false;
+        }
+        const xAOD::MuonContainer* muons{readHandle.cptr()};
+        if (getSF(muons, m_nominal_SF, CP::SystematicVariation("", 0)) == CP::CorrectionCode::Error) {
+            return false;
+        } if (getSF(muons, m_stat_up_SF, CP::SystematicVariation("MUON_EFF_TrigStatUncertainty", +1)) == CP::CorrectionCode::Error) {
+            return CP::CorrectionCode::Error;
+        } if (getSF(muons, m_stat_down_SF, CP::SystematicVariation("MUON_EFF_TrigStatUncertainty", -1)) == CP::CorrectionCode::Error) {
+            return CP::CorrectionCode::Error;
+        } if (getSF(muons, m_sys_up_SF, CP::SystematicVariation("MUON_EFF_TrigSystUncertainty", +1)) == CP::CorrectionCode::Error) {
+            return CP::CorrectionCode::Error;
+        } if (getSF(muons, m_sys_down_SF, CP::SystematicVariation("MUON_EFF_TrigSystUncertainty", -1)) == CP::CorrectionCode::Error) {
+            return CP::CorrectionCode::Error;
+        }
+        return true;
     }
-    CP::CorrectionCode TriggerSFBranches::getSF(const xAOD::MuonContainer* muons, double &Var, const CP::SystematicVariation &syst) {
+    CP::CorrectionCode TriggerSFBranches::getSF(const xAOD::MuonContainer* muons, 
+                                                MuonVal::ScalarBranch<double> &branch, 
+                                                const CP::SystematicVariation &syst) {
         if (muons->empty()) {
             return CP::CorrectionCode::Ok;
         }
@@ -67,287 +75,159 @@ namespace TestMuonSF {
         if (m_handle->applySystematicVariation(syst_set) != StatusCode::SUCCESS) {
             return CP::CorrectionCode::Error;
         }
-        return m_handle->getTriggerScaleFactor(*muons, Var, name());
-    }
-    //############################################################
-    //                   MuonEffiBranches
-    //############################################################
-    MuonEffiBranches::MuonEffiBranches(TTree* tree) :
-                SFBranches(tree) {
+        double Var{1.};
+        CP::CorrectionCode code = m_handle->getTriggerScaleFactor(*muons, Var, m_trigger);
+        branch = Var;
+        return code; 
     }
+
+
     //############################################################
     //                   MuonSFBranches
     //############################################################
-    MuonSFBranches::MuonSFBranches(TTree* tree, const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, const std::string& rel_name) :
-                MuonEffiBranches(tree),
-                m_handle(handle),
-                m_release(rel_name),
-                m_SFs()
-    {
-      auto mesf = dynamic_cast<const CP::MuonEfficiencyScaleFactors*>(handle.operator->());
-      if (!mesf) std::abort();
-      m_uncorrelate_sys = mesf->uncorrelate_sys();
+
+    MuonSFBranches::MuonSFBranches(MuonVal::MuonTesterTree& tree, 
+                                  const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, 
+                                  const std::string& relName) :
+        MuonVal::MuonTesterBranch{tree, relName + (relName.empty() ? "" : "_") + 
+                                        getProperty<std::string>(handle.get(), "WorkingPoint")},
+        m_handle{handle} {}
+
+    bool MuonSFBranches::init(){
+        auto mesf = dynamic_cast<const CP::MuonEfficiencyScaleFactors*>(m_handle.get());
+        if (!mesf) {
+            ATH_MSG_ERROR("Given tool not MuonCP::MuonEfficiencyScaleFactors");
+            return false;
+        }
+        m_uncorrelate_sys = mesf->uncorrelate_sys();
+
+        for (const auto& set : CP::make_systematics_vector(m_handle->recommendedSystematics())) {
+            m_SFs.emplace_back(std::make_unique<SFSet>(set, *this));
+            if (!m_SFs.back()->init()) return false;
+        }
+        return true;
+    }
+
+    bool MuonSFBranches::fill(const EventContext& ctx) {
+        for (auto& sys : m_SFs) {
+            if (!sys->fill(ctx)) return false;
+        }
+        return true;
     }
-    CP::CorrectionCode MuonSFBranches::fill(const xAOD::Muon& muon) {
+
+
+    void MuonSFBranches::setMuon(const xAOD::Muon& muon) {
         /// Only the raw systematic sets have been activated
         /// We can loop over each set and fill it properly        
-        if (!m_uncorrelate_sys){
+        if (!m_uncorrelate_sys) {
             for (auto& Syst_SF : m_SFs) {            
-                CP::CorrectionCode cc =  fill_systematic(muon,Syst_SF);
-                if (cc == CP::CorrectionCode::Error) return cc;
+                CP::CorrectionCode cc = fillSystematic(muon, *Syst_SF);
+                if (cc == CP::CorrectionCode::Error){
+                    return;
+                }
             }
         }  else {            
             int bin =  m_handle->getUnCorrelatedSystBin(muon);
             if (bin < 0){
-                Warning("MuonSFBranches()", "Did not find a valid bin for muon  with pT: %.2f GeV, eta: %.2f, phi: %2.f",
-                        muon.pt(), muon.eta(),muon.phi());
-                return CP::CorrectionCode::OutOfValidityRange;
+                ATH_MSG_WARNING("Did not find a valid bin for muon  with pT: "<<muon.pt() *MeVtoGeV <<" GeV, eta:"<<
+                        muon.eta()<<", phi: "<<muon.phi());
+                return;
             }        
             for (auto& Syst_SF: m_SFs){
                 /// Only process the nominal set or the set matching the syst bin
-                bool process = false;
-                if (Syst_SF.first.name().empty()) process =true;
-                else {                    
-                     for (std::set<CP::SystematicVariation>::const_iterator t = Syst_SF.first.begin(); t != Syst_SF.first.end(); ++t) {
-                        if ((*t).isToyVariation()) {
-                            std::pair<unsigned, float> pair = (*t).getToyVariation();
-                            if (pair.first == (unsigned) bin){
-                                process = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-                if (process) {
-                    CP::CorrectionCode cc = fill_systematic(muon, Syst_SF);
-                    if (cc == CP::CorrectionCode::Error) return cc;
-                } else {
-                    /// Assign a dummy value
-                    Syst_SF.second.scale_factor = Syst_SF.second.mc_eff = Syst_SF.second.data_eff = -1.; 
+                bool process =  Syst_SF->cpSet.name().empty() ||
+                                std::find_if(Syst_SF->cpSet.begin(), Syst_SF->cpSet.end(), 
+                                            [bin](const CP::SystematicVariation& t){
+                                                return t.isToyVariation() && t.getToyVariation().first == 
+                                                                            static_cast<unsigned>(bin);
+                                            }) != Syst_SF->cpSet.end();
+                if (!process) continue;
+                CP::CorrectionCode cc = fillSystematic(muon, *Syst_SF);
+                if (cc == CP::CorrectionCode::Error) {
+                    return;
                 }                
             }           
         } 
-        return CP::CorrectionCode::Ok;
     }
-    CP::CorrectionCode MuonSFBranches::fill_systematic(const xAOD::Muon muon, std::pair<const CP::SystematicSet, MuonSFBranches::SFSet>&  Syst_SF){
-        if (m_handle->applySystematicVariation(Syst_SF.first) != StatusCode::SUCCESS) {
-            Error("MuonSFBranches()", "Failed to apply variation %s for %s", Syst_SF.first.name().c_str(), name().c_str());
+
+    CP::CorrectionCode MuonSFBranches::fillSystematic(const xAOD::Muon& muon, 
+                                                      SFSet& Syst_SF) {
+        if (m_handle->applySystematicVariation(Syst_SF.cpSet) != StatusCode::SUCCESS) {
+            ATH_MSG_ERROR("Failed to apply variation "<< Syst_SF.cpSet.name()<<" for "<< name());
             return CP::CorrectionCode::Error;
-        }            
-        CP::CorrectionCode cc = m_handle->getEfficiencyScaleFactor(muon, Syst_SF.second.scale_factor);
+        }  
+        float sf{1.f};
+        CP::CorrectionCode cc = m_handle->getEfficiencyScaleFactor(muon, sf);
         if (cc == CP::CorrectionCode::Error) {
-            Error("MuonSFBranches()", "Failed to retrieve %s scale-factor for variation %s", name().c_str(), Syst_SF.first.name().c_str());
+            ATH_MSG_ERROR("Failed to retrieve the scale factor variation "<< Syst_SF.cpSet.name()<<" for "<< name());
             return CP::CorrectionCode::Error;
-        } 
+        }
+        Syst_SF.scaleFactor = sf;
        
         /// No data-mc efficiencies provided for eta beyond 2.5
-        if (std::fabs(muon.eta()) > 2.5) {
-            Syst_SF.second.data_eff = -1;
-            Syst_SF.second.mc_eff = -1;
+        if (std::abs(muon.eta()) > 2.5) {
+            Syst_SF.dataEff = -1;
+            Syst_SF.mcEff = -1;
             return CP::CorrectionCode::Ok;
         }            
-        cc = m_handle->getDataEfficiency(muon, Syst_SF.second.data_eff);
+        cc = m_handle->getDataEfficiency(muon, sf);
         if (cc == CP::CorrectionCode::Error) {
-             Error("MuonSFBranches()", "Failed to retrieve %s data efficiency for variation %s", name().c_str(), Syst_SF.first.name().c_str());
-            return CP::CorrectionCode::Error;
-        }            
-        cc = m_handle->getMCEfficiency(muon, Syst_SF.second.mc_eff);
+            ATH_MSG_ERROR("Failed to retrieve the data efficiency variation "<< Syst_SF.cpSet.name()<<" for "<< name());
+            return cc;
+        }
+        Syst_SF.dataEff = sf;          
+        cc = m_handle->getMCEfficiency(muon, sf);
         if (cc == CP::CorrectionCode::Error) {
-            Error("MuonSFBranches()", "Failed to retrieve %s mc efficiency for variation %s", name().c_str(), Syst_SF.first.name().c_str());
+            ATH_MSG_ERROR("Failed to retrieve the mc efficiency variation "<< Syst_SF.cpSet.name()<<" for "<< name());
             return CP::CorrectionCode::Error;
         }
+        Syst_SF.mcEff = sf;
         return CP::CorrectionCode::Ok;        
     }
     
-    std::string MuonSFBranches::name() const {
-        return m_release + (m_release.empty() ? "" : "_") + getProperty<std::string>(m_handle.operator->(), "WorkingPoint");
-    }
-    bool MuonSFBranches::init() {
-        for (auto set : CP::make_systematics_vector(m_handle->recommendedSystematics())) {
-            std::map<CP::SystematicSet, SFSet>::iterator Itr = m_SFs.find(set);
-            if (Itr == m_SFs.end()) {
-                m_SFs.insert(std::pair<CP::SystematicSet, SFSet>(set, SFSet()));
-                Itr = m_SFs.find(set);
-                if (!AddToTree(set, Itr->second)) return false;
-            }
-        }
-        return true;
-    }
-    bool MuonSFBranches::AddToTree(const CP::SystematicSet& syst, MuonSFBranches::SFSet& ScaleFactor) {
-        std::string SystName = (syst.name().empty() ? std::string("") : std::string("__")) + syst.name();
-        if (!initBranch(ScaleFactor.scale_factor, std::string("SF") + SystName)) return false;
-        if (!initBranch(ScaleFactor.data_eff, std::string("DataEff") + SystName)) return false;
-        if (!initBranch(ScaleFactor.mc_eff, std::string("MCEff") + SystName)) return false;
-        return true;
-    }
+    
     //############################################################
     //                   MuonReplicaBranches
     //############################################################
-    MuonReplicaBranches::MuonReplicaBranches(TTree* tree, const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, const std::string& rel_name) :
-                MuonEffiBranches(tree),
-                m_handle(handle),
-                m_release(rel_name),
-                m_SFs() {
-    }
-    CP::CorrectionCode MuonReplicaBranches::fill(const xAOD::Muon& muon) {
-        for (auto& Syst_SF : m_SFs) {
-            if (m_handle->applySystematicVariation(Syst_SF.first) != StatusCode::SUCCESS) {
-                return CP::CorrectionCode::Error;
-            }
-            CP::CorrectionCode cc = m_handle->getEfficiencyScaleFactorReplicas(muon, Syst_SF.second);
-            if (cc == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-        }
-        return CP::CorrectionCode::Ok;
-    }
-    std::string MuonReplicaBranches::name() const {
-        return m_release + (m_release.empty() ? "" : "_") + getProperty<std::string>(m_handle.operator->(), "WorkingPoint");
+    MuonReplicaBranches::MuonReplicaBranches(MuonVal::MuonTesterTree& tree, 
+                                             const ToolHandle<CP::IMuonEfficiencyScaleFactors> &handle, 
+                                             const std::string& relName) :
+        MuonVal::MuonTesterBranch{tree, relName + (relName.empty() ? "" : "_") + 
+                                 getProperty<std::string>(handle.get(), "WorkingPoint") + "SFReplica"},
+        m_handle{handle} {
     }
     bool MuonReplicaBranches::init() {
         for (auto set : CP::make_systematics_vector(m_handle->recommendedSystematics())) {
-            std::map<CP::SystematicSet, std::vector<float>>::iterator Itr = m_SFs.find(set);
-            if (Itr == m_SFs.end()) {
-                m_SFs.insert(std::pair<CP::SystematicSet, std::vector<float> >(set, std::vector<float>()));
-                Itr = m_SFs.find(set);
-                std::string SystName = (set.name().empty() ? std::string("") : std::string("__")) + set.name();
-                if (!initBranch(Itr->second, std::string("SFReplica") + SystName)) return false;
-            }
+            auto br =std::make_shared<MuonVal::VectorBranch<float>>(tree(), name() + MuonSFBranches::systName(set)); 
+            m_SFs[set] = br;
+            if(!br->init()) return false;
         }
         return true;
     }
-    //###########################################################
-    //                  MuonInfoBranches
-    //###########################################################
-    MuonInfoBranches::MuonInfoBranches(TTree* tree, const ToolHandle<CP::IMuonSelectionTool>& sel_tool) :
-                MuonEffiBranches(tree),
-                m_selection_tool(sel_tool),
-                m_pt(FLT_MAX),
-                m_eta(FLT_MAX),
-                m_phi(FLT_MAX),
-                m_quality(-1),
-                m_author(-1),
-                m_type(-1),
-                m_passLowPt(false),
-                m_passHighPt(false),
-                m_precLayers(0){
-    }
-    bool MuonInfoBranches::init() {
-        if (!initBranch(m_pt, "pt")) return false;
-        if (!initBranch(m_eta, "eta")) return false;
-        if (!initBranch(m_phi, "phi")) return false;
-        if (!initBranch(m_quality, "quality")) return false;
-        if (!initBranch(m_author, "author")) return false;
-        if (!m_selection_tool.isSet()) return true;
-        if (!initBranch(m_passLowPt, "isLowPt")) return false;
-        if (!initBranch(m_passHighPt, "isHighPt")) return false;
-        if (!initBranch(m_precLayers, "PrecisionLayers")) return false;
-        
-       
-        return true;
-    }
-    std::string MuonInfoBranches::name() const {
-        return "Muon";
-    }
-    CP::CorrectionCode MuonInfoBranches::fill(const xAOD::Muon& muon) {
-        m_pt = muon.pt();
-        m_eta = muon.eta();
-        m_phi = muon.phi();
-        m_author = muon.author();
-        m_type = muon.type();
-        if (!muon.summaryValue(m_precLayers, xAOD::SummaryType::numberOfPrecisionLayers)){
-            Error("MuonInfoBranches()", "Failed to retrieve the precision layers");
-            return CP::CorrectionCode::Error;
-        }
-        if (m_selection_tool.isSet()){
-            m_quality = m_selection_tool->getQuality(muon);
-            m_passLowPt = m_selection_tool->passedLowPtEfficiencyCuts(muon);
-            m_passHighPt = m_selection_tool->passedHighPtCuts(muon);
-        } else m_quality = muon.quality();
-        return CP::CorrectionCode::Ok;
-    }
-
-    //###########################################################
-    //                  MuonSFTestHelper
-    //###########################################################
-    MuonSFTestHelper::MuonSFTestHelper(const std::string& release_name, bool HasOwnerShip) :
-                m_name(release_name),
-                m_tree(),
-                m_tree_raw_ptr(new TTree("MuonEfficiencyTest", "MuonEfficiencyTest")),
-                m_Branches(),
-                m_sel_tool(){
-        if (release_name.find('/') != std::string::npos) m_name = "c" + release_name.substr(release_name.rfind('/') + 1, m_name.size()); // branches cannot start with number
-        m_Branches.push_back(std::make_unique<TestMuonSF::MuonInfoBranches>(tree(),m_sel_tool));
-        if (HasOwnerShip) m_tree = std::shared_ptr < TTree > (m_tree_raw_ptr);
-    }
-    MuonSFTestHelper::MuonSFTestHelper(std::shared_ptr<TTree> tree, const std::string& release_name) :
-                m_name(release_name),
-                m_tree(tree),
-                m_tree_raw_ptr(tree.get()),
-                m_Branches(),
-                m_sel_tool(){
-        if (release_name.find('/') != std::string::npos) m_name = "c" + release_name.substr(release_name.rfind('/') + 1, m_name.size()); // branches cannot start with number
-    }
-    MuonSFTestHelper::MuonSFTestHelper(TTree* tree, const std::string& release_name) :
-                m_name(release_name),
-                m_tree(),
-                m_tree_raw_ptr(tree),
-                m_Branches(),
-                m_sel_tool(){
-        if (release_name.find('/') != std::string::npos) m_name = "c" + release_name.substr(release_name.rfind('/') + 1, m_name.size()); // branches cannot start with number
-    }
-    void MuonSFTestHelper::addTool(const asg::AnaToolHandle<CP::IMuonEfficiencyScaleFactors> &handle) {
-        addTool(handle.getHandle());
-    }
-    void MuonSFTestHelper::addTool(const ToolHandle<CP::IMuonEfficiencyScaleFactors>& handle) {
-        m_Branches.push_back(std::make_unique<TestMuonSF::MuonSFBranches>(tree(), handle, m_name));
-    }
-    void MuonSFTestHelper::addReplicaTool(const asg::AnaToolHandle<CP::IMuonEfficiencyScaleFactors> &handle) {
-        addReplicaTool(handle.getHandle());
-    }
-    void MuonSFTestHelper::addReplicaTool(const ToolHandle<CP::IMuonEfficiencyScaleFactors>& handle) {
-        m_Branches.push_back(std::make_unique<TestMuonSF::MuonReplicaBranches>(tree(), handle, m_name));
-    }
-    void MuonSFTestHelper::setSelectionTool(const asg::AnaToolHandle<CP::IMuonSelectionTool> & sel_tool){
-        setSelectionTool(sel_tool.getHandle());
-    }
-    void MuonSFTestHelper::setSelectionTool(const ToolHandle<CP::IMuonSelectionTool> & sel_tool){
-       m_sel_tool = sel_tool;    
-    }
-          
-    bool MuonSFTestHelper::init() {
-        if (m_Branches.empty()) {
-            Error("init()", "No scale-factors have been defined thus far");
-            return false;
-        }
-        for (auto& BR : m_Branches) {
-            if (!BR->init()) return false;
+    bool MuonReplicaBranches::fill(const EventContext& ctx) {
+        for (auto& [sys, br] : m_SFs) {
+            if (!br->fill(ctx)) {
+                ATH_MSG_ERROR("Failed to fill "<<sys.name());
+                return false;
+            }
         }
         return true;
     }
-    CP::CorrectionCode MuonSFTestHelper::fill(const xAOD::Muon* mu) {
-        return fill(*mu);
-    }
-    CP::CorrectionCode MuonSFTestHelper::fill(const xAOD::Muon& mu) {
-        for (auto& br : m_Branches) {
-            if (br->fill(mu) == CP::CorrectionCode::Error) {return CP::CorrectionCode::Error;}
-        }
-        return CP::CorrectionCode::Ok;
-    }
-    CP::CorrectionCode MuonSFTestHelper::fill(const xAOD::MuonContainer* muons) {
-        for (const auto mu : *muons) {
-            if (fill(mu) == CP::CorrectionCode::Error) return CP::CorrectionCode::Error;
-            fillTree();
+
+    void MuonReplicaBranches::setMuon(const xAOD::Muon& muon) {
+        for (auto& [cpSys, br] : m_SFs) {
+            if (m_handle->applySystematicVariation(cpSys) != StatusCode::SUCCESS) {
+                return;
+            }
+            std::vector<float> replica{};
+            CP::CorrectionCode cc = m_handle->getEfficiencyScaleFactorReplicas(muon, replica);
+            if (cc == CP::CorrectionCode::Error) {
+                return;
+            }
+            for (auto repl : replica) {
+                br->push_back(repl);
+            }
         }
-        return CP::CorrectionCode::Ok;
-    }
-    TTree* MuonSFTestHelper::tree() {
-        return m_tree_raw_ptr;
     }
-    std::shared_ptr<TTree> MuonSFTestHelper::tree_shared() {
-        return m_tree;
-    }
-    void MuonSFTestHelper::fillTree() {
-        tree()->Fill();
-    }
-
 }
 
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx
deleted file mode 100644
index 9d5efeaeb855..000000000000
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.cxx
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
- */
-
-// Local include(s):
-#include "MuonEfficiencyCorrections_TestAlg.h"
-#include "PATInterfaces/SystematicsTool.h"
-#include <cmath>
-
-#include "xAODMuon/MuonContainer.h"
-#include "xAODJet/JetContainer.h"
-
-namespace CP {
-
-    MuonEfficiencyCorrections_TestAlg::MuonEfficiencyCorrections_TestAlg(const std::string& name, ISvcLocator* svcLoc) :
-                AthHistogramAlgorithm(name, svcLoc) {
-        // force strict checking of return codes
-        CP::CorrectionCode::enableFailure();
-    }
-
-    StatusCode MuonEfficiencyCorrections_TestAlg::initialize() {
-        ATH_MSG_DEBUG("SGKey = " << m_sgKey);
-        ATH_CHECK(m_eventInfo.initialize());
-        ATH_CHECK(m_prw_Tool.retrieve());
-        ATH_CHECK(m_sel_tool.retrieve());
-        ATH_MSG_DEBUG("PileupReweightingTool  = " << m_prw_Tool);
-        if (m_effi_SF_tools.empty()) {
-            ATH_MSG_FATAL("Please provide at least one muon sf- tool");
-            return StatusCode::FAILURE;
-        }
-        if (m_comparison_tools.empty()) {
-            m_test_helper = std::make_unique < TestMuonSF::MuonSFTestHelper > ();
-        } else {
-            m_test_helper = std::make_unique < TestMuonSF::MuonSFTestHelper > (m_first_release_name);
-            m_comparison_helper = std::make_unique < TestMuonSF::MuonSFTestHelper> (m_test_helper->tree(), m_second_release_name);
-            for (auto & SFTool : m_comparison_tools) {
-                ATH_CHECK(SFTool.retrieve());
-                m_comparison_helper->addTool(SFTool);
-            }
-        }
-        m_test_helper->setSelectionTool(m_sel_tool);
-        m_test_helper->tree()->Branch("eventNumber", &m_evNumber);
-        for (auto & SFTool : m_effi_SF_tools) {
-            ATH_CHECK(SFTool.retrieve());
-            m_test_helper->addTool(SFTool);
-        }
-        if (!m_test_helper->init()) {
-            ATH_MSG_FATAL("Failed to initialize");
-            return StatusCode::FAILURE;
-        }
-        if (m_comparison_helper && !m_comparison_helper->init()) {
-            ATH_MSG_FATAL("Failed to initialize");
-            return StatusCode::FAILURE;
-        }
-        ATH_CHECK(histSvc()->regTree(std::string("/MUONEFFTESTER/") + m_test_helper->tree()->GetName(), m_test_helper->tree()));
-        return StatusCode::SUCCESS;
-    }
-
-    StatusCode MuonEfficiencyCorrections_TestAlg::execute() {
-        // Retrieve the muons:
-        const xAOD::MuonContainer* muons = nullptr;
-        ATH_CHECK(evtStore()->retrieve(muons, m_sgKey));
-        // Retrieve the EventInfo:
-        SG::ReadHandle<xAOD::EventInfo> ei(m_eventInfo);
-       
-        ATH_MSG_DEBUG("Start to run over event "<<ei->eventNumber()<<" in run" <<ei->runNumber());
-       
-        //Apply the prwTool first before calling the efficiency correction methods
-        ATH_CHECK(m_prw_Tool->apply(*ei));
-        m_evNumber = ei->eventNumber();
-        
-        for (const auto mu : *muons) {
-            if (mu->pt() < m_pt_cut || (m_eta_cut > 0 && std::abs(mu->eta()) >= m_eta_cut)) continue;
-            // reject all loose muons
-            if (m_sel_tool->getQuality(*mu) > m_muon_quality) continue;          
-            if (m_test_helper->fill(mu) != CP::CorrectionCode::Ok || (m_comparison_helper && m_comparison_helper->fill(mu) != CP::CorrectionCode::Ok)) {
-                ATH_MSG_FATAL("Failed to fill muon with pt: "<<mu->pt()/1.e3<<" GeV eta: "<<mu->eta()<<" phi: "<<mu->phi());
-                return StatusCode::FAILURE;
-            }           
-            m_test_helper->fillTree();
-        }
-        ATH_MSG_DEBUG("Done with processing the event");
-        // Return gracefully:
-        return StatusCode::SUCCESS;
-    }
-
-} // namespace CP
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx
new file mode 100644
index 000000000000..aeb578fb52f5
--- /dev/null
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx
@@ -0,0 +1,93 @@
+/*
+ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+ */
+
+// Local include(s):
+#include "MuonScaleFactorTestAlg.h"
+#include "StoreGate/ReadHandle.h"
+#include "MuonTesterTree/EventInfoBranch.h"
+#include "PATInterfaces/SystematicsTool.h"
+#include <cmath>
+
+namespace{
+    constexpr double MeVtoGeV = 1.e-3;
+}
+
+namespace CP {
+    MuonScaleFactorTestAlg::MuonScaleFactorTestAlg(const std::string& name, ISvcLocator* svcLoc) :
+        AthHistogramAlgorithm(name, svcLoc) {
+        // force strict checking of return codes
+        CP::CorrectionCode::enableFailure();
+    }
+
+    StatusCode MuonScaleFactorTestAlg::initialize() {
+        ATH_CHECK(m_eventInfo.initialize());
+        ATH_CHECK(m_sgKey.initialize());
+        ATH_CHECK(m_prw_Tool.retrieve());
+        ATH_CHECK(m_sel_tool.retrieve());
+
+        ATH_MSG_DEBUG("PileupReweightingTool  = " << m_prw_Tool);
+        ATH_CHECK(m_effiTools.retrieve());
+        ATH_CHECK(m_comparisonTools.retrieve());
+        for (auto& tool : m_effiTools) {
+            auto sfBranch = std::make_shared<TestMuonSF::MuonSFBranches>(m_tree,tool,
+                                                                         m_comparisonTools.empty() ? "" : m_defaultRelease);
+            
+            m_sfBranches.push_back(sfBranch);
+            m_tree.addBranch(sfBranch);
+
+            auto replicaBranch = std::make_shared<TestMuonSF::MuonReplicaBranches>(m_tree, tool,
+                                                                                   m_comparisonTools.empty() ? "" : m_defaultRelease);
+
+            m_sfBranches.push_back(replicaBranch);
+            m_tree.addBranch(replicaBranch);        
+        }
+        for (auto& tool : m_comparisonTools) {
+            auto sfBranch = std::make_shared<TestMuonSF::MuonSFBranches>(m_tree, tool, m_validRelease);
+            m_sfBranches.push_back(sfBranch);
+            m_tree.addBranch(sfBranch);
+
+            auto replicaBranch = std::make_shared<TestMuonSF::MuonReplicaBranches>(m_tree,tool, m_validRelease);
+            m_sfBranches.push_back(replicaBranch);
+            m_tree.addBranch(replicaBranch);        
+        } 
+        ATH_CHECK(m_tree.init(this));
+        return StatusCode::SUCCESS;
+    }
+    StatusCode MuonScaleFactorTestAlg::finalize() {
+        ATH_CHECK(m_tree.write());
+        return StatusCode::SUCCESS;
+    }
+
+    StatusCode MuonScaleFactorTestAlg::execute() {
+        const EventContext& ctx{Gaudi::Hive::currentContext()};        
+        // Retrieve the muons:
+        SG::ReadHandle<xAOD::MuonContainer> muons{m_sgKey, ctx};       
+        // Retrieve the EventInfo:
+        SG::ReadHandle<xAOD::EventInfo> ei{m_eventInfo, ctx};
+       
+        ATH_MSG_DEBUG("Start to run over event "<<ei->eventNumber()<<" in run" <<ei->runNumber());
+       
+        //Apply the prwTool first before calling the efficiency correction methods
+        ATH_CHECK(m_prw_Tool->apply(*ei));       
+        
+        for (const xAOD::Muon* mu : *muons) {
+            if (mu->pt() < m_pt_cut || (m_eta_cut > 0 && std::abs(mu->eta()) >= m_eta_cut)) continue;
+            // reject all loose muons
+            if (m_sel_tool->getQuality(*mu) > m_muon_quality) continue;          
+            
+            m_muonPt = mu->pt() * MeVtoGeV;
+            m_muonEta = mu->eta();
+            m_muonPhi = mu->phi();
+            m_muonQ = mu->charge();
+            for (auto& br : m_sfBranches) {
+                br->setMuon(*mu);
+            }
+            ATH_CHECK(m_tree.fill(ctx));          
+        }
+        ATH_MSG_DEBUG("Done with processing the event");
+        // Return gracefully:
+        return StatusCode::SUCCESS;
+    }
+
+} // namespace CP
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.h
similarity index 59%
rename from PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h
rename to PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.h
index 5314a2dd218d..4d340fcf047e 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonEfficiencyCorrections_TestAlg.h
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.h
@@ -13,50 +13,64 @@
 #include "MuonEfficiencyCorrections/MuonSFTestHelper.h"
 
 #include "MuonAnalysisInterfaces/IMuonEfficiencyScaleFactors.h"
+#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h"
 #include "MuonAnalysisInterfaces/IMuonSelectionTool.h"
 
 #include "AsgAnalysisInterfaces/IPileupReweightingTool.h"
 
+#include "MuonTesterTree/MuonTesterTree.h"
+
 namespace CP {
 
 /// small test algorithm to quickly test/demonstrate the usage of the MuonEfficiencyCorrections code within athena
 
-    class MuonEfficiencyCorrections_TestAlg: public AthHistogramAlgorithm {
+    class MuonScaleFactorTestAlg: public AthHistogramAlgorithm {
 
         public:
             /// Regular Algorithm constructor
-            MuonEfficiencyCorrections_TestAlg(const std::string& name, ISvcLocator* svcLoc);
+            MuonScaleFactorTestAlg(const std::string& name, ISvcLocator* svcLoc);
 
             /// Function initialising the algorithm
             StatusCode initialize() override;
+            /// Function finalizing the algortihm
+            StatusCode finalize() override;
             /// Function executing the algorithm
             StatusCode execute() override;
-            virtual ~MuonEfficiencyCorrections_TestAlg() = default;
+            virtual ~MuonScaleFactorTestAlg() = default;
 
         private:
             SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo{this, "EventInfoContName", "EventInfo", "event info key"};
             /// muon container
             SG::ReadHandleKey<xAOD::MuonContainer> m_sgKey{this, "SGKey", "Muons"};
 
-            ToolHandleArray<IMuonEfficiencyScaleFactors> m_effi_SF_tools{this, "EfficiencyTools", {}};
-            ToolHandleArray<IMuonEfficiencyScaleFactors> m_comparison_tools{this, "EfficiencyToolsForComparison", {}};
+            ToolHandleArray<IMuonEfficiencyScaleFactors> m_effiTools{this, "EfficiencyTools", {}};
+            ToolHandleArray<IMuonEfficiencyScaleFactors> m_comparisonTools{this, "EfficiencyToolsForComparison", {}};
 
             /// Scale factor tool
             ToolHandle<IPileupReweightingTool> m_prw_Tool{this, "PileupReweightingTool", ""};
             ToolHandle<IMuonSelectionTool> m_sel_tool{this, "MuonSelectionTool", ""};
 
-            std::unique_ptr<TestMuonSF::MuonSFTestHelper> m_test_helper{};
-            std::unique_ptr<TestMuonSF::MuonSFTestHelper> m_comparison_helper{};
+            
 
 
-            Gaudi::Property<std::string> m_first_release_name{this, "DefaultRelease", ""};
-            Gaudi::Property<std::string> m_second_release_name{this, "ValidationRelease", ""};
+            Gaudi::Property<std::string> m_defaultRelease{this, "DefaultRelease", ""};
+            Gaudi::Property<std::string> m_validRelease{this, "ValidationRelease", ""};
             
             Gaudi::Property<float> m_pt_cut{this, "MinPt", -1.};
             Gaudi::Property<float> m_eta_cut{this, "MaxEta", -1.};
             Gaudi::Property<int> m_muon_quality{this, "MinQuality", xAOD::Muon::Loose};
+
+            MuonVal::MuonTesterTree m_tree{"MuonSFTester", "MUONEFFTESTER"};
+
+            MuonVal::ScalarBranch<float>& m_muonPt{m_tree.newScalar<float>("muon_pt")};
+            MuonVal::ScalarBranch<float>& m_muonEta{m_tree.newScalar<float>("muon_eta")};
+            MuonVal::ScalarBranch<float>& m_muonPhi{m_tree.newScalar<float>("muon_phi")};
+            MuonVal::ScalarBranch<int>& m_muonQ{m_tree.newScalar<int>("muon_q")};
+
+            std::vector<std::shared_ptr<TestMuonSF::MuonEffiBranch>> m_sfBranches{};
+
             
-            unsigned long long m_evNumber;
+
     };
 
 } // namespace CP
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.cxx
deleted file mode 100644
index ee430b81580d..000000000000
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.cxx
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
- */
-#include "MuonEfficiencyCorrections/MuonSFTestHelper.h"
-#include "PATInterfaces/SystematicsUtil.h"
-
-#include "MuonTriggerSF_TestAlg.h"
-
-
-namespace Trig{
-    //=============================================================================
-    MuonTriggerSF_TestAlg::MuonTriggerSF_TestAlg(const std::string& name,
-                    ISvcLocator* pSvcLocator) :
-                    AthAlgorithm(name, pSvcLocator),
-                    m_outputStream(""),
-                    m_inputContainerName(""),
-                    m_triggers(),
-                    m_branches(),
-                    m_histSvc("THistSvc/THistSvc", name),
-                    m_trigEff(""),
-                    m_prwTool(""),
-                    m_tree(nullptr),
-                    m_runNumber(-1) {
-        declareProperty("outputStream", m_outputStream);
-        declareProperty("inputContainerName", m_inputContainerName);
-        declareProperty("triggers" , m_triggers);
-       
-        declareProperty("TriggerEfficiencyTool", m_trigEff);
-        declareProperty("prwTool", m_prwTool);
-        
-    }
-
-    //=============================================================================
-    StatusCode MuonTriggerSF_TestAlg::initialize() {
-        ATH_CHECK(m_eventInfo.initialize());
-        CHECK(m_histSvc.retrieve());
-        CHECK(m_trigEff.retrieve());
-        CHECK(m_prwTool.retrieve());
-        
-        //Create the tree and register it to the hist-service
-        std::string tree_key = "/TRIGGERSFTESTER/" + m_outputStream ;
-        m_tree = new TTree (m_outputStream.c_str(), "TriggerSFTesterTree");
-        m_tree->Branch("runNumber", &m_runNumber);
-        
-        
-        for (const auto& trig: m_triggers){
-            m_branches.push_back(TestMuonSF::TriggerSFBranch_Ptr( new TestMuonSF::TriggerSFBranches(m_tree, m_trigEff, trig) ));
-        }
-        m_triggers.clear();
-        for (const auto& branch : m_branches){
-            if(!branch->init()) return StatusCode::FAILURE;
-        }
-        
-        for (CP::SystematicVariation syst : m_trigEff->affectingSystematics()) {
-           ATH_MSG_INFO("Recommended systematic: " << syst.name());
-        }
-        ATH_CHECK(m_histSvc->regTree(tree_key.c_str(), m_tree));
-        return StatusCode::SUCCESS;
-    }
-
-    //=============================================================================
-    StatusCode MuonTriggerSF_TestAlg::execute() {
-        
-        //Retrieve the EventInfo to apply the prwTool before activating the trigger tool
-        SG::ReadHandle<xAOD::EventInfo> evtInfo(m_eventInfo);
-        ATH_CHECK(m_prwTool->apply(*evtInfo));
-        m_runNumber = m_prwTool->getRandomRunNumber(*evtInfo);
-        
-        const xAOD::MuonContainer* Muons;
-        ATH_CHECK(evtStore()->retrieve(Muons,"Muons"));
-        if (Muons->empty()) return StatusCode::SUCCESS;
-        
-        for (const auto& branch : m_branches){
-            if (branch->fill(Muons) != CP::CorrectionCode::Ok) return StatusCode::FAILURE;
-        }
-        m_tree->Fill();
-        
-        return StatusCode::SUCCESS;
-    }
-
-    //=============================================================================
-    StatusCode MuonTriggerSF_TestAlg::finalize() {     
-        return StatusCode::SUCCESS;
-    }
-}
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.h b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.h
deleted file mode 100644
index bfc3bde42319..000000000000
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonTriggerSF_TestAlg.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
- */
-
-
-// Gaudi/Athena include(s):
-#include "AthenaBaseComps/AthAlgorithm.h"
-#include "GaudiKernel/ITHistSvc.h"
-#include "GaudiKernel/ToolHandle.h"
-#include "StoreGate/ReadHandleKey.h"
-#include "xAODEventInfo/EventInfo.h"
-
-#include "AsgTools/ToolHandleArray.h"
-
-#include "PATInterfaces/SystematicsUtil.h"
-
-#include <MuonEfficiencyCorrections/MuonSFTestHelper.h>
-#include <MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h>
-#include "AsgAnalysisInterfaces/IPileupReweightingTool.h"
-
-namespace Trig{
-    class MuonTriggerSF_TestAlg: virtual public AthAlgorithm {
-        public:
-
-            MuonTriggerSF_TestAlg(const std::string& name, ISvcLocator* pSvcLocator);
-            virtual ~MuonTriggerSF_TestAlg() {
-            }
-
-            StatusCode initialize();
-            StatusCode execute();
-            StatusCode finalize();
-        private:
-            SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo{this, "EventInfoContName", "EventInfo", "event info key"};
-            // Properties:
-            std::string m_outputStream;
-            std::string m_inputContainerName;
-            std::vector<std::string> m_triggers;
-            std::vector<TestMuonSF::TriggerSFBranch_Ptr> m_branches;
-
-            // Tools and services:
-            ServiceHandle<ITHistSvc> m_histSvc;
-            ToolHandle<CP::IMuonTriggerScaleFactors> m_trigEff;
-            ToolHandle<CP::IPileupReweightingTool> m_prwTool;
-            TTree* m_tree;
-            unsigned int m_runNumber;            
-  
-    };
-}
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.cxx
deleted file mode 100644
index 00658366d851..000000000000
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.cxx
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
- */
-
-// ROOT
-#include "TH1.h"
-#include "TH2.h"
-
-// xAOD
-#include "xAODMuon/MuonContainer.h"
-#include "AthContainers/ConstDataVector.h"
-
-// Local
-#include "TestTrigSF.h"
-
-using namespace Trig;
-
-//=============================================================================
-TestTrigSF::TestTrigSF(const std::string& name,
-                ISvcLocator* pSvcLocator) :
-                AthAlgorithm(name, pSvcLocator),
-                m_histSvc("THistSvc/THistSvc", name),
-                m_countEvent(0),
-                m_barrel_sf(0),
-                m_endcap_sf(0),
-                m_barrel_sf_err_stat_up(0),
-                m_barrel_sf_err_stat_dw(0),
-                m_endcap_sf_err_stat_up(0),
-                m_endcap_sf_err_stat_dw(0),
-                m_barrel_sf_err_syst_up(0),
-                m_barrel_sf_err_syst_dw(0),
-                m_endcap_sf_err_syst_up(0),
-                m_endcap_sf_err_syst_dw(0)
-{
-    declareProperty("outputStream", m_outputStream);
-    declareProperty("inputContainerName", m_inputContainerName);
-    declareProperty("triggersName", m_triggerName = "HLT_mu14");
-
-    declareProperty("trigEff", m_trigEff);
-}
-
-//=============================================================================
-StatusCode TestTrigSF::initialize()
-{
-    //
-    // Initialize tools and services
-    //
-    CHECK(m_histSvc.retrieve());
-    CHECK(m_trigEff.retrieve());
-
-    //
-    // Start total
-    //
-    m_timerTotal.Start();
-
-    double *barrel_phi = new double[7];
-    barrel_phi[0] = -2.9453;
-    barrel_phi[1] = -2.1598;
-    barrel_phi[2] = -0.9817;
-    barrel_phi[3] = -0.1963;
-    barrel_phi[4] = 0.9817;
-    barrel_phi[5] = 2.1598;
-    barrel_phi[6] = 3.3380;
-
-    double *barrel_eta = new double[7];
-    barrel_eta[0] = -1.05;
-    barrel_eta[1] = -0.908;
-    barrel_eta[2] = -0.476;
-    barrel_eta[3] = 0.0;
-    barrel_eta[4] = 0.476;
-    barrel_eta[5] = 0.908;
-    barrel_eta[6] = 1.05;
-
-    double *endcap_eta = new double[12];
-    endcap_eta[0] = -2.5;
-    endcap_eta[1] = -2.4;
-    endcap_eta[2] = -1.918;
-    endcap_eta[3] = -1.348;
-    endcap_eta[4] = -1.1479;
-    endcap_eta[5] = -1.05;
-    endcap_eta[6] = 1.05;
-    endcap_eta[7] = 1.1479;
-    endcap_eta[8] = 1.348;
-    endcap_eta[9] = 1.918;
-    endcap_eta[10] = 2.4;
-    endcap_eta[11] = 2.5;
-
-    m_barrel_sf = new TH2D("barrel_sf", "", 6, barrel_eta, 6, barrel_phi);
-    m_endcap_sf = new TH2D("endcap_sf", "", 11, endcap_eta, 12, -3.403392, 2.879793);
-
-    RegHist(m_barrel_sf, "");
-    RegHist(m_endcap_sf, "");
-
-    m_barrel_sf_err_stat_up = new TH2D("barrel_sf_err_stat_up", "", 6, barrel_eta, 6, barrel_phi);
-    m_barrel_sf_err_stat_dw = new TH2D("barrel_sf_err_stat_dw", "", 6, barrel_eta, 6, barrel_phi);
-
-    m_endcap_sf_err_stat_up = new TH2D("endcap_sf_err_stat_up", "", 11, endcap_eta, 12, -3.403392, 2.879793);
-    m_endcap_sf_err_stat_dw = new TH2D("endcap_sf_err_stat_dw", "", 11, endcap_eta, 12, -3.403392, 2.879793);
-
-    m_barrel_sf_err_syst_up = new TH2D("barrel_sf_err_syst_up", "", 6, barrel_eta, 6, barrel_phi);
-    m_barrel_sf_err_syst_dw = new TH2D("barrel_sf_err_syst_dw", "", 6, barrel_eta, 6, barrel_phi);
-
-    m_endcap_sf_err_syst_up = new TH2D("endcap_sf_err_syst_up", "", 11, endcap_eta, 12, -3.403392, 2.879793);
-    m_endcap_sf_err_syst_dw = new TH2D("endcap_sf_err_syst_dw", "", 11, endcap_eta, 12, -3.403392, 2.879793);
-
-    RegHist(m_barrel_sf_err_stat_up, "");
-    RegHist(m_barrel_sf_err_stat_dw, "");
-
-    RegHist(m_endcap_sf_err_stat_up, "");
-    RegHist(m_endcap_sf_err_stat_dw, "");
-
-    RegHist(m_barrel_sf_err_syst_up, "");
-    RegHist(m_barrel_sf_err_syst_dw, "");
-
-    RegHist(m_endcap_sf_err_syst_up, "");
-    RegHist(m_endcap_sf_err_syst_dw, "");
-
-    for (CP::SystematicVariation syst : m_trigEff->affectingSystematics()) {
-        msg(MSG::INFO) << "Recommended systematic: " << syst.name() << endmsg;
-    }
-
-    return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-StatusCode TestTrigSF::execute()
-{
-    //
-    // Process current event
-    //
-    msg() << MSG::DEBUG << "execute() - begin..." << endmsg;
-
-    m_countEvent++;
-
-    const xAOD::MuonContainer* xaodContainer = 0;
-
-    if (evtStore()->retrieve(xaodContainer, m_inputContainerName).isFailure() || !xaodContainer) {
-        msg() << MSG::ERROR << "Failed to get:" << m_inputContainerName << endmsg;
-        return StatusCode::FAILURE;
-    }
-
-    msg(MSG::DEBUG) << "Size of MuonContainer: " << xaodContainer->size() << endmsg;
-
-    //-----------------------------------------------------------------------------
-    // Process muons
-    //
-    for (const xAOD::Muon *ptr : *xaodContainer) {
-
-        msg(MSG::DEBUG) << "   pT= " << ptr->pt() << endmsg;
-
-        CheckSF(ptr);
-    }
-
-    msg(MSG::DEBUG) << "execute() - processed " << endmsg;
-    return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-StatusCode TestTrigSF::finalize()
-{
-    //
-    // Finalize output
-    //
-    msg(MSG::INFO) << " processed " << m_countEvent << " event(s)" << endmsg;
-
-    return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-void TestTrigSF::CheckSF(const xAOD::Muon *ptr)
-                {
-    //-----------------------------------------------------------------------------
-    // Muon trigger SF
-    //
-    ConstDataVector < xAOD::MuonContainer > trigger_SF_muon(SG::VIEW_ELEMENTS);
-    trigger_SF_muon.push_back(ptr);
-
-    double triggerSF = 0.0;
-
-    CP::CorrectionCode ct = m_trigEff->getTriggerScaleFactor(*trigger_SF_muon.asDataVector(), triggerSF, m_triggerName);
-
-    if (ct.code() == 0) {
-        msg(MSG::WARNING) << "Failed to get trigger SF" << endmsg;
-        return;
-    }
-
-    TH2 *h = m_endcap_sf;
-    TH2 *h_stat_up = m_endcap_sf_err_stat_up;
-    TH2 *h_stat_dw = m_endcap_sf_err_stat_dw;
-    TH2 *h_syst_up = m_endcap_sf_err_syst_up;
-    TH2 *h_syst_dw = m_endcap_sf_err_syst_dw;
-
-    std::string key = "endcap";
-
-    if (std::abs(ptr->eta()) < 1.05) {
-        h = m_barrel_sf;
-        h_stat_up = m_barrel_sf_err_stat_up;
-        h_stat_dw = m_barrel_sf_err_stat_dw;
-        h_syst_up = m_barrel_sf_err_syst_up;
-        h_syst_dw = m_barrel_sf_err_syst_dw;
-
-        key = "barrel";
-    }
-
-    if (!h) {
-        msg(MSG::WARNING) << "Missing hist" << endmsg;
-        return;
-    }
-
-    FillHist(h, ptr, triggerSF);
-
-    msg(MSG::INFO) << m_triggerName << " eta=" << ptr->eta() << " phi=" << ptr->phi() << " SF value=" << triggerSF << endmsg;
-
-    //
-    // Chck systematic
-    //
-    CheckSyst(ptr, "MUON_EFF_TrigStatUncertainty", +1, h_stat_up);
-    CheckSyst(ptr, "MUON_EFF_TrigStatUncertainty", -1, h_stat_dw);
-
-    CheckSyst(ptr, "MUON_EFF_TrigSystUncertainty", +1, h_syst_up);
-    CheckSyst(ptr, "MUON_EFF_TrigSystUncertainty", -1, h_syst_dw);
-}
-
-//=============================================================================
-void TestTrigSF::CheckSyst(const xAOD::Muon *ptr, const std::string &syst_name, int step, TH2 *h)
-                {
-    CP::SystematicVariation syst(syst_name, step);
-
-    const bool isaff = m_trigEff->isAffectedBySystematic(syst);
-
-    if (!isaff) {
-        msg(MSG::WARNING) << syst_name << " step=" << step << ": isAffected=" << isaff << endmsg;
-        return;
-    }
-
-    CP::SystematicSet syst_set;
-    syst_set.insert(syst);
-
-    if (m_trigEff->applySystematicVariation(syst_set) != StatusCode::SUCCESS) {
-        msg(MSG::WARNING) << "Failed to apply systematic: " << syst_name << endmsg;
-        return;
-    }
-
-    ConstDataVector < xAOD::MuonContainer > trigger_SF_muon(SG::VIEW_ELEMENTS);
-    trigger_SF_muon.push_back(ptr);
-
-    double triggerSF = 0.0;
-
-    if (m_trigEff->getTriggerScaleFactor(*trigger_SF_muon.asDataVector(), triggerSF, m_triggerName) != CP::CorrectionCode::Ok) {
-        msg(MSG::WARNING) << "Failed to get trigger SF" << endmsg;
-        return;
-    }
-
-    FillHist(h, ptr, triggerSF);
-
-    msg(MSG::INFO) << "Systematic=" << syst_name << " step=" << step << " hist=" << h->GetName() << " SF value=" << triggerSF << endmsg;
-
-    if (m_trigEff->applySystematicVariation(CP::SystematicSet()) != StatusCode::SUCCESS) {
-        msg(MSG::WARNING) << "Failed to apply default after systematic: " << syst_name << endmsg;
-        return;
-    }
-}
-
-//=============================================================================
-void TestTrigSF::FillHist(TH2 *h, const xAOD::Muon *ptr, double val)
-                {
-    const int bin = h->FindBin(ptr->eta(), ptr->phi());
-
-    const double hcont = h->GetBinContent(bin);
-
-    msg(MSG::DEBUG) << " hist=" << h->GetName() << " bin=" << bin << " eta=" << ptr->eta() << " phi=" << ptr->phi() << endmsg;
-
-    if (hcont > 0.0) {
-
-        if (std::abs(hcont - val) > 0.0001) {
-            msg(MSG::WARNING) << " hist=" << h->GetName() << "   content=" << hcont << " != val=" << val << endmsg;
-        }
-    }
-    else {
-        h->SetBinContent(bin, val);
-    }
-}
-
-//=============================================================================
-void TestTrigSF::RegHist(TH1 *h, const std::string &key)
-                {
-    //
-    // Register histogram
-    //
-    std::string hist_key = "/" + m_outputStream + "/" + key;
-    if (key.empty() && h) {
-        hist_key = "/" + m_outputStream + "/" + std::string(h->GetName());
-    }
-
-    if (m_histSvc->regHist(hist_key, h).isFailure()) {
-        msg() << MSG::WARNING << "Could not register histogram: " << hist_key << endmsg;
-    }
-    else {
-        msg() << MSG::INFO << "Registered histogram: " << hist_key << endmsg;
-    }
-}
-
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.h b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.h
deleted file mode 100644
index d0bc396364cc..000000000000
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/TestTrigSF.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Dear emacs, this is -*- c++ -*-
-
-/*
- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
- */
-
-#ifndef TRIG_TESTTRIGSF_H
-#define TRIG_TESTTRIGSF_H
-
-//
-// Algorithm to test trigger SF
-//
-
-// C/C++
-#include <set>
-
-// ROOT
-#include "TStopwatch.h"
-
-// Gaudi
-#include "GaudiKernel/ITHistSvc.h"
-#include "GaudiKernel/ToolHandle.h"
-
-// Athena
-#include "AthenaBaseComps/AthAlgorithm.h"
-
-// Local
-#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h"
-
-class TH1;
-class TH2;
-
-namespace Trig
-{
-    class Object;
-
-    class TestTrigSF: virtual public AthAlgorithm
-    {
-        public:
-
-            TestTrigSF(const std::string& name, ISvcLocator* pSvcLocator);
-            virtual ~TestTrigSF() {
-            }
-
-            StatusCode initialize();
-            StatusCode execute();
-            StatusCode finalize();
-
-        private:
-
-            typedef std::map<std::string, std::string> L1Map;
-
-        private:
-
-            void RegHist(TH1 *h, const std::string &key);
-
-            void CheckSF(const xAOD::Muon *ptr);
-
-            void CheckSyst(const xAOD::Muon *ptr, const std::string &syst_name, int step, TH2 *h);
-
-            void FillHist(TH2 *h, const xAOD::Muon *ptr, double val);
-
-        private:
-
-            // Properties:
-            std::string m_outputStream;
-            std::string m_inputContainerName;
-            std::string m_triggerName;
-
-            // Tools and services:
-            ServiceHandle<ITHistSvc> m_histSvc;
-            ToolHandle<CP::IMuonTriggerScaleFactors> m_trigEff;
-
-            // Variables:
-            TStopwatch m_timerEvent; // Total job timer
-            TStopwatch m_timerTotal; // Total job timer
-
-            int m_countEvent;
-
-            L1Map m_mapL1;
-
-            TH2 *m_barrel_sf;
-            TH2 *m_endcap_sf;
-
-            TH2 *m_barrel_sf_err_stat_up;
-            TH2 *m_barrel_sf_err_stat_dw;
-
-            TH2 *m_endcap_sf_err_stat_up;
-            TH2 *m_endcap_sf_err_stat_dw;
-
-            TH2 *m_barrel_sf_err_syst_up;
-            TH2 *m_barrel_sf_err_syst_dw;
-
-            TH2 *m_endcap_sf_err_syst_up;
-            TH2 *m_endcap_sf_err_syst_dw;
-    };
-}
-
-#endif
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/components/MuonEfficiencyCorrections_entries.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/components/MuonEfficiencyCorrections_entries.cxx
index 5584ac803da6..2a496a4e7de0 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/components/MuonEfficiencyCorrections_entries.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/components/MuonEfficiencyCorrections_entries.cxx
@@ -1,22 +1,15 @@
 /*
- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
  */
 // Local include(s):
 #include "MuonEfficiencyCorrections/MuonEfficiencyScaleFactors.h"
 #include "MuonEfficiencyCorrections/MuonTriggerScaleFactors.h"
 // MCP tester macros
-#include "../MuonEfficiencyCorrections_TestAlg.h"
-#include "../TestTrigSF.h"
-#include "../MuonTriggerSF_TestAlg.h"
+#include "../MuonScaleFactorTestAlg.h"
 #include "../MuonCloseJetDecorationAlg.h"
 
 DECLARE_COMPONENT( CP::MuonEfficiencyScaleFactors )
-
 DECLARE_COMPONENT( CP::MuonTriggerScaleFactors )
 
-DECLARE_COMPONENT( CP::MuonEfficiencyCorrections_TestAlg )
-DECLARE_COMPONENT( CP::MuonCloseJetDecorationAlg )
-
-DECLARE_COMPONENT( Trig::TestTrigSF )
-
-DECLARE_COMPONENT( Trig::MuonTriggerSF_TestAlg )
+DECLARE_COMPONENT( CP::MuonScaleFactorTestAlg )
+DECLARE_COMPONENT( CP::MuonCloseJetDecorationAlg )
\ No newline at end of file
-- 
GitLab


From e5d9fc28ab37b4cff10497eb3a4b817dbdac993e Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Tue, 14 May 2024 11:38:40 +0200
Subject: [PATCH 3/7] Add CA config

---
 .../MuonEfficiencyCorrections/CMakeLists.txt  |  3 +
 .../python/MuonEfficiencyCorrectionsCfg.py    | 83 +++++++++++++++++++
 2 files changed, 86 insertions(+)
 create mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
index 64057a7d8168..1786d60306ce 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
@@ -45,3 +45,6 @@ if( XAOD_STANDALONE )
    _add_exec( MuonTriggerSFFilesTest )
    _add_exec( MuonTriggerSFConfGenerator )
 endif()
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
new file mode 100644
index 000000000000..688c7514bceb
--- /dev/null
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+def MuonScaleFactorTestAlgCfg(flags, name="MuonScaleFactorTestAlg", **kwargs):
+    result = ComponentAccumulator()
+    from MuonSelectorTools.MuonSelectorToolsConfig import MuonSelectionToolCfg
+    kwargs.setdefault("MuonSelectionTool", result.popToolsAndMerge(MuonSelectionToolCfg(flags)))
+    the_alg = CompFactory.CP.MuonScaleFactorTestAlg(name, **kwargs)
+    result.addEventAlgo(the_alg, primary = True)
+    return result
+
+def MuonEfficiencyCorrectionsCfg(flags, name="MuonEffiCorrections", **kwargs):
+    result = ComponentAccumulator()
+    kwargs.setdefault("ApplyKinematicSystematic", False)
+    eff_tool = CompFactory.CP.MuonEfficiencyScaleFactors(name, **kwargs)
+    result.setPrivateTools(eff_tool)
+    return result
+
+def setupHistSvcCfg(flags, out_file="EffTester.root"):
+    result = ComponentAccumulator()
+    if len(out_file) == 0: return result
+    histSvc = CompFactory.THistSvc(Output=["MUONEFFTESTER DATAFILE='{out_file}', OPT='RECREATE'".format(out_file = out_file)])
+    result.addService(histSvc, primary=True)
+    return result
+
+def setupArgParser():
+    from argparse import ArgumentParser
+
+    parser = ArgumentParser()
+    parser.add_argument("--threads", type=int, help="number of threads", default=1)
+    parser.add_argument("--inputFile", "-i", default=[
+                        "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Tier0ChainTests/mc20_13TeV.361107.PowhegPythia8EvtGen_AZNLOCTEQ6L1_Zmumu.recon.AOD.e3601_s3681_r13167/AOD.27312826._000061.pool.root.1"
+                        ], 
+                        help="Input file to run on ", nargs="+")
+    parser.add_argument("--outRootFile", default="EffiDump.root", help="Output ROOT file to dump the geomerty")
+    parser.add_argument("--maxEvents", type=int, help="Maximum events to run on", default = -1)
+    return parser
+
+
+
+if __name__ == "__main__":
+    from AthenaConfiguration.AllConfigFlags import initConfigFlags 
+
+    args = setupArgParser().parse_args()
+
+    flags = initConfigFlags()
+    flags.Concurrency.NumThreads = args.threads
+    flags.Concurrency.NumConcurrentEvents = args.threads  # Might change this later, but good enough for the moment.
+    flags.Input.Files = args.inputFile
+    flags.Scheduler.ShowDataDeps = True 
+    flags.Scheduler.ShowDataFlow = True
+    flags.lock()
+    flags.dump(evaluate=True)
+
+
+    from AthenaConfiguration.MainServicesConfig import MainServicesCfg
+    cfg = MainServicesCfg(flags)
+    ### Setup the file reading
+    from AthenaConfiguration.Enums import Format
+    if flags.Input.Format == Format.POOL:
+        from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+        cfg.merge(PoolReadCfg(flags))
+    
+    cfg.merge(setupHistSvcCfg(flags, out_file = args.outRootFile))
+    cfg.merge(MuonScaleFactorTestAlgCfg(flags))
+
+    cfg.printConfig(withDetails=True, summariseProps=True)
+   
+    sc = cfg.run(args.maxEvents)
+    if not sc.isSuccess():
+        import sys
+        sys.exit("Execution failed")
+
+
+
+
+
+
+    
+
-- 
GitLab


From b14d87fd5ea12f92d7976ce9c492d6bf932a6701 Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Tue, 14 May 2024 11:41:49 +0200
Subject: [PATCH 4/7] Yeeeeees there's a pile-up CA configuration

---
 .../python/MuonEfficiencyCorrectionsCfg.py                      | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
index 688c7514bceb..08eab67d517f 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
@@ -8,6 +8,8 @@ def MuonScaleFactorTestAlgCfg(flags, name="MuonScaleFactorTestAlg", **kwargs):
     result = ComponentAccumulator()
     from MuonSelectorTools.MuonSelectorToolsConfig import MuonSelectionToolCfg
     kwargs.setdefault("MuonSelectionTool", result.popToolsAndMerge(MuonSelectionToolCfg(flags)))
+    from AsgAnalysisAlgorithms.PileupReweightingAlgConfig import PileupReweightingToolCfg
+    kwargs.setdefault("PileupReweightingTool", result.popToolsAndMerge(PileupReweightingToolCfg(flags)))
     the_alg = CompFactory.CP.MuonScaleFactorTestAlg(name, **kwargs)
     result.addEventAlgo(the_alg, primary = True)
     return result
-- 
GitLab


From 171ee60654d6fb997a5c22630b04bb2897e36040 Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Tue, 14 May 2024 11:49:25 +0200
Subject: [PATCH 5/7] Add SF tool & event info

---
 .../python/MuonEfficiencyCorrectionsCfg.py                    | 4 +++-
 .../MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
index 08eab67d517f..45cc92c21318 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/python/MuonEfficiencyCorrectionsCfg.py
@@ -67,7 +67,9 @@ if __name__ == "__main__":
         cfg.merge(PoolReadCfg(flags))
     
     cfg.merge(setupHistSvcCfg(flags, out_file = args.outRootFile))
-    cfg.merge(MuonScaleFactorTestAlgCfg(flags))
+    sf_tools= [cfg.popToolsAndMerge(MuonEfficiencyCorrectionsCfg(flags,
+                                                                WorkingPoint="Loose"))]
+    cfg.merge(MuonScaleFactorTestAlgCfg(flags, EfficiencyTools = sf_tools))
 
     cfg.printConfig(withDetails=True, summariseProps=True)
    
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx
index aeb578fb52f5..5c58cd3f78ec 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/src/MuonScaleFactorTestAlg.cxx
@@ -50,7 +50,8 @@ namespace CP {
             auto replicaBranch = std::make_shared<TestMuonSF::MuonReplicaBranches>(m_tree,tool, m_validRelease);
             m_sfBranches.push_back(replicaBranch);
             m_tree.addBranch(replicaBranch);        
-        } 
+        }
+        m_tree.addBranch(std::make_shared<MuonVal::EventInfoBranch>(m_tree, 0));
         ATH_CHECK(m_tree.init(this));
         return StatusCode::SUCCESS;
     }
-- 
GitLab


From 84ce999926599c5b55cd58c17bc6050c80ab5722 Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Tue, 14 May 2024 13:18:00 +0200
Subject: [PATCH 6/7] protect code

---
 .../MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx        | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
index 6173393d30c4..22501ff239a1 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/Root/MuonSFTestHelper.cxx
@@ -2,6 +2,7 @@
  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
  */
 
+#ifndef XAOD_STANDALONE
 #include "MuonEfficiencyCorrections/MuonSFTestHelper.h"
 #include "MuonEfficiencyCorrections/UtilFunctions.h"
 #include "MuonEfficiencyCorrections/MuonEfficiencyScaleFactors.h"
@@ -230,4 +231,4 @@ namespace TestMuonSF {
         }
     }
 }
-
+#endif
-- 
GitLab


From 1f0c1eaa3f5ee3e2783076d6e017f55d7f414416 Mon Sep 17 00:00:00 2001
From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Tue, 14 May 2024 15:10:11 +0200
Subject: [PATCH 7/7] Tschuuuuuuuss

---
 .../MuonEfficiencyCorrections/CMakeLists.txt  |   1 -
 ...MuonEfficiencyScaleFactorsSFFileTester.cxx | 234 ------------------
 2 files changed, 235 deletions(-)
 delete mode 100644 PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/util/MuonEfficiencyScaleFactorsSFFileTester.cxx

diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
index 1786d60306ce..8d40ad9578ef 100644
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
+++ b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/CMakeLists.txt
@@ -40,7 +40,6 @@ endmacro( _add_exec )
 
 if( XAOD_STANDALONE )
    _add_exec( MuonEfficiencyScaleFactorsTest )
-   _add_exec( MuonEfficiencyScaleFactorsSFFileTester )
    _add_exec( MuonTriggerSFRootCoreTest )
    _add_exec( MuonTriggerSFFilesTest )
    _add_exec( MuonTriggerSFConfGenerator )
diff --git a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/util/MuonEfficiencyScaleFactorsSFFileTester.cxx b/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/util/MuonEfficiencyScaleFactorsSFFileTester.cxx
deleted file mode 100644
index 40999f80cfa2..000000000000
--- a/PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections/util/MuonEfficiencyScaleFactorsSFFileTester.cxx
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
- */
-
-/*
- * This macro is meant for testing purposes of the MCP efficiency teams, it is not a minimal working example for analyzers,
- * please use MuonEfficiencyScaleFactorsTest or MuonTriggerSFRootCoreTest instead
- */
-
-#include <memory>
-#include <cstdlib>
-#include <string>
-#include <map>
-
-// ROOT include(s):
-#include <TFile.h>
-#include <TError.h>
-#include <TStopwatch.h>
-#include <TString.h>
-
-// Infrastructure include(s):
-#ifdef ROOTCORE
-#   include "xAODRootAccess/Init.h"
-#   include "xAODRootAccess/TEvent.h"
-#   include "xAODRootAccess/tools/ReturnCheck.h"
-#   include "AsgMessaging/Check.h"
-#endif // ROOTCORE
-
-// EDM include(s):
-#include "xAODEventInfo/EventInfo.h"
-#include "xAODMuon/MuonContainer.h"
-#include "xAODMuon/MuonAuxContainer.h"
-
-// Local include(s):
-#include "MuonEfficiencyCorrections/MuonEfficiencyScaleFactors.h"
-#include "PATInterfaces/ISystematicsTool.h"
-
-#include "xAODCore/tools/IOStats.h"
-#include "xAODCore/tools/ReadStats.h"
-
-#include "AsgTools/ToolHandle.h"
-#include "AsgTools/StandaloneToolHandle.h"
-#include "AsgAnalysisInterfaces/IPileupReweightingTool.h"
-
-#include "MuonEfficiencyCorrections/MuonSFTestHelper.h"
-#define CHECK_CPCorr(Arg) \
-    if (Arg.code() == CP::CorrectionCode::Error){    \
-        Error(#Arg,"Correction Code 'Error' (returned in line %i) ",__LINE__); \
-        return 1;   \
-    }
-
-typedef asg::StandaloneToolHandle<CP::IMuonEfficiencyScaleFactors> EffiToolInstance;
-
-EffiToolInstance createSFTool(const std::string& WP, const std::string& CustomInput, bool uncorrelate_Syst, bool doJPsi, bool isComparison=false) {
-    EffiToolInstance tool(std::string("CP::MuonEfficiencyScaleFactors/EffiTool_") + WP + (isComparison ? "_comp" : "" ) );
-
-    tool.setProperty("WorkingPoint", WP).isSuccess();
-    tool.setProperty("UncorrelateSystematics", uncorrelate_Syst).isSuccess();
-    if (doJPsi) tool.setProperty("LowPtThreshold", 1.e14).isSuccess();
-    else tool.setProperty("LowPtThreshold", -1.).isSuccess();
-    if (!CustomInput.empty()) tool.setProperty("CustomInputFolder", CustomInput).isSuccess();
-    tool.retrieve().isSuccess();
-
-    return tool;
-}
-
-int main(int argc, char* argv[]) {
-
-    // force strict checking of return codes
-    StatusCode::enableFailure();
-    StatusCode::enableFailure();
-
-    // The application's name:
-    const char* APP_NAME = argv[0];
-
-    // this default is for MC16a -> data2016
-    std::string prwFilename = "dev/PileupReweighting/share/DSID361xxx/pileup_mc20a_dsid361107_FS.root";
-    std::string ilumiFilename = "GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root";
-    std::string OutputFilename = "Applied_SFs.root";
-    std::string InDir = "";
-    std::string DefaultCalibRelease = "";
-    std::string SFComparisonFolder = "";
-    bool doJPsi = false;
-    long long int nmax = -1;
-
-    // read the config provided by the user
-    for (int k = 1; k < argc - 1; ++k) {
-        if (std::string(argv[k]).find("-i") == 0) {
-            InDir = argv[k + 1];
-        }
-        if (std::string(argv[k]).find("--c1") == 0) {
-            DefaultCalibRelease = argv[k + 1];
-        }
-        if (std::string(argv[k]).find("--c2") == 0) {
-            SFComparisonFolder = argv[k + 1];
-        }
-        if (std::string(argv[k]).find("-n") == 0) {
-            nmax = atoi(argv[k + 1]);
-        }
-        if (std::string(argv[k]).find("-o") == 0) {
-            OutputFilename = argv[k + 1];
-        }
-        if (std::string(argv[k]).find("--JPsi") == 0) {
-            doJPsi = true;
-            if (OutputFilename == "Applied_SFs.root") OutputFilename = "Applied_SFs_JPsi.root";
-        }
-        if (std::string(argv[k]).find("--ilumi") == 0) {
-            ilumiFilename = argv[k + 1];
-        }
-        if (std::string(argv[k]).find("--prw") == 0) {
-            prwFilename = argv[k + 1];
-        }
-    }
-    bool doComparison = !SFComparisonFolder.empty();
-
-    // check( if we received a file name:
-    if (argc < 3) {
-        Error(APP_NAME, "No file name received!");
-        Error(APP_NAME, "  Usage: %s -i [xAOD file name]", APP_NAME);
-        return EXIT_FAILURE;
-    }
-
-    RETURN_CHECK(APP_NAME, xAOD::Init(APP_NAME));
-
-    // Open the input file:
-    const TString fileName = InDir;
-    Info(APP_NAME, "Opening file: %s", fileName.Data());
-    std::unique_ptr<TFile> ifile(TFile::Open(fileName, "READ"));
-    if (!ifile.get()) {
-        Error(APP_NAME, " Unable to load xAOD input file");
-        return EXIT_FAILURE;
-    }
-
-    // Create a TEvent object:
-    xAOD::TEvent event;
-    RETURN_CHECK(APP_NAME, event.readFrom(ifile.get(), xAOD::TEvent::kClassAccess));
-    Info(APP_NAME, "Number of events in the file: %i", static_cast<int>(event.getEntries()));
-
-    // Decide how many events to run over:
-    Long64_t entries = event.getEntries();
-    if ((nmax != -1) && (nmax < entries)) entries = nmax;
-
-    TStopwatch tsw;
-    tsw.Start();
-
-    const std::vector<std::string> WPs {
-        // reconstruction WPs
-        "Loose", "Medium", "Tight", "HighPt", "LowPt",
-        // track-to-vertex-association WPs
-        "TTVA",
-        // BadMuon veto SFs
-        //"BadMuonVeto_HighPt",
-        // isolation WPs
-        "Loose_VarRadIso", "Tight_VarRadIso", "PflowLoose_VarRadIso", "PflowTight_VarRadIso"
-    };
-    std::vector<EffiToolInstance> EffiTools;
-    std::vector<EffiToolInstance> ComparisonTools;
-
-    for (auto& WP : WPs) {
-        EffiTools.push_back(createSFTool(WP, DefaultCalibRelease, false, doJPsi));
-        if (doComparison) ComparisonTools.push_back(createSFTool(WP, SFComparisonFolder, false, doJPsi, true));
-    }
-
-    TestMuonSF::MuonSFTestHelper PrimaryHelper(DefaultCalibRelease, true);
-    TestMuonSF::MuonSFTestHelper ComparisonHelper(PrimaryHelper.tree_shared(), SFComparisonFolder);
-
-    for (auto Effi : EffiTools) {
-        PrimaryHelper.addTool(Effi.getHandle());
-        PrimaryHelper.addReplicaTool(Effi.getHandle());
-    }
-    for (auto Effi : ComparisonTools) {
-        ComparisonHelper.addTool(Effi.getHandle());
-        ComparisonHelper.addReplicaTool(Effi.getHandle());
-    }
-    if (!PrimaryHelper.init()) return EXIT_FAILURE;
-    if (doComparison && !ComparisonHelper.init()) return EXIT_FAILURE;
-    double t_init = tsw.CpuTime();
-    tsw.Reset();
-    tsw.Start();
-
-    unsigned int nMuons = 0;
-
-    asg::StandaloneToolHandle < CP::IPileupReweightingTool > m_prw_tool("CP::PileupReweightingTool/myTool");
-    // This is just a placeholder configuration for testing. Do not use these config files for your analysis!
-    std::vector<std::string> m_ConfigFiles { prwFilename };
-    std::vector<std::string> m_LumiCalcFiles { ilumiFilename };
-    ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("ConfigFiles", m_ConfigFiles));
-    ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("LumiCalcFiles", m_LumiCalcFiles));
-    ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("DataScaleFactor", 1.0 / 1.09));
-    ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("DataScaleFactorUP", 1.));
-    ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("DataScaleFactorDOWN", 1.0 / 1.18));
-    ASG_CHECK_SA(APP_NAME, m_prw_tool.initialize());
-
-    // write a root file containing the SFs, stat and sys errors
-    TFile *f = new TFile(OutputFilename.c_str(), "RECREATE");
-
-    for (Long64_t entry = 0; entry < entries; ++entry) {
-
-        // Tell the object which entry to look at:
-        event.getEntry(entry);
-
-        // Print some event information for fun:
-        const xAOD::EventInfo* ei = 0;
-        RETURN_CHECK(APP_NAME, event.retrieve(ei, "EventInfo"));
-        RETURN_CHECK(APP_NAME, m_prw_tool->apply(*ei));
-        if (entry % 5000 == 0) Info(APP_NAME, "===>>>  start processing event #%i, run #%i (%i events processed so far)  <<<===", static_cast<int>(ei->eventNumber()), static_cast<int>(ei->runNumber()), static_cast<int>(entry));
-
-        // Get the Muons from the event:
-        const xAOD::MuonContainer* muons = 0;
-        RETURN_CHECK(APP_NAME, event.retrieve(muons, "Muons"));
-        for (const auto *mu : *muons) {
-            if (PrimaryHelper.fill(mu) != CP::CorrectionCode::Ok) return EXIT_FAILURE;
-            if (doComparison && ComparisonHelper.fill(mu) != CP::CorrectionCode::Ok) return EXIT_FAILURE;
-            PrimaryHelper.fillTree();
-        }
-        nMuons = nMuons+muons->size();
-
-    }
-    double t_run = tsw.CpuTime() / entries;
-    Info(APP_NAME, " MCP init took %g s", t_init);
-    Info(APP_NAME, " time per event: %g s", t_run);
-
-    std::cout << "Number of muons in file: " << nMuons << std::endl;
-
-    f->cd();
-    f->WriteObject(PrimaryHelper.tree(), PrimaryHelper.tree()->GetName());
-    f->Close();
-
-    //get smart slimming list
-    xAOD::IOStats::instance().stats().printSmartSlimmingBranchList();
-
-    // Return gracefully:
-    return 0;
-}
-- 
GitLab