Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-22 08:22:23

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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   // @todo check consistency
0039   // copy the configuration
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   // Remaining layer parameters - they include the envelopes
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   // create the layer transforms if not given
0086   // we need to transform in case layerZ != 0, so that the layer will be
0087   // correctly defined using the halflength
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   // create the layer and push it back
0108   std::shared_ptr<const CylinderBounds> cBounds(
0109       new CylinderBounds(layerR, layerHalfZ));
0110 
0111   // create the layer
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   // now return
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   // remaining layer parameters
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   // adjust the layer radius
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   // create the layer transforms if not given
0163   // we need to transform in case layerZ != 0, so that the layer will be
0164   // correctly defined using the halflength
0165   // create the layer transforms if not given
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   // create the surface array
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   // create the layer and push it back
0187   std::shared_ptr<const CylinderBounds> cBounds(
0188       new CylinderBounds(layerR, layerHalfZ));
0189 
0190   // create the layer
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   // now return
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   // adjust the layer radius
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   // create the layer transforms if not given
0242   Transform3 fullTransform = transform;
0243   if (fullTransform.isApprox(Transform3::Identity())) {
0244     fullTransform = Translation3(0, 0, layerZ) * fullTransform;
0245   }
0246   // create the surface array
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   // create the share disc bounds
0256   auto dBounds = std::make_shared<const RadialBounds>(
0257       protoLayer.min(AxisDirection::AxisR),
0258       protoLayer.max(AxisDirection::AxisR));
0259 
0260   // create the layers
0261   // we use the same transform here as for the layer itself
0262   // for disk this is fine since we don't bin in Z, so does not matter
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   // return the layer
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   // adjust the layer radius
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   // create the layer transforms if not given
0312   Transform3 fullTransform = transform;
0313   if (fullTransform.isApprox(Transform3::Identity())) {
0314     fullTransform = Translation3(0, 0, layerZ) * fullTransform;
0315   }
0316 
0317   // create the surface array
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   // create the shared disc bounds
0327   auto dBounds = std::make_shared<const RadialBounds>(
0328       protoLayer.min(AxisDirection::AxisR),
0329       protoLayer.max(AxisDirection::AxisR));
0330 
0331   // create the layers
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   // return the layer
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   // remaining layer parameters
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   // create the layer transforms if not given
0401   // we need to transform in case centerX/centerY/centerZ != 0, so that the
0402   // layer will be correctly defined
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   // create the layer and push it back
0419   auto pBounds = std::make_shared<RectangleBounds>(layerHalf1, layerHalf2);
0420 
0421   // create the layer
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   // now return
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 }  // namespace Acts