ATLAS Offline Software
TriggerCoolUtil.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2 
3 import sys
4 from re import match
5 from time import ctime
6 from typing import Any
7 
8 from PyCool import cool
9 from CoolConvUtilities.AtlCoolLib import indirectOpen
10 
11 def 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
318 if __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]]))
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename R::value_type > sorted(const R &r, PROJ proj={})
Helper function to create a sorted vector from an unsorted range.
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:310
python.TriggerCoolUtil.TriggerCoolUtil.getL1ConfigKeys
def getL1ConfigKeys(db, runlist)
Definition: TriggerCoolUtil.py:134
python.TriggerCoolUtil.TriggerCoolUtil.getHLTConfigKeys
def getHLTConfigKeys(db, runlist)
Definition: TriggerCoolUtil.py:63
python.TriggerCoolUtil.TriggerCoolUtil._getKeys
def _getKeys(db, runlist, folder, in_name, out_name)
Definition: TriggerCoolUtil.py:94
python.TriggerCoolUtil.TriggerCoolUtil.getTrigConfKeys
dict[str, Any] getTrigConfKeys(int runNumber, int lumiBlock)
Definition: TriggerCoolUtil.py:172
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
python.TriggerCoolUtil.TriggerCoolUtil.printStreams
def printStreams(db, run, verbosity)
Definition: TriggerCoolUtil.py:298
python.TriggerCoolUtil.TriggerCoolUtil.GetConnection
def GetConnection(dbconn, verbosity=0)
Definition: TriggerCoolUtil.py:36
upper
int upper(int c)
Definition: LArBadChannelParser.cxx:49
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.TriggerCoolUtil.TriggerCoolUtil.getHLTPrescaleKey
int|None getHLTPrescaleKey(int run, int lb, db=None)
Definition: TriggerCoolUtil.py:122
python.TriggerCoolUtil.TriggerCoolUtil.getMenuConfigKey
dict[str, Any]|None getMenuConfigKey(int run, db=None)
Definition: TriggerCoolUtil.py:56
python.TriggerCoolUtil.TriggerCoolUtil.getL1PrescaleKey
int|None getL1PrescaleKey(int run, int lb, db=None)
Definition: TriggerCoolUtil.py:139
python.TriggerCoolUtil.TriggerCoolUtil
Definition: TriggerCoolUtil.py:33
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.TriggerCoolUtil.TriggerCoolUtil.getHLTPrescaleKeys
def getHLTPrescaleKeys(db, runlist)
Definition: TriggerCoolUtil.py:117
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
python.TriggerCoolUtil.iterate_runlist
def iterate_runlist(list[tuple[int, int]] runlist)
Definition: TriggerCoolUtil.py:11
python.TriggerCoolUtil.TriggerCoolUtil.printHLTMenu
def printHLTMenu(db, run, verbosity, printL2=True, printEF=True)
Definition: TriggerCoolUtil.py:251
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
python.TriggerCoolUtil.TriggerCoolUtil.getBunchGroupKey
dict[int, Any] getBunchGroupKey(db, runlist)
Definition: TriggerCoolUtil.py:151
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
python.TriggerCoolUtil.TriggerCoolUtil.getBunchGroupKeyForRunLB
int|None getBunchGroupKeyForRunLB(int run, int lb, db=None)
Definition: TriggerCoolUtil.py:156
python.TriggerCoolUtil.TriggerCoolUtil.getDBConnectionForRun
def getDBConnectionForRun(int runNumber)
Definition: TriggerCoolUtil.py:168
python.TriggerCoolUtil.TriggerCoolUtil.getRunStartTime
def getRunStartTime(db, runlist, runs)
Definition: TriggerCoolUtil.py:187
python.TriggerCoolUtil.TriggerCoolUtil.printL1Menu
def printL1Menu(db, run, verbosity)
Definition: TriggerCoolUtil.py:208
python.AtlCoolLib.indirectOpen
def indirectOpen(coolstr, readOnly=True, debug=False)
Definition: AtlCoolLib.py:129
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:357