Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:43

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Plugins/Geant4/Geant4DetectorSurfaceFactory.hpp"
0012 #include "Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp"
0013 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0014 #include "Acts/Visualization/GeometryView3D.hpp"
0015 #include "Acts/Visualization/ObjVisualization3D.hpp"
0016 
0017 #include <memory>
0018 #include <string>
0019 
0020 #include "G4Box.hh"
0021 #include "G4LogicalVolume.hh"
0022 #include "G4PVPlacement.hh"
0023 #include "G4RotationMatrix.hh"
0024 #include "G4SystemOfUnits.hh"
0025 #include "G4ThreeVector.hh"
0026 #include "G4Transform3D.hh"
0027 #include "G4Tubs.hh"
0028 
0029 class G4VPhysicalVolume;
0030 
0031 BOOST_AUTO_TEST_SUITE(Geant4Plugin)
0032 
0033 BOOST_AUTO_TEST_CASE(Geant4DetecturSurfaceFactory_box) {
0034   G4Box* worldS = new G4Box("world", 100, 100, 100);
0035 
0036   G4LogicalVolume* worldLV = new G4LogicalVolume(worldS, nullptr, "World");
0037 
0038   G4Box* boxS = new G4Box("box", 10, 20, 20);
0039   G4LogicalVolume* boxLV = new G4LogicalVolume(boxS, nullptr, "World");
0040   G4VPhysicalVolume* boxPV = new G4PVPlacement(nullptr, G4ThreeVector(), boxLV,
0041                                                "Box", worldLV, false, 0, true);
0042 
0043   G4Transform3D nominal;
0044 
0045   // Get the box
0046   auto nameSelector =
0047       std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
0048           std::vector<std::string>{"ox"}, false);
0049 
0050   Acts::Geant4DetectorSurfaceFactory::Cache cache;
0051   Acts::Geant4DetectorSurfaceFactory::Options options;
0052   options.sensitiveSurfaceSelector = nameSelector;
0053 
0054   Acts::Geant4DetectorSurfaceFactory factory;
0055   factory.construct(cache, nominal, *boxPV, options);
0056 
0057   BOOST_CHECK_EQUAL(cache.sensitiveSurfaces.size(), 1u);
0058   BOOST_CHECK_EQUAL(cache.passiveSurfaces.size(), 0u);
0059 
0060   auto [element, surface] = cache.sensitiveSurfaces.front();
0061   BOOST_CHECK_EQUAL(surface->type(), Acts::Surface::SurfaceType::Plane);
0062 }
0063 
0064 BOOST_AUTO_TEST_CASE(Geant4DetecturSurfaceFactory_Cylinder) {
0065   G4Box* worldS = new G4Box("world", 1000, 1000, 1000);
0066 
0067   G4LogicalVolume* worldLV = new G4LogicalVolume(worldS, nullptr, "World");
0068 
0069   G4Tubs* cylinderS =
0070       new G4Tubs("cylinder", 99, 100, 100, -M_PI * CLHEP::radian,
0071                  2 * M_PI * CLHEP::radian);
0072 
0073   G4LogicalVolume* cylinderLV =
0074       new G4LogicalVolume(cylinderS, nullptr, "World");
0075   G4VPhysicalVolume* cylinderPV =
0076       new G4PVPlacement(nullptr, G4ThreeVector(), cylinderLV, "Cylinder",
0077                         worldLV, false, 0, true);
0078 
0079   G4Transform3D nominal;
0080 
0081   // Get the box
0082   auto nameSelector =
0083       std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
0084           std::vector<std::string>{"yl"}, false);
0085 
0086   Acts::Geant4DetectorSurfaceFactory::Cache cache;
0087   Acts::Geant4DetectorSurfaceFactory::Options options;
0088   options.sensitiveSurfaceSelector = nameSelector;
0089 
0090   Acts::Geant4DetectorSurfaceFactory factory;
0091   factory.construct(cache, nominal, *cylinderPV, options);
0092 
0093   BOOST_CHECK_EQUAL(cache.sensitiveSurfaces.size(), 1u);
0094   BOOST_CHECK_EQUAL(cache.passiveSurfaces.size(), 0u);
0095 
0096   auto [element, surface] = cache.sensitiveSurfaces.front();
0097   BOOST_CHECK_EQUAL(surface->type(), Acts::Surface::SurfaceType::Cylinder);
0098 }
0099 
0100 BOOST_AUTO_TEST_CASE(Geant4DetecturSurfaceFactory_Transforms) {
0101   Acts::GeometryContext gctx;
0102 
0103   G4Box* worldS = new G4Box("world", 1000, 1000, 1000);
0104   G4LogicalVolume* worldLV = new G4LogicalVolume(worldS, nullptr, "World");
0105   G4VPhysicalVolume* worldPV = new G4PVPlacement(
0106       nullptr, G4ThreeVector(), worldLV, "World", nullptr, false, 0, false);
0107 
0108   auto vol1S = new G4Box("volume1", 25, 10, 50);
0109   auto vol1L = new G4LogicalVolume(vol1S, nullptr, "Volume1");
0110 
0111   G4Transform3D transformVol1(CLHEP::HepRotationX(M_PI / 4),
0112                               G4ThreeVector(20, 0, 0));
0113 
0114   [[maybe_unused]] auto vol1PV = new G4PVPlacement(
0115       transformVol1, vol1L, "Volume1", worldLV, false, 0, false);
0116 
0117   auto vol2S = new G4Box("volume2", 25, 10, 50);
0118   auto vol2L = new G4LogicalVolume(vol2S, nullptr, "Volume2");
0119 
0120   G4Transform3D transformVol2(CLHEP::HepRotationY(M_PI / 6),
0121                               G4ThreeVector(0, 100, 20));
0122 
0123   [[maybe_unused]] auto vol2PV = new G4PVPlacement(
0124       transformVol2, vol2L, "Volume2", vol1L, false, 0, false);
0125 
0126   auto vol3S = new G4Box("volume3", 25, 10, 50);
0127   auto vol3L = new G4LogicalVolume(vol3S, nullptr, "Volume3");
0128 
0129   G4Transform3D transformVol3(CLHEP::HepRotationZ(M_PI / 12),
0130                               G4ThreeVector(30, 100, 0));
0131 
0132   [[maybe_unused]] auto vol3PV = new G4PVPlacement(
0133       transformVol3, vol3L, "Volume3", vol2L, false, 0, false);
0134 
0135   // Get the lowest volume
0136   auto nameSelector =
0137       std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
0138           std::vector<std::string>{"olume"}, false);
0139 
0140   Acts::Geant4DetectorSurfaceFactory::Cache cache;
0141   Acts::Geant4DetectorSurfaceFactory::Options options;
0142   options.sensitiveSurfaceSelector = nameSelector;
0143 
0144   G4Transform3D nominal;
0145 
0146   Acts::Geant4DetectorSurfaceFactory factory;
0147   factory.construct(cache, nominal, *worldPV, options);
0148 
0149   auto [element, surface] = cache.sensitiveSurfaces.front();
0150   BOOST_CHECK_EQUAL(surface->type(), Acts::Surface::SurfaceType::Plane);
0151 
0152   auto center = surface->center(gctx);
0153   auto normal = surface->normal(gctx, center, Acts::Vector3(1, 0, 0));
0154   CHECK_CLOSE_ABS(center.x(), 45.981, 1e-3);
0155   CHECK_CLOSE_ABS(center.y(), 137.886, 1e-3);
0156   CHECK_CLOSE_ABS(center.z(), 144.957, 1e-3);
0157   CHECK_CLOSE_ABS(normal.x(), -0.224, 1e-3);
0158   CHECK_CLOSE_ABS(normal.y(), 0.592, 1e-3);
0159   CHECK_CLOSE_ABS(normal.z(), 0.775, 1e-3);
0160 
0161   Acts::ObjVisualization3D obj;
0162   Acts::Vector3 origin(0, 0, 0);
0163   Acts::GeometryView3D::drawArrowForward(obj, origin, Acts::Vector3(100, 0, 0),
0164                                          1000, 10,
0165                                          Acts::ViewConfig({255, 0, 0}));
0166   Acts::GeometryView3D::drawArrowForward(obj, origin, Acts::Vector3(0, 100, 0),
0167                                          1000, 10,
0168                                          Acts::ViewConfig({0, 255, 0}));
0169   Acts::GeometryView3D::drawArrowForward(obj, origin, Acts::Vector3(0, 0, 100),
0170                                          1000, 10,
0171                                          Acts::ViewConfig({0, 0, 255}));
0172   Acts::GeometryView3D::drawArrowForward(
0173       obj, surface->center(gctx), surface->center(gctx) + 100 * normal, 1000,
0174       10, Acts::ViewConfig({0, 255, 0}));
0175   auto surfaces = cache.sensitiveSurfaces;
0176   for (const auto& [k, val] : Acts::enumerate(cache.sensitiveSurfaces)) {
0177     const auto& [el, surf] = val;
0178     Acts::ViewConfig vCfg;
0179     if (k == 0) {
0180       vCfg.color = Acts::ColorRGB({0, 255, 0});
0181     } else if (k == 1) {
0182       vCfg.color = Acts::ColorRGB({255, 0, 0});
0183     } else if (k == 2) {
0184       vCfg.color = Acts::ColorRGB({0, 255, 255});
0185     }
0186     Acts::GeometryView3D::drawSurface(obj, *surf, gctx,
0187                                       Acts::Transform3::Identity(), vCfg);
0188   }
0189 
0190   obj.write("RotatedSurface.obj");
0191 }
0192 
0193 BOOST_AUTO_TEST_SUITE_END()