File indexing completed on 2026-07-22 08:22:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/LayerCreator.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/CylinderLayer.hpp"
0013 #include "Acts/Geometry/DiscLayer.hpp"
0014 #include "Acts/Geometry/Extent.hpp"
0015 #include "Acts/Geometry/Layer.hpp"
0016 #include "Acts/Geometry/PlaneLayer.hpp"
0017 #include "Acts/Geometry/ProtoLayer.hpp"
0018 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0019 #include "Acts/Surfaces/CylinderBounds.hpp"
0020 #include "Acts/Surfaces/RadialBounds.hpp"
0021 #include "Acts/Surfaces/RectangleBounds.hpp"
0022 #include "Acts/Surfaces/Surface.hpp"
0023
0024 #include <memory>
0025 #include <ostream>
0026 #include <utility>
0027
0028 namespace Acts {
0029
0030 using VectorHelpers::perp;
0031 using VectorHelpers::phi;
0032
0033 LayerCreator::LayerCreator(const LayerCreator::Config& lcConfig,
0034 std::unique_ptr<const Logger> logger)
0035 : m_cfg(lcConfig), m_logger(std::move(logger)) {}
0036
0037 void LayerCreator::setConfiguration(const LayerCreator::Config& lcConfig) {
0038
0039
0040 m_cfg = lcConfig;
0041 }
0042
0043 void LayerCreator::setLogger(std::unique_ptr<const Logger> newLogger) {
0044 m_logger = std::move(newLogger);
0045 }
0046
0047 MutableLayerPtr LayerCreator::cylinderLayer(
0048 const GeometryContext& gctx,
0049 std::vector<std::shared_ptr<const Surface>> surfaces, std::size_t binsPhi,
0050 std::size_t binsZ, std::optional<ProtoLayer> _protoLayer,
0051 const Transform3& transform, std::unique_ptr<ApproachDescriptor> ad,
0052 std::uint8_t maxNeighborDistance) const {
0053 ProtoLayer protoLayer =
0054 _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces);
0055 if (!_protoLayer) {
0056 protoLayer.envelope[AxisDirection::AxisR] = m_cfg.defaultEnvelopeR;
0057 protoLayer.envelope[AxisDirection::AxisZ] = m_cfg.defaultEnvelopeZ;
0058 }
0059
0060
0061 double layerR = protoLayer.medium(AxisDirection::AxisR);
0062 double layerZ = protoLayer.medium(AxisDirection::AxisZ);
0063 double layerHalfZ = 0.5 * protoLayer.range(AxisDirection::AxisZ);
0064 double layerThickness = protoLayer.range(AxisDirection::AxisR);
0065
0066 ACTS_VERBOSE("Creating a cylindrical Layer:");
0067 ACTS_VERBOSE(" - with layer R = " << layerR);
0068 ACTS_VERBOSE(" - from R min/max = "
0069 << protoLayer.min(AxisDirection::AxisR, false) << " / "
0070 << protoLayer.max(AxisDirection::AxisR, false));
0071 ACTS_VERBOSE(" - with R thickness = " << layerThickness);
0072 ACTS_VERBOSE(" - incl envelope = "
0073 << protoLayer.envelope[AxisDirection::AxisR][0u] << " / "
0074 << protoLayer.envelope[AxisDirection::AxisR][1u]);
0075
0076 ACTS_VERBOSE(" - with z min/max = "
0077 << protoLayer.min(AxisDirection::AxisZ, false) << " (-"
0078 << protoLayer.envelope[AxisDirection::AxisZ][0u] << ") / "
0079 << protoLayer.max(AxisDirection::AxisZ, false) << " (+"
0080 << protoLayer.envelope[AxisDirection::AxisZ][1u] << ")");
0081
0082 ACTS_VERBOSE(" - z center = " << layerZ);
0083 ACTS_VERBOSE(" - halflength z = " << layerHalfZ);
0084
0085
0086
0087
0088 Transform3 fullTransform = transform;
0089 if (fullTransform.isApprox(Transform3::Identity())) {
0090 fullTransform = Translation3(0, 0, layerZ) * fullTransform;
0091 ACTS_VERBOSE(" - layer z shift = " << -layerZ);
0092 }
0093
0094 ACTS_VERBOSE(" - with phi min/max = "
0095 << protoLayer.min(AxisDirection::AxisPhi, false) << " / "
0096 << protoLayer.max(AxisDirection::AxisPhi, false));
0097 ACTS_VERBOSE(" - # of modules = " << surfaces.size() << " ordered in ( "
0098 << binsPhi << " x " << binsZ << ")");
0099 std::unique_ptr<SurfaceArray> sArray;
0100 if (!surfaces.empty()) {
0101 sArray = std::make_unique<SurfaceArray>(
0102 m_cfg.surfaceArrayCreator->surfaceArrayOnCylinder(
0103 gctx, std::move(surfaces), binsPhi, binsZ, protoLayer,
0104 fullTransform, maxNeighborDistance));
0105 }
0106
0107
0108 std::shared_ptr<const CylinderBounds> cBounds(
0109 new CylinderBounds(layerR, layerHalfZ));
0110
0111
0112 MutableLayerPtr cLayer =
0113 CylinderLayer::create(fullTransform, cBounds, std::move(sArray),
0114 layerThickness, std::move(ad), active);
0115
0116 if (!cLayer) {
0117 ACTS_ERROR("Creation of cylinder layer did not succeed!");
0118 }
0119 associateSurfacesToLayer(*cLayer);
0120
0121
0122 return cLayer;
0123 }
0124
0125 MutableLayerPtr LayerCreator::cylinderLayer(
0126 const GeometryContext& gctx,
0127 std::vector<std::shared_ptr<const Surface>> surfaces, BinningType bTypePhi,
0128 BinningType bTypeZ, std::optional<ProtoLayer> _protoLayer,
0129 const Transform3& transform, std::unique_ptr<ApproachDescriptor> ad,
0130 std::uint8_t maxNeighborDistance) const {
0131 ProtoLayer protoLayer =
0132 _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces);
0133 if (!_protoLayer) {
0134 protoLayer.envelope[AxisDirection::AxisR] = m_cfg.defaultEnvelopeR;
0135 protoLayer.envelope[AxisDirection::AxisZ] = m_cfg.defaultEnvelopeZ;
0136 }
0137
0138
0139 double layerR = protoLayer.medium(AxisDirection::AxisR);
0140 double layerZ = protoLayer.medium(AxisDirection::AxisZ);
0141 double layerHalfZ = 0.5 * protoLayer.range(AxisDirection::AxisZ);
0142 double layerThickness = protoLayer.range(AxisDirection::AxisR);
0143
0144
0145 ACTS_VERBOSE("Creating a cylindrical Layer:");
0146 ACTS_VERBOSE(" - with layer R = " << layerR);
0147 ACTS_VERBOSE(" - from R min/max = "
0148 << protoLayer.min(AxisDirection::AxisR, false) << " / "
0149 << protoLayer.max(AxisDirection::AxisR, false));
0150 ACTS_VERBOSE(" - with R thickness = " << layerThickness);
0151 ACTS_VERBOSE(" - incl envelope = "
0152 << protoLayer.envelope[AxisDirection::AxisR][0u] << " / "
0153 << protoLayer.envelope[AxisDirection::AxisR][1u]);
0154 ACTS_VERBOSE(" - with z min/max = "
0155 << protoLayer.min(AxisDirection::AxisZ, false) << " (-"
0156 << protoLayer.envelope[AxisDirection::AxisZ][0u] << ") / "
0157 << protoLayer.max(AxisDirection::AxisZ, false) << " (+"
0158 << protoLayer.envelope[AxisDirection::AxisZ][1u] << ")");
0159 ACTS_VERBOSE(" - z center = " << layerZ);
0160 ACTS_VERBOSE(" - halflength z = " << layerHalfZ);
0161
0162
0163
0164
0165
0166 Transform3 fullTransform = transform;
0167 if (fullTransform.isApprox(Transform3::Identity()) && bTypeZ == equidistant) {
0168 fullTransform = Translation3(0, 0, layerZ) * fullTransform;
0169 ACTS_VERBOSE(" - layer z shift = " << -layerZ);
0170 }
0171
0172 ACTS_VERBOSE(" - with phi min/max = "
0173 << protoLayer.min(AxisDirection::AxisPhi, false) << " / "
0174 << protoLayer.max(AxisDirection::AxisPhi, false));
0175 ACTS_VERBOSE(" - # of modules = " << surfaces.size() << "");
0176
0177
0178 std::unique_ptr<SurfaceArray> sArray;
0179 if (!surfaces.empty()) {
0180 sArray = std::make_unique<SurfaceArray>(
0181 m_cfg.surfaceArrayCreator->surfaceArrayOnCylinder(
0182 gctx, std::move(surfaces), bTypePhi, bTypeZ, protoLayer,
0183 fullTransform, maxNeighborDistance));
0184 }
0185
0186
0187 std::shared_ptr<const CylinderBounds> cBounds(
0188 new CylinderBounds(layerR, layerHalfZ));
0189
0190
0191 MutableLayerPtr cLayer =
0192 CylinderLayer::create(fullTransform, cBounds, std::move(sArray),
0193 layerThickness, std::move(ad), active);
0194
0195 if (!cLayer) {
0196 ACTS_ERROR("Creation of cylinder layer did not succeed!");
0197 }
0198 associateSurfacesToLayer(*cLayer);
0199
0200
0201 return cLayer;
0202 }
0203
0204 MutableLayerPtr LayerCreator::discLayer(
0205 const GeometryContext& gctx,
0206 std::vector<std::shared_ptr<const Surface>> surfaces, std::size_t binsR,
0207 std::size_t binsPhi, std::optional<ProtoLayer> _protoLayer,
0208 const Transform3& transform, std::unique_ptr<ApproachDescriptor> ad,
0209 std::uint8_t maxNeighborDistance) const {
0210 ProtoLayer protoLayer =
0211 _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces);
0212 if (!_protoLayer) {
0213 protoLayer.envelope[AxisDirection::AxisR] = m_cfg.defaultEnvelopeR;
0214 protoLayer.envelope[AxisDirection::AxisZ] = m_cfg.defaultEnvelopeZ;
0215 }
0216
0217 double layerZ = protoLayer.medium(AxisDirection::AxisZ);
0218 double layerThickness = protoLayer.range(AxisDirection::AxisZ);
0219
0220
0221 ACTS_VERBOSE("Creating a disk Layer:");
0222 ACTS_VERBOSE(" - at Z position = " << layerZ);
0223 ACTS_VERBOSE(" - from Z min/max = "
0224 << protoLayer.min(AxisDirection::AxisZ, false) << " / "
0225 << protoLayer.max(AxisDirection::AxisZ, false));
0226 ACTS_VERBOSE(" - with Z thickness = " << layerThickness);
0227 ACTS_VERBOSE(" - incl envelope = "
0228 << protoLayer.envelope[AxisDirection::AxisZ][0u] << " / "
0229 << protoLayer.envelope[AxisDirection::AxisZ][1u]);
0230 ACTS_VERBOSE(" - with R min/max = "
0231 << protoLayer.min(AxisDirection::AxisR, false) << " (-"
0232 << protoLayer.envelope[AxisDirection::AxisR][0u] << ") / "
0233 << protoLayer.max(AxisDirection::AxisR, false) << " (+"
0234 << protoLayer.envelope[AxisDirection::AxisR][1u] << ")");
0235 ACTS_VERBOSE(" - with phi min/max = "
0236 << protoLayer.min(AxisDirection::AxisPhi, false) << " / "
0237 << protoLayer.max(AxisDirection::AxisPhi, false));
0238 ACTS_VERBOSE(" - # of modules = " << surfaces.size() << " ordered in ( "
0239 << binsR << " x " << binsPhi << ")");
0240
0241
0242 Transform3 fullTransform = transform;
0243 if (fullTransform.isApprox(Transform3::Identity())) {
0244 fullTransform = Translation3(0, 0, layerZ) * fullTransform;
0245 }
0246
0247 std::unique_ptr<SurfaceArray> sArray;
0248 if (!surfaces.empty()) {
0249 sArray = std::make_unique<SurfaceArray>(
0250 m_cfg.surfaceArrayCreator->surfaceArrayOnDisc(
0251 gctx, std::move(surfaces), binsR, binsPhi, protoLayer,
0252 fullTransform, maxNeighborDistance));
0253 }
0254
0255
0256 auto dBounds = std::make_shared<const RadialBounds>(
0257 protoLayer.min(AxisDirection::AxisR),
0258 protoLayer.max(AxisDirection::AxisR));
0259
0260
0261
0262
0263 MutableLayerPtr dLayer =
0264 DiscLayer::create(fullTransform, dBounds, std::move(sArray),
0265 layerThickness, std::move(ad), active);
0266
0267 if (!dLayer) {
0268 ACTS_ERROR("Creation of disc layer did not succeed!");
0269 }
0270 associateSurfacesToLayer(*dLayer);
0271
0272 return dLayer;
0273 }
0274
0275 MutableLayerPtr LayerCreator::discLayer(
0276 const GeometryContext& gctx,
0277 std::vector<std::shared_ptr<const Surface>> surfaces, BinningType bTypeR,
0278 BinningType bTypePhi, std::optional<ProtoLayer> _protoLayer,
0279 const Transform3& transform, std::unique_ptr<ApproachDescriptor> ad,
0280 std::uint8_t maxNeighborDistance) const {
0281 ProtoLayer protoLayer =
0282 _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces);
0283 if (!_protoLayer) {
0284 protoLayer.envelope[AxisDirection::AxisR] = m_cfg.defaultEnvelopeR;
0285 protoLayer.envelope[AxisDirection::AxisZ] = m_cfg.defaultEnvelopeZ;
0286 }
0287
0288 const double layerZ = protoLayer.medium(AxisDirection::AxisZ);
0289 const double layerThickness = protoLayer.range(AxisDirection::AxisZ);
0290
0291
0292 ACTS_VERBOSE("Creating a disk Layer:");
0293 ACTS_VERBOSE(" - at Z position = " << layerZ);
0294 ACTS_VERBOSE(" - from Z min/max = "
0295 << protoLayer.min(AxisDirection::AxisZ, false) << " / "
0296 << protoLayer.max(AxisDirection::AxisZ, false));
0297 ACTS_VERBOSE(" - with Z thickness = " << layerThickness);
0298 ACTS_VERBOSE(" - incl envelope = "
0299 << protoLayer.envelope[AxisDirection::AxisZ][0u] << " / "
0300 << protoLayer.envelope[AxisDirection::AxisZ][1u]);
0301 ACTS_VERBOSE(" - with R min/max = "
0302 << protoLayer.min(AxisDirection::AxisR, false) << " (-"
0303 << protoLayer.envelope[AxisDirection::AxisR][0u] << ") / "
0304 << protoLayer.max(AxisDirection::AxisR, false) << " (+"
0305 << protoLayer.envelope[AxisDirection::AxisR][1u] << ")");
0306 ACTS_VERBOSE(" - with phi min/max = "
0307 << protoLayer.min(AxisDirection::AxisPhi, false) << " / "
0308 << protoLayer.max(AxisDirection::AxisPhi, false));
0309 ACTS_VERBOSE(" - # of modules = " << surfaces.size());
0310
0311
0312 Transform3 fullTransform = transform;
0313 if (fullTransform.isApprox(Transform3::Identity())) {
0314 fullTransform = Translation3(0, 0, layerZ) * fullTransform;
0315 }
0316
0317
0318 std::unique_ptr<SurfaceArray> sArray;
0319 if (!surfaces.empty()) {
0320 sArray = std::make_unique<SurfaceArray>(
0321 m_cfg.surfaceArrayCreator->surfaceArrayOnDisc(
0322 gctx, std::move(surfaces), bTypeR, bTypePhi, protoLayer,
0323 fullTransform, maxNeighborDistance));
0324 }
0325
0326
0327 auto dBounds = std::make_shared<const RadialBounds>(
0328 protoLayer.min(AxisDirection::AxisR),
0329 protoLayer.max(AxisDirection::AxisR));
0330
0331
0332 MutableLayerPtr dLayer =
0333 DiscLayer::create(fullTransform, dBounds, std::move(sArray),
0334 layerThickness, std::move(ad), active);
0335 if (!dLayer) {
0336 ACTS_ERROR("Creation of disc layer did not succeed!");
0337 }
0338 associateSurfacesToLayer(*dLayer);
0339
0340 return dLayer;
0341 }
0342
0343 MutableLayerPtr LayerCreator::planeLayer(
0344 const GeometryContext& gctx,
0345 std::vector<std::shared_ptr<const Surface>> surfaces, std::size_t bins1,
0346 std::size_t bins2, AxisDirection aDir,
0347 std::optional<ProtoLayer> _protoLayer, const Transform3& transform,
0348 std::unique_ptr<ApproachDescriptor> ad,
0349 std::uint8_t maxNeighborDistance) const {
0350 ProtoLayer protoLayer =
0351 _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces);
0352 if (!_protoLayer) {
0353 protoLayer.envelope[AxisDirection::AxisR] = m_cfg.defaultEnvelopeR;
0354 protoLayer.envelope[AxisDirection::AxisZ] = m_cfg.defaultEnvelopeZ;
0355 }
0356
0357
0358 double layerHalf1 = 0, layerHalf2 = 0, layerThickness = 0;
0359 switch (aDir) {
0360 case AxisDirection::AxisX: {
0361 layerHalf1 = 0.5 * protoLayer.range(AxisDirection::AxisY);
0362 layerHalf2 = 0.5 * protoLayer.range(AxisDirection::AxisZ);
0363 layerThickness = protoLayer.range(AxisDirection::AxisX);
0364 break;
0365 }
0366 case AxisDirection::AxisY: {
0367 layerHalf1 = 0.5 * protoLayer.range(AxisDirection::AxisX);
0368 layerHalf2 = 0.5 * protoLayer.range(AxisDirection::AxisZ);
0369 layerThickness = protoLayer.range(AxisDirection::AxisY);
0370 break;
0371 }
0372 case AxisDirection::AxisZ: {
0373 layerHalf1 = 0.5 * protoLayer.range(AxisDirection::AxisX);
0374 layerHalf2 = 0.5 * protoLayer.range(AxisDirection::AxisY);
0375 layerThickness = protoLayer.range(AxisDirection::AxisZ);
0376 break;
0377 }
0378 default:
0379 throw std::invalid_argument("Invalid binning value");
0380 }
0381
0382 const double centerX = protoLayer.medium(AxisDirection::AxisX);
0383 const double centerY = protoLayer.medium(AxisDirection::AxisY);
0384 const double centerZ = protoLayer.medium(AxisDirection::AxisZ);
0385
0386 ACTS_VERBOSE("Creating a plane Layer:");
0387 ACTS_VERBOSE(" - with layer center = "
0388 << "(" << centerX << ", " << centerY << ", " << centerZ << ")");
0389 ACTS_VERBOSE(" - from X min/max = "
0390 << protoLayer.min(AxisDirection::AxisX) << " / "
0391 << protoLayer.max(AxisDirection::AxisX));
0392 ACTS_VERBOSE(" - from Y min/max = "
0393 << protoLayer.min(AxisDirection::AxisY) << " / "
0394 << protoLayer.max(AxisDirection::AxisY));
0395 ACTS_VERBOSE(" - with Z thickness = " << layerThickness);
0396 ACTS_VERBOSE(" - incl envelope = " << protoLayer.envelope[aDir][0u]
0397 << " / "
0398 << protoLayer.envelope[aDir][1u]);
0399
0400
0401
0402
0403 Transform3 fullTransform = transform;
0404 if (fullTransform.isApprox(Transform3::Identity())) {
0405 fullTransform = Translation3(centerX, centerY, centerZ) * fullTransform;
0406 ACTS_VERBOSE(" - layer shift = " << "(" << centerX << ", " << centerY
0407 << ", " << centerZ << ")");
0408 }
0409
0410 std::unique_ptr<SurfaceArray> sArray;
0411 if (!surfaces.empty()) {
0412 sArray = std::make_unique<SurfaceArray>(
0413 m_cfg.surfaceArrayCreator->surfaceArrayOnPlane(
0414 gctx, std::move(surfaces), bins1, bins2, aDir, protoLayer,
0415 fullTransform, maxNeighborDistance));
0416 }
0417
0418
0419 auto pBounds = std::make_shared<RectangleBounds>(layerHalf1, layerHalf2);
0420
0421
0422 MutableLayerPtr pLayer =
0423 PlaneLayer::create(fullTransform, pBounds, std::move(sArray),
0424 layerThickness, std::move(ad), active);
0425
0426 if (!pLayer) {
0427 ACTS_ERROR("Creation of plane layer did not succeed!");
0428 }
0429 associateSurfacesToLayer(*pLayer);
0430
0431
0432 return pLayer;
0433 }
0434
0435 void LayerCreator::associateSurfacesToLayer(Layer& layer) const {
0436 if (layer.surfaceArray() != nullptr) {
0437 auto surfaces = layer.surfaceArray()->surfaces();
0438
0439 for (auto& surface : surfaces) {
0440 auto mutableSurface = const_cast<Surface*>(surface);
0441 mutableSurface->associateLayer(layer);
0442 }
0443 }
0444 }
0445
0446 }