File indexing completed on 2025-07-15 08:14:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 from __future__ import absolute_import, unicode_literals
0012 import cppyy
0013 import importlib
0014 import types
0015 import logging
0016
0017
0018 logger = logging.getLogger(__name__)
0019
0020
0021 def compileAClick(dictionary, g4=True):
0022 """
0023 We compile the DDG4 plugin on the fly if it does not exist using the AClick mechanism.
0024
0025 """
0026 from ROOT import gInterpreter, gSystem
0027 import os.path
0028 dd4hep = os.getenv("DD4hepINSTALL", "/usr")
0029 rootsys = os.getenv("ROOTSYS", "/usr")
0030
0031 inc = ' -I' + rootsys + '/include -I' + dd4hep + '/include '
0032 lib = ' -L' + dd4hep + '/lib64 ' + ' -L' + dd4hep + '/lib -lDDCore -lDDG4 -lDDSegmentation '
0033 if g4:
0034 geant4 = os.getenv('G4INSTALL', "/usr")
0035 inc = inc + ' -I' + geant4 + '/include/Geant4 -Wno-shadow -g -O0 '
0036 lib = lib + ' -L' + geant4 + '/lib64 -L' + geant4 + '/lib -lG4event -lG4tracking -lG4particles '
0037
0038 gSystem.AddIncludePath(inc)
0039 gSystem.AddLinkedLibs(lib)
0040 logger.info('Loading AClick %s', dictionary)
0041 package_spec = importlib.util.find_spec('DDG4')
0042 dic = os.path.dirname(package_spec.origin) + os.sep + dictionary
0043 gInterpreter.ProcessLine('.L ' + dic + '+')
0044 from ROOT import dd4hep as module
0045 return module
0046
0047
0048 def loaddd4hep():
0049 """
0050 Import DD4hep module from ROOT using ROOT reflection
0051 """
0052 import os
0053 import sys
0054
0055 rootsys = os.getenv("ROOTSYS", "/usr")
0056 sys.path.append(os.path.join(rootsys, 'lib'))
0057 sys.path.append(os.path.join(rootsys, 'lib64'))
0058 sys.path.append(os.path.join(rootsys, 'lib', 'root'))
0059 sys.path.append(os.path.join(rootsys, 'lib64', 'root'))
0060 from ROOT import gSystem
0061
0062 import platform
0063 if platform.system() == "Darwin":
0064 gSystem.SetDynamicPath(os.environ['DD4HEP_LIBRARY_PATH'])
0065 os.environ['DYLD_LIBRARY_PATH'] = os.pathsep.join([os.environ['DD4HEP_LIBRARY_PATH'],
0066 os.environ.get('DYLD_LIBRARY_PATH', '')]).strip(os.pathsep)
0067 result = gSystem.Load("libDDCore")
0068 if result < 0:
0069 raise Exception('dd4hep.py: Failed to load the dd4hep library libDDCore: ' + gSystem.GetErrorStr())
0070 from ROOT import dd4hep as module
0071 return module
0072
0073
0074
0075 name_space = __import__(__name__)
0076
0077
0078 def import_namespace_item(ns, nam):
0079 scope = getattr(name_space, ns)
0080 attr = getattr(scope, nam)
0081 setattr(name_space, nam, attr)
0082 return attr
0083
0084
0085 def import_root(nam):
0086 setattr(name_space, nam, getattr(ROOT, nam))
0087
0088
0089
0090
0091 try:
0092 dd4hep = loaddd4hep()
0093 import ROOT
0094 except Exception as X:
0095 import sys
0096 logger.error('+--%-100s--+', 100 * '-')
0097 logger.error('| %-100s |', 'Failed to load dd4hep base library:')
0098 logger.error('| %-100s |', str(X))
0099 logger.error('+--%-100s--+', 100 * '-')
0100 sys.exit(1)
0101
0102
0103 class _Levels:
0104 def __init__(self):
0105 self.VERBOSE = 1
0106 self.DEBUG = 2
0107 self.INFO = 3
0108 self.WARNING = 4
0109 self.ERROR = 5
0110 self.FATAL = 6
0111 self.ALWAYS = 7
0112
0113
0114
0115 def unicode_2_string(value):
0116 """Turn any unicode literal into str, needed when passing to c++.
0117
0118 Recursively transverses dicts, lists, sets, tuples
0119
0120 :return: always a str
0121 """
0122 if isinstance(value, (bool, float, int)):
0123 value = value
0124 elif isinstance(value, str):
0125 value = str(value)
0126 elif isinstance(value, bytes):
0127 value = value.decode()
0128 elif isinstance(value, (list, set, tuple)):
0129 value = [unicode_2_string(x) for x in value]
0130 elif isinstance(value, dict):
0131 tempDict = {}
0132 for key, val in value.items():
0133 key = unicode_2_string(key)
0134 val = unicode_2_string(val)
0135 tempDict[key] = val
0136 value = tempDict
0137 return str(value)
0138
0139
0140 OutputLevel = _Levels()
0141 VERBOSE = OutputLevel.VERBOSE
0142 DEBUG = OutputLevel.DEBUG
0143 INFO = OutputLevel.INFO
0144 WARNING = OutputLevel.WARNING
0145 ERROR = OutputLevel.ERROR
0146 FATAL = OutputLevel.FATAL
0147
0148
0149
0150
0151
0152
0153
0154
0155 std = cppyy.gbl.std
0156 std_vector = std.vector
0157 std_list = std.list
0158 std_map = std.map
0159 std_pair = std.pair
0160
0161 core = dd4hep
0162 cond = dd4hep.cond
0163 tools = dd4hep.tools
0164 align = dd4hep.align
0165 detail = dd4hep.detail
0166 units = types.ModuleType('units')
0167
0168 import_namespace_item('tools', 'Evaluator')
0169
0170 import_namespace_item('core', 'NamedObject')
0171 import_namespace_item('core', 'run_interpreter')
0172
0173 import_namespace_item('detail', 'interp')
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184 def import_detail():
0185 import_namespace_item('detail', 'DD4hepUI')
0186
0187
0188
0189 def import_geometry():
0190 import_namespace_item('core', 'setPrintLevel')
0191 import_namespace_item('core', 'setPrintFormat')
0192 import_namespace_item('core', 'printLevel')
0193 import_namespace_item('core', 'PrintLevel')
0194
0195 import_namespace_item('core', 'debug')
0196 import_namespace_item('core', 'info')
0197 import_namespace_item('core', 'warning')
0198 import_namespace_item('core', 'error')
0199 import_namespace_item('core', 'fatal')
0200 import_namespace_item('core', 'exception')
0201
0202 import_namespace_item('core', 'Detector')
0203 import_namespace_item('core', 'evaluator')
0204 import_namespace_item('core', 'g4Evaluator')
0205
0206 import_namespace_item('core', 'VolumeManager')
0207 import_namespace_item('core', 'OverlayedField')
0208 import_namespace_item('core', 'Ref_t')
0209
0210
0211 import_namespace_item('core', 'Author')
0212 import_namespace_item('core', 'Header')
0213 import_namespace_item('core', 'Constant')
0214 import_namespace_item('core', 'Atom')
0215 import_namespace_item('core', 'Material')
0216 import_namespace_item('core', 'VisAttr')
0217 import_namespace_item('core', 'Limit')
0218 import_namespace_item('core', 'LimitSet')
0219 import_namespace_item('core', 'LimitSetObject')
0220 import_namespace_item('core', 'Region')
0221 import_namespace_item('core', 'RegionObject')
0222 import_namespace_item('core', 'HitCollection')
0223
0224
0225 import_namespace_item('core', 'Segmentation')
0226 import_namespace_item('core', 'SegmentationObject')
0227 import_namespace_item('core', 'Readout')
0228 import_namespace_item('core', 'ReadoutObject')
0229
0230
0231 import_namespace_item('core', 'Alignment')
0232 import_namespace_item('core', 'AlignmentCondition')
0233
0234
0235 import_namespace_item('core', 'Condition')
0236 import_namespace_item('core', 'ConditionKey')
0237
0238
0239 import_namespace_item('core', 'World')
0240 import_namespace_item('core', 'DetElement')
0241 import_namespace_item('core', 'SensitiveDetector')
0242
0243
0244 import_namespace_item('core', 'Volume')
0245 import_namespace_item('core', 'PlacedVolume')
0246
0247
0248 import_namespace_item('core', 'Solid')
0249 import_namespace_item('core', 'Box')
0250 import_namespace_item('core', 'HalfSpace')
0251 import_namespace_item('core', 'Polycone')
0252 import_namespace_item('core', 'ConeSegment')
0253 import_namespace_item('core', 'Tube')
0254 import_namespace_item('core', 'CutTube')
0255 import_namespace_item('core', 'TruncatedTube')
0256 import_namespace_item('core', 'EllipticalTube')
0257 import_namespace_item('core', 'Cone')
0258 import_namespace_item('core', 'Trap')
0259 import_namespace_item('core', 'PseudoTrap')
0260 import_namespace_item('core', 'Trapezoid')
0261 import_namespace_item('core', 'Torus')
0262 import_namespace_item('core', 'Sphere')
0263 import_namespace_item('core', 'Paraboloid')
0264 import_namespace_item('core', 'Hyperboloid')
0265 import_namespace_item('core', 'PolyhedraRegular')
0266 import_namespace_item('core', 'Polyhedra')
0267 import_namespace_item('core', 'ExtrudedPolygon')
0268 import_namespace_item('core', 'EightPointSolid')
0269 import_namespace_item('core', 'BooleanSolid')
0270 import_namespace_item('core', 'SubtractionSolid')
0271 import_namespace_item('core', 'UnionSolid')
0272 import_namespace_item('core', 'IntersectionSolid')
0273
0274
0275
0276 def import_tgeo():
0277 import_root('TGeoManager')
0278 import_root('TGeoNode')
0279 import_root('TGeoNodeMatrix')
0280
0281 import_root('TGeoVolume')
0282 import_root('TGeoVolumeMulti')
0283 import_root('TGeoVolumeAssembly')
0284
0285 import_root('TGeoMaterial')
0286 import_root('TGeoMedium')
0287 import_root('TGeoIsotope')
0288 import_root('TGeoElement')
0289
0290 import_root('TGeoMatrix')
0291 import_root('TGeoHMatrix')
0292 import_root('TGeoIdentity')
0293 import_root('TGeoTranslation')
0294 import_root('TGeoRotation')
0295 import_root('TGeoScale')
0296 import_root('TGeoCombiTrans')
0297
0298 import_root('TGeoShape')
0299 import_root('TGeoBBox')
0300 import_root('TGeoArb8')
0301 import_root('TGeoTrap')
0302 import_root('TGeoGtra')
0303 import_root('TGeoCompositeShape')
0304 import_root('TGeoCone')
0305 import_root('TGeoConeSeg')
0306 import_root('TGeoTube')
0307 import_root('TGeoTubeSeg')
0308 import_root('TGeoCtub')
0309 import_root('TGeoEltu')
0310 import_root('TGeoHype')
0311 import_root('TGeoHalfSpace')
0312 import_root('TGeoPara')
0313 import_root('TGeoParaboloid')
0314 import_root('TGeoPcon')
0315 import_root('TGeoPgon')
0316 import_root('TGeoScaledShape')
0317 import_root('TGeoShapeAssembly')
0318 import_root('TGeoSphere')
0319 import_root('TGeoTorus')
0320 import_root('TGeoTrd1')
0321 import_root('TGeoTrd2')
0322 import_root('TGeoXtru')
0323
0324
0325 import_tgeo()
0326 import_geometry()
0327 import_detail()
0328
0329
0330
0331 class Logger:
0332 """
0333 Helper class to use the dd4hep printout functions from python
0334
0335 \author M.Frank
0336 \version 1.0
0337 """
0338
0339 def __init__(self, name):
0340 "Logger constructor"
0341 self.name = name
0342
0343 def setPrintLevel(self, level):
0344 "Adjust printout level of dd4hep"
0345 if isinstance(level, str):
0346 if level == 'VERBOSE':
0347 level = OutputLevel.VERBOSE
0348 elif level == 'DEBUG':
0349 level = OutputLevel.DEBUG
0350 elif level == 'INFO':
0351 level = OutputLevel.INFO
0352 elif level == 'WARNING':
0353 level = OutputLevel.WARNING
0354 elif level == 'ERROR':
0355 level = OutputLevel.ERROR
0356 elif level == 'FATAL':
0357 level = OutputLevel.FATAL
0358 else:
0359 level = int(level)
0360 dd4hep.setPrintLevel(level)
0361
0362 def always(self, msg):
0363 "Call dd4hep printout function with level ALWAYS"
0364 dd4hep.always(self.name, msg)
0365
0366 def verbose(self, msg):
0367 "Call dd4hep printout function with level VERBOSE"
0368 dd4hep.verbose(self.name, msg)
0369
0370 def debug(self, msg):
0371 "Call dd4hep printout function with level DEBUG"
0372 dd4hep.debug(self.name, msg)
0373
0374 def info(self, msg):
0375 "Call dd4hep printout function with level INFO"
0376 dd4hep.info(self.name, msg)
0377
0378 def warning(self, msg):
0379 "Call dd4hep printout function with level WARNING"
0380 dd4hep.warning(self.name, msg)
0381
0382 def error(self, msg):
0383 "Call dd4hep printout function with level ERROR"
0384 dd4hep.error(self.name, msg)
0385
0386 def fatal(self, msg):
0387 "Call dd4hep printout function with level FATAL"
0388 dd4hep.fatal(self.name, msg)
0389
0390 def exception(self, msg):
0391 "Call dd4hep exception function"
0392 dd4hep.exception(self.name, msg)
0393
0394
0395 dd4hep_logger = Logger
0396
0397
0398
0399
0400
0401
0402
0403 class CommandLine:
0404 """
0405 Helper to ease parsing the command line.
0406 Any argument given in the command line is accessible
0407 from the object. If no value is supplied, the returned
0408 value is True. If the argument is not present None is returned.
0409
0410 \author M.Frank
0411 \version 1.0
0412 """
0413 def __init__(self, help=None):
0414 import sys
0415 self.data = {}
0416 help_call = help
0417 have_help = False
0418 for i in range(len(sys.argv)):
0419 if sys.argv[i][0] == '-':
0420 key = sys.argv[i][1:]
0421 val = True
0422 if i + 1 < len(sys.argv):
0423 v = sys.argv[i + 1]
0424 if v[0] != '-':
0425 val = v
0426 self.data[key] = val
0427 if key.upper() == 'HELP' or key.upper() == '?':
0428 have_help = True
0429 if have_help and help_call:
0430 help_call()
0431 if self.data.get('print_level'):
0432 log = Logger('CommandLine')
0433 log.setPrintLevel(self.data.get('print_level'))
0434
0435 def __getattr__(self, attr):
0436 if self.data.get(attr):
0437 return self.data.get(attr)
0438 return None
0439
0440
0441
0442
0443
0444
0445
0446 try:
0447 import_namespace_item('core', 'dd4hep_units')
0448
0449 def import_units(ns=None):
0450 if ns is None:
0451 ns = name_space
0452
0453 logger.debug('Importing units into namespace ' + str(ns.__name__))
0454 count = 0
0455 for nam in dir(dd4hep.dd4hep_units):
0456 if nam[0] != '_':
0457 count = count + 1
0458 setattr(ns, nam, getattr(core.dd4hep_units, nam))
0459
0460 return count
0461
0462 except Exception as e:
0463 logger.warning('No units can be imported. ' + str(e))
0464
0465 def import_units(ns=None):
0466 return 0
0467
0468 import_units(ns=units)