ATLAS Offline Software
AtlasSemantics.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2 
3 import GaudiConfig2.semantics
4 from GaudiKernel.GaudiHandles import PrivateToolHandleArray, PublicToolHandle, ServiceHandle
5 from GaudiKernel.DataHandle import DataHandle
6 import re
7 import copy
8 from collections.abc import Sequence
9 
10 
11 class AppendListSemantics(GaudiConfig2.semantics.SequenceSemantics):
12  '''
13  Extend the sequence-semantics with a merge-method that appends the lists
14  Use 'appendList<T>' as fifth parameter of the Gaudi::Property<T> constructor
15  to invoke this merging method. The template parameter is important, also
16  in the string that forms the fifth argument.
17  '''
18  __handled_types__ = (re.compile(r"^appendList<.*>$"),)
19  def __init__(self, cpp_type):
20  super(AppendListSemantics, self).__init__(cpp_type)
21 
22  def merge(self,b,a):
23  a.extend(b)
24  return a
25 
26 class MapMergeNoReplaceSemantics(GaudiConfig2.semantics.MappingSemantics):
27  '''
28  Extend the mapping-semantics with a merge-method that merges two mappings as long as they do not have different values for the same key
29  Use 'mapMergeNoReplace<T>' as fifth parameter of the Gaudi::Property<T> constructor
30  to invoke this merging method.
31  '''
32  __handled_types__ = (re.compile(r"^mapMergeNoReplace<.*>$"),)
33  def __init__(self, cpp_type):
34  super(MapMergeNoReplaceSemantics, self).__init__(cpp_type)
35 
36  def merge(self,a,b):
37  for k in b.keys():
38  if k in a and b[k] != a[k]:
39  raise ValueError('conflicting values in map under key %r and %r %r' % (k, b[k], a[k]))
40  a[k] = b[k]
41  return a
42 
43 
44 class VarHandleKeySemantics(GaudiConfig2.semantics.PropertySemantics):
45  '''
46  Semantics for all data handle keys (Read, Write, Decor, Cond).
47  '''
48  __handled_types__ = (re.compile(r"SG::.*HandleKey<.*>$"),)
49 
50  def __init__(self, cpp_type):
51  super().__init__(cpp_type)
52  # Deduce actual handle type
53  self._type = next(GaudiConfig2.semantics.extract_template_args(cpp_type))
54  self._isCond = 'CondHandle' in cpp_type
55 
56  if cpp_type.startswith("SG::Read"):
57  self._mode = "R"
58  elif cpp_type.startswith("SG::Write"):
59  self._mode = "W"
60  else:
61  raise TypeError(f"C++ type {cpp_type} not supported")
62 
63  def store(self, value):
64  if isinstance(value, DataHandle):
65  v = value.Path
66  elif isinstance(value, str):
67  v = value
68  else:
69  raise TypeError(f"cannot assign {value!r} ({type(value)}) to {self.name}"
70  ", expected string or DataHandle")
71  return DataHandle(v, self._mode, self._type, self._isCond)
72 
73 
74 class VarHandleArraySematics(GaudiConfig2.semantics.SequenceSemantics):
75  '''
76  Treat VarHandleKeyArrays like arrays of strings
77  '''
78  __handled_types__ = ("SG::VarHandleKeyArray",)
79 
80  class _ItemSemantics(GaudiConfig2.semantics.StringSemantics):
81  """Semantics for an item (DataHandle) in a VarHandleKeyArray converting to string"""
82 
83  def __init__(self):
84  super().__init__("std::string")
85 
86  def store(self, value):
87  if isinstance(value, DataHandle):
88  return value.Path
89  elif isinstance(value, str):
90  return value
91  else:
92  raise TypeError(f"cannot assign {value!r} ({type(value)}) to {self.name}"
93  ", expected string or DataHandle")
94 
95  def __init__(self, cpp_type):
96  super().__init__(cpp_type, valueSem = self._ItemSemantics())
97 
98  def merge(self,bb,aa):
99  for b in bb:
100  if b not in aa:
101  aa.append(b)
102  return aa
103 
104 
105 class ToolHandleSemantics(GaudiConfig2.semantics.PropertySemantics):
106  '''
107  Private alg-tools need recusive merging (de-duplication):
108  '''
109  __handled_types__ = ("PrivateToolHandle",)
110  def __init__(self,cpp_type):
111  super(ToolHandleSemantics, self).__init__(cpp_type)
112 
113 
114  def merge(self,b,a):
115  #Deal with 'None'
116  if a is None or a=='': return b
117  if b is None or b=='': return a
118  return a.merge(b)
119 
120 class PublicHandleSemantics(GaudiConfig2.semantics.PropertySemantics):
121  '''
122  ServiceHandles (and the deprecated PublicToolHandles) are assigned as strings
123  '''
124  __handled_types__ = ("PublicToolHandle","ServiceHandle")
125 
126  def __init__(self,cpp_type):
127  super(PublicHandleSemantics, self).__init__(cpp_type)
128 
129  def default(self,value):
130  return value.typeAndName
131 
132  def store(self,value):
133  if isinstance(value,str): #Assume the string is correct and the tool/svc alreayd in the CA ...
134  return value
135 
136  if value is None:
137  return ""
138 
139  if not hasattr(value,"__component_type__"):
140  raise TypeError("Got {}, expected Tool or Service in assignment to {}".format(type(value),self.name))
141 
142  if value.__component_type__ not in ('Service','AlgTool'):
143  raise TypeError('{} expected, got {!r} in assignemnt to {}'.\
144  format(value.__component_type__,value, self.name))
145 
146  #It would be great if at this point we could verify that the service was
147  #ineed added to the ComponentAccumulator. Latest, do that when bootstapping
148  #the application
149 
150  return "{}/{}".format(value.__cpp_type__,value.name)
151 
152 class PublicHandleArraySemantics(GaudiConfig2.semantics.PropertySemantics):
153  '''
154  Semantics for arrays of string-based pointers to components defined elsewhere
155  '''
156  __handled_types__ = ("PublicToolHandleArray","ServiceHandleArray")
157  def __init__(self,cpp_type):
158  super(PublicHandleArraySemantics, self).__init__(cpp_type)
159 
160  def store(self, value):
161  if not isinstance(value,Sequence) and not isinstance(value,set):
162  value=[value,]
163 
164  newValue=[]
165  for v in value:
166  if isinstance(v,GaudiConfig2._configurables.Configurable):
167  if v.__component_type__ not in ('Service','AlgTool'):
168  raise TypeError('{} expected, got {!r} in assignemnt to {}'.\
169  format(value.__component_type__,v, self.name))
170  else:
171  newValue.append("{}/{}".format(v.__cpp_type__,v.name))
172 
173  elif isinstance(v,(PublicToolHandle,ServiceHandle)):
174  newValue.append("{}/{}".format(v.getType(),v.getName()))
175 
176  elif isinstance(v,str):
177  #Check if component is known ...
178  newValue.append(v)
179  pass
180  else:
181  raise TypeError('Configurable expected, got {!r} in assignment to {}'.\
182  format(v,self.name))
183  return newValue
184 
185  def default(self, value):
186  return copy.copy(value)
187 
188 
189  def merge(self,bb,aa):
190  for b in bb:
191  if b not in aa:
192  aa.append(b)
193  return aa
194  #union=set(a) | set(b)
195  #return union
196 
197 
198 class ToolHandleArraySemantics(GaudiConfig2.semantics.PropertySemantics):
199  '''
200  Private alg-tools need recusive merging (de-duplication):
201  '''
202  __handled_types__ = ("PrivateToolHandleArray",)
203  def __init__(self,cpp_type):
204  super(ToolHandleArraySemantics, self).__init__(cpp_type)
205 
206  def default(self,value):
207  return copy.copy(value)
208 
209  def store(self,value):
210  if not isinstance(value,PrivateToolHandleArray):
211  #try to convert the value to a PrivateToolHandleArray
212  value=PrivateToolHandleArray(value)
213  return value
214 
215  def merge(self,b,a):
216  for bTool in b:
217  try:
218  #If a tool with that name exists in a, we'll merge it
219  a.__getitem__(bTool.getName()).merge(bTool)
220  except IndexError:
221  #Tool does not exists in a, append it
222  a.append(bTool)
223  return a
224 
225 class SubAlgoSemantics(GaudiConfig2.semantics.PropertySemantics):
226  __handled_types__ = ("SubAlgorithm",)
227  def __init__(self,cpp_type):
228  super(SubAlgoSemantics, self).__init__(cpp_type)
229 
230  def store(self,value):
231  if not isinstance(value,Sequence):
232  value=[value,]
233 
234  for v in value:
235  if v.__component_type__ != 'Algorithm':
236  raise TypeError('Algorithm expected, got {!r} in assignemnt to {}'.\
237  format(value, self.name))
238  return value
239 
240 
241  #Without explicitly definig a default, calling .append or += will change the class-default,
242  #affecting all instances of the same class.
243  def default(self,value):
244  return []
245 
246 
247 from AthenaServices.ItemListSemantics import OutputStreamItemListSemantics
248 
249 GaudiConfig2.semantics.SEMANTICS.append(AppendListSemantics)
250 GaudiConfig2.semantics.SEMANTICS.append(VarHandleKeySemantics)
251 GaudiConfig2.semantics.SEMANTICS.append(VarHandleArraySematics)
252 GaudiConfig2.semantics.SEMANTICS.append(ToolHandleSemantics)
253 GaudiConfig2.semantics.SEMANTICS.append(ToolHandleArraySemantics)
254 GaudiConfig2.semantics.SEMANTICS.append(PublicHandleSemantics)
255 GaudiConfig2.semantics.SEMANTICS.append(PublicHandleArraySemantics)
256 GaudiConfig2.semantics.SEMANTICS.append(SubAlgoSemantics)
257 GaudiConfig2.semantics.SEMANTICS.append(MapMergeNoReplaceSemantics)
258 GaudiConfig2.semantics.SEMANTICS.append(OutputStreamItemListSemantics)
python.AtlasSemantics.AppendListSemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:19
vtune_athena.format
format
Definition: vtune_athena.py:14
python.AtlasSemantics.AppendListSemantics.merge
def merge(self, b, a)
Definition: AtlasSemantics.py:22
python.AtlasSemantics.VarHandleKeySemantics._type
_type
Definition: AtlasSemantics.py:53
python.AtlasSemantics.VarHandleKeySemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:50
python.AtlasSemantics.MapMergeNoReplaceSemantics.merge
def merge(self, a, b)
Definition: AtlasSemantics.py:36
python.AtlasSemantics.SubAlgoSemantics.store
def store(self, value)
Definition: AtlasSemantics.py:230
python.AtlasSemantics.VarHandleArraySematics._ItemSemantics.__init__
def __init__(self)
Definition: AtlasSemantics.py:83
python.AtlasSemantics.SubAlgoSemantics.default
def default(self, value)
Definition: AtlasSemantics.py:243
python.AtlasSemantics.PublicHandleArraySemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:157
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
python.AtlasSemantics.PublicHandleSemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:126
python.AtlasSemantics.SubAlgoSemantics
Definition: AtlasSemantics.py:225
python.AtlasSemantics.MapMergeNoReplaceSemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:33
python.AtlasSemantics.ToolHandleArraySemantics.store
def store(self, value)
Definition: AtlasSemantics.py:209
python.AtlasSemantics.MapMergeNoReplaceSemantics
Definition: AtlasSemantics.py:26
python.AtlasSemantics.AppendListSemantics
Definition: AtlasSemantics.py:11
python.AtlasSemantics.ToolHandleArraySemantics
Definition: AtlasSemantics.py:198
python.AtlasSemantics.PublicHandleSemantics.store
def store(self, value)
Definition: AtlasSemantics.py:132
python.AtlasSemantics.PublicHandleArraySemantics.store
def store(self, value)
Definition: AtlasSemantics.py:160
python.AtlasSemantics.PublicHandleArraySemantics.default
def default(self, value)
Definition: AtlasSemantics.py:185
python.AtlasSemantics.VarHandleArraySematics.merge
def merge(self, bb, aa)
Definition: AtlasSemantics.py:98
python.AtlasSemantics.VarHandleArraySematics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:95
python.AtlasSemantics.ToolHandleArraySemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:203
python.AtlasSemantics.PublicHandleArraySemantics.merge
def merge(self, bb, aa)
Definition: AtlasSemantics.py:189
python.AtlasSemantics.VarHandleKeySemantics._isCond
_isCond
Definition: AtlasSemantics.py:54
python.AtlasSemantics.VarHandleArraySematics._ItemSemantics
Definition: AtlasSemantics.py:80
python.AtlasSemantics.VarHandleKeySemantics
Definition: AtlasSemantics.py:44
python.AtlasSemantics.ToolHandleSemantics.merge
def merge(self, b, a)
Definition: AtlasSemantics.py:114
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
python.AtlasSemantics.VarHandleKeySemantics._mode
_mode
Definition: AtlasSemantics.py:57
python.AtlasSemantics.ToolHandleSemantics
Definition: AtlasSemantics.py:105
python.AtlasSemantics.PublicHandleSemantics
Definition: AtlasSemantics.py:120
python.AtlasSemantics.VarHandleArraySematics._ItemSemantics.store
def store(self, value)
Definition: AtlasSemantics.py:86
python.AtlasSemantics.ToolHandleArraySemantics.default
def default(self, value)
Definition: AtlasSemantics.py:206
python.AtlasSemantics.PublicHandleSemantics.default
def default(self, value)
Definition: AtlasSemantics.py:129
python.AtlasSemantics.ToolHandleArraySemantics.merge
def merge(self, b, a)
Definition: AtlasSemantics.py:215
python.AtlasSemantics.VarHandleKeySemantics.store
def store(self, value)
Definition: AtlasSemantics.py:63
python.AtlasSemantics.VarHandleArraySematics
Definition: AtlasSemantics.py:74
python.AtlasSemantics.PublicHandleArraySemantics
Definition: AtlasSemantics.py:152
python.AtlasSemantics.ToolHandleSemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:110
merge
Definition: merge.py:1
python.AtlasSemantics.SubAlgoSemantics.__init__
def __init__(self, cpp_type)
Definition: AtlasSemantics.py:227