Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:32

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 <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Detector/Blueprint.hpp"
0012 #include "Acts/Detector/CylindricalContainerBuilder.hpp"
0013 #include "Acts/Detector/DetectorBuilder.hpp"
0014 #include "Acts/Detector/DetectorComponents.hpp"
0015 #include "Acts/Detector/DetectorVolume.hpp"
0016 #include "Acts/Detector/GeometryIdGenerator.hpp"
0017 #include "Acts/Detector/IndexedRootVolumeFinderBuilder.hpp"
0018 #include "Acts/Detector/detail/BlueprintDrawer.hpp"
0019 #include "Acts/Detector/detail/BlueprintHelper.hpp"
0020 #include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0023 #include "Acts/Navigation/InternalNavigation.hpp"
0024 #include "Acts/Surfaces/CylinderSurface.hpp"
0025 #include "Acts/Surfaces/DiscSurface.hpp"
0026 #include "Acts/Utilities/BinningData.hpp"
0027 
0028 #include <fstream>
0029 
0030 template <typename surface_type>
0031 class SurfaceBuilder : public Acts::Experimental::IInternalStructureBuilder {
0032  public:
0033   SurfaceBuilder(const Acts::Transform3& trf, double p0, double p1)
0034       : m_surface(Acts::Surface::makeShared<surface_type>(trf, p0, p1)) {}
0035   /// Conrstruct and return the internal structure creation
0036   ///
0037   /// @param gctx the geometry context at the creation of the internal structure
0038   ///
0039   /// @return a consistent set of detector volume internals
0040   Acts::Experimental::InternalStructure construct(
0041       [[maybe_unused]] const Acts::GeometryContext& gctx) const final {
0042     // Trivialities first: internal volumes
0043     std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
0044         internalVolumes = {};
0045     Acts::Experimental::ExternalNavigationDelegate internalVolumeUpdater =
0046         Acts::Experimental::tryNoVolumes();
0047 
0048     // Retrieve the layer surfaces
0049     Acts::Experimental::InternalNavigationDelegate internalCandidatesUpdater =
0050         Acts::Experimental::tryAllPortalsAndSurfaces();
0051 
0052     // Return the internal structure
0053     return Acts::Experimental::InternalStructure{
0054         {m_surface},
0055         internalVolumes,
0056         std::move(internalCandidatesUpdater),
0057         std::move(internalVolumeUpdater)};
0058   }
0059 
0060  private:
0061   std::shared_ptr<Acts::Surface> m_surface;
0062 };
0063 
0064 BOOST_AUTO_TEST_SUITE(Detector)
0065 
0066 BOOST_AUTO_TEST_CASE(CylindricalDetectorFromBlueprintTest) {
0067   Acts::GeometryContext tContext;
0068 
0069   // This tests shows how to careate cylindrical detector from a detector
0070   // blueprint.
0071   //
0072   // In general, the blueprint (lines below) is generated through reading in
0073   // or by parsing the geometry model (DD4heo, TGeo, Geant4, etc.). For
0074   // testing purpose, let us create the blueprint manually.
0075   //
0076 
0077   // Blueprint starts here ----------------
0078 
0079   // Detector dimensions
0080   double detectorIr = 0.;
0081   double detectorOr = 120.;
0082   double detectorHz = 400.;
0083 
0084   // Beam pipe
0085   double beamPipeOr = 20.;
0086 
0087   // Pixel system
0088   double pixelIr = 25;
0089   double pixelOr = 115;
0090   double pixelEcHz = 50;
0091   double pixelEcLayerHz = 10;
0092 
0093   // Create  root node
0094   std::vector<Acts::AxisDirection> detectorBinning = {
0095       Acts::AxisDirection::AxisR};
0096   std::vector<double> detectorBoundaries = {detectorIr, detectorOr, detectorHz};
0097 
0098   // The root node - detector
0099   auto detectorBpr = std::make_unique<Acts::Experimental::Blueprint::Node>(
0100       "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0101       detectorBoundaries, detectorBinning);
0102 
0103   // The beam pipe
0104   std::vector<double> beamPipeBoundaries = {detectorIr, beamPipeOr, detectorHz};
0105 
0106   auto beamPipeStructure =
0107       std::make_shared<SurfaceBuilder<Acts::CylinderSurface>>(
0108           Acts::Transform3::Identity(), 18, 0.99 * detectorHz);
0109   auto beamPipe = std::make_unique<Acts::Experimental::Blueprint::Node>(
0110       "beam_pipe", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0111       beamPipeBoundaries, beamPipeStructure);
0112   detectorBpr->add(std::move(beamPipe));
0113 
0114   // A pixel system
0115   std::vector<double> pixelBoundaries = {pixelIr, pixelOr, detectorHz};
0116   std::vector<Acts::AxisDirection> pixelBinning = {Acts::AxisDirection::AxisZ};
0117   auto pixel = std::make_unique<Acts::Experimental::Blueprint::Node>(
0118       "pixel", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0119       pixelBoundaries, pixelBinning);
0120 
0121   // Nec: Small differences to check if the adjustments are made
0122   std::vector<double> pixelEcBoundaries = {pixelIr, pixelOr - 5., pixelEcHz};
0123   std::vector<Acts::AxisDirection> pixelEcBinning = {
0124       Acts::AxisDirection::AxisZ};
0125 
0126   Acts::Transform3 pixelNecTransform =
0127       Acts::Transform3::Identity() *
0128       Acts::Translation3(0., 0., -detectorHz + pixelEcHz);
0129 
0130   auto pixelNec = std::make_unique<Acts::Experimental::Blueprint::Node>(
0131       "pixel_nec", pixelNecTransform, Acts::VolumeBounds::eCylinder,
0132       pixelEcBoundaries, pixelEcBinning);
0133 
0134   // Add a single encap layer
0135   std::vector<double> pixelNecBoundaries = {pixelIr + 2, pixelOr - 7.,
0136                                             pixelEcLayerHz};
0137 
0138   auto pixelNecLayerStructure =
0139       std::make_shared<SurfaceBuilder<Acts::DiscSurface>>(
0140           pixelNecTransform, pixelIr + 10., pixelOr - 10.);
0141 
0142   auto pixelNecLayer = std::make_unique<Acts::Experimental::Blueprint::Node>(
0143       "pixel_nec_layer", pixelNecTransform, Acts::VolumeBounds::eCylinder,
0144       pixelNecBoundaries, pixelNecLayerStructure);
0145 
0146   pixelNec->add(std::move(pixelNecLayer));
0147 
0148   // Barrel
0149   std::vector<double> pixelBarrelBoundaries = {pixelIr + 1, pixelOr - 1.,
0150                                                detectorHz - 2 * pixelEcHz};
0151   std::vector<Acts::AxisDirection> pixelBarrelBinning = {
0152       Acts::AxisDirection::AxisR};
0153 
0154   auto pixelBarrel = std::make_unique<Acts::Experimental::Blueprint::Node>(
0155       "pixel_barrel", Acts::Transform3::Identity(),
0156       Acts::VolumeBounds::eCylinder, pixelBarrelBoundaries, pixelBarrelBinning);
0157 
0158   auto pixelBarrelL0Structure =
0159       std::make_shared<SurfaceBuilder<Acts::CylinderSurface>>(
0160           Acts::Transform3::Identity(), 62.5, detectorHz - 2 * pixelEcHz - 10.);
0161   std::vector<double> pixelBarrelL0Boundaries = {60, 65.,
0162                                                  detectorHz - 2 * pixelEcHz};
0163   auto pixelBarrelL0 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0164       "pixel_barrel_l0", Acts::Transform3::Identity(),
0165       Acts::VolumeBounds::eCylinder, pixelBarrelL0Boundaries,
0166       pixelBarrelL0Structure);
0167 
0168   auto pixelBarrelL1Structure =
0169       std::make_shared<SurfaceBuilder<Acts::CylinderSurface>>(
0170           Acts::Transform3::Identity(), 102.5,
0171           detectorHz - 2 * pixelEcHz - 10.);
0172 
0173   std::vector<double> pixelBarrelL1Boundaries = {100, 105.,
0174                                                  detectorHz - 2 * pixelEcHz};
0175   auto pixelBarrelL1 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0176       "pixel_barrel_l1", Acts::Transform3::Identity(),
0177       Acts::VolumeBounds::eCylinder, pixelBarrelL1Boundaries,
0178       pixelBarrelL1Structure);
0179   pixelBarrel->add(std::move(pixelBarrelL0));
0180   pixelBarrel->add(std::move(pixelBarrelL1));
0181 
0182   Acts::Transform3 pixelPecTransform =
0183       Acts::Transform3::Identity() *
0184       Acts::Translation3(0., 0., detectorHz - pixelEcHz);
0185 
0186   auto pixelPec = std::make_unique<Acts::Experimental::Blueprint::Node>(
0187       "pixel_pec", pixelPecTransform, Acts::VolumeBounds::eCylinder,
0188       pixelEcBoundaries, pixelEcBinning);
0189 
0190   std::vector<double> pixelPecBoundaries = {pixelIr + 2, pixelOr - 7., 10.};
0191 
0192   auto pixelPecLayerStructure =
0193       std::make_shared<SurfaceBuilder<Acts::DiscSurface>>(
0194           pixelPecTransform, pixelIr + 10., pixelOr - 10.);
0195 
0196   auto pixelPecLayer = std::make_unique<Acts::Experimental::Blueprint::Node>(
0197       "pixel_pec_layer", pixelPecTransform, Acts::VolumeBounds::eCylinder,
0198       pixelPecBoundaries, pixelPecLayerStructure);
0199 
0200   pixelPec->add(std::move(pixelPecLayer));
0201 
0202   // Adding pixel
0203   pixel->add(std::move(pixelNec));
0204   pixel->add(std::move(pixelPec));
0205   pixel->add(std::move(pixelBarrel));
0206 
0207   detectorBpr->add(std::move(pixel));
0208 
0209   // An Indexed volume finder will be attached
0210   std::vector<Acts::AxisDirection> rootVolumeBinning = {
0211       Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisR};
0212   detectorBpr->rootVolumeFinderBuilder =
0213       std::make_shared<Acts::Experimental::IndexedRootVolumeFinderBuilder>(
0214           rootVolumeBinning);
0215 
0216   // A geo ID generator
0217   detectorBpr->geoIdGenerator =
0218       std::make_shared<Acts::Experimental::GeometryIdGenerator>(
0219           Acts::Experimental::GeometryIdGenerator::Config{},
0220           Acts::getDefaultLogger("RecursiveIdGenerator",
0221                                  Acts::Logging::VERBOSE));
0222 
0223   // Complete and fill gaps
0224   Acts::Experimental::detail::BlueprintHelper::fillGaps(*detectorBpr);
0225 
0226   std::fstream fs("cylindrical_detector_blueprint.dot", std::ios::out);
0227   Acts::Experimental::detail::BlueprintDrawer::dotStream(fs, *detectorBpr);
0228   fs.close();
0229 
0230   // ----------------------------- end of blueprint
0231 
0232   // Create a Cylindrical detector builder from this blueprint
0233   auto detectorBuilder =
0234       std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0235           *detectorBpr, Acts::Logging::VERBOSE);
0236 
0237   // Detector builder
0238   Acts::Experimental::DetectorBuilder::Config dCfg;
0239   dCfg.auxiliary =
0240       "*** Test : auto generated cylindrical detector builder  ***";
0241   dCfg.name = "Cylindrical detector from blueprint";
0242   dCfg.builder = detectorBuilder;
0243   dCfg.geoIdGenerator = detectorBpr->geoIdGenerator;
0244 
0245   auto detector = Acts::Experimental::DetectorBuilder(dCfg).construct(tContext);
0246 
0247   BOOST_REQUIRE_NE(detector, nullptr);
0248 
0249   // There should be 14 volumes, and they should be built in order
0250   // beam_pipe
0251   // detector_gap_0
0252   // pixel_nec_gap_0
0253   // pixel_nec_layer
0254   // pixel_nec_gap_1
0255   // pixel_barrel_gap_0
0256   // pixel_barrel_l0
0257   // pixel_barrel_gap_1
0258   // pixel_barrel_l1
0259   // pixel_barrel_gap_2
0260   // pixel_pec_gap_0
0261   // pixel_pec_layer
0262   // pixel_pec_gap_1
0263   // detector_gap_1
0264   BOOST_CHECK_EQUAL(detector->volumes().size(), 14u);
0265   BOOST_CHECK_EQUAL(detector->volumes()[0]->name(), "beam_pipe");
0266   BOOST_CHECK_EQUAL(detector->volumes()[1]->name(), "detector_gap_0");
0267   BOOST_CHECK_EQUAL(detector->volumes()[2]->name(), "pixel_nec_gap_0");
0268   BOOST_CHECK_EQUAL(detector->volumes()[3]->name(), "pixel_nec_layer");
0269   BOOST_CHECK_EQUAL(detector->volumes()[4]->name(), "pixel_nec_gap_1");
0270   BOOST_CHECK_EQUAL(detector->volumes()[5]->name(), "pixel_barrel_gap_0");
0271   BOOST_CHECK_EQUAL(detector->volumes()[6]->name(), "pixel_barrel_l0");
0272   BOOST_CHECK_EQUAL(detector->volumes()[7]->name(), "pixel_barrel_gap_1");
0273   BOOST_CHECK_EQUAL(detector->volumes()[8]->name(), "pixel_barrel_l1");
0274   BOOST_CHECK_EQUAL(detector->volumes()[9]->name(), "pixel_barrel_gap_2");
0275   BOOST_CHECK_EQUAL(detector->volumes()[10]->name(), "pixel_pec_gap_0");
0276   BOOST_CHECK_EQUAL(detector->volumes()[11]->name(), "pixel_pec_layer");
0277   BOOST_CHECK_EQUAL(detector->volumes()[12]->name(), "pixel_pec_gap_1");
0278   BOOST_CHECK_EQUAL(detector->volumes()[13]->name(), "detector_gap_1");
0279 }
0280 
0281 BOOST_AUTO_TEST_SUITE_END()