From 73586214b2e6be2856c07b832b2471cf70e4d218 Mon Sep 17 00:00:00 2001
From: Walter Lampl <walter.lampl@cern.ch>
Date: Wed, 8 Apr 2020 13:30:22 +0000
Subject: [PATCH] Add athena accessor to the menu

---
 .../python/HLTTriggerConfigAccess.py          |   3 +-
 .../python/L1TriggerConfigAccess.py           |   7 +-
 .../TrigConfStorage/python/TriggerCoolUtil.py |   4 +-
 .../TrigConfigSvc/python/TrigConfigSvcCfg.py  |  29 ++-
 .../python/TriggerConfigAccess.py             | 213 ++++++++++++++++++
 5 files changed, 242 insertions(+), 14 deletions(-)
 create mode 100644 Trigger/TrigConfiguration/TrigConfigSvc/python/TriggerConfigAccess.py

diff --git a/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py b/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py
index 7c992656749..5d6bb603998 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py
+++ b/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py
@@ -47,8 +47,7 @@ class HLTPrescalesSetAccess(TriggerConfigAccess):
         super(HLTPrescalesSetAccess,self).__init__( ConfigType.HLTPS, mainkey = "prescales",
                                                     filename = filename, dbalias = dbalias, dbkey = hltpskey )
         self.loader.setQuery([
-            "SELECT HPS_DATA FROM {schema}.HLT_PRESCALE_SET WHERE HPS_ID={dbkey}", # for new db schema
-            ""  # for current db schema
+            "SELECT HPS_DATA FROM {schema}.HLT_PRESCALE_SET WHERE HPS_ID={dbkey}" # for current and new db schema
         ])
         self.load()
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/python/L1TriggerConfigAccess.py b/Trigger/TrigConfiguration/TrigConfIO/python/L1TriggerConfigAccess.py
index cd6d06f33c3..11b022e592f 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/python/L1TriggerConfigAccess.py
+++ b/Trigger/TrigConfiguration/TrigConfIO/python/L1TriggerConfigAccess.py
@@ -153,8 +153,7 @@ class L1PrescalesSetAccess(TriggerConfigAccess):
         super(L1PrescalesSetAccess,self).__init__( ConfigType.L1PS, mainkey = "cutValues",
                                                    filename = filename, dbalias = dbalias, dbkey = l1pskey )
         self.loader.setQuery([
-            "SELECT L1PS_DATA FROM {schema}.L1_PRESCALE_SET WHERE L1PS_ID={dbkey}", # for new db schema
-            "SELECT L1MT.L1MT_MENU FROM {schema}.L1_MASTER_TABLE L1MT where L1MT.L1MT_ID={dbkey}"  # for current db schema
+            "SELECT L1PS_DATA FROM {schema}.L1_PRESCALE_SET WHERE L1PS_ID={dbkey}" # for current and new db schema
         ])
         self.load()
 
@@ -182,8 +181,8 @@ class BunchGroupSetAccess(TriggerConfigAccess):
     this class provides access to the L1 bunchgroup set
     the methods are self-explanatory for people with knowledge of the configuration
     """
-    def __init__(self, filename = None, dbalias = None, smkey = None ):
-        loader = self._getLoader( configType = ConfigType.L1PS, filename = filename, dbalias = dbalias, dbkey = smkey )
+    def __init__(self, filename = None, dbalias = None, bgskey = None ):
+        loader = self._getLoader( configType = ConfigType.L1PS, filename = filename, dbalias = dbalias, dbkey = bgskey )
         super(BunchGroupSetAccess,self).__init__(loader, mainkey = "bunchgroups")
 
 
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/python/TriggerCoolUtil.py b/Trigger/TrigConfiguration/TrigConfStorage/python/TriggerCoolUtil.py
index 10589d66e40..e277ea7a276 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/python/TriggerCoolUtil.py
+++ b/Trigger/TrigConfiguration/TrigConfStorage/python/TriggerCoolUtil.py
@@ -110,9 +110,11 @@ class TriggerCoolUtil:
                 confsrc = payload['ConfigSource'].split(',')
                 release = 'unknown'
                 if len(confsrc)>1: release = confsrc[1]
+                dbalias = confsrc[0]
                 configKeys[runNr] = { "REL"     : release,
                                       "SMK"     : smk,
-                                      "HLTPSK"  : hltpsk }
+                                      "HLTPSK"  : hltpsk,
+                                      "DB"      : dbalias }
         return configKeys
 
     @staticmethod
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py
index 2e0660ce64c..81005db7222 100644
--- a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py
@@ -51,6 +51,21 @@ def getHLTPrescalesSetFileName( flags=None ):
         hltPrescalesSetFileName = 'HLTPrescalesSet_'+flags.Trigger.triggerMenuSetup+'_'+flags.Trigger.menuVersion+'.json'
     return hltPrescalesSetFileName
 
+# L1 Bunchgroups set json file name
+def getBunchGroupSetFileName( flags=None ):
+    if flags is None:
+        from TriggerJobOpts.TriggerFlags import TriggerFlags as tf
+        bunchGroupSetFileName = 'BunchGroupSet_'+tf.triggerMenuSetup()+'_'+tf.menuVersion()+'.json'
+    else:
+        bunchGroupSetFileName = 'BunchGroupSet_'+flags.Trigger.triggerMenuSetup+'_'+flags.Trigger.menuVersion+'.json'
+    return bunchGroupSetFileName
+
+
+# HLT Job options json file name
+def getHLTJobOptionsFileName( flags=None ):
+    return 'HLTJobOptions.json'
+
+
 # Creates an L1 Prescale file from the menu
 # this is a temporary solution, in the final version the L1PrescalesSet file should come from the menu
 def createL1PrescalesFileFromMenu( flags=None ):
@@ -104,28 +119,28 @@ def createHLTPrescalesFileFromMenu( flags=None ):
 
 def getTrigConfigFromFlag( flags=None ):
     log = logging.getLogger('TrigConfigSvcCfg')
-    if flags is None:
+    if flags is None: # old-style TriggerFlags
         from TriggerJobOpts.TriggerFlags import TriggerFlags as tf
-        tcflag = tf.triggerConfig()
-        log.info("Parsing TriggerFlags.triggerConfig %s", tcflag)
+        tcflag = tf.triggerConfig() if tf.triggerConfig.statusOn else None
+        log.info("Parsing old-style trigger flags 'triggerConfig': %s", tcflag)
     else:
         tcflag = flags.Trigger.triggerConfig
-        log.info("Parsing flags.Trigger.triggerConfig %s", tcflag)
+        log.info("Parsing new-style trigger flag 'triggerConfig': %s", tcflag)
     if tcflag is None:
         tcflag = "FILE"
     source, dbconn, keys = (tcflag+":::").split(":")[:3]
-    smk,l1psk,hltpsk,bgk = (keys+",,,").split(",")[:4]
+    smk,l1psk,hltpsk,bgsk = (keys+",,,").split(",")[:4]
     smk = int(smk) if smk != "" else None
     l1psk = int(l1psk) if l1psk!="" else None
     hltpsk = int(hltpsk) if hltpsk!="" else None
-    bgk = int(bgk) if bgk!="" else None
+    bgsk = int(bgsk) if bgsk!="" else None
     tcdict = {
         "source" : source.upper(),  # DB, FILE, COOL
         "dbconn" : dbconn, # db connection (if origin==DB or COOL) or "JOSVC" if connection is to be taken from TrigConf::IJobOptionsSvc 
         "smk"    : smk,
         "l1psk"  : l1psk,
         "hltpsk" : hltpsk,
-        "bgk"    : bgk
+        "bgsk"   : bgsk
     }
     # this is for backward compatibility
     if tcdict["source"] == "MCRECO":
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/python/TriggerConfigAccess.py b/Trigger/TrigConfiguration/TrigConfigSvc/python/TriggerConfigAccess.py
new file mode 100644
index 00000000000..a9f6d4e73bf
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/python/TriggerConfigAccess.py
@@ -0,0 +1,213 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+from .TrigConfigSvcCfg import getTrigConfigFromFlag, getL1MenuFileName, getHLTMenuFileName, getL1PrescalesSetFileName, getHLTPrescalesSetFileName
+
+from TrigConfIO.L1TriggerConfigAccess import L1MenuAccess, L1PrescalesSetAccess, BunchGroupSetAccess
+from TrigConfIO.HLTTriggerConfigAccess import HLTMenuAccess, HLTPrescalesSetAccess, HLTJobOptionsAccess
+
+from AthenaCommon.Logging import logging
+from PyUtils.Decorators import memoize
+
+"""
+Access to the trigger configuration in python is provided depending on
+the trigger configuration source
+
+The tc source is taken from the TriggerFlag triggerConfig
+
+1) tc source is set to INFILE
+
+This is usually the case when running on ESD, AOD, and dAOD files and
+only in this case. An exception is RDO with trigger information in
+MC. The menu and prescales are taken from the pool file, from the
+in-file metadata.
+
+
+2) tc source is set to FILE
+
+This is the case when executing the trigger with the configuration
+taken from file.  The filename is provided by the function
+@getL1MenuFileName
+
+3) tc source is set to DB
+
+This is the case when executing the trigger from the DB. The DB
+connection and keys are provided by the triggerConfig flag
+
+4) tc source is COOL
+
+This is the case when reconstructing the data. From COOL the
+configuration keys and db alias are taken, the configurations
+are then loaded from the DB.
+
+"""
+
+@memoize
+def getKeysFromCool(runNr, lbNr = 0):
+    from TrigConfStorage import TriggerCoolUtil
+    condb = "CONDBR2" if runNr > 236108 else "COMP200"
+    db = TriggerCoolUtil.GetConnection(condb)
+    run_range = [[runNr,runNr]]
+    d = { k: TriggerCoolUtil.getHLTConfigKeys(db, run_range)[runNr][k] for k in ['SMK', 'DB'] }
+    for ( key, lbfirst, lblast) in TriggerCoolUtil.getBunchGroupKey(db, run_range)[runNr]['BGKey']:
+        if lb>=lbfirst and (lb<=lblast or lblast==-1):
+            d['BGSK'] = key
+            break
+    for ( key, lbfirst, lblast) in TriggerCoolUtil.getL1ConfigKeys(db, run_range)[runNr]['LVL1PSK']:
+        if lb>=lbfirst and (lb<=lblast or lblast==-1):
+            d['L1PSK'] = key
+            break
+    for ( key, lbfirst, lblast) in TriggerCoolUtil.getHLTPrescaleKeys(db, run_range)[runNr]['HLTPSK2']:
+        if lb>=lbfirst and (lb<=lblast or lblast==-1):
+            d['HLTPSK'] = key
+            break
+
+    # dbalias mapping
+    dbaliasMapping = { "TRIGGERDBR2R" : "TRIGGERDB",
+                       "TRIGGERDBV2" : "TRIGGERDB_RUN1" }
+    if d["DB"] in dbaliasMapping:
+        d["DB"] = dbaliasMapping[ db["DB"] ]
+
+    return d
+
+
+"""
+
+L1 information
+
+"""
+def getL1MenuAccess( flags = None ):
+    log = logging.getLogger('TriggerConfigAccess')
+    tc = getTrigConfigFromFlag( flags )
+    if tc["source"] == "FILE":
+        cfg = L1MenuAccess( filename = getL1MenuFileName( flags ) )
+    elif tc["source"] == "COOL":
+        """This is the case when reconstructing the data."""
+        from RecExConfig.InputFilePeeker import inpSum
+        keysFromCool = getKeysFromCool( inpSum["run_number"] )
+        cfg = L1MenuAccess( dbalias = trigConfFromCool["DB"], smkey = keysFromCool['SMK'] )
+    elif tc["source"] == "DB":
+        cfg = L1MenuAccess( dbalias = tc["dbconn"], smkey = tc["smk"] )
+    elif tc["source"] == "INFILE":
+        from RecExConfig.InputFilePeeker import inputFileSummary as inpSum
+        if inpSum["file_type"] != 'pool':
+            raise RuntimeError("Cannot read trigger configuration (L1 menu) from input type %s" % inpSum["file_type"])
+        raise NotImplementedError("Python access to the trigger configuration (L1 menu) from in-file metadata not yet implemented")
+    else:
+        raise RuntimeError("Unknown source of trigger configuration: %s" % tc["source"])
+    return cfg
+
+
+def getL1PrescalesSetAccess( flags = None ):
+    log = logging.getLogger('TriggerConfigAccess')
+    tc = getTrigConfigFromFlag( flags )
+    if tc["source"] == "FILE":
+        cfg = L1PrescalesSetAccess( filename = getL1PrescalesSetFileName( flags ) )
+    elif tc["source"] == "COOL":
+        """This is the case when reconstructing the data."""
+        from RecExConfig.InputFilePeeker import inpSum
+        keysFromCool = getKeysFromCool( inpSum["run_number"] )
+        cfg = L1PrescalesSetAccess( dbalias = trigConfFromCool["DB"], l1pskey = keysFromCool['L1PSK'] )
+    elif tc["source"] == "DB":
+        cfg = L1PrescalesSetAccess( dbalias = tc["dbconn"], l1pskey = tc["l1psk"] )
+    elif tc["source"] == "INFILE":
+        from RecExConfig.InputFilePeeker import inputFileSummary as inpSum
+        if inpSum["file_type"] != 'pool':
+            raise RuntimeError("Cannot read trigger configuration (L1 prescales) from input type %s" % inpSum["file_type"])
+        raise NotImplementedError("Python access to the trigger configuration (L1 prescales) from in-file metadata not yet implemented")
+    else:
+        raise RuntimeError("Unknown source of trigger configuration: %s" % tc["source"])
+    return cfg
+
+
+def getBunchGroupSetAccess( flags = None ):
+    log = logging.getLogger('TriggerConfigAccess')
+    tc = getTrigConfigFromFlag( flags )
+    if tc["source"] == "FILE":
+        cfg = BunchGroupSetAccess( filename = getBunchGroupSetFileName( flags ) )
+    elif tc["source"] == "COOL":
+        """This is the case when reconstructing the data."""
+        from RecExConfig.InputFilePeeker import inpSum
+        keysFromCool = getKeysFromCool( inpSum["run_number"] )
+        cfg = BunchGroupSetAccess( dbalias = trigConfFromCool["DB"], bgskey = keysFromCool['BGSK'] )
+    elif tc["source"] == "DB":
+        cfg = BunchGroupSetAccess( dbalias = tc["dbconn"], bgskey = tc["bgsk"] )
+    elif tc["source"] == "INFILE":
+        from RecExConfig.InputFilePeeker import inputFileSummary as inpSum
+        if inpSum["file_type"] != 'pool':
+            raise RuntimeError("Cannot read trigger configuration (HLT prescales) from input type %s" % inpSum["file_type"])
+        raise NotImplementedError("Python access to the trigger configuration (HLT prescales) from in-file metadata not yet implemented")
+    else:
+        raise RuntimeError("Unknown source of trigger configuration: %s" % tc["source"])
+    return cfg
+
+
+
+"""
+
+HLT information
+
+"""
+def getHLTMenuAccess( flags = None ):
+    log = logging.getLogger('TriggerConfigAccess')
+    tc = getTrigConfigFromFlag( flags )
+    if tc["source"] == "FILE":
+        cfg = HLTMenuAccess( filename = getHLTMenuFileName( flags ) )
+    elif tc["source"] == "COOL":
+        """This is the case when reconstructing the data."""
+        from RecExConfig.InputFilePeeker import inpSum
+        keysFromCool = getKeysFromCool( inpSum["run_number"] )
+        cfg = HLTMenuAccess( dbalias = trigConfFromCool["DB"], smkey = keysFromCool['SMK'] )
+    elif tc["source"] == "DB":
+        cfg = HLTMenuAccess( dbalias = tc["dbconn"], smkey = tc["smk"] )
+    elif tc["source"] == "INFILE":
+        from RecExConfig.InputFilePeeker import inputFileSummary as inpSum
+        if inpSum["file_type"] != 'pool':
+            raise RuntimeError("Cannot read trigger configuration (HLT menu) from input type %s" % inpSum["file_type"])
+        raise NotImplementedError("Python access to the trigger configuration (HLT menu) from in-file metadata not yet implemented")
+    else:
+        raise RuntimeError("Unknown source of trigger configuration: %s" % tc["source"])
+    return cfg
+
+
+def getHLTPrescalesSetAccess( flags = None ):
+    log = logging.getLogger('TriggerConfigAccess')
+    tc = getTrigConfigFromFlag( flags )
+    if tc["source"] == "FILE":
+        cfg = HLTPrescalesSetAccess( filename = getHLTPrescalesSetFileName( flags ) )
+    elif tc["source"] == "COOL":
+        """This is the case when reconstructing the data."""
+        from RecExConfig.InputFilePeeker import inpSum
+        keysFromCool = getKeysFromCool( inpSum["run_number"] )
+        cfg = HLTPrescalesSetAccess( dbalias = trigConfFromCool["DB"], l1pskey = keysFromCool['HLTPSK'] )
+    elif tc["source"] == "DB":
+        cfg = HLTPrescalesSetAccess( dbalias = tc["dbconn"], l1pskey = tc["hltpsk"] )
+    elif tc["source"] == "INFILE":
+        from RecExConfig.InputFilePeeker import inputFileSummary as inpSum
+        if inpSum["file_type"] != 'pool':
+            raise RuntimeError("Cannot read trigger configuration (HLT prescales) from input type %s" % inpSum["file_type"])
+        raise NotImplementedError("Python access to the trigger configuration (HLT prescales) from in-file metadata not yet implemented")
+    else:
+        raise RuntimeError("Unknown source of trigger configuration: %s" % tc["source"])
+    return cfg
+
+
+def getHLTJobOptionsAccess( flags = None ):
+    log = logging.getLogger('TriggerConfigAccess')
+    tc = getTrigConfigFromFlag( flags )
+    if tc["source"] == "FILE":
+        cfg = HLTJobOptionsAccess( filename = getHLTJobOptionsFileName( flags ) )
+    elif tc["source"] == "COOL":
+        """This is the case when reconstructing the data."""
+        from RecExConfig.InputFilePeeker import inpSum
+        keysFromCool = getKeysFromCool( inpSum["run_number"] )
+        cfg = HLTJobOptionsAccess( dbalias = trigConfFromCool["DB"], smkey = keysFromCool['SMK'] )
+    elif tc["source"] == "DB":
+        cfg = HLTJobOptionsAccess( dbalias = tc["dbconn"], smkey = tc["smk"] )
+    elif tc["source"] == "INFILE":
+        from RecExConfig.InputFilePeeker import inputFileSummary as inpSum
+        if inpSum["file_type"] != 'pool':
+            raise RuntimeError("Cannot read trigger configuration (HLT menu) from input type %s" % inpSum["file_type"])
+        raise NotImplementedError("Python access to the trigger configuration (HLT menu) from in-file metadata not yet implemented")
+    else:
+        raise RuntimeError("Unknown source of trigger configuration: %s" % tc["source"])
+    return cfg
-- 
GitLab