ATLAS Offline Software
Classes | Functions | Variables
python.iconfTool.models.loaders Namespace Reference

Classes

class  ComponentsDiffFileLoader
 
class  ComponentsFileLoader
 

Functions

def __flatten_list (l)
 
def types_in_properties (comp_name, value, dict_to_update)
 
def collect_types (conf)
 
Dict excludeIncludeComps (dic, args, depth, compsToFollow=[])
 
Dict ignoreIrrelevant (dic, args)
 
Dict renameComps (dic, args)
 
Dict ignoreDefaults (allconf, args, known)
 
Dict shortenDefaultComponents (dic, args)
 
list isReference (value, compname, conf, svcCache={})
 
Dict skipProperties (conf, args)
 
Dict loadConfigFile (fname, args)
 
Dict loadDifferencesFile (fname)
 

Variables

 logger
 
 level
 
 mode
 
 componentRenamingDict
 
 baseParser
 
string nargs = "*",
 
list default = [],
 
string help = "Include only components matching (regex) this string",
 
string action = "append",
 
 type = int,
 

Function Documentation

◆ __flatten_list()

def python.iconfTool.models.loaders.__flatten_list (   l)
private

Definition at line 113 of file loaders.py.

113 def __flatten_list(l):
114  return [item for elem in l for item in elem] if l else []
115 
116 

◆ collect_types()

def python.iconfTool.models.loaders.collect_types (   conf)

Definition at line 146 of file loaders.py.

146 def collect_types(conf):
147  name_to_type = {}
148  for (comp_name, comp_settings) in conf.items():
149  types_in_properties(comp_name, comp_settings, name_to_type)
150  return name_to_type
151 
152 

◆ excludeIncludeComps()

Dict python.iconfTool.models.loaders.excludeIncludeComps (   dic,
  args,
  depth,
  compsToFollow = [] 
)

Definition at line 153 of file loaders.py.

153 def excludeIncludeComps(dic, args, depth, compsToFollow=[]) -> Dict:
154  conf = {}
155  if depth == 0:
156  return conf
157  compsToInclude = __flatten_list(args.includeComps)
158  compsToExclude = __flatten_list(args.excludeComps)
159 
160  def eligible(component):
161  exclude = any(re.match(s, component) for s in compsToExclude)
162  if (component in compsToFollow or component.removeprefix("ToolSvc.") in compsToFollow) and not (exclude or component in args.ignore):
163  logger.debug("Considering this component: %s because some other one depends on it", component)
164  return True
165  include = any(re.match(s, component) for s in compsToInclude)
166  if args.includeComps and args.excludeComps:
167  return include and not exclude
168  elif args.includeComps:
169  return include
170  elif args.excludeComps:
171  return not exclude
172 
173  for (comp_name, comp_attributes) in dic.items():
174  if eligible(comp_name):
175  conf[comp_name] = comp_attributes
176  if depth > 0:
177  types = {}
178  types_in_properties(comp_attributes, types, compsToFollow)
179  logger.debug("Following up for types included in here %s whole set of components to follow %s ", types, compsToFollow)
180  compsToFollow += types.keys()
181  logger.debug("Included component %s", comp_name)
182  else:
183  logger.debug("Ignored component %s", comp_name)
184  if depth > 0:
185  conf.update(excludeIncludeComps(dic, args, depth-1, compsToFollow))
186  return conf
187 

◆ ignoreDefaults()

Dict python.iconfTool.models.loaders.ignoreDefaults (   allconf,
  args,
  known 
)

Definition at line 249 of file loaders.py.

249 def ignoreDefaults(allconf, args, known) -> Dict:
250  conf = {}
251  def drop_defaults(component_name, val_dict):
252  # try picking the name from the dict, if missing use last part of the name, if that fails use the component_name (heuristic)
253  component_name_last_part = component_name.split(".")[-1]
254  component_type = known.get(component_name, known.get(component_name_last_part, component_name_last_part))
255  comp_cls = None
256  try:
257  from AthenaConfiguration.ComponentFactory import CompFactory
258  comp_cls = CompFactory.getComp(component_type)
259  logger.debug("Loaded the configuration class %s/%s for defaults elimination", component_type, component_name)
260  except Exception:
261  logger.debug("Could not find the configuration class %s/%s, no defaults for it can be eliminated", component_type, component_name)
262  return val_dict
263  c = {}
264 
265  for k,v in val_dict.items():
266  if not hasattr(comp_cls,'_descriptors'):
267  logger.debug('No \'_descriptors\' attibute for %s', comp_cls)
268  continue
269  if k not in comp_cls._descriptors: # property not in descriptors (for instance, removed from component now)
270  c[k] = v
271  else:
272  default = str(comp_cls._descriptors[k].default)
273  sv = str(v)
274  if (default == sv or
275  default.replace("StoreGateSvc+", "") == sv.replace("StoreGateSvc+", "") or
276  default.replace("ConditionStore+", "") == sv.replace("ConditionStore+", "")):
277  logger.debug("Dropped default value \'%s\' of property %s in %s because the default is \'%s\'", sv, k, component_name, str(default))
278  elif args.ignoreDefaultNamedComps and isinstance(v, str) and sv.endswith(f"/{default}"):
279  logger.debug("Dropped speculatively value %s of property %s in %s because the default it ends with %s", sv, k, component_name, str(default))
280  else:
281  c[k] = v
282  logger.debug("Keep value %s of property %s in %s because it is different from default %s", str(v), str(k), component_name, str(comp_cls._descriptors[k].default))
283  return c
284 
285  # collect types for all components (we look for A/B or lost of A/B strings)
286  for (comp_name, comp_settings) in allconf.items():
287  remaining = drop_defaults(comp_name, comp_settings)
288  if len(remaining) != 0: # ignore components that have only default settings
289  conf[comp_name] = remaining
290  return conf
291 

◆ ignoreIrrelevant()

Dict python.iconfTool.models.loaders.ignoreIrrelevant (   dic,
  args 
)

Definition at line 188 of file loaders.py.

188 def ignoreIrrelevant(dic, args) -> Dict:
189  def remove_irrelevant(val_dict):
190  return (
191  { key: val for key, val in val_dict.items() if key not in args.ignore }
192  if isinstance(val_dict, dict)
193  else val_dict
194  )
195  conf = {}
196  for (key, value) in dic.items():
197  conf[key] = remove_irrelevant(value)
198  return conf
199 

◆ isReference()

list python.iconfTool.models.loaders.isReference (   value,
  compname,
  conf,
  svcCache = {} 
)
Returns a list of (component,class) if value stores reference to other components
   value - the value to check
   compname - full component name
   conf - complete config dict

Definition at line 322 of file loaders.py.

322 def isReference(value, compname, conf, svcCache={}) -> list:
323  """Returns a list of (component,class) if value stores reference to other components
324  value - the value to check
325  compname - full component name
326  conf - complete config dict
327  """
328 
329  def _getSvcClass(instance):
330  """Find instance in service lists to get class.
331  Keeps a cache of the service classes in the svcCache default value.
332  That's fine, unless we are dealing with more than one conf in the program.
333  In that case, initialise svcCache to {} and specify in the caller."""
334  if not svcCache: # only scan ApplicationMgr once
335  props = conf.get('ApplicationMgr',{"":None})
336  if isinstance(props,dict):
337  for prop,val in props.items():
338  if 'Svc' in prop:
339  try:
340  val = ast.literal_eval(str(val))
341  except Exception:
342  pass
343  if isinstance(val,list):
344  for v in val:
345  if isinstance(v,str):
346  vv = v.split('/')
347  if len(vv) == 2:
348  if svcCache.setdefault(vv[1], vv[0]) != vv[0]:
349  svcCache[vv[1]] = None # fail if same instance, different class
350  return svcCache.get(instance)
351 
352  try:
353  value = ast.literal_eval(str(value))
354  except Exception:
355  pass
356 
357  if isinstance(value, str):
358  ctype_name = value.split('/')
359  cls = ctype_name[0] if len(ctype_name) == 2 else None
360  instance = ctype_name[-1]
361  ref = None
362  if instance:
363  if compname and f"{compname}.{instance}" in conf: # private tool
364  ref = f"{compname}.{instance}"
365  elif f"ToolSvc.{instance}" in conf: # public tool
366  ref = f"ToolSvc.{instance}"
367  elif cls is not None or instance in conf: # service or other component
368  ref = instance
369  if cls is None:
370  cls = _getSvcClass(instance)
371  if ref is not None:
372  return [(ref, cls)]
373 
374  elif isinstance(value, list):
375  refs = [isReference(el, compname, conf) for el in value]
376  if any(refs):
377  flattened = []
378  [flattened.extend(el) for el in refs if el]
379  return flattened
380  return []
381 
382 

◆ loadConfigFile()

Dict python.iconfTool.models.loaders.loadConfigFile (   fname,
  args 
)
loads config file into a dictionary, supports several modifications of the input switched on via additional arguments
Supports reading: Pickled file with the CA or properties & JSON

Definition at line 395 of file loaders.py.

395 def loadConfigFile(fname, args) -> Dict:
396  """loads config file into a dictionary, supports several modifications of the input switched on via additional arguments
397  Supports reading: Pickled file with the CA or properties & JSON
398  """
399  if args.debug:
400  print("Debugging info from reading ", fname, " in ", logger.handlers[0].baseFilename)
401  logger.setLevel(logging.DEBUG)
402 
403  conf = {}
404  if fname.endswith(".pkl"):
405  with open(fname, "rb") as input_file:
406  # determine if there is a old or new configuration pickled
407  cfg = pickle.load(input_file)
408  logger.info("... Read %s from %s", cfg.__class__.__name__, fname)
409  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
410  if isinstance(cfg, ComponentAccumulator): # new configuration
411  props = cfg.gatherProps()
412  # to make json compatible with old configuration
413  jos_props = props[2]
414  to_json = {}
415  for comp, name, value in jos_props:
416  to_json.setdefault(comp, {})[name] = value
417  to_json[comp][name] = value
418  conf.update(to_json)
419  conf['ApplicationMgr'] = props[0]
420  conf['MessageSvc'] = props[1]
421 
422  elif isinstance(
423  cfg, (collections.defaultdict, dict)
424  ): # old configuration
425  conf.update(cfg)
426  conf.update(pickle.load(input_file)) # special services
427  # FIXME: there's a third pickle object with python components
428  elif isinstance(cfg, (collections.Sequence)):
429  for c in cfg:
430  conf.update(c)
431  logger.info("... Read %d items from python pickle file: %s", len(conf), fname)
432 
433  elif fname.endswith(".json"):
434 
435  def __keepPlainStrings(element):
436  if isinstance(element, str):
437  return str(element)
438  if isinstance(element, list):
439  return [__keepPlainStrings(x) for x in element]
440  if isinstance(element, dict):
441  return {
442  __keepPlainStrings(key): __keepPlainStrings(value)
443  for key, value in element.items()
444  }
445  return element
446 
447  with open(fname, "r") as input_file:
448  cfg = json.load(input_file, object_hook=__keepPlainStrings)
449  for c in cfg:
450  conf.update(cfg)
451 
452  # For compatibility with HLTJobOptions json, which produces structure:
453  # {
454  # "filetype": "joboptions",
455  # "properties": { the thing we are interested in}
456  # }
457  if 'properties' in conf:
458  conf = conf['properties']
459 
460  logger.info("... Read %d items from json file: %s", len(conf), fname)
461 
462  else:
463  sys.exit("File format not supported.")
464 
465  if conf is None:
466  sys.exit("Unable to load %s file" % fname)
467 
468  if args.includeComps or args.excludeComps or args.includeClasses or args.excludeClasses:
469  logger.info(f"include/exclude comps like {args.includeComps}/{args.excludeComps}")
470  conf = excludeIncludeComps(conf, args, args.follow)
471 
472  if args.ignoreIrrelevant:
473  conf = ignoreIrrelevant(conf, args)
474 
475  if args.renameComps or args.renameCompsFile:
476  conf = renameComps(conf, args)
477 
478  if args.ignoreDefaults:
479  known_types = collect_types(conf)
480  conf = ignoreDefaults(conf, args, known_types)
481 
482  if args.shortenDefaultComponents:
483  conf = shortenDefaultComponents(conf, args)
484 
485  if args.skipProperties:
486  conf = skipProperties(conf, args)
487  return conf
488 

◆ loadDifferencesFile()

Dict python.iconfTool.models.loaders.loadDifferencesFile (   fname)
Read differences file
Format:
full_component_name.property oldvalue=newvalue
example:
AlgX.ToolA.SubToolB.SettingZ 45=46
It is possible to specify missing values, e.g:
AlgX.ToolA.SubToolB.SettingZ 45=    means that now the old value should be ignored
AlgX.ToolA.SubToolB.SettingZ =46    means that now the new value should be ignored
AlgX.ToolA.SubToolB.SettingZ =      means that any change of the value should be ignored 

Definition at line 584 of file loaders.py.

584 def loadDifferencesFile(fname) -> Dict:
585  """
586  Read differences file
587  Format:
588  full_component_name.property oldvalue=newvalue
589  example:
590  AlgX.ToolA.SubToolB.SettingZ 45=46
591  It is possible to specify missing values, e.g:
592  AlgX.ToolA.SubToolB.SettingZ 45= means that now the old value should be ignored
593  AlgX.ToolA.SubToolB.SettingZ =46 means that now the new value should be ignored
594  AlgX.ToolA.SubToolB.SettingZ = means that any change of the value should be ignored
595 
596  """
597  from collections import defaultdict
598  differences = defaultdict(dict)
599  count=0
600  with open(fname, "r") as f:
601  for line in f:
602  if line[0] == "#" or line == "\n":
603  continue
604  line = line.strip()
605  compAndProp, values = line.split(" ")
606  comp, prop = compAndProp.rsplit(".", 1)
607  o,n = values.split("=")
608  oldval,newval = o if o else None, n if n else None
609 
610  differences[comp][prop] = (oldval,newval)
611  count+=1
612  logger.info("... Read %d known differences from file: %s", count, fname)
613  logger.info("..... %s", str(differences))
614 
615  return differences
616 

◆ renameComps()

Dict python.iconfTool.models.loaders.renameComps (   dic,
  args 
)

Definition at line 200 of file loaders.py.

200 def renameComps(dic, args) -> Dict:
201  compsToRename = __flatten_list(args.renameComps)
202  if args.renameCompsFile:
203  with open( args.renameCompsFile, "r") as refile:
204  for line in refile:
205  if not (line.startswith("#") or line.isspace() ):
206  compsToRename.append( line.rstrip('\n') )
207  global componentRenamingDict
208  componentRenamingDict.update({
209  old_name: new_name
210  for old_name, new_name in [
211  [e.strip() for e in element.split("=")] for element in compsToRename
212  ]
213  })
214  for f,t in componentRenamingDict.items():
215  logger.info("Renaming from: %s to %s", f, t)
216 
217  def rename_comps(comp_name):
218  """Renames component if it is in the dict or, when name fragment is in the dict
219  The later is for cases like: ToolSvc.ToolA.X.Y is renamed to ToolSvc.ToolB.X.Y
220  """
221  logger.debug("Trying renaming on, %s", comp_name)
222  for k,v in componentRenamingDict.items():
223  if k == comp_name:
224 # logger.debug("Renamed comp %s to %s", k, v)
225  return v
226 
227  old = f".{k}."
228  if old in comp_name:
229  return comp_name.replace(old, f".{v}.")
230 
231  old = f"{k}."
232  if comp_name.startswith(old):
233  return comp_name.replace(old, f"{v}.")
234 
235 
236  old = f".{k}"
237  if comp_name.endswith(old):
238  return comp_name.replace(old, f".{k}")
239  return comp_name
240 
241  conf = {}
242  for (key, value) in dic.items():
243  renamed = rename_comps(key)
244  if renamed != key:
245  logger.debug("Renamed comp %s to %s", key, renamed)
246  conf[renamed] = value
247  return conf
248 

◆ shortenDefaultComponents()

Dict python.iconfTool.models.loaders.shortenDefaultComponents (   dic,
  args 
)

Definition at line 292 of file loaders.py.

292 def shortenDefaultComponents(dic, args) -> Dict:
293  conf = {}
294  def shorten(val):
295  value = val
296  # the value can possibly be a serialized object (like a list)
297  try:
298  value = ast.literal_eval(str(value))
299  except Exception:
300  pass
301 
302  if isinstance(value, str):
303  svalue = value.split("/")
304  if len(svalue) == 2 and svalue[0] == svalue[1]:
305  logger.debug("Shortened %s", svalue)
306  return svalue[0]
307  if isinstance(value, list):
308  return [shorten(el) for el in value]
309  if isinstance(value, dict):
310  return shorten_defaults(value)
311 
312  return value
313 
314  def shorten_defaults(val_dict):
315  if isinstance(val_dict, dict):
316  return { key: shorten(val) for key,val in val_dict.items() }
317 
318  for (key, value) in dic.items():
319  conf[key] = shorten_defaults(value)
320  return conf
321 

◆ skipProperties()

Dict python.iconfTool.models.loaders.skipProperties (   conf,
  args 
)

Definition at line 383 of file loaders.py.

383 def skipProperties(conf, args) -> Dict:
384  updated = {}
385  for (name, properties) in conf.items():
386  updated[name] = {}
387  if not isinstance(properties, dict): # keep it
388  updated[name] = properties
389  else:
390  for property_name, value in properties.items():
391  if isReference( value, name, conf) or property_name == 'Members': # later for sequences structure
392  updated[name][property_name] = value
393  return updated
394 

◆ types_in_properties()

def python.iconfTool.models.loaders.types_in_properties (   comp_name,
  value,
  dict_to_update 
)
Updates the dictionary with (potentially) component name -> component type

Definition at line 117 of file loaders.py.

117 def types_in_properties(comp_name, value, dict_to_update):
118  """Updates the dictionary with (potentially) component name -> component type"""
119  parsable = False
120  try:
121  s = ast.literal_eval(str(value))
122  parsable = True
123  if isinstance(s, list):
124  for el in s:
125  types_in_properties(comp_name, el, dict_to_update)
126  except Exception:
127  pass
128  # Exclude non-strings, or strings that look like paths rather than type/name pairs
129  if isinstance(value,str):
130  slash_startend = value.startswith("/") or value.endswith("/")
131  json_dict = value.startswith("{") and value.endswith("}")
132  if value.count("/")==1 and not parsable and not slash_startend and not json_dict:
133  comp = value.split("/")
134  if len(comp) == 2:
135  # Record with and without parent
136  dict_to_update[f'{comp_name}.{comp[1]}'] = comp[0]
137  dict_to_update[f'{comp[1]}'] = comp[0]
138  logger.debug("Parsing %s, found type of %s.%s to be %s", value, comp_name, comp[1], comp[0])
139  else:
140  logger.debug("What is typeless comp? %s", value)
141  if isinstance(value, dict):
142  for v in value.values():
143  types_in_properties(comp_name, v, dict_to_update)
144 
145 

Variable Documentation

◆ action

string python.iconfTool.models.loaders.action = "append",

Definition at line 31 of file loaders.py.

◆ baseParser

python.iconfTool.models.loaders.baseParser

Definition at line 25 of file loaders.py.

◆ componentRenamingDict

python.iconfTool.models.loaders.componentRenamingDict

Definition at line 23 of file loaders.py.

◆ default

int python.iconfTool.models.loaders.default = [],

Definition at line 29 of file loaders.py.

◆ help

string python.iconfTool.models.loaders.help = "Include only components matching (regex) this string",

Definition at line 30 of file loaders.py.

◆ level

python.iconfTool.models.loaders.level

Definition at line 20 of file loaders.py.

◆ logger

python.iconfTool.models.loaders.logger

Definition at line 19 of file loaders.py.

◆ mode

python.iconfTool.models.loaders.mode

Definition at line 21 of file loaders.py.

◆ nargs

string python.iconfTool.models.loaders.nargs = "*",

Definition at line 28 of file loaders.py.

◆ type

python.iconfTool.models.loaders.type = int,

Definition at line 103 of file loaders.py.

python.iconfTool.models.loaders.ignoreDefaults
Dict ignoreDefaults(allconf, args, known)
Definition: loaders.py:249
python.iconfTool.models.loaders.collect_types
def collect_types(conf)
Definition: loaders.py:146
python.iconfTool.models.loaders.shortenDefaultComponents
Dict shortenDefaultComponents(dic, args)
Definition: loaders.py:292
python.iconfTool.models.loaders.__flatten_list
def __flatten_list(l)
Definition: loaders.py:113
python.iconfTool.models.loaders.types_in_properties
def types_in_properties(comp_name, value, dict_to_update)
Definition: loaders.py:117
python.iconfTool.models.loaders.skipProperties
Dict skipProperties(conf, args)
Definition: loaders.py:383
python.iconfTool.models.loaders.renameComps
Dict renameComps(dic, args)
Definition: loaders.py:200
python.iconfTool.models.loaders.isReference
list isReference(value, compname, conf, svcCache={})
Definition: loaders.py:322
python.iconfTool.models.loaders.excludeIncludeComps
Dict excludeIncludeComps(dic, args, depth, compsToFollow=[])
Definition: loaders.py:153
python.iconfTool.models.loaders.ignoreIrrelevant
Dict ignoreIrrelevant(dic, args)
Definition: loaders.py:188
Trk::open
@ open
Definition: BinningType.h:40
python.iconfTool.models.loaders.loadDifferencesFile
Dict loadDifferencesFile(fname)
Definition: loaders.py:584
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
str
Definition: BTagTrackIpAccessor.cxx:11
python.iconfTool.models.loaders.loadConfigFile
Dict loadConfigFile(fname, args)
Definition: loaders.py:395