Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:16:42

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 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   # Add ROOT to the python path in case it is not yet there....
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 # We are nearly there ....
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 # ------------------------Generic STL stuff can be accessed using std:  -----
0144 #
0145 # -- e.g. Create an instance of std::vector<dd4hep::sim::Geant4Vertex*>:
0146 #    >>> v=dd4hep.vector('dd4hep::sim::Geant4Vertex*')()
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 # No: This inhibits the usage of native python eval!
0169 # import_namespace_item('detail', 'eval')
0170 
0171 # ---------------------------------------------------------------------------
0172 # def run_interpreter(name):   detail.interp.run(name)
0173 # def evaluator():     return eval.instance()
0174 # def g4Evaluator():   return eval.g4instance()
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   # // Objects.h
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   # // Readout.h
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   # // Alignments.h
0225   import_namespace_item('core', 'Alignment')
0226   import_namespace_item('core', 'AlignmentCondition')
0227 
0228   # // Conditions.h
0229   import_namespace_item('core', 'Condition')
0230   import_namespace_item('core', 'ConditionKey')
0231 
0232   # // DetElement.h
0233   import_namespace_item('core', 'World')
0234   import_namespace_item('core', 'DetElement')
0235   import_namespace_item('core', 'SensitiveDetector')
0236 
0237   # // Volume.h
0238   import_namespace_item('core', 'Volume')
0239   import_namespace_item('core', 'PlacedVolume')
0240 
0241   # // Shapes.h
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 # Helper: Command line interpreter
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):  # noqa: A002
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 #  Import units from TGeo.
0438 #  Calling import_units makes all the units local to the dd4hep module.
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         # setattr(ns, nam, getattr(core, nam))
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)