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