Back to home page

EIC code displayed by LXR

 
 

    


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

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/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/CylinderLayer.hpp"
0013 #include "Acts/Geometry/DiscLayer.hpp"
0014 #include "Acts/Geometry/Extent.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Geometry/LayerCreator.hpp"
0017 #include "Acts/Geometry/ProtoLayer.hpp"
0018 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0019 #include "Acts/Surfaces/CylinderBounds.hpp"
0020 #include "Acts/Surfaces/PlanarBounds.hpp"
0021 #include "Acts/Surfaces/PlaneSurface.hpp"
0022 #include "Acts/Surfaces/RadialBounds.hpp"
0023 #include "Acts/Surfaces/RectangleBounds.hpp"
0024 #include "Acts/Surfaces/Surface.hpp"
0025 #include "Acts/Surfaces/SurfaceArray.hpp"
0026 #include "Acts/Surfaces/SurfaceBounds.hpp"
0027 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0028 #include "Acts/Utilities/BinningType.hpp"
0029 #include "Acts/Utilities/IAxis.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031 
0032 #include <algorithm>
0033 #include <array>
0034 #include <cmath>
0035 #include <cstddef>
0036 #include <fstream>
0037 #include <iomanip>
0038 #include <iostream>
0039 #include <memory>
0040 #include <numbers>
0041 #include <set>
0042 #include <string>
0043 #include <utility>
0044 #include <vector>
0045 
0046 #include <boost/format.hpp>
0047 
0048 namespace Acts::Test {
0049 
0050 // Create a test context
0051 GeometryContext tgContext = GeometryContext();
0052 
0053 using SrfVec = std::vector<std::shared_ptr<const Surface>>;
0054 
0055 void draw_surfaces(const SrfVec& surfaces, const std::string& fname) {
0056   std::ofstream os;
0057   os.open(fname);
0058 
0059   os << std::fixed << std::setprecision(4);
0060 
0061   std::size_t nVtx = 0;
0062   for (const auto& srfx : surfaces) {
0063     std::shared_ptr<const PlaneSurface> srf =
0064         std::dynamic_pointer_cast<const PlaneSurface>(srfx);
0065     const PlanarBounds* bounds =
0066         dynamic_cast<const PlanarBounds*>(&srf->bounds());
0067 
0068     for (const auto& vtxloc : bounds->vertices()) {
0069       Vector3 vtx =
0070           srf->transform(tgContext) * Vector3(vtxloc.x(), vtxloc.y(), 0);
0071       os << "v " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
0072     }
0073 
0074     // connect them
0075     os << "f";
0076     for (std::size_t i = 1; i <= bounds->vertices().size(); ++i) {
0077       os << " " << nVtx + i;
0078     }
0079     os << "\n";
0080 
0081     nVtx += bounds->vertices().size();
0082   }
0083 
0084   os.close();
0085 }
0086 
0087 struct LayerCreatorFixture {
0088   std::shared_ptr<const SurfaceArrayCreator> p_SAC;
0089   std::shared_ptr<LayerCreator> p_LC;
0090 
0091   std::vector<std::shared_ptr<const Surface>> m_surfaces;
0092 
0093   LayerCreatorFixture() {
0094     p_SAC = std::make_shared<const SurfaceArrayCreator>(
0095         SurfaceArrayCreator::Config(),
0096         Acts::getDefaultLogger("SurfaceArrayCreator", Acts::Logging::VERBOSE));
0097     LayerCreator::Config cfg;
0098     cfg.surfaceArrayCreator = p_SAC;
0099     p_LC = std::make_shared<LayerCreator>(
0100         cfg, Acts::getDefaultLogger("LayerCreator", Acts::Logging::VERBOSE));
0101   }
0102 
0103   template <typename... Args>
0104   bool checkBinning(Args&&... args) {
0105     return p_LC->checkBinning(std::forward<Args>(args)...);
0106   }
0107 
0108   bool checkBinContentSize(const SurfaceArray* sArray, std::size_t n) {
0109     std::size_t nBins = sArray->size();
0110     bool result = true;
0111     for (std::size_t i = 0; i < nBins; ++i) {
0112       if (!sArray->isValidBin(i)) {
0113         continue;
0114       }
0115       std::vector<const Surface*> binContent = sArray->at(i);
0116       BOOST_TEST_INFO("Bin: " << i);
0117       BOOST_CHECK_EQUAL(binContent.size(), n);
0118       result = result && binContent.size() == n;
0119     }
0120 
0121     return result;
0122   }
0123 
0124   SrfVec fullPhiTestSurfacesEC(std::size_t n = 10, double shift = 0,
0125                                double zbase = 0, double r = 10) {
0126     SrfVec res;
0127 
0128     double phiStep = 2 * std::numbers::pi / n;
0129     for (std::size_t i = 0; i < n; ++i) {
0130       double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2;
0131 
0132       Transform3 trans;
0133       trans.setIdentity();
0134       trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1)));
0135       trans.translate(Vector3(r, 0, z));
0136 
0137       auto bounds = std::make_shared<const RectangleBounds>(2, 1);
0138       std::shared_ptr<PlaneSurface> srf =
0139           Surface::makeShared<PlaneSurface>(trans, bounds);
0140 
0141       res.push_back(srf);
0142       m_surfaces.push_back(
0143           std::move(srf));  // keep shared, will get destroyed at the end
0144     }
0145 
0146     return res;
0147   }
0148 
0149   SrfVec fullPhiTestSurfacesBRL(int n = 10, double shift = 0, double zbase = 0,
0150                                 double incl = std::numbers::pi / 9.,
0151                                 double w = 2, double h = 1.5) {
0152     SrfVec res;
0153 
0154     double phiStep = 2 * std::numbers::pi / n;
0155     for (int i = 0; i < n; ++i) {
0156       double z = zbase;
0157 
0158       Transform3 trans;
0159       trans.setIdentity();
0160       trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1)));
0161       trans.translate(Vector3(10, 0, z));
0162       trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1)));
0163       trans.rotate(Eigen::AngleAxisd(std::numbers::pi / 2., Vector3(0, 1, 0)));
0164 
0165       auto bounds = std::make_shared<const RectangleBounds>(w, h);
0166       std::shared_ptr<PlaneSurface> srf =
0167           Surface::makeShared<PlaneSurface>(trans, bounds);
0168 
0169       res.push_back(srf);
0170       m_surfaces.push_back(
0171           std::move(srf));  // keep shared, will get destroyed at the end
0172     }
0173 
0174     return res;
0175   }
0176 
0177   SrfVec makeBarrel(int nPhi, int nZ, double w, double h) {
0178     double z0 = -(nZ - 1) * w;
0179     SrfVec res;
0180 
0181     for (int i = 0; i < nZ; i++) {
0182       double z = i * w * 2 + z0;
0183       std::cout << "z=" << z << std::endl;
0184       SrfVec ring =
0185           fullPhiTestSurfacesBRL(nPhi, 0, z, std::numbers::pi / 9., w, h);
0186       res.insert(res.end(), ring.begin(), ring.end());
0187     }
0188 
0189     return res;
0190   }
0191 
0192   std::pair<SrfVec, std::vector<std::pair<const Surface*, const Surface*>>>
0193   makeBarrelStagger(int nPhi, int nZ, double shift = 0,
0194                     double incl = std::numbers::pi / 9., double w = 2,
0195                     double h = 1.5) {
0196     double z0 = -(nZ - 1) * w;
0197     SrfVec res;
0198 
0199     std::vector<std::pair<const Surface*, const Surface*>> pairs;
0200 
0201     for (int i = 0; i < nZ; i++) {
0202       double z = i * w * 2 + z0;
0203 
0204       double phiStep = 2 * std::numbers::pi / nPhi;
0205       for (int j = 0; j < nPhi; ++j) {
0206         Transform3 trans;
0207         trans.setIdentity();
0208         trans.rotate(Eigen::AngleAxisd(j * phiStep + shift, Vector3(0, 0, 1)));
0209         trans.translate(Vector3(10, 0, z));
0210         trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1)));
0211         trans.rotate(
0212             Eigen::AngleAxisd(std::numbers::pi / 2., Vector3(0, 1, 0)));
0213 
0214         auto bounds = std::make_shared<const RectangleBounds>(w, h);
0215         std::shared_ptr<PlaneSurface> srfA =
0216             Surface::makeShared<PlaneSurface>(trans, bounds);
0217 
0218         Vector3 nrm = srfA->normal(tgContext);
0219         Transform3 transB = trans;
0220         transB.pretranslate(nrm * 0.1);
0221         std::shared_ptr<PlaneSurface> srfB =
0222             Surface::makeShared<PlaneSurface>(transB, bounds);
0223 
0224         pairs.push_back(std::make_pair(srfA.get(), srfB.get()));
0225 
0226         res.push_back(srfA);
0227         res.push_back(srfB);
0228         m_surfaces.push_back(std::move(srfA));
0229         m_surfaces.push_back(std::move(srfB));
0230       }
0231     }
0232 
0233     return {res, pairs};
0234   }
0235 };
0236 
0237 BOOST_AUTO_TEST_SUITE(Tools)
0238 
0239 BOOST_FIXTURE_TEST_CASE(LayerCreator_createCylinderLayer, LayerCreatorFixture) {
0240   std::vector<std::shared_ptr<const Surface>> srf;
0241 
0242   srf = makeBarrel(30, 7, 2, 1.5);
0243   draw_surfaces(srf, "LayerCreator_createCylinderLayer_BRL_1.obj");
0244 
0245   // CASE I
0246   double envR = 0.1, envZ = 0.5;
0247   ProtoLayer pl(tgContext, srf);
0248   pl.envelope[Acts::AxisDirection::AxisR] = {envR, envR};
0249   pl.envelope[Acts::AxisDirection::AxisZ] = {envZ, envZ};
0250   std::shared_ptr<CylinderLayer> layer =
0251       std::dynamic_pointer_cast<CylinderLayer>(
0252           p_LC->cylinderLayer(tgContext, srf, equidistant, equidistant, pl));
0253 
0254   //
0255   double rMax = 10.6071, rMin = 9.59111;  // empirical - w/o envelopes
0256   CHECK_CLOSE_REL(layer->thickness(), (rMax - rMin) + 2. * envR, 1e-3);
0257 
0258   const CylinderBounds* bounds = &layer->bounds();
0259   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eR), (rMax + rMin) / 2., 1e-3);
0260   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eHalfLengthZ), 14 + envZ, 1e-3);
0261   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0262   auto axes = layer->surfaceArray()->getAxes();
0263   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30u);
0264   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7u);
0265   CHECK_CLOSE_REL(axes.at(0)->getMin(), -std::numbers::pi, 1e-3);
0266   CHECK_CLOSE_REL(axes.at(0)->getMax(), std::numbers::pi, 1e-3);
0267   CHECK_CLOSE_REL(axes.at(1)->getMin(), -14, 1e-3);
0268   CHECK_CLOSE_REL(axes.at(1)->getMax(), 14, 1e-3);
0269 
0270   // CASE II
0271 
0272   ProtoLayer pl2(tgContext, srf);
0273   pl2.envelope[Acts::AxisDirection::AxisR] = {envR, envR};
0274   pl2.envelope[Acts::AxisDirection::AxisZ] = {envZ, envZ};
0275   layer = std::dynamic_pointer_cast<CylinderLayer>(
0276       p_LC->cylinderLayer(tgContext, srf, 30, 7, pl2));
0277   CHECK_CLOSE_REL(layer->thickness(), (rMax - rMin) + 2 * envR, 1e-3);
0278   bounds = &layer->bounds();
0279   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eR), (rMax + rMin) / 2., 1e-3);
0280   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eHalfLengthZ), 14 + envZ, 1e-3);
0281   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0282   axes = layer->surfaceArray()->getAxes();
0283   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30u);
0284   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7u);
0285   CHECK_CLOSE_REL(axes.at(0)->getMin(), -std::numbers::pi, 1e-3);
0286   CHECK_CLOSE_REL(axes.at(0)->getMax(), std::numbers::pi, 1e-3);
0287   CHECK_CLOSE_REL(axes.at(1)->getMin(), -14, 1e-3);
0288   CHECK_CLOSE_REL(axes.at(1)->getMax(), 14, 1e-3);
0289 
0290   layer = std::dynamic_pointer_cast<CylinderLayer>(
0291       p_LC->cylinderLayer(tgContext, srf, 13, 3, pl2));
0292   CHECK_CLOSE_REL(layer->thickness(), (rMax - rMin) + 2 * envR, 1e-3);
0293   bounds = &layer->bounds();
0294   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eR), (rMax + rMin) / 2., 1e-3);
0295   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eHalfLengthZ), 14 + envZ, 1e-3);
0296   // this succeeds despite sub-optimal binning
0297   // since we now have multientry bins
0298   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0299   axes = layer->surfaceArray()->getAxes();
0300   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 13u);
0301   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 3u);
0302   CHECK_CLOSE_REL(axes.at(0)->getMin(), -std::numbers::pi, 1e-3);
0303   CHECK_CLOSE_REL(axes.at(0)->getMax(), std::numbers::pi, 1e-3);
0304   CHECK_CLOSE_REL(axes.at(1)->getMin(), -14, 1e-3);
0305   CHECK_CLOSE_REL(axes.at(1)->getMax(), 14, 1e-3);
0306 
0307   // CASE III
0308   ProtoLayer pl3;
0309   pl3.extent.range(Acts::AxisDirection::AxisR).set(1, 20);
0310   pl3.extent.range(Acts::AxisDirection::AxisZ).set(-25, 25);
0311   layer = std::dynamic_pointer_cast<CylinderLayer>(
0312       p_LC->cylinderLayer(tgContext, srf, equidistant, equidistant, pl3));
0313   CHECK_CLOSE_REL(layer->thickness(), 19, 1e-3);
0314   bounds = &layer->bounds();
0315   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eR), 10.5, 1e-3);
0316   CHECK_CLOSE_REL(bounds->get(CylinderBounds::eHalfLengthZ), 25, 1e-3);
0317 
0318   // this should fail, b/c it's a completely inconvenient binning
0319   // but it succeeds despite sub-optimal binning
0320   // since we now have multientry bins
0321   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0322 
0323   axes = layer->surfaceArray()->getAxes();
0324   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30u);
0325   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7u);
0326   CHECK_CLOSE_REL(axes.at(0)->getMin(), -std::numbers::pi, 1e-3);
0327   CHECK_CLOSE_REL(axes.at(0)->getMax(), std::numbers::pi, 1e-3);
0328   CHECK_CLOSE_REL(axes.at(1)->getMin(), -25, 1e-3);
0329   CHECK_CLOSE_REL(axes.at(1)->getMax(), 25, 1e-3);
0330 }
0331 
0332 BOOST_FIXTURE_TEST_CASE(LayerCreator_createDiscLayer, LayerCreatorFixture) {
0333   std::vector<std::shared_ptr<const Surface>> surfaces;
0334   auto ringa = fullPhiTestSurfacesEC(30, 0, 0, 10);
0335   surfaces.insert(surfaces.end(), ringa.begin(), ringa.end());
0336   auto ringb = fullPhiTestSurfacesEC(30, 0, 0, 15);
0337   surfaces.insert(surfaces.end(), ringb.begin(), ringb.end());
0338   auto ringc = fullPhiTestSurfacesEC(30, 0, 0, 20);
0339   surfaces.insert(surfaces.end(), ringc.begin(), ringc.end());
0340   draw_surfaces(surfaces, "LayerCreator_createDiscLayer_EC_1.obj");
0341 
0342   ProtoLayer pl(tgContext, surfaces);
0343   pl.extent.range(AxisDirection::AxisZ).set(-10, 10);
0344   pl.extent.range(AxisDirection::AxisR).set(5., 25.);
0345   std::shared_ptr<DiscLayer> layer = std::dynamic_pointer_cast<DiscLayer>(
0346       p_LC->discLayer(tgContext, surfaces, equidistant, equidistant, pl));
0347   CHECK_CLOSE_REL(layer->thickness(), 20, 1e-3);
0348   const RadialBounds* bounds =
0349       dynamic_cast<const RadialBounds*>(&layer->bounds());
0350   CHECK_CLOSE_REL(bounds->rMin(), 5, 1e-3);
0351   CHECK_CLOSE_REL(bounds->rMax(), 25, 1e-3);
0352   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0353   auto axes = layer->surfaceArray()->getAxes();
0354   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 3u);
0355   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 30u);
0356   CHECK_CLOSE_REL(axes.at(0)->getMin(), 5, 1e-3);
0357   CHECK_CLOSE_REL(axes.at(0)->getMax(), 25, 1e-3);
0358   CHECK_CLOSE_REL(axes.at(1)->getMin(), -std::numbers::pi, 1e-3);
0359   CHECK_CLOSE_REL(axes.at(1)->getMax(), std::numbers::pi, 1e-3);
0360   checkBinContentSize(layer->surfaceArray(), 1);
0361 
0362   // check that it's applying a rotation transform to improve phi binning
0363   // BOOST_CHECK_NE(bu->transform(), nullptr);
0364   // double actAngle = ((*bu->transform()) * Vector3(1, 0, 0)).phi();
0365   // double expAngle = -2 * std::numbers::pi / 30 / 2.;
0366   // CHECK_CLOSE_REL(actAngle, expAngle, 1e-3);
0367 
0368   double envMinR = 1, envMaxR = 1, envZ = 5;
0369   std::size_t nBinsR = 3, nBinsPhi = 30;
0370   ProtoLayer pl2(tgContext, surfaces);
0371   pl2.envelope[AxisDirection::AxisR] = {envMinR, envMaxR};
0372   pl2.envelope[AxisDirection::AxisZ] = {envZ, envZ};
0373   layer = std::dynamic_pointer_cast<DiscLayer>(
0374       p_LC->discLayer(tgContext, surfaces, nBinsR, nBinsPhi, pl2));
0375 
0376   double rMin = 8, rMax = 22.0227;
0377   CHECK_CLOSE_REL(layer->thickness(), 0.4 + 2 * envZ, 1e-3);
0378   bounds = dynamic_cast<const RadialBounds*>(&layer->bounds());
0379   CHECK_CLOSE_REL(bounds->rMin(), rMin - envMinR, 1e-3);
0380   CHECK_CLOSE_REL(bounds->rMax(), rMax + envMaxR, 1e-3);
0381   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0382   axes = layer->surfaceArray()->getAxes();
0383   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), nBinsR);
0384   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), nBinsPhi);
0385   CHECK_CLOSE_REL(axes.at(0)->getMin(), rMin, 1e-3);
0386   CHECK_CLOSE_REL(axes.at(0)->getMax(), rMax, 1e-3);
0387   CHECK_CLOSE_REL(axes.at(1)->getMin(), -std::numbers::pi, 1e-3);
0388   CHECK_CLOSE_REL(axes.at(1)->getMax(), std::numbers::pi, 1e-3);
0389   checkBinContentSize(layer->surfaceArray(), 1);
0390 
0391   // check that it's applying a rotation transform to improve phi binning
0392   // BOOST_CHECK_NE(bu->transform(), nullptr);
0393   // actAngle = ((*bu->transform()) * Vector3(1, 0, 0)).phi();
0394   // expAngle = -2 * std::numbers::pi / 30 / 2.;
0395   // CHECK_CLOSE_REL(actAngle, expAngle, 1e-3);
0396 
0397   layer = std::dynamic_pointer_cast<DiscLayer>(
0398       p_LC->discLayer(tgContext, surfaces, equidistant, equidistant, pl2));
0399   CHECK_CLOSE_REL(layer->thickness(), 0.4 + 2 * envZ, 1e-3);
0400   bounds = dynamic_cast<const RadialBounds*>(&layer->bounds());
0401   CHECK_CLOSE_REL(bounds->rMin(), rMin - envMinR, 1e-3);
0402   CHECK_CLOSE_REL(bounds->rMax(), rMax + envMaxR, 1e-3);
0403   BOOST_CHECK(checkBinning(tgContext, *layer->surfaceArray()));
0404   axes = layer->surfaceArray()->getAxes();
0405   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), nBinsR);
0406   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), nBinsPhi);
0407   CHECK_CLOSE_REL(axes.at(0)->getMin(), rMin, 1e-3);
0408   CHECK_CLOSE_REL(axes.at(0)->getMax(), rMax, 1e-3);
0409   CHECK_CLOSE_REL(axes.at(1)->getMin(), -std::numbers::pi, 1e-3);
0410   CHECK_CLOSE_REL(axes.at(1)->getMax(), std::numbers::pi, 1e-3);
0411   checkBinContentSize(layer->surfaceArray(), 1);
0412 
0413   // check that it's applying a rotation transform to improve phi binning
0414   // BOOST_CHECK_NE(bu->transform(), nullptr);
0415   // actAngle = ((*bu->transform()) * Vector3(1, 0, 0)).phi();
0416   // expAngle = -2 * std::numbers::pi / 30 / 2.;
0417   // CHECK_CLOSE_REL(actAngle, expAngle, 1e-3);
0418 }
0419 
0420 BOOST_FIXTURE_TEST_CASE(LayerCreator_barrelStagger, LayerCreatorFixture) {
0421   auto barrel = makeBarrelStagger(30, 7, 0, std::numbers::pi / 9.);
0422   auto brl = barrel.first;
0423   draw_surfaces(brl, "LayerCreator_barrelStagger.obj");
0424 
0425   double envR = 0, envZ = 0;
0426   ProtoLayer pl(tgContext, brl);
0427   pl.envelope[AxisDirection::AxisR] = {envR, envR};
0428   pl.envelope[AxisDirection::AxisZ] = {envZ, envZ};
0429   std::shared_ptr<CylinderLayer> layer =
0430       std::dynamic_pointer_cast<CylinderLayer>(
0431           p_LC->cylinderLayer(tgContext, brl, equidistant, equidistant, pl));
0432 
0433   auto axes = layer->surfaceArray()->getAxes();
0434   BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30u);
0435   BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7u);
0436 
0437   // check if binning is good!
0438   for (const auto& pr : barrel.second) {
0439     auto A = pr.first;
0440     auto B = pr.second;
0441 
0442     // std::cout << A->center().phi() << " ";
0443     // std::cout << B->center().phi() << std::endl;
0444     // std::cout << "dPHi = " << A->center().phi() - B->center().phi() <<
0445     // std::endl;
0446 
0447     Vector3 ctr = A->referencePosition(tgContext, AxisDirection::AxisR);
0448     auto binContent = layer->surfaceArray()->at(ctr);
0449     BOOST_CHECK_EQUAL(binContent.size(), 2u);
0450     std::set<const Surface*> act;
0451     act.insert(binContent[0]);
0452     act.insert(binContent[1]);
0453 
0454     std::set<const Surface*> exp;
0455     exp.insert(A);
0456     exp.insert(B);
0457     BOOST_CHECK(exp == act);
0458   }
0459 
0460   // checkBinning should also report everything is fine
0461   checkBinning(tgContext, *layer->surfaceArray());
0462 }
0463 
0464 BOOST_AUTO_TEST_SUITE_END()
0465 }  // namespace Acts::Test