File indexing completed on 2025-07-12 07:51:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/LayerArrayCreator.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryObjectSorter.hpp"
0013 #include "Acts/Geometry/Layer.hpp"
0014 #include "Acts/Geometry/NavigationLayer.hpp"
0015 #include "Acts/Surfaces/CylinderBounds.hpp"
0016 #include "Acts/Surfaces/CylinderSurface.hpp"
0017 #include "Acts/Surfaces/DiscSurface.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Utilities/BinUtility.hpp"
0021 #include "Acts/Utilities/BinnedArrayXD.hpp"
0022 #include "Acts/Utilities/BinningType.hpp"
0023
0024 #include <algorithm>
0025 #include <memory>
0026 #include <ostream>
0027 #include <utility>
0028 #include <vector>
0029
0030 namespace Acts {
0031
0032 std::unique_ptr<const LayerArray> LayerArrayCreator::layerArray(
0033 const GeometryContext& gctx, const LayerVector& layersInput, double min,
0034 double max, BinningType bType, AxisDirection aDir) const {
0035 ACTS_VERBOSE("Build LayerArray with " << layersInput.size()
0036 << " layers at input.");
0037 ACTS_VERBOSE(" min/max provided : " << min << " / " << max);
0038 ACTS_VERBOSE(" binning type : " << bType);
0039 ACTS_VERBOSE(" binning value : " << aDir);
0040
0041
0042 LayerVector layers(layersInput);
0043
0044
0045 GeometryObjectSorterT<std::shared_ptr<const Layer>> layerSorter(gctx, aDir);
0046 std::ranges::sort(layers, layerSorter);
0047
0048 using LayerOrderPosition = std::pair<std::shared_ptr<const Layer>, Vector3>;
0049
0050 std::shared_ptr<const Layer> layer = nullptr;
0051 std::unique_ptr<const BinUtility> binUtility = nullptr;
0052 std::vector<LayerOrderPosition> layerOrderVector;
0053
0054
0055 switch (bType) {
0056
0057 case equidistant: {
0058
0059 for (auto& layIter : layers) {
0060 ACTS_VERBOSE("equidistant : registering a Layer at binning position : "
0061 << (layIter->referencePosition(gctx, aDir)));
0062 layerOrderVector.push_back(LayerOrderPosition(
0063 layIter, layIter->referencePosition(gctx, aDir)));
0064 }
0065
0066 binUtility = std::make_unique<const BinUtility>(layers.size(), min, max,
0067 open, aDir);
0068 ACTS_VERBOSE("equidistant : created a BinUtility as " << *binUtility);
0069 } break;
0070
0071
0072 case arbitrary: {
0073 std::vector<float> boundaries;
0074
0075 boundaries.push_back(min);
0076 double layerValue = 0.;
0077 double layerThickness = 0.;
0078 std::shared_ptr<const Layer> navLayer = nullptr;
0079 std::shared_ptr<const Layer> lastLayer = nullptr;
0080
0081 for (auto& layIter : layers) {
0082
0083 layerThickness = layIter->thickness();
0084 layerValue = layIter->referencePositionValue(gctx, aDir);
0085
0086 boundaries.push_back(layerValue - 0.5 * layerThickness);
0087 boundaries.push_back(layerValue + 0.5 * layerThickness);
0088
0089 double navigationValue = 0.5 * ((layerValue - 0.5 * layerThickness) +
0090 boundaries.at(boundaries.size() - 3));
0091
0092
0093 if (navigationValue == (layerValue - 0.5 * layerThickness)) {
0094 ACTS_ERROR(
0095 "Layers are attached to each other at: "
0096 << layerValue - 0.5 * layerThickness
0097 << ", which corrupts "
0098 "navigation. This should never happen. Please detach the "
0099 "layers in your geometry description.");
0100 }
0101
0102 if (navigationValue > (layerValue - 0.5 * layerThickness)) {
0103 ACTS_ERROR("Layers are overlapping at: "
0104 << layerValue - 0.5 * layerThickness
0105 << ". This should never happen. "
0106 "Please check your geometry description.");
0107 }
0108
0109
0110 std::shared_ptr<const Surface> navLayerSurface =
0111 createNavigationSurface(gctx, *layIter, aDir,
0112 -std::abs(layerValue - navigationValue));
0113 ACTS_VERBOSE(
0114 "arbitrary : creating a NavigationLayer at "
0115 << (navLayerSurface->referencePosition(gctx, aDir)).x() << ", "
0116 << (navLayerSurface->referencePosition(gctx, aDir)).y() << ", "
0117 << (navLayerSurface->referencePosition(gctx, aDir)).z());
0118 navLayer = NavigationLayer::create(std::move(navLayerSurface));
0119
0120 layerOrderVector.push_back(LayerOrderPosition(
0121 navLayer, navLayer->referencePosition(gctx, aDir)));
0122
0123
0124 layerOrderVector.push_back(LayerOrderPosition(
0125 layIter, layIter->referencePosition(gctx, aDir)));
0126 ACTS_VERBOSE("arbitrary : registering MaterialLayer at "
0127 << (layIter->referencePosition(gctx, aDir)).x() << ", "
0128 << (layIter->referencePosition(gctx, aDir)).y() << ", "
0129 << (layIter->referencePosition(gctx, aDir)).z());
0130
0131 lastLayer = layIter;
0132 }
0133
0134
0135 double navigationValue =
0136 0.5 * (boundaries.at(boundaries.size() - 1) + max);
0137
0138 if (navigationValue != max && lastLayer != nullptr) {
0139
0140 std::shared_ptr<const Surface> navLayerSurface =
0141 createNavigationSurface(gctx, *lastLayer, aDir,
0142 navigationValue - layerValue);
0143 ACTS_VERBOSE(
0144 "arbitrary : creating a NavigationLayer at "
0145 << (navLayerSurface->referencePosition(gctx, aDir)).x() << ", "
0146 << (navLayerSurface->referencePosition(gctx, aDir)).y() << ", "
0147 << (navLayerSurface->referencePosition(gctx, aDir)).z());
0148 navLayer = NavigationLayer::create(std::move(navLayerSurface));
0149
0150 layerOrderVector.push_back(LayerOrderPosition(
0151 navLayer, navLayer->referencePosition(gctx, aDir)));
0152 }
0153
0154 boundaries.push_back(max);
0155
0156 ACTS_VERBOSE(layerOrderVector.size()
0157 << " Layers (material + navigation) built. ");
0158
0159 binUtility = std::make_unique<const BinUtility>(boundaries, open, aDir);
0160 ACTS_VERBOSE("arbitrary : created a BinUtility as " << *binUtility);
0161
0162 } break;
0163
0164 default: {
0165 return nullptr;
0166 }
0167 }
0168
0169 return std::make_unique<const BinnedArrayXD<LayerPtr>>(layerOrderVector,
0170 std::move(binUtility));
0171 }
0172
0173 std::shared_ptr<Surface> LayerArrayCreator::createNavigationSurface(
0174 const GeometryContext& gctx, const Layer& layer, AxisDirection aDir,
0175 double offset) const {
0176
0177 const Surface& layerSurface = layer.surfaceRepresentation();
0178
0179 Vector3 translation(0., 0., 0.);
0180
0181 switch (aDir) {
0182
0183 case AxisDirection::AxisX: {
0184 translation = Vector3(offset, 0., 0.);
0185 } break;
0186
0187 case AxisDirection::AxisY: {
0188 translation = Vector3(0., offset, 0.);
0189 } break;
0190
0191 case AxisDirection::AxisZ: {
0192 translation = Vector3(0., 0., offset);
0193 } break;
0194
0195 case AxisDirection::AxisR: {
0196
0197 if (layerSurface.type() == Surface::Cylinder) {
0198 break;
0199 }
0200 translation = Vector3(offset, 0., 0.);
0201 } break;
0202
0203 default: {
0204 ACTS_WARNING("Not yet implemented.");
0205 }
0206 }
0207
0208 std::shared_ptr<Surface> navigationSurface;
0209
0210 if (layerSurface.type() == Surface::Plane) {
0211
0212 Transform3 shift = Transform3(Translation3(translation));
0213 const PlaneSurface* plane =
0214 dynamic_cast<const PlaneSurface*>(&layerSurface);
0215 navigationSurface = Surface::makeShared<PlaneSurface>(gctx, *plane, shift);
0216 } else if (layerSurface.type() == Surface::Disc) {
0217
0218 Transform3 shift = Transform3(Translation3(translation));
0219 const DiscSurface* disc = dynamic_cast<const DiscSurface*>(&layerSurface);
0220 navigationSurface = Surface::makeShared<DiscSurface>(gctx, *disc, shift);
0221 } else if (layerSurface.type() == Surface::Cylinder) {
0222
0223 const CylinderBounds* cBounds =
0224 dynamic_cast<const CylinderBounds*>(&(layerSurface.bounds()));
0225 double navigationR = cBounds->get(CylinderBounds::eR) + offset;
0226 double halflengthZ = cBounds->get(CylinderBounds::eHalfLengthZ);
0227
0228 auto cylinderBounds =
0229 std::make_shared<CylinderBounds>(navigationR, halflengthZ);
0230 navigationSurface = Surface::makeShared<CylinderSurface>(
0231 layerSurface.transform(gctx), cylinderBounds);
0232 } else {
0233 ACTS_WARNING("Not implemented.");
0234 }
0235 return navigationSurface;
0236 }
0237
0238 }