ATLAS Offline Software
Loading...
Searching...
No Matches
python.TriggerEDM Namespace Reference

Functions

 recordable (arg)
 _addExtraCollectionsToEDMList (edmList, extraList)
 getRawTriggerEDMList (flags, runVersion=-1)
 getTriggerEDMList (flags, key, runVersion=-1)
 _getRun3TrigObjProducedInView (theKey, trigEDMList)
 _handleRun3ViewContainers (el, HLTList)
 getRun3BSList (flags, keys)
 _getRun3TrigObjList (destination, trigEDMList)
 _getRun3TrigEDMSlimList (key, HLTList)
 _getTriggerRun2EDMSlimList (key, edmList)
 getCategory (s)
 _getTypeAndKey (s)
 _keyToLabel (key)
 _getTriggerRun1Run2ObjList (destination, lst)
 getLvl1ESDList ()
 getLvl1AODList ()
 _getL2PreregistrationList ()
 _getEFPreregistrationList ()
 _getHLTPreregistrationList ()
 getPreregistrationList (version=2, doxAODConversion=True)
 _getL2BSTypeList ()
 _getEFBSTypeList ()
 _getHLTBSTypeList ()
 getTPList (version=2)
 getEDMLibraries ()
 _InsertContainerNameForHLT (typedict)
 getEFRun1BSList ()
 getEFRun2EquivalentList ()
 getL2Run1BSList ()
 getL2Run2EquivalentList ()
 isCLIDDefined (cgen, typename)
 testEDMList (edm_list, error_on_edmdetails=True)
 dumpListToJson (fileName, runVersion)

Variables

 log = logging.getLogger('TriggerEDM')
list AllowedOutputFormats = ['BS', 'ESD', 'AODFULL', 'AODSLIM', 'AODBLSSLIM' ]
list _allowedEDMPrefixes = ['HLT_', 'L1_', 'LVL1']

Function Documentation

◆ _addExtraCollectionsToEDMList()

_addExtraCollectionsToEDMList ( edmList,
extraList )
protected
Extend edmList with extraList, keeping track whether a completely new
collection is being added, or a dynamic variable is added to an existing collection, or new targets are added to an existing collection.
The format of extraList is the same as those of TriggerHLTListRun3.

Definition at line 73 of file TriggerEDM.py.

73def _addExtraCollectionsToEDMList(edmList, extraList):
74 """
75 Extend edmList with extraList, keeping track whether a completely new
76 collection is being added, or a dynamic variable is added to an existing collection, or new targets are added to an existing collection.
77 The format of extraList is the same as those of TriggerHLTListRun3.
78 """
79 existing_collections = [(c[0].split("#")[1]).split(".")[0] for c in edmList]
80 insert_idx = getSafeEDMInsertPosition(edmList)
81 for item in extraList:
82 colname = (item[0].split("#")[1]).split(".")[0]
83 if colname not in existing_collections:
84 # a new collection and its Aux container are inserted in front of 'allowTruncation' items.
85 if 'Aux' in colname:
86 edmList.insert(insert_idx+1,item)
87 else:
88 edmList.insert(insert_idx,item)
89 log.info("added new item to Trigger EDM: {}".format(item))
90 else:
91 # Maybe extra dynamic variables or EDM targets are added
92 isAux = "Aux." in item[0]
93 # find the index of the existing item
94 existing_item_nr = [i for i,s in enumerate(edmList) if colname == (s[0].split("#")[1]).split(".")[0]]
95 if len(existing_item_nr) != 1:
96 log.error("Found {} existing edm items corresponding to new item {}, but it must be exactly one!".format(len(existing_item_nr), item))
97 existingItem = edmList[existing_item_nr[0]]
98 if isAux:
99 dynVars = (item[0].split("#")[1]).split(".")[1:]
100 existing_dynVars = (existingItem[0].split("#")[1]).split(".")[1:]
101 existing_dynVars.extend(dynVars)
102 dynVars = list(dict.fromkeys(existing_dynVars))
103 if '' in dynVars:
104 dynVars.remove('')
105 newVars = '.'.join(dynVars)
106 edmTargets = item[1].split(" ") if len(item) > 1 else []
107 existing_edmTargets = existingItem[1].split(" ")
108 edmTargets.extend(existing_edmTargets)
109 edmTargets = list(dict.fromkeys(edmTargets))
110 newTargets = " ".join(edmTargets)
111 typename = item[0].split("#")[0]
112 log.info("old item in Trigger EDM : {}".format(existingItem))
113 signature = existingItem[2] # NOT updated at the moment
114 tags = existingItem[3] if len(existingItem) > 3 else None # NOT updated at the moment
115 edmList.pop(existing_item_nr[0])
116 combName = typename + "#" + colname
117 if isAux:
118 combName += "." + newVars
119 if tags:
120 edmList.insert(existing_item_nr[0], (combName, newTargets, signature, tags))
121 else:
122 edmList.insert(existing_item_nr[0] , (combName, newTargets, signature))
123 log.info("updated item in Trigger EDM: {}".format(edmList[existing_item_nr[0]]))
124
125 if testEDMList(edmList, error_on_edmdetails=False):
126 log.error("edmList contains inconsistencies!")
127
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

◆ _getEFBSTypeList()

_getEFBSTypeList ( )
protected
 List of EF types to be read from BS, used by the TP

Definition at line 584 of file TriggerEDM.py.

584def _getEFBSTypeList():
585 """ List of EF types to be read from BS, used by the TP
586 """
587 l = []
588 for item in TriggerEFList:
589 t,k = _getTypeAndKey(item[0])
590 ctype = t
591 if 'collection' in EDMDetails[t]:
592 ctype = EDMDetails[t]['collection']
593 l += [ctype]
594 return l
595

◆ _getEFPreregistrationList()

_getEFPreregistrationList ( )
protected
List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want in every event for EF

Definition at line 525 of file TriggerEDM.py.

525def _getEFPreregistrationList():
526 """
527 List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want in every event for EF
528 """
529 l = []
530 for item in TriggerEFList:
531 if len (item[1]) == 0: continue
532 t,k = _getTypeAndKey(item[0])
533 if('Aux' in t):
534 continue #we don't wat to preregister Aux containers
535 l += [t+"#"+_keyToLabel(k)]
536 return l
537
if(pathvar)

◆ _getHLTBSTypeList()

_getHLTBSTypeList ( )
protected
 List of HLT types to be read from BS, used by the TP

Definition at line 596 of file TriggerEDM.py.

596def _getHLTBSTypeList():
597 """ List of HLT types to be read from BS, used by the TP
598 """
599 l = []
600 for item in TriggerHLTList:
601 t,k = _getTypeAndKey(item[0])
602 ctype = t
603 if 'collection' in EDMDetails[t]:
604 ctype = EDMDetails[t]['collection']
605 l += [ctype]
606 return l
607

◆ _getHLTPreregistrationList()

_getHLTPreregistrationList ( )
protected
List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want in every event for merged L2/EF in addition to default L2 and EF

Definition at line 538 of file TriggerEDM.py.

538def _getHLTPreregistrationList():
539 """
540 List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want in every event for merged L2/EF in addition to default L2 and EF
541 """
542 l = []
543 for item in TriggerHLTList:
544 if len (item[1]) == 0: continue
545 t,k = _getTypeAndKey(item[0])
546 if('Aux' in t):
547 continue #we don't wat to preregister Aux containers
548 l += [t+"#"+_keyToLabel(k)]
549 return l
550
551

◆ _getL2BSTypeList()

_getL2BSTypeList ( )
protected
 List of L2 types to be read from BS, used by the TP

Definition at line 572 of file TriggerEDM.py.

572def _getL2BSTypeList():
573 """ List of L2 types to be read from BS, used by the TP
574 """
575 l = []
576 for item in TriggerL2List:
577 t,k = _getTypeAndKey(item[0])
578 ctype = t
579 if 'collection' in EDMDetails[t]:
580 ctype = EDMDetails[t]['collection']
581 l += [ctype]
582 return l
583

◆ _getL2PreregistrationList()

_getL2PreregistrationList ( )
protected
List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want in every event for L2

Definition at line 512 of file TriggerEDM.py.

512def _getL2PreregistrationList():
513 """
514 List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want in every event for L2
515 """
516 l = []
517 for item in TriggerL2List:
518 if len (item[1]) == 0: continue
519 t,k = _getTypeAndKey(item[0])
520 if('Aux' in t):
521 continue #we don't wat to preregister Aux containers
522 l += [t+"#"+_keyToLabel(k)]
523 return l
524

◆ _getRun3TrigEDMSlimList()

_getRun3TrigEDMSlimList ( key,
HLTList )
protected
Run 3 version
Modified EDM list to remove all dynamic variables
Requires changing the list to have 'Aux.-'

Definition at line 342 of file TriggerEDM.py.

342def _getRun3TrigEDMSlimList(key, HLTList):
343 """
344 Run 3 version
345 Modified EDM list to remove all dynamic variables
346 Requires changing the list to have 'Aux.-'
347 """
348 _edmList = _getRun3TrigObjList(key,[HLTList])
349
350 output = {}
351 for k,v in _edmList.items():
352 output[k] = [_handleRun3ViewContainers( el, HLTList ) for el in v]
353 return output
354
355#************************************************************
356#
357# For Run 1 and Run 2 (not modified (so far))
358#
359#************************************************************

◆ _getRun3TrigObjList()

_getRun3TrigObjList ( destination,
trigEDMList )
protected
Run 3 version
Gives back the Python dictionary  with the content of ESD/AOD (dst) which can be inserted in OKS.

Definition at line 319 of file TriggerEDM.py.

319def _getRun3TrigObjList(destination, trigEDMList):
320 """
321 Run 3 version
322 Gives back the Python dictionary with the content of ESD/AOD (dst) which can be inserted in OKS.
323 """
324 dset = set(destination.split())
325 toadd = defaultdict(list)
326
327 for item in itertools.chain(*trigEDMList):
328 if item[1] == '': # no output has been defined
329 continue
330
331 confset = set(item[1].split())
332
333 if dset & confset: # intersection of the sets
334 colltype, k = _getTypeAndKey(item[0])
335
336 if k not in toadd[colltype]:
337 toadd[colltype] += [k]
338
339 return toadd
340
341
STL class.

◆ _getRun3TrigObjProducedInView()

_getRun3TrigObjProducedInView ( theKey,
trigEDMList )
protected
Run 3 only
Finds a given key from within the trigEDMList.
Returns true if this collection is produced inside EventViews
(Hence, has the special viewIndex Aux decoration applied by steering)

Definition at line 255 of file TriggerEDM.py.

255def _getRun3TrigObjProducedInView(theKey, trigEDMList):
256 """
257 Run 3 only
258 Finds a given key from within the trigEDMList.
259 Returns true if this collection is produced inside EventViews
260 (Hence, has the special viewIndex Aux decoration applied by steering)
261 """
262 from TrigEDMConfig.TriggerEDMRun3 import InViews
263
264 return any(coll for coll in itertools.chain(*trigEDMList) if
265 len(coll)>3 and theKey==coll[0].split('#')[1] and
266 any(isinstance(v, InViews) for v in coll[3]))
267
268

◆ _getTriggerRun1Run2ObjList()

_getTriggerRun1Run2ObjList ( destination,
lst )
protected
Gives back the Python dictionary  with the content of ESD/AOD (dst) which can be inserted in OKS.

Definition at line 473 of file TriggerEDM.py.

473def _getTriggerRun1Run2ObjList(destination, lst):
474 """
475 Gives back the Python dictionary with the content of ESD/AOD (dst) which can be inserted in OKS.
476 """
477 dset = set(destination.split())
478
479 toadd = {}
480
481 for item in itertools.chain(*lst):
482 if item[1] == '':
483 continue
484 confset = set(item[1].split())
485 if dset & confset: # intersection of the sets
486 t,k = _getTypeAndKey(item[0])
487 colltype = t
488 if 'collection' in EDMDetails[t]:
489 colltype = EDMDetails[t]['collection']
490 if colltype in toadd:
491 if k not in toadd[colltype]:
492 toadd[colltype] += [k]
493 else:
494 toadd[colltype] = [k]
495 return _InsertContainerNameForHLT(toadd)
496
497

◆ _getTriggerRun2EDMSlimList()

_getTriggerRun2EDMSlimList ( key,
edmList )
protected
Run 2 version
Modified EDM list to remove all dynamic variables
Requires changing the list to have 'Aux.-'

Definition at line 360 of file TriggerEDM.py.

360def _getTriggerRun2EDMSlimList(key, edmList):
361 """
362 Run 2 version
363 Modified EDM list to remove all dynamic variables
364 Requires changing the list to have 'Aux.-'
365 """
366 output = {}
367 for k,v in edmList.items():
368 newnames = []
369 for el in v:
370 if 'Aux' in el:
371 newnames+=[el.split('.')[0]+'.-']
372 else:
373 newnames+=[el]
374 output[k] = newnames
375 return output
376

◆ _getTypeAndKey()

_getTypeAndKey ( s)
protected
 From the strings containing type and key of trigger EDM extract type and key

Definition at line 460 of file TriggerEDM.py.

460def _getTypeAndKey(s):
461 """ From the strings containing type and key of trigger EDM extract type and key
462 """
463 return s[:s.index('#')], s[s.index('#')+1:]
464

◆ _handleRun3ViewContainers()

_handleRun3ViewContainers ( el,
HLTList )
protected

Definition at line 269 of file TriggerEDM.py.

269def _handleRun3ViewContainers( el, HLTList ):
270 if 'Aux.' in el:
271 # Get equivalent non-aux string (fragile!!!)
272 keyNoAux = el.split('.')[0].replace('Aux','')
273 # Check if this interface container is produced inside a View
274 inView = _getRun3TrigObjProducedInView(keyNoAux, [HLTList])
275 if el.split('.')[1] == '':
276 # Aux lists zero dynamic vars to save ...
277 if inView:
278 # ... but it was produced in a View, so we need to add the viewIndex dynamic aux
279 return el.split('.')[0]+'.viewIndex'
280 else:
281 # ... and was not in a View, strip all dynamic
282 return el.split('.')[0]+'.-'
283 else:
284 # Aux lists one or more dynamic vars to save ...
285 if inView:
286 # ... and was produced in a View, so add the viewIndex dynamic as well
287 return el+'.viewIndex'
288 else:
289 # ... and was not produced in a View, keep user-supplied list
290 return el
291 else: # no Aux
292 return el
293
294
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:312

◆ _InsertContainerNameForHLT()

_InsertContainerNameForHLT ( typedict)
protected

Definition at line 633 of file TriggerEDM.py.

633def _InsertContainerNameForHLT(typedict):
634 import re
635 output = {}
636 for k,v in typedict.items():
637 newnames = []
638 for el in v:
639 if el.startswith('HLT_') or el == 'HLT':
640 prefixAndLabel = el.split('_',1) #only split on first underscore
641 containername = k if 'Aux' not in k else EDMDetails[k]['parent'] #we want the type in the Aux SG key to be the parent type #104811
642 #maybe this is not needed anymore since we are now versionless with the CLIDs but it's not hurting either
643 containername = re.sub('::','__',re.sub('_v[0-9]+$','',containername))
644 newnames+=['_'.join([prefixAndLabel[0],containername]+([prefixAndLabel[1]] if len(prefixAndLabel) > 1 else []))]
645 else:
646 newnames+=[el]
647 output[k] = newnames
648 return output
649

◆ _keyToLabel()

_keyToLabel ( key)
protected
 The key is usually HLT_*, this function returns second part of it or empty string

Definition at line 465 of file TriggerEDM.py.

465def _keyToLabel(key):
466 """ The key is usually HLT_*, this function returns second part of it or empty string
467 """
468 if '_' not in key:
469 return ''
470 else:
471 return key[key.index('_'):].lstrip('_')
472

◆ dumpListToJson()

dumpListToJson ( fileName,
runVersion )

Definition at line 836 of file TriggerEDM.py.

836def dumpListToJson(fileName,runVersion):
837 import json
838 edmDict = dict([(fmt, getTriggerEDMList(flags=None, key=fmt, runVersion=runVersion)) for fmt in AllowedOutputFormats])
839 with open(fileName,'w') as f:
840 json.dump(edmDict, f)

◆ getCategory()

getCategory ( s)
From name of object in AOD/ESD found by checkFileTrigSize.py, return category 
Clean up object name 

Definition at line 377 of file TriggerEDM.py.

377def getCategory(s):
378 """ From name of object in AOD/ESD found by checkFileTrigSize.py, return category """
379
380 """ Clean up object name """
381 s = s.strip()
382
383 # To-do
384 # seperate the first part of the string at the first '_'
385 # search in EDMDetails for the key corresponding to the persistent value
386 # if a key is found, use this as the first part of the original string
387 # put the string back together
388
389 if s.count('.') : s = s[:s.index('.')]
390 if s.count('::'): s = s[s.index(':')+2:]
391 if s.count('<'): s = s[s.index('<')+1:]
392 if s.count('>'): s = s[:s.index('>')]
393 if s.count('.') : s = s[:s.index('.')]
394 if s.count('Dyn') : s = s[:s.index('Dyn')]
395
396 # containers from Run 1-2 and 3 require different preprocessing
397 # s12 is for Run 1-2, s is for Run 3
398 s12 = s
399
400 if s12.startswith('HLT_xAOD__') or s12.startswith('HLT_Rec__') or s12.startswith('HLT_Analysis__') :
401 s12 = s12[s12.index('__')+2:]
402 s12 = s12[s12.index('_')+1:]
403 #if s12.count('.') : s12 = s12[:s12.index('.')]
404 s12 = "HLT_"+s12
405 elif s12.startswith('HLT_'):
406 #if s.count('Dyn') : s = s[:s.index('Dyn')]
407 if s12.count('_'): s12 = s12[s12.index('_')+1:]
408 if s12.count('_'): s12 = s12[s12.index('_')+1:]
409 s12 = "HLT_"+s12
410
411 TriggerListRun1 = TriggerL2List + TriggerEFList + TriggerResultsRun1List
412 TriggerListRun2 = TriggerResultsList + TriggerLvl1List + TriggerHLTList
413 TriggerListRun3 = getRawTriggerEDMList(flags=None, runVersion=3)
414
415 category = ''
416 bestMatch = ''
417
418 """ Loop over all objects already defined in lists (and hopefully categorized!!) """
419 for item in TriggerListRun1+TriggerListRun2:
420 t,k = _getTypeAndKey(item[0])
421
422 """ Clean up type name """
423 if t.count('::'): t = t[t.index(':')+2:]
424 if t.count('<'): t = t[t.index('<')+1:]
425 if t.count('>'): t = t[:t.index('>')]
426 if (s12.startswith(t) and s12.endswith(k)) and (len(t) > len(bestMatch)):
427 bestMatch = t
428 category = item[2]
429
430 if k.count('.'): k = k[:k.index('.')]
431 if (s12 == k):
432 bestMatch = k
433 category = item[2]
434
435 for item in TriggerListRun3:
436 t,k = _getTypeAndKey(item[0])
437
438 """ Clean up type name """
439 if t.count('::'): t = t[t.index(':')+2:]
440 if t.count('<'): t = t[t.index('<')+1:]
441 if t.count('>'): t = t[:t.index('>')]
442
443 if (s.startswith(t) and s.endswith(k)) and (len(t) > len(bestMatch)):
444 bestMatch = t
445 category = item[2]
446
447 if k.count('.'): k = k[:k.index('.')]
448 if (s == k):
449 bestMatch = k
450 category = item[2]
451
452 if category == '' and 'HLTNav' in s:
453 category = 'HLTNav'
454
455 if category == '': return 'NOTFOUND'
456 return category
457
458
459

◆ getEDMLibraries()

getEDMLibraries ( )

Definition at line 630 of file TriggerEDM.py.

630def getEDMLibraries():
631 return EDMLibraries
632

◆ getEFRun1BSList()

getEFRun1BSList ( )
List of EF trigger objects that were written to ByteStream in Run 1

Definition at line 650 of file TriggerEDM.py.

650def getEFRun1BSList():
651 """
652 List of EF trigger objects that were written to ByteStream in Run 1
653 """
654 l = []
655 for item in TriggerEFEvolutionList:
656 if len (item[1]) == 0: continue
657 t,k = _getTypeAndKey(item[0])
658 l += [t+"#"+_keyToLabel(k)]
659 return l
660

◆ getEFRun2EquivalentList()

getEFRun2EquivalentList ( )
List of Run-2 containers equivalent to Run-1 EF containers

Definition at line 661 of file TriggerEDM.py.

661def getEFRun2EquivalentList():
662 """
663 List of Run-2 containers equivalent to Run-1 EF containers
664 """
665 l = []
666 for item in TriggerEFEvolutionList:
667 if len (item[1]) == 0: continue
668 t,k = _getTypeAndKey(item[1])
669 l += [t+"#"+_keyToLabel(k)]
670 return l
671

◆ getL2Run1BSList()

getL2Run1BSList ( )
List of L2 trigger objects that were written to ByteStream in Run 1

Definition at line 672 of file TriggerEDM.py.

672def getL2Run1BSList():
673 """
674 List of L2 trigger objects that were written to ByteStream in Run 1
675 """
676 l = []
677 for item in TriggerL2EvolutionList:
678 if len (item[1]) == 0: continue
679 t,k = _getTypeAndKey(item[0])
680 l += [t+"#"+_keyToLabel(k)]
681 return l
682

◆ getL2Run2EquivalentList()

getL2Run2EquivalentList ( )
List of Run-2 containers equivalent to Run-1 L2 containers

Definition at line 683 of file TriggerEDM.py.

683def getL2Run2EquivalentList():
684 """
685 List of Run-2 containers equivalent to Run-1 L2 containers
686 """
687 l = []
688 for item in TriggerL2EvolutionList:
689 if len (item[1]) == 0: continue
690 t,k = _getTypeAndKey(item[1])
691 l += [t+"#"+_keyToLabel(k)]
692 return l
693

◆ getLvl1AODList()

getLvl1AODList ( )
Gives back the Python dictionary  with the lvl1 trigger result content of AOD which can be inserted in OKS.

Definition at line 504 of file TriggerEDM.py.

504def getLvl1AODList():
505 """
506 Gives back the Python dictionary with the lvl1 trigger result content of AOD which can be inserted in OKS.
507 """
508 return _getTriggerRun1Run2ObjList('AODFULL',[TriggerLvl1List])
509
510
511

◆ getLvl1ESDList()

getLvl1ESDList ( )
Gives back the Python dictionary  with the lvl1 trigger result content of ESD which can be inserted in OKS.

Definition at line 498 of file TriggerEDM.py.

498def getLvl1ESDList():
499 """
500 Gives back the Python dictionary with the lvl1 trigger result content of ESD which can be inserted in OKS.
501 """
502 return _getTriggerRun1Run2ObjList('ESD',[TriggerLvl1List])
503

◆ getPreregistrationList()

getPreregistrationList ( version = 2,
doxAODConversion = True )
List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want for all levels
version can be: '1 (Run1)', '2 (Run2)'

Definition at line 552 of file TriggerEDM.py.

552def getPreregistrationList(version=2, doxAODConversion=True):
553 """
554 List (Literally Python list) of trigger objects to be preregistered i.e. this objects we want for all levels
555 version can be: '1 (Run1)', '2 (Run2)'
556 """
557
558 l=[]
559 if version==2:
560 l = _getHLTPreregistrationList()
561 elif version==1:
562 # remove duplicates while preserving order
563 objs=_getL2PreregistrationList()+_getEFPreregistrationList()
564 if doxAODConversion:
565 objs += _getHLTPreregistrationList()
566 l=list(dict.fromkeys(objs))
567 else:
568 raise RuntimeError("Invalid version=%s supplied to getPreregistrationList" % version)
569 return l
570
571

◆ getRawTriggerEDMList()

getRawTriggerEDMList ( flags,
runVersion = -1 )
The static EDM list does still need some light manipulation before it can be used commonly.
Never import TriggerHLTListRun3 or TriggerHLTListRun4 directly, always fetch them via this function

Definition at line 128 of file TriggerEDM.py.

128def getRawTriggerEDMList(flags, runVersion=-1):
129 """
130 The static EDM list does still need some light manipulation before it can be used commonly.
131 Never import TriggerHLTListRun3 or TriggerHLTListRun4 directly, always fetch them via this function
132 """
133 if runVersion == -1:
134 runVersion = flags.Trigger.EDMVersion
135
136 if runVersion == 3:
137 edmListCopy = TriggerHLTListRun3.copy()
138 if flags and flags.Trigger.addRun3LowMuEDM:
139 LowMuEDM = getRun3LowMuEDM(flags)
140 log.info( "Adding low mu collections to EDM %i: %s", runVersion, str(LowMuEDM))
141 _addExtraCollectionsToEDMList(edmListCopy, LowMuEDM)
142 elif runVersion == 4:
143 edm4ListCopy = TriggerHLTListRun4.copy()
144 edm3ListCopy = TriggerHLTListRun3.copy()
145 log.debug("Removing duplicated item between TriggerHLTListRun3 and TriggerHLTListRun4.")
146 for i in range(len(edm3ListCopy)-1, -1, -1): # Back iterate by index, we might be removing as we go
147 for r4item in edm4ListCopy:
148 if edm3ListCopy[i][0] == r4item[0]:
149 del edm3ListCopy[i]
150 log.debug(f"- Dupe: {r4item} is removed from TriggerHLTListRun3 to be updated by TriggerHLTListRun4")
151 break
152 lenPreMerge = len(edm3ListCopy)
153 edm4ListCopy.extend(edm3ListCopy)
154 lenPostMerge = len(edm4ListCopy)
155 edmListCopy = edm4ListCopy
156 log.info(f"Added TriggerHLTListRun4 to TriggerHLTListRun3. EDM entries {lenPreMerge} -> {lenPostMerge}")
157 else:
158 errMsg="ERROR the getRawTriggerEDMList function supports runs 3 and 4."
159 log.error(errMsg)
160 raise RuntimeError(errMsg)
161
162 if flags and flags.Trigger.ExtraEDMList:
163 log.info( "Adding extra collections to EDM %i: %s", runVersion, str(flags.Trigger.ExtraEDMList))
164 _addExtraCollectionsToEDMList(edmListCopy, flags.Trigger.ExtraEDMList)
165
166 return edmListCopy
167

◆ getRun3BSList()

getRun3BSList ( flags,
keys )
The keys should contain BS and all the identifiers used for scouting.
Returns list of tuples (typename#key, [keys], [properties]).

Definition at line 295 of file TriggerEDM.py.

295def getRun3BSList(flags, keys):
296 """
297 The keys should contain BS and all the identifiers used for scouting.
298 Returns list of tuples (typename#key, [keys], [properties]).
299 """
300
301 from TrigEDMConfig.TriggerEDMRun3 import persistent
302 keys = set(keys[:])
303 collections = []
304 _HLTList = getRawTriggerEDMList(flags, 3)
305 for definition in _HLTList:
306
307 typename,collkey = definition[0].split("#")
308 # normalise collection name and the key (decorations)
309 typename = persistent(typename)
310 collkey = _handleRun3ViewContainers( collkey, _HLTList )
311 destination = keys & set(definition[1].split())
312 if len(destination) > 0:
313 collections.append( (typename+"#"+collkey, list(destination),
314 definition[3] if len(definition)>3 else []) )
315
316 return collections
317
318

◆ getTPList()

getTPList ( version = 2)
Mapping  of Transient objects to Peristent during serialization (BS creation)
version can be: '1 (Run1)', '2 (Run2)'

Definition at line 608 of file TriggerEDM.py.

608def getTPList(version=2):
609 """
610 Mapping of Transient objects to Peristent during serialization (BS creation)
611 version can be: '1 (Run1)', '2 (Run2)'
612 """
613 l = {}
614 if version==2:
615 bslist = _getHLTBSTypeList()
616 elif version==1:
617 bslist = list(set(_getL2BSTypeList() + _getEFBSTypeList()))
618 else:
619 raise RuntimeError("Invalid version=%s supplied to getTPList" % version)
620
621 for t,d in EDMDetails.items():
622 colltype = t
623 if 'collection' in d:
624 colltype = EDMDetails[t]['collection']
625 if colltype in bslist:
626 l[colltype] = d['persistent']
627 return l
628
629

◆ getTriggerEDMList()

getTriggerEDMList ( flags,
key,
runVersion = -1 )
List (Literally Python dict) of trigger objects to be placed with flags:
flags is the CA flag container
key can be" 'ESD', 'AODSLIM', 'AODFULL'
runVersion can be: '-1 (Auto-configure)', '1 (Run1)', '2 (Run2)', '3' (Run 3), '4' (Run 4)

Definition at line 168 of file TriggerEDM.py.

168def getTriggerEDMList(flags, key, runVersion=-1):
169 """
170 List (Literally Python dict) of trigger objects to be placed with flags:
171 flags is the CA flag container
172 key can be" 'ESD', 'AODSLIM', 'AODFULL'
173 runVersion can be: '-1 (Auto-configure)', '1 (Run1)', '2 (Run2)', '3' (Run 3), '4' (Run 4)
174 """
175 # We allow for this to be overriden as Run1 bytestream actually need to request the Run2 EDM due to it additionally undergoing a transient xAOD migration.
176 if runVersion == -1:
177 runVersion = flags.Trigger.EDMVersion
178
179 if runVersion == 1:
180 return _getTriggerRun1Run2ObjList(key, [TriggerL2List,TriggerEFList, TriggerResultsRun1List])
181
182 elif runVersion == 2:
183 edmList = _getTriggerRun1Run2ObjList(key, [TriggerHLTList, TriggerResultsList])
184 return _getTriggerRun2EDMSlimList(key, edmList) if 'SLIM' in key else edmList
185
186 elif runVersion >= 3:
187 RawEDMList = getRawTriggerEDMList(flags=flags, runVersion=runVersion)
188
189 if key not in AllowedOutputFormats: # AllowedOutputFormats is the entire list of output formats including ESD
190 log.warning('Output format: %s is not in list of allowed formats, please check!', key)
191 return _getRun3TrigObjList(key, [RawEDMList])
192
193 # this keeps only the dynamic variables that have been specified in TriggerEDMRun3
194 Run3TrigEDM = {}
195 Run3TrigEDMSLIM = {}
196
197 if "AODFULL" in key:
198 Run3TrigEDM.update(_getRun3TrigEDMSlimList(key, RawEDMList))
199
200 elif "AODSLIM" in key:
201 # remove the variables that are defined in TriggerEDMRun3.varToRemoveFromAODSLIM from the containers
202
203 # get all containers from list that are marked with AODSLIM
204 if len(varToRemoveFromAODSLIM) == 0:
205 Run3TrigEDM.update(_getRun3TrigEDMSlimList(key, RawEDMList))
206 log.info("No decorations are listed to be removed from AODSLIM")
207 else:
208 Run3TrigEDMSLIM.update(_getRun3TrigEDMSlimList(key, RawEDMList))
209 log.info("The following decorations are going to be removed from the listed collections in AODSLIM {}".format(varToRemoveFromAODSLIM))
210 # Go through all container values and remove the variables to remove
211 # Format of Run3TrigEDMSLIM is {'xAOD::Cont': ['coll1.varA.varB', 'coll2.varD',...],...}
212 for cont, values in Run3TrigEDMSLIM.items():
213 if (isinstance(values, list)):
214 newValues = []
215 for value in values:
216 newValue = value+'.'
217 coll = value.split('.')[0]
218
219 varRemovedFlag = False
220 for myTuple in varToRemoveFromAODSLIM:
221 var = myTuple[0]
222
223 if var in value and coll in myTuple:
224 varRemovedFlag = True
225 removeVar = '.'+var+'.'
226 newValue = newValue.replace(removeVar, '.')
227
228 if newValue[-1:] == '.':
229 newValue = newValue[:-1]
230
231 if varRemovedFlag is False:
232 newValues.append(value)
233 elif varRemovedFlag is True:
234 newValues.append(newValue)
235 else:
236 raise RuntimeError("Decoration removed but no new Value was available, not sure what to do...")
237
238 # Filling the Run3TrigEDM dictionary with the new set of values for each cont
239 Run3TrigEDM[cont] = newValues
240 else:
241 raise RuntimeError("Value in Run3TrigEDM dictionary is not a list")
242
243 else: # ESD
244 Run3TrigEDM.update(_getRun3TrigEDMSlimList(key, RawEDMList))
245
246 log.debug('TriggerEDM for EDM set {} contains the following collections: {}'.format(key, Run3TrigEDM) )
247 return Run3TrigEDM
248
249
250 else:
251 raise RuntimeError("Invalid runVersion=%s supplied to getTriggerEDMList" % runVersion)
252
253
254

◆ isCLIDDefined()

isCLIDDefined ( cgen,
typename )
Checks container type name is hashable

Definition at line 694 of file TriggerEDM.py.

694def isCLIDDefined(cgen,typename):
695 """
696 Checks container type name is hashable
697 """
698 c = cgen.genClidFromName(typename)
699 return (cgen.getNameFromClid(c) is not None)
700

◆ recordable()

recordable ( arg)
Verify that the name is in the list of recorded objects and conform to the name convention

In Run 2 it was a delicate process to configure correctly what got recorded
as it had to be set in the algorithm that produced it as well in the TriggerEDM.py in a consistent manner.

For Run 3 every alg input/output key can be crosschecked against the list of objects to record which is defined here.
I.e. in the configuration alg developer would do this:
from TriggerEDM.TriggerEDMRun3 import recordable

alg.outputKey = recordable("SomeKey")
If the names are correct the outputKey is assigned with SomeKey, if there is a missmatch an exception is thrown.

Definition at line 37 of file TriggerEDM.py.

37def recordable(arg):
38 """
39 Verify that the name is in the list of recorded objects and conform to the name convention
40
41 In Run 2 it was a delicate process to configure correctly what got recorded
42 as it had to be set in the algorithm that produced it as well in the TriggerEDM.py in a consistent manner.
43
44 For Run 3 every alg input/output key can be crosschecked against the list of objects to record which is defined here.
45 I.e. in the configuration alg developer would do this:
46 from TriggerEDM.TriggerEDMRun3 import recordable
47
48 alg.outputKey = recordable("SomeKey")
49 If the names are correct the outputKey is assigned with SomeKey, if there is a missmatch an exception is thrown.
50
51 """
52
53 # Allow passing DataHandle as argument - convert to string and remove store name
54 name = str(arg).replace('StoreGateSvc+','')
55
56 if "HLTNav_" in name:
57 log.error( "Don't call recordable({0}), or add any \"HLTNav_\" collection manually to the EDM. See:collectDecisionObjects.".format( name ) )
58 pass
59 else: #negative filtering
60 if not any([name.startswith(p) for p in _allowedEDMPrefixes]):
61 raise RuntimeError( f"The collection name {name} does not start with any of the allowed prefixes: {_allowedEDMPrefixes}" )
62 if "Aux" in name and not name[-1] != ".":
63 raise RuntimeError( f"The collection name {name} is Aux but the name does not end with the '.'" )
64
65 #TODO Remove TriggerHLTListRun3 once full Trigger EDM Run 4 list defined.
66 for entry in TriggerHLTListRun3 + TriggerHLTListRun4:
67 if entry[0].split( "#" )[1] == name:
68 return arg
69 msg = "The collection name {0} is not declared to be stored by HLT. Add it to TriggerEDMRun4.py".format( name )
70 log.error("ERROR in recordable() - see following stack trace.")
71 raise RuntimeError( msg )
72

◆ testEDMList()

testEDMList ( edm_list,
error_on_edmdetails = True )
Checks EDM list entries for serialization and configuration compliance.

Definition at line 701 of file TriggerEDM.py.

701def testEDMList(edm_list, error_on_edmdetails = True):
702 """
703 Checks EDM list entries for serialization and configuration compliance.
704 """
705
706 #xAOD types that don't expect accompanying Aux containers
707 _noAuxList = ["xAOD::" + contType for contType in ["TrigConfKeys", "BunchConfKey"]]
708
709 cgen = clidGenerator("", False)
710 return_code = 0
711 found_allow_truncation = False
712 serializable_names = []
713 serializable_names_no_label = []
714 serializable_names_no_properties = []
715
716 for i, edm in enumerate(edm_list):
717
718 #check has sufficient entries
719 if len(edm) < 3:
720 log.error("EDM entry too short for " + edm[0])
721 return_code = 1
722 continue
723
724 serializable_name = edm[0]
725 serializable_name_no_label = re.sub(r"\#.*", "", serializable_name)
726 serializable_name_no_properties = serializable_name.split('.')[0]
727
728 serializable_names.append(serializable_name)
729 serializable_names_no_label.append(serializable_name_no_label)
730 serializable_names_no_properties.append(serializable_name_no_properties)
731
732 #check container type name is hashable
733 if not isCLIDDefined(cgen,serializable_name_no_label):
734 log.error("no CLID for " + serializable_name)
735 return_code = 1
736
737 #check that no '.' in entries _not_ containing 'Aux'
738 if "Aux" not in serializable_name and "." in serializable_name:
739 log.error("A '.' found in non-Aux container name " + serializable_name)
740 return_code = 1
741
742 #check for Aux "."
743 if "Aux" in serializable_name and "Aux." not in serializable_name:
744 log.error("no final Aux. in label for " + serializable_name)
745 return_code = 1
746
747 #check contains exactly one #
748 if serializable_name.count("#") != 1:
749 log.error("Invalid naming structure for " + serializable_name)
750 return_code = 1
751 else: # only proceed if type and name can be separated
752 #check that every interface xAOD container directly followed by matching Aux container.
753 if serializable_name.startswith("xAOD") and "Aux" not in serializable_name:
754 cont_type,cont_name = serializable_name.split("#")
755 if cont_type not in _noAuxList:
756 auxmismatch = False
757 if len(edm_list) == i+1:
758 auxmismatch = True
759 cont_to_test = "nothing"
760 else:
761 cont_to_test = edm_list[i+1][0].split(".")[0]+"."
762 cont_type_short = cont_type.replace("Container","")
763 pattern = re.compile(cont_type_short+r".*Aux.*\#"+cont_name+"Aux.")
764 if not pattern.match(cont_to_test):
765 #test if shallow container type.
766 shallow_pattern = re.compile("xAOD::ShallowAuxContainer#"+cont_name+"Aux.")
767 if not shallow_pattern.match(cont_to_test):
768 auxmismatch = True
769 if auxmismatch:
770 log.error("Expected relevant Aux container following interface container %s, but found %s instead.",serializable_name,cont_to_test)
771 return_code = 1
772 else:
773 #check that targets of interface and aux container match
774 targets = set(edm[1].split())
775 if len(edm_list[i+1]) > 1 and cont_to_test.count("#") == 1:
776 contname_to_test = cont_to_test.split("#")[1]
777 targets_to_test = set(edm_list[i+1][1].split())
778 if len(targets ^ targets_to_test) > 0:
779 log.error("Targets of %s (%s) and %s (%s) do not match",cont_name,targets,contname_to_test,targets_to_test)
780 return_code = 1
781
782 #check that Aux always follows non-Aux (our deserialiser relies on that)
783 if i>0 and "Aux" in serializable_name and "Aux" in edm_list[i-1][0]:
784 log.error(f"Aux container {serializable_name} needs to folow the "
785 "associated interface container in the EDM list")
786 return_code = 1
787
788 #check target types are valid. Check that target lists containing higher level targets
789 #have required low level targets (ESD for AOD targets, AODFULL for SLIM targets).
790 file_types = edm[1].split() # might return empty list, this is fine - 0 output file types allowed for an EDM entry (in case of obsolete containers)
791 for file_type in file_types:
792 if file_type not in AllowedOutputFormats:
793 log.error("unknown file type " + file_type + " for " + serializable_name)
794 return_code = 1
795 for higher_level,required_lower_level in [('AOD','ESD'), ('SLIM','AODFULL')]:
796 if higher_level in file_type and required_lower_level not in file_types:
797 log.error("Target list for %s containing '%s' must also contain lower level target '%s'.",serializable_name,file_type,required_lower_level)
798 return_code = 1
799
800 # Check allowTuncation is only at the end
801 tags = edm[3] if len(edm) > 3 else None
802 allow_truncation_flag = False
803 if tags:
804 allow_truncation_flag = allowTruncation in tags
805 if allow_truncation_flag:
806 found_allow_truncation = True
807
808 if found_allow_truncation and not allow_truncation_flag:
809 log.error("All instances of 'allowTruncation' need to be at the END of the EDM serialisation list")
810 return_code = 1
811
812 #end of for loop over entries. Now do complete list checks.
813
814 #check for duplicates:
815 #check that no two EDM entries match after stripping out characters afer '.'
816 if len(set(serializable_names_no_properties)) != len(serializable_names_no_properties):
817 log.error("Duplicates in EDM list! Duplicates found:")
818 import collections.abc
819 for item, count in collections.Counter(serializable_names_no_properties).items():
820 if count > 1:
821 log.error(str(count) + "x: " + str(item))
822 return_code = 1
823
824 #check EDMDetails
825 for EDMDetail in EDMDetailsRun3:
826 if EDMDetail not in serializable_names_no_label:
827 msg = "EDMDetail for " + EDMDetail + " does not correspond to any name in TriggerList"
828 if error_on_edmdetails:
829 log.error(msg)
830 return_code = 1
831 else:
832 log.warning(msg)
833
834 return return_code
835

Variable Documentation

◆ _allowedEDMPrefixes

list python.TriggerEDM._allowedEDMPrefixes = ['HLT_', 'L1_', 'LVL1']
protected

Definition at line 36 of file TriggerEDM.py.

◆ AllowedOutputFormats

list python.TriggerEDM.AllowedOutputFormats = ['BS', 'ESD', 'AODFULL', 'AODSLIM', 'AODBLSSLIM' ]

Definition at line 32 of file TriggerEDM.py.

◆ log

python.TriggerEDM.log = logging.getLogger('TriggerEDM')

Definition at line 21 of file TriggerEDM.py.