Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 08:22:55

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 "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   // The rectangle bounds for plane surface
0051   const auto pBounds =
0052       std::make_shared<const Acts::RectangleBounds>(bounds[0], bounds[1]);
0053   // The radial bounds for disc surface
0054   const auto rBounds =
0055       std::make_shared<const Acts::RadialBounds>(bounds[0], bounds[1]);
0056 
0057   // Material of the surfaces
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   // Construct the rotation
0065   // This assumes the direction is AxisX, AxisY or AxisZ. No reset is necessary
0066   // in case of AxisZ
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   // Construct the surfaces and layers
0079   std::size_t nLayers = positions.size();
0080   std::vector<Acts::LayerPtr> layers(nLayers);
0081   for (unsigned int i = 0; i < nLayers; ++i) {
0082     // The translation without rotation yet
0083     Acts::Translation3 trans(offsets[0], offsets[1], positions[i]);
0084     // The entire transformation (the coordinate system, whose center is defined
0085     // by trans, will be rotated as well)
0086     Acts::Transform3 trafo(rotation * trans);
0087 
0088     // rotate around local z axis by stereo angle
0089     auto stereo = stereoAngles[i];
0090     trafo *= Acts::AngleAxis3(stereo, Acts::Vector3::UnitZ());
0091 
0092     // Create the detector element
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     // Get the surface
0110     auto surface = detElement->surface().getSharedPtr();
0111     // Add the detector element to the detector store
0112     detectorStore.push_back(std::move(detElement));
0113     // Construct the surface array (one surface contained)
0114     std::unique_ptr<Acts::SurfaceArray> surArray(
0115         new Acts::SurfaceArray(surface));
0116     // Construct the layer
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     // Associate the layer to the surface
0125     auto mutableSurface = const_cast<Acts::Surface*>(surface.get());
0126     mutableSurface->associateLayer(*layers[i]);
0127   }
0128 
0129   // The volume transform
0130   Acts::Translation3 transVol(offsets[0], offsets[1],
0131                               (positions.front() + positions.back()) * 0.5);
0132   Acts::Transform3 trafoVol(rotation * transVol);
0133 
0134   // The volume bounds is set to be a bit larger than either cubic with planes
0135   // or cylinder with discs
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   // Create the layer array
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   // Build the tracking volume
0161   auto trackVolume = std::make_shared<Acts::TrackingVolume>(
0162       trafoVol, boundsVol, nullptr, std::move(layArr), nullptr,
0163       Acts::MutableTrackingVolumeVector{}, "Telescope");
0164 
0165   // Build and return tracking geometry
0166   return std::make_unique<Acts::TrackingGeometry>(trackVolume);
0167 }