File indexing completed on 2026-09-17 08:22:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/DiscLayer.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Geometry/ILayerArrayCreator.hpp"
0018 #include "Acts/Geometry/ITrackingVolumeHelper.hpp"
0019 #include "Acts/Geometry/LayerArrayCreator.hpp"
0020 #include "Acts/Geometry/PlaneLayer.hpp"
0021 #include "Acts/Geometry/TrackingGeometry.hpp"
0022 #include "Acts/Geometry/TrackingVolume.hpp"
0023 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0024 #include "Acts/Material/Material.hpp"
0025 #include "Acts/Material/MaterialSlab.hpp"
0026 #include "Acts/Surfaces/RadialBounds.hpp"
0027 #include "Acts/Surfaces/RectangleBounds.hpp"
0028 #include "Acts/Surfaces/Surface.hpp"
0029 #include "Acts/Surfaces/SurfaceArray.hpp"
0030 #include "Acts/Surfaces/SurfacePlacementBase.hpp"
0031 #include "Acts/Utilities/Logger.hpp"
0032 #include "ActsExamples/TelescopeDetector/TelescopeDetectorElement.hpp"
0033
0034 #include <algorithm>
0035 #include <cstddef>
0036 #include <utility>
0037
0038 std::unique_ptr<const Acts::TrackingGeometry>
0039 ActsExamples::buildTelescopeDetector(
0040 const Acts::GeometryContext& gctx,
0041 std::vector<std::shared_ptr<const Acts::SurfacePlacementBase>>&
0042 detectorStore,
0043 const std::vector<double>& positions,
0044 const std::vector<double>& stereoAngles,
0045 const std::array<double, 2>& offsets, const std::array<double, 2>& bounds,
0046 double thickness, TelescopeSurfaceType surfaceType,
0047 Acts::AxisDirection binValue) {
0048 using namespace Acts::UnitLiterals;
0049
0050
0051 const auto pBounds =
0052 std::make_shared<const Acts::RectangleBounds>(bounds[0], bounds[1]);
0053
0054 const auto rBounds =
0055 std::make_shared<const Acts::RadialBounds>(bounds[0], bounds[1]);
0056
0057
0058 Acts::Material silicon = Acts::Material::fromMassDensity(
0059 9.370_cm, 46.52_cm, 28.0855, 14, 2.329_g / 1_cm3);
0060 Acts::MaterialSlab matProp(silicon, thickness);
0061 const auto surfaceMaterial =
0062 std::make_shared<Acts::HomogeneousSurfaceMaterial>(matProp);
0063
0064
0065
0066
0067 Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
0068 if (binValue == Acts::AxisDirection::AxisX) {
0069 rotation.col(0) = Acts::Vector3(0, 0, -1);
0070 rotation.col(1) = Acts::Vector3(0, 1, 0);
0071 rotation.col(2) = Acts::Vector3(1, 0, 0);
0072 } else if (binValue == Acts::AxisDirection::AxisY) {
0073 rotation.col(0) = Acts::Vector3(1, 0, 0);
0074 rotation.col(1) = Acts::Vector3(0, 0, -1);
0075 rotation.col(2) = Acts::Vector3(0, 1, 0);
0076 }
0077
0078
0079 std::size_t nLayers = positions.size();
0080 std::vector<Acts::LayerPtr> layers(nLayers);
0081 for (unsigned int i = 0; i < nLayers; ++i) {
0082
0083 Acts::Translation3 trans(offsets[0], offsets[1], positions[i]);
0084
0085
0086 Acts::Transform3 trafo(rotation * trans);
0087
0088
0089 auto stereo = stereoAngles[i];
0090 trafo *= Acts::AngleAxis3(stereo, Acts::Vector3::UnitZ());
0091
0092
0093 std::shared_ptr<TelescopeDetectorElement> detElement = nullptr;
0094
0095 const auto id =
0096 static_cast<TelescopeDetectorElement::Identifier>(detectorStore.size());
0097
0098 if (surfaceType == TelescopeSurfaceType::Plane) {
0099 detElement = std::make_shared<TelescopeDetectorElement>(
0100 id, std::make_shared<Acts::Transform3>(trafo), pBounds, 1._um,
0101 surfaceMaterial);
0102 } else {
0103 detElement = std::make_shared<TelescopeDetectorElement>(
0104 id, std::make_shared<Acts::Transform3>(trafo), rBounds, 1._um,
0105 surfaceMaterial);
0106 }
0107 detectorStore.push_back(detElement);
0108
0109
0110 auto surface = detElement->surface().getSharedPtr();
0111
0112 detectorStore.push_back(std::move(detElement));
0113
0114 std::unique_ptr<Acts::SurfaceArray> surArray(
0115 new Acts::SurfaceArray(surface));
0116
0117 if (surfaceType == TelescopeSurfaceType::Plane) {
0118 layers[i] =
0119 Acts::PlaneLayer::create(trafo, pBounds, std::move(surArray), 1._mm);
0120 } else {
0121 layers[i] =
0122 Acts::DiscLayer::create(trafo, rBounds, std::move(surArray), 1._mm);
0123 }
0124
0125 auto mutableSurface = const_cast<Acts::Surface*>(surface.get());
0126 mutableSurface->associateLayer(*layers[i]);
0127 }
0128
0129
0130 Acts::Translation3 transVol(offsets[0], offsets[1],
0131 (positions.front() + positions.back()) * 0.5);
0132 Acts::Transform3 trafoVol(rotation * transVol);
0133
0134
0135
0136 auto length = positions.back() - positions.front();
0137 std::shared_ptr<Acts::VolumeBounds> boundsVol = nullptr;
0138 if (surfaceType == TelescopeSurfaceType::Plane) {
0139 boundsVol = std::make_shared<Acts::CuboidVolumeBounds>(
0140 bounds[0] + 5._mm, bounds[1] + 5._mm, length + 10._mm);
0141 } else {
0142 boundsVol = std::make_shared<Acts::CylinderVolumeBounds>(
0143 std::max(bounds[0] - 5.0_mm, 0.), bounds[1] + 5._mm, length + 10._mm);
0144 }
0145
0146 Acts::LayerArrayCreator::Config lacConfig;
0147 Acts::LayerArrayCreator layArrCreator(
0148 lacConfig,
0149 Acts::getDefaultLogger("LayerArrayCreator", Acts::Logging::INFO));
0150 Acts::LayerVector layVec;
0151 for (unsigned int i = 0; i < nLayers; i++) {
0152 layVec.push_back(layers[i]);
0153 }
0154
0155 Acts::GeometryContext genGctx{gctx};
0156 std::unique_ptr<const Acts::LayerArray> layArr(layArrCreator.layerArray(
0157 genGctx, layVec, positions.front() - 2._mm, positions.back() + 2._mm,
0158 Acts::BinningType::arbitrary, binValue));
0159
0160
0161 auto trackVolume = std::make_shared<Acts::TrackingVolume>(
0162 trafoVol, boundsVol, nullptr, std::move(layArr), nullptr,
0163 Acts::MutableTrackingVolumeVector{}, "Telescope");
0164
0165
0166 return std::make_unique<Acts::TrackingGeometry>(trackVolume);
0167 }