ATLAS Offline Software
ItemListSemantics.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2 
3 from GaudiConfig2.semantics import getSemanticsFor, SequenceSemantics
4 from collections import defaultdict
5 
6 from AthenaCommon.Logging import logging
7 msg = logging.getLogger("OutputStreamItemListAuxCheck")
8 
9 
10 class OutputStreamItemListSemantics(SequenceSemantics):
11  __handled_types__ = ( "OutputStreamItemList", )
12  __AUX_ext__ = "Aux."
13  __AUX_len__ = len(__AUX_ext__)
14 
15  def __init__(self, cpp_type):
16  valueSem = getSemanticsFor("std::string") if cpp_type in self.__handled_types__ else None
17  super(OutputStreamItemListSemantics, self).__init__(cpp_type, valueSem=valueSem)
18 
19  def merge(self, bb, aa):
20  for b in bb:
21  if b not in aa:
22  aa.append(b)
23  scrubbed = self.checkAuxAttributes( aa )
24  aa.clear()
25  aa.extend( scrubbed )
26  return aa
27 
28  def checkAuxAttributes(self, itemList):
29  """
30  Checks dynamic Aux attribute selection in the ItemList for duplicates and conflicts
31 
32  From Event/xAOD/xAODCore/Root/AuxSelection.cxx
33  The formalism for attribute selection is the following:
34  - An empty set, or a set containing "*" will select all the dynamic
35  attributes passed to the object.
36  - A single "-" attribute will not select any of the dynamic attributes.
37  - A set of variables (without "-" as the first character of the
38  variable names) will select just the variables listed.
39  - A set of variable names, each prefixed by "-", will select all
40  variables but the ones listed.
41  """
42  newitemlist=[]
43  auxitems = defaultdict(set)
44  for item in itemList:
45  auxpos = item.find(self.__AUX_ext__)
46  if auxpos > 0:
47  # Aux store item
48  itemname = item[ : auxpos+self.__AUX_len__]
49  selection = item[auxpos+self.__AUX_len__ : ]
50  # collect attributes selection for this item in a set
51  # empty selection means 'everything'
52  auxitems[itemname].add( selection )
53  else:
54  newitemlist.append(item)
55 
56  newauxlist=[]
57  for k,sel in auxitems.items():
58  allsel = set() # gather all selection items in this set
59  negsel = set() # set of negative ("-") selections
60  for line in sel:
61  if ".." in line or line.startswith(".") or line.endswith('.'):
62  raise ValueError(f"ItemList AuxAttribute selection syntax error for {k} - extra dot in '{line}'")
63  newsel = set(line.split('.'))
64  newneg = {s for s in newsel if s[:1]=='-'}
65  if newneg:
66  if not negsel:
67  negsel = newneg
68  else:
69  # if they are the same it's OK, but different negative selections are ambiguous
70  if newneg != negsel:
71  raise ValueError(f"Multiple (different) negative selection are not supported: for {k} : {str(sel)}")
72  allsel.update( newsel )
73  if negsel and len(negsel) != len(allsel):
74  raise ValueError(f"Mixing up negative and positive Aux selections is not supported: {k} : {str(sel)}")
75  if len(sel) == 1:
76  # single selection, just pass it on
77  newauxlist.append( k + next(iter(sel)) )
78  continue
79  # multiple selections fun
80  if '' in sel or '*' in allsel:
81  if len(allsel) > 1:
82  msg.info(f"Multiple Aux attribute selections for {k} - will write all attributes." +
83  f" Original selection was: {str(sel)}")
84  newauxlist.append( k + '*')
85  continue
86  # 2 or more positive selections - merge them into one
87  newitem = k + ".".join(sorted(allsel))
88  newauxlist.append(newitem)
89  msg.info(f"Multiple attribute selections for {k} - will write combined selection. Found {len(sel)} selections: {str(sel)}")
90  msg.info(f" New selection: {newitem}")
91 
92  return newitemlist + newauxlist
93 
94 
python.ItemListSemantics.OutputStreamItemListSemantics.__handled_types__
tuple __handled_types__
Definition: ItemListSemantics.py:11
python.ItemListSemantics.OutputStreamItemListSemantics.merge
def merge(self, bb, aa)
Definition: ItemListSemantics.py:19
python.ItemListSemantics.OutputStreamItemListSemantics.__AUX_len__
__AUX_len__
Definition: ItemListSemantics.py:13
python.ItemListSemantics.OutputStreamItemListSemantics.checkAuxAttributes
def checkAuxAttributes(self, itemList)
Definition: ItemListSemantics.py:28
python.ItemListSemantics.OutputStreamItemListSemantics.__init__
def __init__(self, cpp_type)
Definition: ItemListSemantics.py:15
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
python.ItemListSemantics.OutputStreamItemListSemantics
Definition: ItemListSemantics.py:10
add
bool add(const std::string &hname, TKey *tobj)
Definition: fastadd.cxx:55
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
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:224
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.ItemListSemantics.OutputStreamItemListSemantics.__AUX_ext__
string __AUX_ext__
Definition: ItemListSemantics.py:12