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 128 of file loaders.py.

128 def __flatten_list(l):
129  return [item for elem in l for item in elem] if l else []
130 
131 

◆ collect_types()

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

Definition at line 161 of file loaders.py.

161 def collect_types(conf):
162  name_to_type = {}
163  for (comp_name, comp_settings) in conf.items():
164  types_in_properties(comp_name, comp_settings, name_to_type)
165  return name_to_type
166 
167 

◆ excludeIncludeComps()

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

Definition at line 168 of file loaders.py.

168 def excludeIncludeComps(dic, args, depth, compsToFollow=[]) -> Dict:
169  conf = {}
170  if depth == 0:
171  return conf
172  compsToInclude = __flatten_list(args.includeComps)
173  compsToExclude = __flatten_list(args.excludeComps)
174 
175  def eligible(component):
176  exclude = any(re.match(s, component) for s in compsToExclude)
177  if (component in compsToFollow or component.removeprefix("ToolSvc.") in compsToFollow) and not (exclude or component in args.ignore):
178  logger.debug("Considering this component: %s because some other one depends on it", component)
179  return True
180  include = any(re.match(s, component) for s in compsToInclude)
181  if args.includeComps and args.excludeComps:
182  return include and not exclude
183  elif args.includeComps:
184  return include
185  elif args.excludeComps:
186  return not exclude
187 
188  for (comp_name, comp_attributes) in dic.items():
189  if eligible(comp_name):
190  conf[comp_name] = comp_attributes
191  if depth > 0:
192  types = {}
193  types_in_properties(comp_attributes, types, compsToFollow)
194  logger.debug("Following up for types included in here %s whole set of components to follow %s ", types, compsToFollow)
195  compsToFollow += types.keys()
196  logger.debug("Included component %s", comp_name)
197  else:
198  logger.debug("Ignored component %s", comp_name)
199  if depth > 0:
200  conf.update(excludeIncludeComps(dic, args, depth-1, compsToFollow))
201  return conf
202 

◆ ignoreDefaults()

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

Definition at line 263 of file loaders.py.

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

◆ ignoreIrrelevant()

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

Definition at line 203 of file loaders.py.

203 def ignoreIrrelevant(dic, args) -> Dict:
204  def remove_irrelevant(val_dict):
205  return (
206  { key: val for key, val in val_dict.items() if key not in args.ignore }
207  if isinstance(val_dict, dict)
208  else val_dict
209  )
210  conf = {}
211  for (key, value) in dic.items():
212  conf[key] = remove_irrelevant(value)
213  return conf
214 

◆ 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 336 of file loaders.py.

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

◆ 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 409 of file loaders.py.

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

◆ 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 598 of file loaders.py.

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

◆ renameComps()

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

Definition at line 215 of file loaders.py.

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

◆ shortenDefaultComponents()

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

Definition at line 306 of file loaders.py.

306 def shortenDefaultComponents(dic, args) -> Dict:
307  conf = {}
308  def shorten(val):
309  value = val
310  # the value can possibly be a serialized object (like a list)
311  try:
312  value = ast.literal_eval(str(value))
313  except Exception:
314  pass
315 
316  if isinstance(value, str):
317  svalue = value.split("/")
318  if len(svalue) == 2 and svalue[0] == svalue[1]:
319  logger.debug("Shortened %s", svalue)
320  return svalue[0]
321  if isinstance(value, list):
322  return [shorten(el) for el in value]
323  if isinstance(value, dict):
324  return shorten_defaults(value)
325 
326  return value
327 
328  def shorten_defaults(val_dict):
329  if isinstance(val_dict, dict):
330  return { key: shorten(val) for key,val in val_dict.items() }
331 
332  for (key, value) in dic.items():
333  conf[key] = shorten_defaults(value)
334  return conf
335 

◆ skipProperties()

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

Definition at line 397 of file loaders.py.

397 def skipProperties(conf, args) -> Dict:
398  updated = {}
399  for (name, properties) in conf.items():
400  updated[name] = {}
401  if not isinstance(properties, dict): # keep it
402  updated[name] = properties
403  else:
404  for property_name, value in properties.items():
405  if isReference( value, name, conf) or property_name == 'Members': # later for sequences structure
406  updated[name][property_name] = value
407  return updated
408 

◆ 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 132 of file loaders.py.

132 def types_in_properties(comp_name, value, dict_to_update):
133  """Updates the dictionary with (potentially) component name -> component type"""
134  parsable = False
135  try:
136  s = ast.literal_eval(str(value))
137  parsable = True
138  if isinstance(s, list):
139  for el in s:
140  types_in_properties(comp_name, el, dict_to_update)
141  except Exception:
142  pass
143  # Exclude non-strings, or strings that look like paths rather than type/name pairs
144  if isinstance(value,str):
145  slash_startend = value.startswith("/") or value.endswith("/")
146  json_dict = value.startswith("{") and value.endswith("}")
147  if value.count("/")==1 and not parsable and not slash_startend and not json_dict:
148  comp = value.split("/")
149  if len(comp) == 2:
150  # Record with and without parent
151  dict_to_update[f'{comp_name}.{comp[1]}'] = comp[0]
152  dict_to_update[f'{comp[1]}'] = comp[0]
153  logger.debug("Parsing %s, found type of %s.%s to be %s", value, comp_name, comp[1], comp[0])
154  else:
155  logger.debug("What is typeless comp? %s", value)
156  if isinstance(value, dict):
157  for v in value.values():
158  types_in_properties(comp_name, v, dict_to_update)
159 
160 

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 118 of file loaders.py.

python.iconfTool.models.loaders.ignoreDefaults
Dict ignoreDefaults(allconf, args, known)
Definition: loaders.py:263
python.iconfTool.models.loaders.collect_types
def collect_types(conf)
Definition: loaders.py:161
python.iconfTool.models.loaders.shortenDefaultComponents
Dict shortenDefaultComponents(dic, args)
Definition: loaders.py:306
python.iconfTool.models.loaders.__flatten_list
def __flatten_list(l)
Definition: loaders.py:128
python.iconfTool.models.loaders.types_in_properties
def types_in_properties(comp_name, value, dict_to_update)
Definition: loaders.py:132
python.iconfTool.models.loaders.skipProperties
Dict skipProperties(conf, args)
Definition: loaders.py:397
python.iconfTool.models.loaders.renameComps
Dict renameComps(dic, args)
Definition: loaders.py:215
python.iconfTool.models.loaders.isReference
list isReference(value, compname, conf, svcCache={})
Definition: loaders.py:336
python.iconfTool.models.loaders.excludeIncludeComps
Dict excludeIncludeComps(dic, args, depth, compsToFollow=[])
Definition: loaders.py:168
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
python.iconfTool.models.loaders.ignoreIrrelevant
Dict ignoreIrrelevant(dic, args)
Definition: loaders.py:203
Trk::open
@ open
Definition: BinningType.h:40
python.iconfTool.models.loaders.loadDifferencesFile
Dict loadDifferencesFile(fname)
Definition: loaders.py:598
str
Definition: BTagTrackIpAccessor.cxx:11
python.iconfTool.models.loaders.loadConfigFile
Dict loadConfigFile(fname, args)
Definition: loaders.py:409