diff options
-rw-r--r-- | doc/man/indexamajig.1 | 2 | ||||
-rw-r--r-- | libcrystfel/src/detector.c | 4 | ||||
-rw-r--r-- | libcrystfel/src/events.c | 34 | ||||
-rw-r--r-- | libcrystfel/src/hdf5-file.c | 280 |
4 files changed, 182 insertions, 138 deletions
diff --git a/doc/man/indexamajig.1 b/doc/man/indexamajig.1 index 2690e039..d7f59f9d 100644 --- a/doc/man/indexamajig.1 +++ b/doc/man/indexamajig.1 @@ -242,7 +242,7 @@ Prefix the filenames from the input file with \fIprefix\fR. If \fB--basename\fR .PD 0 .IP \fB--hdf5-peaks=\fR\fIpath\fR .PD -When using \fB--peaks=hdf5\fR or \fB--peaks=cxi\fR, read the peak positions from location \fIpath\fR. See \fBPEAK DETECTION\fR above. +When using \fB--peaks=hdf5\fR or \fB--peaks=cxi\fR, read the peak positions from location \fIpath\fR. The path can include placeholders, e.g. \fB--hdf5-peaks=/%/peaks\fR. See \fBPEAK DETECTION\fR above. .PD 0 .IP \fB--tolerance=\fR\fItol\fR diff --git a/libcrystfel/src/detector.c b/libcrystfel/src/detector.c index af1a6da8..debb64fb 100644 --- a/libcrystfel/src/detector.c +++ b/libcrystfel/src/detector.c @@ -129,7 +129,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( !isdigit(ch) && (ch != '.') && (ch != 'x') && (ch != 'y') && (ch != '+') && (ch != '-') ) { - ERROR("Invalid character '%C' found.\n", ch); + ERROR("Invalid character '%c' found.\n", ch); return 0; } @@ -174,7 +174,7 @@ static int dir_conv(const char *a, double *sx, double *sy) assert(len != 0); axis = bits[i][len-1]; if ( (axis != 'x') && (axis != 'y') ) { - ERROR("Invalid symbol '%C' - must be x or y.\n", axis); + ERROR("Invalid symbol '%c' - must be x or y.\n", axis); return 1; } diff --git a/libcrystfel/src/events.c b/libcrystfel/src/events.c index 731f39f8..8d059528 100644 --- a/libcrystfel/src/events.c +++ b/libcrystfel/src/events.c @@ -34,6 +34,7 @@ #include <hdf5.h> #include <string.h> #include <stdlib.h> +#include <assert.h> struct event *initialize_event() @@ -555,23 +556,27 @@ int pop_dim_entry_from_event(struct event *ev) } -char *event_path_placeholder_subst(const char *entry, - const char *data) +char *event_path_placeholder_subst(const char *entry, const char *data) { char *ph_loc; char *full_path; - int len_head, len_tail; + ptrdiff_t len_head; + size_t len_entry, len_data; - full_path = malloc((strlen(data) + strlen(entry)+1)*sizeof(char)); - ph_loc = strstr(data, "%"); - len_head = ph_loc-data; - len_tail = strlen(ph_loc); + len_entry = strlen(entry); + len_data = strlen(data); + full_path = malloc(len_data + len_entry + 1); + if ( full_path == NULL ) return NULL; + + ph_loc = strchr(data, '%'); + len_head = ph_loc - data; + assert(len_head >= 0); strncpy(full_path, data, len_head); - strncpy(full_path+len_head, entry, strlen(entry)); - strncpy(full_path+len_head+strlen(entry), ph_loc+1, len_tail); - strncpy(&full_path[strlen(data) + strlen(entry)],"\0",1); + full_path[len_head] = '\0'; + strcat(full_path, entry); + strcat(full_path, ph_loc+1); return full_path; } @@ -586,13 +591,12 @@ char *retrieve_full_path(struct event *ev, const char *data) for ( ei=0; ei<ev->path_length; ei++ ) { - char *tmp_subst_data; - tmp_subst_data = event_path_placeholder_subst(ev->path_entries[ei], - return_value); + char *tmp; + tmp = event_path_placeholder_subst(ev->path_entries[ei], + return_value); free(return_value); - return_value = strdup(tmp_subst_data); - free(tmp_subst_data); + return_value = tmp; } diff --git a/libcrystfel/src/hdf5-file.c b/libcrystfel/src/hdf5-file.c index ee352f03..0fb388b4 100644 --- a/libcrystfel/src/hdf5-file.c +++ b/libcrystfel/src/hdf5-file.c @@ -464,10 +464,17 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) float *buf; herr_t r; int tw; + char *np; - dh = H5Dopen2(f->fh, p, H5P_DEFAULT); + if ( image->event != NULL ) { + np = retrieve_full_path(image->event, p); + } else { + np = strdup(p); + } + + dh = H5Dopen2(f->fh, np, H5P_DEFAULT); if ( dh < 0 ) { - ERROR("Peak list (%s) not found.\n", p); + ERROR("Peak list (%s) not found.\n", np); return 1; } @@ -475,6 +482,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) if ( sh < 0 ) { H5Dclose(dh); ERROR("Couldn't get dataspace for peak list.\n"); + free(np); return 1; } @@ -483,6 +491,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) H5Sget_simple_extent_ndims(sh)); H5Sclose(sh); H5Dclose(dh); + free(np); return 1; } @@ -493,6 +502,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) H5Sclose(sh); H5Dclose(dh); ERROR("Peak list has the wrong dimensions.\n"); + free(np); return 1; } @@ -501,6 +511,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) H5Sclose(sh); H5Dclose(dh); ERROR("Couldn't reserve memory for the peak list.\n"); + free(np); return 1; } r = H5Dread(dh, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, @@ -508,6 +519,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) if ( r < 0 ) { ERROR("Couldn't read peak list.\n"); free(buf); + free(np); return 1; } @@ -539,6 +551,7 @@ int get_peaks(struct image *image, struct hdfile *f, const char *p) } free(buf); + free(np); H5Sclose(sh); H5Dclose(dh); @@ -2434,17 +2447,15 @@ int check_path_existence(hid_t fh, const char *path) static herr_t parse_file_event_structure(hid_t loc_id, char *name, const H5L_info_t *info, - void *operator_data) + struct parse_params *pp) { - struct parse_params *pp; char *substituted_path; char *ph_loc; char *truncated_path; htri_t check; herr_t herrt_iterate, herrt_info; struct H5O_info_t object_info; - pp = (struct parse_params *)operator_data; if ( !pp->top_level ) { @@ -2468,7 +2479,7 @@ static herr_t parse_file_event_structure(hid_t loc_id, char *name, truncated_path = strdup(substituted_path); ph_loc = strstr(substituted_path,"%"); if ( ph_loc != NULL) { - strncpy(&truncated_path[ph_loc-substituted_path],"\0",1); + truncated_path[ph_loc-substituted_path] = '\0'; } herrt_iterate = 0; @@ -2488,8 +2499,9 @@ static herr_t parse_file_event_structure(hid_t loc_id, char *name, return -1; } - if ( pp->curr_event->path_length == pp->path_dim && - object_info.type == H5O_TYPE_DATASET ) { + if ( pp->curr_event->path_length == pp->path_dim + && object_info.type == H5O_TYPE_DATASET ) + { int fail_append; @@ -2528,159 +2540,187 @@ static herr_t parse_file_event_structure(hid_t loc_id, char *name, } -struct event_list *fill_event_list(struct hdfile *hdfile, struct detector *det) +static int fill_paths(struct hdfile *hdfile, struct detector *det, int pi, + struct event_list *master_el) { - int pi; - int evi; - herr_t check; - struct event_list *master_el; - struct event_list *master_el_with_dims; - - master_el = initialize_event_list(); + struct parse_params pparams; + struct event *empty_event; + struct event_list *panel_ev_list; + int ei; + int check; - if ( det->path_dim != 0 ) { + 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; + } - for ( pi=0; pi<det->n_panels; pi++ ) { + pparams.path = det->panels[pi].data; + pparams.hdfile = hdfile; + pparams.path_dim = det->path_dim; + pparams.curr_event = empty_event; + pparams.top_level = 1; + pparams.ev_list = panel_ev_list; - struct parse_params pparams; - struct event *empty_event; - struct event_list *panel_ev_list; - int ei; + check = parse_file_event_structure(hdfile->fh, NULL, NULL, &pparams); + if ( check < 0 ) { + free_event(empty_event); + free_event_list(panel_ev_list); + return 1; + } - empty_event = initialize_event(); - panel_ev_list = initialize_event_list(); + for ( ei=0; ei<panel_ev_list->num_events; ei++ ) { - pparams.path = det->panels[pi].data; - pparams.hdfile = hdfile; - pparams.path_dim = det->path_dim; - pparams.curr_event = empty_event; - pparams.top_level = 1; - pparams.ev_list = panel_ev_list; + int fail_add; - check = parse_file_event_structure(hdfile->fh, NULL, - NULL, - (void *)&pparams); + 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; + } - if ( check < 0 ) { - free_event(empty_event); - free_event_list(panel_ev_list); - return NULL; - } + } - for ( ei=0; ei<panel_ev_list->num_events; ei++ ) { + free_event(empty_event); + free_event_list(panel_ev_list); - int fail_add; + return 0; +} - fail_add = add_non_existing_event_to_event_list( - master_el, - panel_ev_list->events[ei]); - if ( fail_add ) { - free_event(empty_event); - free_event_list(panel_ev_list); - return NULL; - } - } +static int fill_dims(struct hdfile *hdfile, struct panel *p, struct event *ev, + struct event_list *events) +{ + 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; + int global_path_dim = -1; + int mlwd; + struct dim_structure *panel_dim_structure; - free_event(empty_event); - free_event_list(panel_ev_list); - } + /* Get the full path for this panel in this event */ + full_panel_path = retrieve_full_path(ev, p->data); + dh = H5Dopen2(hdfile->fh, full_panel_path, H5P_DEFAULT); + if ( dh < 0 ) { + ERROR("Failed to enumerate events. " + "Check your geometry file.\n"); + return 1; } - if ( det->dim_dim > 0 ) { - - if ( master_el->num_events == 0 ) { + 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; + } - struct event *empty_ev; - empty_ev = initialize_event(); - append_event_to_event_list(master_el, empty_ev); - free(empty_ev); + 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; } + } - master_el_with_dims = initialize_event_list(); + if ( global_path_dim == -1 ) { - for (evi=0; evi<master_el->num_events; evi++ ) { + global_path_dim = panel_path_dim; - int global_path_dim = -1; - int pai; - int mlwd; + } else if ( panel_path_dim != global_path_dim ) { - for ( pai=0; pai<det->n_panels; pai++ ) { + ERROR("Data blocks paths for panels must have the same number" + " of placeholders\n"); + free(size); + free(max_size); + return 1; + } - char *full_panel_path; - hid_t dh; - hid_t sh; - int dims; - hsize_t *size; - hsize_t *max_size; - int hsdi; - int panel_path_dim = 0; - full_panel_path = retrieve_full_path( - master_el->events[evi], - det->panels[pai].data); + for ( mlwd=0; mlwd<global_path_dim; mlwd++ ) { - dh = H5Dopen2(hdfile->fh, full_panel_path, - H5P_DEFAULT); - if ( dh < 0 ) { - ERROR("Failed to enumerate events. " - "Check your geometry file.\n"); - return NULL; - } - sh = H5Dget_space(dh); - dims = H5Sget_simple_extent_ndims(sh); - - size = malloc(dims*sizeof(hsize_t)); - max_size = malloc(dims*sizeof(hsize_t)); - - dims = H5Sget_simple_extent_dims(sh, size, - max_size); - - for ( hsdi=0; - hsdi<det->panels[pai].dim_structure->num_dims; - hsdi++ ) { - if (det->panels[pai].dim_structure->dims[hsdi] == - HYSL_PLACEHOLDER ) { - panel_path_dim = size[hsdi]; - break; - } - } + struct event *mlwd_ev; + mlwd_ev = copy_event(ev); + push_dim_entry_to_event(mlwd_ev, mlwd); + append_event_to_event_list(events, mlwd_ev); + free(mlwd_ev); + } - if ( global_path_dim == -1 ) { + return 0; +} - global_path_dim = panel_path_dim; - } else if ( panel_path_dim != global_path_dim ) { +struct event_list *fill_event_list(struct hdfile *hdfile, struct detector *det) +{ + struct event_list *master_el; - ERROR("Data blocks paths for panels must " - "have the same number of placeholders"); - free(size); - free(max_size); - return NULL; - } + master_el = initialize_event_list(); + if ( master_el == NULL ) { + ERROR("Failed to allocate event list.\n"); + return NULL; + } + /* First expand any placeholders in the HDF5 paths */ + if ( det->path_dim != 0 ) { + int pi; + for ( pi=0; pi<det->n_panels; pi++ ) { + if ( fill_paths(hdfile, det, pi, master_el) ) { + ERROR("Failed to enumerate paths.\n"); + return NULL; } + } + } - for ( mlwd=0; mlwd<global_path_dim; mlwd++ ) { + /* Now enumerate the placeholder dimensions */ + if ( det->dim_dim > 0 ) { - struct event *mlwd_ev; + struct event_list *master_el_with_dims; + int evi; - mlwd_ev = copy_event(master_el->events[evi]); - push_dim_entry_to_event(mlwd_ev, mlwd); - append_event_to_event_list(master_el_with_dims, - mlwd_ev); - free(mlwd_ev); - } + /* If there were no HDF5 path placeholders, add a dummy event */ + if ( master_el->num_events == 0 ) { + struct event *empty_ev; + empty_ev = initialize_event(); + append_event_to_event_list(master_el, empty_ev); + free(empty_ev); + } + + master_el_with_dims = initialize_event_list(); + /* For each event so far, expand the dimensions */ + for ( evi=0; evi<master_el->num_events; evi++ ) { + int pi; + for ( pi=0; pi<det->n_panels; pi++ ) { + if ( fill_dims(hdfile, &det->panels[pi], + master_el->events[evi], + master_el_with_dims) ) + { + ERROR("Failed to enumerate dims.\n"); + return NULL; + } + } } free_event_list(master_el); return master_el_with_dims; - } + } else { - return master_el; + return master_el; + + } } |