diff options
-rw-r--r-- | libcrystfel/src/datatemplate.c | 254 | ||||
-rw-r--r-- | libcrystfel/src/datatemplate_priv.h | 21 | ||||
-rw-r--r-- | libcrystfel/src/image-cbf.c | 4 | ||||
-rw-r--r-- | libcrystfel/src/image-hdf5.c | 636 | ||||
-rw-r--r-- | libcrystfel/src/image-hdf5.h | 5 | ||||
-rw-r--r-- | libcrystfel/src/image.c | 27 | ||||
-rw-r--r-- | src/crystfel_gui.c | 12 | ||||
-rw-r--r-- | src/im-sandbox.c | 57 | ||||
-rw-r--r-- | src/partialator.c | 2 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 36 | ||||
-rw-r--r-- | tests/evparse1.c | 73 | ||||
-rw-r--r-- | tests/evparse2.c | 65 | ||||
-rw-r--r-- | tests/evparse3.c | 58 | ||||
-rw-r--r-- | tests/evparse4.c | 68 | ||||
-rw-r--r-- | tests/evparse5.c | 64 | ||||
-rw-r--r-- | tests/evparse6.c | 59 | ||||
-rw-r--r-- | tests/evparse7.c | 57 |
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; +} |