From e4c6f097e4aa14e520d289c76da6e096e1c152bf Mon Sep 17 00:00:00 2001
From: Tim Martin <Tim.Martin@cern.ch>
Date: Tue, 11 Dec 2018 16:52:36 +0100
Subject: [PATCH] Save three types of HLT output summary: passed raw, precaled
 away, was a rerun chain

---
 .../src/DecisionSummaryMakerAlg.cxx           | 59 ++++++++++++++++---
 .../src/DecisionSummaryMakerAlg.h             |  5 +-
 2 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx
index ac3a24e15c6f..677efb74aef3 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx
@@ -14,6 +14,7 @@ StatusCode DecisionSummaryMakerAlg::initialize() {
   renounceArray( m_finalDecisionKeys );
   ATH_CHECK( m_finalDecisionKeys.initialize() ); 
   ATH_CHECK( m_summaryKey.initialize() );
+  ATH_CHECK( m_l1SummaryKey.initialize() );
   
   for ( auto& pair: m_lastStepForChain ) {
     struct { std::string chain, collection; } conf { pair.first, pair.second };    
@@ -37,8 +38,12 @@ StatusCode DecisionSummaryMakerAlg::execute(const EventContext& context) const {
   SG::WriteHandle<TrigCompositeUtils::DecisionContainer> outputHandle = TrigCompositeUtils::createAndStore( m_summaryKey, context );
   auto container = outputHandle.ptr();
 
-  TrigCompositeUtils::Decision* output = TrigCompositeUtils::newDecisionIn( container, "HLTSummary" );
-  
+
+  TrigCompositeUtils::Decision* passRawOutput = TrigCompositeUtils::newDecisionIn( container.get(), "HLTPassRaw" );
+  TrigCompositeUtils::Decision* prescaledOutput = TrigCompositeUtils::newDecisionIn( container.get(), "HLTPrescaled" );
+  TrigCompositeUtils::Decision* rerunOutput = TrigCompositeUtils::newDecisionIn( container.get(), "HLTRerun" );
+
+  // Collate final decisions into the passRawOutput object
   for ( auto& key: m_finalDecisionKeys ) {
     auto handle{ SG::makeHandle(key, context) };
     if ( not handle.isValid() )  {
@@ -58,20 +63,58 @@ StatusCode DecisionSummaryMakerAlg::execute(const EventContext& context) const {
     
     TrigCompositeUtils::DecisionIDContainer finalIDs;
     std::set_intersection(  sum.begin(), sum.end(),
-			    thisCollFilter->second.begin(), thisCollFilter->second.end(), 
-			    std::inserter(finalIDs, finalIDs.begin() ) ); // should be faster than remove_if
+          thisCollFilter->second.begin(), thisCollFilter->second.end(), 
+          std::inserter(finalIDs, finalIDs.begin() ) ); // should be faster than remove_if
     
-    TrigCompositeUtils::decisionIDs( output ).insert( TrigCompositeUtils::decisionIDs( output ).end(), 
-						      finalIDs.begin(), finalIDs.end() );
+    TrigCompositeUtils::decisionIDs( passRawOutput ).insert( TrigCompositeUtils::decisionIDs( passRawOutput ).end(), 
+          finalIDs.begin(), finalIDs.end() );
     
   }
   if ( msgLvl( MSG::DEBUG ) ) {
-    ATH_MSG_DEBUG( "Number of positive decisions " <<  TrigCompositeUtils::decisionIDs( output ).size() << " passing chains");
-    for ( auto d: TrigCompositeUtils::decisionIDs( output ) ) {
+    ATH_MSG_DEBUG( "Number of positive decisions " <<  TrigCompositeUtils::decisionIDs( passRawOutput ).size() << " passing chains");
+    for ( auto d: TrigCompositeUtils::decisionIDs( passRawOutput ) ) {
       ATH_MSG_DEBUG( HLT::Identifier( d ) );
     }
   }
 
+  // Get the data from the L1 decoder, this is where prescales were applied
+  SG::ReadHandle<TrigCompositeUtils::DecisionContainer> l1DecoderSummary( m_l1SummaryKey, context );
+  const TrigCompositeUtils::Decision* l1SeededChains = nullptr;
+  const TrigCompositeUtils::Decision* activeChains = nullptr;
+  const TrigCompositeUtils::Decision* rerunChains = nullptr;
+  for (const TrigCompositeUtils::Decision* d : *l1DecoderSummary) {
+    if (d->name() == "l1seeded") {
+      l1SeededChains = d;
+    } else if (d->name() == "unprescaled") {
+      activeChains = d;
+    } else if (d->name() == "rerun") {
+      rerunChains = d;
+    } else {
+      ATH_MSG_WARNING("DecisionSummaryMakerAlg encountered an unknown set of decisions from the L1Decoder, name '" << d->name() << "'");
+    }
+  }
+
+  if (l1SeededChains == nullptr || activeChains == nullptr || rerunChains == nullptr) {
+    ATH_MSG_ERROR("Unable to read in the summary from the L1Decoder. Cannot write to the HLT output summary the prescale status of HLT chains.");
+    return StatusCode::FAILURE;
+  }
+
+  // Get chains which were prescaled out. This is the set of chains which were seeded but which were NOT active (in the first pass)
+  HLT::IDVec prescaledIDs;
+  std::set_difference( 
+        TrigCompositeUtils::decisionIDs(l1SeededChains).begin(), TrigCompositeUtils::decisionIDs(l1SeededChains).end(),
+        TrigCompositeUtils::decisionIDs(activeChains).begin(),   TrigCompositeUtils::decisionIDs(activeChains).end(),
+        std::back_inserter(prescaledIDs) );
+  // Save this to the output
+  TrigCompositeUtils::decisionIDs( prescaledOutput ).insert( TrigCompositeUtils::decisionIDs( prescaledOutput ).end(), 
+        prescaledIDs.begin(), prescaledIDs.end() );
+
+  // Save the set of chains which were flagged as only executing in rerun. This is a direct copy
+  TrigCompositeUtils::DecisionIDContainer rerunIDs;
+  TrigCompositeUtils::decisionIDs( rerunChains, rerunIDs ); // Extract from rerunChains (a Decision*) into rerunIDs (a set<int>)
+  TrigCompositeUtils::decisionIDs( rerunOutput ).insert( TrigCompositeUtils::decisionIDs( rerunOutput ).end(), 
+        rerunIDs.begin(), rerunIDs.end() );
+
   // Do cost monitoring
   if (m_enableCostMonitoring) {
     SG::WriteHandle<xAOD::TrigCompositeContainer> costMonOutput = TrigCompositeUtils::createAndStore(m_costWriteHandleKey, context);
diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h
index cefa7305863e..c03d8d1f2eb9 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h
@@ -24,12 +24,15 @@ public:
   virtual StatusCode finalize() override;
 
 private:
-  SG::WriteHandleKey<TrigCompositeUtils::DecisionContainer> m_summaryKey{ this, "DecisionsSummaryKey", "HLTFinalDecisions", 
+  SG::WriteHandleKey<TrigCompositeUtils::DecisionContainer> m_summaryKey{ this, "DecisionsSummaryKey", "HLTSummary", 
       "location of final decision" };
   SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_finalDecisionKeys{ this, "FinalDecisionKeys", {}, 
       "Final stage of all decisions" };
   SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_costWriteHandleKey { this, "CostWriteHandleKey", "TrigCostContainer",
     "Trig composite collections summarising the HLT execution" };
+  SG::ReadHandleKey<xAOD::TrigCompositeContainer> m_l1SummaryKey { this, "L1DecoderSummaryKey", "L1DecoderSummary",
+    "Chains status after L1 and prescaling" };
+
 
   ServiceHandle<ITrigCostMTSvc> m_trigCostSvcHandle { this, "TrigCostMTSvc", "TrigCostMTSvc", 
     "The trigger cost service" };
-- 
GitLab