aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src/hdf5-file.c
diff options
context:
space:
mode:
authorValerio Mariani <valerio.mariani@desy.de>2014-05-09 11:02:17 +0200
committerThomas White <taw@physics.org>2014-09-05 18:12:38 +0200
commit45492b842c3af2af542256417a8bab5bbc7bd5f7 (patch)
tree53fc320ad0734940c5a3fe2d075ae7417787432a /libcrystfel/src/hdf5-file.c
parentae9fa9e6bfd1ed98a2b146d2e228c69a9cd651cc (diff)
Multi-event mode
Diffstat (limited to 'libcrystfel/src/hdf5-file.c')
-rw-r--r--libcrystfel/src/hdf5-file.c856
1 files changed, 773 insertions, 83 deletions
diff --git a/libcrystfel/src/hdf5-file.c b/libcrystfel/src/hdf5-file.c
index 297f78ac..df37e77f 100644
--- a/libcrystfel/src/hdf5-file.c
+++ b/libcrystfel/src/hdf5-file.c
@@ -37,6 +37,7 @@
#include <hdf5.h>
#include <assert.h>
+#include "events.h"
#include "image.h"
#include "hdf5-file.h"
#include "utils.h"
@@ -103,9 +104,6 @@ struct hdfile *hdfile_open(const char *filename)
f = malloc(sizeof(struct hdfile));
if ( f == NULL ) return NULL;
- /* Please stop spamming my terminal */
- H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
-
f->fh = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
if ( f->fh < 0 ) {
ERROR("Couldn't open file: %s\n", filename);
@@ -118,11 +116,14 @@ struct hdfile *hdfile_open(const char *filename)
}
-int hdfile_set_image(struct hdfile *f, const char *path)
+int hdfile_set_image(struct hdfile *f, const char *path,
+ struct panel *p)
{
hsize_t size[2];
hsize_t max_size[2];
hid_t sh;
+ int sh_dim;
+ int di;
f->dh = H5Dopen2(f->fh, path, H5P_DEFAULT);
if ( f->dh < 0 ) {
@@ -130,17 +131,47 @@ int hdfile_set_image(struct hdfile *f, const char *path)
return -1;
}
f->data_open = 1;
-
sh = H5Dget_space(f->dh);
- if ( H5Sget_simple_extent_ndims(sh) != 2 ) {
- ERROR("Dataset is not two-dimensional\n");
- return -1;
+ sh_dim = H5Sget_simple_extent_ndims(sh);
+
+ if ( p == NULL ) {
+
+ if ( sh_dim != 2 ) {
+ ERROR("Dataset is not two-dimensional\n");
+ return -1;
+ }
+
+ } else {
+
+ if ( sh_dim != p->dim_structure->num_dims ) {
+ ERROR("Dataset dimensionality does not match geometry file\n");
+ return -1;
+ }
+
}
+
H5Sget_simple_extent_dims(sh, size, max_size);
H5Sclose(sh);
- f->nx = size[0];
- f->ny = size[1];
+ if ( p == NULL ) {
+
+ f->nx = size[0];
+ f->ny = size[1];
+
+ } else {
+
+ for (di=0; di<p->dim_structure->num_dims; di++ ) {
+
+ if (p->dim_structure->dims[di] == HYSL_SS ) {
+ f->ny = size[di];
+ }
+ if (p->dim_structure->dims[di] == HYSL_FS ) {
+ f->nx = size[di];
+ }
+
+ }
+
+ }
return 0;
}
@@ -234,15 +265,17 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p)
static void cleanup(hid_t fh)
{
int n_ids, i;
- hid_t ids[256];
+ hid_t ids[2048];
+
+ n_ids = H5Fget_obj_ids(fh, H5F_OBJ_ALL, 2048, ids);
- n_ids = H5Fget_obj_ids(fh, H5F_OBJ_ALL, 256, 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);
@@ -252,17 +285,21 @@ static void cleanup(hid_t fh)
if ( type == H5I_ATTR ) H5Aclose(id);
}
+
}
void hdfile_close(struct hdfile *f)
{
+
if ( f->data_open ) {
H5Dclose(f->dh);
}
+
cleanup(f->fh);
H5Fclose(f->fh);
+
free(f);
}
@@ -401,8 +438,8 @@ int hdf5_write_image(const char *filename, struct image *image, char *element)
new_panel_idxs = realloc(locations[li].panel_idxs,
(locations[li].n_panels+1)*sizeof(int));
if ( new_panel_idxs == NULL ) {
- ERROR("Error while managing write location list for file: %s\n",
- filename);
+ ERROR("Error while managing write location list for"
+ "file: %s\n", filename);
return 1;
}
locations[li].panel_idxs = new_panel_idxs;
@@ -422,9 +459,11 @@ int hdf5_write_image(const char *filename, struct image *image, char *element)
struct hdf5_write_location * new_locations;
new_locations = realloc(locations,
- (num_locations+1)*sizeof(struct hdf5_write_location));
+ (num_locations+1)*
+ sizeof(struct hdf5_write_location));
if ( new_locations == NULL ) {
- ERROR("Error while managing write location list for file: %s\n",
+ ERROR("Error while managing write location list for "
+ "file: %s\n",
filename);
return 1;
}
@@ -432,8 +471,8 @@ int hdf5_write_image(const char *filename, struct image *image, char *element)
new_location = &locations[num_locations];
new_location = malloc(sizeof(struct hdf5_write_location));
if ( new_location == NULL ) {
- ERROR("Error while managing write location list for file: %s\n",
- filename);
+ ERROR("Error while managing write location list for "
+ "file: %s\n", filename);
return 1;
}
locations[num_locations].max_ss = p.orig_max_ss;
@@ -441,8 +480,8 @@ int hdf5_write_image(const char *filename, struct image *image, char *element)
locations[num_locations].location = p_location;
locations[num_locations].panel_idxs = malloc(sizeof(int));
if ( locations[num_locations].panel_idxs == NULL ) {
- ERROR("Error while managing write location list for file: %s\n",
- filename);
+ ERROR("Error while managing write location list for "
+ "file: %s\n", filename);
return 1;
}
locations[num_locations].panel_idxs[0] = pi;
@@ -845,13 +884,66 @@ static int unpack_panels(struct image *image, struct detector *det)
}
-int hdf5_read(const char *filename, struct image *image, const char* element, int satcorr)
+int hdf5_read(struct hdfile *f, struct image *image,
+ const char* element, int satcorr)
{
- return hdf5_read2(filename, image, element, satcorr, 0);
+ herr_t r;
+ float *buf;
+ int fail;
+
+ if ( element == NULL ) {
+ fail = hdfile_set_first_image(f, "/");
+ } else {
+ fail = hdfile_set_image(f, element, NULL);
+ }
+
+ if ( fail ) {
+ ERROR("Couldn't select path\n");
+ return 1;
+ }
+
+ /* Note the "swap" here, according to section 3.2.5,
+ * "C versus Fortran Dataspaces", of the HDF5 user's guide. */
+ image->width = f->ny;
+ image->height = f->nx;
+
+ buf = malloc(sizeof(float)*f->nx*f->ny);
+
+ r = H5Dread(f->dh, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, buf);
+ if ( r < 0 ) {
+ ERROR("Couldn't read data\n");
+ free(buf);
+ return 1;
+ }
+ image->data = buf;
+
+ if ( satcorr ) debodge_saturation(f, image);
+
+ if ( image->beam != NULL ) {
+
+ fill_in_beam_parameters(image->beam, f, NULL);
+ image->lambda = ph_en_to_lambda(eV_to_J(image->beam->photon_energy));
+
+ if ( (image->beam->photon_energy < 0.0)
+ || (image->lambda > 1000) ) {
+ /* Error message covers a silly value in the beam file
+ * or in the HDF5 file. */
+ ERROR("Nonsensical wavelength (%e m or %e eV) value "
+ "for %s.\n",
+ image->lambda, image->beam->photon_energy,
+ image->filename);
+ return 1;
+ }
+
+ }
+
+ return 0;
}
-int hdf5_read2(const char *filename, struct image *image, const char* element, int satcorr, int override_data_and_mask)
+int hdf5_read2(struct hdfile *f, struct image *image,
+ struct event *ev, int satcorr)
{
herr_t r;
float *buf;
@@ -862,8 +954,7 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
int mask_is_present;
int no_mask_loaded;
int pi;
- hid_t mask_dh = NULL;
- struct hdfile *f;
+ hid_t mask_dh = 0;
if ( image->det == NULL ) {
ERROR("Geometry not available\n");
@@ -898,15 +989,12 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
curr_ss = 0;
no_mask_loaded = 1;
- f = hdfile_open(filename);
- if ( f == NULL ) {
- return 1;
- }
-
for ( pi=0; pi<image->det->n_panels; pi++ ) {
int data_width, data_height;
- hsize_t f_offset[2], f_count[2];
+ hsize_t *f_offset, *f_count;
+ int hsi;
+ struct dim_structure *hsd;
hsize_t m_offset[2], m_count[2];
hsize_t dimsm[2];
herr_t check;
@@ -916,26 +1004,53 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
struct panel *p;
p=&image->det->panels[pi];
- if ( override_data_and_mask ) {
- fail = hdfile_set_image(f, element);
+ if ( ev != NULL ) {
+
+ int exists;
+ char *panel_full_path;
+
+ panel_full_path = retrieve_full_path
+ (ev, p->data);
+
+ exists = check_path_existence(f->fh, panel_full_path);
+ if ( !exists ) {
+ ERROR("Cannot find data for panel %s\n",
+ p->name);
+ return 1;
+ }
+
+ fail = hdfile_set_image(f, panel_full_path, p);
+ free(panel_full_path);
+
} else {
- if ( p->data != NULL ) {
- fail = hdfile_set_image(f, p->data);
- } else if ( element != NULL ) {
- fail = hdfile_set_image(f, element);
+
+ if ( p->data == NULL ) {
+
+ fail = hdfile_set_first_image(f, "/");
+
} else {
- fail = hdfile_set_first_image(f,"/");
+
+ int exists;
+ exists = check_path_existence(f->fh, p->data);
+ if ( !exists ) {
+ ERROR("Cannot find data for panel %s\n",
+ p->name);
+ return 1;
+ }
+ fail = hdfile_set_image(f, p->data, p);
+
}
+
}
if ( fail ) {
ERROR("Couldn't select path for panel %s\n",
p->name);
- hdfile_close(f);
return 1;
}
data_width = f->ny;
data_height = f->nx;
+
if ( (data_width < p->w )
|| (data_height < p->h) )
{
@@ -948,10 +1063,29 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
return 1;
}
- f_offset[0] = p->orig_min_ss;
- f_offset[1] = p->orig_min_fs;
- f_count[0] = p->orig_max_ss - p->orig_min_ss +1;
- f_count[1] = p->orig_max_fs - p->orig_min_fs +1;
+ hsd = image->det->panels[pi].dim_structure;
+
+ f_offset = malloc(hsd->num_dims*sizeof(hsize_t));
+ f_count = malloc(hsd->num_dims*sizeof(hsize_t));
+
+ for ( hsi=0; hsi<hsd->num_dims; hsi++ ) {
+
+ if ( hsd->dims[hsi] == HYSL_FS ) {
+ f_offset[hsi] = p->orig_min_fs;
+ f_count[hsi] = p->orig_max_fs - p->orig_min_fs +1;
+ } else if ( hsd->dims[hsi] == HYSL_SS ) {
+ f_offset[hsi] = p->orig_min_ss;
+ f_count[hsi] = p->orig_max_ss - p->orig_min_ss +1;
+ } else if (hsd->dims[hsi] == HYSL_PLACEHOLDER ) {
+ f_offset[hsi] = ev->dim_entries[0];
+ f_count[hsi] = 1;
+ } else {
+ f_offset[hsi] = hsd->dims[hsi];
+ f_count[hsi] = 1;
+ }
+
+ }
+
dataspace = H5Dget_space(f->dh);
check = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
f_offset, NULL, f_count, NULL);
@@ -959,7 +1093,6 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
ERROR("Error selecting file dataspace for panel %s\n",
p->name);
free(buf);
- hdfile_close(f);
return 1;
}
@@ -976,60 +1109,118 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
ERROR("Error selecting memory dataspace for panel %s\n",
p->name);
free(buf);
- hdfile_close(f);
return 1;
}
+
r = H5Dread(f->dh, H5T_NATIVE_FLOAT, memspace, dataspace,
H5P_DEFAULT, buf);
if ( r < 0 ) {
ERROR("Couldn't read data for panel %s\n",
p->name);
free(buf);
- hdfile_close(f);
return 1;
}
H5Dclose(f->dh);
f->data_open = 0;
H5Sclose(dataspace);
+ H5Sclose(memspace);
if ( p->mask != NULL ) {
- mask_dh = H5Dopen2(f->fh, p->mask, H5P_DEFAULT);
- if ( mask_dh <= 0 ) {
- ERROR("Couldn't open flags for panel %s\n",
- p->name);
- image->flags = NULL;
- } else {
- mask_dataspace = H5Dget_space(mask_dh);
- check = H5Sselect_hyperslab(mask_dataspace, H5S_SELECT_SET,
- f_offset, NULL, f_count, NULL);
- if ( check < 0 ) {
- ERROR("Error selecting mask dataspace for panel %s\n",
+ if ( ev != NULL ) {
+
+ int exists;
+ char *mask_full_path;
+
+ mask_full_path = retrieve_full_path (ev, p->mask);
+
+ exists = check_path_existence(f->fh, mask_full_path);
+ if ( !exists ) {
+ ERROR("Cannot find flags for panel %s\n",
p->name);
+ return 1;
}
- r = H5Dread(mask_dh, H5T_NATIVE_UINT16, memspace, mask_dataspace,
- H5P_DEFAULT, flags);
- if ( r < 0 ) {
- ERROR("Couldn't read flags for panel %s\n",
+
+ mask_dh = H5Dopen2(f->fh, mask_full_path, H5P_DEFAULT);
+
+ if ( mask_dh <= 0 ) {
+ ERROR("Couldn't open flags for panel %s\n",
p->name);
+ image->flags = NULL;
} else {
- no_mask_loaded = 0;
+
+ mask_dataspace = H5Dget_space(mask_dh);
+ check = H5Sselect_hyperslab(mask_dataspace, H5S_SELECT_SET,
+ f_offset, NULL, f_count, NULL);
+ if ( check < 0 ) {
+ ERROR("Error selecting mask dataspace for panel %s\n",
+ p->name);
+ }
+ r = H5Dread(mask_dh, H5T_NATIVE_UINT16, memspace,
+ mask_dataspace, H5P_DEFAULT, flags);
+ if ( r < 0 ) {
+ ERROR("Couldn't read flags for panel %s\n",
+ p->name);
+ } else {
+ no_mask_loaded = 0;
+ }
+
+ H5Sclose(mask_dataspace);
+ H5Dclose(mask_dh);
+
}
- H5Sclose(mask_dataspace);
- H5Dclose(mask_dh);
+ } else {
+
+ int exists;
+ exists = check_path_existence(f->fh, p->mask);
+ if ( !exists ) {
+ ERROR("Cannot find flags for panel %s\n",
+ p->name);
+ return 1;
+ }
+
+ mask_dh = H5Dopen2(f->fh, p->mask, H5P_DEFAULT);
+ if ( mask_dh <= 0 ) {
+ ERROR("Couldn't open flags for panel %s\n",
+ p->name);
+ image->flags = NULL;
+ } else {
+
+ mask_dataspace = H5Dget_space(mask_dh);
+ check = H5Sselect_hyperslab(mask_dataspace, H5S_SELECT_SET,
+ f_offset, NULL, f_count, NULL);
+ if ( check < 0 ) {
+ ERROR("Error selecting mask dataspace for panel %s\n",
+ p->name);
+ }
+ r = H5Dread(mask_dh, H5T_NATIVE_UINT16, memspace,
+ mask_dataspace, H5P_DEFAULT, flags);
+ if ( r < 0 ) {
+ ERROR("Couldn't read flags for panel %s\n",
+ p->name);
+ } else {
+ no_mask_loaded = 0;
+ }
+
+ H5Sclose(mask_dataspace);
+ H5Dclose(mask_dh);
+
+ }
}
}
- H5Sclose(memspace);
-
p->min_fs = m_min_fs;
p->max_fs = m_max_fs;
p->min_ss = curr_ss;
p->max_ss = curr_ss + p->h-1;
curr_ss += p->h;
+
+ free(f_offset);
+ free(f_count);
+
}
image->data = buf;
@@ -1042,13 +1233,14 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
if ( satcorr ) debodge_saturation(f, image);
- fill_in_values(image->det, f);
+ fill_in_values(image->det, f, ev);
unpack_panels(image, image->det);
if ( image->beam != NULL ) {
- fill_in_beam_parameters(image->beam, f);
+ fill_in_beam_parameters(image->beam, f, ev);
+
image->lambda = ph_en_to_lambda(eV_to_J(image->beam->photon_energy));
if ( (image->beam->photon_energy < 0.0)
@@ -1056,16 +1248,15 @@ int hdf5_read2(const char *filename, struct image *image, const char* element, i
/* Error message covers a silly value in the beam file
* or in the HDF5 file. */
ERROR("Nonsensical wavelength (%e m or %e eV) value "
- "for %s.\n",
+ "for file: %s, event: %s.\n",
image->lambda, image->beam->photon_energy,
- image->filename);
+ image->filename, get_event_string(image->event));
hdfile_close(f);
return 1;
}
}
- hdfile_close(f);
return 0;
}
@@ -1099,13 +1290,15 @@ int hdfile_is_scalar(struct hdfile *f, const char *name, int verbose)
hid_t type;
int ndims;
int i;
+ int check;
- dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
- if ( dh < 0 ) {
+ check = check_path_existence(f->fh, name);
+ if ( check == 0 ) {
ERROR("No such field '%s'\n", name);
return 0;
}
+ dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
type = H5Dget_type(dh);
/* Get the dimensionality. We have to cope with scalars expressed as
@@ -1143,6 +1336,8 @@ int hdfile_is_scalar(struct hdfile *f, const char *name, int verbose)
}
+
+
static int get_f_value(struct hdfile *f, const char *name, double *val)
{
hid_t dh;
@@ -1150,15 +1345,18 @@ static int get_f_value(struct hdfile *f, const char *name, double *val)
hid_t class;
herr_t r;
double buf;
+ int check;
if ( !hdfile_is_scalar(f, name, 1) ) return 1;
- dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
- if ( dh < 0 ) {
+ check = check_path_existence(f->fh, name);
+ if ( check == 0 ) {
ERROR("No such field '%s'\n", name);
return 1;
}
+ dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
+
type = H5Dget_type(dh);
class = H5Tget_class(type);
@@ -1183,6 +1381,152 @@ static int get_f_value(struct hdfile *f, const char *name, double *val)
}
+static int get_ev_based_f_value(struct hdfile *f, const char *name,
+ struct event *ev, double *val)
+{
+ hid_t dh;
+ hid_t type;
+ hid_t class;
+ hid_t sh;
+ hid_t ms;
+ hsize_t *f_offset = NULL;
+ hsize_t *f_count = NULL;
+ hsize_t m_offset[1];
+ hsize_t m_count[1];
+ hsize_t msdims[1];
+ hsize_t size[3];
+ herr_t r;
+ herr_t check;
+ double buf;
+ int check_pe;
+ int dim_flag;
+ int ndims;
+ int i;
+ char* subst_name = NULL;
+
+ if ( ev->path_length != 0 ) {
+ subst_name = partial_event_substitution(ev, name);
+ } else {
+ subst_name = strdup(name);
+ }
+
+ check_pe = check_path_existence(f->fh, subst_name);
+ if ( check_pe == 0 ) {
+ ERROR("No such field '%s'\n", subst_name);
+ return 1;
+ }
+
+ dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
+ type = H5Dget_type(dh);
+ class = H5Tget_class(type);
+
+ if ( class != H5T_FLOAT ) {
+ ERROR("Not a floating point value.\n");
+ H5Tclose(type);
+ H5Dclose(dh);
+ return 1;
+ }
+
+ /* Get the dimensionality. We have to cope with scalars expressed as
+ * arrays with all dimensions 1, as well as zero-d arrays. */
+ sh = H5Dget_space(dh);
+ ndims = H5Sget_simple_extent_ndims(sh);
+ if ( ndims > 3 ) {
+ H5Tclose(type);
+ H5Dclose(dh);
+ return 1;
+ }
+ H5Sget_simple_extent_dims(sh, size, NULL);
+
+ m_offset[0] = 0;
+ m_count[0] = 1;
+ msdims[0] = 1;
+ ms = H5Screate_simple(1,msdims,NULL);
+
+ /* Check that the size in all dimensions is 1 */
+ /* or that one of the dimensions has the same */
+ /* size as the hyperplane events */
+
+ dim_flag = 0;
+
+ for ( i=0; i<ndims; i++ ) {
+ if ( size[i] != 1 ) {
+ if ( i == 0 && size[i] > ev->dim_entries[0] ) {
+ dim_flag = 1;
+ } else {
+ H5Tclose(type);
+ H5Dclose(dh);
+ return 1;
+ }
+ }
+ }
+
+ if ( dim_flag == 0 ) {
+
+ r = H5Dread(dh, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, &buf);
+
+ if ( r < 0 ) {
+ ERROR("Couldn't read value.\n");
+ H5Tclose(type);
+ H5Dclose(dh);
+ return 1;
+ }
+
+ } else {
+
+ f_offset = malloc(ndims*sizeof(hsize_t));
+ f_count = malloc(ndims*sizeof(hsize_t));
+
+ for ( i=0; i<ndims; i++ ) {
+
+ if ( i == 0 ) {
+ f_offset[i] = ev->dim_entries[0];
+ f_count[i] = 1;
+ } else {
+ f_offset[i] = 0;
+ f_count[i] = 0;
+ }
+
+ }
+
+ check = H5Sselect_hyperslab(sh, H5S_SELECT_SET,
+ f_offset, NULL, f_count, NULL);
+ if ( check <0 ) {
+ ERROR("Error selecting dataspace for float value");
+ free(f_offset);
+ free(f_count);
+ return 1;
+ }
+
+ ms = H5Screate_simple(1,msdims,NULL);
+ check = H5Sselect_hyperslab(ms, H5S_SELECT_SET,
+ m_offset, NULL, m_count, NULL);
+ if ( check < 0 ) {
+ ERROR("Error selecting memory dataspace for float value");
+ free(f_offset);
+ free(f_count);
+ return 1;
+ }
+
+ r = H5Dread(dh, H5T_NATIVE_DOUBLE, ms, sh,
+ H5P_DEFAULT, &buf);
+ if ( r < 0 ) {
+ ERROR("Couldn't read value.\n");
+ H5Tclose(type);
+ H5Dclose(dh);
+ return 1;
+ }
+
+ }
+
+ free(subst_name);
+ *val = buf;
+
+ return 0;
+}
+
+
static int get_i_value(struct hdfile *f, const char *name, int *val)
{
hid_t dh;
@@ -1190,15 +1534,17 @@ static int get_i_value(struct hdfile *f, const char *name, int *val)
hid_t class;
herr_t r;
int buf;
+ int check;
if ( !hdfile_is_scalar(f, name, 1) ) return 1;
- dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
- if ( dh < 0 ) {
+ check = check_path_existence(f->fh, name);
+ if ( check == 0 ) {
ERROR("No such field '%s'\n", name);
return 1;
}
+ dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
type = H5Dget_type(dh);
class = H5Tget_class(type);
@@ -1230,6 +1576,14 @@ double get_value(struct hdfile *f, const char *name)
return val;
}
+double get_ev_based_value(struct hdfile *f, const char *name,
+ struct event *ev)
+{
+ double val = -1;
+ get_ev_based_f_value(f, name, ev, &val);
+ return val;
+}
+
struct copy_hdf5_field
{
@@ -1306,7 +1660,7 @@ void add_copy_hdf5_field(struct copy_hdf5_field *copyme,
void copy_hdf5_fields(struct hdfile *f, const struct copy_hdf5_field *copyme,
- FILE *fh)
+ FILE *fh, struct event *ev)
{
int i;
@@ -1318,7 +1672,7 @@ void copy_hdf5_fields(struct hdfile *f, const struct copy_hdf5_field *copyme,
char *field;
field = copyme->fields[i];
- val = hdfile_get_string_value(f, field);
+ val = hdfile_get_string_value(f, field, ev);
if ( field[0] == '/' ) {
fprintf(fh, "hdf5%s = %s\n", field, val);
@@ -1332,7 +1686,8 @@ void copy_hdf5_fields(struct hdfile *f, const struct copy_hdf5_field *copyme,
}
-char *hdfile_get_string_value(struct hdfile *f, const char *name)
+char *hdfile_get_string_value(struct hdfile *f, const char *name,
+ struct event* ev)
{
hid_t dh;
hsize_t size;
@@ -1344,7 +1699,6 @@ char *hdfile_get_string_value(struct hdfile *f, const char *name)
dh = H5Dopen2(f->fh, name, H5P_DEFAULT);
if ( dh < 0 ) return NULL;
-
type = H5Dget_type(dh);
class = H5Tget_class(type);
@@ -1376,7 +1730,11 @@ char *hdfile_get_string_value(struct hdfile *f, const char *name)
switch ( class ) {
case H5T_FLOAT :
- if ( get_f_value(f, name, &buf_f) ) goto fail;
+ if ( ev != NULL ) {
+ if ( get_ev_based_f_value(f, name, ev, &buf_f) ) goto fail;
+ } else {
+ if ( get_f_value(f, name, &buf_f) ) goto fail;
+ }
tmp = malloc(256);
snprintf(tmp, 255, "%f", buf_f);
return tmp;
@@ -1461,6 +1819,8 @@ char **hdfile_read_group(struct hdfile *f, int *n, const char *parent,
}
+ H5Gclose(gh);
+
return res;
}
@@ -1478,7 +1838,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]);
+ hdfile_set_image(f, names[i], NULL);
for ( j=0; j<n; j++ ) free(names[j]);
free(is_image);
free(is_group);
@@ -1503,3 +1863,333 @@ int hdfile_set_first_image(struct hdfile *f, const char *group)
return 1;
}
+
+
+struct parse_params {
+ struct hdfile *hdfile;
+ int path_dim;
+ const char *path;
+ struct event *curr_event;
+ struct event_list *ev_list;
+ int top_level;
+};
+
+
+int check_path_existence(hid_t fh, const char *path)
+{
+
+ char buffer[256];
+ char buffer_full_path[2048];
+ herr_t herrt;
+ struct H5O_info_t ob_info;
+ char *path_copy = strdup(path);
+ char *start = path_copy;
+ char *sep = NULL;
+
+ strncpy(buffer, "\0",1);
+ strncpy(buffer_full_path, "\0", 1);
+
+ if ( strcmp(path_copy, "/" ) == 0 ) {
+ return 1;
+ }
+
+ do {
+
+ int check;
+
+ sep = strstr(start, "/");
+
+ if ( sep != NULL ) {
+
+ if ( sep == start ) {
+ start = sep+1;
+ strcat(buffer_full_path, "/");
+ continue;
+ }
+
+ strncpy(buffer, start, sep-start);
+ buffer[sep-start]='\0';
+ strcat(buffer_full_path, buffer);
+
+ check = H5Lexists(fh, buffer_full_path, H5P_DEFAULT);
+ if ( check == 0 ) {
+ return 0;
+ } else {
+ herrt = H5Oget_info_by_name(fh, buffer_full_path,
+ &ob_info, H5P_DEFAULT);
+ if ( herrt < 0 ) {
+ return -1;
+ }
+ if ( ob_info.type != H5O_TYPE_GROUP ) {
+ return 0;
+ }
+
+ start = sep+1;
+ strcat(buffer_full_path, "/");
+
+ }
+
+ } else {
+
+ strncpy(buffer, start, strlen(start)+1);
+ strcat(buffer_full_path, buffer);
+
+ check = H5Lexists(fh, buffer_full_path, H5P_DEFAULT);
+ if ( check == 0 ) {
+ return 0;
+ }
+
+ }
+ } while (sep);
+
+ free(path_copy);
+ return 1;
+
+}
+
+
+static herr_t parse_file_event_structure(hid_t loc_id, char *name,
+ const H5L_info_t *info,
+ void *operator_data)
+
+{
+
+ struct parse_params *pp;
+ char *substituted_path;
+ char *ph_loc;
+ char *truncated_path;
+ htri_t check;
+ herr_t herrt_iterate, herrt_info;
+ struct H5O_info_t object_info;
+ pp = (struct parse_params *)operator_data;
+
+ if ( !pp->top_level ) {
+
+ int fail_push;
+
+ fail_push = push_path_entry_to_event(pp->curr_event, name);
+ if ( fail_push ) {
+ return -1;
+ }
+
+ substituted_path = event_path_placeholder_subst(name, pp->path);
+
+ } else {
+ substituted_path = strdup(pp->path);
+ }
+
+ if ( pp->top_level == 1 ) {
+ pp->top_level = 0;
+ }
+
+ truncated_path = strdup(substituted_path);
+ ph_loc = strstr(substituted_path,"%");
+ if ( ph_loc != NULL) {
+ strncpy(&truncated_path[ph_loc-substituted_path],"\0",1);
+ }
+
+ herrt_iterate = 0;
+ herrt_info = 0;
+
+ check = check_path_existence(pp->hdfile->fh, truncated_path);
+ if ( check == 0 ) {
+ pop_path_entry_from_event(pp->curr_event);
+ return 0;
+ } else {
+
+ herrt_info = H5Oget_info_by_name(pp->hdfile->fh, truncated_path,
+ &object_info, H5P_DEFAULT);
+ if ( herrt_info < 0 ) {
+ free(truncated_path);
+ free(substituted_path);
+ return -1;
+ }
+
+ if ( pp->curr_event->path_length == pp->path_dim &&
+ object_info.type == H5O_TYPE_DATASET ) {
+
+ int fail_append;
+
+ fail_append = append_event_to_event_list(pp->ev_list,
+ pp->curr_event);
+ if ( fail_append ) {
+ free(truncated_path);
+ free(substituted_path);
+ return -1;
+ }
+
+ pop_path_entry_from_event(pp->curr_event);
+ return 0;
+
+ } else {
+
+ pp->path = substituted_path;
+
+ if ( object_info.type == H5O_TYPE_GROUP ) {
+
+ herrt_iterate = H5Literate_by_name(pp->hdfile->fh,
+ truncated_path,
+ H5_INDEX_NAME,
+ H5_ITER_NATIVE, NULL,
+ parse_file_event_structure,
+ (void *) pp, H5P_DEFAULT);
+ }
+ }
+ }
+
+ pop_path_entry_from_event(pp->curr_event);
+
+ free(truncated_path);
+ free(substituted_path);
+
+ return herrt_iterate;
+
+}
+
+
+struct event_list *fill_event_list(struct hdfile* hdfile, struct detector* det)
+{
+ int pi;
+ int evi;
+ herr_t check;
+ struct event_list *master_el;
+ struct event_list *master_el_with_dims;
+
+ master_el = initialize_event_list();
+
+ if ( det->path_dim != 0 ) {
+
+ for ( pi=0; pi<det->n_panels; pi++ ) {
+
+ struct parse_params pparams;
+ struct event *empty_event;
+ struct event_list *panel_ev_list;
+ int ei;
+
+ empty_event = initialize_event();
+ panel_ev_list = initialize_event_list();
+
+ pparams.path = det->panels[pi].data;
+ pparams.hdfile = hdfile;
+ pparams.path_dim = det->path_dim;
+ pparams.curr_event = empty_event;
+ pparams.top_level = 1;
+ pparams.ev_list = panel_ev_list;
+
+ check = parse_file_event_structure(hdfile->fh, NULL,
+ NULL,
+ (void *) &pparams);
+
+ if ( check < 0 ) {
+ free_event(empty_event);
+ free_event_list(panel_ev_list);
+ return NULL;
+ }
+
+ for ( ei=0; ei<panel_ev_list->num_events; ei++ ) {
+
+ int fail_add;
+
+ fail_add = add_non_existing_event_to_event_list(master_el,
+ panel_ev_list->events[ei]);
+ if ( fail_add ) {
+
+ free_event(empty_event);
+ free_event_list(panel_ev_list);
+ return NULL;
+ }
+ }
+
+ free_event(empty_event);
+ free_event_list(panel_ev_list);
+ }
+
+ }
+
+ if ( det->dim_dim > 0 ) {
+
+ if ( master_el->num_events == 0 ) {
+
+ struct event *empty_ev;
+ empty_ev = initialize_event();
+ append_event_to_event_list(master_el, empty_ev);
+ free(empty_ev);
+
+ }
+
+ master_el_with_dims = initialize_event_list();
+
+ for (evi=0; evi<master_el->num_events; evi++ ) {
+
+ int global_path_dim = -1;
+ int pai;
+ int mlwd;
+
+ for ( pai=0; pai<det->n_panels; pai++ ) {
+
+ char *full_panel_path;
+ hid_t dh;
+ hid_t sh;
+ int dims;
+ hsize_t *size;
+ hsize_t *max_size;
+ int hsdi;
+ int panel_path_dim = 0;
+
+ full_panel_path = retrieve_full_path(master_el->events[evi],
+ det->panels[pai].data);
+
+ dh = H5Dopen2(hdfile->fh, full_panel_path, H5P_DEFAULT);
+ sh = H5Dget_space(dh);
+ dims = H5Sget_simple_extent_ndims(sh);
+
+ size = malloc(dims*sizeof(hsize_t));
+ max_size = malloc(dims*sizeof(hsize_t));
+
+ dims = H5Sget_simple_extent_dims(sh, size, max_size);
+
+ for ( hsdi=0; hsdi<det->panels[pai].dim_structure->num_dims;
+ hsdi++ ) {
+ if (det->panels[pai].dim_structure->dims[hsdi] ==
+ HYSL_PLACEHOLDER ) {
+ panel_path_dim = size[hsdi];
+ break;
+ }
+ }
+
+
+ if ( global_path_dim == -1 ) {
+
+ global_path_dim = panel_path_dim;
+
+ } else if ( panel_path_dim != global_path_dim ) {
+
+ ERROR("Data blocks paths for panels must have the same "
+ "number of placeholders");
+ free(size);
+ free(max_size);
+ return NULL;
+ }
+
+ }
+
+ for ( mlwd=0; mlwd<global_path_dim; mlwd++ ) {
+
+ struct event *mlwd_ev;
+
+ mlwd_ev = copy_event(master_el->events[evi]);
+ push_dim_entry_to_event(mlwd_ev, mlwd);
+ append_event_to_event_list(master_el_with_dims,
+ mlwd_ev);
+ free(mlwd_ev);
+ }
+
+ }
+
+ free_event_list(master_el);
+ return master_el_with_dims;
+
+ }
+
+ return master_el;
+}