303def readDetailsFromTRP(inputFile, runNumber, maxRanges, itemName="L1_eEM26M--enabled", server="https://atlasop.cern.ch"):
304 log.info("Reading run details from TRP")
305
306 import ROOT
307
308 lumiBlockDict = {}
309
310 for timeRange in inputFile.GetListOfKeys():
311 rangeObj = timeRange.ReadObj()
312 if not rangeObj.IsA().InheritsFrom(ROOT.TDirectory.Class()): continue
313 rangeName = rangeObj.GetName()
314
315 for table in rangeObj.GetListOfKeys():
316 tableObj = table.ReadObj()
317 if "Global" not in tableObj.GetName(): continue
318
319 dirKey =
set(key.ReadObj().GetName()
for key
in tableObj.GetListOfKeys()
if key.ReadObj().GetName().startswith(
'LumiBlock'))
320 lumiBlockDict[rangeName] = sorted(dirKey)
321
322 if not lumiBlockDict:
323 log.error("No lumiblocks were found in the input file")
324 return {}
325
326
327 from DQUtils.sugar import RunLumi
328 from time import ctime
329 from PyCool import cool
330 from TrigConfStorage.TriggerCoolUtil import TriggerCoolUtil
331 dbconn = TriggerCoolUtil.GetConnection("CONDBR2")
332
333 lbRangeTsDict = {}
334
335 f = dbconn.getFolder( "/TRIGGER/LUMI/LBLB" )
336 for lbRange in lumiBlockDict:
337 startLb = int(
min(lumiBlockDict[lbRange]).
replace(
'LumiBlock_',
''))
338 endLb = int(
max(lumiBlockDict[lbRange]).
replace(
'LumiBlock_',
''))
339 log.debug("For range {0} first lumiblock is {1} and last {2}".format(lbRange, startLb, endLb))
340
341 since = RunLumi(runNumber, startLb)
342 until = RunLumi(runNumber, endLb)
343
344 objs = f.browseObjects(since, until, cool.ChannelSelection(0))
345 objs.goToNext()
346 objCurrRef = objs.currentRef()
347 startTime = int(objCurrRef.payload()["StartTime"]/1000)
348
349 while objs.goToNext():
350 objCurrRef = objs.currentRef()
351
352 endTime = int(objCurrRef.payload()["EndTime"]/1000)
353
354 lbRangeTsDict[lbRange] = {"start": startTime, "end" : endTime}
355
356 log.debug(
"Read start and end of range {0} from COOL: {1} - {2}".format(lbRange, ctime(startTime/1E6).
replace(
' ',
'_'), ctime(endTime/1E6).
replace(
' ',
'_')))
357
358
359
360 lbRangeDetailsDict = {}
361 physicsDeadtimeGlobal = []
362 pileupGlobal = []
363 try:
364 import libpbeastpy
365 pbeast = libpbeastpy.ServerProxy(server)
366
367 for lbRange in lbRangeTsDict:
368 lbStart = lbRangeTsDict[lbRange]["start"]
369 lbEnd = lbRangeTsDict[lbRange]["end"]
370
371
372 physicsDeadtimeTRP = pbeast.get_data('ATLAS', 'L1_Rate', 'DT', 'ISS_TRP.' + itemName, False, lbStart, lbEnd, 0, True)
373
374 if len(physicsDeadtimeTRP) == 0:
375 log.error("Deadtime not found for item {0} for range {1}".format(itemName, lbRange))
376 physicsDeadtimeAvg = -1
377 else:
378 physicsDeadtimeTRP = physicsDeadtimeTRP[0].data['ISS_TRP.' + itemName]
379 physicsDeadtimeArray = []
380 for entry in physicsDeadtimeTRP:
381
382 if entry.ts < lbStart or entry.ts > lbEnd:
383 continue
384 if type(entry.value)
is not float:
385 continue
386
387 physicsDeadtimeArray.append(entry.value)
388 physicsDeadtimeGlobal.append(entry.value)
389
390 physicsDeadtimeAvg = sum(physicsDeadtimeArray)/len(physicsDeadtimeArray) if len(physicsDeadtimeArray) > 0 else 1.
391
392
393 pileupPbeast = pbeast.get_data('OLC', 'OCLumi', 'Mu', 'OLC.OLCApp/ATLAS_PREFERRED_LBAv_PHYS', False, lbStart, lbEnd)[0].data['OLC.OLCApp/ATLAS_PREFERRED_LBAv_PHYS']
394 pileupArr = []
395 for entry in pileupPbeast:
396 if entry.ts < lbStart or entry.ts > lbEnd:
397 continue
398 if type(entry.value)
is not float:
399 continue
400
401 pileupArr.append(entry.value)
402 pileupGlobal.append(entry.value)
403
404 pileupAvg = sum(pileupArr)/len(pileupArr) if len(pileupArr) > 0 else -1
405 lbRangeDetailsDict[lbRange] = {
"avgPileup" : round(pileupAvg, 3),
"minPileup" : round(
min(pileupArr), 3),
406 "maxPileup" : round(
max(pileupArr), 3),
"deadtime" : round(physicsDeadtimeAvg, 3)}
407
408 except ImportError as e:
409 log.error("The pbeast python library was not found! Remember to setup tdaq release!")
410 log.debug(e)
411 return {}
412 except RuntimeError as e:
413 if "Sign in to your account" in str(e):
414 log.error("PBeast authentication failed! Remember to export pbeast server sso: export PBEAST_SERVER_SSO_SETUP_TYPE=AutoUpdateKerberos")
415 elif "cannot create CERN SSO cookie" in str(e):
416 log.error("PBeast authentication requires the cookies, please setup")
417 else:
418 log.error("Error when reading from Pbeast! ")
419 log.debug(e)
420 return {}
421
422 log.debug("The final lumiblock dictionary is {0}".format(lbRangeDetailsDict))
423
424 physicsDeadtimeGlobalAvg = sum(physicsDeadtimeGlobal)/len(physicsDeadtimeGlobal) if len(physicsDeadtimeGlobal) > 0 else 1.
425 pileupGlobalAvg = sum(pileupGlobal)/len(pileupGlobal) if len(pileupGlobal) > 0 else 1.
426
427 startTs = lbRangeTsDict[
min(lbRangeTsDict.keys())][
"start"]/1E6
428 endTs = lbRangeTsDict[
max(lbRangeTsDict.keys())][
"end"]/1E6
429 monitoredTime = datetime.timedelta(seconds=(int(endTs - startTs)))
430 additionalDetails = {
431 "DataRangeStart" : ctime(startTs),
432 "DataRangeEnd" : ctime(endTs),
433 "DataRangeDuration" : "{0}:{1}".format(int(monitoredTime.total_seconds()//3600), int((monitoredTime.total_seconds()%3600)//60)),
434 "GlobalMeanPileup" : round(pileupGlobalAvg, 3),
435 "GlobalMinPileup" : round(
min(pileupGlobal), 3),
436 "GlobalMaxPileup" : round(
max(pileupGlobal), 3),
437 "GlobalMeanDeadtime" : round(physicsDeadtimeGlobalAvg, 3)
438 }
439
440 return {"Global" : additionalDetails, "PerLb" : lbRangeDetailsDict}
std::string replace(std::string s, const std::string &s2, const std::string &s3)