File indexing completed on 2026-01-09 09:26:46
0001 from pathlib import Path
0002 from typing import Optional
0003 import math
0004
0005 import acts
0006 import acts.examples
0007 from acts.examples.tgeo import TGeoDetector
0008
0009 from acts.examples.reconstruction import (
0010 SeedFinderConfigArg,
0011 SeedFinderOptionsArg,
0012 SeedFilterConfigArg,
0013 SpacePointGridConfigArg,
0014 SeedingAlgorithmConfigArg,
0015 )
0016
0017 u = acts.UnitConstants
0018
0019 from enum import Enum
0020
0021
0022 class InputSpacePointsType(Enum):
0023 PixelSpacePoints = 0
0024 StripSpacePoints = 1
0025
0026
0027 def buildITkGeometry(
0028 geo_dir: Path,
0029 customMaterialFile: Optional[str] = None,
0030 material: bool = True,
0031 jsonconfig: bool = False,
0032 logLevel=acts.logging.WARNING,
0033 ):
0034 customLogLevel = acts.examples.defaultLogging(logLevel=logLevel)
0035 logger = acts.logging.getLogger("buildITkGeometry")
0036
0037 matDeco = None
0038 if material:
0039 file = None
0040 if customMaterialFile:
0041 file = customMaterialFile
0042 logger.info("Adding custom material from %s", file)
0043 else:
0044 file = geo_dir / "itk-hgtd/material-maps-ITk-HGTD.json"
0045 logger.info("Adding material from %s", file.absolute())
0046 matDeco = acts.IMaterialDecorator.fromFile(
0047 file,
0048 level=customLogLevel(maxLevel=acts.logging.INFO),
0049 )
0050
0051 tgeo_fileName = geo_dir / "itk-hgtd/ATLAS-ITk-HGTD.tgeo.root"
0052
0053 if jsonconfig:
0054 jsonFile = geo_dir / "itk-hgtd/tgeo-atlas-itk-hgtd.json"
0055 logger.info("Create geometry from %s", jsonFile.absolute())
0056 return TGeoDetector(
0057 jsonFile=str(jsonFile),
0058 fileName=str(tgeo_fileName),
0059 surfaceLogLevel=customLogLevel(),
0060 layerLogLevel=customLogLevel(),
0061 volumeLogLevel=customLogLevel(),
0062 materialDecorator=matDeco,
0063 )
0064
0065 from acts.examples.tgeo import TGeoDetector
0066
0067 Volume = TGeoDetector.Config.Volume
0068 LayerTriplet = TGeoDetector.Config.LayerTriplet
0069 equidistant = TGeoDetector.Config.BinningType.equidistant
0070 arbitrary = TGeoDetector.Config.BinningType.arbitrary
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 return TGeoDetector(
0089 fileName=str(tgeo_fileName),
0090 materialDecorator=matDeco,
0091 buildBeamPipe=True,
0092 unitScalor=1.0,
0093 beamPipeRadius=23.934 * u.mm,
0094 beamPipeHalflengthZ=3000.0 * u.mm,
0095 beamPipeLayerThickness=0.8 * u.mm,
0096 surfaceLogLevel=customLogLevel(),
0097 layerLogLevel=customLogLevel(),
0098 volumeLogLevel=customLogLevel(),
0099 volumes=[
0100 Volume(
0101 name="InnerPixels",
0102 binToleranceR=(5 * u.mm, 5 * u.mm),
0103 binToleranceZ=(5 * u.mm, 5 * u.mm),
0104 binTolerancePhi=(0.025 * u.mm, 0.025 * u.mm),
0105 layers=LayerTriplet(True),
0106 subVolumeName=LayerTriplet("ITkPixel__ITkPixelDetector"),
0107 sensitiveNames=LayerTriplet(["ITkPixel__*_Sensor"]),
0108 sensitiveAxes=LayerTriplet("YZX"),
0109 rRange=LayerTriplet((0 * u.mm, 135 * u.mm)),
0110 zRange=LayerTriplet(
0111 negative=(-3000 * u.mm, -250 * u.mm),
0112 central=(-250 * u.mm, 250 * u.mm),
0113 positive=(250 * u.mm, 3000 * u.mm),
0114 ),
0115 splitTolR=LayerTriplet(negative=-1.0, central=5 * u.mm, positive=-1.0),
0116 splitTolZ=LayerTriplet(
0117 negative=10 * u.mm, central=-1.0, positive=10 * u.mm
0118 ),
0119 binning0=LayerTriplet(
0120 negative=[(0, equidistant)],
0121 central=[(6, equidistant), (10, equidistant)],
0122 positive=[(0, equidistant)],
0123 ),
0124 binning1=LayerTriplet(
0125 negative=[(0, equidistant)],
0126 central=[(12, equidistant), (6, equidistant)],
0127 positive=[(0, equidistant)],
0128 ),
0129 cylinderDiscSplit=False,
0130 cylinderNZSegments=0,
0131 cylinderNPhiSegments=0,
0132 discNRSegments=0,
0133 discNPhiSegments=0,
0134 itkModuleSplit=False,
0135 barrelMap={},
0136 discMap={},
0137 ),
0138 Volume(
0139 name="OuterPixels",
0140 binToleranceR=(5 * u.mm, 5 * u.mm),
0141 binToleranceZ=(5 * u.mm, 5 * u.mm),
0142 binTolerancePhi=(0.025 * u.mm, 0.025 * u.mm),
0143 layers=LayerTriplet(True),
0144 subVolumeName=LayerTriplet("ITkPixel__ITkPixelDetector"),
0145 sensitiveNames=LayerTriplet(["ITkPixel__*_Sensor"]),
0146 sensitiveAxes=LayerTriplet("YZX"),
0147 rRange=LayerTriplet((135 * u.mm, 350 * u.mm)),
0148 zRange=LayerTriplet(
0149 negative=(-3000 * u.mm, -377 * u.mm),
0150 central=(-377 * u.mm, 377 * u.mm),
0151 positive=(377 * u.mm, 3000 * u.mm),
0152 ),
0153 splitTolR=LayerTriplet(
0154 negative=15 * u.mm, central=5 * u.mm, positive=15 * u.mm
0155 ),
0156 splitTolZ=LayerTriplet(
0157 negative=20 * u.mm, central=-1.0, positive=20 * u.mm
0158 ),
0159 binning0=LayerTriplet(
0160 negative=[(0, equidistant)],
0161 central=[(0, equidistant)],
0162 positive=[(0, equidistant)],
0163 ),
0164 binning1=LayerTriplet(
0165 negative=[(0, equidistant)],
0166 central=[(0, equidistant)],
0167 positive=[(0, equidistant)],
0168 ),
0169 cylinderDiscSplit=False,
0170 cylinderNZSegments=0,
0171 cylinderNPhiSegments=0,
0172 discNRSegments=0,
0173 discNPhiSegments=0,
0174 itkModuleSplit=False,
0175 barrelMap={},
0176 discMap={},
0177 ),
0178 Volume(
0179 name="Strips",
0180 binToleranceR=(5 * u.mm, 5 * u.mm),
0181 binToleranceZ=(5 * u.mm, 5 * u.mm),
0182 binTolerancePhi=(0.025 * u.mm, 0.025 * u.mm),
0183 layers=LayerTriplet(True),
0184 subVolumeName=LayerTriplet("ITkStrip__ITkStrip"),
0185 sensitiveNames=LayerTriplet(
0186 negative=["ITkStrip__ECSensor*"],
0187 central=["ITkStrip__BRLSensor*"],
0188 positive=["ITkStrip__ECSensor*"],
0189 ),
0190 sensitiveAxes=LayerTriplet("XYZ"),
0191 rRange=LayerTriplet(
0192 negative=(-1.0, 1050 * u.mm),
0193 central=(380 * u.mm, 1050 * u.mm),
0194 positive=(-1.0, 1050 * u.mm),
0195 ),
0196 zRange=LayerTriplet(
0197 negative=(-3000 * u.mm, -1400 * u.mm),
0198 central=(-1400 * u.mm, 1400 * u.mm),
0199 positive=(1400 * u.mm, 3000 * u.mm),
0200 ),
0201 splitTolR=LayerTriplet(
0202 negative=-1.0,
0203 central=35 * u.mm,
0204 positive=-1.0,
0205 ),
0206 splitTolZ=LayerTriplet(
0207 negative=35 * u.mm, central=-1.0, positive=35 * u.mm
0208 ),
0209 binning0=LayerTriplet(
0210 negative=[(-1, arbitrary)],
0211 central=[(0, equidistant)],
0212 positive=[(-1, arbitrary)],
0213 ),
0214 binning1=LayerTriplet(
0215 negative=[(-1, arbitrary)],
0216 central=[(28, equidistant)] * 4,
0217 positive=[(-1, arbitrary)],
0218 ),
0219 cylinderDiscSplit=False,
0220 cylinderNZSegments=0,
0221 cylinderNPhiSegments=0,
0222 discNRSegments=0,
0223 discNPhiSegments=0,
0224 itkModuleSplit=True,
0225 barrelMap={"MS": 2, "SS": 4},
0226 discMap={
0227 "EC0": [
0228 [384.5, 403.481],
0229 [403.481, 427.462],
0230 [427.462, 456.442],
0231 [456.442, 488.423],
0232 ],
0233 "EC1": [
0234 [489.823, 507.916],
0235 [507.916, 535.009],
0236 [535.009, 559.101],
0237 [559.101, 574.194],
0238 ],
0239 "EC2": [[575.594, 606.402], [606.402, 637.209]],
0240 "EC3": [
0241 [638.609, 670.832],
0242 [670.832, 697.055],
0243 [697.055, 723.278],
0244 [723.278, 755.501],
0245 ],
0246 "EC4": [[756.901, 811.482], [811.482, 866.062]],
0247 "EC5": [[867.462, 907.623], [907.623, 967.785]],
0248 },
0249 splitPatterns={
0250 ".*BRL.*MS.*": "MS",
0251 ".*BRL.*SS.*": "SS",
0252 ".*EC.*Sensor(|Back)0.*": "EC0",
0253 ".*EC.*Sensor(|Back)1.*": "EC1",
0254 ".*EC.*Sensor(|Back)2.*": "EC2",
0255 ".*EC.*Sensor(|Back)3.*": "EC3",
0256 ".*EC.*Sensor(|Back)4.*": "EC4",
0257 ".*EC.*Sensor(|Back)5.*": "EC5",
0258 },
0259 ),
0260 Volume(
0261 name="HGTD",
0262 binToleranceR=(15 * u.mm, 15 * u.mm),
0263 binToleranceZ=(5 * u.mm, 5 * u.mm),
0264 binTolerancePhi=(0.25 * u.mm, 0.25 * u.mm),
0265 layers=LayerTriplet(positive=True, central=False, negative=True),
0266 subVolumeName=LayerTriplet("HGTD__HGTD"),
0267 sensitiveNames=LayerTriplet(["HGTD__HGTDSiSensor*"]),
0268 sensitiveAxes=LayerTriplet("XYZ"),
0269 rRange=LayerTriplet(
0270 negative=(0 * u.mm, 1050 * u.mm),
0271 positive=(0 * u.mm, 1050 * u.mm),
0272 ),
0273 zRange=LayerTriplet(
0274 negative=(-4000 * u.mm, -3000 * u.mm),
0275 positive=(3000 * u.mm, 4000 * u.mm),
0276 ),
0277 splitTolR=LayerTriplet(-1.0),
0278 splitTolZ=LayerTriplet(negative=10 * u.mm, positive=10 * u.mm),
0279 binning0=LayerTriplet(
0280 negative=[(0, equidistant)],
0281 central=[(0, equidistant)],
0282 positive=[(0, equidistant)],
0283 ),
0284 binning1=LayerTriplet(
0285 negative=[(0, equidistant)],
0286 central=[(0, equidistant)],
0287 positive=[(0, equidistant)],
0288 ),
0289 cylinderDiscSplit=False,
0290 cylinderNZSegments=0,
0291 cylinderNPhiSegments=0,
0292 discNRSegments=0,
0293 discNPhiSegments=0,
0294 itkModuleSplit=False,
0295 barrelMap={},
0296 discMap={},
0297 ),
0298 ],
0299 )
0300
0301
0302 def itkSeedingAlgConfig(
0303 inputSpacePointsType: InputSpacePointsType, highOccupancyConfig=False
0304 ):
0305 assert isinstance(inputSpacePointsType, InputSpacePointsType)
0306
0307
0308 zMax = 3000 * u.mm
0309 zMin = -3000 * u.mm
0310 beamPos = (0 * u.mm, 0 * u.mm)
0311 collisionRegionMin = -200 * u.mm
0312 collisionRegionMax = 200 * u.mm
0313 maxSeedsPerSpM = 4
0314 cotThetaMax = 27.2899
0315 sigmaScattering = 2
0316 radLengthPerSeed = 0.0975
0317 minPt = 900 * u.MeV
0318 bFieldInZ = 2 * u.T
0319 deltaRMin = 20 * u.mm
0320 maxPtScattering = float("inf") * u.GeV
0321 zBinEdges = [
0322 -3000.0,
0323 -2700.0,
0324 -2500.0,
0325 -1400.0,
0326 -925.0,
0327 -500.0,
0328 -250.0,
0329 250.0,
0330 500.0,
0331 925.0,
0332 1400.0,
0333 2500.0,
0334 2700.0,
0335 3000.0,
0336 ]
0337 rRangeMiddleSP = [
0338 [40.0, 90.0],
0339 [40.0, 90.0],
0340 [40.0, 200.0],
0341 [46.0, 200.0],
0342 [46.0, 200.0],
0343 [46.0, 250.0],
0344 [46.0, 250.0],
0345 [46.0, 250.0],
0346 [46.0, 200.0],
0347 [46.0, 200.0],
0348 [40.0, 200.0],
0349 [40.0, 90.0],
0350 [40.0, 90.0],
0351 ]
0352 useVariableMiddleSPRange = True
0353 binSizeR = 1 * u.mm
0354 seedConfirmation = True
0355 centralSeedConfirmationRange = acts.SeedConfirmationRangeConfig(
0356 zMinSeedConf=-500 * u.mm,
0357 zMaxSeedConf=500 * u.mm,
0358 rMaxSeedConf=140 * u.mm,
0359 nTopForLargeR=1,
0360 nTopForSmallR=2,
0361 seedConfMinBottomRadius=60.0 * u.mm,
0362 seedConfMaxZOrigin=150.0 * u.mm,
0363 minImpactSeedConf=1.0 * u.mm,
0364 )
0365 forwardSeedConfirmationRange = acts.SeedConfirmationRangeConfig(
0366 zMinSeedConf=-3000 * u.mm,
0367 zMaxSeedConf=3000 * u.mm,
0368 rMaxSeedConf=140 * u.mm,
0369 nTopForLargeR=1,
0370 nTopForSmallR=2,
0371 seedConfMinBottomRadius=60.0 * u.mm,
0372 seedConfMaxZOrigin=150.0 * u.mm,
0373 minImpactSeedConf=1.0 * u.mm,
0374 )
0375 zOriginWeightFactor = 1
0376 compatSeedWeight = 100
0377 phiMin = -math.pi
0378 phiMax = math.pi
0379 phiBinDeflectionCoverage = 3
0380 numPhiNeighbors = 1
0381 maxPhiBins = 200
0382
0383 deltaPhiMax = 0.025
0384
0385
0386 if inputSpacePointsType is InputSpacePointsType.PixelSpacePoints:
0387 allowSeparateRMax = False
0388 rMaxGridConfig = 320 * u.mm
0389 rMaxSeedFinderConfig = rMaxGridConfig
0390 deltaRMinSP = 6 * u.mm
0391 deltaRMax = 280 * u.mm
0392 deltaRMaxTopSP = 280 * u.mm
0393 deltaRMaxBottomSP = 150 * u.mm
0394 deltaZMax = float("inf") * u.mm
0395 interactionPointCut = True
0396 impactMax = 2 * u.mm
0397 zBinsCustomLooping = [
0398 2,
0399 3,
0400 4,
0401 5,
0402 12,
0403 11,
0404 10,
0405 9,
0406 7,
0407 6,
0408 8,
0409 ]
0410 zBinNeighborsTop = [
0411 [0, 0],
0412 [-1, 0],
0413 [-2, 0],
0414 [-1, 0],
0415 [-1, 0],
0416 [-1, 0],
0417 [-1, 1],
0418 [0, 1],
0419 [0, 1],
0420 [0, 1],
0421 [0, 2],
0422 [0, 1],
0423 [0, 0],
0424 ]
0425 zBinNeighborsBottom = [
0426 [0, 0],
0427 [0, 1],
0428 [0, 1],
0429 [0, 1],
0430 [0, 1],
0431 [0, 1],
0432 [0, 0],
0433 [-1, 0],
0434 [-1, 0],
0435 [-1, 0],
0436 [-1, 0],
0437 [-1, 0],
0438 [0, 0],
0439 ]
0440 deltaRMiddleMinSPRange = 10 * u.mm
0441 deltaRMiddleMaxSPRange = 10 * u.mm
0442 impactWeightFactor = 100
0443 compatSeedLimit = 3
0444 numSeedIncrement = 100
0445 seedWeightIncrement = 0
0446 maxSeedsPerSpMConf = 5
0447 maxQualitySeedsPerSpMConf = 5
0448 useDeltaRorTopRadius = True
0449
0450 if highOccupancyConfig == True:
0451 rMaxGridConfig = 250 * u.mm
0452 rMaxSeedFinderConfig = rMaxGridConfig
0453 deltaRMax = 200 * u.mm
0454 zBinsCustomLooping = [2, 10, 3, 9, 6, 4, 8, 5, 7]
0455
0456 elif inputSpacePointsType is InputSpacePointsType.StripSpacePoints:
0457 allowSeparateRMax = True
0458 rMaxGridConfig = 1000.0 * u.mm
0459 rMaxSeedFinderConfig = 1200.0 * u.mm
0460 deltaRMinSP = 20 * u.mm
0461 deltaRMax = 600 * u.mm
0462 deltaRMaxTopSP = 300 * u.mm
0463 deltaRMaxBottomSP = deltaRMaxTopSP
0464 deltaZMax = 900 * u.mm
0465 interactionPointCut = False
0466 impactMax = 20 * u.mm
0467 zBinsCustomLooping = [6, 7, 5, 8, 4, 9, 3, 10, 2, 11, 1]
0468 zBinNeighborsTop = [
0469 [0, 0],
0470 [-1, 0],
0471 [-2, 0],
0472 [-1, 0],
0473 [-1, 0],
0474 [-1, 0],
0475 [-1, 1],
0476 [0, 1],
0477 [0, 1],
0478 [0, 1],
0479 [0, 2],
0480 [0, 1],
0481 [0, 0],
0482 ]
0483 zBinNeighborsBottom = [
0484 [0, 0],
0485 [0, 1],
0486 [0, 1],
0487 [0, 1],
0488 [0, 2],
0489 [0, 1],
0490 [0, 0],
0491 [-1, 0],
0492 [-2, 0],
0493 [-1, 0],
0494 [-1, 0],
0495 [-1, 0],
0496 [0, 0],
0497 ]
0498 deltaRMiddleMinSPRange = 30 * u.mm
0499 deltaRMiddleMaxSPRange = 150 * u.mm
0500 impactWeightFactor = 1
0501 compatSeedLimit = 4
0502 numSeedIncrement = 1
0503 seedWeightIncrement = 10100
0504 maxSeedsPerSpMConf = 100
0505 maxQualitySeedsPerSpMConf = 100
0506 useDeltaRorTopRadius = False
0507
0508 if highOccupancyConfig == True:
0509 minPt = 1000 * u.MeV
0510 collisionRegionMin = -150 * u.mm
0511 collisionRegionMax = 150 * u.mm
0512 rRangeMiddleSP = [
0513 [40.0, 80.0],
0514 [40.0, 80.0],
0515 [40.0, 200.0],
0516 [70.0, 200.0],
0517 [70.0, 200.0],
0518 [70.0, 250.0],
0519 [70.0, 250.0],
0520 [70.0, 250.0],
0521 [70.0, 200.0],
0522 [70.0, 200.0],
0523 [40.0, 200.0],
0524 [40.0, 80.0],
0525 [40.0, 80.0],
0526 ]
0527 useVariableMiddleSPRange = False
0528
0529
0530 seedFinderConfigArg = SeedFinderConfigArg(
0531 maxSeedsPerSpM=maxSeedsPerSpM,
0532 cotThetaMax=cotThetaMax,
0533 sigmaScattering=sigmaScattering,
0534 radLengthPerSeed=radLengthPerSeed,
0535 minPt=minPt,
0536 impactMax=impactMax,
0537 deltaPhiMax=deltaPhiMax,
0538 interactionPointCut=interactionPointCut,
0539 deltaZMax=deltaZMax,
0540 maxPtScattering=maxPtScattering,
0541 zBinEdges=zBinEdges,
0542 zBinsCustomLooping=zBinsCustomLooping,
0543 rRangeMiddleSP=rRangeMiddleSP,
0544 useVariableMiddleSPRange=useVariableMiddleSPRange,
0545 binSizeR=binSizeR,
0546 seedConfirmation=seedConfirmation,
0547 centralSeedConfirmationRange=centralSeedConfirmationRange,
0548 forwardSeedConfirmationRange=forwardSeedConfirmationRange,
0549 deltaR=(deltaRMin, deltaRMax),
0550 deltaRBottomSP=(deltaRMinSP, deltaRMaxBottomSP),
0551 deltaRTopSP=(deltaRMinSP, deltaRMaxTopSP),
0552 deltaRMiddleSPRange=(deltaRMiddleMinSPRange, deltaRMiddleMaxSPRange),
0553 collisionRegion=(collisionRegionMin, collisionRegionMax),
0554 r=(None, rMaxSeedFinderConfig),
0555 z=(zMin, zMax),
0556 )
0557
0558 seedFinderOptionsArg = SeedFinderOptionsArg(bFieldInZ=bFieldInZ, beamPos=beamPos)
0559
0560 seedFilterConfigArg = SeedFilterConfigArg(
0561 impactWeightFactor=impactWeightFactor,
0562 zOriginWeightFactor=zOriginWeightFactor,
0563 compatSeedWeight=compatSeedWeight,
0564 compatSeedLimit=compatSeedLimit,
0565 numSeedIncrement=numSeedIncrement,
0566 seedWeightIncrement=seedWeightIncrement,
0567 seedConfirmation=seedConfirmation,
0568 maxSeedsPerSpMConf=maxSeedsPerSpMConf,
0569 maxQualitySeedsPerSpMConf=maxQualitySeedsPerSpMConf,
0570 useDeltaRorTopRadius=useDeltaRorTopRadius,
0571 )
0572 spacePointGridConfigArg = SpacePointGridConfigArg(
0573 rMax=rMaxGridConfig,
0574 deltaRMax=deltaRMax,
0575 zBinEdges=zBinEdges,
0576 phiBinDeflectionCoverage=phiBinDeflectionCoverage,
0577 phi=(phiMin, phiMax),
0578 impactMax=impactMax,
0579 maxPhiBins=maxPhiBins,
0580 )
0581 seedingAlgorithmConfigArg = SeedingAlgorithmConfigArg(
0582 allowSeparateRMax=allowSeparateRMax,
0583 zBinNeighborsTop=zBinNeighborsTop,
0584 zBinNeighborsBottom=zBinNeighborsBottom,
0585 numPhiNeighbors=numPhiNeighbors,
0586 useExtraCuts=highOccupancyConfig,
0587 )
0588
0589 return (
0590 seedingAlgorithmConfigArg,
0591 seedFinderConfigArg,
0592 seedFinderOptionsArg,
0593 seedFilterConfigArg,
0594 spacePointGridConfigArg,
0595 )