Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:45

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/DetectorElementBase.hpp"
0016 #include "Acts/Geometry/DiscLayer.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/ILayerArrayCreator.hpp"
0019 #include "Acts/Geometry/ITrackingVolumeHelper.hpp"
0020 #include "Acts/Geometry/LayerArrayCreator.hpp"
0021 #include "Acts/Geometry/PlaneLayer.hpp"
0022 #include "Acts/Geometry/TrackingGeometry.hpp"
0023 #include "Acts/Geometry/TrackingVolume.hpp"
0024 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0025 #include "Acts/Material/Material.hpp"
0026 #include "Acts/Material/MaterialSlab.hpp"
0027 #include "Acts/Surfaces/RadialBounds.hpp"
0028 #include "Acts/Surfaces/RectangleBounds.hpp"
0029 #include "Acts/Surfaces/Surface.hpp"
0030 #include "Acts/Surfaces/SurfaceArray.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::DetectorElementBase>>&
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     if (surfaceType == TelescopeSurfaceType::Plane) {
0095       detElement = std::make_shared<TelescopeDetectorElement>(
0096           std::make_shared<const Acts::Transform3>(trafo), pBounds, 1._um,
0097           surfaceMaterial);
0098     } else {
0099       detElement = std::make_shared<TelescopeDetectorElement>(
0100           std::make_shared<const Acts::Transform3>(trafo), rBounds, 1._um,
0101           surfaceMaterial);
0102     }
0103     // Get the surface
0104     auto surface = detElement->surface().getSharedPtr();
0105     // Add the detector element to the detector store
0106     detectorStore.push_back(std::move(detElement));
0107     // Construct the surface array (one surface contained)
0108     std::unique_ptr<Acts::SurfaceArray> surArray(
0109         new Acts::SurfaceArray(surface));
0110     // Construct the layer
0111     if (surfaceType == TelescopeSurfaceType::Plane) {
0112       layers[i] =
0113           Acts::PlaneLayer::create(trafo, pBounds, std::move(surArray), 1._mm);
0114     } else {
0115       layers[i] =
0116           Acts::DiscLayer::create(trafo, rBounds, std::move(surArray), 1._mm);
0117     }
0118     // Associate the layer to the surface
0119     auto mutableSurface = const_cast<Acts::Surface*>(surface.get());
0120     mutableSurface->associateLayer(*layers[i]);
0121   }
0122 
0123   // The volume transform
0124   Acts::Translation3 transVol(offsets[0], offsets[1],
0125                               (positions.front() + positions.back()) * 0.5);
0126   Acts::Transform3 trafoVol(rotation * transVol);
0127 
0128   // The volume bounds is set to be a bit larger than either cubic with planes
0129   // or cylinder with discs
0130   auto length = positions.back() - positions.front();
0131   std::shared_ptr<Acts::VolumeBounds> boundsVol = nullptr;
0132   if (surfaceType == TelescopeSurfaceType::Plane) {
0133     boundsVol = std::make_shared<Acts::CuboidVolumeBounds>(
0134         bounds[0] + 5._mm, bounds[1] + 5._mm, length + 10._mm);
0135   } else {
0136     boundsVol = std::make_shared<Acts::CylinderVolumeBounds>(
0137         std::max(bounds[0] - 5.0_mm, 0.), bounds[1] + 5._mm, length + 10._mm);
0138   }
0139 
0140   Acts::LayerArrayCreator::Config lacConfig;
0141   Acts::LayerArrayCreator layArrCreator(
0142       lacConfig,
0143       Acts::getDefaultLogger("LayerArrayCreator", Acts::Logging::INFO));
0144   Acts::LayerVector layVec;
0145   for (unsigned int i = 0; i < nLayers; i++) {
0146     layVec.push_back(layers[i]);
0147   }
0148   // Create the layer array
0149   Acts::GeometryContext genGctx{gctx};
0150   std::unique_ptr<const Acts::LayerArray> layArr(layArrCreator.layerArray(
0151       genGctx, layVec, positions.front() - 2._mm, positions.back() + 2._mm,
0152       Acts::BinningType::arbitrary, binValue));
0153 
0154   // Build the tracking volume
0155   auto trackVolume = std::make_shared<Acts::TrackingVolume>(
0156       trafoVol, boundsVol, nullptr, std::move(layArr), nullptr,
0157       Acts::MutableTrackingVolumeVector{}, "Telescope");
0158 
0159   // Build and return tracking geometry
0160   return std::make_unique<Acts::TrackingGeometry>(trackVolume);
0161 }