Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:13:23

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/detail/BlueprintDrawer.hpp"
0013 #include "Acts/Detector/detail/BlueprintHelper.hpp"
0014 
0015 #include <exception>
0016 #include <fstream>
0017 
0018 namespace Acts::Experimental {
0019 class IInternalStructureBuilder {};
0020 }  // namespace Acts::Experimental
0021 
0022 BOOST_AUTO_TEST_SUITE(Experimental)
0023 
0024 BOOST_AUTO_TEST_CASE(BlueprintHelperSorting) {
0025   // Create  root node
0026   std::vector<Acts::AxisDirection> detectorBinning = {
0027       Acts::AxisDirection::AxisR};
0028   std::vector<double> detectorBoundaries = {0., 50., 100.};
0029   auto detector = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0030       "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0031       detectorBoundaries, detectorBinning);
0032 
0033   BOOST_CHECK_EQUAL(detector->parent, nullptr);
0034   BOOST_CHECK(detector->children.empty());
0035   BOOST_CHECK_EQUAL(detector->name, "detector");
0036 
0037   std::vector<Acts::AxisDirection> pixelsBinning = {Acts::AxisDirection::AxisZ};
0038   std::vector<double> pixelsBoundaries = {20., 50., 100.};
0039 
0040   auto pixels = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0041       "pixels", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0042       pixelsBoundaries, pixelsBinning);
0043 
0044   std::vector<double> beamPipeBoundaries = {0., 20., 100.};
0045   auto beamPipe = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0046       "beam_pipe", Acts::Transform3::Identity(), Acts::VolumeBounds::eOther,
0047       beamPipeBoundaries);
0048 
0049   std::vector<double> gapBoundaries = {20., 50., 10.};
0050   auto gap0 = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0051       "gap0", Acts::Transform3::Identity() * Acts::Translation3(0., 0., -90.),
0052       Acts::VolumeBounds::eCylinder, gapBoundaries);
0053 
0054   std::vector<double> layerBoundaries = {20., 50., 80.};
0055   auto layer = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0056       "layer", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0057       layerBoundaries,
0058       std::make_shared<Acts::Experimental::IInternalStructureBuilder>());
0059 
0060   auto gap1 = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0061       "gap1", Acts::Transform3::Identity() * Acts::Translation3(0., 0., 90.),
0062       Acts::VolumeBounds::eCylinder, gapBoundaries);
0063 
0064   // Add the nodes in a random fashion
0065   pixels->add(std::move(gap1));
0066   pixels->add(std::move(gap0));
0067   pixels->add(std::move(layer));
0068   // Add pixels and beam pipe in reverse order
0069   detector->add(std::move(pixels));
0070   detector->add(std::move(beamPipe));
0071 
0072   std::ofstream fs("detector_unordered.dot");
0073   Acts::Experimental::detail::BlueprintDrawer::dotStream(fs, *detector);
0074   fs.close();
0075 
0076   // Sort the detector
0077   Acts::Experimental::detail::BlueprintHelper::sort(*detector);
0078 
0079   // Test the recursive sort worked
0080   BOOST_CHECK_EQUAL(detector->children.front()->name, "beam_pipe");
0081   BOOST_CHECK_EQUAL(detector->children.back()->name, "pixels");
0082   BOOST_CHECK_EQUAL(detector->children.back()->children.front()->name, "gap0");
0083   BOOST_CHECK_EQUAL(detector->children.back()->children[1u]->name, "layer");
0084   BOOST_CHECK_EQUAL(detector->children.back()->children.back()->name, "gap1");
0085 
0086   std::ofstream fs2("detector_ordered.dot");
0087   Acts::Experimental::detail::BlueprintDrawer::dotStream(fs2, *detector);
0088   fs2.close();
0089 }
0090 
0091 BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapFilling) {
0092   // Detector dimensions
0093   double detectorIr = 0.;
0094   double detectorOr = 120.;
0095   double detectorHz = 400.;
0096 
0097   // Beam pipe
0098   double beamPipeOr = 20.;
0099 
0100   // Pixel system
0101   double pixelIr = 25;
0102   double pixelOr = 115;
0103   double pixelEcHz = 50;
0104 
0105   auto innerBuilder =
0106       std::make_shared<Acts::Experimental::IInternalStructureBuilder>();
0107 
0108   // Create  root node
0109   std::vector<Acts::AxisDirection> detectorBinning = {
0110       Acts::AxisDirection::AxisR};
0111   std::vector<double> detectorBoundaries = {detectorIr, detectorOr, detectorHz};
0112 
0113   // The root node - detector
0114   auto detector = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0115       "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0116       detectorBoundaries, detectorBinning);
0117 
0118   // The beam pipe
0119   std::vector<double> beamPipeBoundaries = {detectorIr, beamPipeOr, detectorHz};
0120   auto beamPipe = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0121       "beam_pipe", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0122       beamPipeBoundaries, innerBuilder);
0123   detector->add(std::move(beamPipe));
0124 
0125   // A pixel system
0126   std::vector<double> pixelBoundaries = {pixelIr, pixelOr, detectorHz};
0127   std::vector<Acts::AxisDirection> pixelBinning = {Acts::AxisDirection::AxisZ};
0128   auto pixel = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0129       "pixel", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0130       pixelBoundaries, pixelBinning);
0131 
0132   // Nec: Small differences to check if the adjustments are made
0133   std::vector<double> pixelEcBoundaries = {pixelIr, pixelOr - 5., pixelEcHz};
0134   std::vector<Acts::AxisDirection> pixelEcBinning = {
0135       Acts::AxisDirection::AxisZ};
0136 
0137   auto pixelNec = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0138       "pixelNec",
0139       Acts::Transform3::Identity() *
0140           Acts::Translation3(0., 0., -detectorHz + pixelEcHz),
0141       Acts::VolumeBounds::eCylinder, pixelEcBoundaries, pixelEcBinning);
0142 
0143   // Add a single encap layer
0144   std::vector<double> pixelNecBoundaries = {pixelIr + 2, pixelOr - 7., 10.};
0145   auto pixelNecLayer =
0146       std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0147           "pixelNecLayer",
0148           Acts::Transform3::Identity() *
0149               Acts::Translation3(0., 0., -detectorHz + pixelEcHz),
0150           Acts::VolumeBounds::eCylinder, pixelNecBoundaries, innerBuilder);
0151 
0152   pixelNec->add(std::move(pixelNecLayer));
0153 
0154   // Barrel
0155   std::vector<double> pixelBarrelBoundaries = {pixelIr + 1, pixelOr - 1.,
0156                                                detectorHz - 2 * pixelEcHz};
0157   std::vector<Acts::AxisDirection> pixelBarrelBinning = {
0158       Acts::AxisDirection::AxisR};
0159 
0160   auto pixelBarrel = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0161       "pixelBarrel", Acts::Transform3::Identity(),
0162       Acts::VolumeBounds::eCylinder, pixelBarrelBoundaries, pixelBarrelBinning);
0163 
0164   std::vector<double> pixelBarrelL0Boundaries = {60, 65.,
0165                                                  detectorHz - 2 * pixelEcHz};
0166   auto pixelBarrelL0 =
0167       std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0168           "pixelBarrelL0", Acts::Transform3::Identity(),
0169           Acts::VolumeBounds::eCylinder, pixelBarrelL0Boundaries, innerBuilder);
0170 
0171   std::vector<double> pixelBarrelL1Boundaries = {100, 105.,
0172                                                  detectorHz - 2 * pixelEcHz};
0173   auto pixelBarrelL1 =
0174       std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0175           "pixelBarrelL1", Acts::Transform3::Identity(),
0176           Acts::VolumeBounds::eCylinder, pixelBarrelL1Boundaries, innerBuilder);
0177   pixelBarrel->add(std::move(pixelBarrelL0));
0178   pixelBarrel->add(std::move(pixelBarrelL1));
0179 
0180   auto pixelPec = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0181       "pixelPec",
0182       Acts::Transform3::Identity() *
0183           Acts::Translation3(0., 0., +detectorHz - pixelEcHz),
0184       Acts::VolumeBounds::eCylinder, pixelEcBoundaries, pixelEcBinning);
0185 
0186   std::vector<double> pixelPecBoundaries = {pixelIr + 2, pixelOr - 7., 10.};
0187   auto pixelPecLayer =
0188       std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0189           "pixelPecLayer",
0190           Acts::Transform3::Identity() *
0191               Acts::Translation3(0., 0., detectorHz - pixelEcHz),
0192           Acts::VolumeBounds::eCylinder, pixelPecBoundaries, innerBuilder);
0193 
0194   pixelPec->add(std::move(pixelPecLayer));
0195 
0196   // Adding pixel
0197   pixel->add(std::move(pixelNec));
0198   pixel->add(std::move(pixelPec));
0199   pixel->add(std::move(pixelBarrel));
0200 
0201   detector->add(std::move(pixel));
0202 
0203   std::ofstream fs("detector_with_gaps.dot");
0204   Acts::Experimental::detail::BlueprintDrawer::dotStream(fs, *detector);
0205   fs.close();
0206 
0207   // Simple test
0208   BOOST_CHECK_EQUAL(detector->children.size(), 2u);
0209   BOOST_CHECK_EQUAL(detector->children[0u]->name, "beam_pipe");
0210   BOOST_CHECK_EQUAL(detector->children[1u]->name, "pixel");
0211 
0212   // Now fill the gaps
0213   Acts::Experimental::detail::BlueprintHelper::fillGaps(*detector);
0214 
0215   // Do the tests again
0216   BOOST_CHECK_EQUAL(detector->children.size(), 4u);
0217   BOOST_CHECK_EQUAL(detector->children[0u]->name, "beam_pipe");
0218   BOOST_CHECK_EQUAL(detector->children[1u]->name, "detector_gap_0");
0219   BOOST_CHECK_EQUAL(detector->children[2u]->name, "pixel");
0220   BOOST_CHECK_EQUAL(detector->children[3u]->name, "detector_gap_1");
0221 
0222   // Adjustment of gap parameters
0223   BOOST_CHECK_EQUAL(detector->children[1u]->boundaryValues[0], beamPipeOr);
0224   BOOST_CHECK_EQUAL(detector->children[1u]->boundaryValues[1], pixelIr);
0225   BOOST_CHECK_EQUAL(detector->children[1u]->boundaryValues[2], detectorHz);
0226 
0227   BOOST_CHECK_EQUAL(detector->children[3u]->boundaryValues[0], pixelOr);
0228   BOOST_CHECK_EQUAL(detector->children[3u]->boundaryValues[1], detectorOr);
0229   BOOST_CHECK_EQUAL(detector->children[3u]->boundaryValues[2], detectorHz);
0230 
0231   // Check the pixel system: Nec / Barrel / Pec
0232   BOOST_CHECK_EQUAL(detector->children[2u]->children.size(), 3u);
0233   BOOST_CHECK_EQUAL(detector->children[2u]->children[0u]->children.size(), 3u);
0234   BOOST_CHECK_EQUAL(detector->children[2u]->children[1u]->children.size(), 5u);
0235   BOOST_CHECK_EQUAL(detector->children[2u]->children[2u]->children.size(), 3u);
0236 
0237   // Nec test
0238   BOOST_CHECK_EQUAL(
0239       detector->children[2u]->children[0u]->children[0]->boundaryValues[0],
0240       pixelIr);
0241   BOOST_CHECK_EQUAL(
0242       detector->children[2u]->children[0u]->children[0]->boundaryValues[1],
0243       pixelOr);
0244 
0245   BOOST_CHECK_EQUAL(
0246       detector->children[2u]->children[0u]->children[1]->boundaryValues[0],
0247       pixelIr);
0248   BOOST_CHECK_EQUAL(
0249       detector->children[2u]->children[0u]->children[1]->boundaryValues[1],
0250       pixelOr);
0251 
0252   BOOST_CHECK_EQUAL(
0253       detector->children[2u]->children[0u]->children[2]->boundaryValues[0],
0254       pixelIr);
0255   BOOST_CHECK_EQUAL(
0256       detector->children[2u]->children[0u]->children[2]->boundaryValues[1],
0257       pixelOr);
0258 
0259   std::ofstream fs2("detector_without_gaps.dot");
0260   Acts::Experimental::detail::BlueprintDrawer::dotStream(fs2, *detector);
0261   fs2.close();
0262 }
0263 
0264 BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapException) {
0265   auto innerBuilder =
0266       std::make_shared<Acts::Experimental::IInternalStructureBuilder>();
0267 
0268   // The root node - detector
0269   std::vector<double> detectorBoundaries = {0., 50., 100.};
0270   std::vector<Acts::AxisDirection> detectorBinning = {
0271       Acts::AxisDirection::AxisX};
0272   auto detector = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0273       "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0274       detectorBoundaries, detectorBinning);
0275 
0276   // Add a volume
0277   std::vector<double> volTwoBoundaries = {0., 20., 100.};
0278   auto vol = std::make_unique<Acts::Experimental::Gen2Blueprint::Node>(
0279       "vol", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0280       volTwoBoundaries, innerBuilder);
0281   detector->add(std::move(vol));
0282 
0283   // Throw because cylinders can not be binned in x
0284   BOOST_CHECK_THROW(
0285       Acts::Experimental::detail::BlueprintHelper::fillGaps(*detector),
0286       std::runtime_error);
0287 }
0288 
0289 BOOST_AUTO_TEST_SUITE_END()