diff --git a/.clang-format b/.clang-format
--- a/.clang-format
+++ b/.clang-format
@@ -66,7 +66,7 @@
Priority: 4
- Regex: '^"(HepMC|HepMC3)/'
Priority: 5
- - Regex: '^"(Pythia8|Photos|Tauola)/'
+ - Regex: '^"(Pythia8|Photos|Tauola|SHERPA|ATOOLS)/'
Priority: 6
- Regex: '^"T[[:alnum:]]+\.h"'
Priority: 7
diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,6 +64,7 @@
option(EVTGEN_PYTHIA "Enable/disable linking with Pythia8" OFF)
option(EVTGEN_PHOTOS "Enable/disable linking with Photos++" OFF)
option(EVTGEN_TAUOLA "Enable/disable linking with Tauola++" OFF)
+option(EVTGEN_SHERPA "Enable/disable linking with Sherpa" OFF)
option(EVTGEN_SUPPRESS_EXTERNAL_WARNINGS "Enable/disable suppression of warnings from external dependencies" OFF)
if (EVTGEN_HEPMC3)
message(STATUS "EvtGen: Linking with HepMC3")
@@ -74,6 +75,7 @@
message(STATUS "EvtGen: Optional linking with Pythia8 EVTGEN_PYTHIA ${EVTGEN_PYTHIA}")
message(STATUS "EvtGen: Optional linking with Photos++ EVTGEN_PHOTOS ${EVTGEN_PHOTOS}")
message(STATUS "EvtGen: Optional linking with Tauola++ EVTGEN_TAUOLA ${EVTGEN_TAUOLA}")
+message(STATUS "EvtGen: Optional linking with Sherpa EVTGEN_SHERPA ${EVTGEN_SHERPA}")
include(EvtGenExternalDependencies)
# Setup clang-tidy checks
diff --git a/EvtGenExternal/EvtExternalGenList.hh b/EvtGenExternal/EvtExternalGenList.hh
--- a/EvtGenExternal/EvtExternalGenList.hh
+++ b/EvtGenExternal/EvtExternalGenList.hh
@@ -43,6 +43,10 @@
EvtAbsRadCorr* getPhotosModel( const double infraredCutOff = 1.0e-7,
const double maxWtInterference = 64.0 );
+ EvtAbsRadCorr* getSherpaPhotonsModel( const double infraredCutOff = 1.0e-7,
+ const int mode = 2,
+ const int useME = 0 );
+
protected:
private:
std::string m_photonType;
diff --git a/EvtGenExternal/EvtSherpaPhotons.hh b/EvtGenExternal/EvtSherpaPhotons.hh
new file mode 100644
--- /dev/null
+++ b/EvtGenExternal/EvtSherpaPhotons.hh
@@ -0,0 +1,86 @@
+
+/***********************************************************************
+* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
+* *
+* This file is part of EvtGen. *
+* *
+* EvtGen is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* EvtGen is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with EvtGen. If not, see . *
+***********************************************************************/
+
+#ifdef EVTGEN_SHERPA
+#ifndef EVTSHERPAPHOTONS_HH
+#define EVTSHERPAPHOTONS_HH
+
+#include "EvtGenBase/EvtAbsRadCorr.hh"
+#include "EvtGenBase/EvtHepMCEvent.hh"
+#include "EvtGenBase/EvtId.hh"
+#include "EvtGenBase/EvtPDL.hh"
+#include "EvtGenBase/EvtParticle.hh"
+
+#include "SHERPA/Main/Sherpa.H"
+
+#include
+
+class EvtParticle;
+class EvtAbsExternalGen;
+
+/* Description: EvtGen's interface to PHOTOS for generation of
+ * QED final state radiation.
+ */
+class EvtSherpaPhotons : public EvtAbsRadCorr {
+ public:
+ EvtSherpaPhotons( const bool useEvtGenRandom = true,
+ const double infraredCutOff = 1.0e-7, const int mode = 2,
+ const int useME = 0 );
+
+ void initialise() override;
+
+ void doRadCorr( EvtParticle* p ) override;
+
+ private:
+ // Provides vector of pointers to the configuration strings for Sherpa
+ std::vector addParameters();
+
+ // Updates the particle properties table of Sherpa
+ void updateParticleLists();
+
+ // The Sherpa instance.
+ std::unique_ptr m_sherpaGen;
+
+ // Vector containing the configuration strings for Sherpa
+ // INIT_ONLY=6 intialises the Sherpa objects without launching simulation.
+ std::vector m_configs{ "Sherpa", "INIT_ONLY=6" };
+
+ // Use EvtGen's random number generator
+ bool m_useEvtGenRandom = true;
+
+ // Default settings for PHOTONS++
+ // Minimum photon Energy (infrared cut-off).
+ double m_infraredCutOff = 1.0e-7;
+ // Switches on (default) the hard emission corrections (mode 2),
+ // otherwise follow the soft-photon only approach (mode 1).
+ int m_mode = 2;
+ // Switches off (default) or on the exact matrix-element corrections (works only for mode 2)
+ int m_useME = 0;
+
+ // Default photon properties
+ const std::string m_photonType = "gamma";
+ EvtId m_gammaId = EvtId( -1, -1 );
+ long int m_gammaPDG = 22;
+ bool m_initialised = false;
+};
+
+#endif
+
+#endif
diff --git a/EvtGenExternal/EvtExternalGenList.hh b/EvtGenExternal/EvtSherpaRandom.hh
copy from EvtGenExternal/EvtExternalGenList.hh
copy to EvtGenExternal/EvtSherpaRandom.hh
--- a/EvtGenExternal/EvtExternalGenList.hh
+++ b/EvtGenExternal/EvtSherpaRandom.hh
@@ -18,36 +18,43 @@
* along with EvtGen. If not, see . *
***********************************************************************/
-#ifndef EVTEXTERNALGENLIST_HH
-#define EVTEXTERNALGENLIST_HH
+#ifdef EVTGEN_SHERPA
-#include "EvtGenBase/EvtAbsRadCorr.hh"
-#include "EvtGenBase/EvtDecayBase.hh"
+#ifndef EVTSHERPARANDOM_HH
+#define EVTSHERPARANDOM_HH
-#include
+#include "EvtGenBase/EvtRandom.hh"
-// Description: A factory type method to create engines for external physics
-// generators like Pythia.
+#include "ATOOLS/Math/Random.H"
-class EvtExternalGenList {
- public:
- EvtExternalGenList( bool convertPythiaCodes = false,
- std::string pythiaXmlDir = "",
- std::string photonType = "gamma",
- bool useEvtGenRandom = true );
-
- virtual ~EvtExternalGenList();
+/* Description: Class to specify the chosen EvtGen random number (engine)
+ * to be used for Sherpa.
+ */
- std::list getListOfModels();
-
- EvtAbsRadCorr* getPhotosModel( const double infraredCutOff = 1.0e-7,
- const double maxWtInterference = 64.0 );
+class EvtSherpaRandom : public ATOOLS::External_RNG {
+ public:
+ double Get() { return EvtRandom::Flat(); }
- protected:
private:
- std::string m_photonType;
-
- bool m_useEvtGenRandom;
};
+// This makes EvtSherpaRandom loadable in Sherpa
+DECLARE_GETTER( EvtSherpaRandom, "EvtSherpaRandom", ATOOLS::External_RNG,
+ ATOOLS::RNG_Key );
+ATOOLS::External_RNG*
+ATOOLS::Getter::operator()(
+ const ATOOLS::RNG_Key& ) const
+{
+ return new EvtSherpaRandom();
+}
+
+// This eventually prints a help message
+void ATOOLS::Getter::PrintInfo(
+ std::ostream& str, const size_t ) const
+{
+ str << " EvtGen-Sherpa RNG interface";
+}
+
+#endif
+
#endif
diff --git a/cmake/Modules/EvtGenExternalDependencies.cmake b/cmake/Modules/EvtGenExternalDependencies.cmake
--- a/cmake/Modules/EvtGenExternalDependencies.cmake
+++ b/cmake/Modules/EvtGenExternalDependencies.cmake
@@ -27,6 +27,7 @@
set(Tauola++_ROOT_DIR "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Location of Tauola++ installation")
set(PHOTOSPP_ROOT_DIR "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Location of Photos++ installation - alternative spelling")
set(TAUOLAPP_ROOT_DIR "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Location of Tauola++ installation - alternative spelling")
+set(SHERPA_ROOT_DIR "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Location of Sherpa installation")
# The components we search for in the external generators depend on the version
# of HepMC we're working with
@@ -43,6 +44,9 @@
# From version 1.1.8 Tauola has HepMC3 support
find_package(Tauola++ REQUIRED COMPONENTS Fortran CxxInterface HepMC3)
endif()
+ if(EVTGEN_SHERPA)
+ find_package(Sherpa REQUIRED)
+ endif()
else()
find_package(HepMC2 REQUIRED)
if(EVTGEN_PYTHIA)
@@ -57,4 +61,7 @@
# Older versions of Tauola don't have the HepMC component, the HepMC2 interface is in CxxInterface
find_package(Tauola++ REQUIRED COMPONENTS Fortran CxxInterface OPTIONAL_COMPONENTS HepMC)
endif()
+ if(EVTGEN_SHERPA)
+ find_package(Sherpa REQUIRED)
+ endif()
endif()
diff --git a/cmake/Modules/FindSherpa.cmake b/cmake/Modules/FindSherpa.cmake
new file mode 100644
--- /dev/null
+++ b/cmake/Modules/FindSherpa.cmake
@@ -0,0 +1,69 @@
+
+########################################################################
+# Copyright 1998-2020 CERN for the benefit of the EvtGen authors #
+# #
+# This file is part of EvtGen. #
+# #
+# EvtGen is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# EvtGen is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with EvtGen. If not, see . #
+########################################################################
+
+# - Try to find Sherpa
+# Defines:
+#
+# SHERPA_FOUND
+# SHERPA_INCLUDE_DIR
+# SHERPA_INCLUDE_DIRS (not cached)
+# SHERPA_LIBRARY
+# SHERPA_LIBRARIES (not cached)
+# SHERPA_LIBRARY_DIRS (not cached)
+
+find_path(SHERPA_INCLUDE_DIR SHERPA/Main/Sherpa.H
+ HINTS $ENV{SHERPA_ROOT_DIR}/include ${SHERPA_ROOT_DIR}/include
+ PATH_SUFFIXES include SHERPA-MC)
+
+mark_as_advanced(SHERPA_INCLUDE_DIR)
+
+# Enforce a minimal list if none is explicitly requested
+if(NOT Sherpa_FIND_COMPONENTS)
+ set(Sherpa_FIND_COMPONENTS SherpaMain ModelMain METoolsMain METoolsLoops METoolsSpinCorrelations PDF PhotonsMEs PhotonsMain PhotonsPhaseSpace PhotonsTools Remnant ToolsMath ToolsOrg ToolsPhys)
+endif()
+
+foreach(component ${Sherpa_FIND_COMPONENTS})
+ find_library(SHERPA_${component}_LIBRARY NAMES ${component} ${_${component}_names}
+ HINTS $ENV{SHERPA_ROOT_DIR}/lib ${SHERPA_ROOT_DIR}/lib $ENV{SHERPA_ROOT_DIR}/lib64 ${SHERPA_ROOT_DIR}/lib64
+ PATH_SUFFIXES SHERPA-MC)
+ if (SHERPA_${component}_LIBRARY)
+ set(SHERPA_${component}_FOUND 1)
+ list(APPEND SHERPA_LIBRARIES ${SHERPA_${component}_LIBRARY})
+
+ get_filename_component(libdir ${SHERPA_${component}_LIBRARY} PATH)
+ list(APPEND SHERPA_LIBRARY_DIRS ${libdir})
+ else()
+ set(SHERPA_${component}_FOUND 0)
+ endif()
+ mark_as_advanced(SHERPA_${component}_LIBRARY)
+endforeach()
+
+if(SHERPA_LIBRARY_DIRS)
+ list(REMOVE_DUPLICATES SHERPA_LIBRARY_DIRS)
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set SHERPA_FOUND to TRUE if
+# all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sherpa DEFAULT_MSG SHERPA_INCLUDE_DIR SHERPA_LIBRARIES )
+
+set(SHERPA_INCLUDE_DIRS ${SHERPA_INCLUDE_DIR})
+
+mark_as_advanced(SHERPA_FOUND)
diff --git a/setupEvtGen.sh b/setupEvtGen.sh
--- a/setupEvtGen.sh
+++ b/setupEvtGen.sh
@@ -71,6 +71,11 @@
TAUOLADIR="TAUOLA."$TAUOLAVER
TAUOLATAR=$TAUOLADIR".tar.gz"
+# Sherpa version number
+SHERPAVER="2.2.15"
+SHERPAPKG="sherpa-v"$SHERPAVER
+SHERPATAR=$SHERPAPKG".tar.gz"
+
# Determine OS
osArch=`uname`
@@ -132,6 +137,7 @@
curl -O https://pythia.org/download/pythia${PYTHIAVER:0:2}/$PYTHIATAR
curl -O http://photospp.web.cern.ch/photospp/resources/$PHOTOSDIR/$PHOTOSTAR
curl -O http://tauolapp.web.cern.ch/tauolapp/resources/$TAUOLADIR/$TAUOLATAR
+curl -O https://gitlab.com/sherpa-team/sherpa/-/archive/v$SHERPAVER/$SHERPATAR
cd $BUILD_BASE/sources
@@ -145,6 +151,7 @@
tar -xzf $BUILD_BASE/tarfiles/$PYTHIATAR
tar -xzf $BUILD_BASE/tarfiles/$PHOTOSTAR
tar -xzf $BUILD_BASE/tarfiles/$TAUOLATAR
+tar -xzf $BUILD_BASE/tarfiles/$SHERPATAR
# Patch TAUOLA and PHOTOS on Darwin (Mac)
if [ "$osArch" == "Darwin" ]
@@ -191,7 +198,6 @@
make
make install
fi
-
else
echo Installing HepMC3 from $BUILD_BASE/sources/$HEPMC3PKG
@@ -223,6 +229,13 @@
fi
fi
+echo Installing Sherpa from $BUILD_BASE/sources/$SHERPAPKG
+cd $BUILD_BASE/sources/$SHERPAPKG
+autoreconf -i
+./configure --with-sqlite3=install --prefix=$INSTALL_PREFIX
+make
+make install
+
echo Installing EvtGen from $BUILD_BASE/sources/evtgen
mkdir -p $BUILD_BASE/builds/evtgen
cd $BUILD_BASE/builds/evtgen
@@ -234,13 +247,15 @@
-DEVTGEN_HEPMC3:BOOL=OFF -DHEPMC2_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PYTHIA:BOOL=ON -DPYTHIA8_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PHOTOS:BOOL=ON -DPHOTOSPP_ROOT_DIR:PATH=$INSTALL_PREFIX \
- -DEVTGEN_TAUOLA:BOOL=OFF
+ -DEVTGEN_TAUOLA:BOOL=OFF \
+ -DEVTGEN_SHERPA:BOOL=ON -DSHERPA_ROOT_DIR:PATH=$INSTALL_PREFIX
else
$CMAKE -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX $BUILD_BASE/sources/evtgen \
-DEVTGEN_HEPMC3:BOOL=ON -DHEPMC3_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PYTHIA:BOOL=ON -DPYTHIA8_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PHOTOS:BOOL=ON -DPHOTOSPP_ROOT_DIR:PATH=$INSTALL_PREFIX \
- -DEVTGEN_TAUOLA:BOOL=OFF
+ -DEVTGEN_TAUOLA:BOOL=OFF \
+ -DEVTGEN_SHERPA:BOOL=ON -DSHERPA_ROOT_DIR:PATH=$INSTALL_PREFIX
fi
else
if [ "$HEPMCMAJORVERSION" -lt "3" ]
@@ -249,13 +264,15 @@
-DEVTGEN_HEPMC3:BOOL=OFF -DHEPMC2_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PYTHIA:BOOL=ON -DPYTHIA8_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PHOTOS:BOOL=ON -DPHOTOSPP_ROOT_DIR:PATH=$INSTALL_PREFIX \
- -DEVTGEN_TAUOLA:BOOL=ON -DTAUOLAPP_ROOT_DIR:PATH=$INSTALL_PREFIX
+ -DEVTGEN_TAUOLA:BOOL=ON -DTAUOLAPP_ROOT_DIR:PATH=$INSTALL_PREFIX \
+ -DEVTGEN_SHERPA:BOOL=ON -DSHERPA_ROOT_DIR:PATH=$INSTALL_PREFIX
else
$CMAKE -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX $BUILD_BASE/sources/evtgen \
-DEVTGEN_HEPMC3:BOOL=ON -DHEPMC3_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PYTHIA:BOOL=ON -DPYTHIA8_ROOT_DIR:PATH=$INSTALL_PREFIX \
-DEVTGEN_PHOTOS:BOOL=ON -DPHOTOSPP_ROOT_DIR:PATH=$INSTALL_PREFIX \
- -DEVTGEN_TAUOLA:BOOL=ON -DTAUOLAPP_ROOT_DIR:PATH=$INSTALL_PREFIX
+ -DEVTGEN_TAUOLA:BOOL=ON -DTAUOLAPP_ROOT_DIR:PATH=$INSTALL_PREFIX \
+ -DEVTGEN_SHERPA:BOOL=ON -DSHERPA_ROOT_DIR:PATH=$INSTALL_PREFIX
fi
fi
make
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -86,7 +86,7 @@
# Add the EvtGenExternal library (if required)...
-if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA )
+if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA OR EVTGEN_SHERPA)
# Again, first build all the object files (with PIC enabled) so they can be
# used to build both the shared and static libs
add_library(objlib_ext OBJECT ${EVTGEN_EXTERNAL_SOURCES})
@@ -134,6 +134,14 @@
target_include_directories(objlib_ext PRIVATE ${Tauola++_INCLUDE_DIRS})
endif()
endif()
+ if(EVTGEN_SHERPA)
+ target_compile_definitions(objlib_ext PRIVATE EVTGEN_SHERPA)
+ if (EVTGEN_SUPPRESS_EXTERNAL_WARNINGS)
+ target_include_directories(objlib_ext SYSTEM PRIVATE ${SHERPA_INCLUDE_DIRS})
+ else()
+ target_include_directories(objlib_ext PRIVATE ${SHERPA_INCLUDE_DIRS})
+ endif()
+ endif()
# Now make the shared library from the object files
add_library(EvtGenExternal SHARED $)
@@ -147,6 +155,11 @@
target_include_directories(EvtGenExternal PUBLIC ${PYTHIA8_INCLUDE_DIRS})
target_link_libraries(EvtGenExternal PUBLIC ${PYTHIA8_LIBRARIES})
endif()
+ if(EVTGEN_SHERPA)
+ target_compile_definitions(EvtGenExternal PUBLIC EVTGEN_SHERPA)
+ target_include_directories(EvtGenExternal PUBLIC ${SHERPA_INCLUDE_DIRS})
+ target_link_libraries(EvtGenExternal PUBLIC ${SHERPA_LIBRARIES})
+ endif()
if(EVTGEN_HEPMC3)
target_compile_definitions(EvtGenExternal PUBLIC EVTGEN_HEPMC3)
target_include_directories(EvtGenExternal PUBLIC ${HEPMC3_INCLUDE_DIR})
@@ -205,6 +218,11 @@
target_include_directories(EvtGenExternalStatic PUBLIC ${PYTHIA8_INCLUDE_DIRS})
target_link_libraries(EvtGenExternalStatic PUBLIC ${PYTHIA8_LIBRARIES})
endif()
+ if(EVTGEN_SHERPA)
+ target_compile_definitions(EvtGenExternalStatic PUBLIC EVTGEN_SHERPA)
+ target_include_directories(EvtGenExternalStatic PUBLIC ${SHERPA_INCLUDE_DIRS})
+ target_link_libraries(EvtGenExternalStatic PUBLIC ${SHERPA_LIBRARIES})
+ endif()
if(EVTGEN_HEPMC3)
target_compile_definitions(EvtGenExternalStatic PUBLIC EVTGEN_HEPMC3)
target_include_directories(EvtGenExternalStatic PUBLIC ${HEPMC3_INCLUDE_DIR})
@@ -261,7 +279,7 @@
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
-if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA )
+if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA OR EVTGEN_SHERPA)
install(
TARGETS EvtGenExternal EvtGenExternalStatic
EXPORT "EvtGenTargets"
diff --git a/src/EvtGenExternal/EvtExternalGenList.cpp b/src/EvtGenExternal/EvtExternalGenList.cpp
--- a/src/EvtGenExternal/EvtExternalGenList.cpp
+++ b/src/EvtGenExternal/EvtExternalGenList.cpp
@@ -20,9 +20,12 @@
#include "EvtGenExternal/EvtExternalGenList.hh"
+#include "EvtGenModels/EvtNoRadCorr.hh"
+
#include "EvtGenExternal/EvtExternalGenFactory.hh"
#include "EvtGenExternal/EvtPHOTOS.hh"
#include "EvtGenExternal/EvtPythia.hh"
+#include "EvtGenExternal/EvtSherpaPhotons.hh"
#include "EvtGenExternal/EvtTauola.hh"
EvtExternalGenList::EvtExternalGenList( bool convertPythiaCodes,
@@ -63,6 +66,30 @@
return photosModel;
}
+#ifdef EVTGEN_SHERPA
+EvtAbsRadCorr* EvtExternalGenList::getSherpaPhotonsModel(
+ const double infraredCutOff, const int mode, const int useME )
+{
+ // Define the Photos model, which uses the EvtSherpaPhotonsEngine class.
+ EvtSherpaPhotons* sherpaPhotonsModel =
+ new EvtSherpaPhotons( m_useEvtGenRandom, infraredCutOff, mode, useME );
+ return sherpaPhotonsModel;
+}
+#else
+EvtAbsRadCorr* EvtExternalGenList::getSherpaPhotonsModel(
+ const double /*infraredCutOff*/, const int /*mode*/, const int /*useME*/ )
+{
+ EvtGenReport( EVTGEN_ERROR, "EvtGen" )
+ << " Sherpa's PHOTONS++ generator has been called for FSR simulation, but Sherpa was not switched on during compilation."
+ << std::endl;
+
+ EvtGenReport( EVTGEN_ERROR, "EvtGen" )
+ << " The simulation will be generated without FSR." << std::endl;
+
+ return new EvtNoRadCorr{};
+}
+#endif
+
std::list EvtExternalGenList::getListOfModels()
{
// Create the Pythia and Tauola models, which use their own engine classes.
diff --git a/src/EvtGenExternal/EvtSherpaPhotons.cpp b/src/EvtGenExternal/EvtSherpaPhotons.cpp
new file mode 100644
--- /dev/null
+++ b/src/EvtGenExternal/EvtSherpaPhotons.cpp
@@ -0,0 +1,296 @@
+
+/***********************************************************************
+* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
+* *
+* This file is part of EvtGen. *
+* *
+* EvtGen is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* EvtGen is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with EvtGen. If not, see . *
+***********************************************************************/
+
+#ifdef EVTGEN_SHERPA
+
+#include "EvtGenExternal/EvtSherpaPhotons.hh"
+
+#include "EvtGenBase/EvtPhotonParticle.hh"
+#include "EvtGenBase/EvtRandom.hh"
+#include "EvtGenBase/EvtReport.hh"
+#include "EvtGenBase/EvtVector4R.hh"
+
+#include "EvtGenExternal/EvtSherpaRandom.hh"
+
+#include "ATOOLS/Org/MyStrStream.H"
+#include "ATOOLS/Phys/Particle.H"
+#include "SHERPA/Initialization/Initialization_Handler.H"
+#include "SHERPA/Single_Events/Event_Handler.H"
+#include "SHERPA/SoftPhysics/Soft_Photon_Handler.H"
+
+#include
+#include
+#include
+
+using std::endl;
+
+EvtSherpaPhotons::EvtSherpaPhotons( const bool useEvtGenRandom,
+ const double infraredCutOff, const int mode,
+ const int useME ) :
+ m_useEvtGenRandom{ useEvtGenRandom },
+ m_infraredCutOff{ infraredCutOff },
+ m_mode{ mode },
+ m_useME{ useME }
+{
+}
+
+void EvtSherpaPhotons::initialise()
+{
+ if ( m_initialised ) {
+ return;
+ }
+
+ EvtGenReport( EVTGEN_INFO, "EvtGen" )
+ << "Setting up Sherpa PHOTONS++ generator for FSR." << endl;
+
+ /* Specify whether we are going to use EvtGen's random number generator
+ * (via EvtSherpaRandom interface) for Sherpa's PHOTONS++ simulation. */
+ if ( m_useEvtGenRandom ) {
+ m_configs.push_back( "SHERPA_LDADD=EvtGenExternal" );
+ m_configs.push_back( "EXTERNAL_RNG=EvtSherpaRandom" );
+ }
+
+ /*
+ * Internal PHOTONS++ settings.
+ * Documentation at
+ * https://sherpa.hepforge.org/doc/Sherpa.html#QED-Corrections
+ */
+
+ /*
+ * YFS_IR_CUTOFF sets the infrared cut-off which serves as a
+ * minimum photon energy in this frame for explicit photon generation.
+ * The default is YFS_IR_CUTOFF = 1E-3 (GeV) but we set it to 1E-7 to equalize
+ * with the cutoff used for PHOTOS.
+ */
+ m_configs.push_back( "YFS_IR_CUTOFF=" + ATOOLS::ToString( m_infraredCutOff ) );
+
+ /*
+ * The keyword YFS_MODE = [0,1,2] determines the mode of operation.
+ * YFS_MODE = 0 switches Photons off.
+ * YFS_MODE = 1 sets the mode to "soft only", meaning soft emissions will be
+ * treated correctly to all orders but no hard emission corrections will be included.
+ * YFS_MODE = 2 these hard emission corrections will also be included up to
+ * first order in alpha_QED. This is the default setting in Sherpa.
+ */
+
+ m_configs.push_back( "YFS_MODE=" + ATOOLS::ToString( m_mode ) );
+
+ /*
+ * The switch YFS_USE_ME = [0,1] tells Photons how to correct hard emissions to
+ * first order in alpha_QED. If YFS_USE_ME = 0, then Photons will use collinearly
+ * approximated real emission matrix elements. Virtual emission matrix elements of
+ * order alpha_QED are ignored. If, however, YFS_USE_ME=1, then exact real and/or
+ * virtual emission matrix elements are used wherever possible.
+ * These are presently available for V->FF, V->SS, S->FF, S->SS, S->Slnu,
+ * S->Vlnu type decays, Z->FF decays and leptonic tau and W decays. For all other
+ * decay types general collinearly approximated matrix elements are used.
+ * In both approaches all hadrons are treated as point-like objects.
+ * The default setting is YFS_USE_ME = 1. This switch is only effective if YFS_MODE = 2.
+ */
+ m_configs.push_back( "YFS_USE_ME=" + ATOOLS::ToString( m_useME ) );
+
+ // TODO: Virtual photon splitting into l+l- will be part of ME corrections from Sherpa 3.0.0 on,
+ // Once released, this should be switched off by default or
+ // taken into account while retrieving the event.
+
+ // Set up run-time arguments for Sherpa.
+ std::vector argv = this->addParameters();
+
+ // Create instance and initialise Sherpa.
+ m_sherpaGen = std::make_unique();
+ m_sherpaGen->InitializeTheRun( argv.size(), &argv[0] );
+ m_sherpaGen->InitializeTheEventHandler();
+
+ m_gammaId = EvtPDL::getId( m_photonType );
+ m_gammaPDG = EvtPDL::getStdHep( m_gammaId );
+
+ this->updateParticleLists();
+
+ m_initialised = true;
+}
+
+std::vector EvtSherpaPhotons::addParameters()
+{
+ std::vector argv;
+ argv.reserve( m_configs.size() );
+
+ for ( auto& config : m_configs ) {
+ if ( config != "Sherpa" ) {
+ EvtGenReport( EVTGEN_INFO, "EvtGen" )
+ << " EvtSherpaPhotons::initialise: Setting parameter '"
+ << config << "'" << endl;
+ }
+ argv.push_back( config.data() );
+ }
+
+ return argv;
+}
+
+void EvtSherpaPhotons::updateParticleLists()
+{
+ /* Use the EvtGen decay and pdl tables (decay/user.dec and evt.pdl)
+ * to update Sherpa's KF_Table which contains all defined particles
+ * and their properties.
+ * Loop over all entries in the EvtPDL particle data table.
+ */
+ const int nPDL = EvtPDL::entries();
+
+ for ( int iPDL = 0; iPDL < nPDL; iPDL++ ) {
+ const EvtId particleId = EvtPDL::getEntry( iPDL );
+
+ // Sherpa and EvtGen should use the same PDG codes for particles
+ const int PDGCode = EvtPDL::getStdHep( particleId );
+ const long unsigned int particleCode = std::abs( PDGCode );
+
+ // If particle is found in Sherpa's KF_Table, then continue.
+ // Updating the pole mass is not necessary because we provide the 4-momenta
+ // and the final mass for final-state radiation generation.
+ ATOOLS::KFCode_ParticleInfo_Map::const_iterator kf_it(
+ ATOOLS::s_kftable.find( particleCode ) );
+ if ( kf_it != ATOOLS::s_kftable.end() ) {
+ continue;
+ }
+
+ // If the PDG is negative, use the charge conjugated ID because
+ // the KF_Table is defined only for positive PDG numbers.
+ const EvtId particleIdConj = EvtPDL::chargeConj( particleId );
+
+ // Get mass, width, charge and spin
+ const double mass = EvtPDL::getMeanMass( particleId );
+ const double width = EvtPDL::getWidth( particleId );
+ const int charge = PDGCode < 0 ? EvtPDL::chg3( particleIdConj )
+ : EvtPDL::chg3( particleId );
+ const int spin = EvtSpinType::getSpin2(
+ EvtPDL::getSpinType( particleId ) );
+
+ // Use as reference the name of the particle (not anti-particle).
+ const std::string idName = PDGCode < 0 ? particleIdConj.getName()
+ : particleId.getName();
+
+ ATOOLS::s_kftable[particleCode] = new ATOOLS::Particle_Info(
+ particleCode, mass, width, charge, spin, 0, 1, idName, idName );
+ }
+}
+
+void EvtSherpaPhotons::doRadCorr( EvtParticle* theParticle )
+{
+ if ( !theParticle ) {
+ return;
+ }
+
+ /* Skip running FSR if the particle has no daughters, since we can't add FSR.
+ * Also skip FSR if the particle has too many daughters (>= 10) as done for PHOTOS.
+ */
+ const int nDaughters( theParticle->getNDaug() );
+ if ( nDaughters == 0 || nDaughters >= 10 ) {
+ return;
+ }
+
+ ATOOLS::Blob_List* blobs = m_sherpaGen->GetEventHandler()->GetBlobs();
+
+ // Use the hadron decay flag always.
+ // Internally, Sherpa handles tau decays in the same way as hadron decays.
+ ATOOLS::Blob* blob = blobs->AddBlob( ATOOLS::btp::Hadron_Decay );
+
+ // Tell Sherpa that the blob needs FSR (that is extra QED)
+ blob->SetStatus( ATOOLS::blob_status::needs_extraQED );
+
+ // Create mother particle and add it to blob
+ ATOOLS::Flavour mother_flav( EvtPDL::getStdHep( theParticle->getId() ) );
+ mother_flav.SetStable( false );
+ const double motherM0 = theParticle->mass();
+ const ATOOLS::Vec4D mother_mom( motherM0, 0., 0., 0. );
+
+ ATOOLS::Particle* mother_part = new ATOOLS::Particle( -1, mother_flav,
+ mother_mom );
+ mother_part->SetFinalMass( motherM0 );
+ mother_part->SetStatus( ATOOLS::part_status::decayed );
+ mother_part->SetInfo( 'I' );
+
+ blob->AddToInParticles( mother_part );
+
+ // Add daughters to the blob
+ for ( int iDaug = 0; iDaug < nDaughters; iDaug++ ) {
+ const EvtParticle* theDaughter = theParticle->getDaug( iDaug );
+ ATOOLS::Flavour daughter_flav( EvtPDL::getStdHep( theDaughter->getId() ) );
+ daughter_flav.SetStable( true );
+
+ const double daugE = theDaughter->getP4().get( 0 );
+ const double daugPx = theDaughter->getP4().get( 1 );
+ const double daugPy = theDaughter->getP4().get( 2 );
+ const double daugPz = theDaughter->getP4().get( 3 );
+ const double daugM0 = theDaughter->mass();
+
+ const ATOOLS::Vec4D daughter_mom( daugE, daugPx, daugPy, daugPz );
+
+ ATOOLS::Particle* daughter_part =
+ new ATOOLS::Particle( iDaug, daughter_flav, daughter_mom );
+ daughter_part->SetFinalMass( daugM0 );
+
+ daughter_part->SetStatus( ATOOLS::part_status::active );
+ daughter_part->SetInfo( 'F' );
+
+ blob->AddToOutParticles( daughter_part );
+ }
+
+ const SHERPA::Initialization_Handler* inithandler =
+ m_sherpaGen->GetInitHandler();
+ SHERPA::Soft_Photon_Handler* softphotonhandler =
+ inithandler->GetSoftPhotonHandler();
+
+ // Simulate the radiation
+ softphotonhandler->AddRadiation( blob );
+
+ // Get number of final-state particles
+ const int nFinal( blob->NOutP() );
+
+ // Retrieve the event from Sherpa blob if FSR photons were added
+ if ( nFinal > nDaughters ) {
+ for ( int iLoop = 0; iLoop < nFinal; iLoop++ ) {
+ const ATOOLS::Particle* daugParticle = blob->OutParticle( iLoop );
+ const ATOOLS::Vec4D daughter_mom = daugParticle->Momentum();
+ const long int pdgId = daugParticle->Flav();
+ const EvtVector4R newP4( daughter_mom[0], daughter_mom[1],
+ daughter_mom[2], daughter_mom[3] );
+ const char daugInfo = daugParticle->Info();
+
+ if ( iLoop < nDaughters ) {
+ // Update momenta of initial particles
+ EvtParticle* daugParticle = theParticle->getDaug( iLoop );
+ if ( daugParticle ) {
+ daugParticle->setP4WithFSR( newP4 );
+ }
+ } else if ( pdgId == m_gammaPDG && daugInfo == 'S' ) {
+ // Add FSR photons. PHOTONS flags them with info 'S'.
+ // Create a new photon particle and add it to the list of daughters
+ EvtPhotonParticle* gamma = new EvtPhotonParticle();
+ gamma->init( m_gammaId, newP4 );
+ gamma->setFSRP4toZero();
+ gamma->setAttribute( "FSR", 1 );
+ gamma->setAttribute( "ISR", 0 );
+ gamma->addDaug( theParticle );
+ }
+ }
+ }
+
+ return;
+}
+
+#endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -34,7 +34,7 @@
if (EVTGEN_HEPMC3)
target_compile_definitions(${test_exe} PRIVATE EVTGEN_HEPMC3)
endif()
- if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA )
+ if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA OR EVTGEN_SHERPA )
target_compile_definitions(${test_exe} PRIVATE EVTGEN_EXTERNAL)
target_link_libraries(${test_exe} PRIVATE EvtGenExternal)
endif()
diff --git a/test/checkJsonFiles.py b/test/checkJsonFiles.py
--- a/test/checkJsonFiles.py
+++ b/test/checkJsonFiles.py
@@ -114,6 +114,9 @@
'yesFSR',
'Pars1',
'Pars2',
+ 'SherpaFSR1',
+ 'SherpaFSR20',
+ 'SherpaFSR21',
]
def __init__( self, jsonFileName ) :
diff --git a/test/testDecayModel.cc b/test/testDecayModel.cc
--- a/test/testDecayModel.cc
+++ b/test/testDecayModel.cc
@@ -131,6 +131,12 @@
? m_config.at( "extras" ).get>()
: std::vector{} };
+ // Set the FSR generator. Use PHOTOS by default.
+ const auto fsrGenerator{
+ ( m_config.contains( "fsr_generator" ) )
+ ? m_config.at( "fsr_generator" ).get()
+ : "PHOTOS" };
+
const auto debugFlag{ ( m_config.contains( "debug_flag" ) &&
m_config.at( "debug_flag" ).is_boolean() )
? m_config.at( "debug_flag" ).get()
@@ -159,7 +165,19 @@
bool convertPythiaCodes( false );
bool useEvtGenRandom( true );
EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom );
- radCorrEngine = genList.getPhotosModel();
+ if ( fsrGenerator == "PHOTOS" ) {
+ radCorrEngine = genList.getPhotosModel();
+ } else if ( fsrGenerator == "SherpaFSR1" ) {
+ radCorrEngine = genList.getSherpaPhotonsModel( 1e-7, 1, 0 );
+ } else if ( fsrGenerator == "SherpaFSR20" ) {
+ radCorrEngine = genList.getSherpaPhotonsModel( 1e-7, 2, 0 );
+ } else if ( fsrGenerator == "SherpaFSR21" ) {
+ radCorrEngine = genList.getSherpaPhotonsModel( 1e-7, 2, 1 );
+ } else {
+ std::cerr << "ERROR: The option fsr_generator = '" << fsrGenerator
+ << "' is not supported. " << std::endl;
+ return false;
+ }
extraModels = genList.getListOfModels();
#endif
@@ -811,12 +829,19 @@
value = p1.get( 3 );
} else if ( !selectedVarName.compare( "cosHel" ) ||
- !selectedVarName.compare( "absCosHel" ) ) {
+ !selectedVarName.compare( "absCosHel" ) ||
+ !selectedVarName.compare( "cosHelParent" ) ) {
// Cosine of helicity angle
EvtVector4R p12;
EvtVector4R p1Res;
- if ( d2 != 0 ) {
+ if ( !selectedVarName.compare( "cosHelParent" ) ) {
+ p12 = selectedParent->getP4Lab();
+ const EvtVector4R boost{ p12.get( 0 ), -p12.get( 1 ), -p12.get( 2 ),
+ -p12.get( 3 ) };
+ // Momentum of particle d1 in resonance frame, p1Res
+ p1Res = boostTo( p1_lab, boost );
+ } else if ( d2 != 0 ) {
// Resonance center-of-mass system (d1 and d2)
p12 = p1_lab + p2_lab;
// Boost vector
diff --git a/validation/CMakeLists.txt b/validation/CMakeLists.txt
--- a/validation/CMakeLists.txt
+++ b/validation/CMakeLists.txt
@@ -33,7 +33,7 @@
if (EVTGEN_HEPMC3)
target_compile_definitions(${validation_exe} PRIVATE EVTGEN_HEPMC3)
endif()
- if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA )
+ if( EVTGEN_PYTHIA OR EVTGEN_PHOTOS OR EVTGEN_TAUOLA OR EVTGEN_SHERPA)
target_compile_definitions(${validation_exe} PRIVATE EVTGEN_EXTERNAL)
target_link_libraries(${validation_exe} PRIVATE EvtGenExternal)
endif()