ATLAS Offline Software
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
python.AthConfigFlags.AthConfigFlags Class Reference
Inheritance diagram for python.AthConfigFlags.AthConfigFlags:
Collaboration diagram for python.AthConfigFlags.AthConfigFlags:

Public Member Functions

def __init__ (self)
 
def athHash (self)
 
def __hash__ (self)
 
def __getattr__ (self, name)
 
def __setattr__ (self, name, value)
 
def __delattr__ (self, name)
 
def __getitem__ (self, name)
 
def __setitem__ (self, name, value)
 
def __delitem__ (self, name)
 
def __iter__ (self)
 
def asdict (self)
 
def addFlag (self, name, setDef, type=None, help=None)
 
def addFlagsCategory (self, path, generator, prefix=False)
 
def needFlagsCategory (self, name)
 
def loadAllDynamicFlags (self)
 
def hasCategory (self, name)
 
def hasFlag (self, name)
 
def __call__ (self, name)
 
def lock (self)
 
def locked (self)
 
def clone (self)
 
def cloneAndReplace (self, subsetToReplace, replacementSubset, keepOriginal=False)
 
def join (self, other, prefix='')
 
def dump (self, pattern=".*", evaluate=False, formatStr="{:40} : {}", maxLength=None)
 
def initAll (self)
 
def getArgumentParser (self, **kwargs)
 
def parser (self)
 
def args (self)
 
def fillFromString (self, flag_string)
 
def fillFromArgs (self, listOfArgs=None, parser=None)
 

Static Public Attributes

 print_context
 

Private Member Functions

def _calculateHash (self)
 
def _renamed_map (self)
 
def _subflag_itr (self)
 
def _loadDynaFlags (self, name)
 
def _set (self, name, value)
 
def _get (self, name)
 
def _tryModify (self)
 

Private Attributes

 _flagdict
 
 _locked
 
 _dynaflags
 
 _loaded
 
 _categoryCache
 
 _hash
 
 _parser
 
 _args
 
 _renames
 

Static Private Attributes

list _hashedFlags = []
 

Detailed Description

Definition at line 219 of file AthConfigFlags.py.

Constructor & Destructor Documentation

◆ __init__()

def python.AthConfigFlags.AthConfigFlags.__init__ (   self)

Definition at line 226 of file AthConfigFlags.py.

226  def __init__(self):
227  self._flagdict=dict()
228  self._locked=False
229  self._dynaflags = dict()
230  self._loaded = set() # dynamic dlags that were loaded
231  self._categoryCache = set() # cache for already found categories
232  self._hash = None
233  self._parser = None
234  self._args = None # user args from parser
235  self._renames = {}
236 

Member Function Documentation

◆ __call__()

def python.AthConfigFlags.AthConfigFlags.__call__ (   self,
  name 
)

Definition at line 478 of file AthConfigFlags.py.

478  def __call__(self,name):
479  return self._get(name)
480 

◆ __delattr__()

def python.AthConfigFlags.AthConfigFlags.__delattr__ (   self,
  name 
)

Definition at line 289 of file AthConfigFlags.py.

289  def __delattr__(self, name):
290  del self[name]
291 

◆ __delitem__()

def python.AthConfigFlags.AthConfigFlags.__delitem__ (   self,
  name 
)

Definition at line 298 of file AthConfigFlags.py.

298  def __delitem__(self, name):
299  self._tryModify()
300  self.loadAllDynamicFlags()
301  for key in list(self._flagdict):
302  if key.startswith(name):
303  del self._flagdict[key]
304  self._categoryCache.clear()
305 

◆ __getattr__()

def python.AthConfigFlags.AthConfigFlags.__getattr__ (   self,
  name 
)

Definition at line 257 of file AthConfigFlags.py.

257  def __getattr__(self, name):
258  # Avoid infinite recursion looking up our own attributes
259  _flagdict = object.__getattribute__(self, "_flagdict")
260 
261  # First try to get an already loaded flag or category
262  if name in _flagdict:
263  return self._get(name)
264 
265  if self.hasCategory(name):
266  return FlagAddress(self, name)
267 
268  # Reaching here means that we may need to load a dynamic flag
269  self._loadDynaFlags(name)
270 
271  # Try again
272  if name in _flagdict:
273  return self._get(name)
274 
275  if self.hasCategory(name):
276  return FlagAddress(self, name)
277 
278  # Reaching here means that it truly isn't something we know about
279  raise AttributeError(f"No such flag: {name}")
280 

◆ __getitem__()

def python.AthConfigFlags.AthConfigFlags.__getitem__ (   self,
  name 
)

Definition at line 292 of file AthConfigFlags.py.

292  def __getitem__(self, name):
293  return getattr(self, name)
294 

◆ __hash__()

def python.AthConfigFlags.AthConfigFlags.__hash__ (   self)

Definition at line 244 of file AthConfigFlags.py.

244  def __hash__(self):
245  raise DeprecationWarning("__hash__ method in AthConfigFlags is deprecated. Probably called from function decorator, use AccumulatorCache decorator instead.")
246 

◆ __iter__()

def python.AthConfigFlags.AthConfigFlags.__iter__ (   self)

Definition at line 306 of file AthConfigFlags.py.

306  def __iter__(self):
307  self.loadAllDynamicFlags()
308  rmap = self._renamed_map()
309  used = set()
310  for flag in self._flagdict:
311  for r in rmap[flag]:
312  first = r.split('.',1)[0]
313  if first not in used:
314  yield first
315  used.add(first)
316 

◆ __setattr__()

def python.AthConfigFlags.AthConfigFlags.__setattr__ (   self,
  name,
  value 
)

Definition at line 281 of file AthConfigFlags.py.

281  def __setattr__(self, name, value):
282  if name.startswith("_"):
283  return object.__setattr__(self, name, value)
284 
285  if name in self._flagdict:
286  return self._set(name, value)
287  raise RuntimeError( "No such flag: "+ name+". The name is likely incomplete." )
288 

◆ __setitem__()

def python.AthConfigFlags.AthConfigFlags.__setitem__ (   self,
  name,
  value 
)

Definition at line 295 of file AthConfigFlags.py.

295  def __setitem__(self, name, value):
296  setattr(self, name, value)
297 

◆ _calculateHash()

def python.AthConfigFlags.AthConfigFlags._calculateHash (   self)
private

Definition at line 247 of file AthConfigFlags.py.

247  def _calculateHash(self):
248  # Once we've hashed a flags instance, we need to be sure that
249  # it never goes away. Otherwise, since we base the hash
250  # on just the id of the dictionary, if a flags object is deleted
251  # and a new one created, the hash of the new one could match the
252  # hash of the old, even if contents are different.
253  # See ATLASRECTS-8070.
254  AthConfigFlags._hashedFlags.append (self)
255  return hash( (frozenset({k: v for k, v in self._renames.items() if k != v}), id(self._flagdict)) )
256 

◆ _get()

def python.AthConfigFlags.AthConfigFlags._get (   self,
  name 
)
private

Definition at line 469 of file AthConfigFlags.py.

469  def _get(self,name):
470  try:
471  return self._flagdict[name].get(self)
472  except KeyError:
473  closestMatch = get_close_matches(name,self._flagdict.keys(),1)
474  raise KeyError(f"No flag with name '{name}' found" +
475  (f". Did you mean '{closestMatch[0]}'?" if closestMatch else ""))
476 

◆ _loadDynaFlags()

def python.AthConfigFlags.AthConfigFlags._loadDynaFlags (   self,
  name 
)
private
loads the flags of the form "A.B.C" first attempting the path "A" then "A.B" and then "A.B.C"

Definition at line 401 of file AthConfigFlags.py.

401  def _loadDynaFlags(self, name):
402  """
403  loads the flags of the form "A.B.C" first attempting the path "A" then "A.B" and then "A.B.C"
404  """
405 
406  def __load_impl( flagBaseName ):
407  if flagBaseName in self._loaded:
408  _msg.debug("Flags %s already loaded",flagBaseName )
409  return
410  if flagBaseName in self._dynaflags:
411  _msg.debug("Dynamically loading the flags under %s", flagBaseName )
412  # Retain locked status and hash
413  isLocked = self._locked
414  myHash = self._hash
415  self._locked = False
416  generator, prefix = self._dynaflags[flagBaseName]
417  self.join( generator(), flagBaseName if prefix else "" )
418  self._locked = isLocked
419  self._hash = myHash
420  del self._dynaflags[flagBaseName]
421  self._loaded.add(flagBaseName)
422 
423  pathfrags = name.split('.')
424  for maxf in range(1, len(pathfrags)+1):
425  __load_impl( '.'.join(pathfrags[:maxf]) )
426 

◆ _renamed_map()

def python.AthConfigFlags.AthConfigFlags._renamed_map (   self)
private
mapping from the old names to the new names

This is the inverse of _renamed, which maps new names to old
names

Returns a list of the new names corresponding to the old names
(since cloneAndReplace may or may not disable access to the old name,
it is possible that an old name renames to multiple new names)

Definition at line 327 of file AthConfigFlags.py.

327  def _renamed_map(self):
328  """mapping from the old names to the new names
329 
330  This is the inverse of _renamed, which maps new names to old
331  names
332 
333  Returns a list of the new names corresponding to the old names
334  (since cloneAndReplace may or may not disable access to the old name,
335  it is possible that an old name renames to multiple new names)
336  """
337  revmap = {}
338 
339  for new, old in self._renames.items():
340  if old not in revmap:
341  revmap[old] = [ new ]
342  else:
343  revmap[old] += [ new ]
344 
345  def rename(key):
346  for old, newlist in revmap.items():
347  if key.startswith(old + '.'):
348  stem = key.removeprefix(old)
349  return [ f'{new}{stem}' if new else '' for new in newlist ]
350  return [ key ]
351 
352  return {x:rename(x) for x in self._flagdict.keys()}
353 

◆ _set()

def python.AthConfigFlags.AthConfigFlags._set (   self,
  name,
  value 
)
private

Definition at line 460 of file AthConfigFlags.py.

460  def _set(self,name,value):
461  self._tryModify()
462  try:
463  self._flagdict[name].set(value)
464  except KeyError:
465  closestMatch = get_close_matches(name,self._flagdict.keys(),1)
466  raise KeyError(f"No flag with name '{name}' found" +
467  (f". Did you mean '{closestMatch[0]}'?" if closestMatch else ""))
468 

◆ _subflag_itr()

def python.AthConfigFlags.AthConfigFlags._subflag_itr (   self)
private
Subflag iterator for all flags

This is used by the asdict() function.

Definition at line 354 of file AthConfigFlags.py.

354  def _subflag_itr(self):
355  """Subflag iterator for all flags
356 
357  This is used by the asdict() function.
358  """
359  self.loadAllDynamicFlags()
360 
361  for old, newlist in self._renamed_map().items():
362  for new in newlist:
363  # Lots of modules are missing in analysis releases. I
364  # tried to prevent imports using the _addFlagsCategory
365  # function which checks if some module exists, but this
366  # turned in to quite a rabbit hole. Catching and ignoring
367  # the missing module exception seems to work, even if it's
368  # not pretty.
369  try:
370  yield new, getattr(self, old)
371  except ModuleNotFoundError as err:
372  _msg.debug(f'missing module: {err}')
373  pass
374 

◆ _tryModify()

def python.AthConfigFlags.AthConfigFlags._tryModify (   self)
private

Definition at line 491 of file AthConfigFlags.py.

491  def _tryModify(self):
492  if self._locked:
493  raise RuntimeError("Attempt to modify locked flag container")
494  else:
495  # if unlocked then invalidate hash
496  self._hash = None
497 

◆ addFlag()

def python.AthConfigFlags.AthConfigFlags.addFlag (   self,
  name,
  setDef,
  type = None,
  help = None 
)

Definition at line 375 of file AthConfigFlags.py.

375  def addFlag(self, name, setDef, type=None, help=None):
376  self._tryModify()
377  if name in self._flagdict:
378  raise KeyError("Duplicated flag name: {}".format( name ))
379  self._flagdict[name]=CfgFlag(setDef, type, help)
380  return
381 

◆ addFlagsCategory()

def python.AthConfigFlags.AthConfigFlags.addFlagsCategory (   self,
  path,
  generator,
  prefix = False 
)
The path is the beginning of the flag name (e.g. "X" for flags generated with name "X.*").
The generator is a function that returns a flags container, the flags have to start with the same path.
When the prefix is True the flags created by the generator are prefixed by "path".

Supported calls are then:
 addFlagsCategory("A", g) - where g is function creating flags  is f.addFlag("A.x", someValue)
 addFlagsCategory("A", g, True) - when flags are defined in g like this: f.addFalg("x", somevalue),
The latter option allows to share one generator among flags that are later loaded in different paths.

Definition at line 382 of file AthConfigFlags.py.

382  def addFlagsCategory(self, path, generator, prefix=False):
383  """
384  The path is the beginning of the flag name (e.g. "X" for flags generated with name "X.*").
385  The generator is a function that returns a flags container, the flags have to start with the same path.
386  When the prefix is True the flags created by the generator are prefixed by "path".
387 
388  Supported calls are then:
389  addFlagsCategory("A", g) - where g is function creating flags is f.addFlag("A.x", someValue)
390  addFlagsCategory("A", g, True) - when flags are defined in g like this: f.addFalg("x", somevalue),
391  The latter option allows to share one generator among flags that are later loaded in different paths.
392  """
393  self._tryModify()
394  _msg.debug("Adding flag category %s", path)
395  self._dynaflags[path] = (generator, prefix)
396 

◆ args()

def python.AthConfigFlags.AthConfigFlags.args (   self)

Definition at line 641 of file AthConfigFlags.py.

641  def args(self):
642  return self._args
643 
644 

◆ asdict()

def python.AthConfigFlags.AthConfigFlags.asdict (   self)
Convert to a python dictionary

This is identical to the `asdict` in FlagAddress, but for all
the flags.

Definition at line 317 of file AthConfigFlags.py.

317  def asdict(self):
318  """Convert to a python dictionary
319 
320  This is identical to the `asdict` in FlagAddress, but for all
321  the flags.
322 
323  """
324  return _asdict(self._subflag_itr())
325 
326 

◆ athHash()

def python.AthConfigFlags.AthConfigFlags.athHash (   self)

Definition at line 237 of file AthConfigFlags.py.

237  def athHash(self):
238  if self._locked is False:
239  raise RuntimeError("Cannot calculate hash of unlocked flag container")
240  elif self._hash is None:
241  self._hash = self._calculateHash()
242  return self._hash
243 

◆ clone()

def python.AthConfigFlags.AthConfigFlags.clone (   self)
Return an unlocked copy of self (dynamic flags are not loaded)

Definition at line 498 of file AthConfigFlags.py.

498  def clone(self):
499  """Return an unlocked copy of self (dynamic flags are not loaded)"""
500  cln = AthConfigFlags()
501  cln._flagdict = deepcopy(self._flagdict)
502  cln._dynaflags = copy(self._dynaflags)
503  cln._renames = deepcopy(self._renames)
504  return cln
505 
506 

◆ cloneAndReplace()

def python.AthConfigFlags.AthConfigFlags.cloneAndReplace (   self,
  subsetToReplace,
  replacementSubset,
  keepOriginal = False 
)
This is to replace subsets of configuration flags like

Example:
newflags = flags.cloneAndReplace('Muon', 'Trigger.Offline.Muon')

Definition at line 507 of file AthConfigFlags.py.

507  def cloneAndReplace(self,subsetToReplace,replacementSubset, keepOriginal=False):
508  """
509  This is to replace subsets of configuration flags like
510 
511  Example:
512  newflags = flags.cloneAndReplace('Muon', 'Trigger.Offline.Muon')
513  """
514 
515  _msg.debug("cloning flags and replacing %s by %s", subsetToReplace, replacementSubset)
516 
517  self._loadDynaFlags( subsetToReplace )
518  self._loadDynaFlags( replacementSubset )
519 
520  subsetToReplace = subsetToReplace.strip(".")
521  replacementSubset = replacementSubset.strip(".")
522 
523  #Sanity check: Don't replace a by a
524  if (subsetToReplace == replacementSubset):
525  raise RuntimeError(f'Can not replace flags {subsetToReplace} with themselves')
526 
527  # protect against subsequent remaps within remaps: clone = flags.cloneAndReplace('Y', 'X').cloneAndReplace('X.b', 'X.a')
528  for alias,src in self._renames.items():
529  if src == "": continue
530  if src+"." in subsetToReplace:
531  raise RuntimeError(f'Can not replace flags {subsetToReplace} by {replacementSubset} because of already present replacement of {alias} by {src}')
532 
533 
534  newFlags = copy(self) # shallow copy
535  newFlags._renames = deepcopy(self._renames) #maintains renames
536 
537  if replacementSubset in newFlags._renames: #and newFlags._renames[replacementSubset]:
538  newFlags._renames[subsetToReplace] = newFlags._renames[replacementSubset]
539  else:
540  newFlags._renames[subsetToReplace] = replacementSubset
541 
542  if not keepOriginal:
543  if replacementSubset not in newFlags._renames or newFlags._renames[replacementSubset] == replacementSubset:
544  newFlags._renames[replacementSubset] = "" # block access to original flags
545  else:
546  del newFlags._renames[replacementSubset]
547  #If replacementSubset was a "pure renaming" of another set of flags,
548  #the original set of flags gets propagated down to its potential further renamings:
549  #no need to worry about maintaining the intermediate steps in the renaming.
550  else:
551  if replacementSubset not in newFlags._renames:
552  newFlags._renames[replacementSubset] = replacementSubset
553  #For _renamed_map to know that these flags still work.
554  newFlags._hash = None
555  return newFlags
556 
557 

◆ dump()

def python.AthConfigFlags.AthConfigFlags.dump (   self,
  pattern = ".*",
  evaluate = False,
  formatStr = "{:40} : {}",
  maxLength = None 
)

Definition at line 579 of file AthConfigFlags.py.

579  def dump(self, pattern=".*", evaluate=False, formatStr="{:40} : {}", maxLength=None): import re
580  compiled = re.compile(pattern)
581  def truncate(s): return s[:maxLength] + ("..." if maxLength and len(s)>maxLength else "")
582  reverse_renames = {value: key for key, value in self._renames.items() if value != ''} # new name to old
583  for name in sorted(self._flagdict):
584  renamed = name
585  if any([name.startswith(r) for r in reverse_renames.keys()]):
586  for oldprefix, newprefix in reverse_renames.items():
587  if name.startswith(oldprefix):
588  renamed = name.replace(oldprefix, newprefix)
589  break
590  if compiled.match(renamed):
591  if evaluate:
592  try:
593  rep = repr(self._flagdict[name] )
594  val = repr(self._flagdict[name].get(self))
595  if val != rep:
596  print(formatStr.format(renamed,truncate("{} {}".format( val, rep )) ))
597  else:
598  print(formatStr.format(renamed, truncate("{}".format(val)) ) )
599  except Exception as e:
600  print(formatStr.format(renamed, truncate("Exception: {}".format( e )) ))
601  else:
602  print(formatStr.format( renamed, truncate("{}".format(repr(self._flagdict[name] ) )) ))
603 
604  if len(self._dynaflags) != 0 and any([compiled.match(x) for x in self._dynaflags.keys()]):
605  print("Flag categories that can be loaded dynamically")
606  print("{:25} : {:>30} : {}".format( "Category","Generator name", "Defined in" ) )
607  for name,gen_and_prefix in sorted(self._dynaflags.items()):
608  if compiled.match(name):
609  print("{:25} : {:>30} : {}".format( name, gen_and_prefix[0].__name__, '/'.join(gen_and_prefix[0].__code__.co_filename.split('/')[-2:]) ) )
610  if len(self._renames):
611  print("Flag categories that are redirected by the cloneAndReplace")
612  for alias,src in self._renames.items():
613  print("{:30} points to {:>30} ".format( alias, src if src else "nothing") )
614 
615 
616 

◆ fillFromArgs()

def python.AthConfigFlags.AthConfigFlags.fillFromArgs (   self,
  listOfArgs = None,
  parser = None 
)
Used to set flags from command-line parameters, like flags.fillFromArgs(sys.argv[1:])

Definition at line 686 of file AthConfigFlags.py.

686  def fillFromArgs(self, listOfArgs=None, parser=None):
687  """
688  Used to set flags from command-line parameters, like flags.fillFromArgs(sys.argv[1:])
689  """
690  import sys
691 
692  self._tryModify()
693 
694  if parser is None:
695  parser = self.parser()
696  self._parser = parser # set our parser to given one
697  argList = listOfArgs or sys.argv[1:]
698  do_help = False
699  # We will now do a pre-parse of the command line arguments to propagate these to the flags
700  # the reason for this is so that we can use the help messaging to display the values of all
701  # flags as they would be *after* any parsing takes place. This is nice to see e.g. the value
702  # that any derived flag (functional flag) will take after, say, the filesInput are set
703  import argparse
704  unrequiredActions = []
705  if "-h" in argList or "--help" in argList:
706  do_help = True
707  if "-h" in argList: argList.remove("-h")
708  if "--help" in argList: argList.remove("--help")
709  # need to unrequire any required arguments in order to do a "pre parse"
710  for a in parser._actions:
711  if a.required:
712  unrequiredActions.append(a)
713  a.required = False
714  (args,leftover)=parser.parse_known_args(argList)
715  for a in unrequiredActions: a.required=True
716 
717  # remove the leftovers from the argList ... for later use in the do_help
718  argList = [a for a in argList if a not in leftover]
719 
720  # First, handle athena.py-like arguments (if available in parser):
721  def arg_set(dest):
722  """Check if dest is available in parser and has been set"""
723  return vars(args).get(dest, None) is not None
724 
725  if arg_set('debug'):
726  self.Exec.DebugStage=args.debug
727 
728  if arg_set('evtMax'):
729  self.Exec.MaxEvents=args.evtMax
730 
731  if arg_set('interactive'):
732  self.Exec.Interactive=args.interactive
733 
734  if arg_set('skipEvents'):
735  self.Exec.SkipEvents=args.skipEvents
736 
737  if arg_set('filesInput'):
738  self.Input.Files = [] # remove generic
739  for f in args.filesInput.split(","):
740  found = glob.glob(f)
741  # if not found, add string directly
742  self.Input.Files += found if found else [f]
743 
744  if "-l" in argList or "--loglevel" in argList: # different check b.c. has a default value so will always be in args
745  from AthenaCommon import Constants
746  self.Exec.OutputLevel = getattr(Constants, args.loglevel)
747 
748  if arg_set('config_only') and args.config_only is not False:
749  from os import environ
750  environ["PICKLECAFILE"] = "" if args.config_only is True else args.config_only
751 
752  if arg_set('threads'):
753  self.Concurrency.NumThreads = args.threads
754  #Work-around a possible inconsistency of NumThreads and NumConcurrentEvents that may
755  #occur when these values are set by the transforms and overwritten by --athenaopts ..
756  #See also ATEAM-907
757  if args.concurrent_events is None and self.Concurrency.NumConcurrentEvents==0:
758  self.Concurrency.NumConcurrentEvents = args.threads
759 
760  if arg_set('concurrent_events'):
761  self.Concurrency.NumConcurrentEvents = args.concurrent_events
762 
763  if arg_set('nprocs'):
764  self.Concurrency.NumProcs = args.nprocs
765 
766  if arg_set('perfmon'):
767  from PerfMonComps.PerfMonConfigHelpers import setPerfmonFlagsFromRunArgs
768  setPerfmonFlagsFromRunArgs(self, args)
769 
770  if arg_set('mtes'):
771  self.Exec.MTEventService = args.mtes
772 
773  if arg_set('mtes_channel'):
774  self.Exec.MTEventServiceChannel = args.mtes_channel
775 
776  if arg_set('profile_python'):
777  from AthenaCommon.Debugging import dumpPythonProfile
778  import atexit, cProfile, functools
779  cProfile._athena_python_profiler = cProfile.Profile()
780  cProfile._athena_python_profiler.enable()
781 
782  # Save stats to file at exit
783  atexit.register(functools.partial(dumpPythonProfile, args.profile_python))
784 
785 
786  # All remaining arguments are assumed to be key=value pairs to set arbitrary flags:
787  for arg in leftover:
788  if arg=='--':
789  argList += ["---"]
790  continue # allows for multi-value arguments to be terminated by a " -- "
791  if do_help and '=' not in arg:
792  argList += arg.split(".") # put arg back back for help (but split by sub-categories)
793  continue
794 
795  self.fillFromString(arg)
796 
797  if do_help:
798  if parser.epilog is None: parser.epilog=""
799  parser.epilog += " Note: Specify additional flags in form <flagName>=<value>."
800  subparsers = {"":[parser,parser.add_subparsers(help=argparse.SUPPRESS)]} # first is category's parser, second is subparsers (effectively the category's subcategories)
801  # silence logging while evaluating flags
802  logging.root.setLevel(logging.ERROR)
803  def getParser(category): # get parser for a given category
804  if category not in subparsers.keys():
805  cat1,cat2 = category.rsplit(".",1) if "." in category else ("",category)
806  p,subp = getParser(cat1)
807  if subp.help==argparse.SUPPRESS:
808  subp.help = "Flag subcategories:"
809  newp = subp.add_parser(cat2,help="{} flags".format(category),
810  formatter_class = argparse.ArgumentDefaultsHelpFormatter,usage=argparse.SUPPRESS)
811  newp._positionals.title = "flags"
812  subparsers[category] = [newp,newp.add_subparsers(help=argparse.SUPPRESS)]
813  return subparsers[category]
814  self.loadAllDynamicFlags()
815  for name in sorted(self._flagdict):
816  category,flagName = name.rsplit(".",1) if "." in name else ("",name)
817  flag = self._flagdict[name]
818  try:
819  val = repr(flag.get(self))
820  except Exception:
821  val = None
822  if flag._help != argparse.SUPPRESS:
823  helptext = ""
824  if flag._help is not None:
825  helptext = f": {flag._help}"
826  if flag._type is not None:
827  helptext += f' [type: {flag._type.__name__}]'
828  if val is not None and helptext == "":
829  helptext = ": " # ensures default values are displayed even if there's no help text
830  getParser(category)[0].add_argument(name, nargs='?', default=val, help=helptext)
831 
832  parser._positionals.title = 'flags and positional arguments'
833  parser.parse_known_args(argList + ["--help"])
834 
835  self._args = args
836 
837  return args
838 
839 
840 

◆ fillFromString()

def python.AthConfigFlags.AthConfigFlags.fillFromString (   self,
  flag_string 
)
Fill the flags from a string of type key=value

Definition at line 645 of file AthConfigFlags.py.

645  def fillFromString(self, flag_string):
646  """Fill the flags from a string of type key=value"""
647  import ast
648 
649  try:
650  key, value = flag_string.split("=")
651  except ValueError:
652  raise ValueError(f"Cannot interpret argument {flag_string}, expected a key=value format")
653 
654  key = key.strip()
655  value = value.strip()
656 
657  # also allow key+=value to append
658  oper = "="
659  if (key[-1]=="+"):
660  oper = "+="
661  key = key[:-1]
662 
663  if not self.hasFlag(key):
664  self._loadDynaFlags( '.'.join(key.split('.')[:-1]) ) # for a flag A.B.C dymanic flags from category A.B
665  if not self.hasFlag(key):
666  raise KeyError(f"{key} is not a known configuration flag")
667 
668  flag_type = self._flagdict[key]._type
669  if flag_type is None:
670  # Regular flag
671  try:
672  ast.literal_eval(value)
673  except Exception: # Can't determine type, assume we got an un-quoted string
674  value=f"\"{value}\""
675 
676  elif isinstance(flag_type, EnumMeta):
677  # Flag is an enum, so we need to import the module containing the enum
678  ENUM = importlib.import_module(flag_type.__module__) # noqa: F841 (used in exec)
679  value=f"ENUM.{value}"
680 
681  # Set the value (this also does the type checking if needed)
682  exec(f"self.{key}{oper}{value}")
683 
684 

◆ getArgumentParser()

def python.AthConfigFlags.AthConfigFlags.getArgumentParser (   self,
**  kwargs 
)
Scripts calling AthConfigFlags.fillFromArgs can extend this parser, and pass their version to fillFromArgs

Definition at line 626 of file AthConfigFlags.py.

626  def getArgumentParser(self, **kwargs):
627  """
628  Scripts calling AthConfigFlags.fillFromArgs can extend this parser, and pass their version to fillFromArgs
629  """
630  import argparse
631  from AthenaCommon.AthOptionsParser import getArgumentParser
632  parser = getArgumentParser(**kwargs)
633  parser.add_argument("---",dest="terminator",action='store_true', help=argparse.SUPPRESS) # special hidden option required to convert option terminator -- for --help calls
634 
635  return parser
636 

◆ hasCategory()

def python.AthConfigFlags.AthConfigFlags.hasCategory (   self,
  name 
)

Definition at line 434 of file AthConfigFlags.py.

434  def hasCategory(self, name):
435  # We cache successfully found categories
436  if name in self._categoryCache:
437  return True
438 
439  if name in self._renames:
440  re_name = self._renames[name]
441  if re_name != name:
442  return self.hasCategory(re_name)
443 
444  # If not found do search through all keys.
445  # TODO: could be improved by using a trie for _flagdict
446  for f in self._flagdict.keys():
447  if f.startswith(name+'.'):
448  self._categoryCache.add(name)
449  return True
450  for c in self._dynaflags.keys():
451  if c.startswith(name):
452  self._categoryCache.add(name)
453  return True
454 
455  return False
456 

◆ hasFlag()

def python.AthConfigFlags.AthConfigFlags.hasFlag (   self,
  name 
)

Definition at line 457 of file AthConfigFlags.py.

457  def hasFlag(self, name):
458  return name in [y for x in self._renamed_map().values() for y in x]
459 

◆ initAll()

def python.AthConfigFlags.AthConfigFlags.initAll (   self)
Mostly a self-test method

Definition at line 617 of file AthConfigFlags.py.

617  def initAll(self):
618  """
619  Mostly a self-test method
620  """
621  for n,f in list(self._flagdict.items()):
622  f.get(self)
623  return
624 
625 

◆ join()

def python.AthConfigFlags.AthConfigFlags.join (   self,
  other,
  prefix = '' 
)
Merges two flag containers
When the prefix is passed each flag from the "other" is prefixed by "prefix."

Definition at line 558 of file AthConfigFlags.py.

558  def join(self, other, prefix=''):
559  """
560  Merges two flag containers
561  When the prefix is passed each flag from the "other" is prefixed by "prefix."
562  """
563  self._tryModify()
564 
565  for (name,flag) in other._flagdict.items():
566  fullName = prefix+"."+name if prefix != "" else name
567  if fullName in self._flagdict:
568  raise KeyError("Duplicated flag name: {}".format( fullName ) )
569  self._flagdict[fullName]=flag
570 
571  for (name,loader) in other._dynaflags.items():
572  fullName = prefix+"."+name if prefix != "" else name
573  if fullName in self._dynaflags:
574  raise KeyError("Duplicated dynamic flags name: {}".format( fullName ) )
575  _msg.debug("Joining dynamic flags with %s", fullName)
576  self._dynaflags[fullName] = loader
577  return
578 

◆ loadAllDynamicFlags()

def python.AthConfigFlags.AthConfigFlags.loadAllDynamicFlags (   self)
Force load all the dynamic flags 

Definition at line 427 of file AthConfigFlags.py.

427  def loadAllDynamicFlags(self):
428  """Force load all the dynamic flags """
429  while len(self._dynaflags) != 0:
430  # Need to convert to a list since _loadDynaFlags may change the dict.
431  for prefix in list(self._dynaflags.keys()):
432  self._loadDynaFlags( prefix )
433 

◆ lock()

def python.AthConfigFlags.AthConfigFlags.lock (   self)

Definition at line 481 of file AthConfigFlags.py.

481  def lock(self):
482  if not self._locked:
483  # before locking, parse args if a parser was defined
484  if self._args is None and self._parser is not None: self.fillFromArgs()
485  self._locked = True
486  return
487 

◆ locked()

def python.AthConfigFlags.AthConfigFlags.locked (   self)

Definition at line 488 of file AthConfigFlags.py.

488  def locked(self):
489  return self._locked
490 

◆ needFlagsCategory()

def python.AthConfigFlags.AthConfigFlags.needFlagsCategory (   self,
  name 
)
public interface for _loadDynaFlags 

Definition at line 397 of file AthConfigFlags.py.

397  def needFlagsCategory(self, name):
398  """ public interface for _loadDynaFlags """
399  self._loadDynaFlags( name )
400 

◆ parser()

def python.AthConfigFlags.AthConfigFlags.parser (   self)

Definition at line 637 of file AthConfigFlags.py.

637  def parser(self):
638  if self._parser is None: self._parser = self.getArgumentParser()
639  return self._parser
640 

Member Data Documentation

◆ _args

python.AthConfigFlags.AthConfigFlags._args
private

Definition at line 234 of file AthConfigFlags.py.

◆ _categoryCache

python.AthConfigFlags.AthConfigFlags._categoryCache
private

Definition at line 231 of file AthConfigFlags.py.

◆ _dynaflags

python.AthConfigFlags.AthConfigFlags._dynaflags
private

Definition at line 229 of file AthConfigFlags.py.

◆ _flagdict

python.AthConfigFlags.AthConfigFlags._flagdict
private

Definition at line 227 of file AthConfigFlags.py.

◆ _hash

python.AthConfigFlags.AthConfigFlags._hash
private

Definition at line 232 of file AthConfigFlags.py.

◆ _hashedFlags

list python.AthConfigFlags.AthConfigFlags._hashedFlags = []
staticprivate

Definition at line 224 of file AthConfigFlags.py.

◆ _loaded

python.AthConfigFlags.AthConfigFlags._loaded
private

Definition at line 230 of file AthConfigFlags.py.

◆ _locked

python.AthConfigFlags.AthConfigFlags._locked
private

Definition at line 228 of file AthConfigFlags.py.

◆ _parser

python.AthConfigFlags.AthConfigFlags._parser
private

Definition at line 233 of file AthConfigFlags.py.

◆ _renames

python.AthConfigFlags.AthConfigFlags._renames
private

Definition at line 235 of file AthConfigFlags.py.

◆ print_context

python.AthConfigFlags.AthConfigFlags.print_context
static

Definition at line 477 of file AthConfigFlags.py.


The documentation for this class was generated from the following file:
python.CaloScaleNoiseConfig.parser
parser
Definition: CaloScaleNoiseConfig.py:75
python.AthOptionsParser.getArgumentParser
def getArgumentParser(legacy_args=False, **kwargs)
Definition: AthOptionsParser.py:140
vtune_athena.format
format
Definition: vtune_athena.py:14
python.Bindings.__iter__
__iter__
Definition: Control/AthenaPython/python/Bindings.py:791
python.Utilities.clone
clone
Definition: Utilities.py:134
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:805
run_Egamma1_LArStrip_Fex.dump
dump
Definition: run_Egamma1_LArStrip_Fex.py:88
python.AthConfigFlags._asdict
def _asdict(iterator)
Definition: AthConfigFlags.py:105
LArG4FSStartPointFilter.exec
exec
Definition: LArG4FSStartPointFilter.py:103
python.PerfMonConfigHelpers.setPerfmonFlagsFromRunArgs
def setPerfmonFlagsFromRunArgs(flags, runArgs)
Definition: PerfMonConfigHelpers.py:3
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
PyAthena::repr
std::string repr(PyObject *o)
returns the string representation of a python object equivalent of calling repr(o) in python
Definition: PyAthenaUtils.cxx:106
add
bool add(const std::string &hname, TKey *tobj)
Definition: fastadd.cxx:55
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
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:232
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:227
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
python.processes.powheg.ZZ.ZZ.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZ.py:18
mc.generator
generator
Configure Herwig7 These are the commands corresponding to what would go into the regular Herwig infil...
Definition: mc.MGH7_FxFx_H71-DEFAULT_test.py:18
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
python.Bindings.__setitem__
__setitem__
Definition: Control/AthenaPython/python/Bindings.py:771
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
python.PyAthenaComps.__setattr__
__setattr__
Definition: PyAthenaComps.py:39
calibdata.copy
bool copy
Definition: calibdata.py:27
python.Bindings.__getitem__
__getitem__
Definition: Control/AthenaPython/python/Bindings.py:779
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
LArG4ShowerLibProcessing.truncate
truncate
Definition: LArG4ShowerLibProcessing.py:39