Skip to content
Snippets Groups Projects
ConfigHelper.py 4.14 KiB
Newer Older
"""Helper object to identify configuration parameters so we can easily overwrite
them via command line magic or via the steering file

To add additional arguments create either a member variable or a property to a
subclass of the ConfigHelper. To add additional arguments to the add_argument
call for the parser object create an additional member::

  self.member = [1,2]
  self._member_EXTRA = {'help': 'description for parameter',
                        'nargs': '+',
                       }

from __future__ import absolute_import, unicode_literals
Andre Sailer's avatar
Andre Sailer committed

Marko Petric's avatar
Marko Petric committed

class ConfigHelper(object):
  """Base class for configuration helper"""
Marko Petric's avatar
Marko Petric committed

  def __init__(self):
    pass

  def getOptions(self):
    finalVars = {}

    # get all direct members not starting with underscore
    allVars = vars(self)
Marko Petric's avatar
Marko Petric committed
    for var, val in six.iteritems(allVars):
      if not var.startswith('_'):
        extraArgumentsName = "_%s_EXTRA" % var
        options = getattr(self, extraArgumentsName) if hasattr(self, extraArgumentsName) else None
        finalVars[var] = {'default': val}
        if options:
          finalVars[var].update(options)

    # now get things defined with @property
Marko Petric's avatar
Marko Petric committed
    props = [(p, getattr(type(self), p)) for p in dir(type(self)) if isinstance(getattr(type(self), p), property)]
    for propName, prop in props:
Marko Petric's avatar
Marko Petric committed
      optName = "_%s_EXTRA" % propName
      doc = prop.__doc__
      options = getattr(self, optName) if hasattr(self, optName) else None
      finalVars[propName] = {'default': getattr(self, propName)}
      if doc:
        finalVars[propName]['help'] = doc
      if options:
        finalVars[propName].update(options)
Marko Petric's avatar
Marko Petric committed
  def printOptions(self):
    """print all parameters"""
Marko Petric's avatar
Marko Petric committed
    for opt, val in six.iteritems(self.getOptions()):
      options.append("\n\t'%s': '%s'" % (opt, val['default']))
Marko Petric's avatar
Marko Petric committed
  def setOption(self, name, val):
    """ set the attribute name to val """
    setattr(self, name, val)

  @staticmethod
Marko Petric's avatar
Marko Petric committed
  def makeList(stringVal, sep=" "):
    """returns a list from a string separated by sep"""
    if not stringVal:
Marko Petric's avatar
Marko Petric committed
    if isinstance(stringVal, list):
      return stringVal
    else:
      return stringVal.split(sep)
  @staticmethod
  def makeSet(stringVal, sep=" "):
    """returns a set from a string separated by sep"""
    if not stringVal:
      return set()
    if isinstance(stringVal, (list, set, tuple)):
      return set(stringVal)
    else:
      return set(stringVal.split(sep))

  @staticmethod
  def makeString(container):
    """Return a string that can be parsed by dd4hep into a vector."""
    if not container:
      return ""
    if isinstance(container, set):
      return '{%s}' % ','.join([str(s) for s in container])

Marko Petric's avatar
Marko Petric committed
  def makeTuple(val):
    """ returns a tuple of the string, separators are space or comma """
    myTuple = None
Marko Petric's avatar
Marko Petric committed
    if isinstance(val, tuple):
Marko Petric's avatar
Marko Petric committed
    if isinstance(val, list):
Marko Petric's avatar
Marko Petric committed
    if isinstance(val, six.string_types):
Marko Petric's avatar
Marko Petric committed
      myTuple = tuple([_.strip("(), ") for _ in val.split(sep)])
Marko Petric's avatar
Marko Petric committed
      raise RuntimeError("Cannot parse input value %s" % val)
Marko Petric's avatar
Marko Petric committed
  def makeBool(val):
    """check if val is a bool or a string of true/false, otherwise raise exception"""
    if isinstance(val, bool):
      return val
    elif isinstance(val, six.string_types):
      if val.lower() == 'true':
        return True
      elif val.lower() == 'false':
        return False
Marko Petric's avatar
Marko Petric committed
    raise RuntimeError(val)

  @staticmethod
  def addAllHelper(ddsim, parser):
    """all configHelper objects to commandline args"""
    for name, obj in six.iteritems(vars(ddsim)):
Marko Petric's avatar
Marko Petric committed
        for var, optionsDict in six.iteritems(obj.getOptions()):
          optionsDict['action'] = 'store_true' if var.startswith("enable") else optionsDict.get('action', 'store')
          parser.add_argument("--%s.%s" % (name, var),
                              dest="%s.%s" % (name, var),
                              **optionsDict
Marko Petric's avatar
Marko Petric committed
                              )