From e9f1262cc9c021d5bf823e05f35b5554ea684480 Mon Sep 17 00:00:00 2001
From: Aleksandra Poreba <aleksandra.poreba@cern.ch>
Date: Thu, 5 Nov 2020 18:35:20 +0000
Subject: [PATCH] Add handling L1 prescales

Also add EBResult struct that will hold result of EB computation
---
 .../TrigCostMonitorMT/CMakeLists.txt          |   2 +-
 .../EnhancedBiasWeightCompAlg.h               |  97 +++++++++++
 .../src/EnhancedBiasWeightCompAlg.cxx         | 160 ++++++++++++++++++
 .../components/TrigCostMonitorMT_entries.cxx  |   4 +-
 .../TrigEDMConfig/python/TriggerEDMRun3.py    |   2 +
 .../python/TriggerConfigGetter.py             |  10 ++
 6 files changed, 273 insertions(+), 2 deletions(-)
 create mode 100644 Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/EnhancedBiasWeightCompAlg.h
 create mode 100644 Trigger/TrigMonitoring/TrigCostMonitorMT/src/EnhancedBiasWeightCompAlg.cxx

diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt b/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt
index 160ea0b3cb7..21d91f2167f 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt
@@ -18,7 +18,7 @@ atlas_add_component( TrigCostMonitorMT
                      src/*.cxx
                      src/components/*.cxx 
                      INCLUDE_DIRS ${TBB_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${TBB_LIBRARIES} AthContainers AthViews AthenaKernel TrigConfHLTData TrigCostMonitorMTLib TrigSteeringEvent TrigTimeAlgsLib )
+                     LINK_LIBRARIES ${TBB_LIBRARIES} AthContainers AthViews AthenaKernel TrigConfHLTData TrigCompositeUtilsLib TrigCostMonitorMTLib TrigSteeringEvent TrigTimeAlgsLib )
 
 
 atlas_add_test( AlgorithmIdentifier_test
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/EnhancedBiasWeightCompAlg.h b/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/EnhancedBiasWeightCompAlg.h
new file mode 100644
index 00000000000..2b5dc055042
--- /dev/null
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/EnhancedBiasWeightCompAlg.h
@@ -0,0 +1,97 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIG_ENHANCEDBIASWEIGHTCOMPALG_H
+#define TRIG_ENHANCEDBIASWEIGHTCOMPALG_H
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "TrigCompositeUtils/TrigCompositeUtils.h"
+#include "TrigConfData/HLTMenu.h"
+#include "TrigConfData/HLTPrescalesSet.h"
+#include "TrigConfData/L1PrescalesSet.h"
+#include "xAODTrigger/TrigCompositeContainer.h"
+
+#include <vector>
+#include <string>
+
+/**
+ *  @class EnhancedBiasWeightCompAlg
+ *  @brief Compute Enhanced Bias weight
+ **/
+
+class EnhancedBiasWeightCompAlg : public AthReentrantAlgorithm {
+  public:
+
+    EnhancedBiasWeightCompAlg(const std::string& name, ISvcLocator* svcLoc);
+
+    virtual StatusCode initialize() override;
+    virtual StatusCode start() override;
+    virtual StatusCode execute(const EventContext& context) const override;
+
+  private:
+    /**
+     *  @class EBChainInfo
+     *  @brief Store necessary information for weight computing for Enhanced Bias chain 
+     **/
+
+    class EBChainInfo {
+      public:
+        EBChainInfo(const HLT::Identifier & id) : m_id(id), m_totalPrescale(1.0) {}
+
+        std::string getName() const {return m_id.name();}
+        TrigCompositeUtils::DecisionID getId() const {return m_id;}
+        float getPrescale() const {return m_totalPrescale;}
+        bool getIsRandom() const {return (getName().find("HLT_noalg_eb_L1RD") != std::string::npos);}
+        bool getIsNoPS() const {return (getName().find("noPS") != std::string::npos);}
+
+        void setPrescale(const float& prescale) {m_totalPrescale = prescale;}
+
+      private:
+        /// HLTID of the chain
+        HLT::Identifier m_id;
+
+        /// Value of total prescale L1 * HLT
+        float m_totalPrescale;
+    };
+
+    /**
+     *  @class EBResult
+     *  @brief Store result of EB weight calculation
+     **/
+    struct EBResult {
+      float weight {1.0};
+      uint8_t isUnbiased {};
+    };
+
+    SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey{ this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu" };
+    SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer> m_finalDecisionKey{ this, "FinalDecisionKey", "HLTNav_Summary", "Final stage of all decisions" };
+    SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_EBWeightKey {this, "EBWeight", "HLT_EBWeight", "Computed EB Weight"};
+
+    SG::ReadCondHandleKey<TrigConf::HLTPrescalesSet> m_HLTPrescaleSetInputKey {this, "HLTPrescales", "HLTPrescales", "HLT prescales set"};
+    SG::ReadCondHandleKey<TrigConf::L1PrescalesSet> m_L1PrescaleSetInputKey {this, "L1Prescales", "L1Prescales", "L1 prescales set"};
+
+    /// Calculate EB result based on total prescales of chains
+    EBResult calculateEBWeight(const std::vector<EBChainInfo>& EBChains) const;
+
+    /// Retrieve total prescales (L1 * HLT) for chains into map
+    StatusCode getPrescales(const EventContext& context, std::vector<EBChainInfo>& EBChains) const;
+
+    /// Get list of Enhanced Bias chains that passed
+    std::vector<EBChainInfo> getPassedEBChains(const TrigCompositeUtils::Decision& decisionObject) const;
+
+    /// Check if any of random chains passed
+    bool checkIfTriggeredByRandomChain(const std::vector<EBChainInfo>& EBChain) const;
+
+    /// Parse list of l1 items
+    std::vector<std::string> parseItems(const std::string& itemStr);
+
+    /// Available EB chains' IDs from HLT Menu
+    std::vector<TrigCompositeUtils::DecisionID> m_EBChainIds;
+
+    /// L1 items for EB chains from HLT Menu
+    std::map<TrigCompositeUtils::DecisionID, std::vector<std::string>> m_EBChainIdToItem;
+
+};
+
+#endif //TRIG_ENHANCEDBIASWEIGHTCOMPALG_H
\ No newline at end of file
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/EnhancedBiasWeightCompAlg.cxx b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/EnhancedBiasWeightCompAlg.cxx
new file mode 100644
index 00000000000..6f8398b80e9
--- /dev/null
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/EnhancedBiasWeightCompAlg.cxx
@@ -0,0 +1,160 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "TrigCostMonitorMT/EnhancedBiasWeightCompAlg.h"
+
+#include <sstream>
+
+
+EnhancedBiasWeightCompAlg::EnhancedBiasWeightCompAlg(const std::string& name, ISvcLocator* svcLoc)
+    : AthReentrantAlgorithm(name, svcLoc) {}
+
+StatusCode EnhancedBiasWeightCompAlg::initialize(){
+    
+    ATH_CHECK( m_HLTMenuKey.initialize() );
+    ATH_CHECK( m_finalDecisionKey.initialize() );
+    ATH_CHECK( m_EBWeightKey.initialize() );
+
+    ATH_CHECK( m_HLTPrescaleSetInputKey.initialize() );
+    ATH_CHECK( m_L1PrescaleSetInputKey.initialize() );
+
+    return StatusCode::SUCCESS;
+}
+
+
+StatusCode EnhancedBiasWeightCompAlg::start() {
+    
+    SG::ReadHandle<TrigConf::HLTMenu> hltMenuHandle = SG::makeHandle( m_HLTMenuKey );
+    ATH_CHECK( hltMenuHandle.isValid() );
+
+    // Save ids of EB chains - that contain "_eb_"
+    m_EBChainIds = std::vector<TrigCompositeUtils::DecisionID>();
+    for (const TrigConf::Chain& chain : *hltMenuHandle){
+        std::vector<std::string> streams = chain.streams();
+        if (std::find(streams.begin(), streams.end(), "EnhancedBias") != streams.end()){
+            auto chainId = HLT::Identifier(chain.name());
+            m_EBChainIds.push_back(chainId);
+            m_EBChainIdToItem[chainId] = parseItems(chain.l1item());
+        }
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+
+StatusCode EnhancedBiasWeightCompAlg::execute(const EventContext& context) const {
+
+    auto finalDecisionsHandle = SG::makeHandle( m_finalDecisionKey, context );
+    ATH_CHECK( finalDecisionsHandle.isValid() );
+
+    // Retrieve information about EB chains that passed
+    std::vector<EBChainInfo> EBChains;
+    for (const TrigCompositeUtils::Decision* decisionObject : *finalDecisionsHandle) {
+        if (decisionObject->name() == "HLTPassRaw") {
+           EBChains = getPassedEBChains(*decisionObject);
+           break;
+        }
+    }
+
+    // Setup output handle
+    SG::WriteHandle<xAOD::TrigCompositeContainer> outputHandle = TrigCompositeUtils::createAndStore(m_EBWeightKey, context);
+
+    // None of EB chains passed the algorithm
+    if (EBChains.empty()) return StatusCode::SUCCESS;
+
+    // Retrieve L1 and HLT prescales
+    ATH_CHECK( getPrescales(context, EBChains) );
+    
+    // Calculate EB weight
+    EBResult result = calculateEBWeight(EBChains);
+
+    // Save output values: EBWeight and EBUnbiased
+    xAOD::TrigComposite* tc = new xAOD::TrigComposite();
+    outputHandle->push_back(tc);
+
+    tc->setDetail<float>("EBWeight", result.weight);
+    tc->setDetail<uint8_t>("EBUnbiased", result.isUnbiased);
+
+    ATH_MSG_DEBUG("EnhacedBias EBWeight: " << result.weight << " EnhacedBias isUnbiased: " << result.isUnbiased );
+
+    return StatusCode::SUCCESS;
+}
+
+
+StatusCode EnhancedBiasWeightCompAlg::getPrescales(const EventContext& context, std::vector<EBChainInfo>& EBChains) const {
+
+    SG::ReadCondHandle<TrigConf::HLTPrescalesSet> HLTPrescalesSet (m_HLTPrescaleSetInputKey, context);
+    ATH_CHECK( HLTPrescalesSet.isValid() );
+    
+    SG::ReadCondHandle<TrigConf::L1PrescalesSet> L1PrescalesSet (m_L1PrescaleSetInputKey, context);
+    ATH_CHECK( L1PrescalesSet.isValid() );
+
+    for (EBChainInfo& chain : EBChains) {
+
+        double HLTPrescale = HLTPrescalesSet->prescale(chain.getId()).prescale;
+        double L1Prescale = 1.0;
+        if (!chain.getIsNoPS()) {
+            for (const std::string& item : m_EBChainIdToItem.at(chain.getId())){
+                L1Prescale *= L1PrescalesSet->prescale(item).prescale;
+            }
+        }
+
+        chain.setPrescale(HLTPrescale * L1Prescale);
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+
+EnhancedBiasWeightCompAlg::EBResult EnhancedBiasWeightCompAlg::calculateEBWeight(const std::vector<EBChainInfo>& EBChains) const{
+
+    double weight = 1.;
+
+    for (const EBChainInfo& chain : EBChains){
+       weight *= 1. - ( 1. / chain.getPrescale() );
+    }
+
+    weight = (std::fabs(1.0 - weight) < 1e-10) ? 0. : (1. / (1. - weight));
+
+    // Check if the event was triggered by EB noalg random chain
+    bool isUnbiased = checkIfTriggeredByRandomChain(EBChains);
+    
+    return {float(weight), isUnbiased}; 
+}
+
+
+std::vector<EnhancedBiasWeightCompAlg::EBChainInfo> EnhancedBiasWeightCompAlg::getPassedEBChains(const TrigCompositeUtils::Decision& decisionObject) const {
+    
+    std::vector<EBChainInfo> passedEBChains;
+
+    for (const TrigCompositeUtils::DecisionID& chainId : m_EBChainIds) {
+        if (std::find(decisionObject.decisions().begin(), decisionObject.decisions().end(), chainId) != decisionObject.decisions().end()) {
+            passedEBChains.push_back(EBChainInfo(HLT::Identifier(chainId)));
+        }
+    }
+
+    return passedEBChains;
+}
+
+
+bool EnhancedBiasWeightCompAlg::checkIfTriggeredByRandomChain(const std::vector<EBChainInfo>& EBChains) const {
+    
+    return std::find_if (EBChains.begin(), EBChains.end(), 
+        [](const EBChainInfo& chain) -> bool { return chain.getIsRandom(); }) != EBChains.end();
+}
+
+std::vector<std::string> EnhancedBiasWeightCompAlg::parseItems(const std::string& itemStr) {
+    
+    std::vector<std::string> items;
+
+    std::stringstream itemStream (itemStr);
+    std::string item;
+
+    while (std::getline(itemStream, item, ',')) {
+        items.push_back(item);
+    }
+
+    return items;
+}
\ No newline at end of file
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/components/TrigCostMonitorMT_entries.cxx b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/components/TrigCostMonitorMT_entries.cxx
index 982026a4cee..35b0f248de0 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/components/TrigCostMonitorMT_entries.cxx
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/components/TrigCostMonitorMT_entries.cxx
@@ -1,9 +1,11 @@
 /*
-  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 "src/TrigCostMTSvc.h"
 #include "TrigCostMonitorMT/TrigCostMTAuditor.h"
+#include "TrigCostMonitorMT/EnhancedBiasWeightCompAlg.h"
 
 DECLARE_COMPONENT( TrigCostMTSvc )
 DECLARE_COMPONENT( TrigCostMTAuditor )
+DECLARE_COMPONENT( EnhancedBiasWeightCompAlg )
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index 30031821161..5a58b88f36b 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -83,6 +83,8 @@ TriggerHLTListRun3 = [
     ('xAOD::TrigDecision#xTrigDecision' ,                    'ESD AODFULL AODSLIM', 'Steer'),
     ('xAOD::TrigDecisionAuxInfo#xTrigDecisionAux.',          'ESD AODFULL AODSLIM', 'Steer'),
     ('xAOD::TrigConfKeys#TrigConfKeys' ,                     'ESD AODFULL AODSLIM', 'Steer'),
+    ('xAOD::TrigCompositeContainer#HLT_EBWeight',            'ESD AODFULL AODSLIM', 'Steer'),
+    ('xAOD::TrigCompositeAuxContainer#HLT_EBWeightAux.EBWeight.EBUnbiased', 'ESD AODFULL AODSLIM', 'Steer'),
     ('xAOD::TrigConfKeys#TrigConfKeysOnline' ,               'BS ESD AODFULL AODSLIM', 'Steer'),
 
     ('TrigRoiDescriptorCollection#HLT_EMRoIs',                   'BS ESD AODFULL AODSLIM',  'Steer'),
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py
index 70001805428..d36900c6b43 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py
@@ -489,6 +489,16 @@ class TriggerConfigGetter(Configured):
                                 ]
                 objKeyStore.addManyTypesMetaData( metadataItems )
 
+            if TriggerFlags.EDMDecodingVersion() >= 3:
+                from TrigEDMConfig.TriggerEDMRun3 import recordable
+                from AthenaConfiguration.ComponentFactory import CompFactory
+                from AthenaConfiguration.ComponentAccumulator import conf2toConfigurable
+
+                enhancedBiasWeightCompAlg = CompFactory.EnhancedBiasWeightCompAlg()
+                enhancedBiasWeightCompAlg.EBWeight = recordable("HLT_EBWeight")
+
+                topAlgs += conf2toConfigurable( enhancedBiasWeightCompAlg )
+
         except ImportError: # don't want to branch in rel 18
             pass
 
-- 
GitLab