ATLAS Offline Software
Public Member Functions | Static Public Attributes | Private Member Functions | 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
 

Detailed Description

Definition at line 219 of file AthConfigFlags.py.

Constructor & Destructor Documentation

◆ __init__()

def python.AthConfigFlags.AthConfigFlags.__init__ (   self)

Definition at line 221 of file AthConfigFlags.py.

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

Member Function Documentation

◆ __call__()

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

Definition at line 466 of file AthConfigFlags.py.

466  def __call__(self,name):
467  return self._get(name)
468 

◆ __delattr__()

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

Definition at line 277 of file AthConfigFlags.py.

277  def __delattr__(self, name):
278  del self[name]
279 

◆ __delitem__()

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

Definition at line 286 of file AthConfigFlags.py.

286  def __delitem__(self, name):
287  self._tryModify()
288  self.loadAllDynamicFlags()
289  for key in list(self._flagdict):
290  if key.startswith(name):
291  del self._flagdict[key]
292  self._categoryCache.clear()
293 

◆ __getattr__()

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

Definition at line 245 of file AthConfigFlags.py.

245  def __getattr__(self, name):
246  # Avoid infinite recursion looking up our own attributes
247  _flagdict = object.__getattribute__(self, "_flagdict")
248 
249  # First try to get an already loaded flag or category
250  if name in _flagdict:
251  return self._get(name)
252 
253  if self.hasCategory(name):
254  return FlagAddress(self, name)
255 
256  # Reaching here means that we may need to load a dynamic flag
257  self._loadDynaFlags(name)
258 
259  # Try again
260  if name in _flagdict:
261  return self._get(name)
262 
263  if self.hasCategory(name):
264  return FlagAddress(self, name)
265 
266  # Reaching here means that it truly isn't something we know about
267  raise AttributeError(f"No such flag: {name}")
268 

◆ __getitem__()

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

Definition at line 280 of file AthConfigFlags.py.

280  def __getitem__(self, name):
281  return getattr(self, name)
282 

◆ __hash__()

def python.AthConfigFlags.AthConfigFlags.__hash__ (   self)

Definition at line 239 of file AthConfigFlags.py.

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

◆ __iter__()

def python.AthConfigFlags.AthConfigFlags.__iter__ (   self)

Definition at line 294 of file AthConfigFlags.py.

294  def __iter__(self):
295  self.loadAllDynamicFlags()
296  rmap = self._renamed_map()
297  used = set()
298  for flag in self._flagdict:
299  for r in rmap[flag]:
300  first = r.split('.',1)[0]
301  if first not in used:
302  yield first
303  used.add(first)
304 

◆ __setattr__()

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

Definition at line 269 of file AthConfigFlags.py.

269  def __setattr__(self, name, value):
270  if name.startswith("_"):
271  return object.__setattr__(self, name, value)
272 
273  if name in self._flagdict:
274  return self._set(name, value)
275  raise RuntimeError( "No such flag: "+ name+". The name is likely incomplete." )
276 

◆ __setitem__()

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

Definition at line 283 of file AthConfigFlags.py.

283  def __setitem__(self, name, value):
284  setattr(self, name, value)
285 

◆ _calculateHash()

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

Definition at line 242 of file AthConfigFlags.py.

242  def _calculateHash(self):
243  return hash( (frozenset({k: v for k, v in self._renames.items() if k != v}), id(self._flagdict)) )
244 

◆ _get()

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

Definition at line 457 of file AthConfigFlags.py.

457  def _get(self,name):
458  try:
459  return self._flagdict[name].get(self)
460  except KeyError:
461  closestMatch = get_close_matches(name,self._flagdict.keys(),1)
462  raise KeyError(f"No flag with name '{name}' found" +
463  (f". Did you mean '{closestMatch[0]}'?" if closestMatch else ""))
464 

◆ _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 389 of file AthConfigFlags.py.

389  def _loadDynaFlags(self, name):
390  """
391  loads the flags of the form "A.B.C" first attempting the path "A" then "A.B" and then "A.B.C"
392  """
393 
394  def __load_impl( flagBaseName ):
395  if flagBaseName in self._loaded:
396  _msg.debug("Flags %s already loaded",flagBaseName )
397  return
398  if flagBaseName in self._dynaflags:
399  _msg.debug("Dynamically loading the flags under %s", flagBaseName )
400  # Retain locked status and hash
401  isLocked = self._locked
402  myHash = self._hash
403  self._locked = False
404  generator, prefix = self._dynaflags[flagBaseName]
405  self.join( generator(), flagBaseName if prefix else "" )
406  self._locked = isLocked
407  self._hash = myHash
408  del self._dynaflags[flagBaseName]
409  self._loaded.add(flagBaseName)
410 
411  pathfrags = name.split('.')
412  for maxf in range(1, len(pathfrags)+1):
413  __load_impl( '.'.join(pathfrags[:maxf]) )
414 

◆ _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 315 of file AthConfigFlags.py.

315  def _renamed_map(self):
316  """mapping from the old names to the new names
317 
318  This is the inverse of _renamed, which maps new names to old
319  names
320 
321  Returns a list of the new names corresponding to the old names
322  (since cloneAndReplace may or may not disable access to the old name,
323  it is possible that an old name renames to multiple new names)
324  """
325  revmap = {}
326 
327  for new, old in self._renames.items():
328  if old not in revmap:
329  revmap[old] = [ new ]
330  else:
331  revmap[old] += [ new ]
332 
333  def rename(key):
334  for old, newlist in revmap.items():
335  if key.startswith(old + '.'):
336  stem = key.removeprefix(old)
337  return [ f'{new}{stem}' if new else '' for new in newlist ]
338  return [ key ]
339 
340  return {x:rename(x) for x in self._flagdict.keys()}
341 

◆ _set()

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

Definition at line 448 of file AthConfigFlags.py.

448  def _set(self,name,value):
449  self._tryModify()
450  try:
451  self._flagdict[name].set(value)
452  except KeyError:
453  closestMatch = get_close_matches(name,self._flagdict.keys(),1)
454  raise KeyError(f"No flag with name '{name}' found" +
455  (f". Did you mean '{closestMatch[0]}'?" if closestMatch else ""))
456 

◆ _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 342 of file AthConfigFlags.py.

342  def _subflag_itr(self):
343  """Subflag iterator for all flags
344 
345  This is used by the asdict() function.
346  """
347  self.loadAllDynamicFlags()
348 
349  for old, newlist in self._renamed_map().items():
350  for new in newlist:
351  # Lots of modules are missing in analysis releases. I
352  # tried to prevent imports using the _addFlagsCategory
353  # function which checks if some module exists, but this
354  # turned in to quite a rabbit hole. Catching and ignoring
355  # the missing module exception seems to work, even if it's
356  # not pretty.
357  try:
358  yield new, getattr(self, old)
359  except ModuleNotFoundError as err:
360  _msg.debug(f'missing module: {err}')
361  pass
362 

◆ _tryModify()

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

Definition at line 479 of file AthConfigFlags.py.

479  def _tryModify(self):
480  if self._locked:
481  raise RuntimeError("Attempt to modify locked flag container")
482  else:
483  # if unlocked then invalidate hash
484  self._hash = None
485 

◆ addFlag()

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

Definition at line 363 of file AthConfigFlags.py.

363  def addFlag(self, name, setDef, type=None, help=None):
364  self._tryModify()
365  if name in self._flagdict:
366  raise KeyError("Duplicated flag name: {}".format( name ))
367  self._flagdict[name]=CfgFlag(setDef, type, help)
368  return
369 

◆ 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 370 of file AthConfigFlags.py.

370  def addFlagsCategory(self, path, generator, prefix=False):
371  """
372  The path is the beginning of the flag name (e.g. "X" for flags generated with name "X.*").
373  The generator is a function that returns a flags container, the flags have to start with the same path.
374  When the prefix is True the flags created by the generator are prefixed by "path".
375 
376  Supported calls are then:
377  addFlagsCategory("A", g) - where g is function creating flags is f.addFlag("A.x", someValue)
378  addFlagsCategory("A", g, True) - when flags are defined in g like this: f.addFalg("x", somevalue),
379  The latter option allows to share one generator among flags that are later loaded in different paths.
380  """
381  self._tryModify()
382  _msg.debug("Adding flag category %s", path)
383  self._dynaflags[path] = (generator, prefix)
384 

◆ args()

def python.AthConfigFlags.AthConfigFlags.args (   self)

Definition at line 629 of file AthConfigFlags.py.

629  def args(self):
630  return self._args
631 
632 

◆ 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 305 of file AthConfigFlags.py.

305  def asdict(self):
306  """Convert to a python dictionary
307 
308  This is identical to the `asdict` in FlagAddress, but for all
309  the flags.
310 
311  """
312  return _asdict(self._subflag_itr())
313 
314 

◆ athHash()

def python.AthConfigFlags.AthConfigFlags.athHash (   self)

Definition at line 232 of file AthConfigFlags.py.

232  def athHash(self):
233  if self._locked is False:
234  raise RuntimeError("Cannot calculate hash of unlocked flag container")
235  elif self._hash is None:
236  self._hash = self._calculateHash()
237  return self._hash
238 

◆ clone()

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

Definition at line 486 of file AthConfigFlags.py.

486  def clone(self):
487  """Return an unlocked copy of self (dynamic flags are not loaded)"""
488  cln = AthConfigFlags()
489  cln._flagdict = deepcopy(self._flagdict)
490  cln._dynaflags = copy(self._dynaflags)
491  cln._renames = deepcopy(self._renames)
492  return cln
493 
494 

◆ 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 495 of file AthConfigFlags.py.

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

◆ dump()

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

Definition at line 567 of file AthConfigFlags.py.

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

◆ 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 674 of file AthConfigFlags.py.

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

◆ fillFromString()

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

Definition at line 633 of file AthConfigFlags.py.

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

◆ 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 614 of file AthConfigFlags.py.

614  def getArgumentParser(self, **kwargs):
615  """
616  Scripts calling AthConfigFlags.fillFromArgs can extend this parser, and pass their version to fillFromArgs
617  """
618  import argparse
619  from AthenaCommon.AthOptionsParser import getArgumentParser
620  parser = getArgumentParser(**kwargs)
621  parser.add_argument("---",dest="terminator",action='store_true', help=argparse.SUPPRESS) # special hidden option required to convert option terminator -- for --help calls
622 
623  return parser
624 

◆ hasCategory()

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

Definition at line 422 of file AthConfigFlags.py.

422  def hasCategory(self, name):
423  # We cache successfully found categories
424  if name in self._categoryCache:
425  return True
426 
427  if name in self._renames:
428  re_name = self._renames[name]
429  if re_name != name:
430  return self.hasCategory(re_name)
431 
432  # If not found do search through all keys.
433  # TODO: could be improved by using a trie for _flagdict
434  for f in self._flagdict.keys():
435  if f.startswith(name+'.'):
436  self._categoryCache.add(name)
437  return True
438  for c in self._dynaflags.keys():
439  if c.startswith(name):
440  self._categoryCache.add(name)
441  return True
442 
443  return False
444 

◆ hasFlag()

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

Definition at line 445 of file AthConfigFlags.py.

445  def hasFlag(self, name):
446  return name in [y for x in self._renamed_map().values() for y in x]
447 

◆ initAll()

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

Definition at line 605 of file AthConfigFlags.py.

605  def initAll(self):
606  """
607  Mostly a self-test method
608  """
609  for n,f in list(self._flagdict.items()):
610  f.get(self)
611  return
612 
613 

◆ 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 546 of file AthConfigFlags.py.

546  def join(self, other, prefix=''):
547  """
548  Merges two flag containers
549  When the prefix is passed each flag from the "other" is prefixed by "prefix."
550  """
551  self._tryModify()
552 
553  for (name,flag) in other._flagdict.items():
554  fullName = prefix+"."+name if prefix != "" else name
555  if fullName in self._flagdict:
556  raise KeyError("Duplicated flag name: {}".format( fullName ) )
557  self._flagdict[fullName]=flag
558 
559  for (name,loader) in other._dynaflags.items():
560  fullName = prefix+"."+name if prefix != "" else name
561  if fullName in self._dynaflags:
562  raise KeyError("Duplicated dynamic flags name: {}".format( fullName ) )
563  _msg.debug("Joining dynamic flags with %s", fullName)
564  self._dynaflags[fullName] = loader
565  return
566 

◆ loadAllDynamicFlags()

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

Definition at line 415 of file AthConfigFlags.py.

415  def loadAllDynamicFlags(self):
416  """Force load all the dynamic flags """
417  while len(self._dynaflags) != 0:
418  # Need to convert to a list since _loadDynaFlags may change the dict.
419  for prefix in list(self._dynaflags.keys()):
420  self._loadDynaFlags( prefix )
421 

◆ lock()

def python.AthConfigFlags.AthConfigFlags.lock (   self)

Definition at line 469 of file AthConfigFlags.py.

469  def lock(self):
470  if not self._locked:
471  # before locking, parse args if a parser was defined
472  if self._args is None and self._parser is not None: self.fillFromArgs()
473  self._locked = True
474  return
475 

◆ locked()

def python.AthConfigFlags.AthConfigFlags.locked (   self)

Definition at line 476 of file AthConfigFlags.py.

476  def locked(self):
477  return self._locked
478 

◆ needFlagsCategory()

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

Definition at line 385 of file AthConfigFlags.py.

385  def needFlagsCategory(self, name):
386  """ public interface for _loadDynaFlags """
387  self._loadDynaFlags( name )
388 

◆ parser()

def python.AthConfigFlags.AthConfigFlags.parser (   self)

Definition at line 625 of file AthConfigFlags.py.

625  def parser(self):
626  if self._parser is None: self._parser = self.getArgumentParser()
627  return self._parser
628 

Member Data Documentation

◆ _args

python.AthConfigFlags.AthConfigFlags._args
private

Definition at line 229 of file AthConfigFlags.py.

◆ _categoryCache

python.AthConfigFlags.AthConfigFlags._categoryCache
private

Definition at line 226 of file AthConfigFlags.py.

◆ _dynaflags

python.AthConfigFlags.AthConfigFlags._dynaflags
private

Definition at line 224 of file AthConfigFlags.py.

◆ _flagdict

python.AthConfigFlags.AthConfigFlags._flagdict
private

Definition at line 222 of file AthConfigFlags.py.

◆ _hash

python.AthConfigFlags.AthConfigFlags._hash
private

Definition at line 227 of file AthConfigFlags.py.

◆ _loaded

python.AthConfigFlags.AthConfigFlags._loaded
private

Definition at line 225 of file AthConfigFlags.py.

◆ _locked

python.AthConfigFlags.AthConfigFlags._locked
private

Definition at line 223 of file AthConfigFlags.py.

◆ _parser

python.AthConfigFlags.AthConfigFlags._parser
private

Definition at line 228 of file AthConfigFlags.py.

◆ _renames

python.AthConfigFlags.AthConfigFlags._renames
private

Definition at line 230 of file AthConfigFlags.py.

◆ print_context

python.AthConfigFlags.AthConfigFlags.print_context
static

Definition at line 465 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:783
python.Utilities.clone
clone
Definition: Utilities.py:134
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:797
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:224
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:194
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
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
python.Bindings.__setitem__
__setitem__
Definition: Control/AthenaPython/python/Bindings.py:763
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:790
python.PyAthenaComps.__setattr__
__setattr__
Definition: PyAthenaComps.py:41
calibdata.copy
bool copy
Definition: calibdata.py:27
python.Bindings.__getitem__
__getitem__
Definition: Control/AthenaPython/python/Bindings.py:771
FourMomUtils::dump
std::ostream & dump(std::ostream &out, const I4MomIter iBeg, const I4MomIter iEnd)
Helper to stream out a range of I4Momentum objects.
Definition: P4Dumper.h:24
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
LArG4ShowerLibProcessing.truncate
truncate
Definition: LArG4ShowerLibProcessing.py:39