diff --git a/Generators/Herwig7_i/CMakeLists.txt b/Generators/Herwig7_i/CMakeLists.txt index 67b331b50ce8d915ce35cdc2317daaf241d7b81d..8616fea38e78c686784eb1fec81d06a4743e5f11 100644 --- a/Generators/Herwig7_i/CMakeLists.txt +++ b/Generators/Herwig7_i/CMakeLists.txt @@ -3,10 +3,6 @@ # Package: Herwig7_i ################################################################################ -if( CMAKE_COMPILER_IS_GNUCXX AND ( NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 7.0 ) ) - return() -endif() - # Declare the package name: atlas_subdir( Herwig7_i ) @@ -19,11 +15,19 @@ atlas_depends_on_subdirs( GaudiKernel Tools/PathResolver ) +#set( THEPEG_LCGVERSION 2.1.4 ) +#set( THEPEG_LCGROOT +# /cvmfs/sft.cern.ch/lcg/releases/LCG_94/MCGenerators/thepeg/${THEPEG_LCGVERSION}/${LCG_PLATFORM}/ ) +# +#set( HERWIG3_LCGVERSION 7.1.4 ) +#set( HERWIG3_LCGROOT +# /cvmfs/sft.cern.ch/lcg/releases/LCG_94/MCGenerators/herwig++/${HERWIG3_LCGVERSION}/${LCG_PLATFORM}/ ) + # External dependencies: find_package( Boost ) find_package( Herwig3 ) -find_package( GSL ) find_package( ThePEG ) +find_package( GSL ) # Remove the --as-needed linker flags: atlas_disable_as_needed() @@ -31,12 +35,16 @@ atlas_disable_as_needed() # Component(s) in the package: atlas_add_component( Herwig7_i Herwig7_i/*.h src/*.cxx src/components/*.cxx - INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${GSL_INCLUDE_DIRS} ${HERWIG3_INCLUDE_DIRS} - ${THEPEG_INCLUDE_DIRS} + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${HERWIG3_INCLUDE_DIRS} + ${THEPEG_INCLUDE_DIRS} ${GSL_INCLUDE_DIRS} PRIVATE_DEFINITIONS -DHWVERSION=\"${HERWIG7_VERSION}\" - LINK_LIBRARIES ${Boost_LIBRARIES} ${GSL_LIBRARIES} ${HERWIG7_LIBRARIES} ${THEPEG_LIBRARIES} + LINK_LIBRARIES ${HERWIG3_LCGROOT}/lib/Herwig/libHerwigAPI.so ${Boost_LIBRARIES} ${HERWIG7_LIBRARIES} ${THEPEG_LIBRARIES} ${GSL_LIBRARIES} GeneratorModulesLib EventInfo GaudiKernel PathResolver ) # Install files from the package: atlas_install_python_modules( python/*.py ) atlas_install_joboptions( share/*.py ) + +set( Herwig7Environment_DIR ${CMAKE_CURRENT_SOURCE_DIR} + CACHE PATH "Location of HerwigppEnvironment.cmake" ) +find_package( Herwig7Environment ) diff --git a/Generators/Herwig7_i/Herwig7EnvironmentConfig.cmake b/Generators/Herwig7_i/Herwig7EnvironmentConfig.cmake new file mode 100644 index 0000000000000000000000000000000000000000..e493c244488fb2c022e7ed295d2c7ba2da0e5a17 --- /dev/null +++ b/Generators/Herwig7_i/Herwig7EnvironmentConfig.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +# +# This module is used to set up the environment for Herwig7 +# +# + +# Set the environment variable(s): +find_package( Herwig3 ) +find_package ( ThePEG ) + +if( HERWIG3_FOUND AND THEPEG_FOUND ) + get_filename_component( _herwig3Path "${HERWIG3_LCGROOT}" DIRECTORY ) + set( HERWIG7ENVIRONMENT_ENVIRONMENT + FORCESET HERWIG7_PATH ${_herwig3Path}/${LCG_PLATFORM} + FORCESET HERWIG7VER ${HERWIG3_LCGVERSION} + FORCESET THEPEGVER ${THEPEG_LCGVERSION}) + unset( _herwig3Path ) +endif() + +# Silently declare the module found: +set( HERWIG7ENVIRONMENT_FOUND TRUE ) + diff --git a/Generators/Herwig7_i/Herwig7_i/Herwig7.h b/Generators/Herwig7_i/Herwig7_i/Herwig7.h index da874d309527d240f80c386e20f9322a933c7b5a..ed0d49dde6613b0b8367fdec5958e8596eb4663b 100644 --- a/Generators/Herwig7_i/Herwig7_i/Herwig7.h +++ b/Generators/Herwig7_i/Herwig7_i/Herwig7.h @@ -1,12 +1,7 @@ // -*- C++ -*- -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - - /*! \file Herwig7.h - * \brief Athena interface for the Herwig 7 generator + * \brief Athena interface for the %Herwig7 generator * \author Daniel Rauch (daniel.rauch@desy.de) */ @@ -15,11 +10,125 @@ #include "GeneratorModules/GenModule.h" +#include "ThePEG/Repository/Repository.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/EventRecord/Event.h" +#include "Herwig/API/HerwigUI.h" + + +/// Interface to the %Herwig7 API +class Herwig7API : public Herwig::HerwigUI { + +public: + + /// Constructor + Herwig7API(){}; + // ATH_MSG_DEBUG("HERWIG7_PATH is "+getenv("HERWIG7_PATH")); + // ThePEG::Repository::load(getenv("HERWIG7_PATH")+"/share/Herwig/HerwigDefaults.rpo"); + // }; + + /// Destructor + ~Herwig7API(){}; + + + /// Requested Herwig run mode + Herwig::RunMode::Mode runMode() const { return(m_runMode); } + + /// Try to resume execution from an earlier interrupted run. + virtual bool resume() const { return(m_resume); } + + /// Require verbose progress markers + virtual bool tics() const { return(m_tics); } + + + /// Repository name to operate on + virtual std::string repository() const { return(m_repository); } + + /// Name of the file to be read + virtual std::string inputfile() const { return(m_inputfile); } + void inputfile(const std::string inputfile) { m_inputfile = inputfile; } + + /// Name of the setup file to be read, to modify the repository + virtual std::string setupfile() const { return(m_setupfile); } + + /// A user-defined tag to append to the run name. + virtual std::string tag() const { return(m_tag); } + + /// An identifier for the integration job to be handled + virtual std::string integrationList() const { return(m_integrationList); } + + + /// Directories from which Herwig reads input files, will be prepended to the search path. + virtual const std::vector<std::string> & prependReadDirectories() const { return(m_prependReadDirectories); } + + /// Directories from which Herwig reads input files, will be appended to the search path. + virtual const std::vector<std::string> & appendReadDirectories() const { return(m_appendReadDirectories); } + + + virtual long N() const { return(m_N); } /// The number of events to generate + + virtual int seed() const { return(m_seed); } /// The seed to use + void seed(int seed) { m_seed = seed; } + + virtual int jobs() const { return(m_jobs); } /// The number of jobs to fork + virtual unsigned int jobSize() const { return(m_jobsize); } /// The number of subprocesses to integrate per integratoin job + virtual unsigned int maxJobs() const { return(m_maxjobs); } /// The maximum number of integration jobs + + /// Bail out and print usage information + virtual void quitWithHelp() const { + std::cerr << "=================================\n"; + std::cerr << "HERE I CAN PUT SOME ERROR MESSAGE\n"; + std::cerr << "=================================\n"; + ThePEG::Repository::cleanup(); + exit( EXIT_FAILURE ); + } + + /// Bail out and be quiet + virtual void quit() const { + ThePEG::Repository::cleanup(); + exit( EXIT_FAILURE ); + } + + /// Return the standard out stream to be used + virtual std::ostream& outStream() const { return(std::cout); } + + /// Return the standard err stream to be used + virtual std::ostream& errStream() const { return(std::cerr); } + + /// Return the standard in stream to be used + virtual std::istream& inStream() const { return(std::cin); } + + +private: + + Herwig::RunMode::Mode m_runMode; + + bool m_resume; + bool m_tics; + + std::string m_repository; + std::string m_inputfile; + std::string m_setupfile; + std::string m_tag; + + std::string m_integrationList; + + std::vector<std::string> m_prependReadDirectories; + std::vector<std::string> m_appendReadDirectories; + + long m_N; + int m_seed; + int m_jobs; + unsigned int m_jobsize; + unsigned int m_maxjobs; + +}; + +/// Interface to athena class Herwig7 : public GenModule { + public: /// Constructor. @@ -37,40 +146,55 @@ public: /// Close down the generator. StatusCode genFinalize(); + private: - /// @name Properties - //@{ + /// Herwig7 API object + Herwig7API m_api; + + /// ThePEG generator object. + ThePEG::EGPtr m_gen; - /// Typedef to hold Herwig repository commands - typedef std::vector<std::string> CommandVector; + /// ThePEG event object. + ThePEG::EventPtr m_event; - /// Commands to set up Herwig from jobOptions. - CommandVector m_herwigCommandVector; + + /// @name Properties + //@{ /// Run name, used in the Herwig/ThePEG config system. std::string m_runname; - /// File to dump an equivalent Herwig .in file to, if specified. - std::string m_infiledump; + /// Name of run file + std::string m_runfile; + + /// Name of setup file + std::string m_setupfile; + + + /// Ignore random number seed provided by athena and use the one from Generate_tf.py instead + bool m_use_seed_from_generatetf; + + /// Random number seed from Generate_tf.py + int m_seed_from_generatetf; /// ME PDF name, stored for AMI capture at finalize. std::string m_pdfname_me; - /// PS and MPI PDF name, stored for AMI capture at finalize. + /// PS PDF name, stored for AMI capture at finalize. + // std::string m_pdfname_ps; + + /// MPI PDF name, stored for AMI capture at finalize. std::string m_pdfname_mpi; + /// Possibly remove Herwig-scratch folder after finishing the event generation + bool m_cleanup_herwig_scratch; + /// Scale integrated cross section by a factor for MetaData output double m_xsscale; //@} - /// ThePEG generator object. - ThePEG::EGPtr m_hw; - - /// ThePEG event object. - ThePEG::EventPtr m_event; - }; #endif diff --git a/Generators/Herwig7_i/cmt/requirements b/Generators/Herwig7_i/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..945ffb12946435f559a425a0a821cc2b99ef52db --- /dev/null +++ b/Generators/Herwig7_i/cmt/requirements @@ -0,0 +1,40 @@ +package Herwig7_i + +author Daniel Rauch <daniel.rauch@desy.de> + +use AtlasPolicy AtlasPolicy-* +use GeneratorModules GeneratorModules-* Generators +use ThePEG ThePEG-* External + +private +use GaudiInterface GaudiInterface-* External +use Herwig7 Herwig7-* External +use AtlasBoost AtlasBoost-* External +use EventInfo EventInfo-* Event +use PathResolver PathResolver-* Tools +end_private + +library Herwig7_i *.cxx -s=components *.cxx +apply_pattern component_library + +# Add the macro definitions for cmake (transparent to CMT) +apply_pattern cmake_add_command command='add_definitions(-DHWVERSION=\"${HERWIG7_VERSION}\")' + +macro Herwig7_i_linkopts "$(Herwig7_linkopts) " +macro_append Herwig7_i_pp_cppflags '-DHWVERSION=\"$(Herwig7_version)\" ' +macro_append Herwig7_i_pp_cppflags '-DHWREPODIR=\"$(Herwig7_repodir)\" ' +macro_append Herwig7_i_pp_cppflags '-DHWMODULEDIR=\"$(Herwig7_moduledir)\" ' +macro_append Herwig7_i_pp_cppflags '-DTHEPEGMODULEDIR=\"$(ThePEG_moduledir)\" ' +#macro_append Herwig7_i_pp_cppflags '-DLCGTAG=\"$(LCG_ext_system)\" ' +#macro_append Herwig7_i_pp_cppflags "-pedantic-errors" + +## This cryptic instruction seems to have the effect of making the NEEDED +## sections in the built library behave properly rather than whatever broken +## thing CMT does by default! Yuck! +private +apply_tag notAsNeeded +end_private + +# Install files from the package: +apply_pattern declare_joboptions files="*.py" +apply_pattern declare_python_modules files="*.py" diff --git a/Generators/Herwig7_i/doc/mainpage.h b/Generators/Herwig7_i/doc/mainpage.h new file mode 100644 index 0000000000000000000000000000000000000000..2fbd8280a7597e790dbbebe53ba97786c83c613f --- /dev/null +++ b/Generators/Herwig7_i/doc/mainpage.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** +@mainpage Herwig7_i + +@section Herwig7ForATLAS Herwig 7 for ATLAS + +Herwig 7 is a general-purpose event generator written in C++. +It provides a significant amount of improvements and new features with respect +to its predecessor Herwig++ 2.X while at the same time featuring also all of +the physics capabilities that (Fortran) HERWIG did. In this sense it is meant +to succede both previous members of the Herwig generator family. + +More information, including documentation and detailed tutorials, as well as +the source code of the generator are available on the project's page at +https://herwig.hepforge.org/ + +For more information on Herwig 7 in ATLAS please refer to the TWiki pages at +https://twiki.cern.ch/twiki/bin/view/AtlasProtected/Herwig7ForAtlas + + +@subsection AthenaInterface The Interface between Herwig7 and Athena + +Herwig 7 can be used in the same way as the Herwig++ 2.X series, in particular +it is capable of showering MadGraph5_aMC@NLO and PowhegBox events. + +Apart from these 'legacy' run modes, the *Matchbox* module in Herwig 7 provides +automated LO and NLO hard process generation and two alternative internal +matching strategies, called 'subtractive' (MCatNLO-like) and 'multiplicative' +(Powheg-like) matching, to both the default, angular-ordered (q-tilde) parton +shower and the dipole shower. Integration of these new features in the interface +is still ongoing and will need to be validated afterwards. + +\note Currently, showering of Alpgen inputs is deprecated and was removed from +the interface since it would require a significant amount of validation. In case +your are interested in this, please let us know. + + +@subsection TableOfContents Contents of this Documentation + +- @ref Links +- @ref FAQ +- @ref MC15JobOptions + +*/ diff --git a/Generators/Herwig7_i/python/Herwig7Config.py b/Generators/Herwig7_i/python/Herwig7Config.py index dfe97b65eaf81e7772622b4174f8560b6a42094f..58905a9246f593f8ca91c7f0e4bf9a5307292af3 100644 --- a/Generators/Herwig7_i/python/Herwig7Config.py +++ b/Generators/Herwig7_i/python/Herwig7Config.py @@ -11,6 +11,7 @@ class Hw7Config(object): ## Constructor def __init__(self, genSeq, runArgs, run_name="Herwig"): + self.genSeq = genSeq self.runArgs = runArgs @@ -44,6 +45,12 @@ set /Herwig/Shower/GammatoQQbarSplitFn:AngularOrdered Yes ## fix for GeV-mass photon radiation until released with Herwig7 itself set /Herwig/Shower/GammatoQQbarSudakov:Alpha /Herwig/Shower/AlphaQED +## fix for initial-state (backward evolution) splitting (AGENE-1384) +set /Herwig/Shower/QtoGammaQSudakov:Alpha /Herwig/Shower/AlphaQED + +## fix for QED lepton radiation scale (ATLMCPROD-5138) +set /Herwig/Shower/LtoLGammaSudakov:pTmin 0.000001 + ## ensure JetFinder uses AntiKt with R=0.4 set /Herwig/Cuts/JetFinder:Variant AntiKt set /Herwig/Cuts/JetFinder:ConeRadius 0.4 @@ -64,6 +71,32 @@ set /Herwig/Cuts/JetFinder:ConeRadius 0.4 set /Herwig/Random:Seed {} """.format(self.runArgs.randomSeed)) + ## Commands specific to certain beam / collision types + def beam_commands(self): + + if self.beams == "EE": + return(""" +## Commands for lepton-lepton collisions +read snippets/EECollider.in +set /Herwig/Shower/PartnerFinder:QEDPartner IIandFF +set /Herwig/Shower/ShowerHandler:MPIHandler NULL +set /Herwig/DipoleShower/DipoleShowerHandler:MPIHandler NULL +set /Herwig/Shower/PowhegShowerHandler:MPIHandler NULL +""") + elif self.beams == "EP": + return(""" +## Commands for proton-lepton collisions +read snippets/EPCollider.in +do /Herwig/Shower/SplittingGenerator:DeleteFinalSplitting e-->e-,gamma; /Herwig/Shower/LtoLGammaSudakov +do /Herwig/Shower/SplittingGenerator:DeleteFinalSplitting mu-->mu-,gamma; /Herwig/Shower/LtoLGammaSudakov +do /Herwig/Shower/SplittingGenerator:DeleteFinalSplitting tau-->tau-,gamma; /Herwig/Shower/LtoLGammaSudakov +set /Herwig/Shower/KinematicsReconstructor:ReconstructionOption Colour +""") + else: + return(""" +## Commands for proton-proton collisions +read snippets/PPCollider.in +""") ## Sets center-of-mass energy sqrts(s) in GeV ## @@ -80,8 +113,8 @@ set /Herwig/Random:Seed {} return(""" ## Center-of-mass energy -set /Herwig/Generators/{}:EventHandler:LuminosityFunction:Energy {} -""".format(self.event_generator, self.runArgs.ecmEnergy)) +set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy {} +""".format(self.runArgs.ecmEnergy)) ## Sets printout verbosity and error tolerance @@ -91,15 +124,15 @@ set /Herwig/Generators/{}:EventHandler:LuminosityFunction:Energy {} return(""" ## Verbosity and printout settings -set /Herwig/Generators/{0}:DebugLevel 1 -set /Herwig/Generators/{0}:PrintEvent 2 -set /Herwig/Generators/{0}:UseStdout Yes -set /Herwig/Generators/{0}:NumberOfEvents 1000000000 -set /Herwig/Generators/{0}:MaxErrors 1000000 +set /Herwig/Generators/EventGenerator:DebugLevel 1 +set /Herwig/Generators/EventGenerator:PrintEvent 2 +set /Herwig/Generators/EventGenerator:UseStdout Yes +set /Herwig/Generators/EventGenerator:NumberOfEvents 1000000000 +set /Herwig/Generators/EventGenerator:MaxErrors 1000000 ## Make sampler print out cross sections for each subprocess -set /Herwig/Samplers/Sampler:Verbose On -""".format(self.event_generator)) +set /Herwig/Samplers/Sampler:Verbose Yes +""") ## ATLAS MC15 default parameters for particle masses and widths and Weinberg angle @@ -187,8 +220,8 @@ set /Herwig/Partons/Hard{0}PDF:MaxFlav {3} set /Herwig/Partons/Hard{0}PDF:RemnantHandler /Herwig/Partons/HadronRemnants set /Herwig/Particles/p+:PDF /Herwig/Partons/Hard{0}PDF set /Herwig/Particles/pbar-:PDF /Herwig/Partons/Hard{0}PDF -set /Herwig/Partons/QCDExtractor:FirstPDF /Herwig/Partons/Hard{0}PDF -set /Herwig/Partons/QCDExtractor:SecondPDF /Herwig/Partons/Hard{0}PDF +set /Herwig/Partons/PPExtractor:FirstPDF /Herwig/Partons/Hard{0}PDF +set /Herwig/Partons/PPExtractor:SecondPDF /Herwig/Partons/Hard{0}PDF """.format(order, name, member, max_flav) @@ -332,8 +365,8 @@ set /Herwig/Partons/RemnantPDF:MaxFlav {} def get_dpdf_path(self): import os - cmt_path = os.environ.get("CMTPATH") - cmt_dir = os.environ.get("CMTCONFIG") + cmt_path = os.environ.get("CMAKE_PREFIX_PATH") + cmt_dir = os.environ.get("BINARY_TAG") cmtPaths = cmt_path.split(':') @@ -365,15 +398,15 @@ set /Herwig/Partons/RemnantPDF:MaxFlav {} set /Herwig/Particles/pomeron:PDF /Herwig/Partons/PomeronPDF # Technical parameters for this run -set /Herwig/Generators/LHCGenerator:EventHandler:Sampler:Ntry 100000 -set /Herwig/Generators/LHCGenerator:MaxErrors 100000 +set /Herwig/Generators/EventGenerator:EventHandler:Sampler:Ntry 100000 +set /Herwig/Generators/EventGenerator:MaxErrors 100000 # MPI doesn't work # TODO: Is this a problem? -set /Herwig/Generators/LHCGenerator:EventHandler:CascadeHandler:MPIHandler NULL +set /Herwig/Generators/EventGenerator:EventHandler:CascadeHandler:MPIHandler NULL # Choice of phase-space generation for PDFs -set /Herwig/Partons/QCDExtractor:FlatSHatY 0 +set /Herwig/Partons/PPExtractor:FlatSHatY 0 """ return cmds @@ -386,10 +419,10 @@ set /Herwig/Partons/QCDExtractor:FlatSHatY 0 return """ # Technical parameters for this run -set /Herwig/Generators/LHCGenerator:EventHandler:Sampler:Ntry 100000 +set /Herwig/Generators/EventGenerator:EventHandler:Sampler:Ntry 100000 # Choice of phase-space generation for PDFs -set /Herwig/Partons/QCDExtractor:FlatSHatY 0 +set /Herwig/Partons/PPExtractor:FlatSHatY 0 # Change the proton PDFs to those for photon radiation set /Herwig/Particles/p+:PDF /Herwig/Partons/BudnevPDF @@ -397,6 +430,6 @@ set /Herwig/Particles/pbar-:PDF /Herwig/Partons/BudnevPDF # MPI doesn't work # TODO: Is this a problem? -set /Herwig/Generators/LHCGenerator:EventHandler:CascadeHandler:MPIHandler NULL +set /Herwig/Generators/EventGenerator:EventHandler:CascadeHandler:MPIHandler NULL """ diff --git a/Generators/Herwig7_i/python/Herwig7ConfigBuiltinME.py b/Generators/Herwig7_i/python/Herwig7ConfigBuiltinME.py index 1a3dab529c64791c5bbe8b58d552cc5cd016cb47..eb0942b173ccc5d177c01bcef4636c9b9d25f9e1 100644 --- a/Generators/Herwig7_i/python/Herwig7ConfigBuiltinME.py +++ b/Generators/Herwig7_i/python/Herwig7ConfigBuiltinME.py @@ -16,12 +16,16 @@ import Herwig7Utils as hw7Utils class Hw7ConfigBuiltinME(hw7Config.Hw7Config): - def __init__(self, genSeq, runArgs, run_name="Herwig"): + def __init__(self, genSeq, runArgs, run_name="Herwig", beams="pp"): + + beams = beams.upper() + if not beams in ["EE", "EP" , "PP"]: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'beams' must be one of the following: ['EE', 'EP' , 'PP']")) ## provide variables initialized by the parent class super(Hw7ConfigBuiltinME, self).__init__(genSeq, runArgs, run_name) - self.event_generator = "LHCGenerator" + self.beams = beams def local_pre_commands(self): @@ -41,7 +45,7 @@ class Hw7ConfigBuiltinME(hw7Config.Hw7Config): ## Local Post-Commands from Herwig7ConfigBuiltinME.py ## ================================================== -saverun {} /Herwig/Generators/LHCGenerator +saverun {} /Herwig/Generators/EventGenerator """.format(self.run_name) @@ -54,6 +58,7 @@ saverun {} /Herwig/Generators/LHCGenerator ## add default settings if they were not overwritten in the JobOptions + self.default_commands += self.beam_commands() self.default_commands += self.energy_commands() self.default_commands += self.random_seed_commands() @@ -72,5 +77,5 @@ saverun {} /Herwig/Generators/LHCGenerator def powheg_commands(): return """ ## Set up Powheg truncated shower -set /Herwig/Shower/Evolver:HardEmissionMode POWHEG +set /Herwig/Shower/ShowerHandler:HardEmission POWHEG """ diff --git a/Generators/Herwig7_i/python/Herwig7ConfigFxFx.py b/Generators/Herwig7_i/python/Herwig7ConfigFxFx.py new file mode 100644 index 0000000000000000000000000000000000000000..c85bf5ffc6b5b4671d5b2732dd77d40266edd38f --- /dev/null +++ b/Generators/Herwig7_i/python/Herwig7ConfigFxFx.py @@ -0,0 +1,244 @@ +#! /usr/bin/env python + +## \file Herwig7ConfigFxFx.py +## \brief Configuration class for showering FxFx-merged LHE files from MG5_aMC@NLO +## \author Krishna Kulkarni (krishna.kulkarni@cern.ch) +## \author Daniel Rauch (daniel.rauch@desy.de) +## +## \warning Only use this for testing/debugging purposes. +## This run mode is neither fully implemented nor validated or supported yet. + +import Herwig7Config as hw7Config +import Herwig7Control as hw7Control +import Herwig7Utils as hw7Utils + +from AthenaCommon import Logging +athMsgLog = Logging.logging.getLogger('Herwig7Control') + + +## Configuration class for showering FxFx-merged LHE files from MG5_aMC@NLO +## +## \warning Only use this for testing/debugging purposes. +## This run mode is neither fully implemented nor validated or supported yet. +class Hw7ConfigFxFx(hw7Config.Hw7Config): + + + def __init__(self, genSeq, runArgs, run_name="Herwig", beams="pp"): + + beams = beams.upper() + if not beams in ["EE", "EP" , "PP"]: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'beams' must be one of the following: ['EE', 'EP' , 'PP']")) + + # provide variables initialized by the parent class + super(Hw7ConfigFxFx, self).__init__(genSeq, runArgs, run_name) + + self.beams = beams + + self.set_fxfx_commands = False + + + def local_pre_commands(self): + + return """ +## ============================================ +## Local Pre-Commands from Herwig7ConfigFxFx.py +## ============================================ + +# > no local pre-commands at the moment +""" + + + def local_post_commands(self): + + return """ +## ============================================= +## Local Post-Commands from Herwig7ConfigFxFx.py +## ============================================= + +saverun {} /Herwig/Generators/EventGenerator +""".format(self.run_name) + + + + ## High-level function for triggering the process setup and the event generation. + ## + ## \warning Please do not modify the generator configuration in the job options after calling the `run()` function as + ## the modified settings would not be applied in the event generation + ## + def run(self): + + # add default settings if they were not overwritten in the JobOptions + + self.default_commands += self.beam_commands() + self.default_commands += self.random_seed_commands() + + if not self.set_printout_commands: + self.default_commands += self.printout_commands() + if not self.set_physics_parameter_commands: + self.default_commands += self.physics_parameter_commands() + if not self.set_technical_parameter_commands: + self.default_commands += self.technical_parameter_commands() + + # check for configuration errors + + if not self.set_fxfx_commands: + raise RuntimeError(hw7Utils.ansi_format_error("Please use 'fxfx_commands()' in the JobOptions!")) + + # exit with error message since this run mode is not yet to be used + # raise RuntimeError(hw7Utils.ansi_format_error("Please don't run FxFx event generation as the interface for the FxFx run mode is neither fully implemented nor validated or supported yet")) + + # do read and run step in one go + hw7Control.run(self) + + + ## Sets up reading of events from an LHE file + ## + ## \todo Settings which are not FxFx-specific should be identical to the LHEF showering of MG5_aMC@NLO events. + ## This should probably be enforced in some way + ## + ## \param[in] merging_scale Merging scale in units of GeV + ## \param[in] njets_max Number of (Born-level) light jets in maximum-multiplicity FxFx process + ## \param[in] me_pdf_order Order of the PDF set to be used + ## \param[in] r_clus Jet radius used in clustering in the merging + ## \param[in] eta_clus_max Max |eta| for jets in clustering in the merging + ## (should match the range used for jets in the hard process generation, which should normally be unrestricted + ## \param[in] usespin Use the spin of tau leptons from the LHE file (spins of other particles are ignored anyways) + ## + ## \todo Remove ihrd and ihvy parameters beginning with Herwig 7.1.0 since the hard process will be deduced automatically + def fxfx_commands(self, + merging_scale, + njets_max, + lhe_filename = "events.lhe", + me_pdf_order = "NLO", + r_clus = 1.0, + eta_clus_max = 15.0, + usespin = True, + automatic_process_detection = True, + ihrd = None, + ihvy = None): + + if not me_pdf_order in ["LO", "NLO"]: + raise RuntimeError(hw7Utils.ansi_format_error("Herwig7ConfigLHEF.py:__lhef_commands: Parameter 'me_pdf_order' must either be 'LO' or 'NLO'!")) + + self.set_fxfx_commands = True + + process_selection = "" + if not automatic_process_detection: + process_selection = """ +## The ihrd and ihvy parameters are Alpgen parameters to identify the hard process +set /Herwig/Shower/FxFxShowerHandler:ihrd {} +set /Herwig/Shower/FxFxShowerHandler:ihvy {} +""".format(ihrd, ihvy) + + self.commands += """ +## ---------------------------- +## Read in Events from LHE File +## ---------------------------- + +#library LesHouches.so +#create ThePEG::LesHouchesFileReader /Herwig/EventHandlers/LHEReader + + +## Create the Handler and Reader +library FxFx.so +create Herwig::FxFxEventHandler /Herwig/EventHandlers/FxFxLHEHandler +create Herwig::FxFxFileReader /Herwig/EventHandlers/FxFxLHEReader + +library FxFxHandler.so +create Herwig::FxFxHandler /Herwig/Shower/FxFxShowerHandler +set /Herwig/Shower/FxFxShowerHandler:ShowerModel /Herwig/Shower/ShowerModel +set /Herwig/Shower/FxFxShowerHandler:SplittingGenerator /Herwig/Shower/SplittingGenerator + + +## Set up the LHE reader +set /Herwig/EventHandlers/FxFxLHEReader:WeightWarnings false +set /Herwig/EventHandlers/FxFxLHEReader:FileName {FileName} +set /Herwig/EventHandlers/FxFxLHEReader:MomentumTreatment RescaleEnergy +# set /Herwig/EventHandlers/FxFxLHEReader:IgnoreIDPRUP Yes + +# Don't use any cuts on LHE files +create ThePEG::Cuts /Herwig/Cuts/NoCuts +set /Herwig/EventHandlers/FxFxLHEReader:Cuts /Herwig/Cuts/NoCuts + + + +insert /Herwig/EventHandlers/FxFxLHEHandler:FxFxReaders 0 /Herwig/EventHandlers/FxFxLHEReader +set /Herwig/EventHandlers/FxFxLHEHandler:PartonExtractor /Herwig/Partons/PPExtractor +set /Herwig/EventHandlers/FxFxLHEHandler:CascadeHandler /Herwig/Shower/FxFxShowerHandler +set /Herwig/EventHandlers/FxFxLHEHandler:HadronizationHandler /Herwig/Hadronization/ClusterHadHandler +set /Herwig/EventHandlers/FxFxLHEHandler:DecayHandler /Herwig/Decays/DecayHandler + +set /Herwig/EventHandlers/FxFxLHEHandler:WeightOption VarNegWeight + + +## MC@NLO settings + +#set /Herwig/Shower/KinematicsReconstructor:ReconstructionOption General +#set /Herwig/Shower/KinematicsReconstructor:InitialInitialBoostOption LongTransBoost +#set /Herwig/Shower/KinematicsReconstructor:FinalStateReconOption Default +#set /Herwig/Shower/KinematicsReconstructor:InitialStateReconOption Rapidity +set /Herwig/Shower/ShowerHandler:MaxPtIsMuF Yes +set /Herwig/Shower/ShowerHandler:RestrictPhasespace Yes +#set /Herwig/Shower/ShowerHandler:ReconstructionOption OffShell4 + +set /Herwig/Shower/PartnerFinder:PartnerMethod Random +set /Herwig/Shower/PartnerFinder:ScaleChoice Partner +set /Herwig/Shower/ShowerHandler:SpinCorrelations No + +set /Herwig/Shower/ShowerHandler:MaxTry 100 + + +## Set up the FxFxShowerHandler + +set /Herwig/Shower/FxFxShowerHandler:MPIHandler /Herwig/UnderlyingEvent/MPIHandler +set /Herwig/Shower/FxFxShowerHandler:RemDecayer /Herwig/Partons/RemnantDecayer +set /Herwig/Shower/FxFxShowerHandler:ShowerAlpha /Herwig/Shower/AlphaQCD + +## Use the automatic process detection +set /Herwig/Shower/FxFxShowerHandler:HardProcessDetection {AutomaticProcessDetection}{ProcessSelection} + +# Number of (Born-level) light jets in maximum-multiplicity FxFx process +set /Herwig/Shower/FxFxShowerHandler:njetsmax {NjetsMax} # Make sure this is set correctly! + +# Mimimum parton-parton R-sep used for generation. +# (legacy from MLM merging, should stay fixed to zero in FxFx as this is NLO) +set /Herwig/Shower/FxFxShowerHandler:drjmin 0.0 + +## Recommended key MLM merging parameters below + +# turn the Vetoing On or Off completely +set /Herwig/Shower/FxFxShowerHandler:VetoIsTurnedOff VetoingIsOn +# merging scale +set /Herwig/Shower/FxFxShowerHandler:ETClus {MergingScale}*GeV +# jet radius used in clustering in merging. +set /Herwig/Shower/FxFxShowerHandler:RClus {RClus} +# factor to multiply RClus (if DR(parton,jet)<rclusfactor*rclus +# the parton and jet are said to have been matched) +set /Herwig/Shower/FxFxShowerHandler:RClusFactor 1.0 +# Max |eta| for jets in clustering in merging. +set /Herwig/Shower/FxFxShowerHandler:EtaClusMax {EtaClusMax} + +## Setup event handlers +set /Herwig/Generators/EventGenerator:EventHandler /Herwig/EventHandlers/FxFxLHEHandler + + +## UNSURE ABOUT THESE --------------------------------------------------------- + +# set /Herwig/EventHandlers/FxFxLHEReader:IncludeSpin {IncludeSpin} +# set /Herwig/EventHandlers/FxFxLHEReader:AllowedToReOpen No + +## Set the PDF for the LHE reader. +set /Herwig/EventHandlers/FxFxLHEReader:PDFA /Herwig/Partons/Hard{MEPDFOrder}PDF +set /Herwig/EventHandlers/FxFxLHEReader:PDFB /Herwig/Partons/Hard{MEPDFOrder}PDF +# The PDF for beam particles A/B - overrides particle's own PDF above +set /Herwig/Shower/FxFxShowerHandler:PDFA /Herwig/Partons/Hard{MEPDFOrder}PDF +set /Herwig/Shower/FxFxShowerHandler:PDFB /Herwig/Partons/Hard{MEPDFOrder}PDF +""".format(MergingScale = merging_scale, + NjetsMax = njets_max, + FileName = lhe_filename, + MEPDFOrder = me_pdf_order, + RClus = r_clus, + EtaClusMax = eta_clus_max, + IncludeSpin = "Yes" if usespin==True else "No", + AutomaticProcessDetection = "Automatic" if automatic_process_detection else "Manual", + ProcessSelection = process_selection) diff --git a/Generators/Herwig7_i/python/Herwig7ConfigGeneric.py b/Generators/Herwig7_i/python/Herwig7ConfigGeneric.py new file mode 100644 index 0000000000000000000000000000000000000000..ea7a388cc1dc7b585e334081d38a26a95e176108 --- /dev/null +++ b/Generators/Herwig7_i/python/Herwig7ConfigGeneric.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python + +## \file Herwig7ConfigGeneric.py +## \brief Python class for reproducing standalone runs inside of athena + +import Herwig7Control as hw7Control +import Herwig7Utils as hw7Utils + +## Configuration base class for %Herwig7 +class Hw7ConfigGeneric(object): + + ## Constructor + def __init__(self, genSeq, runArgs, infile_name=None, runfile_name=None): + + self.infile_name = infile_name + self.runfile_name = runfile_name + self.genSeq = genSeq + self.runArgs = runArgs + + + ## Do the read/run sequence and re-use an already existing infile. + ## + ## This function should provide the build, integrate, mergegrids and run step + ## in one go without creating a gridpack - just pure and direct event generation + def read_run(self): + + ## perform build/integrate/mergegrids sequence + hw7Control.do_read_existing_infile(self) + + ## start the event generation + hw7Control.do_run_existing_runfile(self) + + + def build_integrate_run(self, integration_jobs=1, gridpack=None, cleanup_herwig_scratch=True): + + raise RuntimeError("not yet implemented") + + + ## Just do the run step and re-use an already existing runfile. + def run(self): + + ## start the event generation + hw7Control.do_run_existing_runfile(self) diff --git a/Generators/Herwig7_i/python/Herwig7ConfigLHEF.py b/Generators/Herwig7_i/python/Herwig7ConfigLHEF.py new file mode 100644 index 0000000000000000000000000000000000000000..9fcb055a8bf52092cbafd4fa7deaee48d5fc0324 --- /dev/null +++ b/Generators/Herwig7_i/python/Herwig7ConfigLHEF.py @@ -0,0 +1,281 @@ +#! /usr/bin/env python + +## \file Herwig7ConfigLHEF.py +## \brief Configuration class for showering LHE files from MG5_aMC@NLO or PowhegBox +## \author Daniel Rauch (daniel.rauch@desy.de) + +import os + +import Herwig7Config as hw7Config +import Herwig7Control as hw7Control +import Herwig7Utils as hw7Utils + + +## Configuration class for showering LHE files from MG5_aMC@NLO or PowhegBox +## +## Example JobOptions are available in [`examples/LHEF`](https://svnweb.cern.ch/trac/atlasoff/browser/Generators/Herwig7_i/trunk/examples/LHEF) and [`tests/athenaLHEF/jobOptions`](https://svnweb.cern.ch/trac/atlasoff/browser/Generators/Herwig7_i/trunk/tests/athenaLHEF/jobOptions). +## +## +## Process Setup and Generator Configuration +## ========================================= +## +## The LHE files have to follow a specific naming scheme which is detailed +## [here](https://twiki.cern.ch/twiki/bin/view/AtlasProtected/PreparingLesHouchesEven). +## The name of the LHE file is added as the command line parameter `--inputGeneratorFile` +## to the `Generate_tf.py` command and can be accessed using the variable +## `runArgs.inputGeneratorFile` in the JobOptions where they can be passed to the +## functions [lhef_mg5amc_commands](\ref Herwig7ConfigLHEF::Hw7ConfigLHEF#lhef_mg5amc_commands) +## or [lhef_powhegbox_commands](\ref Herwig7ConfigLHEF::Hw7ConfigLHEF#lhef_powhegbox_commands) +## in order to communicate the LHE file names to %Herwig7, e.g. +## +## \code{.py} +## generator.lhef_mg5amc_commands(lhe_filename=runArgs.inputGeneratorFile, me_pdf_order="NLO") +## \endcode +## +## or +## +## \code{.py} +## generator.lhef_powhegbox_commands(lhe_filename=runArgs.inputGeneratorFile, me_pdf_order="NLO") +## \endcode +## +## +## Event Generation +## ================ +## +## To trigger the actual running of %Herwig7 in Athena please end the JobOptions with +## +## \code{.py} +## # run the generator +## generator.run() +## \endcode +## +## More specifically, the `run()` function triggers the creation of the %Herwig7 input +## file and the preparation of the run (i.e. the `Herwig read` step). +## This means, that no %Herwig7 settings should be modified after calling the +## `run()` function because the changed settings would not be applied during the +## event generation. +## +class Hw7ConfigLHEF(hw7Config.Hw7Config): + + + def __init__(self, genSeq, runArgs, run_name="Herwig", beams="pp"): + + beams = beams.upper() + if not beams in ["EE", "EP" , "PP"]: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'beams' must be one of the following: ['EE', 'EP' , 'PP']")) + + ## provide variables initialized by the parent class + super(Hw7ConfigLHEF, self).__init__(genSeq, runArgs, run_name) + + self.beams = beams + + self.set_lhef_mg5amc_commands = False + self.set_lhef_powhegbox_commands = False + + + def local_pre_commands(self): + + return """ +## ============================================ +## Local Pre-Commands from Herwig7ConfigLHEF.py +## ============================================ + +# > no local pre-commands at the moment +""" + + + def local_post_commands(self): + + return """ +## ============================================= +## Local Post-Commands from Herwig7ConfigLHEF.py +## ============================================= + +saverun {} /Herwig/Generators/EventGenerator +""".format(self.run_name) + + + + ## High-level function for triggering the process setup and the event generation. + ## + ## \warning Please do not modify the generator configuration in the job options after calling the `run()` function as + ## the modified settings would not be applied in the event generation + ## + def run(self): + + ## add default settings if they were not overwritten in the JobOptions + + self.default_commands += self.beam_commands() + self.default_commands += self.random_seed_commands() + + if not self.set_printout_commands: + self.default_commands += self.printout_commands() + if not self.set_physics_parameter_commands: + self.default_commands += self.physics_parameter_commands() + if not self.set_technical_parameter_commands: + self.default_commands += self.technical_parameter_commands() + + ## check for configuration errors + + if self.set_lhef_mg5amc_commands and self.set_lhef_powhegbox_commands: + raise RuntimeError(hw7Utils.ansi_format_error("Please do not use both 'lhef_mg5amc_commands()' and 'lhef_powhegbox_commands()' at the same time!")) + if not self.set_lhef_mg5amc_commands and not self.set_lhef_powhegbox_commands: + raise RuntimeError(hw7Utils.ansi_format_error("Please use either 'lhef_mg5amc_commands()' or 'lhef_powhegbox_commands()' in the JobOptions!")) + + ## do read and run step in one go + + hw7Control.run(self) + + + ## Sets up reading of events from an LHE file + ## + ## \param usespin Use the spin of tau leptons from the LHE file (spins of other particles are ignored anyways) + def __lhef_commands(self, lhe_filename="events.lhe", me_pdf_order="NLO", usespin=True): + + if not me_pdf_order in ["LO", "NLO"]: + raise RuntimeError(hw7Utils.ansi_format_error("Herwig7ConfigLHEF.py:__lhef_commands: Parameter 'me_pdf_order' must either be 'LO' or 'NLO'!")) + + if lhe_filename.endswith(".tar.gz"): # athena will decompress the LHE file for us + lhe_filename = lhe_filename.replace(".tar.gz", ".events") + if not os.path.isfile(lhe_filename): + raise RuntimeError(hw7Utils.ansi_format_error("Herwig7ConfigLHEF.py:__lhef_commands: Could not find decompressed LHE file '{}'!".format(lhe_filename))) + + momentum_treatment = "" + beam_commands = "" + if self.beams == "EE": + momentum_treatment = "Accept" + elif self.beams == "EP": + momentum_treatment = "RescaleEnergy" + beam_commands = """ +## Set the PDF for the LHE reader +# set /Herwig/EventHandlers/LHEReader:PDFA /Herwig/Partons/Hard{MEPDFOrder}PDF +""".format(MEPDFOrder = me_pdf_order) + elif self.beams == "PP": + momentum_treatment = "RescaleEnergy" + beam_commands = """ +## Set the PDF for the LHE reader +# set /Herwig/EventHandlers/LHEReader:PDFA /Herwig/Partons/Hard{MEPDFOrder}PDF +# set /Herwig/EventHandlers/LHEReader:PDFB /Herwig/Partons/Hard{MEPDFOrder}PDF +""".format(MEPDFOrder = me_pdf_order) + + self.commands += """ +## ---------------------------- +## Read in Events from LHE File +## ---------------------------- + +## Create the Handler and Reader +library LesHouches.so +create ThePEG::LesHouchesFileReader /Herwig/EventHandlers/LHEReader +create ThePEG::LesHouchesEventHandler /Herwig/EventHandlers/LHEHandler + +## Set LHE filename +set /Herwig/EventHandlers/LHEReader:FileName {FileName} + +## Setup LHE event handler and LHE reader +set /Herwig/Generators/EventGenerator:EventHandler /Herwig/EventHandlers/LHEHandler +insert /Herwig/EventHandlers/LHEHandler:LesHouchesReaders 0 /Herwig/EventHandlers/LHEReader +set /Herwig/EventHandlers/LHEHandler:PartonExtractor /Herwig/Partons/{Beams}Extractor +set /Herwig/EventHandlers/LHEHandler:CascadeHandler /Herwig/Shower/ShowerHandler +set /Herwig/EventHandlers/LHEHandler:HadronizationHandler /Herwig/Hadronization/ClusterHadHandler +set /Herwig/EventHandlers/LHEHandler:DecayHandler /Herwig/Decays/DecayHandler +set /Herwig/EventHandlers/LHEHandler:WeightNormalization CrossSection +set /Herwig/EventHandlers/LHEHandler:WeightOption VarNegWeight +set /Herwig/EventHandlers/LHEReader:IncludeSpin {IncludeSpin} +set /Herwig/EventHandlers/LHEReader:MomentumTreatment {MomentumTreatment} +set /Herwig/EventHandlers/LHEReader:AllowedToReOpen No + +## Parton shower settings +set /Herwig/Shower/ShowerHandler:MaxPtIsMuF Yes +set /Herwig/Shower/ShowerHandler:RestrictPhasespace Yes +# treatment of wide angle radiation +set /Herwig/Shower/PartnerFinder:PartnerMethod Random +set /Herwig/Shower/PartnerFinder:ScaleChoice Partner + +## Don't use any cuts on LHE files +create ThePEG::Cuts /Herwig/Cuts/NoCuts +set /Herwig/EventHandlers/LHEReader:Cuts /Herwig/Cuts/NoCuts + +{BeamCommands} +""".format(FileName = lhe_filename, + Beams = self.beams, + IncludeSpin = "Yes" if usespin==True else "No", + MomentumTreatment = momentum_treatment, + BeamCommands = beam_commands) + + + ## Commands specific to showering of events produced with MG5_aMC@NLO + ## + ## \param[in] lhe_filename name of the LHE file that is to be showered + ## \param[in] me_pdf_order order (either `LO` or `NLO`) of the matrix element PDF. + ## This has to be consistent with the PDF used in the + ## hard process generation and the PDF set with + ## generator.me_pdf_commands. + ## + ## The reason for these specific settings is that for MC@NLO-like matching schemes + ## the subtraction of the parton shower contribution in the hard process and the + ## parton shower settings have to be consistent in order to recover the + ## correct terms at the NLO. + ## + ## For showering of previously existing LHE files + ## + ## generator.lhef_powhegbox_commands(lhe_filename=runArgs.inputGeneratorFile) + ## + ## will work. + ## + def lhef_mg5amc_commands(self, lhe_filename="events.lhe", me_pdf_order="NLO", usespin=True): + + if not me_pdf_order in ["LO", "NLO"]: + raise RuntimeError(hw7Utils.ansi_format_error("Herwig7ConfigLHEF.py:lhef_mg5amc_commands: Parameter 'me_pdf_order' must either be 'LO' or 'NLO'!")) + + self.set_lhef_mg5amc_commands = True + + self.__lhef_commands(lhe_filename, me_pdf_order, usespin) + + self.commands += """ +## Commands specific to showering of events produced with MG5_aMC@NLO +set /Herwig/Shower/KinematicsReconstructor:ReconstructionOption General +set /Herwig/Shower/KinematicsReconstructor:InitialInitialBoostOption LongTransBoost +set /Herwig/Shower/KinematicsReconstructor:InitialStateReconOption Rapidity +set /Herwig/Shower/KinematicsReconstructor:FinalStateReconOption Default +set /Herwig/Shower/ShowerHandler:SpinCorrelations No +""" + + + ## Commands specific to showering of events produced with PowhegBox + ## + ## \param[in] lhe_filename name of the LHE file that is to be showered + ## \param[in] me_pdf_order order (either `LO` or `NLO`) of the matrix element PDF. + ## This has to be consistent with the PDF used in the + ## hard process generation and the PDF set with + ## generator.me_pdf_commands. + ## \param[in] usespin + ## + ## Specifying the LHE file name with + ## + ## generator.lhef_powhegbox_commands(lhe_filename=runArgs.inputGeneratorFile) + ## + ## should work both for showering existing LHE files as well as for on-the-fly (OTF) + ## running of PowhegBox and %Herwig7. + ## + ## Since for OTF running the LHE file generated by PowhegBox is usually + ## called `PowhegOTF._1.events` using + ## + ## generator.lhef_powhegbox_commands(lhe_filename="PowhegOTF._1.events") + ## + ## will normally also work in this case. If a different name for the LHE file + ## generated by PowhegBox is specified with the `--outputTXTFile` argument to + ## `Generate_tf.py` then `PowhegControl` will update the value of + ## `runArgs.inputGeneratorFile` accordingly and + ## + ## generator.lhef_powhegbox_commands(lhe_filename=runArgs.inputGeneratorFile) + ## + ## should still work. + ## + def lhef_powhegbox_commands(self, lhe_filename="events.lhe", me_pdf_order="NLO", usespin=True): + + if not me_pdf_order in ["LO", "NLO"]: + raise RuntimeError(hw7Utils.ansi_format_error("Herwig7ConfigLHEF.py:lhef_powhegbox_commands: Parameter 'me_pdf_order' must either be 'LO' or 'NLO'!")) + + self.set_lhef_powhegbox_commands = True + + self.__lhef_commands(lhe_filename, me_pdf_order, usespin) diff --git a/Generators/Herwig7_i/python/Herwig7ConfigMatchbox.py b/Generators/Herwig7_i/python/Herwig7ConfigMatchbox.py new file mode 100644 index 0000000000000000000000000000000000000000..ec466b93f0f98436a4cf68de17502477a5ad7a02 --- /dev/null +++ b/Generators/Herwig7_i/python/Herwig7ConfigMatchbox.py @@ -0,0 +1,413 @@ +#! /usr/bin/env python + +## \file Herwig7ConfigMatchbox.py +## \brief Configuration class for Matchbox runs with %Herwig7 +## \author Daniel Rauch (daniel.rauch@desy.de) + +import os + +import Herwig7Config as hw7Config +import Herwig7Control as hw7Control +import Herwig7Utils as hw7Utils + +from AthenaCommon import Logging +athMsgLog = Logging.logging.getLogger('Herwig7ConfigMatchbox') + + +## Configuration class for Matchbox runs with %Herwig7 +## +## Example JobOptions are available in [`examples/Matchbox`](https://svnweb.cern.ch/trac/atlasoff/browser/Generators/Herwig7_i/trunk/examples/Matchbox) and [`tests/athenaMatchbox/jobOptions`](https://svnweb.cern.ch/trac/atlasoff/browser/Generators/Herwig7_i/trunk/tests/athenaMatchbox/jobOptions). +## +## +## Process Setup and Generator Configuration +## ========================================= +## +## To use the Matchbox run mode of %Herwig7 load the corresponding modules and add %Herwig7 to the generator sequence +## +## \code{.py} +## from Herwig7_i.Herwig7_iConf import Herwig7 +## from Herwig7_i.Herwig7ConfigMatchbox import Hw7ConfigMatchbox +## +## genSeq += Herwig7() +## \endcode +## +## You may specify details of the run a la +## +## \code{.py} +## # Provide config information +## evgenConfig.generators += ["Herwig7"] +## evgenConfig.tune = "MMHT2014" +## evgenConfig.description = "Herwig7 Zee sample with CT10 ME PDF and MMHT2014 PS and UE tune" +## evgenConfig.keywords = ["SM","Z","electron"] +## evgenConfig.contact = ["Your Name (your.name@cern.ch)"] +## \endcode +## +## You can initialize a generator configuration object with +## +## \code{.py} +## # initialize generator configuration object +## generator = Hw7ConfigMatchbox(genSeq, runArgs, run_name="HerwigMatchbox", beams="pp") +## \endcode +## +## Please see the [constructor](\ref Herwig7ConfigMatchbox::Hw7ConfigMatchbox#__init__) for +## more information on the arguments. +## +## You can use the functions +## [me_alphas_commands](\ref Herwig7Config::Hw7Config#me_alphas_commands), +## [me_pdf_commands](\ref Herwig7Config::Hw7Config#me_pdf_commands) and +## [tune_commands](\ref Herwig7Config::Hw7Config#tune_commands) +## from Herwig7Config::Hw7Config to configure the strong coupling and the PDFs +## for the hard process and the parton shower and underlying event tunes, e.g. +## +## \code{.py} +## # configure generator +## generator.me_pdf_commands(order="NLO", name="CT10") +## generator.tune_commands() +## \endcode +## +## You can add direct %Herwig7 commands like this +## +## \code{.py} +## generator.add_commands(""" +## +## # Model assumptions +## read Matchbox/StandardModelLike.in +## +## # Set the hard process +## set /Herwig/MatrixElements/Matchbox/Factory:OrderInAlphaS 0 +## set /Herwig/MatrixElements/Matchbox/Factory:OrderInAlphaEW 2 +## do /Herwig/MatrixElements/Matchbox/Factory:Process p p -> e+ e- +## +## # Cut selection (see the documentation for more options) +## set /Herwig/Cuts/ChargedLeptonPairMassCut:MinMass 60*GeV +## set /Herwig/Cuts/ChargedLeptonPairMassCut:MaxMass 120*GeV +## +## # Scale choice (see the documentation for more options) +## cd /Herwig/MatrixElements/Matchbox +## set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale +## +## # Matching and shower selection +## read Matchbox/MCatNLO-DefaultShower.in +## +## # Choose a flavour scheme +## read Matchbox/FiveFlavourScheme.in +## """) +## \endcode +## +## Please see the [Herwig7 tutorial page](http://herwig.hepforge.org/tutorials/index.html) for in-depth information on the different settings and have a look at Herwig7ConfigMatchbox::Hw7ConfigMatchbox and Herwig7Config::Hw7Config to see if there are convenience functions that accomplish the task provided in the interface already. +## +## +## Integration and Event Generation +## ================================ +## +## To trigger the actual running of %Herwig7 in Athena please end the JobOptions with +## +## \code{.py} +## # run the generator +## generator.run() +## \endcode +## +## More specifically, the `run()` function triggers the creation of the %Herwig7 input +## file and the preparation of the run (i.e. the `Herwig [build, integrate, +## mergegrids]` sequence). This means, that no %Herwig7 settings should be modified +## after calling the `run()` function because the changed settings would not be applied +## during the event generation. +## +## +## Cleanup After the Event Generation +## ---------------------------------- +## +## By default the folder `Herwig-scratch` which created by %Herwig7 and contains +## the process libraries and several other files (e.g. integration grids) +## will be cleaned up and deleted after the event generation in order to save +## disk space. You can prevent this with: +## +## \code{.py} +## # run the generator +## generator.run(cleanup_herwig_scratch=True) +## \endcode +## +## +## Parallel Integration +## -------------------- +## +## Machine-local parallelization of the integration can be achieved with +## \code{.py} +## # run the generator +## generator.run(integration_jobs=2) +## \endcode +## +## `Generate_tf.py` comes with the command line parameter `--generatorJobNumber` +## that can be used to specify the number of integration jobs dynamically, instead +## of fixing it in the JobOptions +## \code{.py} +## # run the generator +## generator.run(integration_jobs=runArgs.generatorJobNumber) +## \endcode +## +## +## Gridpacks +## --------- +## +## A gridpack can be created with +## \code{.py} +## # run the generator +## generator.run(gridpack="gridpack.tar.gz") +## \endcode +## +## The JobOptions can be run in athena with a command such as +## +## Generate_tf.py --jobConfig=MC15.999999.H7_MB_Int_Zee_MCatLO_QTilde_H7_UE_MMHT2014.py --runNumber=999999 --ecmEnergy=13000 --randomSeed=12011988 --maxEvents=100 --outputEVNTFile=evgen.root +## +## If you have previously created a gridpack called `gridpack.tar.gz` and want to generate events from it, specify the name of the compressed gridpack using the `--inputGenConfFile` command line parameter, e.g. +## +## Generate_tf.py --jobConfig=MC15.999999.H7_MB_Int_Zee_MCatLO_QTilde_H7_UE_MMHT2014.py --inputGenConfFile=gridpack.tar.gz --runNumber=999999 --ecmEnergy=13000 --randomSeed=12011988 --maxEvents=100 --outputEVNTFile=evgen.root +## +## +## Full Flexibility and Batch-Parallel Integration +## ----------------------------------------------- +## +## The `--generatorRunMode` command line argument for `Generate_tf.py` can be used +## to put in place a very fine-grained control over the various steps that happen +## before the event generation. +## +## In the following example this is combined with the creation and use of +## a gridpack. This, however, doesn't have to be done and can be left out. +## \code{.py} +## if runArgs.generatorRunMode == 'build': +## # use the --generatorJobNumber command line parameter to dynamically +## # specify the total number of parallel integration jobs +## generator.do_build(integration_jobs=runArgs.generatorJobNumber) +## +## elif runArgs.generatorRunMode == 'integrate': +## # use the --generatorJobNumber command line parameter to dynamically +## # specify which specific integration job is to be run +## generator.do_integrate(runArgs.generatorJobNumber) +## +## elif runArgs.generatorRunMode == 'mergegrids': +## # combine integration grids and prepare a gridpack +## # use the --generatorJobNumber command line parameter to dynamically +## # specify the total number of parallel integration jobs +## generator.do_mergegrids(integration_jobs=runArgs.generatorJobNumber, gridpack="gridpack.tar.gz") +## +## elif runArgs.generatorRunMode == 'run': +## # generate events using the specified gridpack +## generator.do_run(gridpack="gridpack.tar.gz") +## \endcode +## +## Please note that for the `do_build()` function the same caveat applies as for +## the `run()` function: The %Herwig7 generator configuration should not be modified +## afterwards in the job options as the new settings would not be applied in the +## event generation. +## +## \note Currently the build, the integration and the mergegrids steps have to +## run in the same directory which means that the files written by athena +## will be re-created and overwritten. +## In one of the next releases %Herwig7 will bring infrastructure to re-use +## `Herwig-scratch` folders from a different location which will allow for +## a full batch parallelization of the integration in athena. +## +class Hw7ConfigMatchbox(hw7Config.Hw7Config): + + + ## \brief Initialize a generator configuration object for the Matchbox run mode + def __init__(self, genSeq, runArgs, run_name="Herwig", beams="pp"): + + beams = beams.upper() + if not beams in ["EE", "EP", "PP"]: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'beams' must be one of the following ['EE', 'EP', 'PP']!")) + + ## provide variables initialized by the parent class + super(Hw7ConfigMatchbox, self).__init__(genSeq, runArgs, run_name) + + self.beams = beams + + + def local_pre_commands(self): + + # try to locate the MG5_aMC@NLO installation + MG5aMC_path = os.environ['MADPATH'] + if not os.path.isfile(os.path.join(MG5aMC_path, 'bin', 'mg5_aMC')): + athMsgLog.warn(hw7Utils.ansi_format_warning("The MadGraph5_aMC@NLO installation can't be found from $MADPATH = {}, so don't be surprised if your run crashes in you are using matrix elements from MG5_aMC@NLO in Herwig7 / Matchbox. Please ensure that the location exists, that you have permissions to access it and that it contains the executable 'bin/mg5_aMC'".format(MG5aMC_path))) + + # try to locate the GoSam installation + try: + GoSam_path = os.environ['GOSAM_PATH'] + except: + # \todo Get rid of this and just use the environment variable `GOSAMPATH` + GoSam_path = '/afs/.cern.ch/sw/lcg/external/MCGenerators_lcgcmt67c/gosam/2.0.3/x86_64-slc6-gcc47-opt' + athMsgLog.warn(hw7Utils.ansi_format_warning("Falling back to hard-coded GoSam installation location at '{}' - please ensure that the GOSAM_PATH environment variable is correctly set".format(GoSam_path))) + if not os.path.isfile(os.path.join(GoSam_path, 'bin', 'gosam.py')): + athMsgLog.warn(hw7Utils.ansi_format_warning("The GoSam installation can't be found from $GOSAMPATH = {}, so don't be surprised if your run crashes in you are using matrix elements from GoSam in Herwig7 / Matchbox. Please ensure that the location exists, that you have permissions to access it and that it contains the script 'bin/gosam.py'".format(GoSam_path))) + + try: + OpenLoops_path= os.environ['OPENLOOPS_PATH'] + except: + OpenLoops_path = '/afs/.cern.ch/sw/lcg/releases/MCGenerators/openloops/1.3.1-1f1f6/x86_64-slc6-gcc49-opt' + athMsgLog.warn(hw7Utils.ansi_format_warning("Falling back to hard-coded OPENLOOPS installation location at '{}' - please ensure that the OPENLOOPS_PATH environment variable is correctly set".format(OpenLoops_path))) + if not os.path.isdir(os.path.join(OpenLoops_path, "proclib")): + athMsgLog.warn(hw7Utils.ansi_format_warning("The OpenLoops process libraries can't be found from $OPENLOOPS_PATH = {}".format(OpenLoops_path))) + + return """ +## ================================================ +## Local Pre-Commands from Herwig7ConfigMatchbox.py +## ================================================ + +## Fixing interface locations for MadGraph +set /Herwig/MatrixElements/Matchbox/Amplitudes/MadGraph:BinDir {0} +set /Herwig/MatrixElements/Matchbox/Amplitudes/MadGraph:DataDir {1} +set /Herwig/MatrixElements/Matchbox/Amplitudes/MadGraph:MadgraphPrefix {2} + +## Fixing interface locations for GoSam +set /Herwig/MatrixElements/Matchbox/Amplitudes/GoSam:BinDir {0} +set /Herwig/MatrixElements/Matchbox/Amplitudes/GoSam:DataDir {1} +set /Herwig/MatrixElements/Matchbox/Amplitudes/GoSam:GoSamPrefix {3} + +##Fixing interface locations of Openloops +set /Herwig/MatrixElements/Matchbox/Amplitudes/OpenLoops:OpenLoopsLibs {5} +set /Herwig/MatrixElements/Matchbox/Amplitudes/OpenLoops:OpenLoopsPrefix {6} + +read snippets/Matchbox.in +read snippets/{4}Collider.in +""".format(hw7Control.herwig7_bin_path, + hw7Control.herwig7_share_path, + MG5aMC_path, + GoSam_path, + self.beams, + os.path.join(OpenLoops_path,"proclib"), + OpenLoops_path) + + + def local_post_commands(self): + + return """ +## ================================================= +## Local Post-Commands from Herwig7ConfigMatchbox.py +## ================================================= + +do /Herwig/MatrixElements/Matchbox/Factory:ProductionMode +saverun {} /Herwig/Generators/EventGenerator +""".format(self.run_name) + + + def __configure(self): + + ## add default settings if they were not overwritten in the JobOptions + + self.default_commands += self.energy_commands() + self.default_commands += self.random_seed_commands() + + if not self.set_printout_commands: + self.default_commands += self.printout_commands() + if not self.set_physics_parameter_commands: + self.default_commands += self.physics_parameter_commands() + if not self.set_technical_parameter_commands: + self.default_commands += self.technical_parameter_commands() + + + ## High-level function for triggering the process setup and the event generation. + ## + ## \param[in] integration_jobs Number of threads for machine-local parallelization of the integration + ## \param[in] gridpack Name of the gridpack that possibly is to be created (after the integration) + ## or to be used (for the event generation). + ## No gridpack is created or used if the parameter is not specified. + ## If you have created a gridpack + ## and would like to generate events from it, please pass the name of the + ## gridpack to the `Generate_tf.py` command using the `--inputGenConfFile` + ## command line argument + ## \param[in] cleanup_herwig_scratch Remove the `Herwig-scratch` folder after event generation to save disk space + ## + ## \warning Please do not modify the generator configuration in the job options after calling the `run()` function as + ## the modified settings would not be applied in the event generation + ## + def run(self, integration_jobs=1, gridpack=None, cleanup_herwig_scratch=True): + + self.__configure() + + if gridpack: + hw7Control.matchbox_run_gridpack(self, integration_jobs, gridpack, cleanup_herwig_scratch) + else: + hw7Control.matchbox_run(self, integration_jobs, cleanup_herwig_scratch) + + + # atomic functions for complete control from within the JobOptions ---------- + + ## Atomic steering function for doing the build step alone + ## + ## \param[in] integration_jobs Number of integration jobs to be prepared + ## + ## \warning Please do not modify the generator configuration in the job options after calling the `do_build()` function as + ## the modified settings would not be applied in the event generation + ## + def do_build(self, integration_jobs): + self.__configure() + hw7Control.do_build(self, integration_jobs) + hw7Control.do_abort() + + ## Atomic steering function for doing one specific integration job + ## \todo provide info about the range + def do_integrate(self, integration_job): + hw7Control.do_integrate(self.run_name, integration_job) + hw7Control.do_abort() + + ## Atomic steering function for combining the integration grids and + ## possibly creating a gridpack + ## \param[in] integration_jobs Number of integration jobs + ## \param[in] gridpack Name of the gridpack to be created. + ## No gridpack is created if the parameter is not specified. + def do_mergegrids(self, integration_jobs, gridpack=None): + hw7Control.do_mergegrids(self.run_name, integration_jobs) + if gridpack: + hw7Control.do_compress_gridpack(self.run_name, gridpack) + hw7Control.do_abort() + + ## Atomic steering function for possibly unpacking a gridpack + ## and generating events + ## \param[in] gridpack Name of the gridpack to be used. + ## No gridpack is used if the parameter is not specified. + ## \param[in] cleanup_herwig_scratch Remove the `Herwig-scratch` folder after event generation to save disk space + def do_run(self, gridpack=None, cleanup_herwig_scratch=True): + if gridpack: + hw7Control.do_uncompress_gridpack(gridpack) + hw7Control.do_run(self, cleanup_herwig_scratch) + + + # configuration commands ---------------------------------------------------- + + ## Configure the sampler + ## + ## \warning Please be very careful when modifying the sampler settings + ## and ensure that the statistics in the integration phase is + ## sufficient to provide an adequate phase space sampling and setup. + ## The total cross section estimated after the integration is + ## output before the event generation, please watch out for the + ## corresponding lines beginning with + ## + ## Py:Herwig7Utils INFO Calculating cross section after integration + ## + ## If the statistical uncertainty on this estimated total cross + ## section is larger than 0.2% a warning is printed, encouraging + ## you to consider increasing the statistics of the integration. + ## + def sampler_commands(self, bin_sampler="CellGridSampler", + initial_points=10000, n_iterations=1, remapper_points=50000, + exploration_steps=4, exploration_points=500): + + bin_samplers = ["CellGridSampler", "MonacoSampler", "FlatBinSampler"] + + if not bin_sampler in bin_samplers: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'bin_sampler' must be one of {}!".format(bin_samplers))) + + self.commands += """ +## Sampler Configuration +set /Herwig/Samplers/Sampler:BinSampler /Herwig/Samplers/{} +set /Herwig/Samplers/Sampler:BinSampler:InitialPoints {} +set /Herwig/Samplers/Sampler:BinSampler:NIterations {} +set /Herwig/Samplers/Sampler:BinSampler:RemapperPoints {} +""".format(bin_sampler, initial_points, n_iterations, remapper_points) + + if bin_sampler == "CellGridSampler": + self.commands += """ +set /Herwig/Samplers/CellGridSampler:ExplorationSteps {} +set /Herwig/Samplers/CellGridSampler:ExplorationPoints {} +""".format(exploration_steps, exploration_points) diff --git a/Generators/Herwig7_i/python/Herwig7ConfigMerging.py b/Generators/Herwig7_i/python/Herwig7ConfigMerging.py new file mode 100644 index 0000000000000000000000000000000000000000..26bf6db9be45df7d5c9189fb6db2e99a4a1fb871 --- /dev/null +++ b/Generators/Herwig7_i/python/Herwig7ConfigMerging.py @@ -0,0 +1,434 @@ +#! /usr/bin/env python + +## \file Herwig7ConfigMatchbox.py +## \brief Configuration class for Matchbox runs with %Herwig7 +## \author Daniel Rauch (daniel.rauch@desy.de) + +import os + +import Herwig7Config as hw7Config +import Herwig7Control as hw7Control +import Herwig7Utils as hw7Utils + +from AthenaCommon import Logging +athMsgLog = Logging.logging.getLogger('Herwig7ConfigMerging') + + +## Configuration class for Matchbox runs with %Herwig7 +## +## Example JobOptions are available in [`examples/Matchbox`](https://svnweb.cern.ch/trac/atlasoff/browser/Generators/Herwig7_i/trunk/examples/Matchbox) and [`tests/athenaMatchbox/jobOptions`](https://svnweb.cern.ch/trac/atlasoff/browser/Generators/Herwig7_i/trunk/tests/athenaMatchbox/jobOptions). +## +## +## Process Setup and Generator Configuration +## ========================================= +## +## To use the Matchbox run mode of %Herwig7 load the corresponding modules and add %Herwig7 to the generator sequence +## +## \code{.py} +## from Herwig7_i.Herwig7_iConf import Herwig7 +## from Herwig7_i.Herwig7ConfigMatchbox import Hw7ConfigMatchbox +## +## genSeq += Herwig7() +## \endcode +## +## You may specify details of the run a la +## +## \code{.py} +## # Provide config information +## evgenConfig.generators += ["Herwig7"] +## evgenConfig.tune = "MMHT2014" +## evgenConfig.description = "Herwig7 Zee sample with CT10 ME PDF and MMHT2014 PS and UE tune" +## evgenConfig.keywords = ["SM","Z","electron"] +## evgenConfig.contact = ["Your Name (your.name@cern.ch)"] +## \endcode +## +## You can initialize a generator configuration object with +## +## \code{.py} +## # initialize generator configuration object +## generator = Hw7ConfigMatchbox(genSeq, runArgs, run_name="HerwigMatchbox", beams="pp") +## \endcode +## +## Please see the [constructor](\ref Herwig7ConfigMatchbox::Hw7ConfigMatchbox#__init__) for +## more information on the arguments. +## +## You can use the functions +## [me_alphas_commands](\ref Herwig7Config::Hw7Config#me_alphas_commands), +## [me_pdf_commands](\ref Herwig7Config::Hw7Config#me_pdf_commands) and +## [tune_commands](\ref Herwig7Config::Hw7Config#tune_commands) +## from Herwig7Config::Hw7Config to configure the strong coupling and the PDFs +## for the hard process and the parton shower and underlying event tunes, e.g. +## +## \code{.py} +## # configure generator +## generator.me_pdf_commands(order="NLO", name="CT10") +## generator.tune_commands() +## \endcode +## +## You can add direct %Herwig7 commands like this +## +## \code{.py} +## generator.add_commands(""" +## +## # Model assumptions +## read Matchbox/StandardModelLike.in +## +## # Set the hard process +## set /Herwig/MatrixElements/Matchbox/Factory:OrderInAlphaS 0 +## set /Herwig/MatrixElements/Matchbox/Factory:OrderInAlphaEW 2 +## do /Herwig/MatrixElements/Matchbox/Factory:Process p p -> e+ e- +## +## # Cut selection (see the documentation for more options) +## set /Herwig/Cuts/ChargedLeptonPairMassCut:MinMass 60*GeV +## set /Herwig/Cuts/ChargedLeptonPairMassCut:MaxMass 120*GeV +## +## # Scale choice (see the documentation for more options) +## cd /Herwig/MatrixElements/Matchbox +## set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale +## +## # Matching and shower selection +## read Matchbox/MCatNLO-DefaultShower.in +## +## # Choose a flavour scheme +## read Matchbox/FiveFlavourScheme.in +## """) +## \endcode +## +## Please see the [Herwig7 tutorial page](http://herwig.hepforge.org/tutorials/index.html) for in-depth information on the different settings and have a look at Herwig7ConfigMatchbox::Hw7ConfigMatchbox and Herwig7Config::Hw7Config to see if there are convenience functions that accomplish the task provided in the interface already. +## +## +## Integration and Event Generation +## ================================ +## +## To trigger the actual running of %Herwig7 in Athena please end the JobOptions with +## +## \code{.py} +## # run the generator +## generator.run() +## \endcode +## +## More specifically, the `run()` function triggers the creation of the %Herwig7 input +## file and the preparation of the run (i.e. the `Herwig [build, integrate, +## mergegrids]` sequence). This means, that no %Herwig7 settings should be modified +## after calling the `run()` function because the changed settings would not be applied +## during the event generation. +## +## +## Cleanup After the Event Generation +## ---------------------------------- +## +## By default the folder `Herwig-scratch` which created by %Herwig7 and contains +## the process libraries and several other files (e.g. integration grids) +## will be cleaned up and deleted after the event generation in order to save +## disk space. You can prevent this with: +## +## \code{.py} +## # run the generator +## generator.run(cleanup_herwig_scratch=True) +## \endcode +## +## +## Parallel Integration +## -------------------- +## +## Machine-local parallelization of the integration can be achieved with +## \code{.py} +## # run the generator +## generator.run(integration_jobs=2) +## \endcode +## +## `Generate_tf.py` comes with the command line parameter `--generatorJobNumber` +## that can be used to specify the number of integration jobs dynamically, instead +## of fixing it in the JobOptions +## \code{.py} +## # run the generator +## generator.run(integration_jobs=runArgs.generatorJobNumber) +## \endcode +## +## +## Gridpacks +## --------- +## +## A gridpack can be created with +## \code{.py} +## # run the generator +## generator.run(gridpack="gridpack.tar.gz") +## \endcode +## +## The JobOptions can be run in athena with a command such as +## +## Generate_tf.py --jobConfig=MC15.999999.H7_MB_Int_Zee_MCatLO_QTilde_H7_UE_MMHT2014.py --runNumber=999999 --ecmEnergy=13000 --randomSeed=12011988 --maxEvents=100 --outputEVNTFile=evgen.root +## +## If you have previously created a gridpack called `gridpack.tar.gz` and want to generate events from it, specify the name of the compressed gridpack using the `--inputGenConfFile` command line parameter, e.g. +## +## Generate_tf.py --jobConfig=MC15.999999.H7_MB_Int_Zee_MCatLO_QTilde_H7_UE_MMHT2014.py --inputGenConfFile=gridpack.tar.gz --runNumber=999999 --ecmEnergy=13000 --randomSeed=12011988 --maxEvents=100 --outputEVNTFile=evgen.root +## +## +## Full Flexibility and Batch-Parallel Integration +## ----------------------------------------------- +## +## The `--generatorRunMode` command line argument for `Generate_tf.py` can be used +## to put in place a very fine-grained control over the various steps that happen +## before the event generation. +## +## In the following example this is combined with the creation and use of +## a gridpack. This, however, doesn't have to be done and can be left out. +## \code{.py} +## if runArgs.generatorRunMode == 'build': +## # use the --generatorJobNumber command line parameter to dynamically +## # specify the total number of parallel integration jobs +## generator.do_build(integration_jobs=runArgs.generatorJobNumber) +## +## elif runArgs.generatorRunMode == 'integrate': +## # use the --generatorJobNumber command line parameter to dynamically +## # specify which specific integration job is to be run +## generator.do_integrate(runArgs.generatorJobNumber) +## +## elif runArgs.generatorRunMode == 'mergegrids': +## # combine integration grids and prepare a gridpack +## # use the --generatorJobNumber command line parameter to dynamically +## # specify the total number of parallel integration jobs +## generator.do_mergegrids(integration_jobs=runArgs.generatorJobNumber, gridpack="gridpack.tar.gz") +## +## elif runArgs.generatorRunMode == 'run': +## # generate events using the specified gridpack +## generator.do_run(gridpack="gridpack.tar.gz") +## \endcode +## +## Please note that for the `do_build()` function the same caveat applies as for +## the `run()` function: The %Herwig7 generator configuration should not be modified +## afterwards in the job options as the new settings would not be applied in the +## event generation. +## +## \note Currently the build, the integration and the mergegrids steps have to +## run in the same directory which means that the files written by athena +## will be re-created and overwritten. +## In one of the next releases %Herwig7 will bring infrastructure to re-use +## `Herwig-scratch` folders from a different location which will allow for +## a full batch parallelization of the integration in athena. +## +class Hw7ConfigMerging(hw7Config.Hw7Config): + + + ## \brief Initialize a generator configuration object for the Matchbox run mode + def __init__(self, genSeq, runArgs, run_name="Herwig", beams="pp"): + + beams = beams.upper() + if not beams in ["EE", "EP", "PP"]: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'beams' must be one of the following ['EE', 'EP', 'PP']!")) + + ## provide variables initialized by the parent class + super(Hw7ConfigMerging, self).__init__(genSeq, runArgs, run_name) + + self.beams = beams + + + def local_pre_commands(self): + + # try to locate the MG5_aMC@NLO installation + MG5aMC_path = os.environ['MADPATH'] + if not os.path.isfile(os.path.join(MG5aMC_path, 'bin', 'mg5_aMC')): + athMsgLog.warn(hw7Utils.ansi_format_warning("The MadGraph5_aMC@NLO installation can't be found from $MADPATH = {}, so don't be surprised if your run crashes in you are using matrix elements from MG5_aMC@NLO in Herwig7 / Matchbox. Please ensure that the location exists, that you have permissions to access it and that it contains the executable 'bin/mg5_aMC'".format(MG5aMC_path))) + + # try to locate the GoSam installation + try: + GoSam_path = os.environ['GOSAM_PATH'] + except: + # \todo Get rid of this and just use the environment variable `GOSAMPATH` + GoSam_path = '/afs/.cern.ch/sw/lcg/external/MCGenerators_lcgcmt67c/gosam/2.0.3/x86_64-slc6-gcc47-opt' + athMsgLog.warn(hw7Utils.ansi_format_warning("Falling back to hard-coded GoSam installation location at '{}' - please ensure that the GOSAM_PATH environment variable is correctly set".format(GoSam_path))) + if not os.path.isfile(os.path.join(GoSam_path, 'bin', 'gosam.py')): + athMsgLog.warn(hw7Utils.ansi_format_warning("The GoSam installation can't be found from $GOSAMPATH = {}, so don't be surprised if your run crashes in you are using matrix elements from GoSam in Herwig7 / Matchbox. Please ensure that the location exists, that you have permissions to access it and that it contains the script 'bin/gosam.py'".format(GoSam_path))) + + try: + OpenLoops_path= os.environ['OPENLOOPS_PATH'] + except: + OpenLoops_path = '/afs/.cern.ch/sw/lcg/releases/MCGenerators/openloops/1.3.1-1f1f6/x86_64-slc6-gcc49-opt' + athMsgLog.warn(hw7Utils.ansi_format_warning("Falling back to hard-coded OPENLOOPS installation location at '{}' - please ensure that the OPENLOOPS_PATH environment variable is correctly set".format(OpenLoops_path))) + if not os.path.isdir(os.path.join(OpenLoops_path, "proclib")): + athMsgLog.warn(hw7Utils.ansi_format_warning("The OpenLoops process libraries can't be found from $OPENLOOPS_PATH = {}".format(OpenLoops_path))) + + + + return """ +## ================================================ +## Local Pre-Commands from Herwig7ConfigMerging.py +## ================================================ + +## Fixing interface locations for MadGraph +set /Herwig/MatrixElements/Matchbox/Amplitudes/MadGraph:BinDir {0} +set /Herwig/MatrixElements/Matchbox/Amplitudes/MadGraph:DataDir {1} +set /Herwig/MatrixElements/Matchbox/Amplitudes/MadGraph:MadgraphPrefix {2} + +## Fixing interface locations for GoSam +set /Herwig/MatrixElements/Matchbox/Amplitudes/GoSam:BinDir {0} +set /Herwig/MatrixElements/Matchbox/Amplitudes/GoSam:DataDir {1} +set /Herwig/MatrixElements/Matchbox/Amplitudes/GoSam:GoSamPrefix {3} + +##Fixing interface locations of Openloops +set /Herwig/MatrixElements/Matchbox/Amplitudes/OpenLoops:OpenLoopsLibs {5} +set /Herwig/MatrixElements/Matchbox/Amplitudes/OpenLoops:OpenLoopsPrefix {6} + +# Currently the Dipole Snippet is broken (reads to the Rivet interface which we don't build) +# For now manually copy all the relevant settings in +read snippets/DipoleMerging.in +read snippets/{4}Collider.in +read Merging/Merging-Dipole-FactorCMWSchemeTune.in +read Merging/FactorCMWScheme.in +""".format(hw7Control.herwig7_bin_path, + hw7Control.herwig7_share_path, + MG5aMC_path, + GoSam_path, + self.beams, + os.path.join(OpenLoops_path,"proclib"), + OpenLoops_path) + + def local_post_commands(self): + + return """ +## ================================================= +## Local Post-Commands from Herwig7ConfigMerging.py +## ================================================= + +do /Herwig/Merging/MergingFactory:ProductionMode +saverun {} /Herwig/Generators/EventGenerator +""".format(self.run_name) + + + def __configure(self): + + ## add default settings if they were not overwritten in the JobOptions + + self.default_commands += self.energy_commands() + self.default_commands += self.random_seed_commands() + + if not self.set_printout_commands: + self.default_commands += self.printout_commands() + if not self.set_physics_parameter_commands: + self.default_commands += self.physics_parameter_commands() + if not self.set_technical_parameter_commands: + self.default_commands += self.technical_parameter_commands() + + + ## High-level function for triggering the process setup and the event generation. + ## + ## \param[in] integration_jobs Number of threads for machine-local parallelization of the integration + ## \param[in] gridpack Name of the gridpack that possibly is to be created (after the integration) + ## or to be used (for the event generation). + ## No gridpack is created or used if the parameter is not specified. + ## If you have created a gridpack + ## and would like to generate events from it, please pass the name of the + ## gridpack to the `Generate_tf.py` command using the `--inputGenConfFile` + ## command line argument + ## \param[in] cleanup_herwig_scratch Remove the `Herwig-scratch` folder after event generation to save disk space + ## + ## \warning Please do not modify the generator configuration in the job options after calling the `run()` function as + ## the modified settings would not be applied in the event generation + ## + def run(self, integration_jobs=1, gridpack=None, cleanup_herwig_scratch=True): + + self.__configure() + + if gridpack: + hw7Control.matchbox_run_gridpack(self, integration_jobs, gridpack, cleanup_herwig_scratch) + else: + hw7Control.matchbox_run(self, integration_jobs, cleanup_herwig_scratch) + + + # atomic functions for complete control from within the JobOptions ---------- + + ## Atomic steering function for doing the build step alone + ## + ## \param[in] integration_jobs Number of integration jobs to be prepared + ## + ## \warning Please do not modify the generator configuration in the job options after calling the `do_build()` function as + ## the modified settings would not be applied in the event generation + ## + def do_build(self, integration_jobs): + self.__configure() + hw7Control.do_build(self, integration_jobs) + hw7Control.do_abort() + + ## Atomic steering function for doing one specific integration job + ## \todo provide info about the range + def do_integrate(self, integration_job): + hw7Control.do_integrate(self.run_name, integration_job) + hw7Control.do_abort() + + ## Atomic steering function for combining the integration grids and + ## possibly creating a gridpack + ## \param[in] integration_jobs Number of integration jobs + ## \param[in] gridpack Name of the gridpack to be created. + ## No gridpack is created if the parameter is not specified. + def do_mergegrids(self, integration_jobs, gridpack=None): + hw7Control.do_mergegrids(self.run_name, integration_jobs) + if gridpack: + hw7Control.do_compress_gridpack(self.run_name, gridpack) + hw7Control.do_abort() + + ## Atomic steering function for possibly unpacking a gridpack + ## and generating events + ## \param[in] gridpack Name of the gridpack to be used. + ## No gridpack is used if the parameter is not specified. + ## \param[in] cleanup_herwig_scratch Remove the `Herwig-scratch` folder after event generation to save disk space + def do_run(self, gridpack=None, cleanup_herwig_scratch=True): + if gridpack: + hw7Control.do_uncompress_gridpack(gridpack) + hw7Control.do_run(self, cleanup_herwig_scratch) + + + # configuration commands ---------------------------------------------------- + + ## Configure the sampler + ## + ## \warning Please be very careful when modifying the sampler settings + ## and ensure that the statistics in the integration phase is + ## sufficient to provide an adequate phase space sampling and setup. + ## The total cross section estimated after the integration is + ## output before the event generation, please watch out for the + ## corresponding lines beginning with + ## + ## Py:Herwig7Utils INFO Calculating cross section after integration + ## + ## If the statistical uncertainty on this estimated total cross + ## section is larger than 0.2% a warning is printed, encouraging + ## you to consider increasing the statistics of the integration. + ## + def sampler_commands(self, bin_sampler="CellGridSampler", + initial_points=10000, n_iterations=1, remapper_points=50000, + exploration_steps=4, exploration_points=500): + + bin_samplers = ["CellGridSampler", "MonacoSampler", "FlatBinSampler"] + + if not bin_sampler in bin_samplers: + raise RuntimeError(hw7Utils.ansi_format_error("Parameter 'bin_sampler' must be one of {}!".format(bin_samplers))) + + self.commands += """ +## Sampler Configuration +set /Herwig/Samplers/Sampler:BinSampler /Herwig/Samplers/{} +set /Herwig/Samplers/Sampler:BinSampler:InitialPoints {} +set /Herwig/Samplers/Sampler:BinSampler:NIterations {} +set /Herwig/Samplers/Sampler:BinSampler:RemapperPoints {} +""".format(bin_sampler, initial_points, n_iterations, remapper_points) + + if bin_sampler == "CellGridSampler": + self.commands += """ +set /Herwig/Samplers/CellGridSampler:ExplorationSteps {} +set /Herwig/Samplers/CellGridSampler:ExplorationPoints {} +""".format(exploration_steps, exploration_points) + + if bin_sampler == "MonacoSampler": + self.commands += """ +read snippets/MonacoSampler.in""" + + def merging_weight(self, htPower=0, maxPtPower=0, onlyColoured="No"): + if not onlyColoured in ["Yes","No"]: + raise RuntimeError(hw7Utils.ansi_format_error("OnlyColoured must be Yes or No")) + + self.commands+=""" +##Merging Weighter for better phase space coverage +set /Herwig/Merging/MPreWeight:HTPower {} +set /Herwig/Merging/MPreWeight:MaxPTPower {} +set /Herwig/Merging/MPreWeight:OnlyColoured {} +""".format(htPower,maxPtPower,onlyColoured) + diff --git a/Generators/Herwig7_i/python/Herwig7Control.py b/Generators/Herwig7_i/python/Herwig7Control.py index 778c867a90bfb02b02ba3800550d0bf83e18c63a..c736c8e131ef7d42ebf671d20a2d90c37f9bd303 100644 --- a/Generators/Herwig7_i/python/Herwig7Control.py +++ b/Generators/Herwig7_i/python/Herwig7Control.py @@ -22,9 +22,24 @@ athMsgLog = Logging.logging.getLogger('Herwig7Control') ## \brief Get path to the `share/Herwig` folder ## - +## Try to get it from the `InstallArea` first. +## If this fails fall back to `$HERWIG7_PATH/share/Herwig` +## def get_share_path(): + cmt_paths = os.environ.get("CMAKE_PREFIX_PATH") + cmt_config = os.environ.get("BINARY_TAG") + + # trying to get it from the `InstallArea` + for path in cmt_paths.split(':'): + path = os.path.join(path, "InstallArea", cmt_config, "share") + try: + filelist = os.listdir(path) + except: + filelist = [] + if "HerwigDefaults.rpo" in filelist: return(path) + + # falling back to `$HERWIG7_PATH` path = os.path.join(os.environ['HERWIG7_PATH'], 'share/Herwig') if os.path.isfile(os.path.join(path, 'HerwigDefaults.rpo')): return(path) @@ -39,16 +54,14 @@ herwig7_bin_path = os.path.join(herwig7_path, 'bin') herwig7_share_path = get_share_path() herwig7_binary = os.path.join(herwig7_bin_path, 'Herwig') -herwig7_mergegrids = os.path.join(herwig7_bin_path, 'herwig-mergegrids') ## Do the read/run sequence. ## -## This function should provide the build, integrate, mergegrids and run step -## in one go without creating a gridpack - just pure and direct event generation +## This function should provide the read and run step in one go def run(gen_config): - ## perform build/integrate/mergegrids sequence + ## perform the read step do_read(gen_config) ## start the event generation @@ -85,7 +98,6 @@ def matchbox_run_gridpack(gen_config, integration_jobs, gridpack_name, cleanup_h ## create infile from jobOption commands write_infile(gen_config) - # write_infile(run_name, event_generator, seed, commands) ## do build/integrate/mergegrids sequence xsec, err = do_build_integrate_mergegrids(gen_config, integration_jobs) @@ -148,6 +160,19 @@ def do_read(gen_config): share_path = get_share_path() do_step('read', [herwig7_binary, 'read', get_infile_name(gen_config.run_name), '-I', share_path]) +## Do the read step and re-use an already existing infile +def do_read_existing_infile(gen_config): + + ## print start banner including version numbers + log(message=start_banner()) + + ## copy HerwigDefaults.rpo to the current working directory + get_default_repository() + + ## call Herwig7 binary to do the read step + share_path = get_share_path() + do_step('read', [herwig7_binary, 'read', gen_config.infile_name, '-I', share_path]) + ## Do the build step def do_build(gen_config, integration_jobs): @@ -163,7 +188,7 @@ def do_build(gen_config, integration_jobs): ## call the Herwig7 binary to do the build step share_path = get_share_path() - do_step('build', [herwig7_binary, 'build', get_infile_name(gen_config.run_name), '-I', share_path, '-y'+str(integration_jobs)]) + do_step('build', [herwig7_binary, 'build', get_infile_name(gen_config.run_name), '-I', share_path, '-y '+str(integration_jobs)]) ## Do the integrate step for one specific integration job @@ -184,7 +209,7 @@ def do_integrate(run_name, integration_job): def do_mergegrids(run_name, integration_jobs): runfile_name = get_runfile_name(run_name) - mergegrids_command = [herwig7_mergegrids, runfile_name] + mergegrids_command = [herwig7_binary, 'mergegrids', runfile_name] # if setupfile_name: mergegrids_command.append('--setupfile='+setupfile_name) do_step('mergegrids', mergegrids_command) @@ -266,6 +291,23 @@ def do_run(gen_config, cleanup_herwig_scratch=True): athMsgLog.info(hw7Utils.ansi_format_info("Returning to the job options and starting the event generation afterwards")) +## Do the run step and re-use an already existing runfile +def do_run_existing_runfile(gen_config): + + ## this is necessary to make Herwig aware of the name of the run file + gen_config.genSeq.Herwig7.RunFile = gen_config.runfile_name + + ## overwrite athena's seed for the random number generator + if gen_config.runArgs.randomSeed is None: + gen_config.genSeq.Herwig7.UseRandomSeedFromGeneratetf = False + else: + gen_config.genSeq.Herwig7.UseRandomSeedFromGeneratetf = True + gen_config.genSeq.Herwig7.RandomSeedFromGeneratetf = gen_config.runArgs.randomSeed + + ## don't break out here so that the job options can be finished and the C++ + ## part of the interface can take over and generate the events + athMsgLog.info(hw7Utils.ansi_format_info("Returning to the job options and starting the event generation afterwards")) + # utility functions ----------------------------------------------------------- diff --git a/Generators/Herwig7_i/python/Herwig7Utils.py b/Generators/Herwig7_i/python/Herwig7Utils.py index 636e825e5a4aed6ea2b1e91cb05786118e80730e..71a7b979cf1e317c211fc78d386e42ecca5687c8 100644 --- a/Generators/Herwig7_i/python/Herwig7Utils.py +++ b/Generators/Herwig7_i/python/Herwig7Utils.py @@ -9,7 +9,7 @@ import math, os, subprocess, time from AthenaCommon import Logging athMsgLog = Logging.logging.getLogger('Herwig7Utils') -integration_grids_precision_threshold = 0.002 # warn if integration xsec below +integration_grids_precision_threshold = 0.05 # warn if integration xsec below ## Class for handling commands to modify the generator configuration @@ -145,7 +145,8 @@ def get_cross_section(run_name, integration_jobs=1): if err / xsec > integration_grids_precision_threshold: threshold = '{}%'.format(integration_grids_precision_threshold*100.0) - athMsgLog.warn(ansi_format_warning('! WARNING: The integration grids only have a low precision (worse than {}): xsec = {} +/- {} nb (accuracy: {:.3f}%)'.format(threshold, xsec, err, err/xsec*100.0))) + athMsgLog.warn(ansi_format_warning('! The integration grids only have a low precision (worse than {}): xsec = {} +/- {} nb (accuracy: {:.3f}%)'.format(threshold, xsec, err, err/xsec*100.0))) + athMsgLog.warn(ansi_format_warning('! In order to speed up the event generation you should consider improving the statistics of the integration / phase space sampling stage (see the sampler_commands() function).')) else: athMsgLog.info(ansi_format_info('After integration the estimated cross section was found to be: xsec = {} +/- {} nb (accuracy: {:.3f}%)'.format(xsec, err, err/xsec*100.0))) diff --git a/Generators/Herwig7_i/share/common/Herwig71EvtGen_H7UE_NNPDF30nlo_dipole_jetjet.py b/Generators/Herwig7_i/share/common/Herwig71EvtGen_H7UE_NNPDF30nlo_dipole_jetjet.py new file mode 100644 index 0000000000000000000000000000000000000000..6a01b3434d2dd351279139ac1dadc5d9cc4999f3 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig71EvtGen_H7UE_NNPDF30nlo_dipole_jetjet.py @@ -0,0 +1,58 @@ +name = runArgs.jobConfig[0] +name_info = name.split("_JZ")[1].split(".py") +slice = int(name_info[0]) + +minkT = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} + +# initialize Herwig7 generator configuration for built-in matrix elements +include("Herwig7_i/Herwig7_BuiltinME.py") + +# configure Herwig7 +Herwig7Config.add_commands("set /Herwig/Partons/RemnantDecayer:AllowTop Yes") +Herwig7Config.me_pdf_commands(order="NLO", name="NNPDF30_nlo_as_0118") + +command = """ +insert /Herwig/MatrixElements/SubProcess:MatrixElements[0] /Herwig/MatrixElements/MEQCD2to2 +set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0 +set /Herwig/Cuts/JetKtCut:MinKT """+str(minkT[slice])+"""*GeV +""" +print command + +Herwig7Config.add_commands(command) + +command2 = """ +cd /Herwig/EventHandlers +set EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler +read snippets/DipoleShowerFiveFlavours.in +cd /Herwig/DipoleShower +do DipoleShowerHandler:AddVariation isr:muRfac=2.0_fsr:muRfac=2.0 2.0 2.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=2.0_fsr:muRfac=1.0 2.0 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=2.0_fsr:muRfac=0.5 2.0 0.5 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=2.0" 1.0 2.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.5" 1.0 0.5 All +do DipoleShowerHandler:AddVariation isr:muRfac=0.5_fsr:muRfac=2.0" 0.5 2.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=0.5_fsr:muRfac=1.0 0.5 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=0.5_fsr:muRfac=0.5 0.5 0.5 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.75_fsr:muRfac=1.0 1.75 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.5_fsr:muRfac=1.0 1.5 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.25_fsr:muRfac=1.0 1.25 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=0.625_fsr:muRfac=1.0" 0.625 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=0.75_fsr:muRfac=1.0 0.75 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=0.875_fsr:muRfac=1.0 0.875 1.0 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=1.75 1.0 1.75 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=1.5 1.0 1.5 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=1.25 1.0 1.25 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.625 1.0 0.625 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.75 1.0 0.75 All +do DipoleShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.875 1.0 0.85 All +""" +print command2 +Herwig7Config.add_commands(command2) + + +# add EvtGen +include("Herwig7_i/Herwig71_EvtGen.py") + +# run Herwig7 +Herwig7Config.run() + diff --git a/Generators/Herwig7_i/share/common/Herwig71EvtGen_H7UE_NNPDF30nlo_jetjet.py b/Generators/Herwig7_i/share/common/Herwig71EvtGen_H7UE_NNPDF30nlo_jetjet.py new file mode 100644 index 0000000000000000000000000000000000000000..261a666be550a19e97b8ffae6f10d4be13bf9bde --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig71EvtGen_H7UE_NNPDF30nlo_jetjet.py @@ -0,0 +1,50 @@ +name = runArgs.jobConfig[0] +name_info = name.split("_JZ")[1].split(".py") +slice = int(name_info[0]) + +minkT = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} + +# initialize Herwig7 generator configuration for built-in matrix elements +include("Herwig7_i/Herwig7_BuiltinME.py") + +# configure Herwig7 +Herwig7Config.add_commands("set /Herwig/Partons/RemnantDecayer:AllowTop Yes") +Herwig7Config.me_pdf_commands(order="NLO", name="NNPDF30_nlo_as_0118") + +command = """ +insert /Herwig/MatrixElements/SubProcess:MatrixElements[0] /Herwig/MatrixElements/MEQCD2to2 +set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0 +set /Herwig/Cuts/JetKtCut:MinKT """+str(minkT[slice])+"""*GeV + +cd /Herwig/Shower +do ShowerHandler:AddVariation isr:muRfac=2.0_fsr:muRfac=2.0 2.0 2.0 All +do ShowerHandler:AddVariation isr:muRfac=2.0_fsr:muRfac=1.0 2.0 1.0 All +do ShowerHandler:AddVariation isr:muRfac=2.0_fsr:muRfac=0.5 2.0 0.5 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=2.0" 1.0 2.0 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.5" 1.0 0.5 All +do ShowerHandler:AddVariation isr:muRfac=0.5_fsr:muRfac=2.0" 0.5 2.0 All +do ShowerHandler:AddVariation isr:muRfac=0.5_fsr:muRfac=1.0 0.5 1.0 All +do ShowerHandler:AddVariation isr:muRfac=0.5_fsr:muRfac=0.5 0.5 0.5 All +do ShowerHandler:AddVariation isr:muRfac=1.75_fsr:muRfac=1.0 1.75 1.0 All +do ShowerHandler:AddVariation isr:muRfac=1.5_fsr:muRfac=1.0 1.5 1.0 All +do ShowerHandler:AddVariation isr:muRfac=1.25_fsr:muRfac=1.0 1.25 1.0 All +do ShowerHandler:AddVariation isr:muRfac=0.625_fsr:muRfac=1.0" 0.625 1.0 All +do ShowerHandler:AddVariation isr:muRfac=0.75_fsr:muRfac=1.0 0.75 1.0 All +do ShowerHandler:AddVariation isr:muRfac=0.875_fsr:muRfac=1.0 0.875 1.0 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=1.75 1.0 1.75 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=1.5 1.0 1.5 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=1.25 1.0 1.25 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.625 1.0 0.625 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.75 1.0 0.75 All +do ShowerHandler:AddVariation isr:muRfac=1.0_fsr:muRfac=0.875 1.0 0.85 All +""" +print command + +Herwig7Config.add_commands(command) + +# add EvtGen +include("Herwig7_i/Herwig71_EvtGen.py") + +# run Herwig7 +Herwig7Config.run() + diff --git a/Generators/Herwig7_i/share/common/Herwig71_EvtGen.py b/Generators/Herwig7_i/share/common/Herwig71_EvtGen.py new file mode 100644 index 0000000000000000000000000000000000000000..58a7f58dcb7758d251e6ff984f9e6a25575466f8 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig71_EvtGen.py @@ -0,0 +1,57 @@ +## Run EvtGen afterburner on top of Pythia 8 +assert hasattr(genSeq, "Herwig7") +include("EvtGen_i/EvtGen_Fragment.py") +evgenConfig.auxfiles += ['Herwig71Inclusive.pdt'] +genSeq.EvtInclusiveDecay.pdtFile = "Herwig71Inclusive.pdt" + +Herwig7Config.add_commands(""" +# Quick "fix" to the mismatch between Herwig 7 and EvtGen of the masses below +set /Herwig/Particles/B'_c1+:NominalMass 7.3 +set /Herwig/Particles/B'_c1-:NominalMass 7.3 +set /Herwig/Particles/B_c1+:NominalMass 7.3 +set /Herwig/Particles/B_c1-:NominalMass 7.3 +set /Herwig/Particles/B_c2+:NominalMass 7.35 +set /Herwig/Particles/B_c2-:NominalMass 7.35 +set /Herwig/Particles/B*_c0+:NominalMass 7.25 +set /Herwig/Particles/B*_c0-:NominalMass 7.25 +set /Herwig/Particles/B_c+:NominalMass 6.277 +set /Herwig/Particles/B_c-:NominalMass 6.277 +# +# This is a complete kludge. Herwig7 has switched the mapping of names and pdgids for the D'(s1) and the D(s1) +# That means EvtGen misinterprets which particle it should be decaying, since the PDGID is what is written +# in the record. So, we'll set things up to change the masses so that the HEPMC record lis OK. That means +# we want: +# Mass: 2.45960 ID: 20433 (Pythia8 calls this the D*_1s+ , EvtGen calls it D_s1-. 20433 is what Herwig calls +# D'_s1+ and orginally gave it a mass of 2.53535) +# Mass: 2.53512 ID: 10433 (Pythia8 calls this the D_1s+ , EvtGen calls it D'_s1+. 10433 is what Herwig calls +# D_s1+ and orginally gave it a mass of 2.4589 +# +# Since EvtGen will redecay everything anyway, we'll make these particles stable in Herwig +# +set /Herwig/Particles/D'_s1+:NominalMass 2.4595000e+00 +set /Herwig/Particles/D'_s1+:Width 0.001 +set /Herwig/Particles/D'_s1+:WidthCut 0.01 +set /Herwig/Particles/D'_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D'_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:NominalMass 2.4595000e+00 +set /Herwig/Particles/D'_s1-:Width 0.001 +set /Herwig/Particles/D'_s1-:WidthCut 0.01 +set /Herwig/Particles/D'_s1-:Width_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:Mass_generator:Initialize Yes +set /Herwig/Particles/D_s1+:NominalMass 2.5352800e+00 +set /Herwig/Particles/D_s1+:Width 0.001 +set /Herwig/Particles/D_s1+:WidthCut 0.01 +set /Herwig/Particles/D_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D_s1-:NominalMass 2.5352800e+00 +set /Herwig/Particles/D_s1+:Width 0.001 +set /Herwig/Particles/D_s1+:WidthCut 0.01 +set /Herwig/Particles/D_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:Stable Stable +set /Herwig/Particles/D'_s1+:Stable Stable +set /Herwig/Particles/D_s1-:Stable Stable +set /Herwig/Particles/D_s1+:Stable Stable + +""") + diff --git a/Generators/Herwig7_i/share/common/Herwig7EG_Matchbox_MG_H7UEMMHT2014_dipole_multijet_withGridpack.py b/Generators/Herwig7_i/share/common/Herwig7EG_Matchbox_MG_H7UEMMHT2014_dipole_multijet_withGridpack.py new file mode 100644 index 0000000000000000000000000000000000000000..c4f8401911d0c3a4ce4b006a565af45de0e648f1 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7EG_Matchbox_MG_H7UEMMHT2014_dipole_multijet_withGridpack.py @@ -0,0 +1,131 @@ +from Herwig7_i.Herwig7_iConf import Herwig7 +from Herwig7_i.Herwig7ConfigMatchbox import Hw7ConfigMatchbox + +name = runArgs.jobConfig[0] +dsid = int(name.split(".")[1]) + +genSeq += Herwig7() + +## Provide config information +evgenConfig.generators += ["Herwig7"] +evgenConfig.tune = "MMHT2014" + +## initialize generator configuration object +generator = Hw7ConfigMatchbox(genSeq, runArgs, run_name="HerwigMatchbox", beams="pp") + +## configure generator +generator.me_pdf_commands(order="NLO", name="MMHT2014nlo68cl") +generator.tune_commands() + +# HT slice boundaries +pTDict = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} +multDict = {0:1.1,1:1.2,2:2.2,3:4.0,4:5.0,5:6.0,6:7.0,7:8.0,8:9.0,9:10.0,10:10.0,11:10.0,12:10.0} + +#Herwig7EvtGen_Matchbox_MadGraph_H7UEMMHT2014_multijet.py +name_info = name.split("_JZ")[1].split(".py")[0] +slice = int(name_info) +mergingscale = 30 + +evt_multiplier = multDict[slice] + +if runArgs.maxEvents > 0: + nevents=runArgs.maxEvents*evt_multiplier +else: + nevents=5000*evt_multiplier + +generator.add_commands(""" +read Matchbox/StandardModelLike.in +read Matchbox/DiagonalCKM.in + +## Set the order of the couplings +cd /Herwig/MatrixElements/Matchbox +set Factory:OrderInAlphaS 2 +set Factory:OrderInAlphaEW 0 + +## Select the process +## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. +do Factory:Process p p -> j j + +################################################## +## Matrix element library selection +################################################## + +## Select a generic tree/loop combination or a +## specialized NLO package + +# read Matchbox/MadGraph-GoSam.in +# read Matchbox/MadGraph-MadGraph.in +# read Matchbox/MadGraph-NJet.in + +read Matchbox/MadGraph-OpenLoops.in + +# read Matchbox/HJets.in +# read Matchbox/VBFNLO.in + +################################################## +## Cut selection +## See the documentation for more options +################################################## +cd /Herwig/Cuts/ + +## cuts on additional jets + +read Matchbox/DefaultPPJets.in + +insert JetCuts:JetRegions 0 FirstJet +""" ++ "set FirstJet:PtMin "+str(pTDict[slice])+"*GeV" +""" +################################################## +## Scale choice +## See the documentation for more options +################################################## + +cd /Herwig/MatrixElements/Matchbox +set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale + +################################################## +## Matching and shower selection +## Please also see flavour scheme settings +## towards the end of the input file. +################################################## + +read Matchbox/MCatNLO-DipoleShower.in +# read Matchbox/Powheg-DefaultShower.in +## use for strict LO/NLO comparisons +# read Matchbox/MCatLO-DefaultShower.in +## use for improved LO showering +# read Matchbox/LO-DefaultShower.in + +#read Matchbox/FiveFlavourScheme.in +## required for dipole shower and fixed order in five flavour scheme +read Matchbox/FiveFlavourNoBMassScheme.in + +""") + +# Using author's default +generator.sampler_commands("MonacoSampler", 20000, 4, 50000, 1, 100) + +if runArgs.generatorRunMode == 'build': + generator.do_build(10) + +elif runArgs.generatorRunMode == 'integrate': + generator.do_integrate(runArgs.generatorJobNumber) + +elif runArgs.generatorRunMode == 'mergegrids': + generator.do_mergegrids(10,gridpack="Herwig7_gridpack.tar.gz") + +elif runArgs.generatorRunMode == 'run': + if runArgs.runNumber == 364902: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364902.multijet_dipole_JZ2.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364903: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364903.multijet_dipole_JZ3.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364904: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364904.multijet_dipole_JZ4.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364905: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364905.multijet_dipole_JZ5.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364906: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364906.multijet_dipole_JZ6.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364907: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364907.multijet_dipole_JZ7.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364908: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364908.multijet_dipole_JZ8.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364909: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364909.multijet_dipole_JZ9.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364910: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364910.multijet_dipole_JZ10.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364911: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364911.multijet_dipole_JZ11.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364912: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364912.multijet_dipole_JZ12.TXT.mc15_v2._00001.tar.gz") + + diff --git a/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF23lo_jetjet.py b/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF23lo_jetjet.py new file mode 100644 index 0000000000000000000000000000000000000000..2a233eae33ec7a73776fd70501d80703a389c52c --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF23lo_jetjet.py @@ -0,0 +1,28 @@ +name = runArgs.jobConfig[0] +name_info = name.split("_JZ")[1].split(".py") +slice = int(name_info[0]) + +minkT = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} + +# initialize Herwig7 generator configuration for built-in matrix elements +include("Herwig7_i/Herwig7_BuiltinME.py") + +# configure Herwig7 +Herwig7Config.add_commands("set /Herwig/Partons/RemnantDecayer:AllowTop Yes") +Herwig7Config.me_pdf_commands(order="LO", name="NNPDF23_lo_as_0130_qed") + +command = """ +insert /Herwig/MatrixElements/SimpleQCD:MatrixElements[0] /Herwig/MatrixElements/MEQCD2to2 +set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0 +set /Herwig/Cuts/JetKtCut:MinKT """+str(minkT[slice])+"""*GeV +""" +print command + +Herwig7Config.add_commands(command) + +# add EvtGen +include("Herwig7_i/Herwig7_EvtGen.py") + +# run Herwig7 +Herwig7Config.run() + diff --git a/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF30nlo_dipole_jetjet.py b/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF30nlo_dipole_jetjet.py new file mode 100644 index 0000000000000000000000000000000000000000..6d792ef5ba9bac72455ad10fcb6d6570e7f32bfb --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF30nlo_dipole_jetjet.py @@ -0,0 +1,35 @@ +name = runArgs.jobConfig[0] +name_info = name.split("_JZ")[1].split(".py") +slice = int(name_info[0]) + +minkT = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} + +# initialize Herwig7 generator configuration for built-in matrix elements +include("Herwig7_i/Herwig7_BuiltinME.py") + +# configure Herwig7 +Herwig7Config.add_commands("set /Herwig/Partons/RemnantDecayer:AllowTop Yes") +Herwig7Config.me_pdf_commands(order="NLO", name="NNPDF30_nlo_as_0118") + +command = """ +insert /Herwig/MatrixElements/SimpleQCD:MatrixElements[0] /Herwig/MatrixElements/MEQCD2to2 +set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0 +set /Herwig/Cuts/JetKtCut:MinKT """+str(minkT[slice])+"""*GeV +""" +print command + +Herwig7Config.add_commands(command) + +command2 = """ +set /Herwig/Generators/LHCGenerator:EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler +read snippets/DipoleShowerFiveFlavours.in +""" +print command2 +Herwig7Config.add_commands(command2) + +# add EvtGen +include("Herwig7_i/Herwig7_EvtGen.py") + +# run Herwig7 +Herwig7Config.run() + diff --git a/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF30nlo_jetjet.py b/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF30nlo_jetjet.py new file mode 100644 index 0000000000000000000000000000000000000000..05767f46149a32f9ba36412d4f84115278313ef1 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7EvtGen_H7UE_NNPDF30nlo_jetjet.py @@ -0,0 +1,28 @@ +name = runArgs.jobConfig[0] +name_info = name.split("_JZ")[1].split(".py") +slice = int(name_info[0]) + +minkT = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} + +# initialize Herwig7 generator configuration for built-in matrix elements +include("Herwig7_i/Herwig7_BuiltinME.py") + +# configure Herwig7 +Herwig7Config.add_commands("set /Herwig/Partons/RemnantDecayer:AllowTop Yes") +Herwig7Config.me_pdf_commands(order="NLO", name="NNPDF30_nlo_as_0118") + +command = """ +insert /Herwig/MatrixElements/SimpleQCD:MatrixElements[0] /Herwig/MatrixElements/MEQCD2to2 +set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0 +set /Herwig/Cuts/JetKtCut:MinKT """+str(minkT[slice])+"""*GeV +""" +print command + +Herwig7Config.add_commands(command) + +# add EvtGen +include("Herwig7_i/Herwig7_EvtGen.py") + +# run Herwig7 +Herwig7Config.run() + diff --git a/Generators/Herwig7_i/share/common/Herwig7EvtGen_Matchbox_MadGraph_H7UEMMHT2014_multijet_withGridpack.py b/Generators/Herwig7_i/share/common/Herwig7EvtGen_Matchbox_MadGraph_H7UEMMHT2014_multijet_withGridpack.py new file mode 100644 index 0000000000000000000000000000000000000000..268a953de42006bded51945cd0b933736981abb3 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7EvtGen_Matchbox_MadGraph_H7UEMMHT2014_multijet_withGridpack.py @@ -0,0 +1,129 @@ +from Herwig7_i.Herwig7_iConf import Herwig7 +from Herwig7_i.Herwig7ConfigMatchbox import Hw7ConfigMatchbox + +name = runArgs.jobConfig[0] +dsid = int(name.split(".")[1]) + +genSeq += Herwig7() + +## Provide config information +evgenConfig.generators += ["Herwig7"] +evgenConfig.tune = "MMHT2014" + +## initialize generator configuration object +generator = Hw7ConfigMatchbox(genSeq, runArgs, run_name="HerwigMatchbox", beams="pp") + +## configure generator +generator.me_pdf_commands(order="NLO", name="MMHT2014nlo68cl") +generator.tune_commands() + +# HT slice boundaries +pTDict = {0:0,1:0,2:15,3:50,4:150,5:350,6:600,7:950,8:1500,9:2200,10:2800,11:3500,12:4200} +multDict = {0:1.1,1:1.2,2:2.2,3:4.0,4:5.0,5:6.0,6:7.0,7:8.0,8:9.0,9:10.0,10:10.0,11:10.0,12:10.0} + +#Herwig7EvtGen_Matchbox_MadGraph_H7UEMMHT2014_multijet.py +name_info = name.split("_JZ")[1].split(".py")[0] +slice = int(name_info) +mergingscale = 30 + +evt_multiplier = multDict[slice] + +if runArgs.maxEvents > 0: + nevents=runArgs.maxEvents*evt_multiplier +else: + nevents=5000*evt_multiplier + +generator.add_commands(""" +read Matchbox/StandardModelLike.in +read Matchbox/DiagonalCKM.in + +## Set the order of the couplings +cd /Herwig/MatrixElements/Matchbox +set Factory:OrderInAlphaS 2 +set Factory:OrderInAlphaEW 0 + +## Select the process +## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. +do Factory:Process p p -> j j + +################################################## +## Matrix element library selection +################################################## + +## Select a generic tree/loop combination or a +## specialized NLO package + +# read Matchbox/MadGraph-GoSam.in +# read Matchbox/MadGraph-MadGraph.in +# read Matchbox/MadGraph-NJet.in + +read Matchbox/MadGraph-OpenLoops.in + +# read Matchbox/HJets.in +# read Matchbox/VBFNLO.in + +################################################## +## Cut selection +## See the documentation for more options +################################################## +cd /Herwig/Cuts/ + +## cuts on additional jets + +read Matchbox/DefaultPPJets.in + +insert JetCuts:JetRegions 0 FirstJet +""" ++ "set FirstJet:PtMin "+str(pTDict[slice])+"*GeV" +""" +################################################## +## Scale choice +## See the documentation for more options +################################################## + +cd /Herwig/MatrixElements/Matchbox +set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale + +################################################## +## Matching and shower selection +## Please also see flavour scheme settings +## towards the end of the input file. +################################################## + +read Matchbox/MCatNLO-DefaultShower.in +# read Matchbox/Powheg-DefaultShower.in +## use for strict LO/NLO comparisons +# read Matchbox/MCatLO-DefaultShower.in +## use for improved LO showering +# read Matchbox/LO-DefaultShower.in + +read Matchbox/FiveFlavourScheme.in +## required for dipole shower and fixed order in five flavour scheme +# read Matchbox/FiveFlavourNoBMassScheme.in + +""") + +# Using author's default +generator.sampler_commands("MonacoSampler", 20000, 4, 50000, 1, 100) + +if runArgs.generatorRunMode == 'build': + generator.do_build(10) + +elif runArgs.generatorRunMode == 'integrate': + generator.do_integrate(runArgs.generatorJobNumber) + +elif runArgs.generatorRunMode == 'mergegrids': + generator.do_mergegrids(10,gridpack="Herwig7_gridpack.tar.gz") + +elif runArgs.generatorRunMode == 'run': + if runArgs.runNumber == 364922: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364922.multijet_angular_JZ2.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364923: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364923.multijet_angular_JZ3.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364924: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364924.multijet_angular_JZ4.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364925: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364925.multijet_angular_JZ5.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364926: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364926.multijet_angular_JZ6.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364927: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364927.multijet_angular_JZ7.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364928: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364928.multijet_angular_JZ8.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364929: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364929.multijet_angular_JZ9.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364930: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364930.multijet_angular_JZ10.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364931: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364931.multijet_angular_JZ11.TXT.mc15_v2._00001.tar.gz") + elif runArgs.runNumber == 364932: generator.do_run(gridpack="group.phys-gener.Herwig7_Matchbox_MG_H7UEMMHT2014.364932.multijet_angular_JZ12.TXT.mc15_v2._00001.tar.gz") diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_Base_Fragment.py b/Generators/Herwig7_i/share/common/Herwig7_701_Base_Fragment.py new file mode 100644 index 0000000000000000000000000000000000000000..9ef1172dae4c613ab9ac751bead27200f158dbfa --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_Base_Fragment.py @@ -0,0 +1,33 @@ +## JobOption fragment for Herwig 7.0.1 + +from Herwig7_i.Herwig7_iConf import Herwig7 +genSeq += Herwig7() +evgenConfig.generators += ["Herwig7"] + +try: + from Herwig7_i import config as hw +except: + raise RuntimeError(""" +The release you have set up features the re-designed Herwig7 interface in athena which makes use of Herwig7 versions >= 7.0.4. +The JobOptions, that you are trying to run, were written for and can only be used with the now discontinued interface for Herwig7 version 7.0.1, but can't be run with the new interface. +Please check if you would like to +* use more recent JobOptions, that are compatible with the new Herwig7 interface +or +* set up a different release, that includes the old interface for Herwig7 +Please have a look at https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/Herwig7ForAtlas for more information on release numbers and the corresponding interface versions. +""") + +genSeq.Herwig7.Commands += hw.atlas_parameter_cmds().splitlines() + +genSeq.Herwig7.Commands += [ + "## fix for global default settings until released with Herwig7 itself", + "set /Herwig/Shower/GtoQQbarSplitFn:AngularOrdered Yes", + "set /Herwig/Shower/GammatoQQbarSplitFn:AngularOrdered Yes", + "", + "## fix for GeV-mass photon radiation", + "set /Herwig/Shower/GammatoQQbarSudakov:Alpha /Herwig/Shower/AlphaQED", + "", + "## fix for initial-state (backward evolution) splitting", + "set /Herwig/Shower/QtoGammaQSudakov:Alpha /Herwig/Shower/AlphaQED", + "" +] diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_EvtGen.py b/Generators/Herwig7_i/share/common/Herwig7_701_EvtGen.py new file mode 100644 index 0000000000000000000000000000000000000000..abe4ae10a71c054540422a3fc4dbb5d9836a5668 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_EvtGen.py @@ -0,0 +1,60 @@ +## JobOption fragment for Herwig 7.0.1 + +## Run EvtGen afterburner on top of Pythia 8 +assert hasattr(genSeq, "Herwig7") +include("EvtGen_i/EvtGen_Fragment.py") +evgenConfig.auxfiles += ['HerwigppInclusiveP8.pdt'] +genSeq.EvtInclusiveDecay.pdtFile = "HerwigppInclusiveP8.pdt" + +# quick "fix" to the mismatch between Herwig 7 and EvtGen of the masses below +cmds1 = """ +set /Herwig/Particles/B'_c1+:NominalMass 7.3 +set /Herwig/Particles/B'_c1-:NominalMass 7.3 +set /Herwig/Particles/B_c1+:NominalMass 7.3 +set /Herwig/Particles/B_c1-:NominalMass 7.3 +set /Herwig/Particles/B_c2+:NominalMass 7.35 +set /Herwig/Particles/B_c2-:NominalMass 7.35 +set /Herwig/Particles/B*_c0+:NominalMass 7.25 +set /Herwig/Particles/B*_c0-:NominalMass 7.25 +set /Herwig/Particles/B_c+:NominalMass 6.277 +set /Herwig/Particles/B_c-:NominalMass 6.277 +# +# This is a complete kludge. Herwig7 has switched the mapping of names and pdgids for the D'(s1) and the D(s1) +# That means EvtGen misinterprets which particle it should be decaying, since the PDGID is what is written +# in the record. So, we'll set things up to change the masses so that the HEPMC record lis OK. That means +# we want: +# Mass: 2.45960 ID: 20433 (Pythia8 calls this the D*_1s+ , EvtGen calls it D_s1-. 20433 is what Herwig calls +# D'_s1+ and orginally gave it a mass of 2.53535) +# Mass: 2.53512 ID: 10433 (Pythia8 calls this the D_1s+ , EvtGen calls it D'_s1+. 10433 is what Herwig calls +# D_s1+ and orginally gave it a mass of 2.4589 +# +# Since EvtGen will redecay everything anyway, we'll make these particles stable in Herwig +# +set /Herwig/Particles/D'_s1+:NominalMass 2.4595000e+00 +set /Herwig/Particles/D'_s1+:Width 0.001 +set /Herwig/Particles/D'_s1+:WidthCut 0.01 +set /Herwig/Particles/D'_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D'_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:NominalMass 2.4595000e+00 +set /Herwig/Particles/D'_s1-:Width 0.001 +set /Herwig/Particles/D'_s1-:WidthCut 0.01 +set /Herwig/Particles/D'_s1-:Width_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:Mass_generator:Initialize Yes +set /Herwig/Particles/D_s1+:NominalMass 2.5352800e+00 +set /Herwig/Particles/D_s1+:Width 0.001 +set /Herwig/Particles/D_s1+:WidthCut 0.01 +set /Herwig/Particles/D_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D_s1-:NominalMass 2.5352800e+00 +set /Herwig/Particles/D_s1+:Width 0.001 +set /Herwig/Particles/D_s1+:WidthCut 0.01 +set /Herwig/Particles/D_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:Stable Stable +set /Herwig/Particles/D'_s1+:Stable Stable +set /Herwig/Particles/D_s1-:Stable Stable +set /Herwig/Particles/D_s1+:Stable Stable +""" +genSeq.Herwig7.Commands += cmds1.splitlines() + +del cmds1 diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..408517dd82f3e2c2b90aa51a9444982ba09ea95d --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_Common.py @@ -0,0 +1,15 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with CT10 NLO ME PDF +include("Herwig7_i/Herwig7_701_Base_Fragment.py") + +## Construct command set +from Herwig7_i import config as hw +cmds = hw.energy_cmds(runArgs.ecmEnergy) + hw.base_cmds() \ + + hw.nlo_pdf_cmds("CT10.LHgrid", "MMHT2014lo68cl.LHpdf") \ + + hw.ue_tune_cmds("H7-UE-MMHT") +genSeq.Herwig7.Commands += cmds.splitlines() +del cmds + +evgenConfig.tune = "H7-UE-MMHT" + diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..c7661897b81e941393178fd63a54cebfd8b3a428 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_EvtGen_Common.py @@ -0,0 +1,5 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with CT10 NLO ME PDF and EvtGen +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_Common.py") +include("Herwig7_i/Herwig7_701_EvtGen.py") diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_LHEF_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_LHEF_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..43a42cba937a9977d136e9d9bbf12a4eaec0cf26 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_LHEF_Common.py @@ -0,0 +1,7 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with CT10 NLO ME PDF with NLO events read from a LHEF file +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_Common.py") + +from Herwig7_i import config as hw +genSeq.Herwig7.Commands += hw.lhef_cmds(filename="events.lhe", nlo=True).splitlines() diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_LHEF_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_LHEF_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..78cd2e19202a0493cc5100ceb33b59af485edf0d --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_LHEF_EvtGen_Common.py @@ -0,0 +1,7 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with CT10 NLO ME PDF with NLO events read from a LHEF file and decays done with EvtGen +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_CT10_EvtGen_Common.py") + +from Herwig7_i import config as hw +genSeq.Herwig7.Commands += hw.lhef_cmds(filename="events.lhe", nlo=True).splitlines() diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..6a600e65b040cf8301f4ebf80f41639b34a07a5d --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_EvtGen_Common.py @@ -0,0 +1,15 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with a CT10f4 NLO ME PDF +include("Herwig7_i/Herwig7_701_Base_Fragment.py") + +## Construct command set +from Herwig7_i import config as hw +cmds = hw.energy_cmds(runArgs.ecmEnergy) + hw.base_cmds() \ + + hw.nlo_pdf_cmds("CT10f4.LHgrid", "MMHT2014lo68cl.LHpdf") \ + + hw.ue_tune_cmds("H7-UE-MMHT") +genSeq.Herwig7.Commands += cmds.splitlines() +del cmds +include("Herwig7_i/Herwig7_701_EvtGen.py") + +evgenConfig.tune = "H7-UE-MMHT" diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_LHEF_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_LHEF_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..671b2c92e81c2efe0871200ceca2fa01b93894a1 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_LHEF_EvtGen_Common.py @@ -0,0 +1,7 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with a CT10f4 NLO ME PDF with NLO events read from an LHEF file +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_CT10f4ME_EvtGen_Common.py") + +from Herwig7_i import config as hw +genSeq.Herwig7.Commands += hw.lhef_cmds(filename="events.lhe", nlo=True).splitlines() diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..c334313442f77bda328a73d7b8c202385fb1e741 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_Common.py @@ -0,0 +1,15 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with the MMHT2014 LO ME PDF +include("Herwig7_i/Herwig7_701_Base_Fragment.py") + +## Construct command set +from Herwig7_i import config as hw +cmds = hw.energy_cmds(runArgs.ecmEnergy) + hw.base_cmds() \ + + hw.lo_pdf_cmds("MMHT2014lo68cl.LHpdf") \ + + hw.ue_tune_cmds("H7-UE-MMHT") +genSeq.Herwig7.Commands += cmds.splitlines() +del cmds + +evgenConfig.tune = "H7-UE-MMHT" + diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..3a1b8ef4ab70b8aa9f1c1c3155053c5a4384165c --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_EvtGen_Common.py @@ -0,0 +1,5 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with MMHT2014 LO PDF and EvtGen +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_Common.py") +include("Herwig7_i/Herwig7_701_EvtGen.py") diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..f712135625b7a7837f956971ad896aeaa0f50311 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_Common.py @@ -0,0 +1,15 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with NNPDF3.0 NLO ME PDF +include("Herwig7_i/Herwig7_701_Base_Fragment.py") + +## Construct command set +from Herwig7_i import config as hw +cmds = hw.energy_cmds(runArgs.ecmEnergy) + hw.base_cmds() \ + + hw.nlo_pdf_cmds("NNPDF30_nlo_as_0118.LHgrid", "MMHT2014lo68cl.LHpdf") \ + + hw.ue_tune_cmds("H7-UE-MMHT") +genSeq.Herwig7.Commands += cmds.splitlines() +del cmds + +evgenConfig.tune = "H7-UE-MMHT" + diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..5979883b94fb93b430be01618d588fa9db6b2116 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_EvtGen_Common.py @@ -0,0 +1,5 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with NNPDF3.0 NLO ME PDF and EvtGen +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_Common.py") +include("Herwig7_i/Herwig7_701_EvtGen.py") diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_LHEF_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_LHEF_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..4477caf7404d41047e0602ddc190dc34897889a7 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_LHEF_Common.py @@ -0,0 +1,7 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with NNPDF3.0 NLO ME PDF with NLO events read from a LHEF file +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_Common.py") + +from Herwig7_i import config as hw +genSeq.Herwig7.Commands += hw.lhef_cmds(filename="events.lhe", nlo=True).splitlines() diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_LHEF_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_LHEF_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..33204b7ed60803988dcae964794e115fc9c32362 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_LHEF_EvtGen_Common.py @@ -0,0 +1,7 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for the H7-UE-MMHT tune series with NNPDF3.0 NLO ME PDF with NLO events read from a LHEF file and decays done with EvtGen +include("Herwig7_i/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3ME_EvtGen_Common.py") + +from Herwig7_i import config as hw +genSeq.Herwig7.Commands += hw.lhef_cmds(filename="events.lhe", nlo=True).splitlines() diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3nnloME_LHEF_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3nnloME_LHEF_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..111c2b3ec4bf3fa05c864bd5184adceed273cc2c --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_H7UE_MMHT2014lo68cl_NNPDF3nnloME_LHEF_EvtGen_Common.py @@ -0,0 +1,19 @@ +## JobOption fragment for Herwig 7.0.1 + +include("Herwig7_i/Herwig7_701_Base_Fragment.py") + +## Herwig7 config for the H7-UE-MMHT tune series with NNPDF3.0 NNLO ME PDF with events read from a LHEF file and decays done with EvtGen + +## Construct command set +from Herwig7_i import config as hw +cmds = hw.energy_cmds(runArgs.ecmEnergy) + hw.base_cmds() \ + + hw.nlo_pdf_cmds("NNPDF30_nnlo_as_0118.LHgrid", "MMHT2014lo68cl.LHpdf") \ + + hw.ue_tune_cmds("H7-UE-MMHT") +genSeq.Herwig7.Commands += cmds.splitlines() +del cmds + +evgenConfig.tune = "H7-UE-MMHT" + +genSeq.Herwig7.Commands += hw.lhef_cmds(filename="events.lhe", nlo=True).splitlines() + +include("Herwig7_i/Herwig7_701_EvtGen.py") diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_QED_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_QED_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..09508b44e411b3651d3906a3ead5ee62c39725e8 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_QED_Common.py @@ -0,0 +1,17 @@ +## JobOption fragment for Herwig 7.0.1 + +# Common job option for gamma gamma processes in Herwig7 +# MPI tune is not relevant as the pdf_gammagamma_cmds() function disables MPI +# Contact: Oldrich Kepka +include("MC15JobOptions/Herwig7_701_Base_Fragment.py") +from Herwig7_i import config as hw +cmds = hw.energy_cmds(runArgs.ecmEnergy) + hw.base_cmds() + hw.pdf_gammagamma_cmds() +cmds += """ +set /Herwig/Partons/QCDExtractor:FirstPDF /Herwig/Partons/BudnevPDF +set /Herwig/Partons/QCDExtractor:SecondPDF /Herwig/Partons/BudnevPDF +""" +cmds += "create ThePEG::O1AlphaS /Herwig/AlphaQCD_O1 O1AlphaS.so\n" +cmds += "set /Herwig/Generators/LHCGenerator:StandardModelParameters:QCD/RunningAlphaS /Herwig/AlphaQCD_O1\n" +cmds += "set /Herwig/Partons/BudnevPDF:Q2Max 4." +genSeq.Herwig7.Commands += cmds.splitlines() +del cmds diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_QED_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_701_QED_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..47174618709c5302dcb8da9cf7269553c8af1b9b --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_QED_EvtGen_Common.py @@ -0,0 +1,5 @@ +## JobOption fragment for Herwig 7.0.1 + +## Herwig7 config for Herwig7_QED and EvtGen +include("Herwig7_i/Herwig7_701_QED_Common.py") +include("Herwig7_i/Herwig7_701_EvtGen.py") diff --git a/Generators/Herwig7_i/share/common/Herwig7_701_StripWeights.py b/Generators/Herwig7_i/share/common/Herwig7_701_StripWeights.py new file mode 100644 index 0000000000000000000000000000000000000000..8c7b032e9c067bea2d9c5c17efb5de9462e274a6 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_701_StripWeights.py @@ -0,0 +1,54 @@ +import os, shutil + +m_inFile = runArgs.inputGeneratorFile + +if not m_inFile: + exit() + +# Pick name Prefix +# - if original file is compressed then athena places the uncompressed +# LHE file in the current working directory before this script is executed +m_Prefix = None +if m_inFile is not None: + if '.tar.gz' in m_inFile: + m_Prefix = os.path.split(m_inFile)[1].split('.tar.gz')[0] + elif '.events' in m_inFile: + m_Prefix = os.path.split(m_inFile)[1].split('.events')[0] + abs_path = os.path.split(os.path.abspath(m_inFile))[0] + cwd_path = os.getcwd() + if abs_path != cwd_path: # if original file is in a different folder + # uncompressed LHE file in a different folder is not supported by job transform, + # rectify this by copying the original LHE file to the current working directory + shutil.copyfile(m_inFile, os.path.split(m_inFile)[1]) + +m_lhe_extracted_old = m_Prefix+".events" +m_lhe_extracted_new = "new."+m_Prefix+".events" + +if m_Prefix is None: + raise RuntimeError("File title could not be determined because of unknown file extension") + +# Strip Weights from old LHE file and write new LHE file +weights = False +with open(m_lhe_extracted_old, "r") as lhef_in: + with open(m_lhe_extracted_new, "w") as lhef_out: + + for line in lhef_in: + + # find tags related to multiple/optional weights + if "<initrwgt>" in line or "<rwgt>" in line: + weights = True + + # propagate line if we are currently not in a line + # related to the optional/multiple event weights + if not weights: + lhef_out.write(line) + + # remember end of optional/multiple event weights lines + if "</initrwgt>" in line or "</rwgt>" in line: + weights = False + +# Delete old (unstripped) LHE file +os.remove(m_lhe_extracted_old) + +# Rename new (stripped) LHE file to the old filename +shutil.move(m_lhe_extracted_new, m_lhe_extracted_old) diff --git a/Generators/Herwig7_i/share/common/Herwig7_BuiltinME.py b/Generators/Herwig7_i/share/common/Herwig7_BuiltinME.py new file mode 100644 index 0000000000000000000000000000000000000000..c7c3484e2ece2e4a9b347ddc9f3dd6a4352982bf --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_BuiltinME.py @@ -0,0 +1,8 @@ +# initialize Herwig7 generator configuration object for built-in/old-style matrix elements + +from Herwig7_i.Herwig7_iConf import Herwig7 +from Herwig7_i.Herwig7ConfigBuiltinME import Hw7ConfigBuiltinME + +genSeq += Herwig7() +Herwig7Config = Hw7ConfigBuiltinME(genSeq, runArgs) + diff --git a/Generators/Herwig7_i/share/common/Herwig7_EvtGen.py b/Generators/Herwig7_i/share/common/Herwig7_EvtGen.py new file mode 100644 index 0000000000000000000000000000000000000000..5279993acbf0c9008d3165e3ba667d552328b1ee --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_EvtGen.py @@ -0,0 +1,57 @@ +## Run EvtGen afterburner on top of Pythia 8 +assert hasattr(genSeq, "Herwig7") +include("EvtGen_i/EvtGen_Fragment.py") +evgenConfig.auxfiles += ['HerwigppInclusiveP8.pdt'] +genSeq.EvtInclusiveDecay.pdtFile = "HerwigppInclusiveP8.pdt" + +Herwig7Config.add_commands(""" +# Quick "fix" to the mismatch between Herwig 7 and EvtGen of the masses below +set /Herwig/Particles/B'_c1+:NominalMass 7.3 +set /Herwig/Particles/B'_c1-:NominalMass 7.3 +set /Herwig/Particles/B_c1+:NominalMass 7.3 +set /Herwig/Particles/B_c1-:NominalMass 7.3 +set /Herwig/Particles/B_c2+:NominalMass 7.35 +set /Herwig/Particles/B_c2-:NominalMass 7.35 +set /Herwig/Particles/B*_c0+:NominalMass 7.25 +set /Herwig/Particles/B*_c0-:NominalMass 7.25 +set /Herwig/Particles/B_c+:NominalMass 6.277 +set /Herwig/Particles/B_c-:NominalMass 6.277 +# +# This is a complete kludge. Herwig7 has switched the mapping of names and pdgids for the D'(s1) and the D(s1) +# That means EvtGen misinterprets which particle it should be decaying, since the PDGID is what is written +# in the record. So, we'll set things up to change the masses so that the HEPMC record lis OK. That means +# we want: +# Mass: 2.45960 ID: 20433 (Pythia8 calls this the D*_1s+ , EvtGen calls it D_s1-. 20433 is what Herwig calls +# D'_s1+ and orginally gave it a mass of 2.53535) +# Mass: 2.53512 ID: 10433 (Pythia8 calls this the D_1s+ , EvtGen calls it D'_s1+. 10433 is what Herwig calls +# D_s1+ and orginally gave it a mass of 2.4589 +# +# Since EvtGen will redecay everything anyway, we'll make these particles stable in Herwig +# +set /Herwig/Particles/D'_s1+:NominalMass 2.4595000e+00 +set /Herwig/Particles/D'_s1+:Width 0.001 +set /Herwig/Particles/D'_s1+:WidthCut 0.01 +set /Herwig/Particles/D'_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D'_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:NominalMass 2.4595000e+00 +set /Herwig/Particles/D'_s1-:Width 0.001 +set /Herwig/Particles/D'_s1-:WidthCut 0.01 +set /Herwig/Particles/D'_s1-:Width_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:Mass_generator:Initialize Yes +set /Herwig/Particles/D_s1+:NominalMass 2.5352800e+00 +set /Herwig/Particles/D_s1+:Width 0.001 +set /Herwig/Particles/D_s1+:WidthCut 0.01 +set /Herwig/Particles/D_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D_s1-:NominalMass 2.5352800e+00 +set /Herwig/Particles/D_s1+:Width 0.001 +set /Herwig/Particles/D_s1+:WidthCut 0.01 +set /Herwig/Particles/D_s1+:Width_generator:Initialize Yes +set /Herwig/Particles/D_s1+:Mass_generator:Initialize Yes +set /Herwig/Particles/D'_s1-:Stable Stable +set /Herwig/Particles/D'_s1+:Stable Stable +set /Herwig/Particles/D_s1-:Stable Stable +set /Herwig/Particles/D_s1+:Stable Stable + +""") + diff --git a/Generators/Herwig7_i/share/common/Herwig7_LHEF.py b/Generators/Herwig7_i/share/common/Herwig7_LHEF.py new file mode 100644 index 0000000000000000000000000000000000000000..4dcaf84da3ac94cf9a759d3d0caa88bf188c56e6 --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_LHEF.py @@ -0,0 +1,30 @@ +# initialize Herwig7 generator configuration object for showering of LHE files +include("EvgenProdTools/merge_lhe_files.py") + +from Herwig7_i.Herwig7_iConf import Herwig7 +from Herwig7_i.Herwig7ConfigLHEF import Hw7ConfigLHEF + +genSeq += Herwig7() +Herwig7Config = Hw7ConfigLHEF(genSeq, runArgs) + +# handle compressed LHE files passed via runArgs.inputGeneratorFile +import glob +from AthenaCommon import Logging +athMsgLog = Logging.logging.getLogger('Herwig7_i/Herwig7_LHEF.py') +if ".tar.gz" in runArgs.inputGeneratorFile or ".tgz" in runArgs.inputGeneratorFile: + athMsgLog.info("inputGeneratorFile '{}' is compressed - will look for uncompressed LHE file".format(runArgs.inputGeneratorFile)) + lhe_files = glob.glob("*._*.ev*ts") + athMsgLog.info("Number of lhe files {}".format(len(lhe_files))) + if len(lhe_files) == 0: + raise RuntimeError("Could not find uncompressed LHE file") + if len(lhe_files) > 1: + athMsgLog.info("Found more than one uncompressed LHE file: {}".format(lhe_files)) +# my_lhe_file = "merged_lhef.events" +# skeleton.GENtoEVGEN splits the file name on "._" (in rel. 20.7.9.9.6,MCProd, +# so insert this in the merged file name - to make it run also for this release) + my_lhe_file = "merged_lhef._0.events" + merge_lhe_files(lhe_files, my_lhe_file ) + lhe_files[0] = my_lhe_file + athMsgLog.info("Using uncompressed LHE file '{}' as inputGeneratorFile".format(lhe_files[0])) + runArgs.inputGeneratorFile = lhe_files[0] + diff --git a/Generators/Herwig7_i/share/common/Herwig7_QED_EvtGen_Common.py b/Generators/Herwig7_i/share/common/Herwig7_QED_EvtGen_Common.py new file mode 100644 index 0000000000000000000000000000000000000000..5b15aad75c4e151c57afbda5495560839e17829a --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_QED_EvtGen_Common.py @@ -0,0 +1,33 @@ +# JobOption fragment for Herwig >=7.0.4 + +# Common job option for gamma gamma processes in Herwig7 +# Contact: Oldrich Kepka + +assert hasattr(genSeq, "Herwig7") + +Herwig7Config.add_commands(Herwig7Config.pdf_gammagamma_cmds()) + + +cmds = """ +set /Herwig/Partons/QCDExtractor:FirstPDF /Herwig/Partons/BudnevPDF +set /Herwig/Partons/QCDExtractor:SecondPDF /Herwig/Partons/BudnevPDF +set /Herwig/Partons/BudnevPDF:Q2Max 4. + +create ThePEG::O1AlphaS /Herwig/AlphaQCD_O1 O1AlphaS.so +set /Herwig/Generators/LHCGenerator:StandardModelParameters:QCD/RunningAlphaS /Herwig/AlphaQCD_O1 + +# Cuts +cd /Herwig/Cuts +set QCDCuts:ScaleMin 0.0*MeV +set QCDCuts:X1Min 0 +set QCDCuts:X2Min 0 +set QCDCuts:X1Max 1. +set QCDCuts:X2Max 1. +erase QCDCuts:MultiCuts 0 +""" +Herwig7Config.add_commands(cmds) +del cmds + +# To avoid warning from displaced vertices, bugfix needed in herwig++ +testSeq.TestHepMC.MaxTransVtxDisp = 1000000 +testSeq.TestHepMC.MaxVtxDisp = 1000000000 diff --git a/Generators/Herwig7_i/share/common/Herwig7_QED_EvtGen_ll.py b/Generators/Herwig7_i/share/common/Herwig7_QED_EvtGen_ll.py new file mode 100644 index 0000000000000000000000000000000000000000..5e77d470797fd1d4e0d2124ed7ba3c06153e3c6d --- /dev/null +++ b/Generators/Herwig7_i/share/common/Herwig7_QED_EvtGen_ll.py @@ -0,0 +1,47 @@ +# JobOption fragment for Herwig >=7.0.4 + +# Common job option for gamma gamma -> ll processes in Herwig7 +# Generation in Min < M < Max window. Min/Max and lepton flavour determined +# from the JO name, e.g. MC15.363749.Herwig7EvtGen_BudnevQED_ggTOee_20M45_LeptonFilter.py +# Contact: Oldrich Kepka + +# Finnal states to be found in the JO name +h7finalStates = {"ggTOee": "Electron", "ggTOmumu": "Muon", "ggTOtautau": "Tau" } + +# Assert right JO name format +info = runArgs.jobConfig[0].split("_") +assert (info[1] == "BudnevQED") , "JobOption name does not contain BudnevQED" +assert (info[2] in h7finalStates), "Unknown final state key %s" % info[2] + +# Extract final state and mass range from the JO name +fs = h7finalStates[info[2]] +mrange = info[3].split('M') +assert (len(mrange) >0), "Cannot extract mass range from the JO" +del h7finalStates + + +# Initialize Herwig7 generator configuration for built-in matrix elements +include("Herwig7_i/Herwig7_BuiltinME.py") + +# Generic QED include with maximum phase-space +include("Herwig7_i/Herwig7_QED_EvtGen_Common.py") + +# Mmin<M<Mmax +command = """\ +set QCDCuts:MHatMin """+str(mrange[0])+"""*GeV\n""" +if len(mrange) > 1 and mrange[1]!='': + command += "set QCDCuts:MHatMax "+str(mrange[1])+"*GeV\n" + +# Hard process +command += """\ +set LeptonKtCut:MinKT 2*GeV # save minimal setting, override in upstream jo if pT-filter used +cd /Herwig/MatrixElements +insert SimpleQCD:MatrixElements 0 /Herwig/MatrixElements/MEgg2ff +set /Herwig/MatrixElements/MEgg2ff:Process """+str(fs)+""" +""" + + +Herwig7Config.add_commands(command) +del command +del mrange +del fs diff --git a/Generators/Herwig7_i/src/Herwig7.cxx b/Generators/Herwig7_i/src/Herwig7.cxx index 1575dffa450e4b249044ef3769aaeaca9ec677e5..de6e73ba6133cac7441a241c47c2f0aad99fb80e 100644 --- a/Generators/Herwig7_i/src/Herwig7.cxx +++ b/Generators/Herwig7_i/src/Herwig7.cxx @@ -1,10 +1,5 @@ // -*- C++ -*- -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - - /*! \file Herwig7.cxx * \brief Implementation of the Herwig 7 Athena interface. * \author Daniel Rauch (daniel.rauch@desy.de) @@ -27,9 +22,13 @@ #include "ThePEG/PDF/PartonExtractor.h" #include "ThePEG/PDF/PDF.h" +#include "Herwig/API/HerwigAPI.h" + #include "PathResolver/PathResolver.h" -#include <boost/algorithm/string.hpp> +#include "boost/thread/thread.hpp" +#include "boost/filesystem.hpp" +#include "boost/algorithm/string.hpp" #include "boost/foreach.hpp" #define foreach BOOST_FOREACH @@ -62,13 +61,23 @@ using namespace std; // Constructor Herwig7::Herwig7(const string& name, ISvcLocator* pSvcLocator) : GenModule(name, pSvcLocator), - m_pdfname_me("UNKNOWN"), - m_pdfname_mpi("UNKNOWN") + m_use_seed_from_generatetf(false), + m_seed_from_generatetf(0), + m_pdfname_me("UNKNOWN"), m_pdfname_mpi("UNKNOWN") // m_pdfname_ps("UNKONWN"), { - declareProperty("Commands", m_herwigCommandVector); - declareProperty("RunName", m_runname="Atlas"); - declareProperty("InFileDump", m_infiledump="herwigInfileDump.in"); + declareProperty("RunFile", m_runfile="Herwig7"); + declareProperty("SetupFile", m_setupfile=""); + + declareProperty("UseRandomSeedFromGeneratetf", m_use_seed_from_generatetf); + declareProperty("RandomSeedFromGeneratetf", m_seed_from_generatetf); + + declareProperty("PDFNameME", m_pdfname_me); + // declareProperty("PDFNamePS", m_pdfname_ps); + declareProperty("PDFNameMPI", m_pdfname_mpi); + declareProperty("CrossSectionScaleFactor", m_xsscale=1.0); + + declareProperty("CleanupHerwigScratch", m_cleanup_herwig_scratch); } @@ -93,7 +102,14 @@ StatusCode Herwig7::genInitialize() { // Represent the combined seed as a string, so the config system can parse it back to a long ;) ostringstream ss_seed; ss_seed << combined_seed; - string atlseed = ss_seed.str(); + // Configure the API and print the seed to the log + if (m_use_seed_from_generatetf){ + ATH_MSG_INFO("Using the random number seed " + to_string(m_seed_from_generatetf) + " provided via Generate_tf.py"); + m_api.seed(m_seed_from_generatetf); + } else { + ATH_MSG_INFO("Using the random number seed " + ss_seed.str() + " provided by athena"); + m_api.seed(combined_seed); + } // Change repo log level and make sure that config errors result in a program exit //ThePEG::Debug::level = 10000; @@ -142,108 +158,16 @@ StatusCode Herwig7::genInitialize() { const string repopath = PathResolver::find_file_from_list("HerwigDefaults.rpo", reposearchpaths); ATH_MSG_DEBUG("Loading Herwig default repo from " << repopath); ThePEG::Repository::load(repopath); - ATH_MSG_DEBUG("Loaded Herwig default repository"); - - - // Prepend the defaults to the command vector, so that *everything* gets dumped - ATH_MSG_DEBUG("Defining default params"); - CommandVector defaultcmds; - defaultcmds.push_back("cd /Herwig/Generators"); - defaultcmds.push_back("set /Herwig/Generators/LHCGenerator:RandomNumberGenerator:Seed " + atlseed); - defaultcmds.push_back("set /Herwig/Generators/LHCGenerator:DebugLevel 1"); - defaultcmds.push_back("set /Herwig/Generators/LHCGenerator:PrintEvent 0"); - defaultcmds.push_back("set /Herwig/Generators/LHCGenerator:MaxErrors 1000000"); - defaultcmds.push_back("set /Herwig/Generators/LHCGenerator:NumberOfEvents 1000000000"); - defaultcmds.push_back("set /Herwig/Generators/LHCGenerator:UseStdout Yes"); - - // Append config directives from job options to the defaults - CommandVector cmds = defaultcmds; - cmds.insert(cmds.begin()+cmds.size(), m_herwigCommandVector.begin(), m_herwigCommandVector.end()); - - // Apply the config commands - ATH_MSG_DEBUG("Processing default and job option commands"); - string commands = ""; - foreach (const string& cmd, cmds) { - commands += "\n" + cmd; - const size_t iNonSpace = cmd.find_first_not_of(" "); - // Only run the command if it's not just whitespace or a comment - if (iNonSpace != string::npos && cmd.data()[iNonSpace] != '#') { - ATH_MSG_DEBUG("Herwig7 command: " << cmd); - const string reply = ThePEG::Repository::exec(cmd, std::cout); - if (!reply.empty()) { - if (reply.find("Error") != string::npos) { - ATH_MSG_ERROR("Herwig7 error: " + reply); - return StatusCode::FAILURE; - } else { - ATH_MSG_INFO("Herwig7 info: " + reply); - } - } - } - } - ATH_MSG_DEBUG("Updating repository"); - ThePEG::Repository::update(); - - // Dump out the config commands, with an extra saverun to make life easier - ostringstream ss_cmds; - ss_cmds << commands << "\n\n" - << "# Extra saverun for standalone convenience: Athena doesn't execute this\n" - << "saverun " << m_runname << " /Herwig/Generators/LHCGenerator\n"; - const string dumpcommands = ss_cmds.str(); - ATH_MSG_DEBUG("All job option commands:\n" << dumpcommands); - if (m_infiledump.length() > 0) { - ofstream f(m_infiledump.c_str()); - f << dumpcommands; - f.close(); - } + ATH_MSG_DEBUG("Successfully loaded Herwig default repository"); - // PDF settings checks - //cout << ThePEG::Repository::exec("get /Herwig/Particles/p+:PDF", std::cout) << endl; - //cout << ThePEG::Repository::exec("get /Herwig/Particles/p+:PDF:PDFName", std::cout) << endl; - - // Make a "run" object from the config repository. - ATH_MSG_DEBUG("Getting generator from ThePEG."); - ThePEG::EGPtr tmpEG = ThePEG::BaseRepository::GetObject<ThePEG::EGPtr>("/Herwig/Generators/LHCGenerator"); - try { - ATH_MSG_DEBUG("Reducing repository to single LHC generator run"); - m_hw = ThePEG::Repository::makeRun(tmpEG, m_runname); - } catch (ThePEG::Exception& e) { - ATH_MSG_ERROR("Exception in ThePEG: " << e.what()); - throw; - } catch (std::exception& e) { - ATH_MSG_ERROR("STL exception: " << e.what()); - throw; - } + ATH_MSG_INFO("Setting runfile name '"+m_runfile+"'"); + m_api.inputfile(m_runfile); + + ATH_MSG_INFO("starting to prepare the run from runfile '"+m_runfile+"'..."); - // Write out some run parameters - const string repo_energy = ThePEG::Repository::exec("get /Herwig/Generators/LHCGenerator:EventHandler:LuminosityFunction:Energy", std::cout); - ATH_MSG_INFO("Run energy: " + repo_energy + " GeV"); - const string repo_seed = ThePEG::Repository::exec("get /Herwig/Generators/LHCGenerator:RandomNumberGenerator:Seed", std::cout); - ATH_MSG_INFO("Random seed: " + repo_seed); - // MPI parameters - const string repo_intrkt = ThePEG::Repository::exec("get /Herwig/Shower/Evolver:IntrinsicPtGaussian", std::cout); - ATH_MSG_INFO("Intrinsic kT: " + repo_intrkt + " GeV/c"); - const string repo_ptmatch = ThePEG::Repository::exec("get /Herwig/UnderlyingEvent/MPIHandler:pTmin0", std::cout); - ATH_MSG_INFO("MPI matching pT0: " + repo_ptmatch + " GeV/c"); - const string repo_invrad = ThePEG::Repository::exec("get /Herwig/UnderlyingEvent/MPIHandler:InvRadius", std::cout); - ATH_MSG_INFO("Inverse hadron radius: " + repo_invrad + " GeV**2"); - // Kinematic efficiency cuts - const string repo_jetminkt = ThePEG::Repository::exec("get /Herwig/Cuts/JetKtCut:MinKT", std::cout); - ATH_MSG_INFO("Minimum jet kT: " + repo_jetminkt + " GeV/c"); - const string repo_lepminkt = ThePEG::Repository::exec("get /Herwig/Cuts/LeptonKtCut:MinKT", std::cout); - ATH_MSG_INFO("Minimum lepton kT: " + repo_lepminkt + " GeV/c"); - const string repo_photonminkt = ThePEG::Repository::exec("get /Herwig/Cuts/PhotonKtCut:MinKT", std::cout); - ATH_MSG_INFO("Minimum photon kT: " + repo_photonminkt + " GeV/c"); - // PDFs - const string me_pdf = ThePEG::Repository::exec("get /Herwig/Particles/p+:PDF:PDFName", std::cout); - m_pdfname_me = (me_pdf.find("***") == string::npos) ? me_pdf : "UNKNOWN"; - ATH_MSG_INFO("Matrix element PDF: " + m_pdfname_me); - const string mpi_pdf = ThePEG::Repository::exec("get /Herwig/Shower/ShowerHandler:PDFA:PDFName", std::cout); - m_pdfname_mpi = (mpi_pdf.find("***") == string::npos && mpi_pdf.find("Error:") == string::npos) ? mpi_pdf : m_pdfname_me; - ATH_MSG_INFO("MPI PDF: " + m_pdfname_mpi); - - // Initialise the run - ATH_MSG_DEBUG("Calling Herwig7 initialize()"); - m_hw->initialize(); + // read in a Herwig runfile and obtain the event generator + m_gen = Herwig::API::prepareRun(m_api); + ATH_MSG_DEBUG("preparing the run..."); return StatusCode::SUCCESS; } @@ -254,9 +178,9 @@ StatusCode Herwig7::genInitialize() { * Run the generator for one event and store the event internally. */ StatusCode Herwig7::callGenerator() { - ATH_MSG_DEBUG("Herwig7 generating"); - assert(m_hw); - m_event = m_hw->shoot(); + ATH_MSG_DEBUG("Herwig7 generating an event"); + assert(m_gen); + m_event = m_gen->shoot(); return StatusCode::SUCCESS; } @@ -328,12 +252,31 @@ StatusCode Herwig7::fillEvt(HepMC::GenEvent* evt) { */ StatusCode Herwig7::genFinalize() { ATH_MSG_INFO("Herwig7 finalizing."); - assert(m_hw); + assert(m_gen); cout << "MetaData: generator = Herwig7 " << HWVERSION << endl; - cout << std::scientific << std::setprecision(5) << "MetaData: cross-section (nb) = " << m_hw->eventHandler()->integratedXSec()*m_xsscale/ThePEG::nanobarn << endl; + cout << std::scientific << std::setprecision(5) << "MetaData: cross-section (nb) = " << m_gen->eventHandler()->integratedXSec()*m_xsscale/ThePEG::nanobarn << endl; + // cout << "MetaData: PDF = " << m_pdfname_me << " (ME); " << m_pdfname_ps << " (shower); " << m_pdfname_mpi << " (MPI)" << endl; cout << "MetaData: PDF = " << m_pdfname_me << " (ME); " << m_pdfname_mpi << " (shower/MPI)" << endl; - m_hw->finalize(); + m_gen->finalize(); ThePEG::Repository::cleanup(); + + // possibly tidy up working directory + if (m_cleanup_herwig_scratch && boost::filesystem::is_directory("Herwig-scratch")){ + + ATH_MSG_INFO("removing Herwig-scratch folder from "+boost::filesystem::current_path().string()); + + // sleep for some time to allow all access to terminate + boost::this_thread::sleep(boost::posix_time::seconds(5)); /// \todo Think of other way to wait for all access to terminate + + // in case the folder can't be deleted continue with warning + try { + boost::filesystem::remove_all("Herwig-scratch"); + } catch (const exception& e) { + ATH_MSG_WARNING("Failed to delete the folder 'Herwig-scratch': "+string(e.what())); + } + + } + return StatusCode::SUCCESS; } diff --git a/Generators/Herwig7_i/src/components/Herwig7_i_load.cxx b/Generators/Herwig7_i/src/components/Herwig7_i_load.cxx new file mode 100644 index 0000000000000000000000000000000000000000..280170ff40183c59114a38cae5a5dfa3b0f0135c --- /dev/null +++ b/Generators/Herwig7_i/src/components/Herwig7_i_load.cxx @@ -0,0 +1,3 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES(Herwig7_i) diff --git a/Projects/Athena/externals/Herwig3.cmake b/Projects/Athena/externals/Herwig3.cmake index 85b274e718d80c99f20cc7dd3855faa8c184f0db..9e84bcad7793547f59c5baaf9ee94761d9738477 100644 --- a/Projects/Athena/externals/Herwig3.cmake +++ b/Projects/Athena/externals/Herwig3.cmake @@ -2,6 +2,6 @@ # File specifying the location of Herwig3 to use. # -set( HERWIG3_LCGVERSION 7.0.4 ) +set( HERWIG3_LCGVERSION 7.1.3p1 ) set( HERWIG3_LCGROOT ${LCG_RELEASE_DIR}/MCGenerators/herwig++/${HERWIG3_LCGVERSION}/${LCG_PLATFORM} ) diff --git a/Projects/Athena/externals/ThePEG.cmake b/Projects/Athena/externals/ThePEG.cmake index d4739d0012fee887f240c06720e752307d39f90c..8773d80e083448ad926528a2fb53cd084d1ae668 100644 --- a/Projects/Athena/externals/ThePEG.cmake +++ b/Projects/Athena/externals/ThePEG.cmake @@ -2,6 +2,6 @@ # File specifying the location of ThePEG to use. # -set( THEPEG_LCGVERSION 2.0.4 ) +set( THEPEG_LCGVERSION 2.1.3p1 ) set( THEPEG_LCGROOT ${LCG_RELEASE_DIR}/MCGenerators/thepeg/${THEPEG_LCGVERSION}/${LCG_PLATFORM} )