ATLAS Offline Software
Loading...
Searching...
No Matches
TriggerCoolUtil.py
Go to the documentation of this file.
1# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2
3import sys
4from re import match
5from time import ctime
6from typing import Any
7
8from PyCool import cool
9from CoolConvUtilities.AtlCoolLib import indirectOpen
10
11def iterate_runlist(runlist: list[tuple[int, int]]):
12 """Helper to iterate through runlist. The format is:
13 runlist: [[run1,run2], [run3,run4], ... ]
14 In addition each "run" can be a tuple of format (run,LB)
15 """
16 def makeRunLumi(rl):
17 """Create (Run,Lumi) tuple"""
18 return rl if isinstance(rl,tuple) else (rl,0)
19
20 for (a,b) in runlist:
21 (r1,l1) = makeRunLumi(a)
22 (r2,l2) = makeRunLumi(b)
23
24 limmin = (r1 << 32) + l1
25 if isinstance(b,tuple):
26 limmax = (r2 << 32) + l2
27 else:
28 limmax = ((r2+1) << 32) - 1 # full run
29
30 yield (limmin, limmax)
31
32
34
35 @staticmethod
36 def GetConnection(dbconn, verbosity=0):
37 connection = None
38 m = match(r".*?([^/.]+)\.db",dbconn)
39 if dbconn in ["CONDBR2","COMP200","OFLP200"]:
40 connection = f'COOLONL_TRIGGER/{dbconn}'
41 elif m:
42 dbname=m.group(1).upper()
43 connection = "sqlite://;schema=%s;dbname=%s;" % (dbconn,dbname)
44 else:
45 raise RuntimeError ("Can't connect to COOL db %s" % dbconn)
46 try:
47 openConn = indirectOpen(connection,readOnly=True,debug=(verbosity>0))
48 except Exception:
49 import traceback
50 traceback.print_exc()
51 sys.exit(-1)
52 return openConn
53
54
55 @staticmethod
56 def getMenuConfigKey(run: int, db = None) -> dict[str, Any] | None:
57 if db is None:
58 db = TriggerCoolUtil.getDBConnectionForRun(run)
59 configs = TriggerCoolUtil.getHLTConfigKeys(db, [(run, run)])
60 return configs.get(run, None)
61
62 @staticmethod
63 def getHLTConfigKeys(db,runlist):
64 configKeys = {}
65 f = db.getFolder( "/TRIGGER/HLT/HltConfigKeys" )
66 for (limmin,limmax) in iterate_runlist(runlist):
67 objs = f.browseObjects( limmin, limmax, cool.ChannelSelection(0))
68 while objs.goToNext():
69 obj=objs.currentRef()
70 runNr = obj.since()>>32
71 if runNr>1e9: continue # test runs in COOL
72 payload=obj.payload()
73 smk = payload['MasterConfigurationKey']
74 hltpsk = payload['HltPrescaleConfigurationKey']
75 # Format for ConfigSource (see ATR-21550):
76 # Run-2: TRIGGERDBR2R,21.1.24,AthenaP1
77 # Run-3: TRIGGERDB_RUN3;22.0.101;Athena,22.0.101 --extra_args ...
78 release = 'unknown'
79 if runNr>379000:
80 confsrc = payload['ConfigSource'].split(';')
81 if len(confsrc)>2: release = confsrc[2].split()[0]
82 else:
83 confsrc = payload['ConfigSource'].split(',', maxsplit=1)
84 if len(confsrc)>1: release = confsrc[1]
85
86 dbalias = confsrc[0]
87 configKeys[runNr] = { "REL" : release,
88 "SMK" : smk,
89 "HLTPSK" : hltpsk,
90 "DB" : dbalias }
91 return configKeys
92
93 @staticmethod
94 def _getKeys(db, runlist, folder, in_name, out_name):
95 """Helper to retrieve run/LB-index configuration keys
96 returns empty dict if not iov is found
97 """
98 lbmask = 0xFFFFFFFF
99 configKeys = {}
100 f = db.getFolder( folder )
101 for (limmin,limmax) in iterate_runlist(runlist):
102 objs = f.browseObjects( limmin, limmax, cool.ChannelSelection(0))
103 while objs.goToNext():
104 obj=objs.currentRef()
105 runNr = obj.since()>>32
106 if runNr>1e9: continue # test runs in COOL
107 payload = obj.payload()
108 key = payload[in_name]
109 firstLB = obj.since() & lbmask
110 until = (obj.until() & lbmask)
111 lastLB = until-1 if until>0 else lbmask
112 configKeys.setdefault(runNr,{}).setdefault( out_name, [] ).append((key,firstLB,lastLB))
113
114 return configKeys
115
116 @staticmethod
117 def getHLTPrescaleKeys(db,runlist):
118 return TriggerCoolUtil._getKeys(db, runlist, "/TRIGGER/HLT/PrescaleKey",
119 "HltPrescaleKey", "HLTPSK2")
120
121 @staticmethod
122 def getHLTPrescaleKey(run: int, lb: int, db = None) -> int | None:
123 if db is None:
124 db = TriggerCoolUtil.getDBConnectionForRun(run)
125 prescales = TriggerCoolUtil.getHLTPrescaleKeys(db, [(run, run)])
126 if(run not in prescales):
127 return None
128 for (hltpsk, firstlb, lastlb) in prescales[run]['HLTPSK2']:
129 if firstlb<=lb and lb<=lastlb:
130 return hltpsk
131 return None
132
133 @staticmethod
134 def getL1ConfigKeys(db,runlist):
135 return TriggerCoolUtil._getKeys(db, runlist, "/TRIGGER/LVL1/Lvl1ConfigKey",
136 "Lvl1PrescaleConfigurationKey", "LVL1PSK")
137
138 @staticmethod
139 def getL1PrescaleKey(run: int, lb: int, db = None) -> int | None:
140 if db is None:
141 db = TriggerCoolUtil.getDBConnectionForRun(run)
142 prescales = TriggerCoolUtil.getL1ConfigKeys(db, [(run, run)])
143 if(run not in prescales):
144 return None
145 for (l1psk, firstlb, lastlb) in prescales[run]['LVL1PSK']:
146 if firstlb<=lb and lb<=lastlb:
147 return l1psk
148 return None
149
150 @staticmethod
151 def getBunchGroupKey(db,runlist) -> dict[int, Any]:
152 return TriggerCoolUtil._getKeys(db, runlist, "/TRIGGER/LVL1/BunchGroupKey",
153 "Lvl1BunchGroupConfigurationKey", "BGKey")
154
155 @staticmethod
156 def getBunchGroupKeyForRunLB(run: int, lb: int, db = None) -> int | None:
157 if db is None:
158 db = TriggerCoolUtil.getDBConnectionForRun(run)
159 bunches = TriggerCoolUtil.getBunchGroupKey(db, [(run, run)])
160 if(run not in bunches):
161 return None
162 for (bgsk, firstlb, lastlb) in bunches[run]['BGKey']:
163 if firstlb<=lb and lb<=lastlb:
164 return bgsk
165 return None
166
167 @staticmethod
168 def getDBConnectionForRun(runNumber: int):
169 return TriggerCoolUtil.GetConnection('CONDBR2' if runNumber > 230000 else 'COMP200')
170
171 @staticmethod
172 def getTrigConfKeys(runNumber: int, lumiBlock: int) -> dict[str, Any]:
173 db = TriggerCoolUtil.getDBConnectionForRun(runNumber)
174 bgkey = TriggerCoolUtil.getBunchGroupKeyForRunLB(runNumber, lumiBlock, db)
175 l1pskey = TriggerCoolUtil.getL1PrescaleKey(runNumber, lumiBlock, db)
176 hltpskey = TriggerCoolUtil.getHLTPrescaleKey(runNumber, lumiBlock, db)
177 menucfg = TriggerCoolUtil.getMenuConfigKey(runNumber, db)
178 return {
179 "SMK": menucfg['SMK'] if menucfg else None,
180 "DB": menucfg['DB'] if menucfg else None,
181 "LVL1PSK": l1pskey,
182 "HLTPSK": hltpskey,
183 "BGSK": bgkey
184 }
185
186 @staticmethod
187 def getRunStartTime(db,runlist, runs):
188 latestRunNr=0
189 startTime = {}
190 f = db.getFolder( "/TRIGGER/LUMI/LBLB" )
191 for rr in runlist:
192 limmin=(rr[0] << 32)+0
193 limmax=((rr[1]+1) << 32)+0
194 objs = f.browseObjects( limmin, limmax, cool.ChannelSelection(0) )
195 while objs.goToNext():
196 obj=objs.currentRef()
197 runNr = obj.since()>>32
198 if runNr==latestRunNr: continue
199 latestRunNr=runNr
200 if runNr not in runs: continue
201 payload=obj.payload()
202 starttime = payload['StartTime']
203 startTime[runNr] = { "STARTTIME" : ctime(starttime/1E9).replace(' ','_') }
204 return startTime
205
206
207 @staticmethod
208 def printL1Menu(db, run, verbosity):
209 limmin=run<<32
210 limmax=(run+1)<<32
211
212 printPrescales = verbosity>0
213 printDisabled = verbosity>1
214 print ("LVL1 Menu:")
215 f = db.getFolder( "/TRIGGER/LVL1/Menu" )
216 chansel=cool.ChannelSelection.all()
217 objs = f.browseObjects( limmin,limmax,chansel)
218 fps = db.getFolder( "/TRIGGER/LVL1/Prescales" )
219 objsps = fps.browseObjects( limmin,limmax,chansel)
220 itemName = {}
221 itemPrescale = {}
222 longestName = 0
223 while objs.goToNext():
224 obj=objs.currentRef()
225 channel = obj.channelId()
226 payload=obj.payload()
227 itemname = payload['ItemName']
228 itemName[channel] = itemname
229 longestName=max(longestName,len(itemname))
230 while objsps.goToNext():
231 objps=objsps.currentRef()
232 channel = objps.channelId()
233 payloadps=objps.payload()
234 ps = payloadps['Lvl1Prescale']
235 if channel in itemPrescale:
236 itemPrescale[channel] += [ ps ]
237 else:
238 itemPrescale[channel] = [ ps ]
239 for channel in itemName:
240 doPrint = False
241 for x in itemPrescale[channel]:
242 if x>0 or printDisabled: doPrint = True
243 if not doPrint: continue
244 if printPrescales:
245 print ("%4i: %-*s PS " % (channel, longestName, itemName[channel]), itemPrescale[channel])
246 else:
247 print ("%4i: %s" % (channel, itemName[channel]))
248
249
250 @staticmethod
251 def printHLTMenu(db, run, verbosity, printL2=True, printEF=True):
252 limmin=run<<32
253 limmax=((run+1)<<32)-1
254 print ("HLT Menu:")
255 f = db.getFolder( "/TRIGGER/HLT/Menu" )
256 chansel=cool.ChannelSelection.all()
257 objs = f.browseObjects( limmin,limmax,chansel)
258 sizeName=0
259 sizePS=0
260 sizePT=0
261 sizeStr=0
262 sizeLow=0
263 chainNames = {}
264 chainExtraInfo = {}
265 while objs.goToNext():
266 obj=objs.currentRef()
267 payload=obj.payload()
268 level = payload['TriggerLevel']
269 if level=='L2' and not printL2: continue
270 if level=='EF' and not printEF: continue
271 name = payload['ChainName']
272 sizeName=max(sizeName,len(name))
273 counter = payload['ChainCounter']
274 chainNames[(level,counter)] = name
275 if verbosity>0:
276 version = payload['ChainVersion']
277 prescale = payload['Prescale']
278 passthr = payload['PassThrough']
279 stream = payload['StreamInfo']
280 lower = payload['LowerChainName']
281 sizePS=max(sizePS,prescale)
282 sizePT=max(sizePT,passthr)
283 sizeStr=max(sizeStr,len(stream))
284 sizeLow=max(sizeLow,len(lower))
285 chainExtraInfo[(name,level)] = (version, prescale, passthr, stream, lower)
286 sizePS = len("%i"%sizePS)
287 sizePT = len("%i"%sizePT)
288 for c in sorted(chainNames):
289 name = chainNames[c]
290 print ("%s %4i: %-*s" % (c[0], c[1], sizeName, name),)
291 if verbosity>0:
292 (version, prescale, passthr, stream, lower) = chainExtraInfo[(name,c[0])]
293 print ("[V %1s, PS %*i, PT %*i, by %-*s , => %-*s ]" %
294 (version, sizePS, prescale, sizePT, passthr, sizeLow, lower, sizeStr, stream), end='')
295 print()
296
297 @staticmethod
298 def printStreams(db, run, verbosity):
299 limmin=run<<32
300 limmax=((run+1)<<32)-1
301 print ("Used Streams:")
302 f = db.getFolder( "/TRIGGER/HLT/Menu" )
303 chansel=cool.ChannelSelection.all()
304 objs = f.browseObjects( limmin,limmax,chansel)
305 streams = set()
306 while objs.goToNext():
307 obj=objs.currentRef()
308 payload=obj.payload()
309 streamsOfChain = payload['StreamInfo']
310 for streamprescale in streamsOfChain.split(';'):
311 streamname = streamprescale.split(',')[0]
312 streams.add(streamname)
313 for s in sorted(list(streams)):
314 print (s)
315
316
317# Testing
318if __name__ == "__main__":
319 from pprint import pprint
320
321 db = TriggerCoolUtil.GetConnection('CONDBR2')
322 run2 = 363947 # Run-2
323 run3 = 435333 # Run-3
324
325 for run in [run2, run3]:
326 print("\nFull run:")
327 pprint(TriggerCoolUtil.getHLTConfigKeys(db, [[run,run]]))
328 pprint(TriggerCoolUtil.getHLTPrescaleKeys(db, [[run,run]]))
329 pprint(TriggerCoolUtil.getL1ConfigKeys(db, [[run,run]]))
330 pprint(TriggerCoolUtil.getBunchGroupKey(db, [[run,run]]))
331
332 # Detailed tests for Run-3:
333 print("\nLB range within run:")
334 pprint(TriggerCoolUtil.getHLTPrescaleKeys(db, [[(run3,266),(run3,400)]]))
335
336 print("\nRun range:")
337 pprint(TriggerCoolUtil.getHLTPrescaleKeys(db, [[run3,435349]]))
338
339 print("\nMultiple run ranges:")
340 pprint(TriggerCoolUtil.getHLTPrescaleKeys(db, [[run3,435349],[435831,435927]]))
341
342 print("\nMultiple run/LB ranges:")
343 pprint(TriggerCoolUtil.getHLTPrescaleKeys(db, [[(run3,266),(435349,10)],
344 [(435831,466),435927]]))
int upper(int c)
if(febId1==febId2)
void print(char *figname, TCanvas *c1)
#define max(a, b)
Definition cfImp.cxx:41
int|None getHLTPrescaleKey(int run, int lb, db=None)
int|None getBunchGroupKeyForRunLB(int run, int lb, db=None)
dict[str, Any] getTrigConfKeys(int runNumber, int lumiBlock)
_getKeys(db, runlist, folder, in_name, out_name)
int|None getL1PrescaleKey(int run, int lb, db=None)
dict[int, Any] getBunchGroupKey(db, runlist)
printHLTMenu(db, run, verbosity, printL2=True, printEF=True)
dict[str, Any]|None getMenuConfigKey(int run, db=None)
STL class.
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
iterate_runlist(list[tuple[int, int]] runlist)