File indexing completed on 2025-01-18 09:14:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 from __future__ import absolute_import, unicode_literals
0012 import cppyy
0013 from dd4hep_base import *
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
0027
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
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
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
0052 from ROOT import dd4hep as module
0053 return module
0054
0055
0056
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
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
0269
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,)):
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
0300 if hasattr(cls, call):
0301
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
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
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
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