From 3d4582be3e92b82eba46390eac8adbc822340ff0 Mon Sep 17 00:00:00 2001
From: Rafal Bielski <rafal.bielski@cern.ch>
Date: Wed, 9 Dec 2020 18:34:09 +0000
Subject: [PATCH] Partial Event Building: Update configuration and add unit
 tests

---
 .../python/TrigPartialEventBuildingConfig.py  | 27 +++++++++--
 .../TriggerMenuMT/CMakeLists.txt              |  6 +++
 .../EventBuildingSequenceSetup.py             | 45 ++++++++++++++++++-
 .../python/HLTMenuConfig/Menu/StreamInfo.py   |  2 +-
 .../scripts/menu_config_tests.py              | 44 ++++++++++++++++++
 5 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/Trigger/TrigAlgorithms/TrigPartialEventBuilding/python/TrigPartialEventBuildingConfig.py b/Trigger/TrigAlgorithms/TrigPartialEventBuilding/python/TrigPartialEventBuildingConfig.py
index a47d8e6ae65..de2bfa27b2c 100644
--- a/Trigger/TrigAlgorithms/TrigPartialEventBuilding/python/TrigPartialEventBuildingConfig.py
+++ b/Trigger/TrigAlgorithms/TrigPartialEventBuilding/python/TrigPartialEventBuildingConfig.py
@@ -2,13 +2,13 @@
 #  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 #
 
-from TrigPartialEventBuilding.TrigPartialEventBuildingConf import StaticPEBInfoWriterTool, RoIPEBInfoWriterTool
+from AthenaConfiguration.ComponentFactory import CompFactory
 from TrigEDMConfig.DataScoutingInfo import getFullHLTResultID
 from libpyeformat_helper import SourceIdentifier, SubDetector
 from RegionSelector import RegSelToolConfig
 
 
-class StaticPEBInfoWriterToolCfg(StaticPEBInfoWriterTool):
+def StaticPEBInfoWriterToolCfg(name='StaticPEBInfoWriterTool'):
     def addROBs(self, robs):
         self.ROBList.extend(robs)
 
@@ -23,8 +23,17 @@ class StaticPEBInfoWriterToolCfg(StaticPEBInfoWriterTool):
         ctpResultSID = SourceIdentifier(SubDetector.TDAQ_CTP, moduleId)
         self.addROBs([ctpResultSID.code()])
 
+    CompFactory.StaticPEBInfoWriterTool.addROBs = addROBs
+    CompFactory.StaticPEBInfoWriterTool.addSubDets = addSubDets
+    CompFactory.StaticPEBInfoWriterTool.addHLTResultToROBList = addHLTResultToROBList
+    CompFactory.StaticPEBInfoWriterTool.addCTPResultToROBList = addCTPResultToROBList
 
-class RoIPEBInfoWriterToolCfg(RoIPEBInfoWriterTool):
+    tool = CompFactory.StaticPEBInfoWriterTool(name)
+
+    return tool
+
+
+def RoIPEBInfoWriterToolCfg(name='RoIPEBInfoWriterTool'):
     def addRegSelDets(self, detNames):
         '''
         Add RegionSelector tools for given detector look-up tables to build PEB list of ROBs
@@ -51,7 +60,7 @@ class RoIPEBInfoWriterToolCfg(RoIPEBInfoWriterTool):
 
     def addSubDets(self, dets):
         '''Add extra fixed list of SubDets independent of RoI'''
-        self.ExtraSubDets.extend(dets)
+        self.ExtraSubDets.extend([int(detid) for detid in dets])
 
     def addHLTResultToROBList(self, moduleId=getFullHLTResultID()):
         hltResultSID = SourceIdentifier(SubDetector.TDAQ_HLT, moduleId)
@@ -60,3 +69,13 @@ class RoIPEBInfoWriterToolCfg(RoIPEBInfoWriterTool):
     def addCTPResultToROBList(self, moduleId=0):
         ctpResultSID = SourceIdentifier(SubDetector.TDAQ_CTP, moduleId)
         self.addROBs([ctpResultSID.code()])
+
+    CompFactory.RoIPEBInfoWriterTool.addRegSelDets = addRegSelDets
+    CompFactory.RoIPEBInfoWriterTool.addROBs = addROBs
+    CompFactory.RoIPEBInfoWriterTool.addSubDets = addSubDets
+    CompFactory.RoIPEBInfoWriterTool.addHLTResultToROBList = addHLTResultToROBList
+    CompFactory.RoIPEBInfoWriterTool.addCTPResultToROBList = addCTPResultToROBList
+
+    tool = CompFactory.RoIPEBInfoWriterTool(name)
+
+    return tool
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/CMakeLists.txt b/Trigger/TriggerCommon/TriggerMenuMT/CMakeLists.txt
index 7a03fb29a67..aec1bf6342f 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/CMakeLists.txt
+++ b/Trigger/TriggerCommon/TriggerMenuMT/CMakeLists.txt
@@ -151,6 +151,12 @@ atlas_add_test( LS2_emu_menu_DH
                 PROPERTIES TIMEOUT 500
                 POST_EXEC_SCRIPT nopost.sh )
 
+file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unitTestRun_EventBuildingSequenceSetup )
+atlas_add_test( EventBuildingSequenceSetup
+                SCRIPT python -m TriggerMenuMT.HLTMenuConfig.CommonSequences.EventBuildingSequenceSetup
+                PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unitTestRun_EventBuildingSequenceSetup
+                POST_EXEC_SCRIPT nopost.sh )
+
 #----------------------------------
 # List of menus to be created:
 atlas_build_lvl1_trigger_menu( LS2_v1 )
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py
index e3cdd1e7823..5f5fb419daf 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py
@@ -8,7 +8,7 @@ from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep, MenuSeque
 from TrigPartialEventBuilding.TrigPartialEventBuildingConf import PEBInfoWriterAlg
 from TrigPartialEventBuilding.TrigPartialEventBuildingConfig import StaticPEBInfoWriterToolCfg, RoIPEBInfoWriterToolCfg
 from DecisionHandling import DecisionHandlingConf
-from libpyeformat_helper import SubDetector
+from libpyeformat_helper import SourceIdentifier, SubDetector
 from AthenaCommon.CFElements import seqAND, findAlgorithm
 from AthenaCommon.Logging import logging
 log = logging.getLogger('EventBuildingSequenceSetup')
@@ -169,3 +169,46 @@ def alignEventBuildingSteps(all_chains):
             numStepsNeeded = maxPebStepPosition[ebt] - pebStepPosition
             log.debug('Aligning PEB step for chain %s by adding %d empty steps', chainDict['chainName'], numStepsNeeded)
             chainConfig.insertEmptySteps('EmptyPEBAlign', numStepsNeeded, pebStepPosition-1)
+
+
+# Unit test
+if __name__ == "__main__":
+    failures = 0
+    for eb_identifier in EventBuildingInfo.getAllEventBuildingIdentifiers():
+        tool = None
+        try:
+            tool = pebInfoWriterTool('TestTool_'+eb_identifier, eb_identifier)
+        except Exception as ex:
+            failures += 1
+            log.error('Caught exception while configuring PEBInfoWriterTool for %s: %s', eb_identifier, ex)
+            continue
+
+        if not tool:
+            failures += 1
+            log.error('No tool created for %s', eb_identifier)
+            continue
+
+        if tool.__cpp_type__ not in ['StaticPEBInfoWriterTool', 'RoIPEBInfoWriterTool']:
+            failures += 1
+            log.error('Unexpected tool type for %s: %s', eb_identifier, tool.__cpp_type__)
+            continue
+
+        robs = tool.ROBList if tool.__cpp_type__ == 'StaticPEBInfoWriterTool' else tool.ExtraROBs
+        dets = tool.SubDetList if tool.__cpp_type__ == 'StaticPEBInfoWriterTool' else tool.ExtraSubDets
+        robs_check_passed = True
+        for rob_id in robs:
+            rob_sid = SourceIdentifier(rob_id)
+            rob_det_id = rob_sid.subdetector_id()
+            if int(rob_det_id) in dets:
+                robs_check_passed = False
+                log.error('Redundant configuration for %s: ROB %s added to the ROB list while full SubDetector '
+                          '%s is already in the SubDets list', eb_identifier, rob_sid.human(), str(rob_det_id))
+
+        if not robs_check_passed:
+            failures += 1
+            continue
+
+        log.info('%s correctly configured', tool.name)
+
+    import sys
+    sys.exit(failures)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/StreamInfo.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/StreamInfo.py
index f91ed07976a..0b63eb0f903 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/StreamInfo.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/StreamInfo.py
@@ -49,7 +49,7 @@ _all_streams = [
     StreamInfo('express', 'express', True, True),
     # MONITORING STREAMS
     StreamInfo('IDMonitoring', 'monitoring', True, True),
-    StreamInfo('CSC', 'monitoring', True, True),
+    StreamInfo('CSC', 'monitoring', True, False),
     # CALIBRATION STREAMS
     StreamInfo('BeamSpot', 'calibration', True, False),
     StreamInfo('LArCells', 'calibration', False, False),
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py b/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py
index 04ae8bc1e24..72a6380828e 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py
@@ -155,11 +155,55 @@ class RestrictedCTPIDs(MenuVerification):
                         if ctp_id > 512]
         self.failures.extend(over_max_ids)
 
+
+class PartialEventBuildingChecks(MenuVerification):
+    def __init__(self):
+        super(PartialEventBuildingChecks, self).__init__(
+            description='Config consistency of Partial Event Building')
+
+    def run(self, config):
+        from TriggerMenuMT.HLTMenuConfig.Menu import EventBuildingInfo
+        eb_identifiers = EventBuildingInfo.getAllEventBuildingIdentifiers()
+
+        for chain_name, chain_config in config['chains'].items():
+            peb_identifiers = [idf for idf in eb_identifiers if idf in chain_name]
+            peb_writers = [seq for seq in chain_config['sequencers'] if 'PEBInfoWriter' in seq]
+
+            if len(peb_identifiers) == 0 and len(peb_writers) == 0:
+                # Not a PEB chain
+                continue
+
+            if len(peb_identifiers) != 1:
+                self.failures.append(
+                    '{:s} has {:d} event building identifiers'.format(chain_name, len(peb_identifiers)))
+
+            if len(peb_writers) != 1:
+                self.failures.append(
+                    '{:s} has {:d} PEBInfoWriter sequences'.format(chain_name, len(peb_writers)))
+
+            if peb_identifiers and peb_writers and not peb_writers[0].endswith(peb_identifiers[0]):
+                    self.failures.append(
+                        '{:s} PEB sequence name {:s} doesn\'t end with PEB identifier {:s}'.format(
+                            chain_name, peb_writers[0], peb_identifiers[0]))
+
+            for stream_name in chain_config['streams']:
+                if stream_name not in config['streams']:
+                    self.failures.append(
+                        'Stream {:s} for chain {:s} is not defined in streaming configuration'.format(
+                            stream_name, chain_name))
+
+                if config['streams'][stream_name]['forceFullEventBuilding']:
+                    self.failures.append(
+                        'PEB chain {:s} streamed to a full-event-building stream {:s}'.format(
+                            chain_name, stream_name))
+
+
 menu_tests = {
     TriggerLevel.HLT: [
         UniqueChainNames(),
         ConsecutiveChainCounters(),
         StructuredChainNames(TriggerLevel.HLT),
+        PartialEventBuildingChecks()
     ],
     TriggerLevel.L1: [
         RestrictedCTPIDs(),
-- 
GitLab