diff options
Diffstat (limited to 'src/gui_project.c')
-rw-r--r-- | src/gui_project.c | 873 |
1 files changed, 873 insertions, 0 deletions
diff --git a/src/gui_project.c b/src/gui_project.c new file mode 100644 index 00000000..0c7d5502 --- /dev/null +++ b/src/gui_project.c @@ -0,0 +1,873 @@ +/* + * gui_project.c + * + * GUI project persistence + * + * 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 <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "gui_project.h" +#include "gui_backend_local.h" +#include "gui_backend_slurm.h" + +static double parse_float(const char *val) +{ + float v; + + if (sscanf(val, "%f", &v) != 1) { + ERROR("Invalid float value '%s'\n", val); + return NAN; + } + + return v; +} + + +static int parse_int(const char *val) +{ + int v; + + if (sscanf(val, "%i", &v) != 1) { + ERROR("Invalid int value '%s'\n", val); + return 0; + } + + return v; +} + + +static const char *str_matchtype(enum match_type_id mt) +{ + switch ( mt ) { + case MATCH_EVERYTHING : return "everything"; + case MATCH_H5 : return "hdf5"; + case MATCH_CHEETAH_LCLS_H5 : return "lcls-cheetah-hdf5"; + case MATCH_CHEETAH_CXI : return "cheetah-cxi"; + case MATCH_CBF : return "cbf"; + case MATCH_CBFGZ : return "cbfgz"; + } + return NULL; +} + + +enum match_type_id decode_matchtype(const char *type_id) +{ + if ( strcmp(type_id, "everything") == 0 ) return MATCH_EVERYTHING; + if ( strcmp(type_id, "hdf5") == 0 ) return MATCH_H5; + if ( strcmp(type_id, "lcls-cheetah-hdf5") == 0 ) return MATCH_CHEETAH_LCLS_H5; + if ( strcmp(type_id, "cheetah-cxi") == 0 ) return MATCH_CHEETAH_CXI; + if ( strcmp(type_id, "cbf") == 0 ) return MATCH_CBF; + if ( strcmp(type_id, "cbfgz") == 0 ) return MATCH_CBFGZ; + ERROR("Unknown match type id '%s'\n", type_id); + return MATCH_EVERYTHING; +} + + +int match_filename(const char *fn, enum match_type_id mt) +{ + const char *ext = NULL; + const char *ext2 = NULL; + + if ( mt == MATCH_EVERYTHING ) return 1; + + ext = filename_extension(fn, &ext2); + if ( ext == NULL ) return 0; + + if ( mt == MATCH_H5 ) return (strcmp(ext, ".h5")==0); + if ( mt == MATCH_CHEETAH_LCLS_H5 ) { + return ((strcmp(ext, ".h5")==0) + && (strncmp(fn, "LCLS", 4)==0)); + } + if ( mt == MATCH_CHEETAH_CXI ) return strcmp(ext, ".cxi")==0; + if ( mt == MATCH_CBF ) return strcmp(ext, ".cbf")==0; + if ( mt == MATCH_CBFGZ ) { + if ( ext2 != NULL ) { + return strcmp(ext2, ".cbf.gz")==0; + } + } + + return 0; +} + + +/* "tols" is in frac (not %) and radians */ +static void parse_tols(const char *text, float *tols) +{ + int r; + + r = sscanf(text, "%f,%f,%f,%f,%f,%f", + &tols[0], &tols[1], &tols[2], + &tols[3], &tols[4], &tols[5]); + + if ( r != 6 ) { + STATUS("Invalid tolerances '%s'\n", text); + } else { + int i; + for ( i=0; i<3; i++ ) tols[i] /= 100.0; + for ( i=3; i<6; i++ ) tols[i] = deg2rad(tols[i]); + } +} + + +static int find_backend(const char *name, struct crystfelproject *proj) +{ + int i; + + for ( i=0; i<proj->n_backends; i++ ) { + if ( strcmp(proj->backends[i].name, name) == 0 ) { + return i; + } + } + + ERROR("Couldn't find backend '%s'\n", name); + return 0; +} + + +static void handle_var(const char *key, const char *val, + struct crystfelproject *proj) +{ + if ( strcmp(key, "peak_search_params.method") == 0 ) { + proj->peak_search_params.method = parse_peaksearch(val); + if ( proj->peak_search_params.method == PEAK_ERROR ) { + ERROR("Unrecognised peak search method '%s'\n", + val); + } + } + + if ( strcmp(key, "peak_search_params.threshold") == 0 ) { + proj->peak_search_params.threshold = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.min_sq_gradient") == 0 ) { + proj->peak_search_params.min_sq_gradient = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.min_snr") == 0 ) { + proj->peak_search_params.min_snr = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.local_bg_radius") == 0 ) { + proj->peak_search_params.local_bg_radius = parse_int(val); + } + + if ( strcmp(key, "peak_search_params.min_res") == 0 ) { + proj->peak_search_params.min_res = parse_int(val); + } + + if ( strcmp(key, "peak_search_params.min_sig") == 0 ) { + proj->peak_search_params.min_sig = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.max_res") == 0 ) { + proj->peak_search_params.max_res = parse_int(val); + } + + if ( strcmp(key, "peak_search_params.min_pix_count") == 0 ) { + proj->peak_search_params.min_pix_count = parse_int(val); + } + + if ( strcmp(key, "peak_search_params.max_pix_count") == 0 ) { + proj->peak_search_params.max_pix_count = parse_int(val); + } + + if ( strcmp(key, "peak_search_params.min_peak_over_neighbour") == 0 ) { + proj->peak_search_params.min_peak_over_neighbour = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.pk_inn") == 0 ) { + proj->peak_search_params.pk_inn = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.pk_mid") == 0 ) { + proj->peak_search_params.pk_mid = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.pk_out") == 0 ) { + proj->peak_search_params.pk_out = parse_float(val); + } + + if ( strcmp(key, "peak_search_params.half_pixel_shift") == 0 ) { + proj->peak_search_params.half_pixel_shift = parse_int(val); + } + + if ( strcmp(key, "peak_search_params.revalidate") == 0 ) { + proj->peak_search_params.revalidate = parse_int(val); + } + + if ( strcmp(key, "indexing.cell_file") == 0 ) { + proj->indexing_params.cell_file = strdup(val); + } + + if ( strcmp(key, "indexing.methods") == 0 ) { + proj->indexing_params.indexing_methods = strdup(val); + } + + if ( strcmp(key, "indexing.multi_lattice") == 0 ) { + proj->indexing_params.multi = parse_int(val); + } + + if ( strcmp(key, "indexing.no_refine") == 0 ) { + proj->indexing_params.no_refine = parse_int(val); + } + + if ( strcmp(key, "indexing.no_retry") == 0 ) { + proj->indexing_params.no_retry = parse_int(val); + } + + if ( strcmp(key, "indexing.no_peak_check") == 0 ) { + proj->indexing_params.no_peak_check = parse_int(val); + } + + if ( strcmp(key, "indexing.no_cell_check") == 0 ) { + proj->indexing_params.no_cell_check = parse_int(val); + } + + if ( strcmp(key, "indexing.cell_tolerance") == 0 ) { + parse_tols(val, proj->indexing_params.tols); + } + + if ( strcmp(key, "indexing.min_peaks") == 0 ) { + proj->indexing_params.min_peaks = parse_int(val); + } + + if ( strcmp(key, "indexing.new_job_title") == 0 ) { + free(proj->indexing_new_job_title); + proj->indexing_new_job_title = strdup(val); + } + + if ( strcmp(key, "indexing.backend") == 0 ) { + proj->indexing_backend_selected = find_backend(val, proj); + } + + if ( strcmp(key, "integration.method") == 0 ) { + proj->indexing_params.integration_method = strdup(val); + } + + if ( strcmp(key, "integration.overpredict") == 0 ) { + proj->indexing_params.overpredict = parse_int(val); + } + + if ( strcmp(key, "integration.push_res") == 0 ) { + proj->indexing_params.push_res = parse_float(val); + } + + if ( strcmp(key, "integration.ir_inn") == 0 ) { + proj->indexing_params.ir_inn = parse_float(val); + } + + if ( strcmp(key, "integration.ir_mid") == 0 ) { + proj->indexing_params.ir_mid = parse_float(val); + } + + if ( strcmp(key, "integration.ir_out") == 0 ) { + proj->indexing_params.ir_out = parse_float(val); + } + + if ( strcmp(key, "show_peaks") == 0 ) { + proj->show_peaks = parse_int(val); + } + + if ( strcmp(key, "show_refls") == 0 ) { + proj->show_refls = parse_int(val); + } + + if ( strcmp(key, "geom") == 0 ) { + proj->geom_filename = strdup(val); + } + + if ( strcmp(key, "data_folder") == 0 ) { + proj->data_top_folder = strdup(val); + } + + if ( strcmp(key, "stream") == 0 ) { + proj->stream_filename = strdup(val); + } + + if ( strcmp(key, "search_pattern") == 0 ) { + proj->data_search_pattern = decode_matchtype(val); + } + + /* Backend indexing option? */ + if ( strncmp(key, "indexing.", 9) == 0 ) { + int i; + for ( i=0; i<proj->n_backends; i++ ) { + struct crystfel_backend *be; + be = &proj->backends[i]; + be->read_indexing_opt(be->indexing_opts_priv, + key, val); + } + } + +} + + +void clear_project_files(struct crystfelproject *proj) +{ + int i; + + if ( proj->filenames != NULL ) { + for ( i=0; i<proj->n_frames; i++ ) { + free(proj->filenames[i]); + free(proj->events[i]); + } + free(proj->filenames); + free(proj->events); + } + proj->n_frames = 0; + proj->max_frames = 0; + proj->filenames = NULL; + proj->events = NULL; +} + + +void add_file_to_project(struct crystfelproject *proj, + const char *filename, const char *event) +{ + if ( proj->n_frames == proj->max_frames ) { + int n_max = proj->max_frames + 1024; + char **n_filenames; + char **n_events; + n_filenames = realloc(proj->filenames, + n_max*sizeof(char *)); + n_events = realloc(proj->events, + n_max*sizeof(char *)); + if ( (n_filenames == NULL) || (n_events == NULL) ) { + ERROR("Failed to allocate new filename\n"); + return; + } + proj->max_frames = n_max; + proj->filenames = n_filenames; + proj->events = n_events; + } + + proj->filenames[proj->n_frames] = strdup(filename); + proj->events[proj->n_frames] = safe_strdup(event); + proj->n_frames++; +} + + +static char **add_stream(char *new_stream, + char **streams, + int *pn_streams) +{ + int i = *pn_streams; + char **new_streams = realloc(streams, + (i+1)*sizeof(struct gui_result)); + if ( new_streams == NULL ) return streams; + + new_streams[i] = new_stream; + *pn_streams = i+1; + return new_streams; +} + + +static void read_parameters(FILE *fh, struct crystfelproject *proj) +{ + char *rval; + char line[1024]; + + do { + + char *sp; + + rval = fgets(line, 1023, fh); + if ( rval == NULL ) break; + chomp(line); + if ( line[0] == '\0' ) continue; + + if ( strcmp(line, "-----") == 0 ) break; + + sp = strchr(line, ' '); + if ( sp == NULL ) { + ERROR("Unrecognised line in crystfel.project " + "file: '%s'\n", line); + continue; + } + sp[0] = '\0'; + handle_var(line, sp+1, proj); + + } while ( rval != NULL ); +} + + +static void read_results(FILE *fh, struct crystfelproject *proj) +{ + char *rval; + char line[1024]; + char **streams = NULL; + int n_streams = 0; + char *results_name = NULL; + + do { + + rval = fgets(line, 1023, fh); + if ( rval == NULL ) break; + chomp(line); + if ( line[0] == '\0' ) continue; + + if ( strncmp(line, "Result ", 7) == 0 ) { + + if ( n_streams > 0 ) { + add_result(proj, + results_name, + streams, + n_streams); + } + + n_streams = 0; + streams = NULL; + results_name = strdup(line+7); + } + + if ( strncmp(line, " Stream ", 10) == 0 ) { + streams = add_stream(strdup(line+10), + streams, + &n_streams); + } + + if ( strcmp(line, "-----") == 0 ) { + + if ( n_streams > 0 ) { + add_result(proj, + results_name, + streams, + n_streams); + } + + break; + + } + + } while ( rval != NULL ); +} + + +static void read_frames(FILE *fh, struct crystfelproject *proj) +{ + char *rval; + char line[1024]; + + do { + + rval = fgets(line, 1023, fh); + if ( rval == NULL ) break; + + chomp(line); + + if ( line[0] == '\0' ) continue; + + char *ev = NULL; + size_t n = strlen(line)-1; + for ( ; n>0; n-- ) { + if ( line[n] == ' ' ) { + line[n] = '\0'; + ev = &line[n+1]; + break; + } + } + add_file_to_project(proj, line, ev); + + } while ( rval != NULL ); +} + + +int load_project(struct crystfelproject *proj) +{ + FILE *fh; + + fh = fopen("crystfel.project", "r"); + if ( fh == NULL ) return 1; + + default_project(proj); + + read_parameters(fh, proj); + read_results(fh, proj); + read_frames(fh, proj); + + fclose(fh); + + return 0; +} + + +int save_project(struct crystfelproject *proj) +{ + int i; + FILE *fh; + + fh = fopen("crystfel.project", "w"); + if ( fh == NULL ) { + STATUS("Couldn't save project.\n"); + return 1; + } + + if ( proj->geom_filename != NULL ) { + fprintf(fh, "geom %s\n", proj->geom_filename); + } + if ( proj->data_top_folder != NULL ) { + fprintf(fh, "data_folder %s\n", proj->data_top_folder); + } + fprintf(fh, "search_pattern %s\n", + str_matchtype(proj->data_search_pattern)); + if ( proj->stream_filename != NULL ) { + fprintf(fh, "stream %s\n", proj->stream_filename); + } + + fprintf(fh, "peak_search_params.method %s\n", + str_peaksearch(proj->peak_search_params.method)); + fprintf(fh, "peak_search_params.threshold %f\n", + proj->peak_search_params.threshold); + fprintf(fh, "peak_search_params.min_sq_gradient %f\n", + proj->peak_search_params.min_sq_gradient); + fprintf(fh, "peak_search_params.min_snr %f\n", + proj->peak_search_params.min_snr); + fprintf(fh, "peak_search_params.min_pix_count %i\n", + proj->peak_search_params.min_pix_count); + fprintf(fh, "peak_search_params.max_pix_count %i\n", + proj->peak_search_params.max_pix_count); + fprintf(fh, "peak_search_params.local_bg_radius %i\n", + proj->peak_search_params.local_bg_radius); + fprintf(fh, "peak_search_params.min_res %i\n", + proj->peak_search_params.min_res); + fprintf(fh, "peak_search_params.max_res %i\n", + proj->peak_search_params.max_res); + fprintf(fh, "peak_search_params.min_snr_biggest_pix %f\n", + proj->peak_search_params.min_snr_biggest_pix); + fprintf(fh, "peak_search_params.min_snr_peak_pix %f\n", + proj->peak_search_params.min_snr_peak_pix); + fprintf(fh, "peak_search_params.min_peak_over_neighbour %f\n", + proj->peak_search_params.min_peak_over_neighbour); + fprintf(fh, "peak_search_params.pk_inn %f\n", + proj->peak_search_params.pk_inn); + fprintf(fh, "peak_search_params.pk_mid %f\n", + proj->peak_search_params.pk_mid); + fprintf(fh, "peak_search_params.pk_out %f\n", + proj->peak_search_params.pk_out); + fprintf(fh, "peak_search_params.half_pixel_shift %i\n", + proj->peak_search_params.half_pixel_shift); + fprintf(fh, "peak_search_params.revalidate %i\n", + proj->peak_search_params.revalidate); + + if ( proj->indexing_params.cell_file != NULL ) { + fprintf(fh, "indexing.cell_file %s\n", + proj->indexing_params.cell_file); + } + + if ( proj->indexing_params.indexing_methods != NULL ) { + fprintf(fh, "indexing.methods %s\n", + proj->indexing_params.indexing_methods); + } + fprintf(fh, "indexing.multi_lattice %i\n", + proj->indexing_params.multi); + fprintf(fh, "indexing.no_refine %i\n", + proj->indexing_params.no_refine); + fprintf(fh, "indexing.no_retry %i\n", + proj->indexing_params.no_retry); + fprintf(fh, "indexing.no_peak_check %i\n", + proj->indexing_params.no_peak_check); + fprintf(fh, "indexing.no_cell_check %i\n", + proj->indexing_params.no_cell_check); + + /* Values in file are in percent and degrees */ + /* Values in "tol" are in frac (not %) and radians */ + fprintf(fh, "indexing.cell_tolerance %f,%f,%f,%f,%f,%f\n", + proj->indexing_params.tols[0]*100.0, + proj->indexing_params.tols[1]*100.0, + proj->indexing_params.tols[2]*100.0, + rad2deg(proj->indexing_params.tols[3]), + rad2deg(proj->indexing_params.tols[4]), + rad2deg(proj->indexing_params.tols[5])); + fprintf(fh, "indexing.min_peaks %i\n", + proj->indexing_params.min_peaks); + + if ( proj->indexing_new_job_title != NULL ) { + fprintf(fh, "indexing.new_job_title %s\n", + proj->indexing_new_job_title); + } + + fprintf(fh, "indexing.backend %s\n", + proj->backends[proj->indexing_backend_selected].name); + for ( i=0; i<proj->n_backends; i++ ) { + struct crystfel_backend *be; + be = &proj->backends[i]; + be->write_indexing_opts(be->indexing_opts_priv, fh); + } + + fprintf(fh, "integration.method %s\n", + proj->indexing_params.integration_method); + fprintf(fh, "integration.overpredict %i\n", + proj->indexing_params.overpredict); + fprintf(fh, "integration.push_res %f\n", + proj->indexing_params.push_res); + fprintf(fh, "integration.ir_inn %f\n", + proj->indexing_params.ir_inn); + fprintf(fh, "integration.ir_mid %f\n", + proj->indexing_params.ir_mid); + fprintf(fh, "integration.ir_out %f\n", + proj->indexing_params.ir_out); + + fprintf(fh, "show_peaks %i\n", proj->show_peaks); + fprintf(fh, "show_refls %i\n", proj->show_refls); + + fprintf(fh, "-----\n"); + for ( i=0; i<proj->n_results; i++ ) { + int j; + fprintf(fh, "Result %s\n", proj->results[i].name); + for ( j=0; j<proj->results[i].n_streams; j++ ) { + fprintf(fh, " Stream %s\n", + proj->results[i].streams[j]); + } + } + + fprintf(fh, "-----\n"); + for ( i=0; i<proj->n_frames; i++ ) { + if ( proj->events[i] != NULL ) { + fprintf(fh, "%s %s\n", + proj->filenames[i], proj->events[i]); + } else { + fprintf(fh, "%s\n", proj->filenames[i]); + } + } + + fclose(fh); + + proj->unsaved = 0; + return 0; +} + + +void default_project(struct crystfelproject *proj) +{ + proj->unsaved = 0; + proj->geom_filename = NULL; + proj->n_frames = 0; + proj->max_frames = 0; + proj->filenames = NULL; + proj->events = NULL; + proj->peak_params = NULL; + proj->data_top_folder = NULL; + proj->data_search_pattern = 0; + proj->stream_filename = NULL; + proj->dtempl = NULL; + proj->cur_image = NULL; + proj->indexing_opts = NULL; + proj->n_running_tasks = 0; + proj->indexing_new_job_title = NULL; + proj->merge_new_job_title = NULL; + + proj->indexing_backend_selected = 0; + proj->merge_backend_selected = 0; + proj->n_backends = 0; + proj->backends = malloc(2*sizeof(struct crystfel_backend)); + /* FIXME: Crappy error handling */ + if ( proj->backends == NULL ) { + ERROR("Couldn't allocate space for backends\n"); + } + + if ( make_local_backend(&proj->backends[proj->n_backends++]) ) { + ERROR("Local backend setup failed\n"); + } + + #ifdef HAVE_SLURM + if ( make_slurm_backend(&proj->backends[proj->n_backends++]) ) { + ERROR("SLURM backend setup failed\n"); + } + #endif + + /* Default parameter values */ + proj->show_peaks = 0; + proj->show_refls = 0; + + proj->peak_search_params.method = PEAK_ZAEF; + proj->peak_search_params.threshold = 800.0; + proj->peak_search_params.min_sq_gradient = 100000; + proj->peak_search_params.min_snr = 5.0; + proj->peak_search_params.min_pix_count = 2; + proj->peak_search_params.max_pix_count = 200; + proj->peak_search_params.local_bg_radius = 3; + proj->peak_search_params.min_res = 0; + proj->peak_search_params.max_res = 1200; + proj->peak_search_params.min_snr_biggest_pix = 7.0; + proj->peak_search_params.min_snr_peak_pix = 6.0; + proj->peak_search_params.min_sig = 11.0; + proj->peak_search_params.min_peak_over_neighbour = -INFINITY; + proj->peak_search_params.pk_inn = 4.0; + proj->peak_search_params.pk_mid = 5.0; + proj->peak_search_params.pk_out = 7.0; + proj->peak_search_params.half_pixel_shift = 1; + proj->peak_search_params.revalidate = 1; + + proj->indexing_params.cell_file = NULL; + proj->indexing_params.indexing_methods = NULL; + proj->indexing_params.multi = 1; + proj->indexing_params.no_refine = 0; + proj->indexing_params.no_retry = 0; + proj->indexing_params.no_peak_check = 0; + proj->indexing_params.no_cell_check = 0; + proj->indexing_params.tols[0] = 0.05; /* frac (not %) */ + proj->indexing_params.tols[1] = 0.05; /* frac (not %) */ + proj->indexing_params.tols[2] = 0.05; /* frac (not %) */ + proj->indexing_params.tols[3] = deg2rad(1.5); /* rad */ + proj->indexing_params.tols[4] = deg2rad(1.5); /* rad */ + proj->indexing_params.tols[5] = deg2rad(1.5); /* rad */ + proj->indexing_params.min_peaks = 0; + proj->indexing_params.integration_method = strdup("rings"); + proj->indexing_params.overpredict = 0; + proj->indexing_params.push_res = INFINITY; + proj->indexing_params.ir_inn = 4.0; + proj->indexing_params.ir_mid = 5.0; + proj->indexing_params.ir_out = 7.0; + + proj->results = NULL; + proj->n_results = 0; +} + + +/* Assumes ownership of "name" and "streams" */ +int add_result(struct crystfelproject *proj, + char *name, + char **streams, + int n_streams) +{ + int i; + struct gui_result *new_results; + + new_results = realloc(proj->results, + (proj->n_results+1)*sizeof(struct gui_result)); + if ( new_results == NULL ) return 1; + + new_results[proj->n_results].name = name; + new_results[proj->n_results].streams = streams; + new_results[proj->n_results].n_streams = n_streams; + new_results[proj->n_results].indices = malloc(n_streams*sizeof(StreamIndex *)); + + for ( i=0; i<n_streams; i++ ) { + new_results[proj->n_results].indices[i] = NULL; + } + + proj->results = new_results; + proj->n_results++; + + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(proj->results_combo), + name, name); + + return 0; +} + + +static void update_result_index(struct gui_result *result) +{ + int i; + + for ( i=0; i<result->n_streams; i++ ) { + + /* FIXME: Skip if already up to date */ + + stream_index_free(result->indices[i]); + result->indices[i] = stream_make_index(result->streams[i]); + + } +} + + +struct gui_result *find_result_by_name(struct crystfelproject *proj, + const char *name) +{ + int i; + + for ( i=0; i<proj->n_results; i++ ) { + if ( strcmp(proj->results[i].name, name) == 0 ) { + return &proj->results[i]; + } + } + return NULL; +} + + +struct image *find_result(struct crystfelproject *proj, + const char *results_name, + const char *filename, + const char *event) +{ + Stream *st; + int i; + int found = 0; + struct image *image; + struct gui_result *result; + + result = find_result_by_name(proj, results_name); + if ( result == NULL ) return NULL; + + for ( i=0; i<result->n_streams; i++ ) { + if ( stream_select_chunk(NULL, + result->indices[i], + filename, + event) == 0 ) + { + found = 1; + break; + } + } + + if ( !found ) { + update_result_index(result); + for ( i=0; i<result->n_streams; i++ ) { + if ( stream_select_chunk(NULL, + result->indices[i], + filename, + event) == 0 ) + { + found = 1; + break; + } + } + } + + if ( !found ) return NULL; + + st = stream_open_for_read(result->streams[i]); + if ( stream_select_chunk(st, result->indices[i], + filename, event) ) + { + ERROR("Error selecting chunk.\n"); + return NULL; + } + + image = stream_read_chunk(st, STREAM_REFLECTIONS + | STREAM_PEAKS + | STREAM_DATA_DETGEOM); + + stream_close(st); + return image; +} |