File indexing completed on 2025-12-16 09:24:40
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsTests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0010
0011 #include "Acts/Geometry/Blueprint.hpp"
0012 #include "Acts/Geometry/BlueprintOptions.hpp"
0013 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/CylinderVolumeBuilder.hpp"
0016 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
0017 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0018 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0019 #include "Acts/Geometry/PassiveLayerBuilder.hpp"
0020 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0021 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
0022 #include "Acts/Material/BinnedSurfaceMaterial.hpp"
0023 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0024 #include "Acts/Navigation/SurfaceArrayNavigationPolicy.hpp"
0025 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0026 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0027 #include "Acts/Utilities/AxisDefinitions.hpp"
0028 #include "ActsTests/CommonHelpers/PredefinedMaterials.hpp"
0029
0030 using namespace Acts;
0031
0032 namespace ActsTests {
0033
0034 std::vector<Surface*> CylindricalTrackingGeometry::surfacesRing(
0035 DetectorStore& detStore, double moduleHalfXminY, double moduleHalfXmaxY,
0036 double moduleHalfY, double moduleThickness, double moduleTilt,
0037 double ringRadius, double ringZ, double zStagger, int nPhi) {
0038 std::vector<Surface*> layerSurfaces;
0039
0040
0041 MaterialSlab moduleMaterial(makeSilicon(), moduleThickness);
0042
0043
0044 std::shared_ptr<const ISurfaceMaterial> moduleMaterialPtr =
0045 std::shared_ptr<const ISurfaceMaterial>(
0046 new HomogeneousSurfaceMaterial(moduleMaterial));
0047
0048
0049 std::shared_ptr<PlanarBounds> mBounds = nullptr;
0050 if (moduleHalfXminY == moduleHalfXmaxY) {
0051 mBounds = std::make_shared<RectangleBounds>(moduleHalfXminY, moduleHalfY);
0052 } else {
0053 mBounds = std::make_shared<TrapezoidBounds>(moduleHalfXminY,
0054 moduleHalfXmaxY, moduleHalfY);
0055 }
0056
0057 double phiStep = 2 * std::numbers::pi / nPhi;
0058
0059 for (int im = 0; im < nPhi; ++im) {
0060
0061 double phi = -std::numbers::pi + im * phiStep;
0062 auto mModuleTransform = Transform3(
0063 Translation3(ringRadius * std::cos(phi), ringRadius * std::sin(phi),
0064 ringZ + (im % 2) * zStagger) *
0065 AngleAxis3(phi - std::numbers::pi / 2., Vector3::UnitZ()) *
0066 AngleAxis3(moduleTilt, Vector3::UnitY()));
0067
0068
0069 auto detElement = std::make_unique<DetectorElementStub>(
0070 mModuleTransform, mBounds, moduleThickness, moduleMaterialPtr);
0071
0072 layerSurfaces.push_back(&detElement->surface());
0073 detStore.push_back(std::move(detElement));
0074 }
0075
0076 return layerSurfaces;
0077 }
0078
0079 std::vector<Surface*> CylindricalTrackingGeometry::surfacesCylinder(
0080 DetectorStore& detStore, double moduleHalfX, double moduleHalfY,
0081 double moduleThickness, double moduleTiltPhi, double layerRadius,
0082 double radialStagger, double longitudinalOverlap,
0083 const std::pair<int, int>& binningSchema) {
0084 std::vector<Surface*> layerSurfaces;
0085
0086
0087 MaterialSlab moduleMaterial(makeSilicon(), moduleThickness);
0088
0089
0090 std::shared_ptr<const ISurfaceMaterial> moduleMaterialPtr =
0091 std::shared_ptr<const ISurfaceMaterial>(
0092 new HomogeneousSurfaceMaterial(moduleMaterial));
0093
0094
0095 auto mBounds = std::make_shared<RectangleBounds>(moduleHalfX, moduleHalfY);
0096
0097
0098 auto moduleCenters =
0099 modulePositionsCylinder(layerRadius, radialStagger, moduleHalfY,
0100 longitudinalOverlap, binningSchema);
0101
0102 for (auto& mCenter : moduleCenters) {
0103
0104 double modulePhi = VectorHelpers::phi(mCenter);
0105
0106 Vector3 moduleLocalZ(std::cos(modulePhi + moduleTiltPhi),
0107 std::sin(modulePhi + moduleTiltPhi), 0.);
0108
0109 Vector3 moduleLocalY(0., 0., 1);
0110
0111 Vector3 moduleLocalX(-std::sin(modulePhi + moduleTiltPhi),
0112 std::cos(modulePhi + moduleTiltPhi), 0.);
0113
0114 RotationMatrix3 moduleRotation;
0115 moduleRotation.col(0) = moduleLocalX;
0116 moduleRotation.col(1) = moduleLocalY;
0117 moduleRotation.col(2) = moduleLocalZ;
0118
0119 auto mModuleTransform = Transform3(Translation3(mCenter) * moduleRotation);
0120
0121 auto detElement = std::make_unique<DetectorElementStub>(
0122 mModuleTransform, mBounds, moduleThickness, moduleMaterialPtr);
0123
0124 layerSurfaces.push_back(&detElement->surface());
0125 detStore.push_back(std::move(detElement));
0126 }
0127 return layerSurfaces;
0128 }
0129
0130
0131
0132 std::vector<Vector3> CylindricalTrackingGeometry::modulePositionsCylinder(
0133 double radius, double zStagger, double moduleHalfLength, double lOverlap,
0134 const std::pair<int, int>& binningSchema) {
0135 int nPhiBins = binningSchema.first;
0136 int nZbins = binningSchema.second;
0137
0138 std::vector<Vector3> mPositions;
0139 mPositions.reserve(nPhiBins * nZbins);
0140
0141 double phiStep = 2 * std::numbers::pi / (nPhiBins);
0142 double minPhi = -std::numbers::pi + phiStep / 2.;
0143 double zStart = -0.5 * (nZbins - 1) * (2 * moduleHalfLength - lOverlap);
0144 double zStep = 2 * std::abs(zStart) / (nZbins - 1);
0145
0146 for (std::size_t zBin = 0; zBin < static_cast<std::size_t>(nZbins); ++zBin) {
0147
0148 double moduleZ = zStart + zBin * zStep;
0149 double moduleR =
0150 (zBin % 2) != 0u ? radius - 0.5 * zStagger : radius + 0.5 * zStagger;
0151 for (std::size_t phiBin = 0; phiBin < static_cast<std::size_t>(nPhiBins);
0152 ++phiBin) {
0153
0154 double modulePhi = minPhi + phiBin * phiStep;
0155 mPositions.push_back(Vector3(moduleR * std::cos(modulePhi),
0156 moduleR * std::sin(modulePhi), moduleZ));
0157 }
0158 }
0159 return mPositions;
0160 }
0161
0162 std::shared_ptr<TrackingGeometry> CylindricalTrackingGeometry::buildGen1(
0163 const Logger& ) {
0164 using namespace UnitLiterals;
0165
0166 Logging::Level surfaceLLevel = Logging::INFO;
0167 Logging::Level layerLLevel = Logging::INFO;
0168 Logging::Level volumeLLevel = Logging::INFO;
0169
0170
0171 auto surfaceArrayCreator = std::make_shared<const SurfaceArrayCreator>(
0172 getDefaultLogger("SurfaceArrayCreator", surfaceLLevel));
0173
0174 LayerCreator::Config lcConfig;
0175 lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0176 auto layerCreator = std::make_shared<const LayerCreator>(
0177 lcConfig, getDefaultLogger("LayerCreator", layerLLevel));
0178
0179 LayerArrayCreator::Config lacConfig;
0180 auto layerArrayCreator = std::make_shared<const LayerArrayCreator>(
0181 lacConfig, getDefaultLogger("LayerArrayCreator", layerLLevel));
0182
0183
0184 TrackingVolumeArrayCreator::Config tvacConfig;
0185 auto tVolumeArrayCreator = std::make_shared<const TrackingVolumeArrayCreator>(
0186 tvacConfig, getDefaultLogger("TrackingVolumeArrayCreator", volumeLLevel));
0187
0188 CylinderVolumeHelper::Config cvhConfig;
0189 cvhConfig.layerArrayCreator = layerArrayCreator;
0190 cvhConfig.trackingVolumeArrayCreator = tVolumeArrayCreator;
0191 auto cylinderVolumeHelper = std::make_shared<const CylinderVolumeHelper>(
0192 cvhConfig, getDefaultLogger("CylinderVolumeHelper", volumeLLevel));
0193
0194
0195 MaterialSlab beamPipeMaterial(makeBeryllium(), 0.8_mm);
0196 PassiveLayerBuilder::Config bplConfig;
0197 bplConfig.layerIdentification = "BeamPipe";
0198 bplConfig.centralLayerRadii = std::vector<double>(1, kBeamPipeRadius);
0199 bplConfig.centralLayerHalflengthZ =
0200 std::vector<double>(1, kBeamPipeHalfLengthZ);
0201 bplConfig.centralLayerThickness = std::vector<double>(1, kBeamPipeThickness);
0202 bplConfig.centralLayerMaterial = {
0203 std::make_shared<const HomogeneousSurfaceMaterial>(beamPipeMaterial)};
0204 auto beamPipeBuilder = std::make_shared<const PassiveLayerBuilder>(
0205 bplConfig, getDefaultLogger("BeamPipeLayerBuilder", layerLLevel));
0206
0207 CylinderVolumeBuilder::Config bpvConfig;
0208 bpvConfig.trackingVolumeHelper = cylinderVolumeHelper;
0209 bpvConfig.volumeName = "BeamPipe";
0210 bpvConfig.layerBuilder = beamPipeBuilder;
0211 bpvConfig.layerEnvelopeR = {1_mm, 1_mm};
0212 bpvConfig.buildToRadiusZero = true;
0213 auto beamPipeVolumeBuilder = std::make_shared<const CylinderVolumeBuilder>(
0214 bpvConfig, getDefaultLogger("BeamPipeVolumeBuilder", volumeLLevel));
0215
0216
0217 auto beamPipeBounds =
0218 std::make_shared<const CylinderVolumeBounds>(0., 25., 1100.);
0219 auto beamPipeVolume = beamPipeVolumeBuilder->trackingVolume(
0220 geoContext, nullptr, beamPipeBounds);
0221
0222
0223
0224
0225 MaterialSlab lProperties(makeSilicon(), 1.5_mm);
0226
0227 auto layerMaterialPtr =
0228 std::make_shared<HomogeneousSurfaceMaterial>(lProperties);
0229
0230 std::vector<LayerPtr> pLayers;
0231
0232 for (std::size_t ilp = 0; ilp < kLayerRadii.size(); ++ilp) {
0233 std::vector<Surface*> layerSurfacesMutable =
0234 surfacesCylinder(detectorStore, kModuleHalfX[ilp], kModuleHalfY[ilp],
0235 kModuleThickness[ilp], kModuleTiltPhi[ilp],
0236 kLayerRadii[ilp], 2_mm, 5_mm, kLayerBinning[ilp]);
0237
0238 std::vector<const Surface*> layerSurfaces;
0239 std::ranges::transform(layerSurfacesMutable,
0240 std::back_inserter(layerSurfaces),
0241 [](Surface* s) { return s; });
0242
0243
0244 std::vector<std::shared_ptr<const Surface>> layerSurfacePtrs;
0245 layerSurfacePtrs.reserve(layerSurfaces.size());
0246 for (auto& sf : layerSurfaces) {
0247 layerSurfacePtrs.push_back(sf->getSharedPtr());
0248 }
0249
0250
0251 ProtoLayer protoLayer(geoContext, layerSurfaces);
0252 protoLayer.envelope[AxisDirection::AxisR] = {0.5, 0.5};
0253 auto pLayer = layerCreator->cylinderLayer(
0254 geoContext, std::move(layerSurfacePtrs), kLayerBinning[ilp].first,
0255 kLayerBinning[ilp].second, protoLayer);
0256 auto approachSurfaces = pLayer->approachDescriptor()->containedSurfaces();
0257 auto mutableOuterSurface = const_cast<Surface*>(approachSurfaces.at(1));
0258 mutableOuterSurface->assignSurfaceMaterial(layerMaterialPtr);
0259
0260 pLayers.push_back(pLayer);
0261
0262 }
0263
0264
0265 auto pLayerArray = layerArrayCreator->layerArray(
0266 geoContext, pLayers, 25., 300., arbitrary, AxisDirection::AxisR);
0267 auto pVolumeBounds = std::make_shared<CylinderVolumeBounds>(25., 300., 1100.);
0268
0269 auto pVolume = std::make_shared<TrackingVolume>(
0270 Transform3::Identity(), pVolumeBounds, nullptr, std::move(pLayerArray),
0271 nullptr, MutableTrackingVolumeVector{}, "Pixel::Barrel");
0272
0273
0274 auto detectorVolume = cylinderVolumeHelper->createContainerTrackingVolume(
0275 geoContext, {beamPipeVolume, pVolume});
0276
0277
0278 return std::make_shared<TrackingGeometry>(detectorVolume);
0279 }
0280
0281 std::shared_ptr<TrackingGeometry> CylindricalTrackingGeometry::buildGen3(
0282 const Logger& logger) {
0283 using namespace Experimental;
0284 using namespace UnitLiterals;
0285 using enum CylinderVolumeBounds::Face;
0286 using enum AxisDirection;
0287 using LayerType = LayerBlueprintNode::LayerType;
0288
0289 const MaterialSlab lProperties(makeSilicon(), 1.5_mm);
0290
0291
0292 std::vector<float> binEdges = {
0293 -476.5, 0, 476.5};
0294
0295 BinUtility binUtility(2u, -std::numbers::pi, std::numbers::pi,
0296 BinningOption::closed, AxisPhi);
0297
0298 binUtility += Acts::BinUtility(binEdges, BinningOption::open, AxisZ);
0299
0300 std::vector<MaterialSlab> materialSlabs0 = {lProperties, lProperties};
0301 std::vector<MaterialSlab> materialSlabs1 = {lProperties, lProperties};
0302
0303 auto binnedMaterial = std::make_shared<BinnedSurfaceMaterial>(
0304 binUtility, std::vector{materialSlabs0, materialSlabs1}, 0.,
0305 MappingType::Default);
0306
0307 Blueprint::Config cfg;
0308 cfg.envelope = ExtentEnvelope{{
0309 .z = {20_mm, 20_mm},
0310 .r = {0_mm, 20_mm},
0311 }};
0312 Blueprint root{cfg};
0313
0314 root.addCylinderContainer("Detector", AxisR, [&](auto& detector) {
0315 auto beampipeBounds =
0316 std::make_unique<CylinderVolumeBounds>(0_mm, kBeamPipeRadius, 100_mm);
0317 auto beampipe = std::make_unique<TrackingVolume>(
0318 Transform3::Identity(), std::move(beampipeBounds), "Beampipe");
0319
0320 detector.addMaterial("BeampipeMaterial", [&](auto& bpMat) {
0321 MaterialSlab beamPipeMaterial(makeBeryllium(), kBeamPipeThickness);
0322 bpMat.configureFace(OuterCylinder, binnedMaterial);
0323 bpMat.addStaticVolume(std::move(beampipe));
0324 });
0325
0326 auto layerMaterialPtr =
0327 std::make_shared<HomogeneousSurfaceMaterial>(lProperties);
0328
0329 for (std::size_t ilp = 0; ilp < kLayerRadii.size(); ++ilp) {
0330 std::vector<Surface*> layerSurfaces =
0331 surfacesCylinder(detectorStore, kModuleHalfX[ilp], kModuleHalfY[ilp],
0332 kModuleThickness[ilp], kModuleTiltPhi[ilp],
0333 kLayerRadii[ilp], 2_mm, 5_mm, kLayerBinning[ilp]);
0334
0335
0336 std::vector<std::shared_ptr<Surface>> layerSurfacePtrs;
0337 layerSurfacePtrs.reserve(layerSurfaces.size());
0338 for (auto& sf : layerSurfaces) {
0339 layerSurfacePtrs.push_back(sf->getSharedPtr());
0340 }
0341
0342
0343 MutableProtoLayer protoLayer(geoContext, layerSurfaces);
0344 protoLayer.envelope[AxisR] = {0.5, 0.5};
0345
0346 std::string layerName = "L" + std::to_string(ilp);
0347 detector.addMaterial(layerName + "_Mat", [&](auto& mat) {
0348 mat.configureFace(OuterCylinder, layerMaterialPtr);
0349 mat.addLayer(layerName, [&](auto& layer) {
0350 layer.setProtoLayer(protoLayer);
0351 layer.setLayerType(LayerType::Cylinder);
0352 layer.setEnvelope(
0353 ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0354
0355 using SrfArrayNavPol = SurfaceArrayNavigationPolicy;
0356
0357 layer.setNavigationPolicyFactory(
0358 NavigationPolicyFactory{}
0359 .add<TryAllNavigationPolicy>(
0360 TryAllNavigationPolicy::Config{.sensitives = false})
0361 .add<SrfArrayNavPol>(SrfArrayNavPol::Config{
0362 .layerType = SrfArrayNavPol::LayerType::Cylinder,
0363 .bins = kLayerBinning[ilp]})
0364 .asUniquePtr());
0365 });
0366 });
0367
0368 }
0369 });
0370
0371 BlueprintOptions opts;
0372 return root.construct(opts, geoContext, logger);
0373 }
0374
0375 std::shared_ptr<TrackingGeometry> CylindricalTrackingGeometry::operator()(
0376 const Logger& logger) {
0377 if (gen3) {
0378 return buildGen3(logger);
0379 } else {
0380 return buildGen1(logger);
0381 }
0382 }
0383 }