Commit 598aebb9 authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

Merge branch 'tmmt_chainprop' into 'master'

TriggerMenuMT: Introduce typesafe ChainProp class

See merge request atlas/athena!46826
parents fd1e1d33 be927c30
# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
import collections
import typing
from typing import List
import dataclasses
from dataclasses import dataclass, field
def namedtuple_with_defaults(typename, field_names, default_values=()):
T = collections.namedtuple(typename, field_names)
T.__new__.__defaults__ = (None,) * len(T._fields)
if isinstance(default_values, collections.Mapping):
prototype = T(**default_values)
prototype = T(*default_values)
T.__new__.__defaults__ = tuple(prototype)
return T
class ChainProp:
"""Class to hold chain properties with (limited) type-checking"""
name: str # mandatory
groups: List[str] # mandatory
monGroups: List[str] = field(default_factory = list)
l1SeedThresholds: List[str] = field(default_factory = list)
stream: List[str] = field(default_factory = lambda : ['Main'])
mergingStrategy: str = 'auto'
mergingOrder: List[str] = field(default_factory = list)
mergingOffset: int = -1
topoStartFrom: bool = False # might be obsolete
# currently we don't have a type-checker in LCG so we
# implement a limited version ourselves:
def _check_types(self):
"""Check field types"""
for f in dataclasses.fields(self):
actual_type = typing.get_origin(f.type) or f.type
value = getattr(self,
if actual_type == list:
if value and not isinstance(value[0], typing.get_args(f.type)):
return f
elif not isinstance(value, actual_type):
return f
return None
# namedtuple class with some defaults set for those entries that do not require settings
ChainProp = namedtuple_with_defaults("ChainProp",
['name', 'l1SeedThresholds', 'stream', 'groups', 'mergingStrategy', 'mergingOrder', 'mergingOffset', 'topoStartFrom','monGroups'],
'l1SeedThresholds': [],
'mergingOrder': [],
'mergingOffset': -1,
'topoStartFrom': False,
'monGroups' : []})
def __post_init__(self):
f = self._check_types()
if f is not None:
raise TypeError(f"Expected type of '{}' to be {f.type}, "
f"got {repr(getattr(self,}")
if __name__=='__main__':
ch = ChainProp(name='abc', groups=['g1'])
......@@ -400,10 +400,10 @@ def setupMenu():
TriggerFlags.JetSlice.signatures = TriggerFlags.JetSlice.signatures() + [
ChainProp(name='HLT_j85_L1J20', l1SeedThresholds=['FSNOSEED'], groups=[SingleJetGroup]),
ChainProp(name='HLT_j80_j60_SHARED_j40__L1J15', l1SeedThresholds=['FSNOSEED']*3, groups=[MultiJetGroup]),
ChainProp(name='HLT_j85_CLEANlb_L1J20', l1SeedThresholds=['FSNOSEED'], groups=[SingleJetGroup]),
ChainProp(name='HLT_j85_CLEANllp_L1J20', l1SeedThresholds=['FSNOSEED'], groups=[SingleJetGroup]),
ChainProp(name='HLT_j85_L1J20', l1SeedThresholds=['FSNOSEED'], groups=SingleJetGroup),
ChainProp(name='HLT_j80_j60_SHARED_j40__L1J15', l1SeedThresholds=['FSNOSEED']*3, groups=MultiJetGroup),
ChainProp(name='HLT_j85_CLEANlb_L1J20', l1SeedThresholds=['FSNOSEED'], groups=SingleJetGroup),
ChainProp(name='HLT_j85_CLEANllp_L1J20', l1SeedThresholds=['FSNOSEED'], groups=SingleJetGroup),
ChainProp(name='HLT_j45_L1J15', l1SeedThresholds=['FSNOSEED'], groups=['PS:Online']+SingleJetGroup),
ChainProp(name='HLT_j45_subjesgsc_ftf_L1J15', l1SeedThresholds=['FSNOSEED'], groups=SingleJetGroup),
ChainProp(name='HLT_j45_subjesgscIS_ftf_L1J15', l1SeedThresholds=['FSNOSEED'], groups=SingleJetGroup),
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment