Back to home page

EIC code displayed by LXR

 
 

    


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

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/Units.hpp"
0012 #include "Acts/Geometry/ApproachDescriptor.hpp"
0013 #include "Acts/Geometry/BoundarySurfaceT.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/GeometryIdentifier.hpp"
0016 #include "Acts/Geometry/Layer.hpp"
0017 #include "Acts/Geometry/TrackingGeometry.hpp"
0018 #include "Acts/Geometry/TrackingVolume.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Surfaces/SurfaceArray.hpp"
0021 #include "Acts/Utilities/BinnedArray.hpp"
0022 
0023 #include <cstddef>
0024 #include <memory>
0025 #include <unordered_map>
0026 #include <vector>
0027 
0028 #include "TrackingVolumeCreation.hpp"
0029 
0030 using namespace Acts::UnitLiterals;
0031 
0032 namespace Acts::Test {
0033 
0034 // Create a test context
0035 GeometryContext tgContext = GeometryContext();
0036 
0037 TrackingGeometry makeTrackingGeometry(const GeometryIdentifierHook& hook) {
0038   /// we test a two-level hierarchy
0039   /// every deeper level hierarchy is a derivate of this
0040   ///
0041   /// WorldVolume   with volumeID       == 1
0042   /// - InnerVolume with volumeID       == 2
0043   /// -- InnerInnerVolume with volumeID == 3
0044   /// -- InnerOuterVolume with volumeID == 4
0045   /// - OuterVolume with volumeID       == 5
0046 
0047   // sensitive surface definitions
0048   double surfaceHalfLengthZ = 50_mm;
0049   double surfaceRstagger = 5_mm;
0050   double surfaceZoverlap = 10_mm;
0051   double layerEnvelope = 0.5_mm;
0052   double volumeEnvelope = 10_mm;
0053 
0054   // inner inner volume definitions
0055   double iiv_surfaceR = 25_mm;
0056   double iiv_volumeR =
0057       iiv_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
0058 
0059   ///  inner outer volume definitions
0060   double iov_surfaceR = 100_mm;
0061   double iov_volumeR =
0062       iov_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
0063 
0064   ///  inner inner volume
0065   auto iiVolume = constructCylinderVolume(
0066       tgContext, surfaceHalfLengthZ, iiv_surfaceR, surfaceRstagger,
0067       surfaceZoverlap, layerEnvelope, volumeEnvelope, 0., iiv_volumeR,
0068       "InnerInnerVolume");
0069   ///  inner outer volume
0070   auto ioVolume = constructCylinderVolume(
0071       tgContext, surfaceHalfLengthZ, iov_surfaceR, surfaceRstagger,
0072       surfaceZoverlap, layerEnvelope, volumeEnvelope, iiv_volumeR, iov_volumeR,
0073       "InnerOuterVolume");
0074 
0075   // now create the Inner Container volume
0076   double volumeHalfZ =
0077       (4 * surfaceHalfLengthZ - surfaceZoverlap) + volumeEnvelope;
0078   /// the inner volume
0079   auto iVolume = constructContainerVolume(
0080       tgContext, iiVolume, ioVolume, iov_volumeR, volumeHalfZ, "InnerVolume");
0081 
0082   // outer volume definitions
0083   double ov_surfaceR = 150_mm;
0084   double ov_volumeR =
0085       ov_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
0086 
0087   ///  inner outer volume
0088   auto oVolume = constructCylinderVolume(
0089       tgContext, surfaceHalfLengthZ, ov_surfaceR, surfaceRstagger,
0090       surfaceZoverlap, layerEnvelope, volumeEnvelope, iov_volumeR, ov_volumeR,
0091       "OuterVolume");
0092   /// the inner volume
0093   auto volume = constructContainerVolume(
0094       tgContext, iVolume, oVolume, ov_volumeR, volumeHalfZ, "WorldVolume");
0095 
0096   // creating a TrackingGeometry
0097   // -> close the geometry, this should set the GeometryIdentifier
0098   TrackingGeometry tGeometry(volume, nullptr, hook);
0099   return tGeometry;
0100 }
0101 
0102 BOOST_AUTO_TEST_CASE(GeometryIdentifier_closeGeometry_test) {
0103   GeometryIdentifierHook hook{};
0104   TrackingGeometry tGeometry = makeTrackingGeometry(hook);
0105   auto world = tGeometry.highestTrackingVolume();
0106 
0107   // the lambda for checking
0108   auto check_vol = [](const TrackingVolume& vol,
0109                       GeometryIdentifier::Value geoid) {
0110     // check the geometry id of the volume
0111     BOOST_CHECK_EQUAL(geoid, vol.geometryId().volume());
0112     // check the geometry id of all boundary surfaces of the volume
0113     // - this is strictly only possible when glueing is OFF
0114     GeometryIdentifier::Value bsurface_id = 0;
0115     for (const auto& bSf : vol.boundarySurfaces()) {
0116       // check the bsurface volume id
0117       auto bs_vol_id = bSf->surfaceRepresentation().geometryId().volume();
0118       BOOST_CHECK_EQUAL(geoid, bs_vol_id);
0119       // check the bsurface boundary id
0120       auto bs_bsf_id = bSf->surfaceRepresentation().geometryId().boundary();
0121       auto bs_ext_id = bSf->surfaceRepresentation().geometryId().extra();
0122       BOOST_CHECK_EQUAL(++bsurface_id, bs_bsf_id);
0123       BOOST_CHECK_EQUAL(bs_ext_id, 0);
0124     }
0125     // testing the layer and its approach surfaces
0126     if (vol.confinedLayers() != nullptr) {
0127       // layers start are counted from 1 - n
0128       GeometryIdentifier::Value layer_id = 0;
0129       for (const auto& lay : vol.confinedLayers()->arrayObjects()) {
0130         // check the layer volume id and layer id
0131         auto lay_vol_id = lay->geometryId().volume();
0132         auto lay_lay_id = lay->geometryId().layer();
0133         BOOST_CHECK_EQUAL(++layer_id, lay_lay_id);
0134         BOOST_CHECK_EQUAL(geoid, lay_vol_id);
0135         // test the layer approach surfaces
0136         if (lay->approachDescriptor() != nullptr) {
0137           // approach surfaces are counted from 1 - n
0138           GeometryIdentifier::Value asurface_id = 0;
0139           for (const auto& asf :
0140                lay->approachDescriptor()->containedSurfaces()) {
0141             // check the approach volume id, approach layer id
0142             auto asf_vol_id = asf->geometryId().volume();
0143             auto asf_lay_id = asf->geometryId().layer();
0144             auto asf_asf_id = asf->geometryId().approach();
0145             auto ssf_ext_id = asf->geometryId().extra();
0146             BOOST_CHECK_EQUAL(layer_id, asf_lay_id);
0147             BOOST_CHECK_EQUAL(geoid, asf_vol_id);
0148             BOOST_CHECK_EQUAL(++asurface_id, asf_asf_id);
0149             BOOST_CHECK_EQUAL(0, ssf_ext_id);
0150           }
0151         }
0152         // test the sensitive surfaces
0153         if (lay->surfaceArray() != nullptr) {
0154           // sensitive surfaces are counted from 1 - n
0155           GeometryIdentifier::Value ssurface_id = 0;
0156           for (const auto& ssf : lay->surfaceArray()->surfaces()) {
0157             // check the approach volume id, approach layer id
0158             auto ssf_vol_id = ssf->geometryId().volume();
0159             auto ssf_lay_id = ssf->geometryId().layer();
0160             auto ssf_ssf_id = ssf->geometryId().sensitive();
0161             auto ssf_ext_id = ssf->geometryId().extra();
0162             BOOST_CHECK_EQUAL(layer_id, ssf_lay_id);
0163             BOOST_CHECK_EQUAL(geoid, ssf_vol_id);
0164             BOOST_CHECK_EQUAL(++ssurface_id, ssf_ssf_id);
0165             BOOST_CHECK_EQUAL(0, ssf_ext_id);
0166           }
0167         }
0168       }
0169     }
0170   };
0171 
0172   // get the two volumes the world is built of
0173   auto ioVolumes = world->confinedVolumes()->arrayObjects();
0174   // check the size - has to be two volumes
0175   BOOST_CHECK_EQUAL(2ul, ioVolumes.size());
0176   // get the innermost volumes
0177   auto iioVolumes = ioVolumes[0]->confinedVolumes()->arrayObjects();
0178   // check the size - has to be two volumes
0179   BOOST_CHECK_EQUAL(2ul, iioVolumes.size());
0180 
0181   // check the world
0182   check_vol(*world, 1);
0183   // - check InnerVolume
0184   check_vol(*ioVolumes[0], 2);
0185   // -- check the InnerInnerVolume
0186   check_vol(*iioVolumes[0], 3);
0187   // -- check the InenerOuterVolume
0188   check_vol(*iioVolumes[1], 4);
0189   // - check the OuterVolume
0190   check_vol(*ioVolumes[1], 5);
0191 }
0192 
0193 template <typename Callable>
0194 struct CallableHook : public Acts::GeometryIdentifierHook {
0195   Callable callable;
0196 
0197   CallableHook(const Callable& c) : callable(c) {}
0198 
0199   Acts::GeometryIdentifier decorateIdentifier(
0200       Acts::GeometryIdentifier identifier,
0201       const Acts::Surface& surface) const override {
0202     return callable(identifier, surface);
0203   }
0204 };
0205 
0206 BOOST_AUTO_TEST_CASE(GeometryIdentifier_closeGeometry_test_extra) {
0207   std::size_t extra = 0;
0208   std::unordered_map<const Surface*, std::size_t> extraMap;
0209   auto hookImpl = [&](GeometryIdentifier orig, const Surface& srf) {
0210     ++extra;
0211     extraMap[&srf] = extra;
0212     orig.setExtra(extra);
0213     return orig;
0214   };
0215   CallableHook<decltype(hookImpl)> hook{hookImpl};
0216 
0217   TrackingGeometry tGeometry = makeTrackingGeometry(hook);
0218   auto world = tGeometry.highestTrackingVolume();
0219 
0220   // the lambda for checking
0221   auto check_vol = [&extraMap](const TrackingVolume& vol,
0222                                GeometryIdentifier::Value geoid) {
0223     // check the geometry id of the volume
0224     BOOST_CHECK_EQUAL(geoid, vol.geometryId().volume());
0225     // check the geometry id of all boundary surfaces of the volume
0226     // - this is strictly only possible when glueing is OFF
0227     GeometryIdentifier::Value bsurface_id = 0;
0228     for (const auto& bSf : vol.boundarySurfaces()) {
0229       // check the bsurface volume id
0230       auto bs_vol_id = bSf->surfaceRepresentation().geometryId().volume();
0231       BOOST_CHECK_EQUAL(geoid, bs_vol_id);
0232       // check the bsurface boundary id
0233       auto bs_bsf_id = bSf->surfaceRepresentation().geometryId().boundary();
0234       auto bs_ext_id = bSf->surfaceRepresentation().geometryId().extra();
0235       BOOST_CHECK_EQUAL(++bsurface_id, bs_bsf_id);
0236       BOOST_CHECK_EQUAL(bs_ext_id, 0);
0237     }
0238     // testing the layer and its approach surfaces
0239     if (vol.confinedLayers() != nullptr) {
0240       // layers start are counted from 1 - n
0241       GeometryIdentifier::Value layer_id = 0;
0242       for (const auto& lay : vol.confinedLayers()->arrayObjects()) {
0243         // check the layer volume id and layer id
0244         auto lay_vol_id = lay->geometryId().volume();
0245         auto lay_lay_id = lay->geometryId().layer();
0246         BOOST_CHECK_EQUAL(++layer_id, lay_lay_id);
0247         BOOST_CHECK_EQUAL(geoid, lay_vol_id);
0248         // test the layer approach surfaces
0249         if (lay->approachDescriptor() != nullptr) {
0250           // approach surfaces are counted from 1 - n
0251           GeometryIdentifier::Value asurface_id = 0;
0252           for (const auto& asf :
0253                lay->approachDescriptor()->containedSurfaces()) {
0254             // check the approach volume id, approach layer id
0255             auto asf_vol_id = asf->geometryId().volume();
0256             auto asf_lay_id = asf->geometryId().layer();
0257             auto asf_asf_id = asf->geometryId().approach();
0258             auto ssf_ext_id = asf->geometryId().extra();
0259             BOOST_CHECK_EQUAL(layer_id, asf_lay_id);
0260             BOOST_CHECK_EQUAL(geoid, asf_vol_id);
0261             BOOST_CHECK_EQUAL(++asurface_id, asf_asf_id);
0262             BOOST_CHECK_EQUAL(0, ssf_ext_id);
0263           }
0264         }
0265         // test the sensitive surfaces
0266         if (lay->surfaceArray() != nullptr) {
0267           // sensitive surfaces are counted from 1 - n
0268           GeometryIdentifier::Value ssurface_id = 0;
0269           for (const auto& ssf : lay->surfaceArray()->surfaces()) {
0270             // check the approach volume id, approach layer id
0271             auto ssf_vol_id = ssf->geometryId().volume();
0272             auto ssf_lay_id = ssf->geometryId().layer();
0273             auto ssf_ssf_id = ssf->geometryId().sensitive();
0274             auto ssf_ext_id = ssf->geometryId().extra();
0275             BOOST_CHECK_EQUAL(layer_id, ssf_lay_id);
0276             BOOST_CHECK_EQUAL(geoid, ssf_vol_id);
0277             BOOST_CHECK_EQUAL(++ssurface_id, ssf_ssf_id);
0278             BOOST_CHECK_EQUAL(extraMap[ssf], ssf_ext_id);
0279           }
0280         }
0281       }
0282     }
0283   };
0284 
0285   // get the two volumes the world is built of
0286   auto ioVolumes = world->confinedVolumes()->arrayObjects();
0287   // check the size - has to be two volumes
0288   BOOST_CHECK_EQUAL(2ul, ioVolumes.size());
0289   // get the innermost volumes
0290   auto iioVolumes = ioVolumes[0]->confinedVolumes()->arrayObjects();
0291   // check the size - has to be two volumes
0292   BOOST_CHECK_EQUAL(2ul, iioVolumes.size());
0293 
0294   // check the world
0295   check_vol(*world, 1);
0296   // - check InnerVolume
0297   check_vol(*ioVolumes[0], 2);
0298   // -- check the InnerInnerVolume
0299   check_vol(*iioVolumes[0], 3);
0300   // -- check the InenerOuterVolume
0301   check_vol(*iioVolumes[1], 4);
0302   // - check the OuterVolume
0303   check_vol(*ioVolumes[1], 5);
0304 }
0305 
0306 BOOST_AUTO_TEST_CASE(TrackingGeometry_testVisitSurfaces) {
0307   GeometryIdentifierHook hook{};
0308   TrackingGeometry tGeometry = makeTrackingGeometry(hook);
0309 
0310   // this will also cover TrackingVolume::visitSurfaces
0311   // it's a pretty bare-bones test, and only asserts that the
0312   // method is called on the expected number of surfaces
0313   std::size_t nSurfaces = 0;
0314   tGeometry.visitSurfaces([&nSurfaces](const auto*) { nSurfaces++; });
0315   BOOST_CHECK_EQUAL(nSurfaces, 9u);
0316 
0317   // this will also cover TrackingVolume::visitVolumes
0318   std::size_t nVolumes = 0;
0319   tGeometry.visitVolumes([&nVolumes](const auto*) { nVolumes++; });
0320   BOOST_CHECK_EQUAL(nVolumes, 5u);
0321 }
0322 
0323 }  // namespace Acts::Test