diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b5e05c3..6bf4661 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,369 +1,369 @@ # --------------------------------- # - General Setup - # --------------------------------- stages: - build - test - FOG:build - FOG:test - clean_code - long_test - publish variables: # build directories HEJ_BUILD_DIR: tmp_HEJ/HEJ_build HEJ_INSTALL_DIR: tmp_HEJ/HEJ_installed FOG_BUILD_DIR: tmp_HEJ/FOG_build FOG_INSTALL_DIR: ${HEJ_INSTALL_DIR} # docker images DOCKER_BASIC: hejdock/hepenv DOCKER_HEPMC3: hejdock/hepmc3env DOCKER_QCDLOOP: hejdock/qcdloopenv DOCKER_RIVET: hejdock/rivetenv DOCKER_HIGHFIVE: "hejdock/highfiveenv:centos7" # default name of cmake CMAKE: cmake CTEST: ctest # ----------- Macros ----------- after_script: - date .tags_template: tags: &tags_def - docker # default pipeline triggers .only_template: only: &only_def - branches - tags - merge_requests # save complete history of failed tests .save_failure: artifacts: &artifacts_failed when: on_failure untracked: true expire_in: 3d # --------------------------------- # - Script Templates - # --------------------------------- # ----------- Build ----------- .HEJ_build: tags: *tags_def only: *only_def stage: build before_script: - date - source /cvmfs/pheno.egi.eu/HEJ/HEJ_env.sh || exit 1 # prepare build - t_HEJ_DIR=${PWD} - t_HEJ_INSTALL_DIR=${PWD}/${HEJ_INSTALL_DIR} - t_HEJ_BUILD_DIR=${PWD}/${HEJ_BUILD_DIR} - mkdir -p ${t_HEJ_BUILD_DIR} - cd ${t_HEJ_BUILD_DIR} - ${CMAKE} ${t_HEJ_DIR} -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_INSTALL_PREFIX=${t_HEJ_INSTALL_DIR} script: - make -j $(nproc --ignore=1) - make install artifacts: # save build and installed folder name: build expire_in: 1d paths: - ${HEJ_INSTALL_DIR} - ${HEJ_BUILD_DIR} # ----------- Test ----------- .HEJ_test: tags: *tags_def only: *only_def stage: test before_script: - date - source /cvmfs/pheno.egi.eu/HEJ/HEJ_env.sh || exit 1 # load HEJ - t_HEJ_DIR=${PWD} - t_HEJ_INSTALL_DIR=${PWD}/${HEJ_INSTALL_DIR} - export LD_LIBRARY_PATH=${t_HEJ_INSTALL_DIR}/lib:${LD_LIBRARY_PATH} - export PATH=${t_HEJ_INSTALL_DIR}/bin:${PATH} - cd ${HEJ_BUILD_DIR} - ${CMAKE} ${t_HEJ_DIR} # rerun cmake to create all test configure files script: - ${CTEST} --output-on-failure artifacts: *artifacts_failed ## ----------- FOG build ----------- .FOG_build: tags: *tags_def only: *only_def stage: FOG:build before_script: - date - source /cvmfs/pheno.egi.eu/HEJ/HEJ_env.sh || exit 1 # load HEJ - t_HEJ_INSTALL_DIR=${PWD}/${HEJ_INSTALL_DIR} - export LD_LIBRARY_PATH=${t_HEJ_INSTALL_DIR}/lib:${LD_LIBRARY_PATH} - export PATH=${t_HEJ_INSTALL_DIR}/bin:${PATH} # prepare build - t_FOG_DIR=${PWD}/FixedOrderGen - t_FOG_INSTALL_DIR=${PWD}/${FOG_INSTALL_DIR} - t_FOG_BUILD_DIR=${PWD}/${FOG_BUILD_DIR} - mkdir -p ${t_FOG_BUILD_DIR} - cd ${t_FOG_BUILD_DIR} - ${CMAKE} ${t_FOG_DIR} -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_INSTALL_PREFIX=${t_FOG_INSTALL_DIR} script: - make -j $(nproc --ignore=1) - make install artifacts: # save build and installed folder name: FOG_build expire_in: 1d paths: - ${HEJ_INSTALL_DIR} - ${FOG_INSTALL_DIR} - ${FOG_BUILD_DIR} ## ----------- FOG test ----------- .FOG_test: tags: *tags_def only: *only_def stage: FOG:test before_script: - date - source /cvmfs/pheno.egi.eu/HEJ/HEJ_env.sh || exit 1 # load HEJ - t_FOG_DIR=${PWD}/FixedOrderGen - t_HEJ_INSTALL_DIR=${PWD}/${HEJ_INSTALL_DIR} - t_FOG_INSTALL_DIR=${PWD}/${FOG_INSTALL_DIR} - export LD_LIBRARY_PATH=${t_HEJ_INSTALL_DIR}/lib:${LD_LIBRARY_PATH} - export PATH=${t_HEJ_INSTALL_DIR}/bin:${t_FOG_INSTALL_DIR}/bin:${PATH} - t_FOG_BUILD_DIR=${PWD}/${FOG_BUILD_DIR} - cd ${t_FOG_BUILD_DIR} - ${CMAKE} ${t_FOG_DIR} # rerun cmake to create all test configure files script: - - ${CTEST} --output-on-failure + - ${CTEST} --output-on-failure -j $(nproc --ignore=1) artifacts: *artifacts_failed # --------------------------------- # - Build & Test - # --------------------------------- # ----------- basic ----------- build:basic: image: ${DOCKER_BASIC} extends: .HEJ_build test:basic: image: ${DOCKER_BASIC} extends: .HEJ_test dependencies: - build:basic FOG:build:basic: image: ${DOCKER_BASIC} extends: .FOG_build dependencies: - build:basic FOG:test:basic: image: ${DOCKER_BASIC} extends: .FOG_test dependencies: - FOG:build:basic # ----------- HepMC 3 ----------- build:hepmc3: image: ${DOCKER_HEPMC3} extends: .HEJ_build test:hepmc3: image: ${DOCKER_HEPMC3} extends: .HEJ_test dependencies: - build:hepmc3 # ----------- HighFive/hdf5 ----------- build:HighFive: image: ${DOCKER_HIGHFIVE} extends: .HEJ_build variables: CMAKE: cmake3 test:HighFive: image: ${DOCKER_HIGHFIVE} extends: .HEJ_test variables: CMAKE: cmake3 CTEST: ctest3 dependencies: - build:HighFive # ----------- QCDloop ----------- build:qcdloop: image: ${DOCKER_QCDLOOP} extends: .HEJ_build test:qcdloop: image: ${DOCKER_QCDLOOP} extends: .HEJ_test dependencies: - build:qcdloop # ----------- rivet ----------- build:rivet: image: ${DOCKER_RIVET} extends: .HEJ_build test:rivet: image: ${DOCKER_RIVET} extends: .HEJ_test dependencies: - build:rivet script: - ${CTEST} --output-on-failure - bash -c '[ -f tst.yoda ]' && echo "found rivet output" - rivet-cmphistos tst.yoda - bash -c '[ -f MC_XS_XS.dat ]' && echo "yoda not empty" # --------------------------------- # - Clean Code - # --------------------------------- No_tabs: stage: clean_code tags: *tags_def only: *only_def image: hejdock/git dependencies: [] script: - date - check_tabs # ----------- No gcc warnings ----------- .Warning_build: extends: .HEJ_build stage: clean_code dependencies: [] script: - cd ${t_HEJ_DIR} # suppress warnings from side packages - sed -i 's/include_directories(${LHAPDF/include_directories(SYSTEM ${LHAPDF/g' CMakeLists.txt - sed -i 's/include_directories(${fastjet/include_directories(SYSTEM ${fastjet/g' CMakeLists.txt - sed -i 's/include_directories(${Boost/include_directories(SYSTEM ${Boost/g' CMakeLists.txt - cd ${t_HEJ_BUILD_DIR} - ${CMAKE} ${t_HEJ_DIR} -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_BUILD_TYPE=RelWithDebInfo # only clean release builds - make -j $(nproc --ignore=1) artifacts: # don't save anything .Warning_FOG: extends: .FOG_build stage: clean_code script: - cd ${t_FOG_DIR} # suppress warnings from side packages - sed -i 's/include_directories(${LHAPDF/include_directories(SYSTEM ${LHAPDF/g' CMakeLists.txt - sed -i 's/include_directories(${fastjet/include_directories(SYSTEM ${fastjet/g' CMakeLists.txt - sed -i 's/include_directories(${Boost/include_directories(SYSTEM ${Boost/g' CMakeLists.txt - cd ${t_FOG_BUILD_DIR} - ${CMAKE} ${t_FOG_DIR} -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_BUILD_TYPE=RelWithDebInfo # only clean release builds - make -j $(nproc --ignore=1) artifacts: # don't save anything No_Warning:basic: image: ${DOCKER_BASIC} extends: .Warning_build No_Warning:basic:FOG: image: ${DOCKER_BASIC} extends: .Warning_FOG dependencies: - build:basic # --------------------------------- # - Long tests - # --------------------------------- .HEJ_test_long: extends: .HEJ_build stage: long_test script: - ${CMAKE} ${t_HEJ_DIR} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DTEST_ALL=TRUE - make -j $(nproc --ignore=1) install - ctest --output-on-failure only: # only run on specific branches - master - /^v\d+\.\d+$/ - merge_requests # allow triggering long test manually .HEJ_test_long:manual: extends: .HEJ_test_long when: manual only: # default only - branches - tags # ----------- QCDloop ----------- Long_test:qcdloop: image: ${DOCKER_QCDLOOP} extends: .HEJ_test_long dependencies: - build:qcdloop manual:Long_test:qcdloop: image: ${DOCKER_QCDLOOP} extends: .HEJ_test_long:manual dependencies: - build:qcdloop # --------------------------------- # - Publish - # --------------------------------- Publish_version: stage: publish tags: *tags_def image: hejdock/git dependencies: [] only: - /^v\d+\.\d+$/ except: - tags when: on_success before_script: - mkdir -p .ssh/ && echo "${SSH_KEY}" > .ssh/id_rsa && chmod 0600 .ssh/id_rsa - rm -rf ~/.ssh/id_rsa; mkdir -p ~/.ssh/ - ln -s $PWD/.ssh/id_rsa ~/.ssh/id_rsa && chmod 0600 ~/.ssh/id_rsa - ssh -T ${PUBLIC_GIT_PREFIX} -o "StrictHostKeyChecking no" || echo "added ssh" script: - git remote add public ${PUBLIC_GIT_PREFIX}${PUBLIC_GIT_POSTFIX} - git checkout $CI_COMMIT_REF_NAME - git branch - git pull - git push public - git push public --tags after_script: - rm -f /root/.ssh/id_rsa && rm -fr .ssh - git remote rm public diff --git a/FixedOrderGen/t/h_2j.cc b/FixedOrderGen/t/h_2j.cc index 8bdc382..7e352b7 100644 --- a/FixedOrderGen/t/h_2j.cc +++ b/FixedOrderGen/t/h_2j.cc @@ -1,73 +1,73 @@ /** * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019 * \copyright GPLv2 or later */ #ifdef NDEBUG #undef NDEBUG #endif #include <algorithm> #include <cmath> #include <cassert> #include <iostream> #include "config.hh" #include "EventGenerator.hh" -#include "HEJ/Ranlux64.hh" +#include "HEJ/Mixmax.hh" #include "HEJ/Event.hh" #include "HEJ/PDF.hh" #include "HEJ/MatrixElement.hh" using namespace HEJFOG; int main(){ constexpr double invGeV2_to_pb = 389379292.; constexpr double xs_ref = 2.04928; // +- 0.00377252 //calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20 auto config = load_config("config_h_2j.yml"); - HEJ::Ranlux64 ran{}; + HEJ::Mixmax ran{}; HEJFOG::EventGenerator generator{ config.process, config.beam, HEJ::ScaleGenerator{ config.scales.base, config.scales.factors, config.scales.max_ratio }, config.jets, config.pdf_id, config.subleading_fraction, config.subleading_channels, config.particles_properties, config.Higgs_coupling, ran }; double xs = 0., xs_err = 0.; for (int trials = 0; trials < config.events; ++trials){ auto ev = generator.gen_event(); if(generator.status() != good) continue; assert(ev); ev->central().weight *= invGeV2_to_pb; ev->central().weight /= config.events; const auto the_Higgs = std::find_if( begin(ev->outgoing()), end(ev->outgoing()), [](HEJ::Particle const & p){ return p.type == HEJ::ParticleID::h; } ); assert(the_Higgs != end(ev->outgoing())); if(std::abs(the_Higgs->rapidity()) > 5.) continue; xs += ev->central().weight; xs_err += ev->central().weight*ev->central().weight; } xs_err = std::sqrt(xs_err); std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << std::endl; assert(std::abs(xs - xs_ref) < 3*xs_err); assert(xs_err < 0.01*xs); } diff --git a/doc/sphinx/HEJ.rst b/doc/sphinx/HEJ.rst index 1365039..bf8e1fe 100644 --- a/doc/sphinx/HEJ.rst +++ b/doc/sphinx/HEJ.rst @@ -1,304 +1,324 @@ .. _`Running HEJ 2`: Running HEJ 2 ============= Quick start ----------- In order to run HEJ 2, you need a configuration file and a file containing fixed-order events. A sample configuration is given by the :file:`config.yml` file distributed together with HEJ 2. Events in the Les Houches Event File format can be generated with standard Monte Carlo generators like `MadGraph5_aMC@NLO <https://launchpad.net/mg5amcnlo>`_ or `Sherpa <https://sherpa.hepforge.org/trac/wiki>`_. If HEJ 2 was compiled with `HDF5 <https://www.hdfgroup.org/>`_ support, it can also read event files in the format suggested in `arXiv:1905.05120 <https://arxiv.org/abs/1905.05120>`_. HEJ 2 assumes that the cross section is given by the sum of the event weights. Depending on the fixed-order generator it may be necessary to adjust the weights in the Les Houches Event File accordingly. The processes supported by HEJ 2 are - Pure multijet production - Production of a Higgs boson with jets +- Production of a W boson with jets .. - - *TODO* Production of a W boson with jets - *TODO* Production of a Z boson or photon with jets where at least two jets are required in each case. For the time being, only leading-order events are supported. After generating an event file :file:`events.lhe` adjust the parameters under the `fixed order jets`_ setting in :file:`config.yml` to the settings in the fixed-order generation. Resummation can then be added by running:: HEJ config.yml events.lhe Using the default settings, this will produce an output event file :file:`HEJ.lhe` with events including high-energy resummation. When using the `Docker image <https://hub.docker.com/r/hejdock/hej>`_, HEJ can be run with .. code-block:: bash docker run -v $PWD:$PWD -w $PWD hejdock/hej HEJ config.yml events.lhe .. _`HEJ 2 settings`: Settings -------- HEJ 2 configuration files follow the `YAML <http://yaml.org/>`_ format. The following configuration parameters are supported: .. _`trials`: **trials** High-energy resummation is performed by generating a number of resummation phase space configurations corresponding to an input fixed-order event. This parameter specifies how many such configurations HEJ 2 should try to generate for each input event. Typical values vary between 10 and 100. .. _`min extparton pt`: **min extparton pt** Specifies the minimum transverse momentum in GeV of the most forward and the most backward parton. This setting is needed to regulate an otherwise uncancelled divergence. Its value should be slightly below the minimum transverse momentum of jets specified by `resummation jets: min pt`_. See also the `max ext soft pt fraction`_ setting. .. _`max ext soft pt fraction`: **max ext soft pt fraction** Specifies the maximum fraction that soft radiation can contribute to the transverse momentum of each the most forward and the most backward jet. Values between around 0.05 and 0.1 are recommended. See also the `min extparton pt`_ setting. .. _`fixed order jets`: **fixed order jets** This tag collects a number of settings specifying the jet definition in the event input. The settings should correspond to the ones used in the fixed-order Monte Carlo that generated the input events. .. _`fixed order jets: min pt`: **min pt** Minimum transverse momentum in GeV of fixed-order jets. .. _`fixed order jets: algorithm`: **algorithm** The algorithm used to define jets. Allowed settings are :code:`kt`, :code:`cambridge`, :code:`antikt`, :code:`cambridge for passive`. See the `FastJet <http://fastjet.fr/>`_ documentation for a description of these algorithms. .. _`fixed order jets: R`: **R** The R parameter used in the jet algorithm, roughly corresponding to the jet radius in the plane spanned by the rapidity and the azimuthal angle. .. _`resummation jets`: **resummation jets** This tag collects a number of settings specifying the jet definition in the observed, i.e. resummed events. These settings are optional, by default the same values as for the `fixed order jets`_ are assumed. .. _`resummation jets: min pt`: **min pt** Minimum transverse momentum in GeV of resummation jets. This should be between 25% and 50% larger than the minimum transverse momentum of fixed order jets set by `fixed order jets: min pt`_. .. _`resummation jets: algorithm`: **algorithm** The algorithm used to define jets. The HEJ 2 approach to resummation relies on properties of :code:`antikt` jets, so this value is strongly recommended. For a list of possible other values, see the `fixed order jets: algorithm`_ setting. .. _`resummation jets: R`: **R** The R parameter used in the jet algorithm. .. _`FKL`: **FKL** Specifies how to treat events respecting FKL rapidity ordering. These configurations are dominant in the high-energy limit. The possible values are :code:`reweight` to enable resummation, :code:`keep` to keep the events as they are up to a possible change of renormalisation and factorisation scale, and :code:`discard` to discard these events. .. _`unordered`: **unordered** - Specifies how to treat events with one emission that does not respect - FKL ordering. In the high-energy limit, such configurations are - logarithmically suppressed compared to FKL configurations. The - possible values are the same as for the `FKL`_ setting, but - :code:`reweight` is currently only supported for Higgs boson plus - jets production. + + Specifies how to treat events with one emission that does not respect FKL + ordering, e.g. :code:`u d => g u d`. In the high-energy limit, such + configurations are logarithmically suppressed compared to FKL configurations. + The possible values are the same as for the `FKL`_ setting, but + :code:`reweight` is currently only supported for Higgs or W bosons plus jets + production. + +.. _`ex_qqx`: + +**extremal qqx** + Specifies how to treat events with a quark-antiquark pair as extremal partons + in rapidity, e.g. :code:`g d => u u_bar d`. In the high-energy limit, such + configurations are logarithmically suppressed compared to FKL configurations. + The possible values are the same as for the `FKL`_ setting, but + :code:`reweight` is currently only supported for W boson plus jets + production. + +.. _`min_qqx`: + +**central qqx** + Specifies how to treat events with a quark-antiquark pair central in + rapidity, e.g. :code:`g g => g u u_bar g`. In the high-energy limit, such + configurations are logarithmically suppressed compared to FKL configurations. + The possible values are the same as for the `FKL`_ setting, but + :code:`reweight` is currently only supported for W boson plus jets + production. .. _`non-HEJ`: **non-HEJ** Specifies how to treat events where no resummation is possible. The allowed values are :code:`keep` to keep the events as they are up to a possible change of renormalisation and factorisation scale and :code:`discard` to discard these events. .. _`scales`: **scales** Specifies the renormalisation and factorisation scales for the output events. This can either be a single entry or a list :code:`[scale1, scale2, ...]`. For the case of a list the first entry defines the central scale. Possible values are fixed numbers to set the scale in GeV or the following: - :code:`H_T`: The sum of the scalar transverse momenta of all final-state particles - :code:`max jet pperp`: The maximum transverse momentum of all jets - :code:`jet invariant mass`: Sum of the invariant masses of all jets - :code:`m_j1j2`: Invariant mass between the two hardest jets. - Scales can be multiplied or divided by an overall factor, - e.g. :code:`H_T/2`. + Scales can be multiplied or divided by overall factors, e.g. :code:`H_T/2`. It is also possible to import scales from an external library, see :ref:`Custom scales` .. _`scale factors`: **scale factors** A list of numeric factors by which each of the `scales`_ should be multiplied. Renormalisation and factorisation scales are varied independently. For example, a list with entries :code:`[0.5, 2]` would give the four scale choices (0.5μ\ :sub:`r`, 0.5μ\ :sub:`f`); (0.5μ\ :sub:`r`, 2μ\ :sub:`f`); (2μ\ :sub:`r`, 0.5μ\ :sub:`f`); (2μ\ :sub:`r`, 2μ\ :sub:`f`) in this order. The ordering corresponds to the order of the final event weights. .. _`max scale ratio`: **max scale ratio** Specifies the maximum factor by which renormalisation and factorisation scales may difer. For a value of :code:`2` and the example given for the `scale factors`_ the scale choices (0.5μ\ :sub:`r`, 2μ\ :sub:`f`) and (2μ\ :sub:`r`, 0.5μ\ :sub:`f`) will be discarded. .. _`log correction`: **log correction** Whether to include corrections due to the evolution of the strong coupling constant in the virtual corrections. Allowed values are :code:`true` and :code:`false`. .. _`event output`: **event output** Specifies the name of a single event output file or a list of such files. The file format is either specified explicitly or derived from the suffix. For example, :code:`events.lhe` or, equivalently :code:`Les Houches: events.lhe` generates an output event file :code:`events.lhe` in the Les Houches format. The supported formats are - :code:`file.lhe` or :code:`Les Houches: file`: The Les Houches event file format. - :code:`file.hepmc` or :code:`HepMC: file`: The HepMC format. .. _`random generator`: **random generator** Sets parameters for random number generation. .. _`random generator: name`: **name** Which random number generator to use. Currently, :code:`mixmax` and :code:`ranlux64` are supported. Mixmax is recommended. See the `CLHEP documentation <http://proj-clhep.web.cern.ch/proj-clhep/index.html#docu>`_ for details on the generators. .. _`random generator: seed`: **seed** The seed for random generation. This should be a single number for :code:`mixmax` and the name of a state file for :code:`ranlux64`. .. _`analysis`: **analysis** Name and Setting for the event analyses; either a custom analysis plugin or Rivet. For the first the :code:`plugin` sub-entry should be set to the analysis file path. All further entries are passed on to the analysis. To use Rivet a list of Rivet analyses have to be given in :code:`rivet` and prefix for the yoda file has to be set through :code:`output`. See :ref:`Writing custom analyses` for details. .. _`Higgs coupling`: **Higgs coupling** This collects a number of settings concerning the effective coupling of the Higgs boson to gluons. This is only relevant for the production process of a Higgs boson with jets and only supported if HEJ 2 was compiled with `QCDLoop <https://github.com/scarrazza/qcdloop>`_ support. .. _`Higgs coupling: use impact factors`: **use impact factors** Whether to use impact factors for the coupling to the most forward and most backward partons. Impact factors imply the infinite top-quark mass limit. .. _`Higgs coupling: mt`: **mt** The value of the top-quark mass in GeV. If this is not specified, the limit of an infinite mass is taken. .. _`Higgs coupling: include bottom`: **include bottom** Whether to include the Higgs coupling to bottom quarks. .. _`Higgs coupling: mb`: **mb** The value of the bottom-quark mass in GeV. Only used for the Higgs coupling, external bottom-quarks are always assumed to be massless. Advanced Settings ~~~~~~~~~~~~~~~~~ All of the following settings are optional. Please **do not set** any of the following options, unless you know exactly what you are doing. The default behaviour gives the most reliable results for a wide range of observables. .. _`regulator parameter`: **regulator parameter** - Slicing parameter to regularise the subtraction term, see :math:`\lambda` + Slicing parameter to regularise the subtraction term, called :math:`\lambda` in `arxiv:1706.01002 <https://arxiv.org/abs/1706.01002>`_. Default is 0.2 diff --git a/src/Ranlux64.cc b/src/Ranlux64.cc index ea67bb6..ded4e1c 100644 --- a/src/Ranlux64.cc +++ b/src/Ranlux64.cc @@ -1,61 +1,61 @@ /** * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019 * \copyright GPLv2 or later */ #include "HEJ/Ranlux64.hh" +#include <iostream> #include <cstdio> +#include <cstdlib> +#include <filesystem> namespace HEJ { namespace { //! create Ranlux64Engine with state read from the given file CLHEP::Ranlux64Engine make_Ranlux64Engine(std::string const & seed_file) { CLHEP::Ranlux64Engine result; result.restoreStatus(seed_file.c_str()); return result; } CLHEP::Ranlux64Engine make_Ranlux64Engine() { /* * some (all?) of the Ranlux64Engine constructors leave fields * uninitialised, invoking undefined behaviour. This can be * circumvented by restoring the state from a file */ static const std::string state = "9876\n" "0.91280703978419097666\n" "0.41606065829518357191\n" "0.99156342622341142601\n" "0.030922955274050423213\n" "0.16206278421638486975\n" "0.76151768001958330956\n" "0.43765760066092695979\n" "0.42904698253748563275\n" "0.11476317525663759511\n" "0.026620053590963976831\n" "0.65953715764414511114\n" "0.30136722624439826745\n" "3.5527136788005009294e-15 4\n" "1 202\n"; - const std::string file = std::tmpnam(nullptr); - { - std::ofstream out{file}; - out << state; - } - auto result = make_Ranlux64Engine(file); - std::remove(file.c_str()); + + std::FILE* tmpf = std::tmpfile(); + std::fputs(state.c_str(),tmpf); + auto result = make_Ranlux64Engine("/proc/self/fd/"+std::to_string(fileno(tmpf))); return result; } } Ranlux64::Ranlux64(): ran_{make_Ranlux64Engine()} {} Ranlux64::Ranlux64(std::string const & seed_file): ran_{make_Ranlux64Engine(seed_file)} {} double Ranlux64::flat() { return ran_.flat(); } }