Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:07

0001 # ==========================================================================
0002 #  AIDA Detector description implementation
0003 # --------------------------------------------------------------------------
0004 # Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 # All rights reserved.
0006 #
0007 # For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 # For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 #
0010 # ==========================================================================
0011 from __future__ import absolute_import, unicode_literals
0012 import cppyy
0013 from dd4hep_base import *  # noqa: F401, F403
0014 
0015 logger = None
0016 
0017 
0018 def loadDDDigi():
0019   global logger
0020   import ROOT
0021   import dd4hep_base
0022   from ROOT import gSystem
0023 
0024   logger = dd4hep_base.dd4hep_logger('dddigi')
0025 
0026   # Try to load libglapi to avoid issues with TLS Static
0027   # Turn off all errors from ROOT about the library missing
0028   if 'libglapi' not in gSystem.GetLibraries():
0029     orgLevel = ROOT.gErrorIgnoreLevel
0030     ROOT.gErrorIgnoreLevel = 6000
0031     gSystem.Load("libglapi")
0032     ROOT.gErrorIgnoreLevel = orgLevel
0033 
0034   import os
0035   import platform
0036   if platform.system() == "Darwin":
0037     gSystem.SetDynamicPath(os.environ['DD4HEP_LIBRARY_PATH'])
0038   #
0039   # load with ROOT the DDDigi plugin library, which in turn loads the DDigi module
0040   result = gSystem.Load("libDDDigiPlugins")
0041   if result < 0:
0042     raise Exception('DDDigi.py: Failed to load the DDDigi library libDDDigiPlugins: ' + gSystem.GetErrorStr())
0043   logger.info('DDDigi.py: Successfully loaded DDDigi plugin library libDDDigiPlugins!')
0044   #
0045   # import with ROOT the I/O module to read DDG4 output
0046   result = gSystem.Load("libDDDigi_IO")
0047   if result < 0:
0048     raise Exception('DDDigi.py: Failed to load the DDDigi IO library libDDDigi_IO: ' + gSystem.GetErrorStr())
0049   logger.info('DDDigi.py: Successfully loaded DDDigi IO plugin library libDDDigi_IO!')
0050   #
0051   # import the main dd4hep module from ROOT
0052   from ROOT import dd4hep as module
0053   return module
0054 
0055 
0056 # We are nearly there ....
0057 current = __import__(__name__)
0058 
0059 
0060 def _import_class(ns, nam):
0061   scope = getattr(current, ns)
0062   setattr(current, nam, getattr(scope, nam))
0063 
0064 
0065 # ---------------------------------------------------------------------------
0066 #
0067 try:
0068   dd4hep = loadDDDigi()
0069 except Exception as X:
0070   logger.error('+--%-100s--+' % (100 * '-',))
0071   logger.error('|  %-100s  |' % ('Failed to load DDDigi library:',))
0072   logger.error('|  %-100s  |' % (str(X),))
0073   logger.error('+--%-100s--+' % (100 * '-',))
0074   exit(1)
0075 
0076 core = dd4hep
0077 digi = dd4hep.digi
0078 Kernel = digi.KernelHandle
0079 Interface = digi.DigiActionCreation
0080 Detector = core.Detector
0081 
0082 
0083 # ---------------------------------------------------------------------------
0084 def _constant(self, name):
0085   return self.constantAsString(name)
0086 
0087 
0088 Detector.globalVal = _constant
0089 # ---------------------------------------------------------------------------
0090 
0091 
0092 def importConstants(description, namespace=None, debug=False):
0093   """
0094   Import the Detector constants into the dddigi namespace
0095   """
0096   ns = current
0097   if namespace is not None and not hasattr(current, namespace):
0098     import types
0099     m = types.ModuleType('dddigi.' + namespace)
0100     setattr(current, namespace, m)
0101     ns = m
0102   evaluator = dd4hep.g4Evaluator()
0103   cnt = 0
0104   num = 0
0105   todo = {}
0106   strings = {}
0107   for c in description.constants():
0108     if c.second.dataType == 'string':
0109       strings[str(c.first)] = c.second.GetTitle()
0110     else:
0111       todo[str(c.first)] = c.second.GetTitle().replace('(int)', '')
0112   while len(todo) and cnt < 100:
0113     cnt = cnt + 1
0114     if cnt == 100:
0115       logger.info('%s %d out of %d %s "%s": [%s]\n+++ %s' %
0116                   ('+++ FAILED to import',
0117                    len(todo), len(todo) + num,
0118                    'global values into namespace',
0119                    ns.__name__, 'Try to continue anyway', 100 * '=',))
0120       for k, v in todo.items():
0121         if not hasattr(ns, k):
0122           logger.info('+++ FAILED to import: "' + k + '" = "' + str(v) + '"')
0123       logger.info('+++ %s' % (100 * '=',))
0124 
0125     for k, v in list(todo.items()):
0126       if not hasattr(ns, k):
0127         val = evaluator.evaluate(v)
0128         status = evaluator.status()
0129         if status == 0:
0130           evaluator.setVariable(k, val)
0131           setattr(ns, k, val)
0132           if debug:
0133             logger.info('Imported global value: "' + k + '" = "' + str(val) + '" into namespace' + ns.__name__)
0134           del todo[k]
0135           num = num + 1
0136   if cnt < 100:
0137     logger.info('+++ Imported %d global values to namespace:%s' % (num, ns.__name__),)
0138 
0139 
0140 def TestAction(kernel, nam, sleep=0):
0141   obj = Interface.createAction(kernel, str('DigiTestAction/' + nam))
0142   if sleep != 0:
0143     obj.sleep = sleep
0144   return obj
0145 # ---------------------------------------------------------------------------
0146 
0147 
0148 def Action(kernel, nam, **options):
0149   action = Interface.createAction(kernel, str(nam))
0150   for option in options.items():
0151     setattr(action, option[0], option[1])
0152   return action
0153 # ---------------------------------------------------------------------------
0154 
0155 
0156 def _get_action(self):
0157   " Convert handles to action references to access underlying properties provided a dictionary exists. "
0158   return Interface.toAction(self)
0159 
0160 
0161 # ---------------------------------------------------------------------------
0162 def _adopt_property(self, action, foreign_name, local_name=None):
0163   proc = _get_action(action)
0164   if not local_name:
0165     local_name = foreign_name
0166   _get_action(self).adopt_property(proc, str(foreign_name), str(local_name))
0167 
0168 
0169 # ---------------------------------------------------------------------------
0170 def _add_new_property(self, name, value):
0171   Interface.addProperty(_get_action(self), str(name), value)
0172 
0173 
0174 # ---------------------------------------------------------------------------
0175 def _add_new_position_property(self, name, value):
0176   Interface.addPositionProperty(_get_action(self), str(name), str(value))
0177 
0178 
0179 # ---------------------------------------------------------------------------
0180 def _add_new_set_property(self, name, value):
0181   Interface.addSetProperty(_get_action(self), str(name), value)
0182 
0183 
0184 # ---------------------------------------------------------------------------
0185 def _add_new_list_property(self, name, value):
0186   Interface.addListProperty(_get_action(self), str(name), value)
0187 
0188 
0189 # ---------------------------------------------------------------------------
0190 def _add_new_vector_property(self, name, value):
0191   Interface.addVectorProperty(_get_action(self), str(name), value)
0192 
0193 
0194 # ---------------------------------------------------------------------------
0195 def _add_new_mapped_property(self, name, value):
0196   Interface.addMappedProperty(_get_action(self), str(name), value)
0197 # ---------------------------------------------------------------------------
0198 
0199 
0200 def _kernel_terminate(self):
0201   return self.get().terminate()
0202 # ---------------------------------------------------------------------------
0203 
0204 
0205 def _default_adopt(self, action):
0206   self.__adopt(action.get())
0207 # ---------------------------------------------------------------------------
0208 
0209 
0210 def _adopt_event_action(self, action):
0211   " Helper to convert DigiActions objects to DigiEventAction "
0212   proc = Interface.toEventAction(_get_action(action))
0213   attr = self.__adopt
0214   attr(proc)
0215 # ---------------------------------------------------------------------------
0216 
0217 
0218 def _adopt_container_processor(self, action, processor_argument):
0219   " Helper to convert DigiActions objects to DigiEventAction "
0220   parent = Interface.toContainerSequenceAction(_get_action(self))
0221   attr = parent.adopt_processor
0222   proc = Interface.toContainerProcessor(_get_action(action))
0223   attr(proc, processor_argument)
0224 # ---------------------------------------------------------------------------
0225 
0226 
0227 def _adopt_segment_processor(self, action, processor_argument):
0228   " Helper to convert DigiActions objects to DigiEventAction "
0229   attr = _get_action(self).__adopt_segment_processor
0230   proc = Interface.toContainerProcessor(_get_action(action))
0231   attr(proc, processor_argument)
0232 # ---------------------------------------------------------------------------
0233 
0234 
0235 def _adopt_sequence_action(self, name, **options):
0236   " Helper to adopt DigiAction objects for DigiSynchronize "
0237   kernel = Interface.createKernel(_get_action(self))
0238   action = Action(kernel, name)
0239   for option in options.items():
0240     setattr(action, option[0], option[1])
0241   self.adopt(action)
0242   return action
0243 # ---------------------------------------------------------------------------
0244 
0245 
0246 def _adopt_processor(self, action, containers):
0247   proc = Interface.toContainerProcessor(_get_action(action))
0248   attr = _get_action(self).__adopt_processor
0249   attr(proc, containers)
0250 # ---------------------------------------------------------------------------
0251 
0252 
0253 def _get(self, name):
0254   a = Interface.toAction(self)
0255   ret = Interface.getProperty(a, name)
0256   if ret.status > 0:
0257     # print('Property: %s = %s [%s]' % (name, str(ret.data), str(ret.data.__class__),))
0258     v = ret.data
0259     try:
0260       v = eval(v)
0261     except TypeError:
0262       pass
0263     finally:
0264       pass
0265     return v
0266   elif hasattr(a, name):
0267     return getattr(a, name)
0268   # elif a.__class__ != self.__class__ and hasattr(a, name):
0269   #   return getattr(a, name)
0270   msg = 'DigiAction::GetProperty [Unhandled]: Cannot access property ' + a.name() + '.' + str(name)
0271   raise KeyError(msg)
0272 # ---------------------------------------------------------------------------
0273 
0274 
0275 def _set(self, name, value):
0276   """This function is called when properties are passed to the c++ objects."""
0277   import dd4hep as dd4hep
0278   act = _get_action(self)
0279   nam = dd4hep.unicode_2_string(name)
0280   if isinstance(value, (list,)):  # cppyy.gbl.string showing up for some reason
0281     value = [x.decode('utf-8') if isinstance(x, cppyy.gbl.std.string) else x for x in value]
0282   if isinstance(value, str):
0283     val = dd4hep.unicode_2_string(value)
0284   else:
0285     val = str(value)
0286   if Interface.setProperty(act, nam, val):
0287     return
0288   msg = 'DigiAction::SetProperty [Unhandled]: Cannot set ' + act.name() + '.' + str(name) + ' = ' + str(value)
0289   raise KeyError(msg)
0290 # ---------------------------------------------------------------------------
0291 
0292 
0293 def _props(obj, **extensions):
0294   from dd4hep_base import debug as dd4hep_debug
0295   _import_class('digi', obj)
0296   cls = getattr(current, obj)
0297   for extension in extensions.items():
0298     call = extension[0]
0299     # print('TRY: Overloading: ' + str(cls) + ' ' + call + ' to __' + call + ' ' + str(hasattr(cls, call)))
0300     if hasattr(cls, call):
0301       # print('Overloading: ' + str(cls) + ' ' + call + ' to __' + call)
0302       setattr(cls, '__' + call, getattr(cls, call))
0303     else:
0304       dd4hep_debug('FAILED', 'Overloading: ' + str(cls) + ' ' + call + ' to __' + call + ' ' + str(hasattr(cls, call)))
0305     setattr(cls, call, extension[1])
0306   cls.__getattr__ = _get
0307   cls.__setattr__ = _set
0308   return cls
0309 # ---------------------------------------------------------------------------
0310 
0311 
0312 #
0313 # Import unmodified classes from C++
0314 _import_class('digi', 'DigiContext')
0315 
0316 
0317 # ---------------------------------------------------------------------------
0318 Kernel = _props('KernelHandle')
0319 _props('DigiKernel')
0320 _props('DigiAction')
0321 _import_class('digi', 'DigiEventAction')
0322 _import_class('digi', 'DigiInputAction')
0323 #
0324 # Import classes with specialized python extensions
0325 _props('ActionHandle',
0326        adopt_property=_adopt_property,
0327        add_property=_add_new_property,
0328        add_position_property=_add_new_position_property,
0329        add_set_property=_add_new_set_property,
0330        add_list_property=_add_new_list_property,
0331        add_vector_property=_add_new_vector_property,
0332        add_mapped_property=_add_new_mapped_property,
0333        adopt_container_processor=_adopt_container_processor)
0334 _props('DigiSynchronize', adopt=_adopt_event_action, adopt_action=_adopt_sequence_action)
0335 _props('DigiActionSequence', adopt=_adopt_event_action, adopt_action=_adopt_sequence_action)
0336 _props('DigiParallelActionSequence', adopt_action=_adopt_sequence_action)
0337 _props('DigiSequentialActionSequence', adopt_action=_adopt_sequence_action)
0338 _props('DigiContainerSequenceAction', adopt_container_processor=_adopt_container_processor)
0339 _props('DigiMultiContainerProcessor', adopt_processor=_adopt_processor)
0340 _props('DigiSegmentSplitter', adopt_segment_processor=_adopt_segment_processor)
0341 # ---------------------------------------------------------------------------
0342 
0343 
0344 # ---------------------------------------------------------------------------
0345 #
0346 # Need to import digitize late, since it cross includes dddigi
0347 # ---------------------------------------------------------------------------
0348 Digitize = None
0349 try:
0350   import digitize
0351   Digitize = digitize.Digitize
0352 except Exception as X:
0353   logger.error('Failed to import digitize application: ' + str(X))
0354 # ---------------------------------------------------------------------------