From 3792231e67f64174b2ec1ad44e2ff531617f7250 Mon Sep 17 00:00:00 2001
From: Tomas Dado <tomas.dado@cern.ch>
Date: Thu, 3 Dec 2020 10:28:09 +0100
Subject: [PATCH] AnalysisTop: Re-anabling GlobalTriggerEfficiencyCorrection
 tool

---
 .../TopPhys/xAOD/TopCPTools/CMakeLists.txt    |   1 +
 .../TopCPTools/Root/TopTriggerCPTools.cxx     | 538 +++++++++---------
 2 files changed, 265 insertions(+), 274 deletions(-)

diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt
index 2a7dfa40be52..89ba00a007bf 100644
--- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt
+++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt
@@ -35,6 +35,7 @@ atlas_add_library( TopCPTools Root/*.cxx Root/*.h Root/*.icc
                                   TrigConfInterfaces
                                   TrigDecisionToolLib
                                   TriggerAnalysisInterfaces
+                                  TrigGlobalEfficiencyCorrectionLib
                                   TrigTauMatchingLib
                                   TriggerMatchingToolLib
                                   xAODBTaggingEfficiencyLib
diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx
index 190f0f6cc559..acf7072d6997 100644
--- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx
+++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
  */
 
 #include "TopCPTools/TopTriggerCPTools.h"
@@ -22,8 +22,8 @@
 #include "TriggerMatchingTool/MatchingTool.h"
 #include "TriggerMatchingTool/MatchFromCompositeTool.h"
 #include "TrigTauMatching/TrigTauMatching.h"
-//#include "TrigGlobalEfficiencyCorrection/TrigGlobalEfficiencyCorrectionTool.h"
-//#include "TrigGlobalEfficiencyCorrection/ImportData.h"
+#include "TrigGlobalEfficiencyCorrection/TrigGlobalEfficiencyCorrectionTool.h"
+#include "TrigGlobalEfficiencyCorrection/ImportData.h"
 #include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h"
 #include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h"
 #include "MuonEfficiencyCorrections/MuonTriggerScaleFactors.h"
@@ -79,20 +79,10 @@ namespace top {
         if (asg::ToolStore::contains<Trig::IMatchingTool>(trig_match_name)) {
           m_trigMatchTool = asg::ToolStore::get<Trig::IMatchingTool>(trig_match_name);
         } else {
-          if (m_config->getDerivationStream() == "PHYS") {
-            Trig::MatchFromCompositeTool* trigMatchTool = new Trig::MatchFromCompositeTool(trig_match_name);
-            top::check(trigMatchTool->initialize(),
-                       "Failed to initialize trig. matching tool");
-            m_trigMatchTool = trigMatchTool;
-
-          } else {
-            Trig::MatchingTool* trigMatchTool = new Trig::MatchingTool(trig_match_name);
-            top::check(trigMatchTool->setProperty("TrigDecisionTool", m_trigDecisionTool),
-                       "Failed to set trigger decision tool to trigger matching tool");
-            top::check(trigMatchTool->initialize(),
-                       "Failed to initialize trig. matching tool");
-            m_trigMatchTool = trigMatchTool;
-          }
+          Trig::MatchFromCompositeTool* trigMatchTool = new Trig::MatchFromCompositeTool(trig_match_name);
+          top::check(trigMatchTool->initialize(),
+                     "Failed to initialize trig. matching tool");
+          m_trigMatchTool = trigMatchTool;
         }
 
         ///-- Tau matching --///
@@ -128,267 +118,267 @@ namespace top {
     StatusCode statusCode = StatusCode::SUCCESS;
 
     // utilities for TrigGlobEffCorr::ImportData
-    //TrigGlobEffCorr::ImportData triggerData;
-    //top::check(triggerData.importTriggers(), "failed to import trigger data");
-    //auto const& triggerDict = triggerData.getDictionary();
-    //std::unordered_map<std::string, TrigGlobEffCorr::ImportData::TrigDef> triggerDefs;
-    //for (auto&& kv : triggerData.getTriggerDefs()) {
-    //  auto it = triggerDict.find(kv.first);
-    //  if (it != triggerDict.end()) {
-    //    triggerDefs[it->second] = kv.second;
-    //  }
-    //}
-    //auto getTriggerLegs =
-    //  [&](std::unordered_map<std::string, std::vector<std::string> > const& triggerCombination,
-    //      std::unordered_map<std::string, std::set<std::string> >& electronLegsByPeriod) {
-    //    for (auto&& kv : triggerCombination) {
-    //      std::string const& period = kv.first;
-    //      for (auto const& trigKey : kv.second) {
-    //        auto triggerDefsIt = triggerDefs.find(trigKey);
-    //        if (triggerDefsIt == triggerDefs.end()) {
-    //          statusCode = StatusCode::FAILURE;
-    //          ATH_MSG_ERROR("unrecognized trigger `" << trigKey << "'");
-    //          continue;
-    //        }
-    //        auto const& trigDef = triggerDefsIt->second;
-    //        for (auto const& leg : trigDef.leg) {
-    //          if (!leg) continue;
-    //          std::string const& legname = triggerDict.at(leg);
-    //          bool ok = true;
-    //          xAOD::Type::ObjectType legtype = triggerData.associatedLeptonFlavour(legname, ok);
-    //          if (!ok) {
-    //            statusCode = StatusCode::FAILURE;
-    //            ATH_MSG_ERROR("could not determine object type for trigger leg `" << legname <<
-    //              "'");
-    //            continue;
-    //          }
-    //          switch (legtype) {
-    //          case xAOD::Type::Electron:
-    //            electronLegsByPeriod[period].insert(legname);
-    //            break;
-
-    //          case xAOD::Type::Muon:
-    //            break;
-
-    //          default:
-    //            statusCode = StatusCode::FAILURE;
-    //            ATH_MSG_ERROR(
-    //              "trigger leg `" << legname << "' has unsupported object type `" << legtype << "'");
-    //            continue;
-    //          }
-    //        }
-    //      }
-    //    }
-    //  };
-
-    //// Get trigger strings from configuration
-    //std::map<std::string, std::string> triggerCombination, triggerCombinationLoose;
-    //std::vector<std::string> electronSystematics, muonSystematics, electronToolNames, muonToolNames;
-    //std::unordered_map<std::string, std::vector<std::string> > const emptymap;
-    //std::unordered_map<std::string, std::vector<std::string> > const&
-    //triggersByPeriod = (m_config->doTightEvents() ? m_config->getGlobalTriggers() : emptymap),
-    //  triggersByPeriodLoose = (m_config->doLooseEvents() ? m_config->getGlobalTriggersLoose() : emptymap);
-
-    //std::unordered_map<std::string, std::set<std::string> > electronLegsByPeriod, electronLegsByPeriodLoose;
-    //getTriggerLegs(triggersByPeriod, electronLegsByPeriod);
-    //getTriggerLegs(triggersByPeriodLoose, electronLegsByPeriodLoose);
-
-    //// Get quality
-    //std::string electronID, electronIDLoose, electronIsolation, electronIsolationLoose, muonQuality, muonQualityLoose;
-    //if (m_config->doTightEvents()) {
-    //  electronID = m_config->electronID();
-    //  electronIsolation = m_config->electronIsolationSF();
-    //  muonQuality = m_config->muonQuality();
-    //}
-    //if (m_config->doLooseEvents()) {
-    //  electronIDLoose = m_config->electronIDLoose();
-    //  electronIsolationLoose = m_config->electronIsolationSFLoose();
-    //  muonQualityLoose = m_config->muonQualityLoose();
-    //}
-
-    //// Tidy name for e/gamma
-    //electronID = mapWorkingPoints(electronID);
-    //electronIDLoose = mapWorkingPoints(electronIDLoose);
-    //// This is hopefully only temporary
-    //electronIsolation = mapWorkingPoints(electronIsolation);
-    //electronIsolationLoose = mapWorkingPoints(electronIsolationLoose);
-
-    //// Create electron trigger SF and Eff tools
-    //ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools, electronSFTools, electronEffToolsLoose,
-    //                                                      electronSFToolsLoose;
-    //std::map<std::string, std::string> legsPerTool, legsPerToolLoose;
-    //int nTools = 0;
-
-    //// Loop over the triggers found (electrons - tight)
-    //for (auto& y_t : electronLegsByPeriod) {
-    //  std::string year = y_t.first;
-    //  for (auto& trigKey : y_t.second) {
-    //    nTools++;
-    //    for (int j = 0; j < 2; ++j) { // one tool instance for efficiencies, another for scale factors
-    //      ATH_MSG_INFO("TIGHT " << year << " " << trigKey << " " << electronID << " " << electronIsolation);
-    //      auto t = m_electronToolsFactory.emplace(
-    //        m_electronToolsFactory.end(), "AsgElectronEfficiencyCorrectionTool/ElTrigEff_" + std::to_string(
-    //          j) + "_" + std::to_string(nTools));
-    //      top::check(t->setProperty("MapFilePath",
-    //                                "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/map3.txt"),
-    //                 "Fail");
-    //      top::check(t->setProperty("TriggerKey",
-    //                                (j ? year + "_" + trigKey : "Eff_" + year + "_" + trigKey)),
-    //                 "Failed to set TriggerKey");
-    //      if (electronID != "None") top::check(t->setProperty("IdKey", electronID), "Failed to set IdKey");
-    //      if (electronIsolation != "None") top::check(t->setProperty("IsoKey",
-    //                                                                 electronIsolation), "Failed to set IsoKey");
-    //      top::check(t->setProperty("CorrelationModel", "TOTAL"), "Failed to set CorrelationModel");
-    //      top::check(t->setProperty("ForceDataType",
-    //                                (int) PATCore::ParticleDataType::Full), "Failed to set ForceDataType");
-    //      top::check(t->setProperty("OutputLevel", MSG::INFO), "Failed to set OutputLevel");
-    //      top::check(t->initialize(), "Failed to initalise");
-    //      // Using syntax from examples
-    //      auto& handles = j ? electronSFTools : electronEffTools;
-    //      handles.push_back(t->getHandle());
-    //      std::string name = handles[handles.size() - 1].name();
-    //      legsPerTool[name] = trigKey + " [" + year + "]";
-    //      ATH_MSG_INFO("TIGHT " << name << " -> " << trigKey);
-    //      electronToolNames.push_back(name);
-    //      // Special - Record the systematic names from the efficiency tool (not SF tool)
-    //      if (electronSystematics.size() == 0 && j == 1) {
-    //        for (auto& s :
-    //             handles[handles.size() - 1]->recommendedSystematics().getBaseNames()) electronSystematics.push_back(s);
-
-    //      }
-    //    }
-    //  }
-    //}
-
-    //// Loop over the triggers found (electrons - loose)
-    //nTools = 0;
-    //for (auto& y_t : electronLegsByPeriodLoose) {
-    //  std::string year = y_t.first;
-    //  for (auto& trigKey : y_t.second) {
-    //    nTools++;
-    //    for (int j = 0; j < 2; ++j) { // one tool instance for efficiencies, another for scale factors
-    //      ATH_MSG_INFO("LOOSE " << year << " " << trigKey << " " << electronIDLoose << " " << electronIsolationLoose);
-    //      auto tLoose = m_electronToolsFactoryLoose.emplace(
-    //        m_electronToolsFactoryLoose.end(), "AsgElectronEfficiencyCorrectionTool/ElTrigEffLoose_" + std::to_string(
-    //          j) + "_" + std::to_string(nTools));
-    //      top::check(tLoose->setProperty("MapFilePath",
-    //                                     "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/map3.txt"),
-    //                 "Fail");
-    //      top::check(tLoose->setProperty("TriggerKey",
-    //                                     (j ? year + "_" + trigKey : "Eff_" + year + "_" + trigKey)),
-    //                 "Failed to set TriggerKey");
-    //      if (electronIDLoose !=
-    //          "None") top::check(tLoose->setProperty("IdKey", electronIDLoose), "Failed to set IdKey");
-    //      if (electronIsolationLoose != "None") top::check(tLoose->setProperty("IsoKey",
-    //                                                                           electronIsolationLoose),
-    //                                                       "Failed to set IsoKey");
-    //      top::check(tLoose->setProperty("CorrelationModel", "TOTAL"), "Failed to set CorrelationModel");
-    //      top::check(tLoose->setProperty("ForceDataType",
-    //                                     (int) PATCore::ParticleDataType::Full), "Failed to set ForceDataType");
-    //      top::check(tLoose->setProperty("OutputLevel", MSG::INFO), "Failed to set OutputLevel");
-    //      top::check(tLoose->initialize(), "Failed to initalise");
-    //      // Using syntax from examples
-    //      auto& handlesLoose = j ? electronSFToolsLoose : electronEffToolsLoose;
-    //      handlesLoose.push_back(tLoose->getHandle());
-    //      std::string name = handlesLoose[handlesLoose.size() - 1].name();
-    //      legsPerToolLoose[name] = trigKey + " [" + year + "]";
-    //      ATH_MSG_INFO("LOOSE " << name << " -> " << trigKey);
-    //      electronToolNames.push_back(name);
-    //      // Special - Record the systematic names from the efficiency tool (not SF tool)
-    //      if (electronSystematics.size() == 0 && j == 1) {
-    //        for (auto& s :
-    //             handlesLoose[handlesLoose.size() -
-    //                          1]->recommendedSystematics().getBaseNames()) electronSystematics.push_back(s);
-    //      }
-    //    }
-    //  }
-    //}
-
-    //// Create muon trigger SF tool
-    //ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
-    //ToolHandleArray<CP::IMuonTriggerScaleFactors> muonToolsLoose;
-
-    //if (m_config->doTightEvents()) {
-    //  if (muonQuality != "None") top::check(m_muonTool.setProperty("MuonQuality",
-    //                                                               muonQuality), "Failed to set MuonQuality");
-    //  top::check(m_muonTool.setProperty("AllowZeroSF", true), "Failed to set AllowZeroSF");
-    //  top::check(m_muonTool.initialize(), "Failed to initialise");
-    //  muonTools.push_back(m_muonTool.getHandle());
-    //  ATH_MSG_INFO("Muon tool name (tight) " << muonTools[muonTools.size() - 1].name());
-    //  muonToolNames.push_back(muonTools[muonTools.size() - 1].name());
-    //  // Special - Get muon systematics
-    //  if (muonSystematics.size() == 0) {
-    //    for (auto& s:
-    //    muonTools[muonTools.size() - 1]->recommendedSystematics().getBaseNames()) muonSystematics.push_back(s);
-    //  }
-    //}
-
-    //if (m_config->doLooseEvents()) {
-    //  if (muonQualityLoose != "None") top::check(m_muonToolLoose.setProperty("MuonQuality",
-    //                                                                         muonQualityLoose),
-    //    "Failed to set MuonQuality");
-    //  top::check(m_muonToolLoose.setProperty("AllowZeroSF", true), "Failed to set AllowZeroSF");
-    //  top::check(m_muonToolLoose.initialize(), "Failed to initialise");
-    //  muonToolsLoose.push_back(m_muonToolLoose.getHandle());
-    //  ATH_MSG_INFO("Muon tool name (loose) " << muonToolsLoose[muonToolsLoose.size() - 1].name());
-    //  muonToolNames.push_back(muonToolsLoose[muonToolsLoose.size() - 1].name());
-    //  // Special - Get muon systematics
-    //  if (muonSystematics.size() == 0) {
-    //    for (auto& s: muonToolsLoose[muonToolsLoose.size() - 1]->recommendedSystematics().getBaseNames()) muonSystematics.push_back(s);
-    //  }
-    //}
-
-    //for (auto& key : triggersByPeriod) {
-    //  if (triggerCombination.find(key.first) == triggerCombination.end()) {
-    //    triggerCombination[key.first] = "";
-    //  } else {
-    //    triggerCombination[key.first] += " || ";
-    //  }
-    //  triggerCombination[key.first] += boost::algorithm::join(key.second, " || ");
-    //}
-    //for (auto& key : triggersByPeriodLoose) {
-    //  if (triggerCombinationLoose.find(key.first) == triggerCombinationLoose.end()) {
-    //    triggerCombinationLoose[key.first] = "";
-    //  } else {
-    //    triggerCombinationLoose[key.first] += " || ";
-    //  }
-    //  triggerCombinationLoose[key.first] += boost::algorithm::join(key.second, " || ");
-    //}
-
-    //// Print out what we configured
-    //for (auto kv: triggerCombination) ATH_MSG_DEBUG("TRIG (TIGHT): " << kv.first << " -> " << kv.second);
-    //for (auto kv: triggerCombinationLoose) ATH_MSG_DEBUG("TRIG (LOOSE): " << kv.first << " -> " << kv.second);
+    TrigGlobEffCorr::ImportData triggerData;
+    top::check(triggerData.importTriggers(), "failed to import trigger data");
+    auto const& triggerDict = triggerData.getDictionary();
+    std::unordered_map<std::string, TrigGlobEffCorr::ImportData::TrigDef> triggerDefs;
+    for (auto&& kv : triggerData.getTriggerDefs()) {
+      auto it = triggerDict.find(kv.first);
+      if (it != triggerDict.end()) {
+        triggerDefs[it->second] = kv.second;
+      }
+    }
+    auto getTriggerLegs =
+      [&](std::unordered_map<std::string, std::vector<std::string> > const& triggerCombination,
+          std::unordered_map<std::string, std::set<std::string> >& electronLegsByPeriod) {
+        for (auto&& kv : triggerCombination) {
+          std::string const& period = kv.first;
+          for (auto const& trigKey : kv.second) {
+            auto triggerDefsIt = triggerDefs.find(trigKey);
+            if (triggerDefsIt == triggerDefs.end()) {
+              statusCode = StatusCode::FAILURE;
+              ATH_MSG_ERROR("unrecognized trigger `" << trigKey << "'");
+              continue;
+            }
+            auto const& trigDef = triggerDefsIt->second;
+            for (auto const& leg : trigDef.leg) {
+              if (!leg) continue;
+              std::string const& legname = triggerDict.at(leg);
+              bool ok = true;
+              xAOD::Type::ObjectType legtype = triggerData.associatedLeptonFlavour(legname, ok);
+              if (!ok) {
+                statusCode = StatusCode::FAILURE;
+                ATH_MSG_ERROR("could not determine object type for trigger leg `" << legname <<
+                  "'");
+                continue;
+              }
+              switch (legtype) {
+              case xAOD::Type::Electron:
+                electronLegsByPeriod[period].insert(legname);
+                break;
+
+              case xAOD::Type::Muon:
+                break;
+
+              default:
+                statusCode = StatusCode::FAILURE;
+                ATH_MSG_ERROR(
+                  "trigger leg `" << legname << "' has unsupported object type `" << legtype << "'");
+                continue;
+              }
+            }
+          }
+        }
+      };
+
+    // Get trigger strings from configuration
+    std::map<std::string, std::string> triggerCombination, triggerCombinationLoose;
+    std::vector<std::string> electronSystematics, muonSystematics, electronToolNames, muonToolNames;
+    std::unordered_map<std::string, std::vector<std::string> > const emptymap;
+    std::unordered_map<std::string, std::vector<std::string> > const&
+    triggersByPeriod = (m_config->doTightEvents() ? m_config->getGlobalTriggers() : emptymap),
+      triggersByPeriodLoose = (m_config->doLooseEvents() ? m_config->getGlobalTriggersLoose() : emptymap);
+
+    std::unordered_map<std::string, std::set<std::string> > electronLegsByPeriod, electronLegsByPeriodLoose;
+    getTriggerLegs(triggersByPeriod, electronLegsByPeriod);
+    getTriggerLegs(triggersByPeriodLoose, electronLegsByPeriodLoose);
+
+    // Get quality
+    std::string electronID, electronIDLoose, electronIsolation, electronIsolationLoose, muonQuality, muonQualityLoose;
+    if (m_config->doTightEvents()) {
+      electronID = m_config->electronID();
+      electronIsolation = m_config->electronIsolationSF();
+      muonQuality = m_config->muonQuality();
+    }
+    if (m_config->doLooseEvents()) {
+      electronIDLoose = m_config->electronIDLoose();
+      electronIsolationLoose = m_config->electronIsolationSFLoose();
+      muonQualityLoose = m_config->muonQualityLoose();
+    }
+
+    // Tidy name for e/gamma
+    electronID = mapWorkingPoints(electronID);
+    electronIDLoose = mapWorkingPoints(electronIDLoose);
+    // This is hopefully only temporary
+    electronIsolation = mapWorkingPoints(electronIsolation);
+    electronIsolationLoose = mapWorkingPoints(electronIsolationLoose);
+
+    // Create electron trigger SF and Eff tools
+    ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools, electronSFTools, electronEffToolsLoose,
+                                                          electronSFToolsLoose;
+    std::map<std::string, std::string> legsPerTool, legsPerToolLoose;
+    int nTools = 0;
+
+    // Loop over the triggers found (electrons - tight)
+    for (auto& y_t : electronLegsByPeriod) {
+      std::string year = y_t.first;
+      for (auto& trigKey : y_t.second) {
+        nTools++;
+        for (int j = 0; j < 2; ++j) { // one tool instance for efficiencies, another for scale factors
+          ATH_MSG_INFO("TIGHT " << year << " " << trigKey << " " << electronID << " " << electronIsolation);
+          auto t = m_electronToolsFactory.emplace(
+            m_electronToolsFactory.end(), "AsgElectronEfficiencyCorrectionTool/ElTrigEff_" + std::to_string(
+              j) + "_" + std::to_string(nTools));
+          top::check(t->setProperty("MapFilePath",
+                                    "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/map3.txt"),
+                     "Fail");
+          top::check(t->setProperty("TriggerKey",
+                                    (j ? year + "_" + trigKey : "Eff_" + year + "_" + trigKey)),
+                     "Failed to set TriggerKey");
+          if (electronID != "None") top::check(t->setProperty("IdKey", electronID), "Failed to set IdKey");
+          if (electronIsolation != "None") top::check(t->setProperty("IsoKey",
+                                                                     electronIsolation), "Failed to set IsoKey");
+          top::check(t->setProperty("CorrelationModel", "TOTAL"), "Failed to set CorrelationModel");
+          top::check(t->setProperty("ForceDataType",
+                                    (int) PATCore::ParticleDataType::Full), "Failed to set ForceDataType");
+          top::check(t->setProperty("OutputLevel", MSG::INFO), "Failed to set OutputLevel");
+          top::check(t->initialize(), "Failed to initalise");
+          // Using syntax from examples
+          auto& handles = j ? electronSFTools : electronEffTools;
+          handles.push_back(t->getHandle());
+          std::string name = handles[handles.size() - 1].name();
+          legsPerTool[name] = trigKey + " [" + year + "]";
+          ATH_MSG_INFO("TIGHT " << name << " -> " << trigKey);
+          electronToolNames.push_back(name);
+          // Special - Record the systematic names from the efficiency tool (not SF tool)
+          if (electronSystematics.size() == 0 && j == 1) {
+            for (auto& s :
+                 handles[handles.size() - 1]->recommendedSystematics().getBaseNames()) electronSystematics.push_back(s);
+
+          }
+        }
+      }
+    }
+
+    // Loop over the triggers found (electrons - loose)
+    nTools = 0;
+    for (auto& y_t : electronLegsByPeriodLoose) {
+      std::string year = y_t.first;
+      for (auto& trigKey : y_t.second) {
+        nTools++;
+        for (int j = 0; j < 2; ++j) { // one tool instance for efficiencies, another for scale factors
+          ATH_MSG_INFO("LOOSE " << year << " " << trigKey << " " << electronIDLoose << " " << electronIsolationLoose);
+          auto tLoose = m_electronToolsFactoryLoose.emplace(
+            m_electronToolsFactoryLoose.end(), "AsgElectronEfficiencyCorrectionTool/ElTrigEffLoose_" + std::to_string(
+              j) + "_" + std::to_string(nTools));
+          top::check(tLoose->setProperty("MapFilePath",
+                                         "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/map3.txt"),
+                     "Fail");
+          top::check(tLoose->setProperty("TriggerKey",
+                                         (j ? year + "_" + trigKey : "Eff_" + year + "_" + trigKey)),
+                     "Failed to set TriggerKey");
+          if (electronIDLoose !=
+              "None") top::check(tLoose->setProperty("IdKey", electronIDLoose), "Failed to set IdKey");
+          if (electronIsolationLoose != "None") top::check(tLoose->setProperty("IsoKey",
+                                                                               electronIsolationLoose),
+                                                           "Failed to set IsoKey");
+          top::check(tLoose->setProperty("CorrelationModel", "TOTAL"), "Failed to set CorrelationModel");
+          top::check(tLoose->setProperty("ForceDataType",
+                                         (int) PATCore::ParticleDataType::Full), "Failed to set ForceDataType");
+          top::check(tLoose->setProperty("OutputLevel", MSG::INFO), "Failed to set OutputLevel");
+          top::check(tLoose->initialize(), "Failed to initalise");
+          // Using syntax from examples
+          auto& handlesLoose = j ? electronSFToolsLoose : electronEffToolsLoose;
+          handlesLoose.push_back(tLoose->getHandle());
+          std::string name = handlesLoose[handlesLoose.size() - 1].name();
+          legsPerToolLoose[name] = trigKey + " [" + year + "]";
+          ATH_MSG_INFO("LOOSE " << name << " -> " << trigKey);
+          electronToolNames.push_back(name);
+          // Special - Record the systematic names from the efficiency tool (not SF tool)
+          if (electronSystematics.size() == 0 && j == 1) {
+            for (auto& s :
+                 handlesLoose[handlesLoose.size() -
+                              1]->recommendedSystematics().getBaseNames()) electronSystematics.push_back(s);
+          }
+        }
+      }
+    }
+
+    // Create muon trigger SF tool
+    ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
+    ToolHandleArray<CP::IMuonTriggerScaleFactors> muonToolsLoose;
+
+    if (m_config->doTightEvents()) {
+      if (muonQuality != "None") top::check(m_muonTool.setProperty("MuonQuality",
+                                                                   muonQuality), "Failed to set MuonQuality");
+      top::check(m_muonTool.setProperty("AllowZeroSF", true), "Failed to set AllowZeroSF");
+      top::check(m_muonTool.initialize(), "Failed to initialise");
+      muonTools.push_back(m_muonTool.getHandle());
+      ATH_MSG_INFO("Muon tool name (tight) " << muonTools[muonTools.size() - 1].name());
+      muonToolNames.push_back(muonTools[muonTools.size() - 1].name());
+      // Special - Get muon systematics
+      if (muonSystematics.size() == 0) {
+        for (auto& s:
+        muonTools[muonTools.size() - 1]->recommendedSystematics().getBaseNames()) muonSystematics.push_back(s);
+      }
+    }
+
+    if (m_config->doLooseEvents()) {
+      if (muonQualityLoose != "None") top::check(m_muonToolLoose.setProperty("MuonQuality",
+                                                                             muonQualityLoose),
+        "Failed to set MuonQuality");
+      top::check(m_muonToolLoose.setProperty("AllowZeroSF", true), "Failed to set AllowZeroSF");
+      top::check(m_muonToolLoose.initialize(), "Failed to initialise");
+      muonToolsLoose.push_back(m_muonToolLoose.getHandle());
+      ATH_MSG_INFO("Muon tool name (loose) " << muonToolsLoose[muonToolsLoose.size() - 1].name());
+      muonToolNames.push_back(muonToolsLoose[muonToolsLoose.size() - 1].name());
+      // Special - Get muon systematics
+      if (muonSystematics.size() == 0) {
+        for (auto& s: muonToolsLoose[muonToolsLoose.size() - 1]->recommendedSystematics().getBaseNames()) muonSystematics.push_back(s);
+      }
+    }
+
+    for (auto& key : triggersByPeriod) {
+      if (triggerCombination.find(key.first) == triggerCombination.end()) {
+        triggerCombination[key.first] = "";
+      } else {
+        triggerCombination[key.first] += " || ";
+      }
+      triggerCombination[key.first] += boost::algorithm::join(key.second, " || ");
+    }
+    for (auto& key : triggersByPeriodLoose) {
+      if (triggerCombinationLoose.find(key.first) == triggerCombinationLoose.end()) {
+        triggerCombinationLoose[key.first] = "";
+      } else {
+        triggerCombinationLoose[key.first] += " || ";
+      }
+      triggerCombinationLoose[key.first] += boost::algorithm::join(key.second, " || ");
+    }
+
+    // Print out what we configured
+    for (auto kv: triggerCombination) ATH_MSG_DEBUG("TRIG (TIGHT): " << kv.first << " -> " << kv.second);
+    for (auto kv: triggerCombinationLoose) ATH_MSG_DEBUG("TRIG (LOOSE): " << kv.first << " -> " << kv.second);
 
     // Make the global trigger tool
-//    if (m_config->doTightEvents()) {
-//      TrigGlobalEfficiencyCorrectionTool* globalTriggerEffTool = new TrigGlobalEfficiencyCorrectionTool("TrigGlobalEfficiencyCorrectionTool::TrigGlobal");
-//      top::check(globalTriggerEffTool->setProperty("ElectronEfficiencyTools", electronEffTools), "Failed to attach electron efficiency tools");
-//      top::check(globalTriggerEffTool->setProperty("ElectronScaleFactorTools", electronSFTools), "Failed to attach electron scale factor tools");
-//      top::check(globalTriggerEffTool->setProperty("MuonTools", muonTools), "Failed to attach muon tools");
-//      top::check(globalTriggerEffTool->setProperty("ListOfLegsPerTool", legsPerTool), "Failed to define list of legs per tool");
-//      top::check(globalTriggerEffTool->setProperty("TriggerCombination", triggerCombination), "Failed to define trigger combination");
-//      top::check(globalTriggerEffTool->setProperty("TriggerMatchingTool", m_trigMatchTool), "Failed to set TriggerMatchingTool");
-//      // Setting MSG::ERROR to avoid flooding output with invalid efficiency warnings before event selection is complete
-//      top::check(globalTriggerEffTool->setProperty("OutputLevel", MSG::ERROR), "Failed to set message level");
-//      top::check(globalTriggerEffTool->initialize(), "Failed to initalise");
-//      m_globalTriggerEffTool = globalTriggerEffTool;
-//    }
-//    if (m_config->doLooseEvents()) {
-//      TrigGlobalEfficiencyCorrectionTool* globalTriggerEffToolLoose = new TrigGlobalEfficiencyCorrectionTool("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose");
-//      top::check(globalTriggerEffToolLoose->setProperty("ElectronEfficiencyTools", electronEffToolsLoose), "Failed to attach electron efficiency tools");
-//      top::check(globalTriggerEffToolLoose->setProperty("ElectronScaleFactorTools", electronSFToolsLoose), "Failed to attach electron scale factor tools");
-//      top::check(globalTriggerEffToolLoose->setProperty("MuonTools", muonToolsLoose), "Failed to attach muon tools");
-//      top::check(globalTriggerEffToolLoose->setProperty("ListOfLegsPerTool", legsPerToolLoose), "Failed to define list of legs per tool");
-//      top::check(globalTriggerEffToolLoose->setProperty("TriggerCombination", triggerCombinationLoose), "Failed to define trigger combination");
-//      top::check(globalTriggerEffToolLoose->setProperty("TriggerMatchingTool", m_trigMatchTool), "Failed to set TriggerMatchingTool");
-//      // Setting MSG::ERROR to avoid flooding output with invalid efficiency warnings before event selection is complete
-//      top::check(globalTriggerEffToolLoose->setProperty("OutputLevel", MSG::ERROR), "Failed to set message level");
-//      top::check(globalTriggerEffToolLoose->initialize(), "Failed to initalise");
-//      m_globalTriggerEffToolLoose = globalTriggerEffToolLoose;
-//    }
+    if (m_config->doTightEvents()) {
+      TrigGlobalEfficiencyCorrectionTool* globalTriggerEffTool = new TrigGlobalEfficiencyCorrectionTool("TrigGlobalEfficiencyCorrectionTool::TrigGlobal");
+      top::check(globalTriggerEffTool->setProperty("ElectronEfficiencyTools", electronEffTools), "Failed to attach electron efficiency tools");
+      top::check(globalTriggerEffTool->setProperty("ElectronScaleFactorTools", electronSFTools), "Failed to attach electron scale factor tools");
+      top::check(globalTriggerEffTool->setProperty("MuonTools", muonTools), "Failed to attach muon tools");
+      top::check(globalTriggerEffTool->setProperty("ListOfLegsPerTool", legsPerTool), "Failed to define list of legs per tool");
+      top::check(globalTriggerEffTool->setProperty("TriggerCombination", triggerCombination), "Failed to define trigger combination");
+      top::check(globalTriggerEffTool->setProperty("TriggerMatchingTool", m_trigMatchTool), "Failed to set TriggerMatchingTool");
+      // Setting MSG::ERROR to avoid flooding output with invalid efficiency warnings before event selection is complete
+      top::check(globalTriggerEffTool->setProperty("OutputLevel", MSG::ERROR), "Failed to set message level");
+      top::check(globalTriggerEffTool->initialize(), "Failed to initalise");
+      m_globalTriggerEffTool = globalTriggerEffTool;
+    }
+    if (m_config->doLooseEvents()) {
+      TrigGlobalEfficiencyCorrectionTool* globalTriggerEffToolLoose = new TrigGlobalEfficiencyCorrectionTool("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose");
+      top::check(globalTriggerEffToolLoose->setProperty("ElectronEfficiencyTools", electronEffToolsLoose), "Failed to attach electron efficiency tools");
+      top::check(globalTriggerEffToolLoose->setProperty("ElectronScaleFactorTools", electronSFToolsLoose), "Failed to attach electron scale factor tools");
+      top::check(globalTriggerEffToolLoose->setProperty("MuonTools", muonToolsLoose), "Failed to attach muon tools");
+      top::check(globalTriggerEffToolLoose->setProperty("ListOfLegsPerTool", legsPerToolLoose), "Failed to define list of legs per tool");
+      top::check(globalTriggerEffToolLoose->setProperty("TriggerCombination", triggerCombinationLoose), "Failed to define trigger combination");
+      top::check(globalTriggerEffToolLoose->setProperty("TriggerMatchingTool", m_trigMatchTool), "Failed to set TriggerMatchingTool");
+      // Setting MSG::ERROR to avoid flooding output with invalid efficiency warnings before event selection is complete
+      top::check(globalTriggerEffToolLoose->setProperty("OutputLevel", MSG::ERROR), "Failed to set message level");
+      top::check(globalTriggerEffToolLoose->initialize(), "Failed to initalise");
+      m_globalTriggerEffToolLoose = globalTriggerEffToolLoose;
+    }
 
     // Set information about systematics inside TopConfig
-//    m_config->setGlobalTriggerConfiguration(electronSystematics, muonSystematics, electronToolNames, muonToolNames);
+    m_config->setGlobalTriggerConfiguration(electronSystematics, muonSystematics, electronToolNames, muonToolNames);
 
     return statusCode;
   }
-- 
GitLab