ATLAS Offline Software
Loading...
Searching...
No Matches
MenuPrescaleSet.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3from typing import Optional, Callable, Any
4from dataclasses import dataclass, field
5
6from AthenaCommon.Logging import logging
7log = logging.getLogger(__name__)
8
9
10@dataclass
12 l1_prescales: dict[str, float] = field(default_factory=dict)
13 hlt_prescales: dict[str, float] = field(default_factory=dict)
14
15
16@dataclass
18 '''
19 This is an extremely basic prescale set generator. No "smart" optimizations (e.g. prescaling
20 all HLT chains for an L1 trigger -> prescale L1 trigger by lowest prescale) are applied.
21
22 The prescales are set based on the following priority: disable_* >> *_prescales >> enable_*.
23 Also, HLT chain >> group (i.e. a group can be disabled while a single chain in that group is enables).
24 If the enable_chains/groups/l1_triggers list is not set, all triggers in that category will be enabled by default.
25
26 This is NOT meant to be used in data-taking, only for development tests and standard reprocessings/MC productions.
27
28 For any more complex prescale sets, refer to the `TrigMenuRulebook` (used to create PS sets
29 for data-taking), located at: https://gitlab.cern.ch/atlas-trigger-menu/TrigMenuRulebook/
30 '''
31
32 enable_chains: Optional[list[str]] = None
33 disable_chains: list[str] = field(default_factory=list)
34 chain_prescales: dict[str, float] = field(default_factory=dict)
35
36 enable_groups: Optional[list[str]] = None
37 disable_groups: list[str] = field(default_factory=list)
38 group_prescales: dict[str, float] = field(default_factory=dict)
39
40 enable_l1_triggers: Optional[list[str]] = None
41 disable_l1_triggers: list[str] = field(default_factory=list)
42 l1_trigger_prescales: dict[str, float] = field(default_factory=dict)
43 disable_unused_l1_triggers: bool = False
44
45 custom_rules: Optional[Callable[[AutoPrescaleSet, dict[str, dict[str, Any]]], AutoPrescaleSet]] = None
46
47 def __post_init__(self):
48 if self.enable_chains is not None: self.enable_chains = set(self.enable_chains)
50
51 if self.enable_groups is not None: self.enable_groups = set(self.enable_groups)
53
54 if self.enable_l1_triggers is not None: self.enable_l1_triggers = set(self.enable_l1_triggers)
56
57
58 @staticmethod
59 def disable_unused_l1(ps_set: AutoPrescaleSet, chain_dicts: dict[str, dict[str, Any]]) -> AutoPrescaleSet:
60 '''Disable unused L1 triggers'''
61 enabled_l1_triggers = set()
62
63 for chain in ps_set.hlt_prescales:
64 l1 = chain_dicts[chain]['L1item']
65 if ps_set.hlt_prescales[chain] > 0 and l1: # Skip L1_All
66 enabled_l1_triggers |= {l1} if isinstance(l1, str) else set(l1)
67
68 for l1_trigger in ps_set.l1_prescales:
69 if l1_trigger not in enabled_l1_triggers:
70 ps_set.l1_prescales[l1_trigger] = -1
71
72 return ps_set
73
74
75 @staticmethod
76 def store_json_files(flags, ps_set: AutoPrescaleSet):
77 # Store the L1/HLTPrescale json files
78 from TrigConfigSvc.TrigConfigSvcCfg import createL1PrescalesFileFromMenu
79 createL1PrescalesFileFromMenu(flags, ps_set.l1_prescales)
80
81 from TriggerMenuMT.HLT.Config.Utility.HLTMenuConfig import HLTMenuConfig
82 from TriggerMenuMT.HLT.Config.JSON.HLTPrescaleJSON import generatePrescaleJSON
83 generatePrescaleJSON(flags, HLTMenuConfig.dictsList())
84
85
86 def generate(self, flags, store: bool = False) -> AutoPrescaleSet:
87 # Get list of HLT chain dicts
88 from TriggerMenuMT.HLT.Config.Utility.HLTMenuConfig import HLTMenuConfig
89
90 # Get list of L1 triggers
91 from TrigConfigSvc.TriggerConfigAccess import getL1MenuAccess
92 l1_triggers = getL1MenuAccess(flags).itemNames()
93
94 group_prescales_set = set(self.group_prescales.keys())
95
96 def match(s1: set, s2: set) -> bool: return not s1.isdisjoint(s2)
97
98 # Return PS set
99 ps_set = AutoPrescaleSet()
100
101 # Generate HLT prescales first
102 for chain, chain_dict in HLTMenuConfig.dicts().items():
103 ps = 1
104
105 if chain in self.disable_chains: ps = -1
106 elif self.enable_chains is not None and chain not in self.enable_chains: ps = -1
107 elif chain in self.chain_prescales: ps = self.chain_prescales[chain]
108 elif match(self.disable_groups, chain_dict['groups']): ps = -1
109 elif self.enable_groups is not None and not match(self.enable_groups, chain_dict['groups']): ps = -1
110 elif match(group_prescales_set, chain_dict['groups']):
111 # Apply the PS of the last matched group
112 for group in reversed(chain_dict['groups']):
113 if group in self.group_prescales:
114 ps = self.group_prescales[group]
115 break
116 elif chain_dict['L1item']: # Skips the L1_All trigger (set to '')
117 l1s = {chain_dict['L1item']} if isinstance(chain_dict['L1item'], str) else set(chain_dict['L1item'])
118
119 if l1s.issubset(self.disable_l1_triggers): ps = -1
120 elif self.enable_l1_triggers is not None and not l1s & self.enable_l1_triggers: ps = -1
121
122 if ps <= 0: ps = -1
123
124 ps_set.hlt_prescales[chain] = ps
125
126 # Now generate L1 prescales
127 for l1_trigger in l1_triggers:
128 ps = 1
129 if l1_trigger in self.disable_l1_triggers: ps = -1
130 elif self.enable_l1_triggers is not None and l1_trigger not in self.enable_l1_triggers: ps = -1
131 elif l1_trigger in self.l1_trigger_prescales: ps = self.l1_trigger_prescales[l1_trigger]
132
133 if ps <= 0: ps = -1
134
135 ps_set.l1_prescales[l1_trigger] = ps
136
138 ps_set = self.disable_unused_l1(ps_set, HLTMenuConfig.dicts())
139
140 # Apply any custom rules, if required
141 if self.custom_rules:
142 ps_set = self.custom_rules(ps_set, HLTMenuConfig.dicts())
143
144
145 # Apply HLT prescales to the HLTMenuConfig
146 for chain, ps in ps_set.hlt_prescales.items():
147 if ps != 1: log.info(f'Applying HLTPS to the chain {chain}: {ps}')
148 HLTMenuConfig.dicts()[chain]['prescale'] = ps
149
150 # Store the prescale JSON files
151 if store: self.store_json_files(flags, ps_set)
152
153 return ps_set
154
AutoPrescaleSet disable_unused_l1(AutoPrescaleSet ps_set, dict[str, dict[str, Any]] chain_dicts)
store_json_files(flags, AutoPrescaleSet ps_set)
STL class.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357