Skip to content

Commit

Permalink
refactor: Use interface to define copyable G4 factory (#918)
Browse files Browse the repository at this point in the history
This is needed to ensure G4 can have ownership of the detector constructions.
This also makes the recently introduced polymorphic value container (#855) obsolete, so
this removes it
  • Loading branch information
paulgessinger committed Aug 24, 2021
1 parent 0093d56 commit a80f03b
Show file tree
Hide file tree
Showing 17 changed files with 125 additions and 1,011 deletions.
493 changes: 0 additions & 493 deletions Core/include/Acts/Utilities/PolymorphicValue.hpp

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This file is part of the Acts project.
//
// Copyright (C) 2021 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include <memory>

#include "G4VUserDetectorConstruction.hh"

namespace ActsExamples {

/// @brief Class to construct a G4DetectorConstruction
///
class G4DetectorConstructionFactory {
public:
/// Virtual destructor for memory safety.
virtual ~G4DetectorConstructionFactory() = default;

/// The main virtual method to create a detector construction
/// @return Unique pointer to the detector construction
virtual std::unique_ptr<G4VUserDetectorConstruction> operator()() const = 0;
};
} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#pragma once

#include "ActsExamples/Geant4/G4DetectorConstructionFactory.hpp"

#include <G4VUserDetectorConstruction.hh>
#include <globals.hh>

Expand All @@ -26,4 +28,20 @@ class GdmlDetectorConstruction final : public G4VUserDetectorConstruction {
std::string m_path;
};

class GdmlDetectorConstructionFactory : public G4DetectorConstructionFactory {
public:
/// @brief Construct a new GDML Detector Factory
///
/// @param path The input GDML file path
GdmlDetectorConstructionFactory(const std::string& path);

/// @brief Main factory method following the interface
///
/// @return Detector construction based on GDML.
std::unique_ptr<G4VUserDetectorConstruction> operator()() const override;

private:
std::string m_path;
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Propagator/MaterialInteractor.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/PolymorphicValue.hpp"
#include "ActsExamples/Framework/BareAlgorithm.hpp"
#include "ActsExamples/Framework/ProcessCode.hpp"
#include "ActsExamples/Geant4/G4DetectorConstructionFactory.hpp"
#include "ActsExamples/Geant4/PrimaryGeneratorAction.hpp"

#include <memory>
Expand Down Expand Up @@ -41,7 +41,7 @@ class GeantinoRecording final : public BareAlgorithm {
/// Output collection for the generated material tracks.
std::string outputMaterialTracks = "geant-material-tracks";
/// Detector construction object.
Acts::PolymorphicValue<G4VUserDetectorConstruction> detectorConstruction;
std::shared_ptr<G4DetectorConstructionFactory> detectorConstructionFactory;
/// The number of tracks per event.
size_t tracksPerEvent = 0;
/// Configuration of the generator action
Expand Down
9 changes: 9 additions & 0 deletions Examples/Algorithms/Geant4/src/GdmlDetectorConstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,12 @@ G4VPhysicalVolume* GdmlDetectorConstruction::Construct() {
parser.Read(m_path);
return parser.GetWorldVolume();
}

GdmlDetectorConstructionFactory::GdmlDetectorConstructionFactory(
const std::string& path)
: m_path{path} {}

std::unique_ptr<G4VUserDetectorConstruction>
GdmlDetectorConstructionFactory::operator()() const {
return std::make_unique<GdmlDetectorConstruction>(m_path);
}
13 changes: 8 additions & 5 deletions Examples/Algorithms/Geant4/src/GeantinoRecording.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ActsExamples/Geant4/GeantinoRecording.hpp"

#include "ActsExamples/Framework/WhiteBoard.hpp"
#include "ActsExamples/Geant4/GdmlDetectorConstruction.hpp"

#include <iostream>
#include <stdexcept>
Expand All @@ -32,14 +33,16 @@ GeantinoRecording::GeantinoRecording(GeantinoRecording::Config config,
if (m_cfg.outputMaterialTracks.empty()) {
throw std::invalid_argument("Missing output material tracks collection");
}
if (not m_cfg.detectorConstruction) {
throw std::invalid_argument("Missing detector construction object");
}

m_cfg.generationConfig.particleName = "geantino";
m_cfg.generationConfig.energy = 1000.;

m_runManager->SetUserInitialization(m_cfg.detectorConstruction.release());
if (!m_cfg.detectorConstructionFactory) {
throw std::invalid_argument("Missing detector construction object factory");
}

// This object here retains owner
m_runManager->SetUserInitialization(
(*m_cfg.detectorConstructionFactory)().release());
m_runManager->SetUserInitialization(new FTFP_BERT);
m_runManager->SetUserAction(new RunAction());
m_runManager->SetUserAction(new EventAction());
Expand Down
4 changes: 3 additions & 1 deletion Examples/Algorithms/Geant4DD4hep/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ target_include_directories(
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_link_libraries(
ActsExamplesGeant4DD4hep
PUBLIC ${Geant4_LIBRARIES})
PUBLIC
ActsExamplesGeant4
${Geant4_LIBRARIES})

if(${DD4hep_VERSION} VERSION_LESS 1.11)
target_include_directories(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#pragma once

#include "ActsExamples/Geant4/G4DetectorConstructionFactory.hpp"

#include <G4VUserDetectorConstruction.hh>

namespace dd4hep {
Expand All @@ -30,4 +32,20 @@ class DD4hepDetectorConstruction final : public G4VUserDetectorConstruction {
dd4hep::Detector& m_detector;
};

class DD4hepDetectorConstructionFactory : public G4DetectorConstructionFactory {
public:
/// @brief Construct a new DD4hep detector factory
///
/// @param detector DD4hep detector instance to construct G4 geometry from
DD4hepDetectorConstructionFactory(dd4hep::Detector& detector);

/// @brief Main factory method
///
/// @return Detector construction based on a DD4hep geometry
std::unique_ptr<G4VUserDetectorConstruction> operator()() const override;

private:
dd4hep::Detector& m_detector;
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,13 @@ G4VPhysicalVolume* DD4hepDetectorConstruction::Construct() {
g4map.volumeManager();
return m_world;
}

DD4hepDetectorConstructionFactory::DD4hepDetectorConstructionFactory(
dd4hep::Detector& detector)
: m_detector{detector} {}

std::unique_ptr<G4VUserDetectorConstruction>

DD4hepDetectorConstructionFactory::operator()() const {
return std::make_unique<DD4hepDetectorConstruction>(m_detector);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#include "Acts/Utilities/Logger.hpp"
#include "ActsExamples/Framework/BareAlgorithm.hpp"
#include "ActsExamples/Framework/ProcessCode.hpp"
#include "ActsExamples/Geant4/G4DetectorConstructionFactory.hpp"

#include <functional>
#include <memory>
#include <mutex>

Expand All @@ -34,7 +36,7 @@ class EventRecording final : public ActsExamples::BareAlgorithm {
/// The recorded events output
std::string outputHepMcTracks = "geant-outcome-tracks";

std::unique_ptr<G4VUserDetectorConstruction> detectorConstruction = nullptr;
std::shared_ptr<G4DetectorConstructionFactory> detectorConstructionFactory;

/// random number seed 1
int seed1 = 12345;
Expand All @@ -51,12 +53,18 @@ class EventRecording final : public ActsExamples::BareAlgorithm {
};

/// Constructor
EventRecording(Config&& cnf, Acts::Logging::Level level);
/// @param config the configuration
/// @param level the log level
EventRecording(const Config& config, Acts::Logging::Level level);

~EventRecording();

ActsExamples::ProcessCode execute(
const AlgorithmContext& context) const final override;

/// Readonly access to the config
const Config& config() const { return m_cfg; }

private:
/// The config object
Config m_cfg;
Expand Down
12 changes: 7 additions & 5 deletions Examples/Algorithms/Geant4HepMC/src/EventRecording.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,24 @@ ActsExamples::EventRecording::~EventRecording() {
}

ActsExamples::EventRecording::EventRecording(
ActsExamples::EventRecording::Config&& cnf, Acts::Logging::Level level)
const ActsExamples::EventRecording::Config& config,
Acts::Logging::Level level)
: ActsExamples::BareAlgorithm("EventRecording", level),
m_cfg(std::move(cnf)),
m_cfg(config),
m_runManager(std::make_unique<G4RunManager>()) {
if (m_cfg.inputParticles.empty()) {
throw std::invalid_argument("Missing input particle collection");
}
if (m_cfg.outputHepMcTracks.empty()) {
throw std::invalid_argument("Missing output event collection");
}
if (!m_cfg.detectorConstruction) {
throw std::invalid_argument("Missing detector construction object");
if (!m_cfg.detectorConstructionFactory) {
throw std::invalid_argument("Missing detector construction object factory");
}

/// Now set up the Geant4 simulation
m_runManager->SetUserInitialization(m_cfg.detectorConstruction.release());
m_runManager->SetUserInitialization(
(*m_cfg.detectorConstructionFactory)().release());
m_runManager->SetUserInitialization(new FTFP_BERT);
m_runManager->SetUserAction(new ActsExamples::Geant4::HepMC3::RunAction());
m_runManager->SetUserAction(
Expand Down
8 changes: 3 additions & 5 deletions Examples/Run/Geant4/DD4hep/DD4hepGeantinoRecording.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ int main(int argc, char* argv[]) {
auto dd4hepCfg = Options::readDD4hepConfig<po::variables_map>(vm);
auto geometrySvc = std::make_shared<DD4hep::DD4hepGeometryService>(dd4hepCfg);

Acts::PolymorphicValue<G4VUserDetectorConstruction> g4detector =
Acts::makePolymorphicValue<DD4hepDetectorConstruction>(
*geometrySvc->lcdd());

return runGeantinoRecording(vm, std::move(g4detector));
return runGeantinoRecording(
vm, std::make_unique<DD4hepDetectorConstructionFactory>(
*geometrySvc->lcdd()));
}
7 changes: 2 additions & 5 deletions Examples/Run/Geant4/GdmlGeantinoRecording.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ int main(int argc, char* argv[]) {
}
auto gdmlFile = vm["gdml-file"].as<std::string>();

// Setup the GDML detector
Acts::PolymorphicValue<G4VUserDetectorConstruction> g4detector =
Acts::makePolymorphicValue<GdmlDetectorConstruction>(gdmlFile);

return runGeantinoRecording(vm, std::move(g4detector));
return runGeantinoRecording(
vm, std::make_unique<GdmlDetectorConstructionFactory>(gdmlFile));
}
6 changes: 4 additions & 2 deletions Examples/Run/Geant4/GeantinoRecordingBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "ActsExamples/Framework/RandomNumbers.hpp"
#include "ActsExamples/Framework/Sequencer.hpp"
#include "ActsExamples/Geant4/G4DetectorConstructionFactory.hpp"
#include "ActsExamples/Geant4/Geant4Options.hpp"
#include "ActsExamples/Geant4/GeantinoRecording.hpp"
#include "ActsExamples/Io/Root/RootMaterialTrackWriter.hpp"
Expand All @@ -25,7 +26,8 @@
/// @param detector The detector descriptor instance
inline int runGeantinoRecording(
const boost::program_options::variables_map& vm,
Acts::PolymorphicValue<G4VUserDetectorConstruction> g4detector) {
std::shared_ptr<ActsExamples::G4DetectorConstructionFactory>
g4DetectorFactory) {
using namespace ActsExamples;
Sequencer sequencer(Options::readSequencerConfig(vm));
auto logLevel = Options::readLogLevel(vm);
Expand All @@ -34,7 +36,7 @@ inline int runGeantinoRecording(
// Setup the Geant4 algorithm
auto g4Config = Options::readGeantinoRecordingConfig(vm);
auto outputMaterialTracks = g4Config.outputMaterialTracks;
g4Config.detectorConstruction = std::move(g4detector);
g4Config.detectorConstructionFactory = std::move(g4DetectorFactory);
sequencer.addAlgorithm(
std::make_shared<GeantinoRecording>(std::move(g4Config), logLevel));

Expand Down
7 changes: 3 additions & 4 deletions Examples/Run/Geant4/HepMC/EventRecordingExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,14 @@ int main(int argc, char* argv[]) {
auto dd4hepCfg = ActsExamples::Options::readDD4hepConfig(vm);
auto geometrySvc =
std::make_shared<ActsExamples::DD4hep::DD4hepGeometryService>(dd4hepCfg);
std::unique_ptr<G4VUserDetectorConstruction> g4detector =
std::make_unique<ActsExamples::DD4hepDetectorConstruction>(
*geometrySvc->lcdd());

// Prepare the recording
ActsExamples::EventRecording::Config erConfig;
erConfig.inputParticles = particleReader.outputParticles;
erConfig.outputHepMcTracks = "geant-event";
erConfig.detectorConstruction = std::move(g4detector);
erConfig.detectorConstructionFactory =
std::make_unique<ActsExamples::DD4hepDetectorConstructionFactory>(
*geometrySvc->lcdd());
erConfig.seed1 = vm["g4-rnd-seed1"].as<unsigned int>();
erConfig.seed2 = vm["g4-rnd-seed2"].as<unsigned int>();

Expand Down
1 change: 0 additions & 1 deletion Tests/UnitTests/Core/Utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ add_unittest(Result ResultTests.cpp)
add_unittest(Subspace SubspaceTests.cpp)
add_unittest(TypeTraits TypeTraitsTest.cpp)
add_unittest(UnitVectors UnitVectorsTests.cpp)
add_unittest(PolymorphicValue PolymorphicValueTest.cpp)
if (ACTS_BUILD_CUDA_FEATURES)
add_unittest(Cuda CudaTests.cu)
add_unittest(CudaMostSimplified CudaMostSimplifiedTests.cu)
Expand Down

0 comments on commit a80f03b

Please sign in to comment.