From 800c79da39df81b7a23d2757f1418579228768f0 Mon Sep 17 00:00:00 2001
From: Aleksandra Poreba <aleksandra.poreba@cern.ch>
Date: Wed, 24 Feb 2021 12:27:43 +0100
Subject: [PATCH 1/4] Pass seeded chains and active chains to algorithm idx map

---
 .../TrigCostAnalysis/src/CostData.cxx         | 16 ++++--
 .../TrigCost/TrigCostAnalysis/src/CostData.h  | 17 +++++--
 .../TrigCostAnalysis/src/TrigCostAnalysis.cxx | 15 +++++-
 .../Root/AlgToChainTool.cxx                   | 51 +++++++++++++------
 .../TrigCompositeUtils/AlgToChainTool.h       |  6 +--
 5 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx
index 5674e10a9014..4d650d7d6e9f 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx
@@ -131,11 +131,19 @@ void CostData::setTypeMap( const std::unordered_map<uint32_t, std::string>& type
   m_typeMapPtr = &typeMap;
 }
 
-void CostData::setAlgToChainsMap( const std::map<std::string, std::vector<TrigConf::Chain>>& algToChains ) {
-  m_algToChains = &algToChains;
+void CostData::setChainToAlgMap( const std::map<std::string, std::set<size_t>>& chainToAlgIdx ) {
+  m_chainToAlgIdx = &chainToAlgIdx;
 }
 
 
-const std::map<std::string, std::vector<TrigConf::Chain>>& CostData::algToChainsMap() const {
-  return *m_algToChains;
+const std::map<std::string, std::set<size_t>>& CostData::chainToAlgMap() const {
+  return *m_chainToAlgIdx;
+}
+
+const std::set<TrigCompositeUtils::DecisionID>& CostData::seededChains() const {
+  return *m_seededChains;
+}
+
+void CostData::setSeededChains(const std::set<TrigCompositeUtils::DecisionID>& seededChains) {
+  m_seededChains = &seededChains;
 }
\ No newline at end of file
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h
index ae498afffeb9..d22e34c502c2 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h
@@ -70,12 +70,22 @@ class CostData {
     /**
      * @brief Getter of the alg name to chains map.
      */
-    const std::map<std::string, std::vector<TrigConf::Chain>>& algToChainsMap() const;
+    const std::map<std::string, std::set<size_t>>& chainToAlgMap() const;
 
     /**
      * @brief Set the alg name to chains map.
      */
-    void setAlgToChainsMap( const std::map<std::string, std::vector<TrigConf::Chain>>& algToChains );
+    void setChainToAlgMap( const std::map<std::string, std::set<size_t>>& algToChains );
+
+    /**
+     * @brief Getter of the seeded chains set.
+     */
+    const std::set<TrigCompositeUtils::DecisionID>& seededChains() const;
+
+    /**
+     * @brief Set the seeded chains set.
+     */
+    void setSeededChains(const std::set<TrigCompositeUtils::DecisionID>& seededChains);
 
     /**
      * @brief Getter of map between algorithm (index in costCollection) and ROS requests (indicies in rosCollection)
@@ -161,7 +171,8 @@ class CostData {
     const std::unordered_map<uint32_t, std::string>* m_typeMapPtr; //!< Cached non-owning pointer mapping algorithm instance names to types
     std::map<size_t, std::vector<size_t>> m_algToRos; //!< Mapping of indexes from m_costCollection to corresponding ROS requests made by algorithm
     const std::map<std::string, std::vector<uint32_t>>* m_rosToRob; //!< Mapping of ROS corresponding to ROB requests
-    const std::map<std::string, std::vector<TrigConf::Chain>>* m_algToChains; //!<Mapping of algorithm name to chains
+    const std::map<std::string, std::set<size_t>>* m_chainToAlgIdx; //!<Mapping of algorithm name to chains
+    const std::set<TrigCompositeUtils::DecisionID>* m_seededChains; //!<Set of seeded chains to monitor
 
 };
 
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
index 90498f30f9ef..f3d0af87c3d0 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
@@ -150,11 +150,24 @@ StatusCode TrigCostAnalysis::execute() {
   SG::ReadHandle<xAOD::TrigCompositeContainer> rosDataHandle(m_rosDataKey, context);
   ATH_CHECK( rosDataHandle.isValid() );
 
+  // Save indexes of algorithm in costDataHandle
+  std::map<std::string, std::set<size_t>> chainToAlgIdx;
+  auto algToChain = m_algToChainTool->getChainsForAllAlgs(context);
+  for (const xAOD::TrigComposite* tc : *costDataHandle) {
+    const uint32_t nameHash = tc->getDetail<TrigConf::HLTHash>("alg");
+    const std::string name = TrigConf::HLTUtils::hash2string(nameHash, "ALG");
+
+    for (const TrigConf::Chain& chain : algToChain[name]){
+      chainToAlgIdx[chain.name()].insert(tc->index());
+    }
+  }
+
   const uint32_t onlineSlot = getOnlineSlot( costDataHandle.get() );
   CostData costData;
   ATH_CHECK( costData.set(costDataHandle.get(), rosDataHandle.get(), onlineSlot) );
   costData.setRosToRobMap(m_rosToRob);
-  costData.setAlgToChainsMap(m_algToChainTool->getChainsForAllAlgs());
+  costData.setChainToAlgMap(chainToAlgIdx);
+  costData.setSeededChains(m_algToChainTool->retrieveActiveChains(context, "L1"));
   costData.setLb( context.eventID().lumi_block() );
   costData.setTypeMap( m_algTypeMap );
   if (!m_enhancedBiasTool.name().empty() && !m_enhancedBiasTool->isMC()) {
diff --git a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
index 134d6fe98f7c..cfbb6f032114 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
+++ b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
@@ -80,7 +80,14 @@ std::vector<TrigConf::Chain> TrigCompositeUtils::AlgToChainTool::getChainsForAlg
 std::set<std::string> TrigCompositeUtils::AlgToChainTool::getActiveChainsForAlg(const std::string& algorithmName, const EventContext& context) const {
     std::set<std::string> result;
 
-    std::set<std::string> allActiveChains = retrieveActiveChains(context);
+    std::set<TrigCompositeUtils::DecisionID> allActiveChainsID = retrieveActiveChains(context);
+
+    // Convert DecisionID to names
+    std::set<std::string> allActiveChains;
+    for ( const TrigCompositeUtils::DecisionID& id : allActiveChainsID ) {
+        allActiveChains.insert( HLT::Identifier(id).name() );
+    }
+
     std::set<std::string> allAlgChains = getChainsNamesForAlg(algorithmName);
 
     // Save the chains that are used by selected algorithm and active
@@ -91,7 +98,7 @@ std::set<std::string> TrigCompositeUtils::AlgToChainTool::getActiveChainsForAlg(
     return result;
 }
 
-std::set<std::string> TrigCompositeUtils::AlgToChainTool::retrieveActiveChains(const EventContext& context) const {
+std::set<TrigCompositeUtils::DecisionID> TrigCompositeUtils::AlgToChainTool::retrieveActiveChains(const EventContext& context, const std::string& collectionName) const {
     std::set<TrigCompositeUtils::DecisionID> activeChainsID;
 
     // Retrieve EventStore and keys
@@ -101,11 +108,14 @@ std::set<std::string> TrigCompositeUtils::AlgToChainTool::retrieveActiveChains(c
     std::vector<std::string> keys;
     eventStore->keys(static_cast<CLID>( ClassID_traits<TrigCompositeUtils::DecisionContainer>::ID() ), keys);
 
-    // Retrieve active chains
-    std::set<std::string> activeChains;
-
+    // Retrieve active chains name hashes
     for ( const std::string& key : keys ) {
-        if( key.find("HLTNav") != 0 || key == "HLTNav_Summary" ) {
+        // Look for given collection
+        if ( !collectionName.empty() && key.find("HLTNav_" + collectionName) != 0 ){
+            continue;
+        }
+
+        if( collectionName.empty() && (key.find("HLTNav") != 0 || key == "HLTNav_Summary") ) {
             continue;
         }
 
@@ -127,21 +137,30 @@ std::set<std::string> TrigCompositeUtils::AlgToChainTool::retrieveActiveChains(c
         } 
     }
 
-    // Convert DecisionID to names
-    std::set<std::string> activeChainsNames;
-
-    for ( const TrigCompositeUtils::DecisionID& id : activeChainsID ) {
-        activeChainsNames.insert( HLT::Identifier(id).name() );
-    }
-
-    return activeChainsNames;
+    return activeChainsID;
 }
 
-std::map<std::string, std::vector<TrigConf::Chain>> TrigCompositeUtils::AlgToChainTool::getChainsForAllAlgs() const{
+std::map<std::string, std::vector<TrigConf::Chain>> TrigCompositeUtils::AlgToChainTool::getChainsForAllAlgs(const EventContext& context) const{
     std::map<std::string, std::vector<TrigConf::Chain>> algToChain;
 
     for (const auto& algSeqPair : m_algToSequencersMap){
-        algToChain[algSeqPair.first] = getChainsForAlg(algSeqPair.first);
+        std::set<TrigCompositeUtils::DecisionID> activeChains;
+        for (const std::string& seq : algSeqPair.second){
+            // Look for chains which were active for any of the algorithms of the sequence
+            // Name of collection for given sequencer consist sequence's filter's name
+            std::set<TrigCompositeUtils::DecisionID> chainsPerSeq = retrieveActiveChains(context, "F" + seq);
+            activeChains.insert(chainsPerSeq.begin(), chainsPerSeq.end());
+        }
+        std::vector<TrigConf::Chain> chainsPerAlg = getChainsForAlg(algSeqPair.first);
+
+        // Remove not active chains
+        chainsPerAlg.erase(
+            std::remove_if(chainsPerAlg.begin(), chainsPerAlg.end(),
+                [&](const TrigConf::Chain& c) { return activeChains.find(c.namehash()) == activeChains.end(); }),
+            chainsPerAlg.end()
+        );
+
+        algToChain[algSeqPair.first] = chainsPerAlg;
     }
     return algToChain;
 }
diff --git a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
index a81a1afe5767..6d63f1ce7b40 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
+++ b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
@@ -42,11 +42,11 @@ namespace TrigCompositeUtils {
       std::set<std::string> getActiveChainsForAlg(const std::string& algorithmName, const EventContext& context) const;
 
       /// Request set of chains for all algorithms in the menu
-      std::map<std::string, std::vector<TrigConf::Chain>> getChainsForAllAlgs() const;
+      std::map<std::string, std::vector<TrigConf::Chain>> getChainsForAllAlgs(const EventContext& context) const;
 
+      /// Request set of chains from given navigation collection
+      std::set<TrigCompositeUtils::DecisionID> retrieveActiveChains(const EventContext& context, const std::string& collectionName = "") const;
   private:
-      std::set<std::string> retrieveActiveChains(const EventContext& context) const;
-
       SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey{ this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu" };
 
       std::map<std::string, std::vector<TrigConf::Chain>> m_sequencerToChainMap;
-- 
GitLab


From 47a45e143bdf8f8db033c990763f942457d33398 Mon Sep 17 00:00:00 2001
From: Aleksandra Poreba <aleksandra.poreba@cern.ch>
Date: Mon, 1 Mar 2021 18:15:00 +0100
Subject: [PATCH 2/4] Add chain monitor and counter

---
 .../TrigCostAnalysis/src/TrigCostAnalysis.cxx | 18 +++++-
 .../TrigCostAnalysis/src/TrigCostAnalysis.h   |  3 +
 .../src/counters/CounterChain.cxx             | 20 +++++++
 .../src/counters/CounterChain.h               | 52 ++++++++++++++++
 .../src/monitors/MonitorChain.cxx             | 28 +++++++++
 .../src/monitors/MonitorChain.h               | 59 +++++++++++++++++++
 .../Root/AlgToChainTool.cxx                   | 11 ++++
 .../TrigCompositeUtils/AlgToChainTool.h       |  3 +
 8 files changed, 192 insertions(+), 2 deletions(-)
 create mode 100644 Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx
 create mode 100644 Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h
 create mode 100644 Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx
 create mode 100644 Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h

diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
index f3d0af87c3d0..65d90d32c3ad 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
@@ -15,6 +15,7 @@
 #include "monitors/MonitorGlobal.h"
 #include "monitors/MonitorThreadOccupancy.h"
 #include "monitors/MonitorROS.h"
+#include "monitors/MonitorChain.h"
 
 
 TrigCostAnalysis::TrigCostAnalysis( const std::string& name, ISvcLocator* pSvcLocator ) :
@@ -85,6 +86,13 @@ StatusCode TrigCostAnalysis::start() {
     }
   }
 
+  // Call TrigConf::HLTUtils::string2hash(chain.name()) for all the chains to cache the hash to name mapping
+  std::vector<std::string> chainNames;
+  ATH_CHECK( m_algToChainTool->getAllChainNames(chainNames));
+  for (const std::string& chainName : chainNames){
+    TrigConf::HLTUtils::string2hash(chainName);
+  }
+
   // As an initial guess, 25 should be a good uper maximum for the number of expected View instances.
   ATH_CHECK( checkUpdateMaxView(60) );
   return StatusCode::SUCCESS;
@@ -152,7 +160,7 @@ StatusCode TrigCostAnalysis::execute() {
 
   // Save indexes of algorithm in costDataHandle
   std::map<std::string, std::set<size_t>> chainToAlgIdx;
-  auto algToChain = m_algToChainTool->getChainsForAllAlgs(context);
+  std::map<std::string, std::vector<TrigConf::Chain>> algToChain = m_algToChainTool->getChainsForAllAlgs(context);
   for (const xAOD::TrigComposite* tc : *costDataHandle) {
     const uint32_t nameHash = tc->getDetail<TrigConf::HLTHash>("alg");
     const std::string name = TrigConf::HLTUtils::hash2string(nameHash, "ALG");
@@ -162,12 +170,14 @@ StatusCode TrigCostAnalysis::execute() {
     }
   }
 
+  const std::set<TrigCompositeUtils::DecisionID> seededChains = m_algToChainTool->retrieveActiveChains(context, "L1");
+
   const uint32_t onlineSlot = getOnlineSlot( costDataHandle.get() );
   CostData costData;
   ATH_CHECK( costData.set(costDataHandle.get(), rosDataHandle.get(), onlineSlot) );
   costData.setRosToRobMap(m_rosToRob);
   costData.setChainToAlgMap(chainToAlgIdx);
-  costData.setSeededChains(m_algToChainTool->retrieveActiveChains(context, "L1"));
+  costData.setSeededChains(seededChains);
   costData.setLb( context.eventID().lumi_block() );
   costData.setTypeMap( m_algTypeMap );
   if (!m_enhancedBiasTool.name().empty() && !m_enhancedBiasTool->isMC()) {
@@ -224,6 +234,10 @@ StatusCode TrigCostAnalysis::registerMonitors(MonitoredRange* range) {
     ATH_CHECK( range->addMonitor(std::make_unique<MonitorROS>("ROS_HLT", range)) );
     ATH_MSG_DEBUG("Registering ROS_HLT Monitor for range " << range->getName() << ". Size:" << range->getMonitors().size());
   }
+  if (m_doMonitorChain) {
+    ATH_CHECK( range->addMonitor(std::make_unique<MonitorChain>("Chain_HLT", range)) );
+    ATH_MSG_INFO("Registering Chain_HLT Monitor for range " << range->getName() << ". Size:" << range->getMonitors().size());
+  }
   // if (m_do...) {}
   return StatusCode::SUCCESS;
 }
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h
index 13dfda05de51..d54164cfbd05 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h
@@ -102,6 +102,9 @@ class TrigCostAnalysis: public ::AthHistogramAlgorithm {
     Gaudi::Property<bool> m_doMonitorROS { this, "DoMonitorROS", true,
       "Monitor Read-Out System" };
 
+    Gaudi::Property<bool> m_doMonitorChain { this, "DoMonitorChain", true,
+      "Monitor individual chains by instance name" };
+
     Gaudi::Property<bool> m_useEBWeights { this, "UseEBWeights", true,
       "Apply Enhanced Bias weights" };
 
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx
new file mode 100644
index 000000000000..ab68818ea393
--- /dev/null
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx
@@ -0,0 +1,20 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "xAODTrigger/TrigCompositeContainer.h"
+#include "TrigDataAccessMonitoring/ROBDataMonitor.h"
+
+#include "CounterChain.h"
+
+CounterChain::CounterChain(const std::string& name, const MonitorBase* parent) 
+  : CounterBase(name, parent)
+{
+
+}
+
+
+StatusCode CounterChain::newEvent(const CostData& /*data*/, size_t /*index*/, const float /*weight*/) {
+
+  return StatusCode::SUCCESS;
+}
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h
new file mode 100644
index 000000000000..23df2764602d
--- /dev/null
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGCOSTANALYSIS_COUNTERCHAIN_H
+#define TRIGCOSTANALYSIS_COUNTERCHAIN_H 1
+
+#include "../CounterBase.h"
+
+/**
+ * @class CounterAlgorithm
+ * @brief Concrete implimentation of Counter to monitor all properties of a given Algorithm instance.
+ */
+class CounterChain : public CounterBase {
+  public:
+    /**
+     * @brief Forbid default constructor.
+     */
+    CounterChain() = delete;
+
+    /**
+     * @brief Construct counter.
+     * @param[in] name Counter's name
+     * @param[in] parent Counter's parent monitor, cached non-owning pointer.
+     */
+    CounterChain(const std::string& name, const MonitorBase* parent);
+
+    /**
+     * @brief Default destructor.
+     */
+    virtual ~CounterChain() = default;
+
+    /**
+     * @brief Forbid assignment.
+     */
+    CounterChain& operator=(const CounterChain&) = delete;
+    
+    /**
+     * @brief Forbid copy.
+     */
+    CounterChain(const CounterChain&) = delete;
+
+    /**
+     * @brief Concrete implimentation. Monitores chain's algorithm at specified index. Expected to match this instances name().
+     * @param[in] data Access to event data
+     * @param[in] index Index within appropriate event data container which is to be analysed by this Counter
+     * @param[in] weight Global event weight
+     */
+    virtual StatusCode newEvent(const CostData& data, size_t index, const float weight = 1.) override;
+};
+
+#endif // TRIGCOSTANALYSIS_COUNTERALGORITHM_H
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx
new file mode 100644
index 000000000000..53a90f4b57bd
--- /dev/null
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx
@@ -0,0 +1,28 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MonitorChain.h"
+#include "../counters/CounterChain.h"
+
+MonitorChain::MonitorChain(const std::string& name, const MonitoredRange* parent)
+  : MonitorBase(name, parent) {
+}
+
+StatusCode MonitorChain::newEvent(const CostData& data, const float weight) {
+
+  const std::set<TrigCompositeUtils::DecisionID> seededChains = data.seededChains();
+  int i = 0;
+  for (const TrigCompositeUtils::DecisionID& chain : seededChains){
+    const std::string chainName = TrigConf::HLTUtils::hash2string(chain);
+    ATH_CHECK( getCounter(chainName)->newEvent(data, i, weight) );
+    ++i;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+std::unique_ptr<CounterBase> MonitorChain::newCounter(const std::string& name) {
+  return std::make_unique<CounterChain>(name, this);
+} 
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h
new file mode 100644
index 000000000000..3fe9643a8718
--- /dev/null
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGCOSTANALYSIS_MONITORCHAIN_H
+#define TRIGCOSTANALYSIS_MONITORCHAIN_H 1
+
+
+#include "../MonitorBase.h"
+
+/**
+ * @class MonitorAlgorithm
+ * @brief Concrete implementation of Monitor to monitor all Chain instances in an event.
+ */
+class MonitorChain : public MonitorBase {
+  public:
+    /**
+     * @brief Forbid default constructor.
+     */
+    MonitorChain() = delete;
+
+    /**
+     * @brief Construct monitor.
+     * @param[in] name Monitor's name
+     * @param[in] parent Monitor's parent Range, cached non-owning pointer.
+     */
+    MonitorChain(const std::string& name, const MonitoredRange* parent);
+
+    /**
+     * @brief Default destructor.
+     */
+    virtual ~MonitorChain() = default;
+
+    /**
+     * @brief Forbid assignment.
+     */
+    MonitorChain& operator=(const MonitorChain&) = delete;
+
+    /**
+     * @brief Forbid copy.
+     */
+    MonitorChain(const MonitorChain&) = delete;
+
+    /**
+     * @brief Concrete dispatch method. Iterate over all Algorithms in event data and dispatch to owned Counters
+     * @param[in] data Access to event data
+     * @param[in] weight Global event weight
+     */
+    virtual StatusCode newEvent(const CostData& data, const float weight = 1.) override;
+
+    /**
+     * @brief Concrete counter instantiation. Mints named counter of CounterAlgorith type.
+     * @param[in] name Name of Counter to mint.
+     * @return Owning unique ptr object typed on the CounterBase base class which points to concrete Counter of specialised type.
+     */
+    virtual std::unique_ptr<CounterBase> newCounter(const std::string& name) override; 
+};
+
+#endif // TRIGCOSTANALYSIS_MONITORCHAIN_H
diff --git a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
index cfbb6f032114..686fb79eeba2 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
+++ b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
@@ -3,6 +3,7 @@
 */
 
 #include "TrigCompositeUtils/AlgToChainTool.h"
+#include "TrigConfHLTData/HLTUtils.h"
 
 #ifndef XAOD_STANDALONE
 
@@ -45,6 +46,16 @@ StatusCode TrigCompositeUtils::AlgToChainTool::start() {
     return StatusCode::SUCCESS;
 }
 
+StatusCode TrigCompositeUtils::AlgToChainTool::getAllChainNames(std::vector<std::string>& chainNames) const {
+    SG::ReadHandle<TrigConf::HLTMenu>  hltMenuHandle = SG::makeHandle( m_HLTMenuKey );
+    ATH_CHECK( hltMenuHandle.isValid() );
+
+    for ( const TrigConf::Chain& chain : *hltMenuHandle ) {
+        chainNames.push_back(chain.name());
+    }
+    return StatusCode::SUCCESS;
+}
+
 
 std::set<std::string> TrigCompositeUtils::AlgToChainTool::getChainsNamesForAlg(const std::string& algorithmName) const {
     std::set<std::string> result;
diff --git a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
index 6d63f1ce7b40..b5624bc2fcfc 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
+++ b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
@@ -46,6 +46,9 @@ namespace TrigCompositeUtils {
 
       /// Request set of chains from given navigation collection
       std::set<TrigCompositeUtils::DecisionID> retrieveActiveChains(const EventContext& context, const std::string& collectionName = "") const;
+
+      StatusCode getAllChainNames(std::vector<std::string>&) const;
+
   private:
       SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey{ this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu" };
 
-- 
GitLab


From 87da92e3e9d734513e20473daf854d317cf9b058 Mon Sep 17 00:00:00 2001
From: Aleksandra Poreba <aleksandra.poreba@cern.ch>
Date: Tue, 2 Mar 2021 09:05:35 +0100
Subject: [PATCH 3/4] Cache active chains per seq

---
 .../TrigCompositeUtils/Root/AlgToChainTool.cxx      | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
index 686fb79eeba2..56f47a8d6ed4 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
+++ b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
@@ -154,13 +154,18 @@ std::set<TrigCompositeUtils::DecisionID> TrigCompositeUtils::AlgToChainTool::ret
 std::map<std::string, std::vector<TrigConf::Chain>> TrigCompositeUtils::AlgToChainTool::getChainsForAllAlgs(const EventContext& context) const{
     std::map<std::string, std::vector<TrigConf::Chain>> algToChain;
 
+    // Look for chains which were active for any of the algorithms of the sequence
+    // Name of collection for given sequencer consist sequence's filter's name
+    std::map<std::string, std::set<TrigCompositeUtils::DecisionID>> seqToActiveChains;
+    for (const auto& sequence : m_sequencerToChainMap) {
+        seqToActiveChains[sequence.first] = retrieveActiveChains(context, "F" + sequence.first);
+    }
+
     for (const auto& algSeqPair : m_algToSequencersMap){
         std::set<TrigCompositeUtils::DecisionID> activeChains;
         for (const std::string& seq : algSeqPair.second){
-            // Look for chains which were active for any of the algorithms of the sequence
-            // Name of collection for given sequencer consist sequence's filter's name
-            std::set<TrigCompositeUtils::DecisionID> chainsPerSeq = retrieveActiveChains(context, "F" + seq);
-            activeChains.insert(chainsPerSeq.begin(), chainsPerSeq.end());
+            // Save all active chains per sequences that algorithm was executed
+            activeChains.insert(seqToActiveChains[seq].begin(), seqToActiveChains[seq].end());
         }
         std::vector<TrigConf::Chain> chainsPerAlg = getChainsForAlg(algSeqPair.first);
 
-- 
GitLab


From 600c0c50ee3c684d3adf244c110cd2ba3fbf5a37 Mon Sep 17 00:00:00 2001
From: Aleksandra Poreba <aleksandra.poreba@cern.ch>
Date: Tue, 2 Mar 2021 09:17:49 +0100
Subject: [PATCH 4/4] Update copyrights

---
 Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx             | 2 +-
 Trigger/TrigCost/TrigCostAnalysis/src/CostData.h               | 2 +-
 Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx     | 2 +-
 Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h       | 2 +-
 .../TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx    | 2 +-
 Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx   | 3 +--
 .../TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h     | 2 +-
 7 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx
index 4d650d7d6e9f..3b6fd10389ac 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "CostData.h"
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h
index d22e34c502c2..eb32bcb4f31c 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGCOSTANALYSIS_COSTDATA_H
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
index 65d90d32c3ad..05a505022633 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GaudiKernel/ThreadLocalContext.h"
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h
index d54164cfbd05..bdfa3790be5d 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGCOSTANALYSIS_TRIGCOSTALYSIS_H
diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx
index ab68818ea393..6a2e3e6f9e86 100644
--- a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx
+++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "xAODTrigger/TrigCompositeContainer.h"
diff --git a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
index 56f47a8d6ed4..5e090921a4d0 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
+++ b/Trigger/TrigSteer/TrigCompositeUtils/Root/AlgToChainTool.cxx
@@ -1,9 +1,8 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigCompositeUtils/AlgToChainTool.h"
-#include "TrigConfHLTData/HLTUtils.h"
 
 #ifndef XAOD_STANDALONE
 
diff --git a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
index b5624bc2fcfc..5543bf80264c 100644
--- a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
+++ b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/AlgToChainTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TrigCompositeUtils_AlgToChainTool_h
-- 
GitLab