diff --git a/CI/physmon/reference/particles_ttbar_hist.root b/CI/physmon/reference/particles_ttbar_hist.root index 9c063e85f35..6f822d306a7 100644 Binary files a/CI/physmon/reference/particles_ttbar_hist.root and b/CI/physmon/reference/particles_ttbar_hist.root differ diff --git a/CI/physmon/reference/performance_ambi_ttbar.root b/CI/physmon/reference/performance_ambi_ttbar.root index c7681914461..852fda6e398 100644 Binary files a/CI/physmon/reference/performance_ambi_ttbar.root and b/CI/physmon/reference/performance_ambi_ttbar.root differ diff --git a/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root b/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root index 0fda80b2538..353b7cf9536 100644 Binary files a/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root and b/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_ttbar_hist.root b/CI/physmon/reference/performance_amvf_ttbar_hist.root index e1d7b06d86d..4b65e64925c 100644 Binary files a/CI/physmon/reference/performance_amvf_ttbar_hist.root and b/CI/physmon/reference/performance_amvf_ttbar_hist.root differ diff --git a/CI/physmon/reference/performance_ckf_ttbar.root b/CI/physmon/reference/performance_ckf_ttbar.root index 27eabf03e42..ae3df7e82fa 100644 Binary files a/CI/physmon/reference/performance_ckf_ttbar.root and b/CI/physmon/reference/performance_ckf_ttbar.root differ diff --git a/CI/physmon/reference/performance_seeding_ttbar.root b/CI/physmon/reference/performance_seeding_ttbar.root index e2026cbe817..2c24c7319d8 100644 Binary files a/CI/physmon/reference/performance_seeding_ttbar.root and b/CI/physmon/reference/performance_seeding_ttbar.root differ diff --git a/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root b/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root index eccb29d6e4e..ad78496556d 100644 Binary files a/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root and b/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root differ diff --git a/CI/physmon/reference/vertices_ttbar_hist.root b/CI/physmon/reference/vertices_ttbar_hist.root index cf68b998ed7..dd1e71ede26 100644 Binary files a/CI/physmon/reference/vertices_ttbar_hist.root and b/CI/physmon/reference/vertices_ttbar_hist.root differ diff --git a/CMakeLists.txt b/CMakeLists.txt index c901033f1c1..dfc91319a27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,6 +213,7 @@ set(_acts_nlohmanjson_version 3.2.0) set(_acts_onnxruntime_version 1.12.0) set(_acts_root_version 6.20) set(_acts_tbb_version 2020.1) +set(_acts_pythia8_version 8.309) # recommended dependency version. if there is an opportunity to reach # this version we will try so. @@ -436,15 +437,7 @@ if(ACTS_BUILD_EXAMPLES_HEPMC3) find_package(HepMC3 ${_acts_hepmc3_version} REQUIRED CONFIG) endif() if(ACTS_BUILD_EXAMPLES_PYTHIA8) - find_package(Pythia8 REQUIRED) - - if(DEFINED CMAKE_CXX_STANDARD) - if(${CMAKE_CXX_STANDARD} GREATER_EQUAL 20) - message(WARNING "ACTS is configured to build with C++20." - "As of version 309, Pythia8 does not compile under C++20." - "You can find a patch file at: https://gist.github.com/paulgessinger/7a823b4015d4511cf829472291c8ddcf") - endif() - endif() + find_package(Pythia8 ${_acts_pythia8_version} REQUIRED) endif() # other dependencies if(ACTS_BUILD_DOCS) diff --git a/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp b/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp index fe39105ba55..0293443d17c 100644 --- a/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp +++ b/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp @@ -23,16 +23,35 @@ namespace ActsExamples { -namespace { -struct FrameworkRndmEngine : public Pythia8::RndmEngine { - RandomEngine& rng; +struct Pythia8RandomEngineWrapper : public Pythia8::RndmEngine { + RandomEngine* rng{nullptr}; + + struct { + std::size_t numUniformRandomNumbers = 0; + double first = std::numeric_limits::quiet_NaN(); + double last = std::numeric_limits::quiet_NaN(); + } statistics; + + Pythia8RandomEngineWrapper() = default; - FrameworkRndmEngine(RandomEngine& rng_) : rng(rng_) {} double flat() override { - return std::uniform_real_distribution(0.0, 1.0)(rng); + if (rng == nullptr) { + throw std::runtime_error( + "Pythia8RandomEngineWrapper: no random engine set"); + } + + double value = std::uniform_real_distribution(0.0, 1.0)(*rng); + if (statistics.numUniformRandomNumbers == 0) { + statistics.first = value; + } + statistics.last = value; + statistics.numUniformRandomNumbers++; + return value; } + + void setRandomEngine(RandomEngine& rng_) { rng = &rng_; } + void clearRandomEngine() { rng = nullptr; } }; -} // namespace Pythia8Generator::Pythia8Generator(const Config& cfg, Acts::Logging::Level lvl) : m_cfg(cfg), @@ -49,11 +68,31 @@ Pythia8Generator::Pythia8Generator(const Config& cfg, Acts::Logging::Level lvl) m_pythia8->settings.mode("Beams:frameType", 1); m_pythia8->settings.parm("Beams:eCM", m_cfg.cmsEnergy / Acts::UnitConstants::GeV); + + m_pythia8RndmEngine = std::make_shared(); + +#if PYTHIA_VERSION_INTEGER >= 8310 + m_pythia8->setRndmEnginePtr(m_pythia8RndmEngine); +#else + m_pythia8->setRndmEnginePtr(m_pythia8RndmEngine.get()); +#endif + + RandomEngine rng{m_cfg.initializationSeed}; + m_pythia8RndmEngine->setRandomEngine(rng); m_pythia8->init(); + m_pythia8RndmEngine->clearRandomEngine(); } // needed to allow unique_ptr of forward-declared Pythia class -Pythia8Generator::~Pythia8Generator() = default; +Pythia8Generator::~Pythia8Generator() { + ACTS_INFO("Pythia8Generator produced " + << m_pythia8RndmEngine->statistics.numUniformRandomNumbers + << " uniform random numbers"); + ACTS_INFO( + " first = " << m_pythia8RndmEngine->statistics.first); + ACTS_INFO( + " last = " << m_pythia8RndmEngine->statistics.last); +} std::pair Pythia8Generator::operator()(RandomEngine& rng) { @@ -64,13 +103,10 @@ Pythia8Generator::operator()(RandomEngine& rng) { // pythia8 is not thread safe and generation needs to be protected std::lock_guard lock(m_pythia8Mutex); -// use per-thread random engine also in pythia -#if PYTHIA_VERSION_INTEGER >= 8310 - m_pythia8->rndm.rndmEnginePtr(std::make_shared(rng)); -#else - FrameworkRndmEngine rndmEngine(rng); - m_pythia8->rndm.rndmEnginePtr(&rndmEngine); -#endif + // use per-thread random engine also in pythia + + m_pythia8RndmEngine->setRandomEngine(rng); + { Acts::FpeMonitor mon{0}; // disable all FPEs while we're in Pythia8 m_pythia8->next(); @@ -157,6 +193,9 @@ Pythia8Generator::operator()(RandomEngine& rng) { std::pair out; out.first.insert(vertices.begin(), vertices.end()); out.second.insert(particles.begin(), particles.end()); + + m_pythia8RndmEngine->clearRandomEngine(); + return out; } diff --git a/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.hpp b/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.hpp index 4b6f8a20614..033d0cd789d 100644 --- a/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.hpp +++ b/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.hpp @@ -27,6 +27,8 @@ class Pythia; namespace ActsExamples { +struct Pythia8RandomEngineWrapper; + class Pythia8Generator : public EventGenerator::ParticlesGenerator { public: struct Config { @@ -48,6 +50,8 @@ class Pythia8Generator : public EventGenerator::ParticlesGenerator { bool labelSecondaries = true; /// The spatial threshold to consider a particle originating from a vertex double spatialVertexThreshold = 1.0 * Acts::UnitConstants::um; + /// Random seed for the initialization stage of Pythia8 + unsigned int initializationSeed = 42; }; Pythia8Generator(const Config& cfg, Acts::Logging::Level lvl); @@ -69,6 +73,7 @@ class Pythia8Generator : public EventGenerator::ParticlesGenerator { Config m_cfg; std::unique_ptr m_logger; std::unique_ptr<::Pythia8::Pythia> m_pythia8; + std::shared_ptr m_pythia8RndmEngine; std::mutex m_pythia8Mutex; }; diff --git a/Examples/Python/src/Pythia8.cpp b/Examples/Python/src/Pythia8.cpp index 32747f1097c..9865c9d5231 100644 --- a/Examples/Python/src/Pythia8.cpp +++ b/Examples/Python/src/Pythia8.cpp @@ -46,7 +46,11 @@ void addPythia8(Context& ctx) { .def_readwrite("printShortEventListing", &Gen::Config::printShortEventListing) .def_readwrite("printLongEventListing", - &Gen::Config::printLongEventListing); + &Gen::Config::printLongEventListing) + .def_readwrite("labelSecondaries", &Gen::Config::labelSecondaries) + .def_readwrite("spatialVertexThreshold", + &Gen::Config::spatialVertexThreshold) + .def_readwrite("initializationSeed", &Gen::Config::initializationSeed); patchClassesWithConfig(p8); } diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index e3ab56675d1..bced4603466 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -1,4 +1,4 @@ -test_pythia8__pythia8_particles.root: 6e00f6ab534ef5888861bef3ca5bb47d45171237e875eef0d119df7bda8cba46 +test_pythia8__pythia8_particles.root: a8b53c12e771091bc2f5ace0198e9f6c5ac1909e2e6d0e3e4945e8174048ef62 test_fatras__particles_simulation.root: bc970873fef0c2efd86ed5413623802353d2cd04abea72de14e8cdfc0e40076f test_fatras__hits.root: 6e4beb045fa1712c4d14c280ba33c3fa13e4aff9de88d55c3e32f62ad226f724 test_geant4__particles_simulation.root: 3c9c6265183b04c9d62ed5f2d0709c6dd74e33fbb53ac0aeb3274f6600257fc1 diff --git a/cmake/FindPythia8.cmake b/cmake/FindPythia8.cmake index 6d4155b3585..81486164ebc 100644 --- a/cmake/FindPythia8.cmake +++ b/cmake/FindPythia8.cmake @@ -14,8 +14,13 @@ find_path(Pythia8_INCLUDE_DIR PATHS /opt/pythia8 /usr/local DOC "The Pythia8 include directory") +file(READ "${Pythia8_INCLUDE_DIR}/Pythia8/Pythia.h" Pythia8_VERSION_FILE) +string(REGEX MATCH "#define PYTHIA_VERSION (8\.[0-9]+)" _ ${Pythia8_VERSION_FILE}) +set(Pythia8_VERSION ${CMAKE_MATCH_1}) + find_package_handle_standard_args(Pythia8 - REQUIRED_VARS Pythia8_LIBRARY Pythia8_INCLUDE_DIR) + REQUIRED_VARS Pythia8_LIBRARY Pythia8_INCLUDE_DIR + VERSION_VAR Pythia8_VERSION) add_library(Pythia8 SHARED IMPORTED) set_property(TARGET Pythia8 PROPERTY IMPORTED_LOCATION ${Pythia8_LIBRARY})