File indexing completed on 2025-12-15 09:25:57
0001 import os
0002 import sys
0003 import math
0004 from pathlib import Path
0005 from typing import Optional
0006 import acts
0007 import acts.examples
0008 from acts import root
0009 import warnings
0010
0011
0012 def getOpenDataDetectorDirectory():
0013 odd_dir = os.environ.get("ODD_PATH")
0014 if odd_dir is None:
0015 raise RuntimeError("ODD_PATH environment variable not set")
0016 odd_dir = Path(odd_dir)
0017 return odd_dir
0018
0019
0020 def getOpenDataDetector(
0021 materialDecorator=None,
0022 misaligned=False,
0023 odd_dir: Optional[Path] = None,
0024 logLevel=acts.logging.INFO,
0025 gen3=False,
0026 ):
0027 """This function sets up the open data detector. Requires DD4hep.
0028 Parameters
0029 ----------
0030 materialDecorator: Material Decorator, take RootMaterialDecorator if non is given
0031 odd_dir: if not given, try to get via ODD_PATH environment variable
0032 logLevel: logging level
0033 """
0034 import acts.examples.dd4hep
0035
0036 customLogLevel = acts.examples.defaultLogging(logLevel=logLevel)
0037
0038 if odd_dir is None:
0039 odd_dir = getOpenDataDetectorDirectory()
0040 if not odd_dir.exists():
0041 raise RuntimeError(f"OpenDataDetector not found at {odd_dir}")
0042
0043 odd_xml = odd_dir / "xml" / "OpenDataDetector.xml"
0044 if not odd_xml.exists():
0045 raise RuntimeError(f"OpenDataDetector.xml not found at {odd_xml}")
0046
0047 env_vars = []
0048 map_name = "libOpenDataDetector.components"
0049 lib_name = None
0050 if sys.platform == "linux":
0051 env_vars = ["LD_LIBRARY_PATH"]
0052 lib_name = "libOpenDataDetector.so"
0053 elif sys.platform == "darwin":
0054 env_vars = ["DYLD_LIBRARY_PATH", "DD4HEP_LIBRARY_PATH"]
0055 lib_name = "libOpenDataDetector.dylib"
0056
0057 if lib_name is not None and len(env_vars) > 0:
0058 found = False
0059 for env_var in env_vars:
0060 for lib_dir in os.environ.get(env_var, "").split(":"):
0061 lib_dir = Path(lib_dir)
0062 if (lib_dir / map_name).exists() and (lib_dir / lib_name).exists():
0063 found = True
0064 break
0065 if not found:
0066 msg = (
0067 "Unable to find OpenDataDetector factory library. "
0068 f"You might need to point {'/'.join(env_vars)} to the ODD install location."
0069 f"It might be at {odd_dir / 'factory'}"
0070 )
0071 raise RuntimeError(msg)
0072
0073 if materialDecorator is None:
0074 materialDecorator = acts.root.RootMaterialDecorator(
0075 fileName=str(odd_dir / "data/odd-material-maps.root"),
0076 level=customLogLevel(minLevel=acts.logging.WARNING),
0077 )
0078
0079 if gen3:
0080 if misaligned:
0081 raise InvalidArgumentError(
0082 "Gen3 ODD currently does not support misalignment"
0083 )
0084
0085 oddConfig = acts.examples.dd4hep.OpenDataDetector.Config(
0086 xmlFileNames=[str(odd_xml)],
0087 name="OpenDataDetector",
0088 logLevel=customLogLevel(),
0089 dd4hepLogLevel=customLogLevel(minLevel=acts.logging.WARNING),
0090 )
0091
0092 gctx = acts.GeometryContext()
0093 with warnings.catch_warnings():
0094 warnings.simplefilter("ignore")
0095 detector = acts.examples.dd4hep.OpenDataDetector(
0096 config=oddConfig, gctx=gctx
0097 )
0098
0099 return detector
0100 else:
0101 volumeRadiusCutsMap = {
0102 28: [850.0],
0103 30: [850.0],
0104 23: [400.0, 550.0],
0105 25: [400.0, 550.0],
0106 16: [100.0],
0107 18: [100.0],
0108 }
0109
0110 def geoid_hook(geoid, surface):
0111 gctx = acts.GeometryContext()
0112 if geoid.volume in volumeRadiusCutsMap:
0113 r = math.sqrt(
0114 surface.center(gctx)[0] ** 2 + surface.center(gctx)[1] ** 2
0115 )
0116
0117 geoid.extra = 1
0118 for cut in volumeRadiusCutsMap[geoid.volume]:
0119 if r > cut:
0120 geoid.extra += 1
0121
0122 return geoid
0123
0124 dd4hepConfig = acts.examples.dd4hep.DD4hepDetector.Config(
0125 xmlFileNames=[str(odd_xml)],
0126 name="OpenDataDetector",
0127 logLevel=customLogLevel(),
0128 dd4hepLogLevel=customLogLevel(minLevel=acts.logging.WARNING),
0129 geometryIdentifierHook=acts.GeometryIdentifierHook(geoid_hook),
0130 materialDecorator=materialDecorator,
0131 )
0132
0133 if misaligned:
0134 dd4hepConfig.detectorElementFactory = (
0135 acts.examples.dd4hep.alignedDD4hepDetectorElementFactory
0136 )
0137
0138 with warnings.catch_warnings():
0139 warnings.simplefilter("ignore")
0140 detector = acts.examples.dd4hep.DD4hepDetector(dd4hepConfig)
0141 return detector