diff --git a/.github/workflows/mcstas-basictest.yml b/.github/workflows/mcstas-basictest.yml index 9d256dc9a8..f51abb26fe 100644 --- a/.github/workflows/mcstas-basictest.yml +++ b/.github/workflows/mcstas-basictest.yml @@ -86,13 +86,13 @@ jobs: id: setup-linux if: matrix.method == 'source' && runner.os == 'Linux' run: | - sudo apt -y install libgsl-dev libnexus-dev + sudo apt -y install libgsl-dev libhdf5-dev - name: Setup (macOS, source build) id: setup-macos if: matrix.method == 'source' && runner.os == 'macOS' run: | - brew install bison flex gfortran gsl homebrew/science/nexusformat + brew install bison flex gfortran gsl hdf5 - name: Setup (Windows, source build) id: setup-Windows @@ -161,7 +161,6 @@ jobs: if [ "$RUNNER_OS" == "macOS" ] && [ -f "/opt/homebrew/opt/flex/bin/flex" ]; then export HOMEBRW="/opt/homebrew/opt"; export GSLFLAGS="-lgsl -lgslcblas -L/opt/homebrew/lib -I/opt/homebrew/include"; fi if [ "$RUNNER_OS" == "macOS" ] && [ -f "/usr/local/opt/flex/bin/flex" ]; then export HOMEBRW="/usr/local/opt"; export GSLFLAGS="-lgsl -lgslcblas -L/usr/local/lib -I/usr/local/include"; fi if [ "$RUNNER_OS" == "macOS" ]; then export EXTRA_ARGS_FOR_CMAKE="-DBISON_EXECUTABLE=${HOMEBRW}/bison/bin/bison -DFLEX_EXECUTABLE=${HOMEBRW}/flex/bin/flex -DCMAKE_Fortran_COMPILER=${HOMEBRW}/gfortran/bin/gfortran"; fi - if [ "$RUNNER_OS" == "Linux" ]; then export EXTRA_ARGS_FOR_CMAKE="-DNEXUSLIB=/usr/lib -DNEXUSINCLUDE=/usr/include/nexus"; fi if [ "$RUNNER_OS" == "Windows" ]; then export MPIINC=`cygpath -m -s "${MSMPI_INC}"`; export MPILIB=`cygpath -m -s "${MSMPI_LIB64}"`; export EXTRA_ARGS_FOR_CMAKE="-DMPILIBDIR=${MPILIB} -DMPIINCLUDEDIR=${MPIINC}"; fi cmake \ -DCMAKE_INSTALL_PREFIX=../install_mcstas \ diff --git a/.github/workflows/mcxtrace-basictest.yml b/.github/workflows/mcxtrace-basictest.yml index 14edd63075..b447a0832d 100644 --- a/.github/workflows/mcxtrace-basictest.yml +++ b/.github/workflows/mcxtrace-basictest.yml @@ -86,7 +86,7 @@ jobs: id: setup-linux if: matrix.method == 'source' && runner.os == 'Linux' run: | - sudo apt -y install libgsl-dev libxrl-dev libnexus-dev + sudo apt -y install libgsl-dev libxrl-dev libhdf5-dev - name: Setup (macOS, source build) id: setup-macos @@ -95,7 +95,7 @@ jobs: # cause build-issues. Will soon port basictest scripts to conda # for Windows/Linux run: | - brew install bison flex gfortran gsl + brew install bison flex gfortran gsl hdf5 #if [ "${{ matrix.os }}" != "macos-15" ]; #then # brew tap tschoonj/tap @@ -169,7 +169,6 @@ jobs: if [ "$RUNNER_OS" == "macOS" ] && [ -f "/opt/homebrew/opt/flex/bin/flex" ]; then export HOMEBRW="/opt/homebrew/opt"; export GSLFLAGS="-lgsl -lgslcblas -L/opt/homebrew/lib -I/opt/homebrew/include"; export XRLFLAGS="-lxrl -L/opt/homebrew/lib -I/opt/homebrew/include"; fi if [ "$RUNNER_OS" == "macOS" ] && [ -f "/usr/local/opt/flex/bin/flex" ]; then export HOMEBRW="/usr/local/opt"; export GSLFLAGS="-lgsl -lgslcblas -L/usr/local/lib -I/usr/local/include"; export XRLFLAGS="-lxrl -L/usr/local/lib -I/usr/local/include"; fi if [ "$RUNNER_OS" == "macOS" ]; then export EXTRA_ARGS_FOR_CMAKE="-DBISON_EXECUTABLE=${HOMEBRW}/bison/bin/bison -DFLEX_EXECUTABLE=${HOMEBRW}/flex/bin/flex -DCMAKE_Fortran_COMPILER=${HOMEBRW}/gfortran/bin/gfortran"; fi - if [ "$RUNNER_OS" == "Linux" ]; then export EXTRA_ARGS_FOR_CMAKE="-DNEXUSLIB=/usr/lib -DNEXUSINCLUDE=/usr/include/nexus"; fi if [ "$RUNNER_OS" == "Windows" ]; then export MPIINC=`cygpath -m -s "${MSMPI_INC}"`; export MPILIB=`cygpath -m -s "${MSMPI_LIB64}"`; export EXTRA_ARGS_FOR_CMAKE="-DMPILIBDIR=${MPILIB} -DMPIINCLUDEDIR=${MPIINC}"; fi cmake \ -DCMAKE_INSTALL_PREFIX=../install_mcxtrace \ diff --git a/3rdparty/nexus-package/CMakeLists.txt b/3rdparty/nexus-package/CMakeLists.txt deleted file mode 100644 index c9d1aa8732..0000000000 --- a/3rdparty/nexus-package/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -cmake_minimum_required(VERSION 3.17) - -# This will install NeXus components -project(NeXus_wrapper) - -message(STATUS "Configure ${CMAKE_PROJECT_NAME} ${FLAVOR} ${PROJECT_NAME}") - -# Choose between McStas or McXtrace -option(BUILD_MCSTAS "Choose the McStas flavor" off) -option(BUILD_MCXTRACE "Choose the McXtrace flavor (trumps BUILD_MCSTAS)" Off) - -# Set module path -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -# Set McCode values (from mkdist or defaults) -include(MCUtil) - -if (${BUILD_MCXTRACE}) - set(FLAVOR "mcxtrace") -elseif(${BUILD_MCSTAS}) - set(FLAVOR "mcstas") -else() - message(FATAL_ERROR "No flavor specified!\n" - "Please use either -DBUILD_MCSTAS=1 or -DBUILD_MCXTRACE=1") -endif() -setupMCCODE("${FLAVOR}") - -set(CPACK_PACKAGE_NAME "${FLAVOR}-nexus-${MCCODE_VERSION}") -set(CPACK_PACKAGE_CONTACT "pkwi@fysik.dtu.dk") -set(CPACK_PACKAGE_VERSION "0.0.1") -set(CPACK_PACKAGE_VERSION_MAJOR "0.0") -set(CPACK_PACKAGE_VERSION_MINOR "1") -set(CPACK_NSIS_PACKAGE_NAME "NeXus 0.0.1") -set(CPACK_NSIS_DISPLAY_NAME "NeXus 0.0.1") - -# NSIS -set(NSIS_NAME "${CPACK_PACKAGE_NAME}") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${NSIS_NAME}") - -include(CPack) - -set(WORK "${PROJECT_BINARY_DIR}/work") - -add_subdirectory(nexus-code) - diff --git a/3rdparty/nexus-package/cmake b/3rdparty/nexus-package/cmake deleted file mode 120000 index c06bb027c6..0000000000 --- a/3rdparty/nexus-package/cmake +++ /dev/null @@ -1 +0,0 @@ -../../cmake/ \ No newline at end of file diff --git a/3rdparty/nexus-package/nexus-code b/3rdparty/nexus-package/nexus-code deleted file mode 120000 index 911aa9caa1..0000000000 --- a/3rdparty/nexus-package/nexus-code +++ /dev/null @@ -1 +0,0 @@ -../nexus-code/ \ No newline at end of file diff --git a/3rdparty/sync.sh b/3rdparty/sync.sh index 2ce8b67cce..102d4c9a00 100755 --- a/3rdparty/sync.sh +++ b/3rdparty/sync.sh @@ -27,16 +27,6 @@ else git clone https://github.com/mctools/ncrystal.git fi -if [ -d nexus-code ]; then - echo Updating existing NeXus clone - cd nexus-code - git pull - cd .. -else - echo Cloning NeXus - git clone https://github.com/nexusformat/code nexus-code -fi - if [ -d xraylib ]; then echo Updating existing xraylib clone cd xraylib diff --git a/buildscripts/build_pkg_ghostbsd b/buildscripts/build_pkg_ghostbsd index b907c52c78..b58706f9ed 100755 --- a/buildscripts/build_pkg_ghostbsd +++ b/buildscripts/build_pkg_ghostbsd @@ -39,5 +39,4 @@ export MCINSTALL_PREFIX=/usr/local ./mkdist mcstas-ncrystal ${1} 3rdparty/ncrystal-package "" ghostbsd "" -- pkg ./mkdist mcstas-mcpl ${1} 3rdparty/mcpl-package "" ghostbsd "" -- pkg -./mkdist mcstas-nexus ${1} 3rdparty/nexus-package "" ghostbsd "" -- pkg diff --git a/cmake/Modules/InstallMCCODE.cmake b/cmake/Modules/InstallMCCODE.cmake index b9b24db128..bd263eb66f 100644 --- a/cmake/Modules/InstallMCCODE.cmake +++ b/cmake/Modules/InstallMCCODE.cmake @@ -99,7 +99,7 @@ macro(installMCCODE) # update definitions to match choices if (USE_NEXUS) - AppendDef(HAVE_NEXUS="-DUSE_NEXUS -lNeXus") + AppendDef(HAVE_NEXUS="-DUSE_NEXUS -lhdf5") AppendDef(USE_NEXUS) endif() diff --git a/cmake/Modules/MCUtil.cmake b/cmake/Modules/MCUtil.cmake index 55538985a6..2d9f6c6e34 100644 --- a/cmake/Modules/MCUtil.cmake +++ b/cmake/Modules/MCUtil.cmake @@ -61,12 +61,6 @@ macro(setupMCCODE FLAVOR) set(WINDOWS true) endif() - # Set Nexus linking flag - if(USE_NEXUS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lNeXus") - set(CMAKE_C_LFLAGS "${CMAKE_C_LFLAGS} -lNeXus") - endif() - # Set 32-bit flags if(ARCH EQUAL "i386") set(CMAKE_C_FLAGS "-m32") diff --git a/cmake/Modules/PlatformDefaults.cmake b/cmake/Modules/PlatformDefaults.cmake index bf0d13d619..184ef84908 100644 --- a/cmake/Modules/PlatformDefaults.cmake +++ b/cmake/Modules/PlatformDefaults.cmake @@ -223,17 +223,17 @@ function( detect_platform_variables resultvarname ) provide_var( MPICC ) - #NeXus-flags: + #NeXus-flags: NeXus output is written with HDF5 (NEXUSLIB/NEXUSINCLUDE: where libhdf5 and hdf5.h are) if ( NOT NEXUSFLAGS ) - set(NEXUSFLAGS "-DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lNeXus -lhdf5")#?? should probably have another value + set(NEXUSFLAGS "-DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lhdf5") if ( MCCODE_BUILD_CONDA_PKG ) - set( NEXUSFLAGS "-DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -I\$\{CONDA_PREFIX\}/include/nexus -I\$\{CONDA_PREFIX\}/include -Wl,-rpath,$\{CONDA_PREFIX\}/lib -L\$\{CONDA_PREFIX\}/lib -lNeXus -lhdf5" ) + set( NEXUSFLAGS "-DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -I\$\{CONDA_PREFIX\}/include -Wl,-rpath,$\{CONDA_PREFIX\}/lib -L\$\{CONDA_PREFIX\}/lib -lhdf5" ) endif() if ( WINDOWS ) if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" ) - set( NEXUSFLAGS " /DUSE_NEXUS /DNX_COMPRESSION=NX_COMP_LZW_LVL1 /DH5_BUILT_AS_DYNAMIC_LIB /I\$\{CONDA_PREFIX\}/Library/include/nexus /I\$\{CONDA_PREFIX\}/Library/include /link /LIBPATH:\$\{CONDA_PREFIX\}/Library/lib NeXus.lib hdf5.lib" ) + set( NEXUSFLAGS " /DUSE_NEXUS /DNX_COMPRESSION=NX_COMP_LZW_LVL1 /DH5_BUILT_AS_DYNAMIC_LIB /I\$\{CONDA_PREFIX\}/Library/include /link /LIBPATH:\$\{CONDA_PREFIX\}/Library/lib hdf5.lib" ) else() - set( NEXUSFLAGS "-DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -DH5_BUILT_AS_DYNAMIC_LIB -I\$\{CONDA_PREFIX\}/Library/include/nexus -I\$\{CONDA_PREFIX\}/Library/include -Wl,-rpath,$\{CONDA_PREFIX\}/Library/lib -L\$\{CONDA_PREFIX\}/Library/lib -lNeXus -lhdf5" ) + set( NEXUSFLAGS "-DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -DH5_BUILT_AS_DYNAMIC_LIB -I\$\{CONDA_PREFIX\}/Library/include -Wl,-rpath,$\{CONDA_PREFIX\}/Library/lib -L\$\{CONDA_PREFIX\}/Library/lib -lhdf5" ) endif() endif() if ( NEXUSLIB ) diff --git a/cmake/toolchains/deb32.cmake b/cmake/toolchains/deb32.cmake index c48945d527..009d646332 100644 --- a/cmake/toolchains/deb32.cmake +++ b/cmake/toolchains/deb32.cmake @@ -10,10 +10,8 @@ set(MPICC "mpicc") set(MPILIB "mpi") set(OACCFLAGS "-fast -Minfo=accel -acc=gpu -gpu=managed -DOPENACC") set(MPIRUN "mpirun") -set(NEXUSLIB "/usr/lib") -set(NEXUSINCLUDE "/usr/include/nexus") -# Packages are built before libnexus-dev/libhdf5-dev are installed: set the +# Packages are built before libhdf5-dev is installed: set the # full flags. Debian's serial HDF5 is in /usr/include/hdf5/serial, linked as libhdf5_serial -set(NEXUSFLAGS "-Wl,-rpath,/usr/lib -L/usr/lib -DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lNeXus -lhdf5_serial -I/usr/include/nexus -I/usr/include/hdf5/serial") +set(NEXUSFLAGS "-Wl,-rpath,/usr/lib -L/usr/lib -DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lhdf5_serial -I/usr/include/hdf5/serial") set(MCCODE_CFLAGS "-fno-PIC -fPIE -flto -O3 -mtune=native -march=native -fno-math-errno -ftree-vectorize -g -DNDEBUG -D_POSIX_SOURCE -std=c99 -lm") set(EDITOR "gedit") diff --git a/cmake/toolchains/deb64.cmake b/cmake/toolchains/deb64.cmake index 95e4710381..908e6a2498 100644 --- a/cmake/toolchains/deb64.cmake +++ b/cmake/toolchains/deb64.cmake @@ -10,10 +10,8 @@ set(MPICC "mpicc") set(OACCFLAGS "-fast -Minfo=accel -acc=gpu -gpu=managed -DOPENACC") set(MPILIB "mpi") set(MPIRUN "mpirun") -set(NEXUSLIB "/usr/lib") -set(NEXUSINCLUDE "/usr/include/nexus") -# Packages are built before libnexus-dev/libhdf5-dev are installed: set the +# Packages are built before libhdf5-dev is installed: set the # full flags. Debian's serial HDF5 is in /usr/include/hdf5/serial, linked as libhdf5_serial -set(NEXUSFLAGS "-Wl,-rpath,/usr/lib -L/usr/lib -DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lNeXus -lhdf5_serial -I/usr/include/nexus -I/usr/include/hdf5/serial") +set(NEXUSFLAGS "-Wl,-rpath,/usr/lib -L/usr/lib -DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lhdf5_serial -I/usr/include/hdf5/serial") set(MCCODE_CFLAGS "-fno-PIC -fPIE -flto -O3 -mtune=native -march=native -fno-math-errno -ftree-vectorize -g -DNDEBUG -D_POSIX_SOURCE -std=c99 -lm") set(EDITOR "gedit") diff --git a/cmake/toolchains/deb64arm.cmake b/cmake/toolchains/deb64arm.cmake index 9966e2034b..d761dcd81a 100644 --- a/cmake/toolchains/deb64arm.cmake +++ b/cmake/toolchains/deb64arm.cmake @@ -10,10 +10,8 @@ set(MPICC "mpicc") set(MPILIB "mpi") set(OACCFLAGS "-fast -Minfo=accel -acc=gpu -gpu=managed -DOPENACC") set(MPIRUN "mpirun") -set(NEXUSLIB "/usr/lib") -set(NEXUSINCLUDE "/usr/include/nexus") -# Packages are built before libnexus-dev/libhdf5-dev are installed: set the +# Packages are built before libhdf5-dev is installed: set the # full flags. Debian's serial HDF5 is in /usr/include/hdf5/serial, linked as libhdf5_serial -set(NEXUSFLAGS "-Wl,-rpath,/usr/lib -L/usr/lib -DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lNeXus -lhdf5_serial -I/usr/include/nexus -I/usr/include/hdf5/serial") +set(NEXUSFLAGS "-Wl,-rpath,/usr/lib -L/usr/lib -DUSE_NEXUS -DNX_COMPRESSION=NX_COMP_LZW_LVL1 -lhdf5_serial -I/usr/include/hdf5/serial") set(MCCODE_CFLAGS "-fno-PIC -fPIE -flto -O3 -mtune=native -march=native -fno-math-errno -ftree-vectorize -g -DNDEBUG -D_POSIX_SOURCE -std=c99 -lm") set(EDITOR "gedit") diff --git a/cmake/toolchains/mac-silicon.cmake b/cmake/toolchains/mac-silicon.cmake index 8cbb8b05ce..ddf84297b4 100644 --- a/cmake/toolchains/mac-silicon.cmake +++ b/cmake/toolchains/mac-silicon.cmake @@ -16,6 +16,6 @@ set(XRLFLAGS "-IGETPATH(miniconda3/include) -Wl,-rpath,GETPATH(miniconda3/lib) - set(MPIRUN "mpirun") set(MPILIB "mpi") set(NEXUSLIB "GETPATH(miniconda3/lib)") -set(NEXUSINCLUDE "GETPATH(miniconda3/include/nexus)") +set(NEXUSINCLUDE "GETPATH(miniconda3/include)") set(MCCODE_CFLAGS "-g -O2 -DNDEBUG -lm -std=c99") set(EDITOR "open") diff --git a/cmake/toolchains/mac.cmake b/cmake/toolchains/mac.cmake index eeb7a5105f..fff151f297 100644 --- a/cmake/toolchains/mac.cmake +++ b/cmake/toolchains/mac.cmake @@ -16,6 +16,6 @@ set(XRLFLAGS "-IGETPATH(miniconda3/include) -Wl,-rpath,GETPATH(miniconda3/lib) - set(MPIRUN "mpirun") set(MPILIB "mpi") set(NEXUSLIB "GETPATH(miniconda3/lib)") -set(NEXUSINCLUDE "GETPATH(miniconda3/include/nexus)") +set(NEXUSINCLUDE "GETPATH(miniconda3/include)") set(MCCODE_CFLAGS "-g -O2 -DNDEBUG -lm -std=c99") set(EDITOR "open") diff --git a/cmake/toolchains/mingw64.cmake b/cmake/toolchains/mingw64.cmake index 1e82ea2522..a2824c6088 100644 --- a/cmake/toolchains/mingw64.cmake +++ b/cmake/toolchains/mingw64.cmake @@ -41,8 +41,8 @@ set(MPILIB "msmpi") set(MCCODE_CFLAGS "-flto -O3 -mtune=native -fno-math-errno -ftree-vectorize -g -DNDEBUG -D_POSIX_SOURCE -std=c99 -lm") set(EDITOR "start") -# NeXus location defaults -set(NEXUSINCLUDE "GETPATH(../miniconda3/Library/include/nexus)") +# HDF5 location for NeXus output +set(NEXUSINCLUDE "GETPATH(../miniconda3/Library/include)") set(NEXUSLIB "GETPATH(../miniconda3/Library/lib)") # HDFviewer diff --git a/common/lib/share/mccode-r.c b/common/lib/share/mccode-r.c index e8e0953cf3..84a435be4b 100644 --- a/common/lib/share/mccode-r.c +++ b/common/lib/share/mccode-r.c @@ -1571,8 +1571,313 @@ static char *strcpy_valid(char *valid, char *original) #ifdef USE_NEXUS +/* ========================================================================== */ + +/* NeXus API subset (napi.h) on native HDF5, see mccode-r.h */ + +/* ========================================================================== */ + NXhandle nxhandle = NULL; +/* The open groups are a stack of HDF5 ids, so names are resolved by HDF5 + relative to the current group: no path buffers, and a failed open leaves + the stack unchanged. At most one data set is open (napi semantics). */ +#define MCNX_MAXDEPTH 32 +struct mcnx_file { hid_t fid, d, g[MCNX_MAXDEPTH]; int depth; }; +static int mcnx_quiet = 0; /* nesting depth of NXMDisableErrorReporting (napi5 did not nest) */ + +void NXMDisableErrorReporting(void) { mcnx_quiet++; } +void NXMEnableErrorReporting(void) { if (mcnx_quiet) mcnx_quiet--; } + +static NXstatus mcnx_error(const char *what, const char *name) +{ + if (!mcnx_quiet) fprintf(stderr, "NeXus error: %s '%s'\n", what, name ? name : ""); + return(NX_ERROR); +} + +/* current group, the file id standing for the root group */ +static hid_t mcnx_loc(struct mcnx_file *f) { return f->depth ? f->g[f->depth-1] : f->fid; } + +static hid_t mcnx_type(int type) +{ + return type == NX_INT32 ? H5T_NATIVE_INT : type == NX_FLOAT64 ? H5T_NATIVE_DOUBLE : -1; +} + +/* scalar attribute, replacing an existing one (napi5) */ +static herr_t mcnx_attr(hid_t obj, const char *name, hid_t type, const void *data) +{ + hid_t space = H5Screate(H5S_SCALAR), a; + herr_t ret = -1; + if (H5Aexists_by_name(obj, ".", name, H5P_DEFAULT) > 0) + H5Adelete_by_name(obj, ".", name, H5P_DEFAULT); + a = H5Acreate_by_name(obj, ".", name, type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (a >= 0) { ret = H5Awrite(a, type, data); H5Aclose(a); } + H5Sclose(space); + return(ret); +} + +/* fixed-length string attribute without terminating NUL; HDF5 has no empty fixed strings */ +static herr_t mcnx_attr_str(hid_t obj, const char *name, const char *value, size_t len) +{ + hid_t t; + herr_t ret; + if (!len) return(-1); + t = H5Tcopy(H5T_C_S1); + H5Tset_size(t, len); + ret = mcnx_attr(obj, name, t, value); + H5Tclose(t); + return(ret); +} + +NXstatus NXopen(const char *filename, NXaccess am, NXhandle *h) +{ + struct mcnx_file *f = calloc(1, sizeof(*f)); + hid_t fapl; + + *h = NULL; + if (!f) return(mcnx_error("out of memory opening", filename)); + H5Eset_auto2(H5E_DEFAULT, NULL, NULL); /* failures are reported here, as napi5 did */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fclose_degree(fapl, H5F_CLOSE_STRONG); /* H5Fclose also closes ids left open */ + f->fid = am == NXACC_CREATE5 ? H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl) + : H5Fopen(filename, H5F_ACC_RDWR, fapl); + H5Pclose(fapl); + if (f->fid < 0) { free(f); return(mcnx_error("cannot open file", filename)); } + if (am == NXACC_CREATE5) { /* root attributes, as written by napi5 */ + unsigned maj, min, rel; + char ver[32], date[64]; + time_t t = time(NULL); + size_t n = strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S%z", localtime(&t)); + if (n == 24) { memmove(date+23, date+22, 3); date[22] = ':'; n = 25; } /* +hhmm -> +hh:mm */ + H5get_libversion(&maj, &min, &rel); + snprintf(ver, sizeof(ver), "%u.%u.%u", maj, min, rel); + mcnx_attr_str(f->fid, "NeXus_version", "4.4.2", 5); /* ponytail: last napi version, kept for readers checking it */ + mcnx_attr_str(f->fid, "file_name", filename, strlen(filename)); + mcnx_attr_str(f->fid, "HDF5_Version", ver, strlen(ver)); + mcnx_attr_str(f->fid, "file_time", date, n); /* no NX_class: the napi 4.4.3 builds in use never wrote it */ + } + *h = f; + return(NX_OK); +} + +NXstatus NXclose(NXhandle *h) +{ + struct mcnx_file *f = *h; + herr_t ret; + if (!f) return(NX_ERROR); + ret = H5Fclose(f->fid); /* closes open groups/data set too (H5F_CLOSE_STRONG) */ + free(f); + *h = NULL; + return(ret < 0 ? mcnx_error("cannot close file", NULL) : NX_OK); +} + +NXstatus NXmakegroup(NXhandle h, const char *name, const char *nxclass) +{ + struct mcnx_file *f = h; + hid_t g = H5Gcreate2(mcnx_loc(f), name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + herr_t ret; + if (g < 0) return(mcnx_error("could not create group", name)); + ret = mcnx_attr_str(g, "NX_class", nxclass, strlen(nxclass)); + H5Gclose(g); + return(ret < 0 ? mcnx_error("failed to store class of group", name) : NX_OK); +} + +/* ponytail: the NX_class of the group is not checked against nxclass (napi5 did) */ +NXstatus NXopengroup(NXhandle h, const char *name, const char *nxclass) +{ + struct mcnx_file *f = h; + hid_t g; + if (f->depth == MCNX_MAXDEPTH) return(mcnx_error("groups nested too deep at", name)); + g = H5Gopen2(mcnx_loc(f), name, H5P_DEFAULT); + if (g < 0) return(mcnx_error("group does not exist", name)); + f->g[f->depth++] = g; + return(NX_OK); +} + +NXstatus NXclosegroup(NXhandle h) +{ + struct mcnx_file *f = h; + if (!f->depth) return(mcnx_error("no group open to close", NULL)); /* napi5: silent */ + H5Gclose(f->g[--f->depth]); + return(NX_OK); +} + +NXstatus NXcompmakedata64(NXhandle h, const char *name, int type, int rank, + int64_t dims[], int comp, int64_t chunk[]) +{ + struct mcnx_file *f = h; + hsize_t cur[H5S_MAX_RANK], max[H5S_MAX_RANK], ch[H5S_MAX_RANK]; + hid_t t, s, p, d; + int i, unlimited = 0; + int lzw = comp == NX_COMP_LZW || comp/100 == NX_COMP_LZW; + int level = comp == NX_COMP_LZW ? 6 : comp % 100; + double bytes; + + if (!f->depth || rank < 1 || rank > H5S_MAX_RANK + || (type != NX_CHAR && mcnx_type(type) < 0)) + return(mcnx_error("cannot create data set (no group, rank or type)", name)); + for (i = 0; i < rank; i++) { + unlimited |= dims[i] <= 0; + cur[i] = dims[i] > 0 ? dims[i] : 1; + max[i] = dims[i] > 0 ? dims[i] : H5S_UNLIMITED; + ch[i] = chunk[i] > 0 ? chunk[i] : 1; + } + if (type == NX_CHAR) { /* napi5: the last dimension is the string length */ + t = H5Tcopy(H5T_C_S1); + H5Tset_size(t, cur[rank-1]); + cur[rank-1] = max[rank-1] = ch[rank-1] = 1; + } else t = H5Tcopy(mcnx_type(type)); + p = H5Pcreate(H5P_DATASET_CREATE); + if (lzw || unlimited) { + /* HDF5 refuses chunks of 4 GiB or more: napi5 then lost the whole data set */ + for (bytes = H5Tget_size(t), i = 0; i < rank; i++) bytes *= ch[i]; + if (bytes >= 4294967295.0) ch[0] = ch[0]/(hsize_t)(bytes/4294967295.0 + 1) + 1; + H5Pset_chunk(p, rank, ch); + if (lzw) { H5Pset_shuffle(p); H5Pset_deflate(p, level); } + } + s = H5Screate_simple(rank, cur, max); + d = H5Dcreate2(mcnx_loc(f), name, t, s, H5P_DEFAULT, p, H5P_DEFAULT); + H5Sclose(s); H5Pclose(p); H5Tclose(t); + if (d < 0) return(mcnx_error("could not create data set", name)); + H5Dclose(d); + return(NX_OK); +} + +NXstatus NXcompmakedata(NXhandle h, const char *name, int type, int rank, int dims[], int comp, int chunk[]) +{ + int64_t d[H5S_MAX_RANK], c[H5S_MAX_RANK]; + int i; + for (i = 0; i < rank && i < H5S_MAX_RANK; i++) { d[i] = dims[i]; c[i] = chunk[i]; } + return(NXcompmakedata64(h, name, type, rank, d, comp, c)); +} + +NXstatus NXmakedata(NXhandle h, const char *name, int type, int rank, int dims[]) +{ + return(NXcompmakedata(h, name, type, rank, dims, NX_COMP_NONE, dims)); +} + +NXstatus NXopendata(NXhandle h, const char *name) +{ + struct mcnx_file *f = h; + if (f->d) H5Dclose(f->d); + f->d = H5Dopen2(mcnx_loc(f), name, H5P_DEFAULT); + if (f->d < 0) { f->d = 0; return(mcnx_error("data set not found", name)); } + return(NX_OK); +} + +NXstatus NXclosedata(NXhandle h) +{ + struct mcnx_file *f = h; + if (!f->d) return(mcnx_error("no data set open to close", NULL)); + H5Dclose(f->d); + f->d = 0; + return(NX_OK); +} + +/* write data with the type of the data set (napi5); only used with fixed-size data sets */ +NXstatus NXputdata(NXhandle h, const void *data) +{ + struct mcnx_file *f = h; + hid_t t; + herr_t ret; + if (!f->d) return(mcnx_error("no data set open to write", NULL)); + t = H5Dget_type(f->d); + ret = H5Dwrite(f->d, t, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); + H5Tclose(t); + return(ret < 0 ? mcnx_error("failure to write data", NULL) : NX_OK); +} + +/* write a slab, extending unlimited dimensions as needed */ +NXstatus NXputslab64(NXhandle h, const void *data, const int64_t start[], const int64_t size[]) +{ + struct mcnx_file *f = h; + hsize_t s0[H5S_MAX_RANK], n[H5S_MAX_RANK], ext[H5S_MAX_RANK], max[H5S_MAX_RANK]; + hid_t fs, ms, t; + herr_t ret = -1; + int i, rank, grow = 0; + + if (!f->d) return(mcnx_error("no data set open to write", NULL)); + fs = H5Dget_space(f->d); + rank = H5Sget_simple_extent_dims(fs, ext, max); + for (i = 0; i < rank; i++) { + s0[i] = start[i]; n[i] = size[i]; + if (max[i] == H5S_UNLIMITED && s0[i] + n[i] > ext[i]) { ext[i] = s0[i] + n[i]; grow = 1; } + } + if (grow) { H5Sclose(fs); H5Dset_extent(f->d, ext); fs = H5Dget_space(f->d); } + ms = H5Screate_simple(rank, n, NULL); + t = H5Dget_type(f->d); + if (H5Sselect_hyperslab(fs, H5S_SELECT_SET, s0, NULL, n, NULL) >= 0) + ret = H5Dwrite(f->d, t, ms, fs, H5P_DEFAULT, data); + H5Tclose(t); H5Sclose(ms); H5Sclose(fs); + return(ret < 0 ? mcnx_error("writing slab failed", NULL) : NX_OK); +} + +/* attribute of the open data set, else of the current group (root included) */ +NXstatus NXputattr(NXhandle h, const char *name, const void *data, int len, int type) +{ + struct mcnx_file *f = h; + hid_t obj = f->d ? f->d : mcnx_loc(f); + herr_t ret = type == NX_CHAR ? mcnx_attr_str(obj, name, data, len > 0 ? len : 0) + : mcnx_type(type) >= 0 ? mcnx_attr(obj, name, mcnx_type(type), data) : -1; + return(ret < 0 ? mcnx_error("attribute cannot be created", name) : NX_OK); +} + +NXstatus NXgetinfo64(NXhandle h, int *rank, int64_t dims[], int *type) +{ + struct mcnx_file *f = h; + hsize_t d[H5S_MAX_RANK]; + hid_t s, t; + int i; + if (!f->d) return(mcnx_error("no data set open", NULL)); + s = H5Dget_space(f->d); t = H5Dget_type(f->d); + *rank = H5Sget_simple_extent_dims(s, d, NULL); + for (i = 0; i < *rank; i++) dims[i] = d[i]; + /* ponytail: only the types McCode writes; napi5 also mapped sizes/signedness */ + *type = H5Tget_class(t) == H5T_STRING ? NX_CHAR : H5Tget_class(t) == H5T_INTEGER ? NX_INT32 : NX_FLOAT64; + H5Tclose(t); H5Sclose(s); + return(NX_OK); +} + +/* number of items in the current group; name/class only for the root (all McCode uses) */ +NXstatus NXgetgroupinfo(NXhandle h, int *n, NXname name, NXname nxclass) +{ + struct mcnx_file *f = h; + H5G_info_t info; + if (H5Gget_info(mcnx_loc(f), &info) < 0) return(mcnx_error("cannot get group info", NULL)); + *n = (int)info.nlinks; + strcpy(name, f->depth ? "" : "root"); + strcpy(nxclass, f->depth ? "" : "NXroot"); + return(NX_OK); +} + +NXstatus NXgetgroupID(NXhandle h, NXlink *link) +{ + struct mcnx_file *f = h; + ssize_t len; + if (!f->depth) return(NX_ERROR); + len = H5Iget_name(f->g[f->depth-1], link->targetPath, sizeof(link->targetPath)); + if (len <= 0 || len >= (ssize_t)sizeof(link->targetPath)) + return(mcnx_error("group path too long to link", NULL)); + link->linkType = 0; + return(NX_OK); +} + +/* hard link to link->targetPath in the current group, and 'target' attribute on it */ +NXstatus NXmakelink(NXhandle h, NXlink *link) +{ + struct mcnx_file *f = h; + const char *item = strrchr(link->targetPath, '/'); + hid_t obj; + herr_t ret; + if (!f->depth || !item) return(mcnx_error("cannot link", link->targetPath)); + H5Lcreate_hard(f->fid, link->targetPath, mcnx_loc(f), item+1, H5P_DEFAULT, H5P_DEFAULT); /* an existing link is kept (napi5) */ + obj = H5Oopen(f->fid, link->targetPath, H5P_DEFAULT); + if (obj < 0) return(mcnx_error("link target does not exist", link->targetPath)); + ret = mcnx_attr_str(obj, "target", link->targetPath, strlen(link->targetPath)); + H5Oclose(obj); + return(ret < 0 ? mcnx_error("cannot set link target", link->targetPath) : NX_OK); +} + /* name of the NXentry opened by mcinfo_out_nexus (used by mclist_vds_write) */ static char mcnxentry[CHAR_BUF_LENGTH] = "entry1"; @@ -2398,19 +2703,6 @@ static void mccomp_param_nexus(NXhandle nxhandle, char* component, char* paramet * open data:NXdetector then filename:NXdata and write headers/attributes * requires: NXentry to be opened *******************************************************************************/ -/* napi5 assembles group paths in char[1024] buffers without bounds checks: - a longer path overflows them (crash or corrupt file), so it is not written */ -static int mcnexus_path_ok(MCDETECTOR *detector, char *data_name, int warn) -{ - size_t len = strlen(mcnxentry) + strlen("/instrument/components/") - + strlen(detector->nexuscomp) + strlen("/output/") + strlen(data_name); - if (len < 1000) return(1); - if (warn) - fprintf(stderr, "Warning: %s: NeXus path of '%.40s...' has %lu characters, more than the NeXus API handles. " - "Not written to the NeXus file (mcdatainfo_out_nexus)\n", detector->component, data_name, (unsigned long)len); - return(0); -} - static void mcdatainfo_out_nexus(NXhandle f, MCDETECTOR detector) { @@ -2420,7 +2712,6 @@ mcdatainfo_out_nexus(NXhandle f, MCDETECTOR detector) strcpy_valid(data_name, strlen(detector.filename) ? detector.filename : detector.component); - if (!mcnexus_path_ok(&detector, data_name, 1)) return; /* the NXdetector group has been created in mcinfo_out_nexus (siminfo_init) */ if (NXopengroup(f, "instrument", "NXinstrument") == NX_OK) { @@ -2513,7 +2804,9 @@ int mcdetector_out_axis_nexus(NXhandle f, char *label, char *var, int rank, long axis[i] = min+(max-min)*(i+0.5)/length; /* create the data set */ strcpy_valid(valid, label); + NXMDisableErrorReporting(); /* exists when a list buffer was flushed before */ NXcompmakedata(f, valid, NX_FLOAT64, 1, &dim, NX_COMPRESSION, &dim); + NXMEnableErrorReporting(); /* open it */ if (NXopendata(f, valid) != NX_OK) { fprintf(stderr, "Warning: could not open axis rank %i '%s' (NeXus)\n", @@ -2555,15 +2848,9 @@ int mcdetector_out_array_nexus(NXhandle f, char *part, double *data, MCDETECTOR /* when this is a list, we set 1st dimension to NX_UNLIMITED for creation */ if (strcasestr(detector.format, "list")) fulldims[0] = NX_UNLIMITED; - /* HDF5 refuses chunks of 4 GiB or more (napi5 uses the whole block as chunk): - the data set would not be created at all */ - int64_t chunk[3]={dims[0],dims[1],dims[2]}; - double bytes=8.0*dims[0]*(detector.rank > 1 ? dims[1] : 1)*(detector.rank > 2 ? dims[2] : 1); - if (bytes >= 4294967295.0) chunk[0] = chunk[0]/(int64_t)(bytes/4294967295.0 + 1) + 1; - /* create the data set in NXdata group */ NXMDisableErrorReporting(); /* inactivate NeXus error messages, as creation may fail */ - ret = NXcompmakedata64(f, part, NX_FLOAT64, detector.rank, fulldims, NX_COMPRESSION, chunk); + ret = NXcompmakedata64(f, part, NX_FLOAT64, detector.rank, fulldims, NX_COMPRESSION, dims); if (ret != NX_OK) { /* failed: data set already exists */ int datatype=0; @@ -2620,7 +2907,6 @@ int mcdetector_out_data_nexus(NXhandle f, MCDETECTOR detector) strcpy_valid(data_name, strlen(detector.filename) ? detector.filename : detector.component); - if (!mcnexus_path_ok(&detector, data_name, 0)) return(NX_ERROR); NXlink pLink; int linked = 0; /* the NXdetector group has been created in mcinfo_out_nexus (siminfo_init) */ @@ -3142,8 +3428,6 @@ static void mcdetector_list_write(MCDETECTOR detector, int append_raw) * result; 'h5repack -l CONTI' makes a self-contained copy. *******************************************************************************/ #ifdef USE_NEXUS -#include - /* one VDS to create in mccode.h5 after NXclose (master only) */ struct mclist_vds { char path[4*CHAR_BUF_LENGTH]; /* /entry/.../events in mccode.h5 */ diff --git a/common/lib/share/mccode-r.h.in b/common/lib/share/mccode-r.h.in index f77315f5cc..bd5a1c72aa 100644 --- a/common/lib/share/mccode-r.h.in +++ b/common/lib/share/mccode-r.h.in @@ -995,7 +995,54 @@ MCDETECTOR mcdetector_out_list(char *t, char *xl, char *yl, mcdetector_out_2D(t,xl,yl,x1,x2,y1,y2,m,n,p0,p1,p2,f,NAME_CURRENT_COMP,POS_A_CURRENT_COMP,ROT_A_CURRENT_COMP,INDEX_CURRENT_COMP) #ifdef USE_NEXUS -#include "napi.h" +/* NeXus output: the subset of the frozen NeXus API (napi.h) used by McCode and + its components, implemented on native HDF5 in mccode-r.c. Names, values and + the written file layout follow napi5. */ +#include +typedef void *NXhandle; +typedef int NXstatus; +typedef int NXaccess; +typedef char NXname[128]; +typedef struct { char targetPath[1024]; int linkType; } NXlink; +#define NX_OK 1 +#define NX_ERROR 0 +#define NX_UNLIMITED -1 +#define NX_CHAR 4 +#define NX_FLOAT64 6 +#define NX_INT32 24 +#define NXACC_RDWR 2 +#define NXACC_CREATE5 5 +#define NX_COMP_NONE 100 +#define NX_COMP_LZW 200 +#define NX_COMP_LZW_LVL0 (100*NX_COMP_LZW + 0) +#define NX_COMP_LZW_LVL1 (100*NX_COMP_LZW + 1) +#define NX_COMP_LZW_LVL2 (100*NX_COMP_LZW + 2) +#define NX_COMP_LZW_LVL3 (100*NX_COMP_LZW + 3) +#define NX_COMP_LZW_LVL4 (100*NX_COMP_LZW + 4) +#define NX_COMP_LZW_LVL5 (100*NX_COMP_LZW + 5) +#define NX_COMP_LZW_LVL6 (100*NX_COMP_LZW + 6) +#define NX_COMP_LZW_LVL7 (100*NX_COMP_LZW + 7) +#define NX_COMP_LZW_LVL8 (100*NX_COMP_LZW + 8) +#define NX_COMP_LZW_LVL9 (100*NX_COMP_LZW + 9) +NXstatus NXopen(const char *filename, NXaccess am, NXhandle *h); +NXstatus NXclose(NXhandle *h); +NXstatus NXmakegroup(NXhandle h, const char *name, const char *nxclass); +NXstatus NXopengroup(NXhandle h, const char *name, const char *nxclass); +NXstatus NXclosegroup(NXhandle h); +NXstatus NXmakedata(NXhandle h, const char *name, int type, int rank, int dims[]); +NXstatus NXcompmakedata(NXhandle h, const char *name, int type, int rank, int dims[], int comp, int chunk[]); +NXstatus NXcompmakedata64(NXhandle h, const char *name, int type, int rank, int64_t dims[], int comp, int64_t chunk[]); +NXstatus NXopendata(NXhandle h, const char *name); +NXstatus NXclosedata(NXhandle h); +NXstatus NXputdata(NXhandle h, const void *data); +NXstatus NXputslab64(NXhandle h, const void *data, const int64_t start[], const int64_t size[]); +NXstatus NXputattr(NXhandle h, const char *name, const void *data, int len, int type); +NXstatus NXgetinfo64(NXhandle h, int *rank, int64_t dims[], int *type); +NXstatus NXgetgroupinfo(NXhandle h, int *n, NXname name, NXname nxclass); +NXstatus NXgetgroupID(NXhandle h, NXlink *link); +NXstatus NXmakelink(NXhandle h, NXlink *link); +void NXMDisableErrorReporting(void); +void NXMEnableErrorReporting(void); extern NXhandle nxhandle; /* store post-INIT values of component SETTING parameters (called after init()) */ void mccomp_param_runtime_nexus_all(NXhandle f); diff --git a/devel/bin/mccode-build-conda b/devel/bin/mccode-build-conda index 660c024027..4d47a7304a 100755 --- a/devel/bin/mccode-build-conda +++ b/devel/bin/mccode-build-conda @@ -53,12 +53,6 @@ def mccode_build_conda ( cfg ): extra_args = [] if ( cfg.is_unix ): - nexus_incdir = conda_prefix.joinpath('include/nexus') - nexus_libdir = conda_prefix.joinpath('lib') - if nexus_libdir.is_dir(): - extra_args.append( f'-DNEXUSLIB={nexus_libdir}' ) - if nexus_incdir.is_dir(): - extra_args.append( f'-DNEXUSINCLUDE={nexus_incdir}' ) GENERATOR = 'Unix Makefiles' if ( cfg.is_win ): diff --git a/devel/bin/mccode-create-conda-yml b/devel/bin/mccode-create-conda-yml index 17a4ec81ff..bdd41375eb 100755 --- a/devel/bin/mccode-create-conda-yml +++ b/devel/bin/mccode-create-conda-yml @@ -41,7 +41,7 @@ def create_deplist( cfg ): if cfg.is_win: deps += ['m2-which','m2-sed','m2-gzip','m2-coreutils'] if cfg.include_toplevel_extras: - deps += ['gsl','libnexus','nexpy','cif2hkl >=1.5.1','mcpl-extra >=2.2.8','kdsource'] + deps += ['gsl','hdf5','nexpy','cif2hkl >=1.5.1','mcpl-extra >=2.2.8','kdsource'] if cfg.is_mcstas: deps += ['ncrystal >=4.4.2'] if cfg.is_mcxtrace: diff --git a/docs/manuals/mcstas/kernel.tex b/docs/manuals/mcstas/kernel.tex index 3ccc16ad04..9882ad9fac 100644 --- a/docs/manuals/mcstas/kernel.tex +++ b/docs/manuals/mcstas/kernel.tex @@ -465,11 +465,10 @@ \subsection{The \texttt{NEXUS} extension} \label{s:nexus} The NeXus format~\cite{nexus_webpage} requires to link the simulation to -additional libraries (HDF and NeXus) which must have been -pre-installed. Preferably, \MCS should have been installed with the +the HDF5 library, which must have been pre-installed. Preferably, \MCS should have been installed with the \verb+./configure --with-nexus+ on Unix/Linux systems. To activate the NeXus output, the compilation of the instrument must be done with flag -\verb+-DUSE_NEXUS+ \verb+-lNeXus+. +\verb+-DUSE_NEXUS+ \verb+-lhdf5+. The resulting executable is no longer portable. The default NeXus format is HDF5 with compression. diff --git a/docs/manuals/mcstas/links_othercode.tex b/docs/manuals/mcstas/links_othercode.tex index 942185d063..f67399ee1a 100644 --- a/docs/manuals/mcstas/links_othercode.tex +++ b/docs/manuals/mcstas/links_othercode.tex @@ -15,8 +15,7 @@ \subsection{System requirements} your system: \begin{itemize} \item{\MCS 2.1 or newer} -\item{NeXus libraries from \verb+http://nexusformat.org+ \footnote{For Mac OS X you may get - better milage via the Mantid github site}} +\item{The HDF5 library from \verb+https://www.hdfgroup.org+ (also in conda-forge, Homebrew and the Linux distributions)} \item{Mantid 3.2 or newer} \item{On Mac OS X 10.8 and newer you may need to install one of the below compilers, as the default clang on OS X causes problems for @@ -77,7 +76,7 @@ \subsection{Compiling and running your simulation for Mantid output} \begin{enumerate} \item First of all, enable NeXus in the compilation process: \begin{mcstas} - export MCSTAS_CFLAGS="-g -lm -O2 -DUSE_NEXUS -lNeXus" + export MCSTAS_CFLAGS="-g -lm -O2 -DUSE_NEXUS -lhdf5" \end{mcstas} \item Compile the instrument via the mcrun utility (add \verb+--mpi+ if you need parallelization support): diff --git a/docs/manuals/mcstas/running.tex b/docs/manuals/mcstas/running.tex index d958ab37ff..557f028b78 100644 --- a/docs/manuals/mcstas/running.tex +++ b/docs/manuals/mcstas/running.tex @@ -1764,9 +1764,9 @@ \subsection{NeXus format} The NeXus format~\cite{nexus_webpage} is a platform independent HDF binary data file. To have \MCS use it \begin{enumerate} -\item the HDF and NeXus libraries must have been installed (libNeXus and headers) +\item the HDF5 library must have been installed (libhdf5 and headers) \item the compilation of instruments must be done with the - \verb+-DUSE_NEXUS -lNeXus+ flag (see Section \ref{s:nexus}). This is + \verb+-DUSE_NEXUS -lhdf5+ flag (see Section \ref{s:nexus}). This is automated with the \verb+mcrun+ tool (Section \ref{s:mcrun}). \end{enumerate} All results are saved in a single file, containing 'groups' of data. To view diff --git a/docs/manuals/mcxtrace/kernel.tex b/docs/manuals/mcxtrace/kernel.tex index 3ef343ffeb..400a2014f4 100644 --- a/docs/manuals/mcxtrace/kernel.tex +++ b/docs/manuals/mcxtrace/kernel.tex @@ -300,9 +300,9 @@ \subsection{The \texttt{NEXUS} extension} \index{Keyword!NEXUS} \index{Tools!NeXus} \index{Tools!HDF} \index{Data formats} \label{s:nexus} -To use the NeXus format~\cite{nexus_webpage} the simulation must be linked with additional libraries (HDF and NeXus) which must have been pre-installed. Preferrably, \MCX should +To use the NeXus format~\cite{nexus_webpage} the simulation must be linked with the HDF5 library, which must have been pre-installed. Preferrably, \MCX should have been installed with the \verb+./configure --with-nexus+ on Unix/Linux systems. To activate the NeXus output, the instrument must be compiled with the flags -\verb+-DUSE_NEXUS -lNeXus+. +\verb+-DUSE_NEXUS -lhdf5+. The default NeXus format is NeXus 5 with compression. However, that format may be changed with the optional keyword \verb+NEXUS+ to follow the INITIALIZE section, namely: diff --git a/docs/manuals/mcxtrace/running.tex b/docs/manuals/mcxtrace/running.tex index 36de00bd41..202f852b4f 100644 --- a/docs/manuals/mcxtrace/running.tex +++ b/docs/manuals/mcxtrace/running.tex @@ -1653,9 +1653,9 @@ \subsection{NeXus format} The NeXus format~\cite{nexus_webpage} is a platform independent HDF binary data file. To have \MCX use it \begin{enumerate} -\item the HDF and NeXus libraries must have been installed (libNeXus and headers) +\item the HDF5 library must have been installed (libhdf5 and headers) \item the compilation of instruments must be done with the - \verb+-DUSE_NEXUS -lNeXus+ flag (see Section \ref{s:nexus}). This is + \verb+-DUSE_NEXUS -lhdf5+ flag (see Section \ref{s:nexus}). This is automated with the \verb+mxrun+ tool (Section \ref{s:mxrun}). \end{enumerate} All results are saved in a single file, containing 'groups' of data. To view diff --git a/environment.yml b/environment.yml index c75b1d2e4e..3235f5de32 100644 --- a/environment.yml +++ b/environment.yml @@ -25,7 +25,6 @@ dependencies: - pyqtgraph - qtpy - qscintilla2 - - nexus - nexusformat - nexpy - hdf5 diff --git a/mccode/src/cogen.c.in b/mccode/src/cogen.c.in index ca24eff9fc..0afe71323e 100644 --- a/mccode/src/cogen.c.in +++ b/mccode/src/cogen.c.in @@ -2917,7 +2917,7 @@ cogen_header(struct instr_def *instr, char *output_name) embed_file("mcxtrace-r.h"); #endif /* NeXus support, only active with -DUSE_NEXUS */ - if (verbose) fprintf(stderr, "Compile '%s -DUSE_NEXUS -lNeXus' to enable NeXus support\n", output_name); + if (verbose) fprintf(stderr, "Compile '%s -DUSE_NEXUS -lhdf5' to enable NeXus support\n", output_name); embed_file("mccode-r.c"); #if MCCODE_PROJECT == 1 /* neutron */ embed_file("mcstas-r.c"); @@ -2937,7 +2937,7 @@ cogen_header(struct instr_def *instr, char *output_name) fprintf(stderr,"Dependency: %s.o\n", "mcxtrace-r"); #endif - fprintf(stderr,"Dependency: '-DUSE_NEXUS -lNeXus' to enable NeXus support\n"); + fprintf(stderr,"Dependency: '-DUSE_NEXUS -lhdf5' to enable NeXus support\n"); fprintf(stderr,"To build instrument '%s', compile and link with these libraries (in %s%sshare)\n", instrument_definition->quoted_source, sysdir_new, pathsep); } diff --git a/mcstas-comps/CMakeLists.txt b/mcstas-comps/CMakeLists.txt index a3be3c2fab..b9524a886a 100644 --- a/mcstas-comps/CMakeLists.txt +++ b/mcstas-comps/CMakeLists.txt @@ -13,9 +13,9 @@ include(External) option( ENABLE_CIF2HKL "Build Third Party code cif2hkl (fortran)" ON )#TODO: Only enable Fortran if this is on if ( ENABLE_CIF2HKL ) - set(DEBIDEPS "${FLAVOR}, libnexus-dev, libgsl-dev, mcpl (>= 2.2.0), ncrystal (>= 4.2.0)") + set(DEBIDEPS "${FLAVOR}, libhdf5-dev, libgsl-dev, mcpl (>= 2.2.0), ncrystal (>= 4.2.0)") else() - set(DEBIDEPS "${FLAVOR}, libnexus-dev, libgsl-dev, mcpl (>= 2.2.0), ncrystal (>= 4.2.0), cif2hkl (>= 1.5.1)") + set(DEBIDEPS "${FLAVOR}, libhdf5-dev, libgsl-dev, mcpl (>= 2.2.0), ncrystal (>= 4.2.0), cif2hkl (>= 1.5.1)") endif() set(WORK "${PROJECT_BINARY_DIR}/work") diff --git a/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/ILL_H16_IN5_Mantid.instr b/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/ILL_H16_IN5_Mantid.instr index 52bfef43e9..5f3446690d 100644 --- a/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/ILL_H16_IN5_Mantid.instr +++ b/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/ILL_H16_IN5_Mantid.instr @@ -18,7 +18,7 @@ *
    *
  1. Compile the instrument with NeXus support - zero neutrons: *
      -*
    • export MCSTAS_CFLAGS="-g -lm -O2 -DUSE_NEXUS -lNeXus" +*
    • export MCSTAS_CFLAGS="-g -lm -O2 -DUSE_NEXUS -lhdf5" *
    • mcrun -c -n0 --format=NeXus ILL_H16_IN5_Mantid.instr --no-output-files *
    *
  2. Generate the IDF in XML format using the (Perl) mcdisplay tool: diff --git a/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/README.md b/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/README.md index d3924acf52..c24244f52a 100644 --- a/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/README.md +++ b/mcstas-comps/examples/Mantid/ILL_H16_IN5_Mantid/README.md @@ -18,7 +18,7 @@ use with Mantid-friendly NeXus output. To compile and run, use these steps:
    1. Compile the instrument with NeXus support - zero neutrons:
        -
      • export MCSTAS_CFLAGS="-g -lm -O2 -DUSE_NEXUS -lNeXus" +
      • export MCSTAS_CFLAGS="-g -lm -O2 -DUSE_NEXUS -lhdf5"
      • mcrun -c -n0 --format=NeXus ILL_H16_IN5_Mantid.instr --no-output-files
    2. Generate the IDF in XML format using the (Perl) mcdisplay tool: diff --git a/mcxtrace-comps/CMakeLists.txt b/mcxtrace-comps/CMakeLists.txt index 81a6e7907f..b7a9d4598e 100644 --- a/mcxtrace-comps/CMakeLists.txt +++ b/mcxtrace-comps/CMakeLists.txt @@ -27,9 +27,9 @@ set(CPACK_PACKAGE_VERSION_PATCH "${MCCODE_PATCH}") # (as in mcstas-comps). ENABLE_CIF2HKL is only declared further down, so # read it as a cache variable here (default ON, as in its option()). if ( NOT DEFINED ENABLE_CIF2HKL OR ENABLE_CIF2HKL ) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "${FLAVOR}, libnexus-dev, libxrl-dev, libgsl-dev, mcpl (>= 2.2.0)") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${FLAVOR}, libhdf5-dev, libxrl-dev, libgsl-dev, mcpl (>= 2.2.0)") else() - set(CPACK_DEBIAN_PACKAGE_DEPENDS "${FLAVOR}, libnexus-dev, libxrl-dev, libgsl-dev, mcpl (>= 2.2.0), cif2hkl (>= 1.5.1)") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${FLAVOR}, libhdf5-dev, libxrl-dev, libgsl-dev, mcpl (>= 2.2.0), cif2hkl (>= 1.5.1)") endif() set(CPACK_DEBIAN_PACKAGE_REPLACES "${FLAVOR}-comps-3.5.1") diff --git a/meta-pkgs/windows/environment.yml b/meta-pkgs/windows/environment.yml index 7134de3539..2cf675c0bd 100644 --- a/meta-pkgs/windows/environment.yml +++ b/meta-pkgs/windows/environment.yml @@ -25,7 +25,6 @@ dependencies: - pyqtgraph - qtpy - qscintilla2 - - nexus - nexusformat - nexpy - hdf5 diff --git a/meta-pkgs/windows/mcstas-environment.yml b/meta-pkgs/windows/mcstas-environment.yml index bea4d70219..744658f49a 100644 --- a/meta-pkgs/windows/mcstas-environment.yml +++ b/meta-pkgs/windows/mcstas-environment.yml @@ -25,7 +25,6 @@ dependencies: - pyqtgraph - qtpy - qscintilla2 - - nexus - nexusformat - nexpy - hdf5 diff --git a/meta-pkgs/windows/mcxtrace-environment.yml b/meta-pkgs/windows/mcxtrace-environment.yml index 11ee228800..e7452aa3ed 100644 --- a/meta-pkgs/windows/mcxtrace-environment.yml +++ b/meta-pkgs/windows/mcxtrace-environment.yml @@ -25,7 +25,6 @@ dependencies: - pyqtgraph - qtpy - qscintilla2 - - nexus - nexusformat - nexpy - hdf5 diff --git a/support/MacOSX/Check-dependencies/README.TXT b/support/MacOSX/Check-dependencies/README.TXT index da1c01a464..52cbf49727 100644 --- a/support/MacOSX/Check-dependencies/README.TXT +++ b/support/MacOSX/Check-dependencies/README.TXT @@ -31,9 +31,9 @@ Contents of this folder: - Will ask you to take ownership of /usr/local - Will ask you to configure the firewall to allow simple usage of openmpi -6) If you need support for NeXus output, we propose to install this via homebrew (brew install nexusformat). - To allow compilation with the NeXus libraries, please redefine your CFLAGS through the mcgui/mxgui preferences: - -g -lm -O2 -DUSE_NEXUS -lNeXus -I/usr/local/include/nexus +6) If you need support for NeXus output, we propose to install HDF5 via homebrew (brew install hdf5). + To allow compilation with HDF5, please redefine your CFLAGS through the mcgui/mxgui preferences: + -g -lm -O2 -DUSE_NEXUS -I/usr/local/include -L/usr/local/lib -lhdf5 7) Now open either the newly installed app or environment script