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