Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:14:28

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.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   # Add ROOT to the python path in case it is not yet there....
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 # We are nearly there ....
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 # ------------------------Generic STL stuff can be accessed using std:  -----
0150 #
0151 # -- e.g. Create an instance of std::vector<dd4hep::sim::Geant4Vertex*>:
0152 #    >>> v=dd4hep.vector('dd4hep::sim::Geant4Vertex*')()
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 # No: This inhibits the usage of native python eval!
0175 # import_namespace_item('detail', 'eval')
0176 
0177 # ---------------------------------------------------------------------------
0178 # def run_interpreter(name):   detail.interp.run(name)
0179 # def evaluator():     return eval.instance()
0180 # def g4Evaluator():   return eval.g4instance()
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   # // Objects.h
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   # // Readout.h
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   # // Alignments.h
0231   import_namespace_item('core', 'Alignment')
0232   import_namespace_item('core', 'AlignmentCondition')
0233 
0234   # // Conditions.h
0235   import_namespace_item('core', 'Condition')
0236   import_namespace_item('core', 'ConditionKey')
0237 
0238   # // DetElement.h
0239   import_namespace_item('core', 'World')
0240   import_namespace_item('core', 'DetElement')
0241   import_namespace_item('core', 'SensitiveDetector')
0242 
0243   # // Volume.h
0244   import_namespace_item('core', 'Volume')
0245   import_namespace_item('core', 'PlacedVolume')
0246 
0247   # // Shapes.h
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 # Helper: Command line interpreter
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):  # noqa: A002
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 #  Import units from TGeo.
0444 #  Calling import_units makes all the units local to the dd4hep module.
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         # setattr(ns, nam, getattr(core, nam))
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)