aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--INSTALL.md20
-rw-r--r--config.h.cmake.in1
-rw-r--r--config.h.in1
-rw-r--r--libcrystfel/libcrystfel-config.h.cmake.in1
-rw-r--r--libcrystfel/libcrystfel-config.h.meson.in1
-rw-r--r--libcrystfel/src/image-hdf5.c66
-rw-r--r--libcrystfel/src/image.c35
-rw-r--r--meson.build42
-rw-r--r--meson_options.txt1
-rw-r--r--src/ambigator.c6
-rw-r--r--tests/meson.build82
12 files changed, 166 insertions, 91 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 75783bf8..f9073ca6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -112,6 +112,7 @@ set(HAVE_OPENCL ${OpenCL_FOUND})
set(HAVE_GDKPIXBUF ${GDKPIXBUF_FOUND})
set(HAVE_GDK ${GDK_FOUND})
set(HAVE_ZMQ ${ZMQ_FOUND})
+set(HAVE_HDF5 1)
set(PACKAGE_VERSION ${PROJECT_VERSION})
diff --git a/INSTALL.md b/INSTALL.md
index 9b126aef..fcdef0e3 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -26,24 +26,24 @@ supported facility installations.
Dependencies
------------
-Here are the mandatory dependencies - you cannot install CrystFEL without these:
+There are very few mandatory dependencies for CrystFEL. They are:
* [Meson](https://mesonbuild.com/) 0.55.0 or later
-* [HDF5](https://www.hdfgroup.org/downloads/hdf5/) 1.8.0 or later (1.10.0 or later is required for many recent data formats which use the 'virtual data set' feature)
* [GNU Scientific Library (GSL)](https://www.gnu.org/software/gsl/)
* [Bison](https://www.gnu.org/software/bison/) 2.6 or later
* [Flex](https://www.gnu.org/software/flex/)
[CMake](https://cmake.org/) 3.12 or later can be used in place of Meson,
-but Meson is strongly preferred. The CMake build system is considered
-deprecated, already lacks several useful features and will be removed at some
-point in the future.
+but Meson is strongly preferred. CrystFEL's CMake-based build system is
+considered deprecated and will be removed at some point in the future. It
+already lacks several features compared to the Meson-based system.
The following dependencies are "optional", in the sense that you can install
CrystFEL without them. However, a CrystFEL installation without these will lack
important features such as the graphical user interface. The following list is
roughly in order of importance:
+* [HDF5](https://www.hdfgroup.org/downloads/hdf5/) 1.8.0 or later (required for HDF5 file read/write. Version 1.10.0 or later is required for many recent data formats which use the 'virtual data set' feature)
* [GTK](https://gtk.org/) version between 3.12 and 3.24 inclusive (required for GUI)
* [Cairo](https://www.cairographics.org/) 1.2 or later (required for GUI)
* [Pango](https://pango.gnome.org/) 1.0 or later, including [PangoCairo](https://docs.gtk.org/PangoCairo/) (required for GUI)
@@ -58,6 +58,16 @@ roughly in order of importance:
* [msgpack-c](https://github.com/msgpack/msgpack-c) (for online data streaming)
* [SLURM](https://slurm.schedmd.com/) (development files required for submitting jobs via GUI)
+When building with Meson, it's possible to compile without HDF5. This is
+useful if you only need to use other file formats, e.g. CBF. You may have
+noticed that most compilation problems (see *Notes about strange problems*
+below) are related to HDF5. To build without HDF5, set up your build directory
+as follows, replacing the `meson build` step:
+```
+meson build -Dhdf5=disabled
+```
+When building with CMake, HDF5 is a mandatory dependency.
+
Most of the dependencies mentioned above should be available from your Linux
distribution's package manager, or from [Homebrew](https://brew.sh/) on Mac OS.
We emphatically recommend against trying to install GTK, Cairo, Pango or
diff --git a/config.h.cmake.in b/config.h.cmake.in
index 81944a12..2c781b3c 100644
--- a/config.h.cmake.in
+++ b/config.h.cmake.in
@@ -9,3 +9,4 @@
#cmakedefine HAVE_CLOCK_GETTIME
#cmakedefine HAVE_ZMQ
#cmakedefine HAVE_SLURM
+#cmakedefine HAVE_HDF5
diff --git a/config.h.in b/config.h.in
index 858e1d7d..058e5cea 100644
--- a/config.h.in
+++ b/config.h.in
@@ -9,3 +9,4 @@
#mesondefine HAVE_CLOCK_GETTIME
#mesondefine HAVE_ZMQ
#mesondefine HAVE_SLURM
+#mesondefine HAVE_HDF5
diff --git a/libcrystfel/libcrystfel-config.h.cmake.in b/libcrystfel/libcrystfel-config.h.cmake.in
index 31f28ee1..830055cb 100644
--- a/libcrystfel/libcrystfel-config.h.cmake.in
+++ b/libcrystfel/libcrystfel-config.h.cmake.in
@@ -11,6 +11,7 @@
#cmakedefine HAVE_LIBCCP4
#cmakedefine HAVE_MSGPACK
#cmakedefine HAVE_CLOCK_GETTIME
+#cmakedefine HAVE_HDF5
#cmakedefine HAVE_FORKPTY_PTY_H
#cmakedefine HAVE_FORKPTY_UTIL_H
diff --git a/libcrystfel/libcrystfel-config.h.meson.in b/libcrystfel/libcrystfel-config.h.meson.in
index 6796857e..7d43147d 100644
--- a/libcrystfel/libcrystfel-config.h.meson.in
+++ b/libcrystfel/libcrystfel-config.h.meson.in
@@ -9,6 +9,7 @@
#mesondefine HAVE_LIBCCP4
#mesondefine HAVE_MSGPACK
#mesondefine HAVE_CLOCK_GETTIME
+#mesondefine HAVE_HDF5
#mesondefine HAVE_FORKPTY_PTY_H
#mesondefine HAVE_FORKPTY_UTIL_H
diff --git a/libcrystfel/src/image-hdf5.c b/libcrystfel/src/image-hdf5.c
index 702c1392..7023e811 100644
--- a/libcrystfel/src/image-hdf5.c
+++ b/libcrystfel/src/image-hdf5.c
@@ -33,9 +33,11 @@
#include <assert.h>
#include <math.h>
#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_HDF5
#include <hdf5.h>
#include <hdf5_hl.h>
-#include <unistd.h>
+#endif
#include "image.h"
#include "utils.h"
@@ -45,34 +47,6 @@
#include "datatemplate_priv.h"
-static void close_hdf5(hid_t fh)
-{
- int n_ids, i;
- hid_t ids[2048];
-
- n_ids = H5Fget_obj_ids(fh, H5F_OBJ_ALL, 2048, ids);
-
- for ( i=0; i<n_ids; i++ ) {
-
- hid_t id;
- H5I_type_t type;
-
- id = ids[i];
-
- type = H5Iget_type(id);
-
- if ( type == H5I_GROUP ) H5Gclose(id);
- if ( type == H5I_DATASET ) H5Dclose(id);
- if ( type == H5I_DATATYPE ) H5Tclose(id);
- if ( type == H5I_DATASPACE ) H5Sclose(id);
- if ( type == H5I_ATTR ) H5Aclose(id);
-
- }
-
- H5Fclose(fh);
-}
-
-
/* Get the path parts of the event ID
* e.g. ev_orig = abc/def/ghi//5/2/7
* -> [abc, def, ghi], with *pn_plvals=3.
@@ -320,6 +294,8 @@ char *substitute_path(const char *ev, const char *pattern, int skip_ok)
}
+#ifdef HAVE_HDF5
+
static void make_placeholder_skip(signed int *dt_dims,
signed int *panel_dims)
{
@@ -355,6 +331,36 @@ static int total_dimensions(const struct panel_template *p)
}
+static void close_hdf5(hid_t fh)
+{
+ int n_ids, i;
+ hid_t ids[2048];
+
+ n_ids = H5Fget_obj_ids(fh, H5F_OBJ_ALL, 2048, ids);
+
+ for ( i=0; i<n_ids; i++ ) {
+
+ hid_t id;
+ H5I_type_t type;
+
+ id = ids[i];
+
+ type = H5Iget_type(id);
+
+ if ( type == H5I_GROUP ) H5Gclose(id);
+ if ( type == H5I_DATASET ) H5Dclose(id);
+ if ( type == H5I_DATATYPE ) H5Tclose(id);
+ if ( type == H5I_DATASPACE ) H5Sclose(id);
+ if ( type == H5I_ATTR ) H5Aclose(id);
+
+ }
+
+ H5Fclose(fh);
+}
+
+
+
+
static int load_hdf5_hyperslab(struct panel_template *p,
hid_t fh,
const char *event,
@@ -2316,3 +2322,5 @@ int image_hdf5_write(const struct image *image,
free(locations);
return 0;
}
+
+#endif /* HAVE_HDF5 */
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c
index 3a8fb482..e428b606 100644
--- a/libcrystfel/src/image.c
+++ b/libcrystfel/src/image.c
@@ -49,6 +49,13 @@
/** \file image.h */
+#ifndef HAVE_HDF5
+int is_hdf5_file(const char *filename)
+{
+ return 0;
+}
+#endif
+
struct _imagefeaturelist
{
struct imagefeature *features;
@@ -378,7 +385,11 @@ static int read_header_to_cache(struct image *image, const char *from)
return 1;
case DATA_SOURCE_TYPE_HDF5:
+ #ifdef HAVE_HDF5
return image_hdf5_read_header_to_cache(image, from);
+ #else
+ return 1;
+ #endif
case DATA_SOURCE_TYPE_CBF:
case DATA_SOURCE_TYPE_CBFGZ:
@@ -776,7 +787,11 @@ static int image_read_image_data(struct image *image,
return 1;
case DATA_SOURCE_TYPE_HDF5:
+ #ifdef HAVE_HDF5
return image_hdf5_read(image, dtempl);
+ #else
+ return 1;
+ #endif
case DATA_SOURCE_TYPE_CBF:
return image_cbf_read(image, dtempl, 0);
@@ -1008,8 +1023,10 @@ static int load_mask(struct panel_template *p,
unsigned int mask_bad)
{
if ( is_hdf5_file(mask_fn) ) {
+ #ifdef HAVE_HDF5
image_hdf5_read_mask(p, mask_fn, ev, bad, mask_location,
mask_good, mask_bad);
+ #endif
} else if ( is_cbf_file(mask_fn) ) {
image_cbf_read_mask(p, mask_fn, ev, 0, bad,
@@ -1189,9 +1206,11 @@ static int create_satmap(struct image *image,
}
if ( is_hdf5_file(map_fn) ) {
+ #ifdef HAVE_HDF5
image->sat[i] = image_hdf5_read_satmap(p, map_fn,
image->ev,
p->satmap);
+ #endif
} else {
ERROR("Saturation map must be in HDF5 format\n");
@@ -1476,6 +1495,7 @@ ImageFeatureList *image_read_peaks(const DataTemplate *dtempl,
{
if ( is_hdf5_file(filename) ) {
+ #ifdef HAVE_HDF5
enum peak_layout layout;
if ( dtempl->peak_list_type == PEAK_LIST_AUTO ) {
@@ -1516,6 +1536,10 @@ ImageFeatureList *image_read_peaks(const DataTemplate *dtempl,
return NULL;
}
+ #else
+ ERROR("Can't read peak list - compiled without HDF5\n");
+ return NULL;
+ #endif
} else {
ERROR("Peak lists can only be read from HDF5 files\n");
@@ -1528,8 +1552,14 @@ char **image_expand_frames(const DataTemplate *dtempl,
const char *filename, int *n_frames)
{
if ( is_hdf5_file(filename) ) {
+ #ifdef HAVE_HDF5
return image_hdf5_expand_frames(dtempl, filename,
n_frames);
+ #else
+ ERROR("Can't expand frames - compiled without HDF5\n");
+ return NULL;
+ #endif
+
} else {
char **list;
list = malloc(sizeof(char *));
@@ -1580,7 +1610,12 @@ int image_write(const struct image *image,
const char *filename)
{
if ( is_hdf5_file(filename) ) {
+ #ifdef HAVE_HDF5
return image_hdf5_write(image, dtempl, filename);
+ #else
+ ERROR("Can't write image - compiled without HDF5\n");
+ return 1;
+ #endif
}
ERROR("Can only write to HDF5 files.\n");
diff --git a/meson.build b/meson.build
index 9e9a6985..a9848901 100644
--- a/meson.build
+++ b/meson.build
@@ -34,13 +34,14 @@ if slurmdep.found()
endif
# Find HDF5 using inbuilt Meson methods. Requires Meson >= 0.50.0
-hdf5dep = dependency('hdf5', language: 'c', required: true)
-
-# Request HDF5 1.10-style API
-add_project_arguments('-DH5_USE_110_API', language: 'c')
-add_project_arguments('-DH5O_GET_INFO_BY_IDX1', language: 'c')
+hdf5dep = dependency('hdf5', language: 'c', required: get_option('hdf5'))
+if hdf5dep.found()
+ conf_data.set10('HAVE_HDF5', 1)
+ # Request HDF5 1.10-style API
+ add_project_arguments('-DH5_USE_110_API', language: 'c')
+ add_project_arguments('-DH5O_GET_INFO_BY_IDX1', language: 'c')
+endif
-# "Optional" dependencies
fftwdep = dependency('fftw3', required: false)
if fftwdep.found()
conf_data.set10('HAVE_FFTW', 1)
@@ -184,11 +185,13 @@ indexamajig = executable('indexamajig', indexamajig_sources,
install_rpath: '$ORIGIN/../lib64/:$ORIGIN/../lib')
# make_pixelmap
-executable('make_pixelmap',
- ['src/make_pixelmap.c', versionc],
- dependencies: [mdep, libcrystfeldep, hdf5dep],
- install: true,
- install_rpath: '$ORIGIN/../lib64/:$ORIGIN/../lib')
+if hdf5dep.found()
+ executable('make_pixelmap',
+ ['src/make_pixelmap.c', versionc],
+ dependencies: [mdep, libcrystfeldep, hdf5dep],
+ install: true,
+ install_rpath: '$ORIGIN/../lib64/:$ORIGIN/../lib')
+endif
# geoptimiser
# FIXME: restore
@@ -248,20 +251,21 @@ if gtkdep.found()
endif
# pattern_sim
-pattern_sim_sources = ['src/pattern_sim.c', 'src/diffraction.c', versionc]
-if opencldep.found()
- pattern_sim_sources += ['src/diffraction-gpu.c', 'src/cl-utils.c']
+if hdf5dep.found()
+ pattern_sim_sources = ['src/pattern_sim.c', 'src/diffraction.c', versionc]
+ if opencldep.found()
+ pattern_sim_sources += ['src/diffraction-gpu.c', 'src/cl-utils.c']
+ endif
+ executable('pattern_sim', pattern_sim_sources,
+ dependencies: [mdep, libcrystfeldep, gsldep, hdf5dep, opencldep],
+ install: true,
+ install_rpath: '$ORIGIN/../lib64/:$ORIGIN/../lib')
endif
-executable('pattern_sim', pattern_sim_sources,
- dependencies: [mdep, libcrystfeldep, gsldep, hdf5dep, opencldep],
- install: true,
- install_rpath: '$ORIGIN/../lib64/:$ORIGIN/../lib')
# For testing (see tests/meson.build)
simulation_bits = files(['src/diffraction.c',
'src/diffraction-gpu.c',
'src/cl-utils.c'])
-
# ************************ Misc resources ************************
install_data(['data/crystfel.svg'],
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..16439ae3
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1 @@
+option('hdf5', type: 'feature', value: 'enabled')
diff --git a/src/ambigator.c b/src/ambigator.c
index fe4d5fa1..3777cf0a 100644
--- a/src/ambigator.c
+++ b/src/ambigator.c
@@ -43,7 +43,9 @@
#include <gsl/gsl_rng.h>
#include <gsl/gsl_permutation.h>
#include <gsl/gsl_randist.h>
+#ifdef HAVE_HDF5
#include <hdf5.h>
+#endif
#include <image.h>
#include <utils.h>
@@ -909,6 +911,7 @@ static void write_reindexed_stream(const char *infile, const char *outfile,
static void save_corr(const char *filename, struct cc_list *ccs, int n_crystals,
int *assignments)
{
+#ifdef HAVE_HDF5
hid_t fh, fsh, msh, cdh, rdh;
herr_t r;
hsize_t size[2];
@@ -1035,6 +1038,9 @@ static void save_corr(const char *filename, struct cc_list *ccs, int n_crystals,
H5Fclose(fh);
STATUS("Wrote correlation matrix in HDF5 format to %s\n", filename);
+#else
+ ERROR("Can't save correlation matrix - not compiled with HDF5\n");
+#endif
}
diff --git a/tests/meson.build b/tests/meson.build
index 0109ec9d..b3b3cc79 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -24,11 +24,13 @@ endforeach
# Test of waiting for files
-test('file-wait',
- find_program('file-wait'),
- args : [indexamajig.full_path(),
- files('wavelength_geom.h5'),
- files('wavelength_geom1.geom')])
+if hdf5dep.found()
+ test('file-wait',
+ find_program('file-wait'),
+ args : [indexamajig.full_path(),
+ files('wavelength_geom.h5'),
+ files('wavelength_geom1.geom')])
+endif
test('indexamajig-missing-file',
@@ -105,40 +107,44 @@ if opencldep.found()
endif
# Event enumeration tests
-ev_enum_tests = ['ev_enum1',
- 'ev_enum2',
- 'ev_enum3']
+if hdf5dep.found()
+ ev_enum_tests = ['ev_enum1',
+ 'ev_enum2',
+ 'ev_enum3']
+
+ foreach name : ev_enum_tests
+ exe = executable(name, ''.join([name, '.c']),
+ dependencies : [libcrystfeldep, hdf5dep])
+ h5 = files(''.join([name, '.h5']))
+ geom = files(''.join([name, '.geom']))
+ test(name, exe, args : [h5, geom])
+ endforeach
+endif
-foreach name : ev_enum_tests
- exe = executable(name, ''.join([name, '.c']),
+
+# Wavelength tests
+if hdf5dep.found()
+ wavelength_tests = [['wavelength_geom1', '1e-10'],
+ ['wavelength_geom2', '1.3776e-10'],
+ ['wavelength_geom3', '1.3776e-10'],
+ ['wavelength_geom4', '1.9687e-12'],
+ ['wavelength_geom5', '1.9687e-12'],
+ ['wavelength_geom6', '1.3776e-10'],
+ ['wavelength_geom7', '1.3776e-10'],
+ ['wavelength_geom8', '1.9687e-12'],
+ ['wavelength_geom9', '1.3776e-10'],
+ ['wavelength_geom10', '1.3776e-10'],
+ ['wavelength_geom11', '1.125e-10'],
+ ['wavelength_geom12', '1.125e-10']]
+
+ exe = executable('wavelength_geom', 'wavelength_geom.c',
dependencies : [libcrystfeldep, hdf5dep])
- h5 = files(''.join([name, '.h5']))
- geom = files(''.join([name, '.geom']))
- test(name, exe, args : [h5, geom])
-endforeach
+ h5 = files('wavelength_geom.h5')
-# Wavelength tests
-wavelength_tests = [['wavelength_geom1', '1e-10'],
- ['wavelength_geom2', '1.3776e-10'],
- ['wavelength_geom3', '1.3776e-10'],
- ['wavelength_geom4', '1.9687e-12'],
- ['wavelength_geom5', '1.9687e-12'],
- ['wavelength_geom6', '1.3776e-10'],
- ['wavelength_geom7', '1.3776e-10'],
- ['wavelength_geom8', '1.9687e-12'],
- ['wavelength_geom9', '1.3776e-10'],
- ['wavelength_geom10', '1.3776e-10'],
- ['wavelength_geom11', '1.125e-10'],
- ['wavelength_geom12', '1.125e-10']]
-
-exe = executable('wavelength_geom', 'wavelength_geom.c',
- dependencies : [libcrystfeldep, hdf5dep])
-
-h5 = files('wavelength_geom.h5')
-
-foreach p : wavelength_tests
- geom = files(''.join([p[0], '.geom']))
- expected_wl = p[1]
- test(p[0], exe, args : [h5, geom, expected_wl])
-endforeach
+ foreach p : wavelength_tests
+ geom = files(''.join([p[0], '.geom']))
+ expected_wl = p[1]
+ test(p[0], exe, args : [h5, geom, expected_wl])
+ endforeach
+endif