aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcrystfel/src/datatemplate.c254
-rw-r--r--libcrystfel/src/datatemplate_priv.h21
-rw-r--r--libcrystfel/src/image-cbf.c4
-rw-r--r--libcrystfel/src/image-hdf5.c636
-rw-r--r--libcrystfel/src/image-hdf5.h5
-rw-r--r--libcrystfel/src/image.c27
-rw-r--r--src/crystfel_gui.c12
-rw-r--r--src/im-sandbox.c57
-rw-r--r--src/partialator.c2
-rw-r--r--tests/CMakeLists.txt36
-rw-r--r--tests/evparse1.c73
-rw-r--r--tests/evparse2.c65
-rw-r--r--tests/evparse3.c58
-rw-r--r--tests/evparse4.c68
-rw-r--r--tests/evparse5.c64
-rw-r--r--tests/evparse6.c59
-rw-r--r--tests/evparse7.c57
17 files changed, 949 insertions, 549 deletions
diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c
index a34ec6f5..a34832f4 100644
--- a/libcrystfel/src/datatemplate.c
+++ b/libcrystfel/src/datatemplate.c
@@ -60,37 +60,28 @@ struct rgc_definition {
static struct panel_template *new_panel(DataTemplate *det, const char *name)
{
+ struct panel_template *copyme;
struct panel_template *new;
+ copyme = &det->defaults;
+
det->n_panels++;
det->panels = realloc(det->panels,
det->n_panels*sizeof(struct panel_template));
new = &det->panels[det->n_panels-1];
- memcpy(new, &det->defaults, sizeof(struct panel_template));
+ memcpy(new, copyme, sizeof(struct panel_template));
+ /* Set name */
new->name = strdup(name);
/* Copy strings */
- if ( new->cnz_from != NULL ) new->cnz_from = strdup(new->cnz_from);
- if ( new->data != NULL ) new->data = strdup(new->data);
- if ( new->mask != NULL ) new->mask = strdup(new->mask);
-
- /* Create a new copy of the dim_structure if needed */
- if ( new->dim_structure != NULL ) {
-
- struct dim_structure *dim_copy;
- int di;
-
- dim_copy = initialize_dim_structure();
- dim_copy->num_dims = new->dim_structure->num_dims;
- dim_copy->dims = malloc(dim_copy->num_dims*sizeof(int));
- for ( di=0; di<dim_copy->num_dims; di++ ) {
- dim_copy->dims[di] = new->dim_structure->dims[di];
- }
-
- new->dim_structure = dim_copy;
- }
+ new->cnz_from = safe_strdup(copyme->cnz_from);
+ new->data = safe_strdup(copyme->data);
+ new->mask = safe_strdup(copyme->mask);
+ new->mask_file = safe_strdup(copyme->mask_file);
+ new->satmap = safe_strdup(copyme->satmap);
+ new->satmap_file = safe_strdup(copyme->satmap_file);
return new;
}
@@ -447,6 +438,34 @@ static int dir_conv(const char *a, double *sx, double *sy, double *sz)
}
+int set_dim(struct panel_template *panel, int dimension,
+ const char *val)
+{
+ if ( dimension >= MAX_DIMS ) {
+ ERROR("Too many dimensions!\n");
+ return 1;
+ }
+
+ if ( strcmp(val, "fs") == 0 ) {
+ panel->dims[dimension] = DIM_FS;
+ } else if ( strcmp(val, "ss") == 0 ) {
+ panel->dims[dimension] = DIM_SS;
+ } else if ( strcmp(val, "%") == 0 ) {
+ panel->dims[dimension] = DIM_PLACEHOLDER;
+ } else {
+ char *endptr;
+ unsigned long int fix_val = strtoul(val, &endptr, 10);
+ if ( endptr[0] != '\0' ) {
+ ERROR("Invalid dimension value '%s'\n", val);
+ return 1;
+ } else {
+ panel->dims[dimension] = fix_val;
+ }
+ }
+ return 0;
+}
+
+
static int parse_field_for_panel(struct panel_template *panel, const char *key,
const char *val, DataTemplate *det)
{
@@ -534,16 +553,12 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key,
int dim_entry;
char *endptr;
if ( key[3] != '\0' ) {
- if ( panel->dim_structure == NULL ) {
- panel->dim_structure = initialize_dim_structure();
- }
dim_entry = strtoul(key+3, &endptr, 10);
if ( endptr[0] != '\0' ) {
- ERROR("Invalid dimension number %s\n", key+3);
+ ERROR("Invalid dimension number %s\n",
+ key+3);
} else {
- if ( set_dim_structure_entry(panel->dim_structure,
- dim_entry, val) )
- {
+ if ( set_dim(panel, dim_entry, val) ) {
ERROR("Failed to set dim structure entry\n");
}
}
@@ -703,10 +718,6 @@ DataTemplate *data_template_new_from_string(const char *string_in)
int i;
int rgi, rgci;
int reject = 0;
- int path_dim, mask_path_dim;
- int dim_dim;
- int dim_reject = 0;
- int dim_dim_reject = 0;
struct rg_definition **rg_defl = NULL;
struct rgc_definition **rgc_defl = NULL;
int n_rg_definitions = 0;
@@ -726,8 +737,6 @@ DataTemplate *data_template_new_from_string(const char *string_in)
dt->mask_bad = 0;
dt->n_rigid_groups = 0;
dt->rigid_groups = NULL;
- dt->path_dim = 0;
- dt->dim_dim = 0;
dt->n_rg_collections = 0;
dt->rigid_group_collections = NULL;
dt->photon_energy_bandwidth = -1.0;
@@ -763,7 +772,7 @@ DataTemplate *data_template_new_from_string(const char *string_in)
dt->defaults.satmap = NULL;
dt->defaults.satmap_file = NULL;
dt->defaults.data = NULL;
- dt->defaults.dim_structure = NULL;
+ for ( i=0; i<MAX_DIMS; i++ ) dt->defaults.dims[i] = DIM_UNDEFINED;
dt->defaults.name = NULL;
string = strdup(string_in);
@@ -882,151 +891,6 @@ DataTemplate *data_template_new_from_string(const char *string_in)
return NULL;
}
- path_dim = -1;
- dim_reject = 0;
-
- for ( i=0; i<dt->n_panels; i++ ) {
-
- int panel_dim = 0;
- char *next_instance;
-
- next_instance = dt->panels[i].data;
-
- while ( next_instance ) {
- next_instance = strstr(next_instance, "%");
- if ( next_instance != NULL ) {
- next_instance += 1*sizeof(char);
- panel_dim += 1;
- }
- }
-
- if ( path_dim == -1 ) {
- path_dim = panel_dim;
- } else {
- if ( panel_dim != path_dim ) {
- dim_reject = 1;
- }
- }
-
- }
-
- mask_path_dim = -1;
- for ( i=0; i<dt->n_panels; i++ ) {
-
- int panel_mask_dim = 0;
- char *next_instance;
-
- if ( dt->panels[i].mask != NULL ) {
-
- next_instance = dt->panels[i].mask;
-
- while ( next_instance ) {
- next_instance = strstr(next_instance, "%");
- if ( next_instance != NULL ) {
- next_instance += 1*sizeof(char);
- panel_mask_dim += 1;
- }
- }
-
- if ( mask_path_dim == -1 ) {
- mask_path_dim = panel_mask_dim;
- } else {
- if ( panel_mask_dim != mask_path_dim ) {
- dim_reject = 1;
- }
- }
-
- }
- }
-
- if ( dim_reject == 1 ) {
- ERROR("All panels' data and mask entries must have the same "
- "number of placeholders\n");
- reject = 1;
- }
-
- if ( mask_path_dim > path_dim ) {
- ERROR("Number of placeholders in mask cannot be larger than "
- "for data\n");
- reject = 1;
- }
-
- dt->path_dim = path_dim;
-
- dim_dim_reject = 0;
- dim_dim = -1;
-
- for ( i=0; i<dt->n_panels; i++ ) {
-
- int di;
- int found_ss = 0;
- int found_fs = 0;
- int panel_dim_dim = 0;
-
- if ( dt->panels[i].dim_structure == NULL ) {
- dt->panels[i].dim_structure = default_dim_structure();
- }
-
- for ( di=0; di<dt->panels[i].dim_structure->num_dims; di++ ) {
-
- if ( dt->panels[i].dim_structure->dims[di] ==
- HYSL_UNDEFINED ) {
- dim_dim_reject = 1;
- ERROR("Dimension %i for panel %s is undefined.\n",
- di, dt->panels[i].name);
- }
- if ( dt->panels[i].dim_structure->dims[di] ==
- HYSL_PLACEHOLDER ) {
- panel_dim_dim += 1;
- }
- if ( dt->panels[i].dim_structure->dims[di] ==
- HYSL_SS ) {
- found_ss += 1;
- }
- if ( dt->panels[i].dim_structure->dims[di] ==
- HYSL_FS ) {
- found_fs += 1;
- }
-
- }
-
- if ( found_ss != 1 ) {
- ERROR("Exactly one slow scan dim coordinate is needed "
- "(found %i for panel %s)\n", found_ss,
- dt->panels[i].name);
- dim_dim_reject = 1;
- }
-
- if ( found_fs != 1 ) {
- ERROR("Exactly one fast scan dim coordinate is needed "
- "(found %i for panel %s)\n", found_fs,
- dt->panels[i].name);
- dim_dim_reject = 1;
- }
-
- if ( panel_dim_dim > 1 ) {
- ERROR("Maximum one placeholder dim coordinate is "
- "allowed (found %i for panel %s)\n",
- panel_dim_dim, dt->panels[i].name);
- dim_dim_reject = 1;
- }
-
- if ( dim_dim == -1 ) {
- dim_dim = panel_dim_dim;
- } else {
- if ( panel_dim_dim != dim_dim ) {
- dim_dim_reject = 1;
- }
- }
-
- }
-
- if ( dim_dim_reject == 1) {
- reject = 1;
- }
-
- dt->dim_dim = dim_dim;
-
for ( i=0; i<dt->n_panels; i++ ) {
struct panel_template *p = &dt->panels[i];
@@ -1241,10 +1105,17 @@ void data_template_free(DataTemplate *dt)
free_all_rigid_group_collections(dt);
for ( i=0; i<dt->n_panels; i++ ) {
+ free(dt->panels[i].name);
+ free(dt->panels[i].mask);
+ free(dt->panels[i].mask_file);
+ free(dt->panels[i].satmap);
+ free(dt->panels[i].satmap_file);
free(dt->panels[i].cnz_from);
- free_dim_structure(dt->panels[i].dim_structure);
}
+ free(dt->wavelength_from);
+ free(dt->peak_list);
+
free(dt->panels);
free(dt->bad);
free(dt);
@@ -1433,6 +1304,17 @@ struct detgeom *data_template_to_detgeom(const DataTemplate *dt)
}
+static int num_placeholders(const struct panel_template *p)
+{
+ int i;
+ int n_pl = 0;
+ for ( i=0; i<MAX_DIMS; i++ ) {
+ if ( p->dims[i] == DIM_PLACEHOLDER ) n_pl++;
+ }
+ return n_pl;
+}
+
+
int data_template_get_slab_extents(const DataTemplate *dt,
int *pw, int *ph)
{
@@ -1452,14 +1334,9 @@ int data_template_get_slab_extents(const DataTemplate *dt,
return 1;
}
- if ( p->dim_structure != NULL ) {
- int j;
- for ( j=0; j<p->dim_structure->num_dims; j++ ) {
- if ( p->dim_structure->dims[j] == HYSL_PLACEHOLDER ) {
- /* Not slabby */
- return 1;
- }
- }
+ if ( num_placeholders(p) > 0 ) {
+ /* Not slabby */
+ return 1;
}
if ( p->orig_max_fs > w ) {
@@ -1468,6 +1345,7 @@ int data_template_get_slab_extents(const DataTemplate *dt,
if ( p->orig_max_ss > h ) {
h = p->orig_max_ss;
}
+
}
/* Inclusive -> exclusive */
diff --git a/libcrystfel/src/datatemplate_priv.h b/libcrystfel/src/datatemplate_priv.h
index 75e9adfe..0cf2f025 100644
--- a/libcrystfel/src/datatemplate_priv.h
+++ b/libcrystfel/src/datatemplate_priv.h
@@ -32,6 +32,12 @@
#ifndef DATATEMPLATE_PRIV_H
#define DATATEMPLATE_PRIV_H
+/* Maximum number of dimensions expected in data files */
+#define MAX_DIMS (16)
+
+/* Maximum number of placeholders expected in path structure */
+#define MAX_PATH_PARTS (16)
+
enum adu_per_unit
{
ADU_PER_PHOTON,
@@ -55,6 +61,12 @@ struct dt_rg_collection
};
+/* Special values for dimension IDs */
+#define DIM_FS (-1)
+#define DIM_SS (-2)
+#define DIM_UNDEFINED (-3)
+#define DIM_PLACEHOLDER (-4)
+
/**
* Represents one panel of a detector
*/
@@ -100,11 +112,11 @@ struct panel_template
/** Treat pixel as unreliable if higher than this */
double max_adu;
- /** Location of data in file */
+ /** Location of data in file (possibly with placeholders) */
char *data;
- /** Dimension structure */
- struct dim_structure *dim_structure;
+ /** Dimensions (see definitions for DIM_FS etc above) */
+ signed int dims[MAX_DIMS];
/** \name Transformation matrix from pixel coordinates to lab frame */
/*@{*/
@@ -177,9 +189,6 @@ struct _datatemplate
struct dt_rg_collection **rigid_group_collections;
int n_rg_collections;
- int path_dim;
- int dim_dim;
-
char *peak_list;
struct panel_template defaults; /* FIXME: Shouldn't be stored */
diff --git a/libcrystfel/src/image-cbf.c b/libcrystfel/src/image-cbf.c
index d2d0eca1..5b27c5a5 100644
--- a/libcrystfel/src/image-cbf.c
+++ b/libcrystfel/src/image-cbf.c
@@ -506,7 +506,7 @@ signed int is_cbf_file(const char *filename)
fh = fopen(filename, "r");
if ( fh == NULL ) return -1;
- if ( fgets(line, 1024, fh) == NULL ) return -1;
+ if ( fgets(line, 1024, fh) == NULL ) return 0;
fclose(fh);
if ( strstr(line, "CBF") == NULL ) {
@@ -524,7 +524,7 @@ signed int is_cbfgz_file(const char *filename)
gzfh = gzopen(filename, "rb");
if ( gzfh == NULL ) return -1;
- if ( gzgets(gzfh, line, 1024) == NULL ) return -1;
+ if ( gzgets(gzfh, line, 1024) == NULL ) return 0;
gzclose(gzfh);
if ( strstr(line, "CBF") == NULL ) {
diff --git a/libcrystfel/src/image-hdf5.c b/libcrystfel/src/image-hdf5.c
index 9a7b17ce..13d0c5ed 100644
--- a/libcrystfel/src/image-hdf5.c
+++ b/libcrystfel/src/image-hdf5.c
@@ -7,7 +7,8 @@
* a research centre of the Helmholtz Association.
*
* Authors:
- * 2020 Thomas White <taw@physics.org>
+ * 2020 Thomas White <taw@physics.org>
+ * 2014-2018 Valerio Mariani
*
* This file is part of CrystFEL.
*
@@ -43,6 +44,246 @@
#include "datatemplate_priv.h"
+/* 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 */
+static char **read_path_parts(const char *ev_orig, int *pn_plvals)
+{
+ char **plvals;
+ char *ev;
+ int n_plvals = 0;
+ char *start;
+
+ plvals = malloc(MAX_PATH_PARTS*sizeof(char *));
+ if ( plvals == NULL ) return NULL;
+
+ if ( ev_orig == NULL ) {
+ /* No ev -> no path parts */
+ *pn_plvals = 0;
+ return plvals;
+ }
+
+ ev = strdup(ev_orig);
+ if ( ev == NULL ) return NULL;
+
+ start = ev;
+ do {
+
+ char *sep;
+
+ sep = strchr(start, '/');
+
+ if ( sep == NULL ) {
+ /* This would be very strange, because it
+ * must at least have // */
+ ERROR("Couldn't read path parts ('%s')\n",
+ start);
+ free(ev);
+ free(plvals);
+ return NULL;
+ }
+
+ /* Remaining string starts with '/' is end condition */
+ if ( sep == start ) break;
+
+ if ( n_plvals == MAX_PATH_PARTS ) {
+ ERROR("Too many path parts: %s\n", ev_orig);
+ free(ev);
+ free(plvals);
+ return NULL;
+ }
+
+ sep[0] = '\0';
+ plvals[n_plvals++] = strdup(start);
+
+ start = sep+1;
+
+ } while ( 1 );
+
+ free(ev);
+ *pn_plvals = n_plvals;
+ return plvals;
+}
+
+
+/* Get the dimension parts of the event ID
+ * e.g. ev_orig = abc/def/ghi//5/2/7
+ * -> [5, 2, 7], with *pn_dvals=3 */
+static int *read_dim_parts(const char *ev_orig, int *pn_dvals)
+
+{
+ char *ev;
+ int n_dvals = 0;
+ int *dvals;
+ char *start;
+ int done;
+
+ /* Valid event ID? (Just the part after //, please) */
+ ev = strstr(ev_orig, "//");
+ if ( ev == NULL ) return NULL;
+
+ dvals = malloc(MAX_DIMS*sizeof(int));
+ if ( dvals == NULL ) return NULL;
+
+ if ( ev[2] == '\0' ) {
+ /* No dimension parts - early bailout */
+ *pn_dvals = 0;
+ return dvals; /* NB Not NULL */
+ }
+
+ ev = strdup(ev+2);
+ if ( ev == NULL ) return NULL;
+
+ start = ev;
+ done = 0;
+ do {
+
+ char *sep = strchr(start, '/');
+
+ if ( sep != NULL ) {
+ sep[0] = '\0';
+ } else {
+ done = 1;
+ }
+
+ if ( n_dvals == MAX_PATH_PARTS ) {
+ ERROR("Too many path parts: %s\n", ev_orig);
+ free(ev);
+ free(dvals);
+ return NULL;
+ }
+
+ if ( start[0] == '\0' ) {
+ ERROR("Missing dimension: %s\n", ev_orig);
+ free(ev);
+ free(dvals);
+ return NULL;
+ }
+
+ dvals[n_dvals++] = atoi(start);
+
+ start = sep+1;
+
+ } while ( !done );
+
+ free(ev);
+ *pn_dvals = n_dvals;
+ return dvals;
+}
+
+
+/* ev = abc/def/ghi//5/2/7
+ * pattern = /data/%/somewhere/%/%/data
+ * output = /data/abc/somewhere/def/ghi/data
+ */
+static char *substitute_path(const char *ev, const char *pattern)
+{
+ char **plvals;
+ int n_plvals;
+ int n_pl_exp;
+ size_t l, total_len;
+ int i;
+ char *subs;
+ const char *start;
+ const char *pl_pos;
+
+ if ( pattern == NULL ) {
+ ERROR("Pattern cannot be NULL\n");
+ return NULL;
+ }
+
+ plvals = read_path_parts(ev, &n_plvals);
+ if ( plvals == NULL ) return NULL;
+
+ l = strlen(pattern);
+ n_pl_exp = 0;
+ for ( i=0; i<l; i++ ) {
+ if ( pattern[i] == '%' ) n_pl_exp++;
+ }
+
+ if ( n_plvals != n_pl_exp ) {
+ ERROR("Wrong number of path placeholders: "
+ "'%s' into '%s'\n", ev, pattern);
+ return NULL;
+ }
+
+ total_len = strlen(pattern) - n_pl_exp;
+ for ( i=0; i<n_plvals; i++ ) {
+ total_len += strlen(plvals[i]);
+ }
+ subs = malloc(total_len+1);
+ if ( subs == NULL ) {
+ free(plvals);
+ return NULL;
+ }
+ subs[0] = '\0';
+
+ pl_pos = strchr(pattern, '%');
+ if ( pl_pos == NULL ) {
+ ERROR("Expected a placeholder char (%): '%s'\n",
+ pattern);
+ return NULL;
+ }
+ strncpy(subs, pattern, pl_pos-pattern);
+
+ start = pl_pos+1;
+ for ( i=0; i<n_plvals; i++ ) {
+
+ /* Add the placeholder's value */
+ strcat(subs, plvals[i]);
+ free(plvals[i]);
+
+ /* Add the chars up to the next placeholder... */
+ pl_pos = strchr(start, '%');
+ if ( pl_pos == NULL ) {
+ /* ... or the end */
+ pl_pos = start+strlen(start);
+ }
+ strncat(subs, start, pl_pos-start);
+ start = pl_pos+1;
+ }
+
+ free(plvals);
+
+ return subs;
+}
+
+
+static void make_placeholder_skip(signed int *dt_dims,
+ signed int *panel_dims)
+{
+ int i;
+ int n_dt = 0;
+ for ( i=0; i<MAX_DIMS; i++ ) {
+ if ( panel_dims[i] != DIM_PLACEHOLDER ) {
+ dt_dims[n_dt++] = panel_dims[i];
+ }
+ }
+}
+
+
+static int num_placeholders(const struct panel_template *p)
+{
+ int i;
+ int n_pl = 0;
+ for ( i=0; i<MAX_DIMS; i++ ) {
+ if ( p->dims[i] == DIM_PLACEHOLDER ) n_pl++;
+ }
+ return n_pl;
+}
+
+
+static int total_dimensions(const struct panel_template *p)
+{
+ int i;
+ int n_dim = 0;
+ for ( i=0; i<MAX_DIMS; i++ ) {
+ if ( p->dims[i] != DIM_UNDEFINED ) n_dim++;
+ }
+ return n_dim;
+}
+
+
static int load_hdf5_hyperslab(struct panel_template *p,
const char *filename,
const char *event,
@@ -51,19 +292,24 @@ static int load_hdf5_hyperslab(struct panel_template *p,
int skip_placeholders_ok,
const char *path_spec)
{
- struct event *ev;
hid_t fh;
+ int total_dt_dims;
+ int plh_dt_dims;
+ int dt_dims[MAX_DIMS];
+ int n_dt_dims;
herr_t r;
hsize_t *f_offset, *f_count;
hid_t dh;
- int hsi;
herr_t check;
hid_t dataspace, memspace;
hsize_t dims[2];
char *panel_full_path;
void *data;
- int ndims, dpos;
- int skip_placeholders = 0;
+ int ndims;
+ int dim;
+ int *dim_vals;
+ int n_dim_vals;
+ int pl_pos;
if ( access(filename, R_OK) == -1 ) {
ERROR("File does not exist or cannot be read: %s\n",
@@ -77,21 +323,18 @@ static int load_hdf5_hyperslab(struct panel_template *p,
return 1;
}
- ev = get_event_from_event_string(event);
- if ( (ev == NULL) && (event != NULL) ) {
- ERROR("Invalid event identifier '%s'\n", event);
- H5Fclose(fh);
+ panel_full_path = substitute_path(event, path_spec);
+ if ( panel_full_path == NULL ) {
+ ERROR("Invalid path substitution: '%s' '%s'\n",
+ event, path_spec);
return 1;
}
- panel_full_path = retrieve_full_path(ev, path_spec);
-
dh = H5Dopen2(fh, panel_full_path, H5P_DEFAULT);
if ( dh < 0 ) {
ERROR("Cannot open data for panel %s (%s)\n",
p->name, panel_full_path);
free(panel_full_path);
- free_event(ev);
H5Fclose(fh);
return 1;
}
@@ -105,72 +348,84 @@ static int load_hdf5_hyperslab(struct panel_template *p,
if ( ndims < 0 ) {
ERROR("Failed to get number of dimensions for panel %s\n",
p->name);
- free_event(ev);
H5Fclose(fh);
return 1;
}
- if ( ndims != p->dim_structure->num_dims ) {
- /* Dimensionality doesn't match */
- int n_nonplaceholder = 0;
- for ( hsi=0; hsi<p->dim_structure->num_dims; hsi++ ) {
- if ( p->dim_structure->dims[hsi] != HYSL_PLACEHOLDER ) {
- n_nonplaceholder++;
- }
- }
-
+ /* Does the array have the expected number of dimensions? */
+ total_dt_dims = total_dimensions(p);
+ plh_dt_dims = num_placeholders(p);
+ if ( ndims != total_dt_dims ) {
/* If the dimensions match after excluding
* placeholders, it's OK - probably a static mask
* in a multi-event file. */
- if ( ndims == n_nonplaceholder ) {
- skip_placeholders = 1;
+ if ( skip_placeholders_ok
+ && (ndims == total_dt_dims - plh_dt_dims) )
+ {
+ make_placeholder_skip(dt_dims, p->dims);
+ n_dt_dims = total_dt_dims - plh_dt_dims;
+ } else {
+ ERROR("Unexpected number of dimensions for "
+ "panel %s (%i, but expected %i or %i)\n",
+ p->name, ndims, total_dt_dims,
+ total_dt_dims - plh_dt_dims);
+ H5Fclose(fh);
+ return 1;
}
+ } else {
+ int i;
+ for ( i=0; i<MAX_DIMS; i++ ) {
+ dt_dims[i] = p->dims[i];
+ }
+ n_dt_dims = total_dt_dims;
}
f_offset = malloc(ndims*sizeof(hsize_t));
f_count = malloc(ndims*sizeof(hsize_t));
if ( (f_offset == NULL) || (f_count == NULL ) ) {
ERROR("Failed to allocate offset or count.\n");
- free_event(ev);
H5Fclose(fh);
return 1;
}
- dpos = 0;
- for ( hsi=0; hsi<p->dim_structure->num_dims; hsi++ ) {
+ /* Get those placeholder values from the event ID */
+ dim_vals = read_dim_parts(event, &n_dim_vals);
+
+ pl_pos = 0;
+ for ( dim=0; dim<n_dt_dims; dim++ ) {
- switch ( p->dim_structure->dims[hsi] ) {
+ switch ( dt_dims[dim] ) {
- case HYSL_FS:
- f_offset[dpos] = p->orig_min_fs;
- f_count[dpos] = p->orig_max_fs - p->orig_min_fs+1;
- dpos++;
+ case DIM_FS:
+ f_offset[dim] = p->orig_min_fs;
+ f_count[dim] = p->orig_max_fs - p->orig_min_fs+1;
break;
- case HYSL_SS:
- f_offset[dpos] = p->orig_min_ss;
- f_count[dpos] = p->orig_max_ss - p->orig_min_ss+1;
- dpos++;
+ case DIM_SS:
+ f_offset[dim] = p->orig_min_ss;
+ f_count[dim] = p->orig_max_ss - p->orig_min_ss+1;
break;
- case HYSL_PLACEHOLDER:
- if ( !skip_placeholders ) {
- f_offset[dpos] = ev->dim_entries[0];
- f_count[dpos] = 1;
- dpos++;
- }
+ case DIM_PLACEHOLDER:
+ f_offset[dim] = dim_vals[pl_pos++];
+ f_count[dim] = 1;
+ break;
+
+ case DIM_UNDEFINED:
+ ERROR("Undefined dimension found!\n");
break;
default:
- f_offset[dpos] = p->dim_structure->dims[hsi];
- f_count[dpos] = 1;
- dpos++;
+ /* Fixed value */
+ f_offset[dim] = dt_dims[dim];
+ f_count[dim] = 1;
break;
}
-
}
+ free(dim_vals);
+
check = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
f_offset, NULL, f_count, NULL);
if ( check < 0 ) {
@@ -178,7 +433,6 @@ static int load_hdf5_hyperslab(struct panel_template *p,
p->name);
free(f_offset);
free(f_count);
- free_event(ev);
H5Fclose(fh);
return 1;
}
@@ -192,7 +446,6 @@ static int load_hdf5_hyperslab(struct panel_template *p,
ERROR("Failed to allocate panel %s\n", p->name);
free(f_offset);
free(f_count);
- free_event(ev);
H5Fclose(fh);
return 1;
}
@@ -205,7 +458,6 @@ static int load_hdf5_hyperslab(struct panel_template *p,
free(f_offset);
free(f_count);
free(data);
- free_event(ev);
H5Fclose(fh);
return 1;
}
@@ -214,7 +466,6 @@ static int load_hdf5_hyperslab(struct panel_template *p,
H5Sclose(dataspace);
free(f_offset);
free(f_count);
- free_event(ev);
H5Fclose(fh);
*pdata = data;
@@ -319,9 +570,10 @@ double image_hdf5_get_value(const char *name, const char *filename,
int ndims;
int i;
char *subst_name = NULL;
- struct event *ev;
hid_t fh;
double val;
+ int *dim_vals;
+ int n_dim_vals;
if ( access(filename, R_OK) == -1 ) {
ERROR("File does not exist or cannot be read: %s\n", filename);
@@ -333,15 +585,14 @@ double image_hdf5_get_value(const char *name, const char *filename,
ERROR("Couldn't open file: %s\n", filename);
return NAN;
}
- ev = get_event_from_event_string(event);
- if ( (ev == NULL) && (event != NULL) ) {
- ERROR("Invalid event identifier '%s'\n", event);
+
+ subst_name = substitute_path(event, name);
+ if ( subst_name == NULL ) {
+ ERROR("Invalid event ID '%s'\n", event);
H5Fclose(fh);
return NAN;
}
- subst_name = retrieve_full_path(ev, name);
-
dh = H5Dopen2(fh, subst_name, H5P_DEFAULT);
if ( dh < 0 ) {
ERROR("No such numeric field '%s'\n", subst_name);
@@ -371,10 +622,19 @@ double image_hdf5_get_value(const char *name, const char *filename,
}
H5Sget_simple_extent_dims(sh, size, NULL);
+ /* We expect a scalar value */
m_offset[0] = 0;
m_count[0] = 1;
msdims[0] = 1;
- ms = H5Screate_simple(1,msdims,NULL);
+ ms = H5Screate_simple(1, msdims, NULL);
+
+ dim_vals = read_dim_parts(event, &n_dim_vals);
+ if ( dim_vals == NULL ) {
+ ERROR("Couldn't parse event '%s'\n");
+ H5Tclose(type);
+ H5Dclose(dh);
+ return NAN;
+ }
/* Check that the size in all dimensions is 1
* or that one of the dimensions has the same
@@ -547,7 +807,7 @@ static int read_peak_count(hid_t fh, char *path, int line,
}
-static float *read_hdf5_data(hid_t fh, char *path, int line)
+static float *read_peak_line(hid_t fh, char *path, int line)
{
hid_t dh, sh, mh;
@@ -654,7 +914,6 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl,
char path_i[1024];
int r;
int pk;
- struct event *ev;
char *subst_name;
int line = 0;
@@ -678,22 +937,7 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl,
return NULL;
}
- ev = get_event_from_event_string(event);
- if ( (ev == NULL) && (event != NULL) ) {
- ERROR("Invalid event identifier '%s'\n", event);
- H5Fclose(fh);
- return NULL;
- }
-
- if ( ev->dim_entries == NULL ) {
- ERROR("CXI format peak list format selected,"
- "but file has no event structure");
- return NULL;
- }
- line = ev->dim_entries[0];
-
- subst_name = retrieve_full_path(ev, dtempl->peak_list);
- free_event(ev);
+ subst_name = substitute_path(event, dtempl->peak_list);
if ( subst_name == NULL ) {
ERROR("Invalid peak path %s\n", subst_name);
H5Fclose(fh);
@@ -708,13 +952,13 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl,
r = read_peak_count(fh, path_n, line, &num_peaks);
if ( r != 0 ) return NULL;
- buf_x = read_hdf5_data(fh, path_x, line);
+ buf_x = read_peak_line(fh, path_x, line);
if ( r != 0 ) return NULL;
- buf_y = read_hdf5_data(fh, path_y, line);
+ buf_y = read_peak_line(fh, path_y, line);
if ( r != 0 ) return NULL;
- buf_i = read_hdf5_data(fh, path_i, line);
+ buf_i = read_peak_line(fh, path_i, line);
if ( r != 0 ) return NULL;
features = image_feature_list_new();
@@ -757,7 +1001,6 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl,
float *buf;
herr_t r;
int tw;
- struct event *ev;
char *subst_name;
ImageFeatureList *features;
double peak_offset = half_pixel_shift ? 0.5 : 0.0;
@@ -774,29 +1017,21 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl,
return NULL;
}
- ev = get_event_from_event_string(event);
- if ( (ev == NULL) && (event != NULL) ) {
- ERROR("Invalid event identifier '%s'\n", event);
- H5Fclose(fh);
- return NULL;
- }
-
- subst_name = retrieve_full_path(ev, dtempl->peak_list);
- free_event(ev);
+ subst_name = substitute_path(event, dtempl->peak_list);
if ( subst_name == NULL ) {
- ERROR("Invalid peak path %s\n", subst_name);
- free_event(ev);
- H5Fclose(fh);
+ ERROR("Invalid peak path: '%s' '%s'\n",
+ event, dtempl->peak_list);
return NULL;
}
dh = H5Dopen2(fh, subst_name, H5P_DEFAULT);
- free(subst_name);
if ( dh < 0 ) {
ERROR("Peak list (%s) not found.\n", subst_name);
+ free(subst_name);
H5Fclose(fh);
return NULL;
}
+ free(subst_name);
sh = H5Dget_space(dh);
if ( sh < 0 ) {
@@ -880,221 +1115,6 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl,
}
-struct parse_params {
- hid_t fh;
- int path_dim;
- const char *path;
- struct event *curr_event;
- struct event_list *ev_list;
- int top_level;
-};
-
-
-static herr_t parse_file_event_structure(hid_t loc_id, char *name,
- const H5L_info_t *info,
- struct parse_params *pp)
-
-{
- char *substituted_path;
- char *ph_loc;
- char *truncated_path;
- herr_t herrt_iterate, herrt_info;
- struct H5O_info_t object_info;
-
- 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) {
- truncated_path[ph_loc-substituted_path] = '\0';
- }
-
- herrt_iterate = 0;
- herrt_info = 0;
-
- herrt_info = H5Oget_info_by_name(pp->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->fh,
- truncated_path, H5_INDEX_NAME,
- H5_ITER_NATIVE, NULL,
- (H5L_iterate_t)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;
-}
-
-
-static int fill_paths(hid_t fh, const DataTemplate *dtempl, int pi,
- struct event_list *master_el)
-{
- struct parse_params pparams;
- struct event *empty_event;
- struct event_list *panel_ev_list;
- int ei;
- int check;
-
- empty_event = initialize_event();
- panel_ev_list = initialize_event_list();
- if ( (empty_event == NULL) || (panel_ev_list == NULL) )
- {
- ERROR("Failed to allocate memory for event list.\n");
- return 1;
- }
-
- pparams.path = dtempl->panels[pi].data;
- pparams.fh = fh;
- pparams.path_dim = dtempl->path_dim;
- pparams.curr_event = empty_event;
- pparams.top_level = 1;
- pparams.ev_list = panel_ev_list;
-
- check = parse_file_event_structure(fh, NULL, NULL, &pparams);
- if ( check < 0 ) {
- free_event(empty_event);
- free_event_list(panel_ev_list);
- return 1;
- }
-
- 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 1;
- }
-
- }
-
- free_event(empty_event);
- free_event_list(panel_ev_list);
-
- return 0;
-}
-
-
-static int check_dims(hid_t fh, struct panel_template *p,
- struct event *ev,
- struct event_list *events, int *global_path_dim)
-{
- 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;
- struct dim_structure *panel_dim_structure;
-
- /* Get the full path for this panel in this event */
- full_panel_path = retrieve_full_path(ev, p->data);
-
- dh = H5Dopen2(fh, full_panel_path, H5P_DEFAULT);
- if ( dh < 0 ) {
- ERROR("Error opening '%s'\n", full_panel_path);
- ERROR("Failed to enumerate events. "
- "Check your geometry file.\n");
- return 1;
- }
-
- sh = H5Dget_space(dh);
- dims = H5Sget_simple_extent_ndims(sh);
- size = malloc(dims*sizeof(hsize_t));
- max_size = malloc(dims*sizeof(hsize_t));
- if ( (size==NULL) || (max_size==NULL) ) {
- ERROR("Failed to allocate memory for dimensions\n");
- return 1;
- }
-
- dims = H5Sget_simple_extent_dims(sh, size, max_size);
-
- panel_dim_structure = p->dim_structure;
- for ( hsdi=0; hsdi<panel_dim_structure->num_dims; hsdi++ ) {
- if ( panel_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("All panels must have the same number of frames\n");
- ERROR("Panel %s has %i frames in one dimension, but the first "
- "panel has %i.\n",
- p->name, panel_path_dim, *global_path_dim);
- free(size);
- free(max_size);
- return 1;
- }
-
- H5Sclose(sh);
- H5Dclose(dh);
-
- return 0;
-}
-
-
struct event_list *image_hdf5_expand_frames(const DataTemplate *dtempl,
const char *filename)
{
@@ -1191,5 +1211,5 @@ struct event_list *image_hdf5_expand_frames(const DataTemplate *dtempl,
int is_hdf5_file(const char *filename)
{
- return H5Fis_hdf5(filename);
+ return (H5Fis_hdf5(filename) > 0);
}
diff --git a/libcrystfel/src/image-hdf5.h b/libcrystfel/src/image-hdf5.h
index 84a53d99..7a32a354 100644
--- a/libcrystfel/src/image-hdf5.h
+++ b/libcrystfel/src/image-hdf5.h
@@ -61,8 +61,9 @@ extern ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl,
const char *event,
int half_pixel_shift);
-extern struct event_list *image_hdf5_expand_frames(const DataTemplate *dtempl,
- const char *filename);
+extern char **image_hdf5_expand_frames(const DataTemplate *dtempl,
+ const char *filename,
+ int *n_frames);
extern int is_hdf5_file(const char *filename);
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c
index 6eb6bb11..20e91e6d 100644
--- a/libcrystfel/src/image.c
+++ b/libcrystfel/src/image.c
@@ -287,12 +287,12 @@ static double get_value(struct image *image, const char *from)
val = strtod(from, &rval);
if ( (*rval == '\0') && (rval != from) ) return val;
- if ( is_hdf5_file(image->filename) > 0 ) {
+ if ( is_hdf5_file(image->filename) ) {
return image_hdf5_get_value(from,
image->filename,
image->ev);
- } else if ( is_cbf_file(image->filename) > 0 ) {
+ } else if ( is_cbf_file(image->filename) ) {
/* FIXME: From headers */
return NAN;
@@ -474,10 +474,10 @@ struct image *image_read(DataTemplate *dtempl, const char *filename,
return NULL;
}
- if ( is_hdf5_file(filename) > 0 ) {
+ if ( is_hdf5_file(filename) ) {
image = image_hdf5_read(dtempl, filename, event);
- } else if ( is_cbf_file(filename) > 0 ) {
+ } else if ( is_cbf_file(filename) ) {
image = image_cbf_read(dtempl, filename, event, 0);
} else if ( is_cbfgz_file(filename) ) {
@@ -545,13 +545,13 @@ struct image *image_read(DataTemplate *dtempl, const char *filename,
} else {
mask_fn = p->mask_file;
}
- if ( is_hdf5_file(mask_fn) > 0 ) {
+ if ( is_hdf5_file(mask_fn) ) {
image_hdf5_read_mask(p, mask_fn, event,
image->bad[i],
dtempl->mask_good,
dtempl->mask_bad);
- } else if ( is_cbf_file(filename) > 0 ) {
+ } else if ( is_cbf_file(filename) ) {
image_cbf_read_mask(p, mask_fn, event,
0, image->bad[i],
dtempl->mask_good,
@@ -645,7 +645,7 @@ ImageFeatureList *image_read_peaks(const DataTemplate *dtempl,
const char *event,
int half_pixel_shift)
{
- if ( is_hdf5_file(filename) > 0 ) {
+ if ( is_hdf5_file(filename) ) {
const char *ext;
ext = filename_extension(filename, NULL);
@@ -669,11 +669,16 @@ ImageFeatureList *image_read_peaks(const DataTemplate *dtempl,
}
-struct event_list *image_expand_frames(const DataTemplate *dtempl,
- const char *filename)
+char **image_expand_frames(const DataTemplate *dtempl,
+ const char *filename, int *n_frames)
{
- /* FIXME: Dispatch to other versions, e.g. CBF files */
- return image_hdf5_expand_frames(dtempl, filename);
+ if ( is_hdf5_file(filename) ) {
+ return image_hdf5_expand_frames(dtempl, filename,
+ n_frames);
+ } else {
+ ERROR("Can only expand HDF5 files\n");
+ return NULL;
+ }
}
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c
index 87f57e7c..77a064f3 100644
--- a/src/crystfel_gui.c
+++ b/src/crystfel_gui.c
@@ -138,19 +138,21 @@ static void add_all_events(struct crystfelproject *proj,
const char *filename,
const DataTemplate *dtempl)
{
- struct event_list *events;
+ char **events;
int i;
+ int n_events;
- events = image_expand_frames(dtempl, filename);
+ events = image_expand_frames(dtempl, filename, &n_events);
if ( events == NULL ) {
ERROR("Couldn't expand event list\n");
return;
}
- for ( i=0; i<events->num_events; i++ ) {
- add_file_to_project(proj, filename,
- get_event_string(events->events[i]));
+ for ( i=0; i<n_events; i++ ) {
+ add_file_to_project(proj, filename, events[i]);
+ free(events[i]);
}
+ free(events);
}
diff --git a/src/im-sandbox.c b/src/im-sandbox.c
index 753ceb82..d03a1f87 100644
--- a/src/im-sandbox.c
+++ b/src/im-sandbox.c
@@ -112,7 +112,8 @@ struct get_pattern_ctx
const DataTemplate *dtempl;
const char *prefix;
char *filename;
- struct event_list *events; /* FIXME: Deprecated */
+ char **events;
+ int n_events;
int event_index;
};
@@ -184,11 +185,12 @@ static void check_hung_workers(struct sandbox *sb)
}
-static char *read_prefixed_filename(struct get_pattern_ctx *gpctx, char **event)
+static char *read_prefixed_filename(struct get_pattern_ctx *gpctx,
+ char **event)
{
char* line;
- if ( event != NULL ) *event = NULL;
+ *event = NULL;
line = malloc(1024);
if ( line == NULL ) return NULL;
@@ -206,20 +208,18 @@ static char *read_prefixed_filename(struct get_pattern_ctx *gpctx, char **event)
} while ( line[0] == '\0' );
- /* Chop off event ID if requested */
- if ( event != NULL ) {
- size_t n = strlen(line);
- while ( line[n] != ' ' && n > 2 ) n--;
- if ( n != 2 ) {
- /* Event descriptor must contain "//".
- * If it doesn't, assume the filename just contains a
- * space. */
- if ( strstr(&line[n], "//") != NULL ) {
- line[n] = '\0';
- *event = strdup(&line[n+1]);
- }
- } /* else no spaces at all */
- }
+ /* Chop off event ID */
+ size_t n = strlen(line);
+ while ( line[n] != ' ' && n > 2 ) n--;
+ if ( n != 2 ) {
+ /* Event descriptor must contain "//".
+ * If it doesn't, assume the filename just contains a
+ * space. */
+ if ( strstr(&line[n], "//") != NULL ) {
+ line[n] = '\0';
+ *event = strdup(&line[n+1]);
+ }
+ } /* else no spaces at all */
if ( gpctx->use_basename ) {
char *tmp;
@@ -256,10 +256,10 @@ static int get_pattern(struct get_pattern_ctx *gpctx,
/* Is an event available already? */
if ( (gpctx->events != NULL)
- && (gpctx->event_index < gpctx->events->num_events) )
+ && (gpctx->event_index < gpctx->n_events) )
{
- *pfilename = strdup(gpctx->filename);
- *pevent = get_event_string(gpctx->events->events[gpctx->event_index++]);
+ *pfilename = gpctx->filename;
+ *pevent = gpctx->events[gpctx->event_index++];
return 1;
}
@@ -272,13 +272,17 @@ static int get_pattern(struct get_pattern_ctx *gpctx,
/* Does the line from the input file contain an event ID?
* If so, just send it straight back. */
if ( evstr != NULL ) {
- *pfilename = strdup(filename);
- *pevent = strdup(evstr);
+ *pfilename = filename;
+ *pevent = evstr;
return 1;
}
- free_event_list(gpctx->events);
- gpctx->events = image_expand_frames(gpctx->dtempl, filename);
+ /* We got a filename, but no event. Attempt to expand... */
+ free(gpctx->events); /* Free the old list.
+ * NB The actual strings were freed
+ * by fill_queue */
+ gpctx->events = image_expand_frames(gpctx->dtempl, filename,
+ &gpctx->n_events);
if ( gpctx->events == NULL ) {
ERROR("Failed to get event list.\n");
return 0;
@@ -289,8 +293,8 @@ static int get_pattern(struct get_pattern_ctx *gpctx,
gpctx->filename = filename;
gpctx->event_index = 0;
- *pfilename = strdup(gpctx->filename);
- *pevent = get_event_string(gpctx->events->events[gpctx->event_index++]);
+ *pfilename = gpctx->filename;
+ *pevent = gpctx->events[gpctx->event_index++];
return 1;
}
@@ -788,6 +792,7 @@ static int fill_queue(struct get_pattern_ctx *gpctx, struct sandbox *sb)
snprintf(sb->shared->queue[sb->shared->n_events++], MAX_EV_LEN,
"%s %s %i", filename, evstr, sb->serial++);
sem_post(sb->queue_sem);
+ free(evstr);
}
return 0;
diff --git a/src/partialator.c b/src/partialator.c
index 11005555..1126095a 100644
--- a/src/partialator.c
+++ b/src/partialator.c
@@ -484,7 +484,7 @@ static struct custom_split *load_custom_split(const char *filename)
ds = bits[2];
} else {
fn = bits[0];
- evs = get_event_string(NULL);
+ evs = strdup("(none)");
ds = bits[1];
}
free(bits);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index f8de368c..78d39115 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -101,3 +101,39 @@ add_test(cellcompare_check cellcompare_check)
add_executable(polarisation_check polarisation_check.c)
target_include_directories(polarisation_check PRIVATE ${COMMON_INCLUDES})
target_link_libraries(polarisation_check ${COMMON_LIBRARIES})
+add_test(polarisation_check polarisation_check)
+
+add_executable(evparse1 evparse1.c)
+target_include_directories(evparse1 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse1 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse1 evparse1)
+
+add_executable(evparse2 evparse2.c)
+target_include_directories(evparse2 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse2 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse2 evparse2)
+
+add_executable(evparse3 evparse3.c)
+target_include_directories(evparse3 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse3 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse3 evparse3)
+
+add_executable(evparse4 evparse4.c)
+target_include_directories(evparse4 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse4 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse4 evparse4)
+
+add_executable(evparse5 evparse5.c)
+target_include_directories(evparse5 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse5 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse5 evparse5)
+
+add_executable(evparse6 evparse6.c)
+target_include_directories(evparse6 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse6 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse6 evparse6)
+
+add_executable(evparse7 evparse7.c)
+target_include_directories(evparse7 PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(evparse7 ${COMMON_LIBRARIES} -lhdf5)
+add_test(evparse7 evparse7)
diff --git a/tests/evparse1.c b/tests/evparse1.c
new file mode 100644
index 00000000..ad037841
--- /dev/null
+++ b/tests/evparse1.c
@@ -0,0 +1,73 @@
+/*
+ * evparse1.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ char **plvals;
+ int n_plvals;
+ int r = 0;
+
+ plvals = read_path_parts("cc/data123/bb//234/59", &n_plvals);
+
+ if ( plvals == NULL ) {
+ printf("read_path_parts failed\n");
+ r++;
+ }
+
+ if ( n_plvals != 3 ) {
+ printf("Wrong number of path parts\n");
+ r++;
+ }
+
+ if ( plvals == NULL ) return r;
+
+ if ( strcmp(plvals[0], "cc") != 0 ) {
+ printf("First path part is wrong\n");
+ r++;
+ }
+ if ( strcmp(plvals[1], "data123") != 0 ) {
+ printf("Second path part is wrong\n");
+ r++;
+ }
+ if ( strcmp(plvals[2], "bb") != 0 ) {
+ printf("Third path part is wrong\n");
+ r++;
+ }
+
+ return r;
+}
diff --git a/tests/evparse2.c b/tests/evparse2.c
new file mode 100644
index 00000000..1499b13b
--- /dev/null
+++ b/tests/evparse2.c
@@ -0,0 +1,65 @@
+/*
+ * evparse2.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ char **plvals;
+ int n_plvals;
+ int r = 0;
+
+ plvals = read_path_parts("bb//234/59", &n_plvals);
+
+ if ( plvals == NULL ) {
+ printf("read_path_parts failed\n");
+ r++;
+ }
+
+ if ( n_plvals != 1 ) {
+ printf("Wrong number of path parts\n");
+ r++;
+ }
+
+ if ( plvals == NULL ) return r;
+
+ if ( strcmp(plvals[0], "bb") != 0 ) {
+ printf("First path part is wrong\n");
+ r++;
+ }
+
+ return r;
+}
diff --git a/tests/evparse3.c b/tests/evparse3.c
new file mode 100644
index 00000000..ef6733d0
--- /dev/null
+++ b/tests/evparse3.c
@@ -0,0 +1,58 @@
+/*
+ * evparse3.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ char **plvals;
+ int n_plvals;
+ int r = 0;
+
+ plvals = read_path_parts("//234/59", &n_plvals);
+
+ if ( plvals == NULL ) {
+ printf("read_path_parts failed\n");
+ r++;
+ }
+
+ if ( n_plvals != 0 ) {
+ printf("Wrong number of path parts\n");
+ r++;
+ }
+
+ return r;
+}
diff --git a/tests/evparse4.c b/tests/evparse4.c
new file mode 100644
index 00000000..ca28fa24
--- /dev/null
+++ b/tests/evparse4.c
@@ -0,0 +1,68 @@
+/*
+ * evparse4.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ int *dvals;
+ int n_dvals = 99;
+ int r = 0;
+
+ dvals = read_dim_parts("cc/data123/bb//234/59", &n_dvals);
+
+ if ( n_dvals != 2 ) {
+ printf("Wrong number of dimension parts\n");
+ r++;
+ }
+
+ if ( dvals == NULL ) {
+ printf("read_dim_parts failed\n");
+ return 1;
+ }
+
+ if ( dvals[0] != 234 ) {
+ printf("First dimension part is wrong\n");
+ r++;
+ }
+ if ( dvals[1] != 59 ) {
+ printf("Second dimension part is wrong "
+ "(%i, should be %i)\n", dvals[1], 59);
+ r++;
+ }
+
+ return r;
+}
diff --git a/tests/evparse5.c b/tests/evparse5.c
new file mode 100644
index 00000000..ed0d9b85
--- /dev/null
+++ b/tests/evparse5.c
@@ -0,0 +1,64 @@
+/*
+ * evparse5.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ int *dvals;
+ int n_dvals = 99;
+ int r = 0;
+
+ dvals = read_dim_parts("cc/data123/bb//59", &n_dvals);
+
+ if ( n_dvals != 1 ) {
+ printf("Wrong number of dimension parts\n");
+ r++;
+ }
+
+ if ( dvals == NULL ) {
+ printf("read_dim_parts failed\n");
+ return 1;
+ }
+
+ if ( dvals[0] != 59 ) {
+ printf("First dimension part is wrong "
+ "(%i, should be %i)\n", dvals[0], 59);
+ r++;
+ }
+
+ return r;
+}
diff --git a/tests/evparse6.c b/tests/evparse6.c
new file mode 100644
index 00000000..235c6204
--- /dev/null
+++ b/tests/evparse6.c
@@ -0,0 +1,59 @@
+/*
+ * evparse6.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ int *dvals;
+ int n_dvals = 99;
+ int r = 0;
+
+ dvals = read_dim_parts("cc/data123/bb//", &n_dvals);
+
+ if ( n_dvals != 0 ) {
+ printf("Wrong number of dimension parts (got %i)\n",
+ n_dvals);
+ r++;
+ }
+
+ if ( dvals == NULL ) {
+ printf("read_dim_parts failed\n");
+ return 1;
+ }
+
+ return r;
+}
diff --git a/tests/evparse7.c b/tests/evparse7.c
new file mode 100644
index 00000000..7e7ff104
--- /dev/null
+++ b/tests/evparse7.c
@@ -0,0 +1,57 @@
+/*
+ * evparse7.c
+ *
+ * Check that event string parsing works
+ *
+ * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2020 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "../libcrystfel/src/image-hdf5.c"
+
+int main(int argc, char *argv[])
+{
+ char *subs;
+
+ subs = substitute_path("cc/data123/bb//234/59",
+ "/data/%/test/%/%");
+
+ if ( subs == NULL ) {
+ printf("substitute_path() failed\n");
+ return 1;
+ }
+
+ if ( strcmp(subs, "/data/cc/test/data123/bb") != 0 ) {
+ printf("Wrong substitution: got '%s'\n", subs);
+ return 1;
+ }
+
+ return 0;
+}