aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src/hdf5-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel/src/hdf5-file.c')
-rw-r--r--libcrystfel/src/hdf5-file.c217
1 files changed, 193 insertions, 24 deletions
diff --git a/libcrystfel/src/hdf5-file.c b/libcrystfel/src/hdf5-file.c
index 6542b360..13339506 100644
--- a/libcrystfel/src/hdf5-file.c
+++ b/libcrystfel/src/hdf5-file.c
@@ -44,6 +44,19 @@
#include "utils.h"
+/**
+ * SECTION:hdf5-file
+ * @short_description: HDF5 file handling
+ * @title: HDF5 file handling
+ * @section_id:
+ * @see_also:
+ * @include: "hdf5-file.h"
+ * @Image:
+ *
+ * Routines for accessing HDF5 files.
+ **/
+
+
struct hdf5_write_location {
const char *location;
@@ -121,8 +134,7 @@ struct hdfile *hdfile_open(const char *filename)
}
-int hdfile_set_image(struct hdfile *f, const char *path,
- struct panel *p)
+int hdfile_set_image(struct hdfile *f, const char *path)
{
f->dh = H5Dopen2(f->fh, path, H5P_DEFAULT);
if ( f->dh < 0 ) {
@@ -320,9 +332,34 @@ static float *read_hdf5_data(struct hdfile *f, char *path, int line)
}
-/* Get peaks from HDF5, in "CXI format" (as in "CXIDB") */
-int get_peaks_cxi(struct image *image, struct hdfile *f, const char *p,
- struct filename_plus_event *fpe)
+/**
+ * get_peaks_cxi_2:
+ * @image: An %image structure
+ * @f: An %hdfile structure
+ * @p: The HDF5 path to the peak data
+ * @fpe: A %filename_plus_event structure specifying the event
+ * @half_pixel_shift: Non-zero if 0.5 should be added to all peak coordinates
+ *
+ * Get peaks from HDF5, in "CXI format" (as in "CXIDB"). The data should be in
+ * a set of arrays under @p. The number of peaks should be in a 1D array at
+ * @p/nPeaks. The fast-scan and slow-scan coordinates should be in 2D arrays at
+ * @p/peakXPosRaw and @p/peakYPosRaw respectively (sorry about the naming). The
+ * first dimension of these arrays should be the event number (as given by
+ * @fpe). The intensities are expected to be at @p/peakTotalIntensity in a
+ * similar 2D array.
+ *
+ * CrystFEL considers all peak locations to be distances from the corner of the
+ * detector panel, in pixel units, consistent with its description of detector
+ * geometry (see 'man crystfel_geometry'). The software which generates the
+ * CXI files, including Cheetah, may instead consider the peak locations to be
+ * pixel indices in the data array. In this case, the peak coordinates should
+ * have 0.5 added to them. This will be done if @half_pixel_shift is non-zero.
+ *
+ * Returns: non-zero on error, zero otherwise.
+ *
+ */
+int get_peaks_cxi_2(struct image *image, struct hdfile *f, const char *p,
+ struct filename_plus_event *fpe, int half_pixel_shift)
{
char path_n[1024];
char path_x[1024];
@@ -338,6 +375,8 @@ int get_peaks_cxi(struct image *image, struct hdfile *f, const char *p,
float *buf_y;
float *buf_i;
+ double peak_offset = half_pixel_shift ? 0.5 : 0.0;
+
if ( (fpe != NULL) && (fpe->ev != NULL)
&& (fpe->ev->dim_entries != NULL) )
{
@@ -375,8 +414,8 @@ int get_peaks_cxi(struct image *image, struct hdfile *f, const char *p,
float fs, ss, val;
struct panel *p;
- fs = buf_x[pk];
- ss = buf_y[pk];
+ fs = buf_x[pk] + peak_offset;
+ ss = buf_y[pk] + peak_offset;
val = buf_i[pk];
p = find_orig_panel(image->det, fs, ss);
@@ -395,7 +434,53 @@ int get_peaks_cxi(struct image *image, struct hdfile *f, const char *p,
}
-int get_peaks(struct image *image, struct hdfile *f, const char *p)
+/**
+ * get_peaks_cxi:
+ * @image: An %image structure
+ * @f: An %hdfile structure
+ * @p: The HDF5 path to the peak data
+ * @fpe: A %filename_plus_event structure specifying the event
+ *
+ * This is a wrapper function to preserve API compatibility with older CrystFEL
+ * versions. Use get_peaks_cxi_2() instead.
+ *
+ * This function is equivalent to get_peaks_cxi_2(@image, @f, @p, @fpe, 1).
+ *
+ * Returns: non-zero on error, zero otherwise.
+ *
+ */
+int get_peaks_cxi(struct image *image, struct hdfile *f, const char *p,
+ struct filename_plus_event *fpe)
+{
+ return get_peaks_cxi_2(image, f, p, fpe, 1);
+}
+
+
+/**
+ * get_peaks_2:
+ * @image: An %image structure
+ * @f: An %hdfile structure
+ * @p: The HDF5 path to the peak data
+ * @half_pixel_shift: Non-zero if 0.5 should be added to all peak coordinates
+ *
+ * Get peaks from HDF5. The peak list should be located at @p in the HDF5 file,
+ * a 2D array where the first dimension equals the number of peaks and second
+ * dimension is three. The first two columns contain the fast scan and slow
+ * scan coordinates, respectively, of the peaks. The third column contains the
+ * intensities.
+ *
+ * CrystFEL considers all peak locations to be distances from the corner of the
+ * detector panel, in pixel units, consistent with its description of detector
+ * geometry (see 'man crystfel_geometry'). The software which generates the
+ * CXI files, including Cheetah, may instead consider the peak locations to be
+ * pixel indices in the data array. In this case, the peak coordinates should
+ * have 0.5 added to them. This will be done if @half_pixel_shift is non-zero.
+ *
+ * Returns: non-zero on error, zero otherwise.
+ *
+ */
+int get_peaks_2(struct image *image, struct hdfile *f, const char *p,
+ int half_pixel_shift)
{
hid_t dh, sh;
hsize_t size[2];
@@ -405,6 +490,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p)
herr_t r;
int tw;
char *np;
+ double peak_offset = half_pixel_shift ? 0.5 : 0.0;
if ( image->event != NULL ) {
np = retrieve_full_path(image->event, p);
@@ -473,8 +559,8 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p)
float fs, ss, val;
struct panel *p;
- fs = buf[tw*i+0];
- ss = buf[tw*i+1];
+ fs = buf[tw*i+0] + peak_offset;
+ ss = buf[tw*i+1] + peak_offset;
val = buf[tw*i+2];
p = find_orig_panel(image->det, fs, ss);
@@ -499,6 +585,26 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p)
}
+/**
+ * get_peaks:
+ * @image: An %image structure
+ * @f: An %hdfile structure
+ * @p: The HDF5 path to the peak data
+ *
+ * This is a wrapper function to preserve API compatibility with older CrystFEL
+ * versions. Use get_peaks_2() instead.
+ *
+ * This function is equivalent to get_peaks_2(@image, @f, @p, 1).
+ *
+ * Returns: non-zero on error, zero otherwise.
+ *
+ */
+int get_peaks(struct image *image, struct hdfile *f, const char *p)
+{
+ return get_peaks_2(image, f, p, 1);
+}
+
+
static void cleanup(hid_t fh)
{
int n_ids, i;
@@ -1127,6 +1233,9 @@ static int get_scalar_value(struct hdfile *f, const char *name, void *val,
return 1;
}
+ H5Tclose(type);
+ H5Dclose(dh);
+
return 0;
}
@@ -1154,7 +1263,7 @@ static int get_ev_based_value(struct hdfile *f, const char *name,
char *subst_name = NULL;
if ( ev->path_length != 0 ) {
- subst_name = partial_event_substitution(ev, name);
+ subst_name = retrieve_full_path(ev, name);
} else {
subst_name = strdup(name);
}
@@ -1284,8 +1393,10 @@ int hdfile_get_value(struct hdfile *f, const char *name,
}
-void fill_in_beam_parameters(struct beam_params *beam, struct hdfile *f,
- struct event *ev, struct image *image)
+static void hdfile_fill_in_beam_parameters(struct beam_params *beam,
+ struct hdfile *f,
+ struct event *ev,
+ struct image *image)
{
double eV;
@@ -1298,8 +1409,8 @@ void fill_in_beam_parameters(struct beam_params *beam, struct hdfile *f,
int r;
- r = hdfile_get_value(f, beam->photon_energy_from, ev, &eV,
- H5T_NATIVE_DOUBLE);
+ r = hdfile_get_value(f, beam->photon_energy_from,
+ ev, &eV, H5T_NATIVE_DOUBLE);
if ( r ) {
ERROR("Failed to read '%s'\n",
beam->photon_energy_from);
@@ -1311,6 +1422,36 @@ void fill_in_beam_parameters(struct beam_params *beam, struct hdfile *f,
}
+static void hdfile_fill_in_clen(struct detector *det, struct hdfile *f,
+ struct event *ev)
+{
+ int i;
+
+ for ( i=0; i<det->n_panels; i++ ) {
+
+ struct panel *p = &det->panels[i];
+
+ if ( p->clen_from != NULL ) {
+
+ double val;
+ int r;
+
+ r = hdfile_get_value(f, p->clen_from, ev, &val,
+ H5T_NATIVE_DOUBLE);
+ if ( r ) {
+ ERROR("Failed to read '%s'\n", p->clen_from);
+ } else {
+ p->clen = val * 1.0e-3;
+ }
+
+ }
+
+ adjust_centering_for_rail(p);
+
+ }
+}
+
+
int hdf5_read(struct hdfile *f, struct image *image, const char *element,
int satcorr)
{
@@ -1326,7 +1467,7 @@ int hdf5_read(struct hdfile *f, struct image *image, const char *element,
if ( element == NULL ) {
fail = hdfile_set_first_image(f, "/");
} else {
- fail = hdfile_set_image(f, element, NULL);
+ fail = hdfile_set_image(f, element);
}
if ( fail ) {
@@ -1375,7 +1516,7 @@ int hdf5_read(struct hdfile *f, struct image *image, const char *element,
if ( image->beam != NULL ) {
- fill_in_beam_parameters(image->beam, f, NULL, image);
+ hdfile_fill_in_beam_parameters(image->beam, f, NULL, image);
if ( image->lambda > 1000 ) {
/* Error message covers a silly value in the beam file
@@ -1634,10 +1775,13 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
if ( !exists ) {
ERROR("Cannot find data for panel %s\n",
p->name);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
- fail = hdfile_set_image(f, panel_full_path, p);
+ fail = hdfile_set_image(f, panel_full_path);
free(panel_full_path);
@@ -1654,9 +1798,12 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
if ( !exists ) {
ERROR("Cannot find data for panel %s\n",
p->name);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
- fail = hdfile_set_image(f, p->data, p);
+ fail = hdfile_set_image(f, p->data);
}
@@ -1664,6 +1811,9 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
if ( fail ) {
ERROR("Couldn't select path for panel %s\n",
p->name);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
@@ -1673,6 +1823,9 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
f_count = malloc(hsd->num_dims*sizeof(hsize_t));
if ( (f_offset == NULL) || (f_count == NULL ) ) {
ERROR("Failed to allocate offset or count.\n");
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
for ( hsi=0; hsi<hsd->num_dims; hsi++ ) {
@@ -1700,6 +1853,9 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
if ( check < 0 ) {
ERROR("Error selecting file dataspace for panel %s\n",
p->name);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
@@ -1713,6 +1869,9 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
ERROR("Failed to allocate panel %s\n", p->name);
free(f_offset);
free(f_count);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
for ( i=0; i<p->w*p->h; i++ ) image->sat[pi][i] = INFINITY;
@@ -1724,6 +1883,13 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
p->name);
free(f_offset);
free(f_count);
+ for ( i=0; i<=pi; i++ ) {
+ free(image->dp[i]);
+ free(image->sat[i]);
+ }
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
return 1;
}
@@ -1740,7 +1906,7 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
if ( load_satmap(f, ev, p, f_offset, f_count, hsd,
image->sat[pi]) )
{
- ERROR("Failed to laod sat map for panel %s\n",
+ ERROR("Failed to load sat map for panel %s\n",
p->name);
}
}
@@ -1753,13 +1919,13 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev,
H5Dclose(f->dh);
f->data_open = 0;
- fill_in_values(image->det, f, ev);
+ hdfile_fill_in_clen(image->det, f, ev);
if ( satcorr ) debodge_saturation(f, image);
if ( image->beam != NULL ) {
- fill_in_beam_parameters(image->beam, f, ev, image);
+ hdfile_fill_in_beam_parameters(image->beam, f, ev, image);
if ( (image->lambda > 1.0) || (image->lambda < 1e-20) ) {
@@ -1966,7 +2132,7 @@ char *hdfile_get_string_value(struct hdfile *f, const char *name,
char *tmp = NULL, *subst_name = NULL;
if (ev != NULL && ev->path_length != 0 ) {
- subst_name = partial_event_substitution(ev, name);
+ subst_name = retrieve_full_path(ev, name);
} else {
subst_name = strdup(name);
}
@@ -2166,7 +2332,7 @@ int hdfile_set_first_image(struct hdfile *f, const char *group)
for ( i=0; i<n; i++ ) {
if ( is_image[i] ) {
- hdfile_set_image(f, names[i], NULL);
+ hdfile_set_image(f, names[i]);
for ( j=0; j<n; j++ ) free(names[j]);
free(is_image);
free(is_group);
@@ -2484,6 +2650,9 @@ static int check_dims(struct hdfile *hdfile, struct panel *p, struct event *ev,
return 1;
}
+ H5Sclose(sh);
+ H5Dclose(dh);
+
return 0;
}