diff --git a/CMakeLists.txt b/CMakeLists.txt index ff0c434c..8de2c816 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) #---------------------------------------------------------------------------- project(HepMC3 LANGUAGES CXX) -set(PROJECT_VERSION 3.02.08) -SET(HEPMC3_VERSION 3.02.08) +set(PROJECT_VERSION 3.03.00) +SET(HEPMC3_VERSION 3.03.00) SET(HEPMC3_VERSION_MAJOR 3) -SET(HEPMC3_VERSION_MINOR 2) -SET(HEPMC3_VERSION_PATCH 8) +SET(HEPMC3_VERSION_MINOR 3) +SET(HEPMC3_VERSION_PATCH 0) set(CMAKE_VERBOSE_MAKEFILE OFF) #This module respects HFS, e.g. defines lib or lib64 when it is needed. @@ -437,7 +437,6 @@ if (ASTYLE) test/*cc test/*h interfaces/*/include/*.h - interfaces/*/include/*/*.h interfaces/*/include/*/*.cc WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) @@ -479,8 +478,8 @@ set(CPACK_PACKAGE_VENDOR "HepMC3 Developers") #Should the version be defined above? set(CPACK_PACKAGE_VERSION 3) set(CPACK_PACKAGE_VERSION_MAJOR 3) -set(CPACK_PACKAGE_VERSION_MINOR 2) -set(CPACK_PACKAGE_VERSION_PATCH 8) +set(CPACK_PACKAGE_VERSION_MINOR 3) +set(CPACK_PACKAGE_VERSION_PATCH 0) set(CPACK_PACKAGE_RELEASE 0) set(CPACK_PACKAGE_FILE_NAME "HepMC3") set(CPACK_PACKAGE_DESCRIPTION "Event record library for high energy physics Monte Carlo") diff --git a/ChangeLog b/ChangeLog index 29e664b9..ff53c0bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,13 @@ -------------------------- HepMC3.3.0-pre ---------------------- +2024-05-23 Andrii Verbytskyi + * Update python bindings with binder 1.4.2 + * Update bxzstr to bxzstr 1.2.2 + patches + * Formatting 2024-05-26 Andy Buckley * Explicitly return for inf-generating eta / massless rapidity along pz, to avoid FPE triggering. 2024-04-20 Andy Buckley * Suppress cross-section/weight count-mismatch warning if only one cross-section. -2024-04-08 Mattias Ellert +2024-04-08 Andrii Verbytskyi * Add support for reading with uproot * Drop Python2 support 2023-10-24 Mattias Ellert diff --git a/include/HepMC3/Version.h b/include/HepMC3/Version.h index 13fbcfc1..389eca98 100644 --- a/include/HepMC3/Version.h +++ b/include/HepMC3/Version.h @@ -14,12 +14,12 @@ #include /// HepMC version string -#define HEPMC3_VERSION "3.02.08" +#define HEPMC3_VERSION "3.03.00" /// @brief HepMC version as an integer, HepMC X.Y.Z = 1000000*X + 1000*Y + Z /// /// Use like "#if HEPMC3_VERSION_CODE < 3001004" for < 3.01.04 -#define HEPMC3_VERSION_CODE 3002008 +#define HEPMC3_VERSION_CODE 3003000 namespace HepMC3 { /// Get the HepMC library version string inline std::string version() { diff --git a/include/HepMC3/bxzstr/bxzstr.hpp b/include/HepMC3/bxzstr/bxzstr.hpp index 576624a4..22ce3573 100644 --- a/include/HepMC3/bxzstr/bxzstr.hpp +++ b/include/HepMC3/bxzstr/bxzstr.hpp @@ -14,6 +14,7 @@ #include #include +#include #include "stream_wrapper.hpp" #include "strict_fstream.hpp" @@ -45,6 +46,45 @@ class istreambuf : public std::streambuf { delete [] out_buff; } + virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out){ + std::streampos pos; + + if (way == std::ios_base::cur) + pos = get_cursor() + off; + else if (way == std::ios_base::end) + throw std::runtime_error("Cannot seek from the end position on a compressed stream (the size is not known in advance)."); + else if (way == std::ios_base::beg) + pos = off; + + if(pos == get_cursor()) return get_cursor(); // we are just finding the current position + + return seekpos(pos, which); + } + + virtual std::streampos seekpos(std::streampos pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out){ + if(pos == 0){ + seek_to_zero(); // reset the stream + return 0; // this should not fail + } + + while(pos != get_cursor()){ + underflow(); + std::streamoff relOff = pos-get_cursor(); + if(relOff < 0) { + if(eback() <= gptr()+relOff) { // if it is buffered just rewind to the position + setg(eback(), gptr()+relOff, egptr()); + }else{ // otherwise we have to reset/seek to the zero position and seek forward + seek_to_zero(); + } + }else{ + if(gptr()+relOff >= egptr()) relOff = egptr()-gptr(); + setg(eback(), gptr()+relOff, egptr()); + } + } + + return get_cursor(); + } + virtual std::streambuf::int_type underflow() { if (this->gptr() == this->egptr()) { // pointers for free region in output buffer @@ -91,12 +131,27 @@ class istreambuf : public std::streambuf { // 2 exit conditions: // - end of input: there might or might not be output available // - out_buff_free_start != out_buff: output available + out_buff_end_abs += out_buff_free_start-out_buff; this->setg(out_buff, out_buff, out_buff_free_start); } return this->gptr() == this->egptr() ? traits_type::eof() : traits_type::to_int_type(*this->gptr()); } private: + + std::streampos get_cursor(){ + return out_buff_end_abs + gptr() - egptr(); + } + + void seek_to_zero(){ + in_buff_start = in_buff; + in_buff_end = in_buff; + setg(out_buff, out_buff, out_buff); + if(sbuf_p->pubseekpos(0) != 0) throw std::runtime_error("could not seek underlying stream."); + out_buff_end_abs = 0; + strm_p.reset(); // new one will be created on underflow + } + std::streambuf* sbuf_p; char* in_buff; char* in_buff_start; @@ -107,6 +162,7 @@ class istreambuf : public std::streambuf { bool auto_detect; bool auto_detect_run; Compression type; + std::streampos out_buff_end_abs; static const std::size_t default_buff_size = (std::size_t)1 << 20; }; // class istreambuf diff --git a/include/HepMC3/bxzstr/zstd_stream_wrapper.hpp b/include/HepMC3/bxzstr/zstd_stream_wrapper.hpp index b6698a1b..195fa980 100644 --- a/include/HepMC3/bxzstr/zstd_stream_wrapper.hpp +++ b/include/HepMC3/bxzstr/zstd_stream_wrapper.hpp @@ -12,6 +12,9 @@ #include +#ifndef ZSTD_CLEVEL_DEFAULT +#define ZSTD_CLEVEL_DEFAULT 5 +#endif #include #include @@ -38,7 +41,7 @@ namespace detail { class zstd_stream_wrapper : public stream_wrapper { public: zstd_stream_wrapper(const bool _isInput = true, - const int level = ZSTD_defaultCLevel(), const int = 0) + const int level = ZSTD_CLEVEL_DEFAULT, const int = 0) : isInput(_isInput) { if (this->isInput) { this->dctx = ZSTD_createDCtx(); diff --git a/interfaces/pythia6/include/Pythia6/Pythia6ToHepMC3.cc b/interfaces/pythia6/include/Pythia6/Pythia6ToHepMC3.cc index cd421419..3d82cc47 100644 --- a/interfaces/pythia6/include/Pythia6/Pythia6ToHepMC3.cc +++ b/interfaces/pythia6/include/Pythia6/Pythia6ToHepMC3.cc @@ -5,7 +5,7 @@ // /** * @file Pythia6ToHepMC3.cc - * @brief A simple C-like interface to HepMC3 aimed to be used with Pythia6 + * @brief A simple C-like interface to HepMC3 aimed to be used with Pythia6 * */ #ifndef PYTHIA6_PYTHIA6TOHEPMC3_CC diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 4fff7c19..888e17a4 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,6 +1,6 @@ #project(pyHepMC3 CXX) #Should be fixed -cmake_minimum_required(VERSION 3.1.0) +cmake_minimum_required(VERSION 3.5.0) if(${CMAKE_VERSION} VERSION_LESS "3.14.00") SET_PROPERTY (GLOBAL PROPERTY CMAKE_ROLE "PROJECT") endif() @@ -12,9 +12,9 @@ if (RERUN_BINDER) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) endif() if (USE_INSTALLED_HEPMC3) - set(${PROJECT_NAME}_VERSION 3.2.8) + set(${PROJECT_NAME}_VERSION 3.3.0) set(THIS_PROJECT_NAME ${PROJECT_NAME}) - set(THIS_PROJECT_NAME_VERSION 3.2.8) + set(THIS_PROJECT_NAME_VERSION 3.3.0) option(HEPMC3_ENABLE_TEST "Enable tests" ON) diff --git a/python/src/pyHepMC3_1.cpp b/python/src/pyHepMC3_1.cpp index cbee95a4..60a44d1c 100644 --- a/python/src/pyHepMC3_1.cpp +++ b/python/src/pyHepMC3_1.cpp @@ -73,7 +73,7 @@ void bind_pyHepMC3_1(std::function< pybind11::module &(std::string const &namesp cl.def("rap", (double (HepMC3::FourVector::*)() const) &HepMC3::FourVector::rap, "Rapidity\n\nC++: HepMC3::FourVector::rap() const --> double"); cl.def("abs_eta", (double (HepMC3::FourVector::*)() const) &HepMC3::FourVector::abs_eta, "Absolute pseudorapidity\n\nC++: HepMC3::FourVector::abs_eta() const --> double"); cl.def("abs_rap", (double (HepMC3::FourVector::*)() const) &HepMC3::FourVector::abs_rap, "Absolute rapidity\n\nC++: HepMC3::FourVector::abs_rap() const --> double"); - cl.def("pseudoRapidity", (double (HepMC3::FourVector::*)() const) &HepMC3::FourVector::pseudoRapidity, "Same as eta()\n \n\n Prefer 'only one way to do it', and we don't have equivalent long names for e.g. pid, phi or eta\n\nC++: HepMC3::FourVector::pseudoRapidity() const --> double"); + cl.def("pseudoRapidity", (double (HepMC3::FourVector::*)() const) &HepMC3::FourVector::pseudoRapidity, "Same as eta()\n\n \n Prefer 'only one way to do it', and we don't have equivalent long names for e.g. pid, phi or eta\n\nC++: HepMC3::FourVector::pseudoRapidity() const --> double"); cl.def("is_zero", (bool (HepMC3::FourVector::*)() const) &HepMC3::FourVector::is_zero, "Check if the length of this vertex is zero\n\nC++: HepMC3::FourVector::is_zero() const --> bool"); cl.def("delta_phi", (double (HepMC3::FourVector::*)(const class HepMC3::FourVector &) const) &HepMC3::FourVector::delta_phi, "Signed azimuthal angle separation in [-pi, pi]\n\nC++: HepMC3::FourVector::delta_phi(const class HepMC3::FourVector &) const --> double", pybind11::arg("v")); cl.def("delta_eta", (double (HepMC3::FourVector::*)(const class HepMC3::FourVector &) const) &HepMC3::FourVector::delta_eta, "Pseudorapidity separation\n\nC++: HepMC3::FourVector::delta_eta(const class HepMC3::FourVector &) const --> double", pybind11::arg("v")); diff --git a/python/test/pyHepMC3TestUtils.py b/python/test/pyHepMC3TestUtils.py index 764dca97..628aa663 100644 --- a/python/test/pyHepMC3TestUtils.py +++ b/python/test/pyHepMC3TestUtils.py @@ -11,16 +11,16 @@ def python_label(): def update_path(): try: - os.add_dll_directory(os.path.abspath(os.path.join(os.pardir, python_label()))) - os.add_dll_directory(os.getcwd()) - for val in str(os.getenv("PATH")).split(',:;'): - os.add_dll_directory(os.path.abspath(val)) - for val in str(os.getenv("LD_LIBRARY_PATH")).split(',:;'): - os.add_dll_directory(os.path.abspath(val)) - for val in str(os.getenv("DYLD_LIBRARY_PATH")).split(',:;'): - os.add_dll_directory(os.path.abspath(val)) + os.add_dll_directory(os.path.abspath(os.path.join(os.pardir, python_label()))) + os.add_dll_directory(os.getcwd()) + for val in str(os.getenv("PATH")).split(",:;"): + os.add_dll_directory(os.path.abspath(val)) + for val in str(os.getenv("LD_LIBRARY_PATH")).split(",:;"): + os.add_dll_directory(os.path.abspath(val)) + for val in str(os.getenv("DYLD_LIBRARY_PATH")).split(",:;"): + os.add_dll_directory(os.path.abspath(val)) except: - pass + pass return [os.path.abspath(os.path.join(os.pardir, python_label()))] + [os.getcwd()] + sys.path @@ -47,6 +47,7 @@ def COMPARE_ASCII_FILES(f1, f2): file2.close() return 0 + def fuse_equal(a, b, rtol=0.00001, atol=0.000001): if abs(1.0 * a - 1.0 * b) < atol: return True diff --git a/python/test/test_IO4.py b/python/test/test_IO4.py index 8f3a187d..52e20d6c 100644 --- a/python/test/test_IO4.py +++ b/python/test/test_IO4.py @@ -9,58 +9,60 @@ def test_IO4(): - if sys.version_info[0]<3: - return 0 - if sys.implementation.name != 'cpython': - return 0 + if sys.version_info[0] < 3: + return 0 + if sys.implementation.name != "cpython": + return 0 exts = ["gzip", "bz2", "lzma"] import lzma import gzip import bz2 import shutil + zstdavail = True try: - import zstandard - if not hasattr(zstandard,'open'): - zstdavail = False + import zstandard + + if not hasattr(zstandard, "open"): + zstdavail = False except ImportError as e: - zstdavail = False + zstdavail = False - with open('inputIO4.hepmc', 'rb') as f_in: - with gzip.open("inputIO4.hepmc.gzip", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) + with open("inputIO4.hepmc", "rb") as f_in: + with gzip.open("inputIO4.hepmc.gzip", "wb") as f_out: + shutil.copyfileobj(f_in, f_out) - with open('inputIO4.hepmc', 'rb') as f_in: - with bz2.open("inputIO4.hepmc.bz2", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) + with open("inputIO4.hepmc", "rb") as f_in: + with bz2.open("inputIO4.hepmc.bz2", "wb") as f_out: + shutil.copyfileobj(f_in, f_out) - with open('inputIO4.hepmc', 'rb') as f_in: - with lzma.open("inputIO4.hepmc.lzma", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) + with open("inputIO4.hepmc", "rb") as f_in: + with lzma.open("inputIO4.hepmc.lzma", "wb") as f_out: + shutil.copyfileobj(f_in, f_out) if zstdavail: - exts = ["gzip", "bz2", "lzma", "zstd"] - with open('inputIO4.hepmc', 'rb') as f_in: - with zstandard.open("inputIO4.hepmc.zstd", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) + exts = ["gzip", "bz2", "lzma", "zstd"] + with open("inputIO4.hepmc", "rb") as f_in: + with zstandard.open("inputIO4.hepmc.zstd", "wb") as f_out: + shutil.copyfileobj(f_in, f_out) for ext in exts: - inputA = hm.deduce_reader("inputIO4.hepmc."+ext) - if inputA.failed(): - sys.exit(1) - outputA = hm.WriterAsciiHepMC2("inputIO4.hepmcfrom"+ext) - if outputA.failed(): - sys.exit(2) - while not inputA.failed(): - evt = hm.GenEvent() - inputA.read_event(evt) - if inputA.failed(): - print("End of file reached. Exit.\n") - break - outputA.write_event(evt) - evt.clear() - inputA.close() - outputA.close() - assert 0 == COMPARE_ASCII_FILES("inputIO4.hepmcfrom"+ext, "inputIO4.hepmc") + inputA = hm.deduce_reader("inputIO4.hepmc." + ext) + if inputA.failed(): + sys.exit(1) + outputA = hm.WriterAsciiHepMC2("inputIO4.hepmcfrom" + ext) + if outputA.failed(): + sys.exit(2) + while not inputA.failed(): + evt = hm.GenEvent() + inputA.read_event(evt) + if inputA.failed(): + print("End of file reached. Exit.\n") + break + outputA.write_event(evt) + evt.clear() + inputA.close() + outputA.close() + assert 0 == COMPARE_ASCII_FILES("inputIO4.hepmcfrom" + ext, "inputIO4.hepmc") return 0 diff --git a/python/test/test_IO7.py b/python/test/test_IO7.py index 3be5ca8f..7b1299c9 100644 --- a/python/test/test_IO7.py +++ b/python/test/test_IO7.py @@ -14,14 +14,20 @@ def test_IO7(): try: - import uproot - import numpy - if (int(uproot.__version__.split('.')[2])+int(uproot.__version__.split('.')[1])*100+int(uproot.__version__.split('.')[0])*10000 < 40000): - print("uproot version is too old. Exit.\n") - return 0 + import uproot + import numpy + + if ( + int(uproot.__version__.split(".")[2]) + + int(uproot.__version__.split(".")[1]) * 100 + + int(uproot.__version__.split(".")[0]) * 10000 + < 40000 + ): + print("uproot version is too old. Exit.\n") + return 0 except ImportError as e: - print("uproot and/or numpy are not installed. Exit.\n") - return 0 + print("uproot and/or numpy are not installed. Exit.\n") + return 0 inputA = hmrootIO.ReaderRootTree("inputIO7.root") if inputA.failed(): sys.exit(1) @@ -45,7 +51,7 @@ def test_IO7(): evt.clear() inputA.close() outputA.close() - tocA = time.perf_counter() + tocA = time.perf_counter() ticB = time.perf_counter() while not inputB.failed(): evt = hm.GenEvent() @@ -58,8 +64,10 @@ def test_IO7(): inputB.close() outputB.close() tocB = time.perf_counter() - assert 0 == COMPARE_ASCII_FILES(python_label() + "ReaderRootTreeinputIO7.hepmc", python_label() + "ReaderuprootTreeinputIO7.hepmc") - print("ReaderRootTree: "+str(1000*(tocA-ticA)), "ReaderuprootTree: "+str(1000*(tocB-ticB))) + assert 0 == COMPARE_ASCII_FILES( + python_label() + "ReaderRootTreeinputIO7.hepmc", python_label() + "ReaderuprootTreeinputIO7.hepmc" + ) + print("ReaderRootTree: " + str(1000 * (tocA - ticA)), "ReaderuprootTree: " + str(1000 * (tocB - ticB))) return 0 diff --git a/test/testFourVector.cc b/test/testFourVector.cc index 2e5ca4b3..a7fdebdc 100644 --- a/test/testFourVector.cc +++ b/test/testFourVector.cc @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of HepMC -// Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details) +// Copyright (C) 2014-2024 The HepMC collaboration (see AUTHORS for details) // #include #include