Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Geant4SurfaceProvider optimization #3025

Merged
merged 8 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {
public:
/// Nested configuration struct
struct Config {
/// The path of the gdml file
std::string gdmlPath = "";
/// Pointer to the g4World volume
const G4VPhysicalVolume* g4World = nullptr;

/// Convert the length scale
ActsScalar scaleConversion = 1.;
Expand All @@ -55,6 +55,10 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {
/// Converted material thickness (< 0 indicates keeping original thickness)
ActsScalar convertedMaterialThickness = -1;

/// Transformation to apply to the
/// G4World volume
G4Transform3D worldTransform = G4Transform3D();

/// A selector for passive surfaces
std::shared_ptr<IGeant4PhysicalVolumeSelector> surfacePreselector =
std::make_shared<Acts::Geant4PhysicalVolumeSelectors::AllSelector>();
Expand Down Expand Up @@ -85,13 +89,11 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {
/// Constructor
/// @param config The configuration struct
/// @param options The optional configuration for KDTree
/// @param validateGDMLschema Whether to validate the gdml schema
Geant4SurfaceProvider(const Config& config,
const kdtOptions& options = kdtOptions(),
bool validateGDMLschema = true) {
if (config.gdmlPath.empty()) {
const kdtOptions& options = kdtOptions()) {
if (config.g4World == nullptr) {
throw std::invalid_argument(
"Geant4SurfaceProvider: no gdml file provided");
"Geant4SurfaceProvider: No World volume provided");
}
if (config.surfacePreselector == nullptr) {
throw std::invalid_argument(
Expand All @@ -100,16 +102,8 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {

m_cfg = config;
m_kdtOptions = options;

/// Read the gdml file and get the world volume
G4GDMLParser parser;
parser.Read(m_cfg.gdmlPath, validateGDMLschema);
m_g4World = parser.GetWorldVolume();

if (m_g4World == nullptr) {
throw std::invalid_argument(
"Geant4SurfaceProvider: No g4World initialized");
}
m_g4World = m_cfg.g4World;
m_g4ToWorld = m_cfg.worldTransform;
};

/// Destructor
Expand All @@ -131,11 +125,10 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {

/// Generate the surface cache
Acts::Geant4DetectorSurfaceFactory::Cache g4SurfaceCache;
G4Transform3D g4ToWorld;

/// Find and store surfaces in the cache object
Acts::Geant4DetectorSurfaceFactory{}.construct(
g4SurfaceCache, g4ToWorld, *m_g4World, g4SurfaceOptions);
g4SurfaceCache, m_g4ToWorld, *m_g4World, g4SurfaceOptions);

auto surfaces = g4SurfaceCache.passiveSurfaces;

Expand All @@ -157,7 +150,9 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {

kdtOptions m_kdtOptions;

G4VPhysicalVolume* m_g4World = nullptr;
const G4VPhysicalVolume* m_g4World;

G4Transform3D m_g4ToWorld;
};

} // namespace Experimental
Expand Down
40 changes: 27 additions & 13 deletions Tests/UnitTests/Plugins/Geant4/Geant4SurfaceProviderTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,21 @@ auto gctx = Acts::GeometryContext();
auto [physWorld, names] = ConstructGeant4World();

BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderNames) {
/// Read the gdml file and get the world volume
G4GDMLParser parser;
parser.Read(gdmlPath.string(), false);
auto world = parser.GetWorldVolume();

// Default template parameters are fine
// when using names as identifiers
auto spFullCfg = Acts::Experimental::Geant4SurfaceProvider<>::Config();
spFullCfg.gdmlPath = gdmlPath.string();
spFullCfg.g4World = world;
spFullCfg.surfacePreselector =
std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(names,
true);

auto spFull = std::make_shared<Acts::Experimental::Geant4SurfaceProvider<>>(
spFullCfg, Acts::Experimental::Geant4SurfaceProvider<>::kdtOptions(),
false);
spFullCfg, Acts::Experimental::Geant4SurfaceProvider<>::kdtOptions());

auto lbFullCfg = Acts::Experimental::LayerStructureBuilder::Config();
lbFullCfg.surfacesProvider = spFull;
Expand Down Expand Up @@ -157,15 +161,15 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderNames) {
names.begin() + names.size() / 2);

auto spLeftArmCfg = Acts::Experimental::Geant4SurfaceProvider<>::Config();
spLeftArmCfg.gdmlPath = gdmlPath.string();
spLeftArmCfg.g4World = world;
spLeftArmCfg.surfacePreselector =
std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
leftArmNames, true);

auto spLeftArm =
std::make_shared<Acts::Experimental::Geant4SurfaceProvider<>>(
spLeftArmCfg,
Acts::Experimental::Geant4SurfaceProvider<>::kdtOptions(), false);
Acts::Experimental::Geant4SurfaceProvider<>::kdtOptions());

auto lbCfg = Acts::Experimental::LayerStructureBuilder::Config();
lbCfg.surfacesProvider = spLeftArm;
Expand All @@ -190,17 +194,22 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderNames) {
}

BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) {
/// Read the gdml file and get the world volume
G4GDMLParser parser;
parser.Read(gdmlPath.string(), false);
auto world = parser.GetWorldVolume();

// 1D selection -- select only the second row
auto sp1DCfg = Acts::Experimental::Geant4SurfaceProvider<1>::Config();
sp1DCfg.gdmlPath = gdmlPath.string();
sp1DCfg.g4World = world;

auto kdt1DOpt = Acts::Experimental::Geant4SurfaceProvider<1>::kdtOptions();
kdt1DOpt.range = Acts::RangeXD<1, Acts::ActsScalar>();
kdt1DOpt.range[0].set(8, 12);
kdt1DOpt.binningValues = {Acts::BinningValue::binZ};

auto sp1D = std::make_shared<Acts::Experimental::Geant4SurfaceProvider<1>>(
sp1DCfg, kdt1DOpt, false);
sp1DCfg, kdt1DOpt);

auto lb1DCfg = Acts::Experimental::LayerStructureBuilder::Config();
lb1DCfg.surfacesProvider = sp1D;
Expand All @@ -226,7 +235,7 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) {
// 2D selection -- select only the second row
// of the left arm
auto sp2DCfg = Acts::Experimental::Geant4SurfaceProvider<2>::Config();
sp2DCfg.gdmlPath = gdmlPath.string();
sp2DCfg.g4World = world;

auto kdt2DOpt = Acts::Experimental::Geant4SurfaceProvider<2>::kdtOptions();
kdt2DOpt.range = Acts::RangeXD<2, Acts::ActsScalar>();
Expand All @@ -235,7 +244,7 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) {
kdt2DOpt.binningValues = {Acts::BinningValue::binZ};

auto sp2D = std::make_shared<Acts::Experimental::Geant4SurfaceProvider<2>>(
sp2DCfg, kdt2DOpt, false);
sp2DCfg, kdt2DOpt);

auto lb2DCfg = Acts::Experimental::LayerStructureBuilder::Config();
lb2DCfg.surfacesProvider = sp2D;
Expand All @@ -257,7 +266,7 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) {
// Preselect the left arm based on the position
// and select only the second row
auto sp2DPosCfg = Acts::Experimental::Geant4SurfaceProvider<1>::Config();
sp2DPosCfg.gdmlPath = gdmlPath.string();
sp2DPosCfg.g4World = world;
std::map<unsigned int, std::tuple<double, double>> ranges;

std::array<unsigned int, 3> g4Axes{0};
Expand All @@ -274,7 +283,7 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) {
ranges);

auto sp2DPos = std::make_shared<Acts::Experimental::Geant4SurfaceProvider<1>>(
sp2DPosCfg, kdt1DOpt, false);
sp2DPosCfg, kdt1DOpt);

auto lb2DPosCfg = Acts::Experimental::LayerStructureBuilder::Config();
lb2DPosCfg.surfacesProvider = sp2DPos;
Expand Down Expand Up @@ -345,10 +354,15 @@ BOOST_AUTO_TEST_CASE(Geant4RectangleFromGDML) {

bgdml.close();

/// Read the gdml file and get the world volume
G4GDMLParser parser;
parser.Read("Plane.gdml", false);
auto world = parser.GetWorldVolume();

// 1D selection -- select only the second row
auto planeFromGDMLCfg =
Acts::Experimental::Geant4SurfaceProvider<1>::Config();
planeFromGDMLCfg.gdmlPath = "Plane.gdml";
planeFromGDMLCfg.g4World = world;
planeFromGDMLCfg.surfacePreselector =
std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
std::vector<std::string>{"b_pv"}, true);
Expand All @@ -362,7 +376,7 @@ BOOST_AUTO_TEST_CASE(Geant4RectangleFromGDML) {

auto planeProvider =
std::make_shared<Acts::Experimental::Geant4SurfaceProvider<1>>(
planeFromGDMLCfg, kdt1DOpt, false);
planeFromGDMLCfg, kdt1DOpt);

auto planes = planeProvider->surfaces(tContext);
BOOST_CHECK_EQUAL(planes.size(), 1u);
Expand Down
Loading