diff options
Diffstat (limited to 'libcrystfel/src/events.c')
-rw-r--r-- | libcrystfel/src/events.c | 696 |
1 files changed, 696 insertions, 0 deletions
diff --git a/libcrystfel/src/events.c b/libcrystfel/src/events.c new file mode 100644 index 00000000..87c0530d --- /dev/null +++ b/libcrystfel/src/events.c @@ -0,0 +1,696 @@ +/* + * events.c + * + * Event properties + * + * Copyright © 2012-2014 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2014 Valerio Mariani + * + * 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/>. + * + */ + +#define _ISOC99_SOURCE +#define _GNU_SOURCE + +#include "events.h" + +#include <hdf5.h> +#include <string.h> +#include <stdlib.h> + + +struct event *initialize_event() +{ + + struct event *ev; + + ev = malloc(sizeof(struct event)); + ev->path_entries = NULL; + ev->path_length = 0; + + ev->dim_entries = NULL; + ev->dim_length = 0; + + return ev; + +} + + +struct event_list *initialize_event_list() +{ + + struct event_list *ev_list; + + ev_list = malloc(sizeof(struct event_list)); + + ev_list->events = NULL; + ev_list->num_events = 0; + + return ev_list; + +} + +struct filename_plus_event *initialize_filename_plus_event() +{ + + struct filename_plus_event *fpe; + + fpe = malloc(sizeof(struct filename_plus_event)); + + fpe->filename = NULL; + fpe->ev = NULL; + + return fpe; +} + + +int event_cmp(struct event *ev1, struct event *ev2) +{ + + int pi; + int di; + + if ( ev1->path_length != ev2->path_length || + ev1->dim_length != ev2->dim_length ) { + return 1; + } + + for ( pi=0; pi<ev1->path_length; pi++ ) { + if ( strcmp(ev1->path_entries[pi], ev2->path_entries[pi]) != 0 ) { + return 1; + } + } + + for ( di=0; di<ev1->dim_length; di++ ) { + if ( ev1->path_entries[di] != ev2->path_entries[di] ) { + return 1; + } + } + + return 0; + +} + + +int add_non_existing_event_to_event_list(struct event_list *ev_list, + struct event *ev) +{ + + int evi; + int found = 0; + + for ( evi=0; evi<ev_list->num_events; evi++ ) { + if (event_cmp(ev_list->events[evi], ev) == 0 ) { + found = 1; + break; + } + } + + if ( found == 0) { + return append_event_to_event_list(ev_list, ev); + } + + return 0; +} + + +int append_event_to_event_list(struct event_list *ev_list, struct event *ev) +{ + + struct event **new_el; + + new_el = realloc(ev_list->events, + (1+ev_list->num_events)*sizeof(struct event*)); + if ( new_el == NULL ) { + return 1; + } + ev_list->events = new_el; + ev_list->events[ev_list->num_events] = copy_event(ev); + ev_list->num_events +=1; + + return 0; +} + + +struct event* copy_event(struct event *ev) +{ + + struct event *new_ev; + int pi, di; + + if ( ev->dim_length == 0 && ev->path_length == 0) { + + new_ev = initialize_event(); + + } else { + + new_ev=malloc(sizeof(struct event)); + + new_ev->path_entries = malloc(ev->path_length*sizeof(char *)); + new_ev->path_length = ev->path_length; + + new_ev->dim_entries = malloc(ev->dim_length*sizeof(int *)); + new_ev->dim_length = ev->dim_length; + + for ( pi=0; pi<new_ev->path_length; pi++ ) { + new_ev->path_entries[pi] = strdup(ev->path_entries[pi]); + } + + for ( di=0; di<new_ev->dim_length; di++ ) { + new_ev->dim_entries[di] = ev->dim_entries[di]; + } + + } + return new_ev; +} + + +extern struct event_list *copy_event_list(struct event_list *el) +{ + int ei; + struct event_list *el_copy; + struct event ** events_copy; + + el_copy = malloc(1); + if ( el_copy == NULL ) { + return NULL; + } + + events_copy = malloc(el->num_events); + if ( events_copy == NULL ) { + free (el_copy); + return NULL; + } + el_copy->events = events_copy; + + for ( ei=0; ei<el->num_events; ei++ ) { + el_copy->events[ei]=copy_event(el->events[ei]); + } + + el_copy->num_events = el->num_events; + + return el_copy; +} + + + +void free_event(struct event *ev) +{ + int pi; + + if ( ev->path_length != 0 ) { + for ( pi=0; pi<ev->path_length; pi++ ) { + free(ev->path_entries[pi]); + } + } + free(ev->dim_entries); + free(ev); +} + + +void free_event_list(struct event_list *el) +{ + int ei; + + for ( ei=0; ei<el->num_events; ei++ ) { + free_event(el->events[ei]); + } + free(el); +} + + +void free_filename_plus_event(struct filename_plus_event *fpe) +{ + + free(fpe->filename); + + if ( fpe->ev != NULL ) { + free_event(fpe->ev); + } +} + + +char *get_event_string(struct event *ev) +{ + char *ret_string; + char *new_ret_string; + int ret_string_len; + + if ( ev->path_length != 0) { + + int pi; + + ret_string = strdup(ev->path_entries[0]); + ret_string_len = strlen(ret_string); + + for ( pi=1; pi<ev->path_length; pi++ ) { + + new_ret_string = realloc(ret_string, + (ret_string_len+1+strlen(ev->path_entries[pi])) + *sizeof(char)); + if ( new_ret_string == NULL ) { + return NULL; + } + + ret_string=new_ret_string; + strncpy(&ret_string[ret_string_len],"/", 1); + strncpy(&ret_string[ret_string_len+1],ev->path_entries[pi], + strlen(ev->path_entries[pi])); + + ret_string_len += 1+strlen(ev->path_entries[pi]); + + } + + new_ret_string = realloc(ret_string, + (1+ret_string_len)*sizeof(char)); + if ( new_ret_string == NULL ) { + return NULL; + } + + ret_string = new_ret_string; + + strncpy(&ret_string[ret_string_len], "/", 1); + ret_string_len += 1; + + } else { + + ret_string = strdup("/"); + ret_string_len = strlen(ret_string); + + } + + if ( ev->dim_length !=0 ) { + + char num_buf[64]; + int di; + + for ( di=0; di<ev->dim_length; di++ ) { + sprintf(num_buf, "%i", ev->dim_entries[di]); + + new_ret_string = realloc(ret_string, + (ret_string_len+1+strlen(num_buf)) + *sizeof(char)); + if ( new_ret_string == NULL ) { + return NULL; + } + + ret_string=new_ret_string; + + strncpy(&ret_string[ret_string_len],"/", 1); + strncpy(&ret_string[ret_string_len+1], num_buf, + strlen(num_buf)); + ret_string_len += 1+strlen(num_buf); + + } + + } else { + + new_ret_string = realloc(ret_string, + (1+ret_string_len)*sizeof(char)); + if ( new_ret_string == NULL ) { + return NULL; + } + + ret_string = new_ret_string; + + strncpy(&ret_string[ret_string_len], "/", 1); + ret_string_len += 1; + + } + + new_ret_string = realloc(ret_string, + (1+ret_string_len)*sizeof(char)); + if ( new_ret_string == NULL ) { + return NULL; + } + + ret_string = new_ret_string; + + strncpy(&ret_string[ret_string_len], "\0", 1); + + return ret_string; +} + + +struct event* get_event_from_event_string(char* ev_string) +{ + struct event* ev; + char *ev_sep; + char buf_path[1024]; + char buf_dim[1024]; + char *sep; + char *start; + + ev = initialize_event(); + if ( ev == NULL ) { + return NULL; + } + + ev_sep = strstr(ev_string, "//"); + if ( ev_sep == NULL ) { + return NULL; + } + + strncpy(buf_path, ev_string, ev_sep-ev_string); + buf_path[ev_sep-ev_string] = '\0'; + + strncpy(buf_dim, ev_sep+2, strlen(ev_sep)-2); + buf_dim[strlen(ev_sep)-2] = '\0'; + + if ( strlen(buf_path) !=0 ) { + + do { + + start = buf_path; + + char buf[2014]; + + sep = strstr(start, "/"); + if ( sep != NULL ) { + + strncpy(buf, start, sep-start); + buf[sep-start]='\0'; + push_path_entry_to_event(ev, buf); + start = sep + 1; + + } else { + + sprintf(buf,"%s",start); + push_path_entry_to_event(ev, buf); + + } + } while (sep); + + } + + + if ( strlen(buf_dim) !=0 ) { + + start = buf_dim; + + do { + + char buf[2014]; + int buf_int; + + sep = strstr(start, "/"); + if ( sep != NULL ) { + strncpy(buf, start, sep-start); + buf[sep-start]='\0'; + buf_int = atoi(buf); + push_dim_entry_to_event(ev, buf_int); + start = sep + 1; + + } else { + + sprintf(buf,"%s",start); + buf_int = atoi(buf); + push_dim_entry_to_event(ev, buf_int); + + } + } while (sep); + + } + + + return ev; +} + + +int push_path_entry_to_event(struct event *ev, const char * entry) +{ + char **new_path_entries; + + new_path_entries = realloc(ev->path_entries, + (1+ev->path_length)*sizeof(char *)); + if ( new_path_entries == NULL ) { + return 1; + } + + ev->path_entries = new_path_entries; + ev->path_entries[ev->path_length] = strdup(entry); + ev->path_length += 1; + + return 0; +} + + +int push_dim_entry_to_event(struct event *ev, int entry) +{ + int *new_dim_entries; + + new_dim_entries = realloc(ev->dim_entries, + (1+ev->dim_length)*sizeof(int)); + if ( new_dim_entries == NULL ) { + return 1; + } + + ev->dim_entries = new_dim_entries; + ev->dim_entries[ev->dim_length] = entry; + ev->dim_length += 1; + + return 0; +} + + +int pop_path_entry_from_event(struct event *ev) +{ + char **new_path_entries; + + if ( ev->path_length == 0 ) { + return 1; + } + + free(ev->path_entries[ev->path_length-1]); + + if ( ev->path_length == 1 ) { + ev->path_entries = NULL; + ev->path_length = 0; + return 0; + } + + new_path_entries = realloc(ev->path_entries, + (ev->path_length-1)*sizeof(char *)); + + if ( new_path_entries == NULL) { + return 1; + } + + ev->path_entries = new_path_entries; + ev->path_length = ev->path_length-1; + + return 0; +} + + +int pop_dim_entry_from_event(struct event *ev) +{ + int *new_dim_entries; + + if ( ev->dim_length == 0 ) { + return 1; + } + + if ( ev->dim_length == 1 ) { + ev->dim_entries = NULL; + ev->dim_length = 0; + return 0; + } + + new_dim_entries = realloc(ev->dim_entries, + (ev->dim_length-1)*sizeof(int)); + + if ( new_dim_entries == NULL) { + return 1; + } + + ev->dim_entries = new_dim_entries; + ev->dim_length = ev->dim_length-1; + + return 0; +} + + +char *event_path_placeholder_subst(const char * entry, + const char * data) +{ + + char *ph_loc; + char *full_path; + int len_head, len_tail; + + full_path = malloc(strlen(data) + strlen(entry)); + ph_loc = strstr(data, "%"); + len_head = ph_loc-data; + len_tail = strlen(ph_loc); + + 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); + + return full_path; +} + + +char *retrieve_full_path(struct event *ev, const char *data) +{ + + int ei ; + char *return_value; + + return_value = strdup(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); + + free(return_value); + return_value = strdup(tmp_subst_data); + free(tmp_subst_data); + + } + + return return_value; + +} + + +extern char *partial_event_substitution(struct event *ev, const char *data) +{ + int ei ; + char *return_value; + char *pholder; + + return_value = strdup(data); + pholder = strstr(return_value,"%"); + ei = 0; + + while( pholder != NULL) { + + char *tmp_subst_data; + + tmp_subst_data = event_path_placeholder_subst(ev->path_entries[ei], + return_value); + free(return_value); + return_value = strdup(tmp_subst_data); + free(tmp_subst_data); + pholder = strstr(return_value, "%"); + ei += 1; + } + + return return_value; +} + + +struct dim_structure *initialize_dim_structure() +{ + struct dim_structure *hs; + hs = malloc(sizeof(struct dim_structure)); + if ( hs == NULL ) { + return NULL; + } + + hs->dims = NULL; + hs->num_dims = 0; + + return hs; +} + + +struct dim_structure *default_dim_structure() +{ + struct dim_structure *hsd; + + hsd = initialize_dim_structure(); + + set_dim_structure_entry(hsd, "dim0", "ss"); + set_dim_structure_entry(hsd, "dim1", "fs"); + + return hsd; +} + + +void free_dim_structure(struct dim_structure *hsd) +{ + int di; + + for ( di=0; di<hsd->num_dims; di++ ) { + free (hsd->dims); + free (hsd); + } +} + + +static int parse_dim_structure_val(const char *val) +{ + if ( strcmp(val,"%") == 0 ) { + return HYSL_PLACEHOLDER; + } else if ( strcmp(val,"ss") == 0 ) { + return HYSL_SS; + } else if ( strcmp(val,"fs") == 0 ) { + return HYSL_FS; + } + return atoi(val); + +} + + +int set_dim_structure_entry(struct dim_structure *hsd, const char *string_dim, + const char *val_string) +{ + int dim_entry; + + dim_entry = atoi(string_dim+3)+1; + + if ( dim_entry > hsd->num_dims ) { + + int di; + + int *new_dims = malloc(dim_entry*sizeof(int)); + if ( new_dims == NULL ) { + return 0; + } + + + for ( di=0; di<dim_entry; di++ ) { + new_dims[di] = HYSL_UNDEFINED; + } + + for ( di=0; di<hsd->num_dims; di++ ) { + new_dims[di] = hsd->dims[di]; + } + + new_dims[dim_entry-1] = parse_dim_structure_val(val_string); + if ( hsd->dims == NULL ) { + free (hsd->dims); + } + hsd->dims = new_dims; + hsd->num_dims = dim_entry; + + return 1; + + } + + hsd->dims[dim_entry] = parse_dim_structure_val(val_string); + return 1; +} |