Skip to content
Snippets Groups Projects
dddigi.py 8.82 KiB
Newer Older
Marko Petric's avatar
Marko Petric committed
# ==========================================================================
Marko Petric's avatar
Marko Petric committed
#  AIDA Detector description implementation
Marko Petric's avatar
Marko Petric committed
# --------------------------------------------------------------------------
# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
# All rights reserved.
#
# For the licensing terms see $DD4hepINSTALL/LICENSE.
# For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
#
Marko Petric's avatar
Marko Petric committed
# ==========================================================================
from __future__ import absolute_import, unicode_literals
Marko Petric's avatar
Marko Petric committed
from dd4hep_base import *  # noqa: F403
Markus Frank's avatar
Markus Frank committed
logger = None
Marko Petric's avatar
Marko Petric committed

Markus Frank's avatar
Markus Frank committed
  global logger
Marko Petric's avatar
Marko Petric committed
  import ROOT
Markus Frank's avatar
Markus Frank committed
  import dd4hep_base
Markus Frank's avatar
Markus Frank committed
  logger = dd4hep_base.dd4hep_logger('dddigi')

Marko Petric's avatar
Marko Petric committed
  # Try to load libglapi to avoid issues with TLS Static
  # Turn off all errors from ROOT about the library missing
  if('libglapi' not in gSystem.GetLibraries()):
    orgLevel = ROOT.gErrorIgnoreLevel
    ROOT.gErrorIgnoreLevel = 6000
    gSystem.Load("libglapi")
    ROOT.gErrorIgnoreLevel = orgLevel
  import platform
Marko Petric's avatar
Marko Petric committed
  if platform.system() == "Darwin":
    gSystem.SetDynamicPath(os.environ['DD4HEP_LIBRARY_PATH'])

  result = gSystem.Load("libDDDigiPlugins")
  if result < 0:
Marko Petric's avatar
Marko Petric committed
    raise Exception('DDDigi.py: Failed to load the DDDigi library libDDDigiPlugins: ' + gSystem.GetErrorStr())
  logger.info('DDDigi.py: Successfully loaded DDDigi plugin library libDDDigiPlugins!')
  result = gSystem.Load("libDDG4Plugins")
  if result < 0:
    raise Exception('DDDigi.py: Failed to load the DDG4 library libDDG4Plugins: ' + gSystem.GetErrorStr())
  logger.info('DDDigi.py: Successfully loaded DDG4 plugin library libDDG4Plugins!')
  from ROOT import dd4hep as module
  return module

# We are nearly there ....
current = __import__(__name__)
Marko Petric's avatar
Marko Petric committed

Marko Petric's avatar
Marko Petric committed
def _import_class(ns, nam):
  scope = getattr(current, ns)
  setattr(current, nam, getattr(scope, nam))

Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
Marko Petric's avatar
Marko Petric committed
  dd4hep = loadDDDigi()
Marko Petric's avatar
Marko Petric committed
  logger.error('+--%-100s--+', 100 * '-')
  logger.error('|  %-100s  |', 'Failed to load DDDigi library:')
  logger.error('|  %-100s  |', str(X))
  logger.error('+--%-100s--+', 100 * '-')
Marko Petric's avatar
Marko Petric committed
core = dd4hep
digi = dd4hep.digi
Kernel = digi.KernelHandle
Interface = digi.DigiActionCreation
Markus Frank's avatar
Markus Frank committed
Detector = core.Detector


Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
Marko Petric's avatar
Marko Petric committed
def _constant(self, name):
  return self.constantAsString(name)

Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
Marko Petric's avatar
Marko Petric committed
def importConstants(description, namespace=None, debug=False):
Markus Frank's avatar
Markus Frank committed
  """
  Import the Detector constants into the dddigi namespace
  """
Marko Petric's avatar
Marko Petric committed
  if namespace is not None and not hasattr(current, namespace):
    m = imp.new_module('dddigi.' + namespace)
Marko Petric's avatar
Marko Petric committed
    setattr(current, namespace, m)
    ns = m
  evaluator = dd4hep.g4Evaluator()
  cnt = 0
  num = 0
  todo = {}
  strings = {}
  for c in description.constants():
    if c.second.dataType == 'string':
      strings[c.first] = c.second.GetTitle()
    else:
Marko Petric's avatar
Marko Petric committed
      todo[c.first] = c.second.GetTitle().replace('(int)', '')
  while len(todo) and cnt < 100:
Marko Petric's avatar
Marko Petric committed
      logger.info('%s %d out of %d %s "%s": [%s]\n+++ %s',
                  '+++ FAILED to import',
                  len(todo), len(todo) + num,
                  'global values into namespace',
                  ns.__name__, 'Try to continue anyway', 100 * '=')
      for k, v in todo.items():
        if not hasattr(ns, k):
          logger.info('+++ FAILED to import: "' + k + '" = "' + str(v) + '"')
      logger.info('+++ %s', 100 * '=')

    for k, v in todo.items():
      if not hasattr(ns, k):
        val = evaluator.evaluate(v)
        status = evaluator.status()
        if status == 0:
Marko Petric's avatar
Marko Petric committed
          evaluator.setVariable(k, val)
          setattr(ns, k, val)
          if debug:
            logger.info('Imported global value: "' + k + '" = "' + str(val) + '" into namespace' + ns.__name__)
Marko Petric's avatar
Marko Petric committed
  if cnt < 100:
    logger.info('+++ Imported %d global values to namespace:%s', num, ns.__name__,)
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
def _getKernelProperty(self, name):
Marko Petric's avatar
Marko Petric committed
  ret = Interface.getPropertyKernel(self.get(), name)
Marko Petric's avatar
Marko Petric committed
  elif hasattr(self.get(), name):
    return getattr(self.get(), name)
  elif hasattr(self, name):
    return getattr(self, name)
  msg = 'DigiKernel::GetProperty [Unhandled]: Cannot access Kernel.' + name
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
def _setKernelProperty(self, name, value):
Marko Petric's avatar
Marko Petric committed
  if Interface.setPropertyKernel(self.get(), str(name), str(value)):
Marko Petric's avatar
Marko Petric committed
  msg = 'DigiKernel::SetProperty [Unhandled]: Cannot set Kernel.' + name + ' = ' + str(value)
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
Marko Petric's avatar
Marko Petric committed
def _kernel_terminate(self):
  return self.get().terminate()
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
Kernel.__getattr__ = _getKernelProperty
Kernel.__setattr__ = _setKernelProperty
Marko Petric's avatar
Marko Petric committed
Kernel.terminate = _kernel_terminate
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
ActionHandle = digi.ActionHandle
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
def Action(kernel, nam, parallel=False):
Marko Petric's avatar
Marko Petric committed
  obj = Interface.createAction(kernel, str(nam))
Markus Frank's avatar
Markus Frank committed
# ---------------------------------------------------------------------------
def EventAction(kernel, nam, parallel=False):
  obj = Interface.createEventAction(kernel, str(nam))
  obj.parallel = parallel
  return obj
# ---------------------------------------------------------------------------

def TestAction(kernel, nam, sleep=0):
  obj = Interface.createEventAction(kernel, str('DigiTestAction/' + nam))
  if sleep != 0:
    obj.sleep = sleep
  return obj
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
def ActionSequence(kernel, nam, parallel=False):
Marko Petric's avatar
Marko Petric committed
  obj = Interface.createSequence(kernel, str(nam))
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
def Synchronize(kernel, nam, parallel=False):
Marko Petric's avatar
Marko Petric committed
  obj = Interface.createSync(kernel, str(nam))
Marko Petric's avatar
Marko Petric committed
# ---------------------------------------------------------------------------
Marko Petric's avatar
Marko Petric committed
  def _adopt(self, action):
    self.__adopt(action.get())
Marko Petric's avatar
Marko Petric committed
  _import_class('digi', obj)
  cls = getattr(current, obj)
  setattr(cls, '__adopt', getattr(cls, 'adopt'))
  setattr(cls, 'adopt', _adopt)
  # setattr(cls,'add',_adopt)
  return cls
def _get(self, name):
  a = Interface.toAction(self)
Marko Petric's avatar
Marko Petric committed
  ret = Interface.getProperty(a, name)
Marko Petric's avatar
Marko Petric committed
  elif hasattr(self.action, name):
    return getattr(self.action, name)
  elif hasattr(a, name):
    return getattr(a, name)
  msg = 'DDDigiAction::GetProperty [Unhandled]: Cannot access property ' + a.name() + '.' + name
  """This function is called when properties are passed to the c++ objects."""
Markus Frank's avatar
Markus Frank committed
  import dd4hep as dd4hep
Markus Frank's avatar
Markus Frank committed
  name = dd4hep.unicode_2_string(name)
  value = dd4hep.unicode_2_string(value)
  if Interface.setProperty(a, name, value):
  msg = 'DDDigiAction::SetProperty [Unhandled]: Cannot set ' + a.name() + '.' + name + ' = ' + value
def _props(obj, **extensions):
Marko Petric's avatar
Marko Petric committed
  _import_class('digi', obj)
  cls = getattr(current, obj)
  for extension in extensions.items():
    setattr(cls, extension[0], extension[1])
  cls.__getattr__ = _get
  cls.__setattr__ = _set
  return cls
_setup('DigiActionSequence')
_setup('DigiSynchronize')

_import_class('digi', 'DigiKernel')
_import_class('digi', 'DigiContext')
_import_class('digi', 'DigiAction')
_import_class('digi', 'DigiEventAction')
_import_class('digi', 'DigiInputAction')
_props('EventActionHandle')
_props('InputActionHandle')
_props('ActionSequenceHandle')
_props('SynchronizeHandle')

def adopt_sequence_action(self, name, **options):
  kernel = Interface.createKernel(Interface.toAction(self))
  action = EventAction(kernel, name)
  for option in options.items():
    setattr(action, option[0], option[1])
  self.adopt(action)
  return action

_props('DigiSynchronize')
Markus Frank's avatar
Markus Frank committed
_props('DigiActionSequence', adopt_action=adopt_sequence_action)
_props('DigiParallelActionSequence', adopt_action=adopt_sequence_action)
_props('DigiSequentialActionSequence', adopt_action=adopt_sequence_action)

Markus Frank's avatar
Markus Frank committed
# Need to import digitize late, since it cross includes dddigi
Digitize = None
try:
  import digitize
  Digitize = digitize.Digitize
except Exception as X:
Markus Frank's avatar
Markus Frank committed
  logger.error('Failed to import digitize: '+str(X))