diff options
author | Valerio Mariani <valerio.mariani@desy.de> | 2014-05-09 11:02:17 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2014-09-05 18:12:38 +0200 |
commit | 45492b842c3af2af542256417a8bab5bbc7bd5f7 (patch) | |
tree | 53fc320ad0734940c5a3fe2d075ae7417787432a /src | |
parent | ae9fa9e6bfd1ed98a2b146d2e228c69a9cd651cc (diff) |
Multi-event mode
Diffstat (limited to 'src')
-rw-r--r-- | src/dw-hdfsee.c | 344 | ||||
-rw-r--r-- | src/dw-hdfsee.h | 22 | ||||
-rw-r--r-- | src/hdfsee.c | 18 | ||||
-rw-r--r-- | src/im-sandbox.c | 386 | ||||
-rw-r--r-- | src/partial_sim.c | 2 | ||||
-rw-r--r-- | src/process_image.c | 15 | ||||
-rw-r--r-- | src/process_image.h | 3 |
7 files changed, 589 insertions, 201 deletions
diff --git a/src/dw-hdfsee.c b/src/dw-hdfsee.c index 399436c0..6b49d3f7 100644 --- a/src/dw-hdfsee.c +++ b/src/dw-hdfsee.c @@ -9,9 +9,9 @@ * * Authors: * 2009-2013 Thomas White <taw@physics.org> - * 2012 Richard Kirian * 2014 Valerio Mariani * 2014 Takanori Nakane + * 2012 Richard Kirian * * This file is part of CrystFEL. * @@ -50,6 +50,7 @@ #include "hdfsee.h" #include "utils.h" #include "filters.h" +#include "events.h" static void displaywindow_error(DisplayWindow *dw, const char *message) @@ -72,6 +73,10 @@ static void displaywindow_error(DisplayWindow *dw, const char *message) static gint displaywindow_closed(GtkWidget *window, DisplayWindow *dw) { + if ( dw->hdfile != NULL ) { + hdfile_close(dw->hdfile); + } + if ( dw->surf != NULL ) cairo_surface_destroy(dw->surf); if ( dw->pixbufs != NULL ) { @@ -87,6 +92,7 @@ static gint displaywindow_closed(GtkWidget *window, DisplayWindow *dw) } if ( dw->image != NULL ) { + free(dw->image->filename); free(dw->image->data); free(dw->image->flags); @@ -371,6 +377,10 @@ static int draw_stuff(cairo_surface_t *surf, DisplayWindow *dw) draw_panel_rectangle(cr, &basic_m, dw, i); cairo_fill(cr); + if ( dw->calib_mode && dw->calib_mode_show_focus ) { + maybe_draw_focus(dw, cr, i, &basic_m); + } + } } @@ -558,6 +568,7 @@ static void update_colscale(DisplayWindow *dw) static void displaywindow_update(DisplayWindow *dw) { + set_window_size(dw); update_colscale(dw); @@ -696,6 +707,10 @@ static gint displaywindow_set_binning(GtkWidget *widget, DisplayWindow *dw) return 0; } + if ( dw->hdfile == NULL ) { + return 0; + } + bd = malloc(sizeof(BinningDialog)); if ( bd == NULL ) return 0; dw->binning_dialog = bd; @@ -820,6 +835,10 @@ static gint displaywindow_set_boostint(GtkWidget *widget, DisplayWindow *dw) return 0; } + if ( dw->hdfile == NULL ) { + return 0; + } + bd = malloc(sizeof(BoostIntDialog)); if ( bd == NULL ) return 0; dw->boostint_dialog = bd; @@ -931,6 +950,10 @@ static gint displaywindow_set_ringradius(GtkWidget *widget, DisplayWindow *dw) return 0; } + if ( dw->hdfile == NULL ) { + return 0; + } + rd = malloc(sizeof(RingRadiusDialog)); if ( rd == NULL ) return 0; dw->ringradius_dialog = rd; @@ -1099,46 +1122,6 @@ static gint displaywindow_about(GtkWidget *widget, DisplayWindow *dw) } -//static int load_geometry_file(DisplayWindow *dw, struct image *image, -// const char *filename) -//{ -// struct detector *geom; -// GtkWidget *w; -// int using_loaded = 0; -// if ( dw->image->det == dw->loaded_geom ) using_loaded = 1; - -// geom = get_detector_geometry(filename); -// if ( geom == NULL ) { -// displaywindow_error(dw, "Failed to load geometry file"); -// return -1; -// } -// fill_in_values(geom, dw->hdfile); - -// if ( (1+geom->max_fs != dw->image->width) -// || (1+geom->max_ss != dw->image->height) ) { - -// displaywindow_error(dw, "Geometry doesn't match image."); -// return -1; - -// } - -// /* Sort out the mess */ -// if ( dw->loaded_geom != NULL ) free_detector_geometry(dw->loaded_geom); -// dw->loaded_geom = geom; -// if ( using_loaded ) { -// dw->image->det = dw->loaded_geom; -// } - -// w = gtk_ui_manager_get_widget(dw->ui, -// "/ui/displaywindow/view/usegeom"); -// gtk_widget_set_sensitive(GTK_WIDGET(w), TRUE); -// gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w), TRUE); -// dw->use_geom = 1; - -// return 0; -//} - - static int save_geometry_file(DisplayWindow *dw) { GtkWidget *d; @@ -1161,47 +1144,6 @@ static int save_geometry_file(DisplayWindow *dw) } -//static gint displaywindow_loadgeom_response(GtkWidget *d, gint response, -// DisplayWindow *dw) -//{ -// if ( response == GTK_RESPONSE_ACCEPT ) { - -// char *filename; - -// filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d)); - -// if ( load_geometry_file(dw, dw->image, filename) == 0 ) { -// displaywindow_update(dw); -// } - -// g_free(filename); - -// } - -// gtk_widget_destroy(d); - -// return 0; -//} - - -//static gint displaywindow_load_geom(GtkWidget *widget, DisplayWindow *dw) -//{ -// GtkWidget *d; - -// d = gtk_file_chooser_dialog_new("Load Geometry File", -// GTK_WINDOW(dw->window), -// GTK_FILE_CHOOSER_ACTION_OPEN, -// GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, -// GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, -// NULL); - -// g_signal_connect(G_OBJECT(d), "response", -// G_CALLBACK(displaywindow_loadgeom_response), dw); - -// gtk_widget_show_all(d); - -// return 0; -//} static gint displaywindow_peak_overlay(GtkWidget *widget, DisplayWindow *dw) { GtkWidget *d; @@ -1222,26 +1164,6 @@ static gint displaywindow_peak_overlay(GtkWidget *widget, DisplayWindow *dw) } -//static gint displaywindow_set_usegeom(GtkWidget *d, DisplayWindow *dw) -//{ -// GtkWidget *w; - -// /* Get new value */ -// w = gtk_ui_manager_get_widget(dw->ui, -// "/ui/displaywindow/view/usegeom"); -// dw->use_geom = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); - -// if ( dw->use_geom ) { -// dw->image->det = dw->loaded_geom; -// } else { -// dw->image->det = dw->simple_geom; -// } - -// displaywindow_update(dw); - -// return 0; -//} - static gint displaywindow_set_calibmode(GtkWidget *d, DisplayWindow *dw) { GtkWidget *w, *vbox; @@ -1249,7 +1171,7 @@ static gint displaywindow_set_calibmode(GtkWidget *d, DisplayWindow *dw) w = gtk_ui_manager_get_widget(dw->ui, "/ui/displaywindow/tools/calibmode"); - if ( !dw->use_geom ) { + if ( dw->image->det == dw->simple_geom ) { gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM(w), 0); return 0; } @@ -1475,6 +1397,10 @@ static gint displaywindow_show_numbers(GtkWidget *widget, DisplayWindow *dw) return 0; } + if ( dw->hdfile == NULL ) { + return 0; + } + nw = malloc(sizeof(struct numberswindow)); if ( nw == NULL ) return 0; dw->numbers_window = nw; @@ -1684,6 +1610,8 @@ static void displaywindow_addmenubar(DisplayWindow *dw, GtkWidget *vbox, { "PeaksAction", NULL, "Load Feature List...", NULL, NULL, G_CALLBACK(displaywindow_peak_overlay) }, + { "EventsAction", NULL, "_Events", NULL, NULL, NULL }, + { "HelpAction", NULL, "_Help", NULL, NULL, NULL }, { "AboutAction", GTK_STOCK_ABOUT, "_About hdfsee...", NULL, NULL, @@ -1695,6 +1623,8 @@ static void displaywindow_addmenubar(DisplayWindow *dw, GtkWidget *vbox, GtkToggleActionEntry toggles[] = { { "ColScaleAction", NULL, "Colour Scale", NULL, NULL, G_CALLBACK(displaywindow_set_colscale), FALSE }, + { "CalibModeAction", NULL, "Calibration Mode", NULL, NULL, + G_CALLBACK(displaywindow_set_calibmode), FALSE }, { "RingsAction", NULL, "Resolution Rings", "F9", NULL, G_CALLBACK(displaywindow_set_rings), dw->show_rings }, { "ShowPeaksAction", NULL, "Features", "F8", NULL, @@ -1748,14 +1678,13 @@ static void do_filters(DisplayWindow *dw) } } - struct newhdf { DisplayWindow *dw; GtkWidget *widget; char name[1024]; }; -static gint displaywindow_newhdf(GtkMenuItem *item, struct newhdf *nh, const char *filename) +static gint displaywindow_newhdf(GtkMenuItem *item, struct newhdf *nh) { gboolean a; int fail; @@ -1764,12 +1693,16 @@ static gint displaywindow_newhdf(GtkMenuItem *item, struct newhdf *nh, const cha a = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(nh->widget)); if ( !a ) return 0; - fail = hdf5_read2(filename, nh->dw->image, nh->name, 0, 1); + + fail = hdf5_read(nh->dw->hdfile, nh->dw->image, nh->name, 0); if ( fail ) { ERROR("Couldn't load image"); return 1; } + nh->dw->simple_geom = simple_geometry(nh->dw->image); + nh->dw->image->det = nh->dw->simple_geom; + do_filters(nh->dw); displaywindow_update(nh->dw); return 0; @@ -1804,7 +1737,7 @@ static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile, item = gtk_menu_item_new_with_label(names[i]); sub = displaywindow_addhdfgroup(hdfile, names[i], - dw, rgp, selectme); + dw, rgp, selectme); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), sub); } else if ( is_image[i] ) { @@ -1820,7 +1753,7 @@ static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile, nh->dw = dw; nh->widget = item; g_signal_connect(G_OBJECT(item), "toggled", - G_CALLBACK(displaywindow_newhdf), nh); + G_CALLBACK(displaywindow_newhdf), nh); } if ( (selectme != NULL) @@ -1832,8 +1765,7 @@ static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile, GTK_CHECK_MENU_ITEM(item), FALSE); } - *rgp = gtk_radio_menu_item_get_group( - GTK_RADIO_MENU_ITEM(item)); + *rgp = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); } else { @@ -1842,7 +1774,7 @@ static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile, item = gtk_menu_item_new_with_label(names[i]); if ( hdfile_is_scalar(hdfile, names[i], 0) ) { - tmp = hdfile_get_string_value(hdfile, names[i]); + tmp = hdfile_get_string_value(hdfile, names[i], NULL); } else { tmp = NULL; } @@ -1865,7 +1797,6 @@ static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile, free(names[i]); - } free(is_group); @@ -1875,30 +1806,32 @@ static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile, } -static GtkWidget *displaywindow_createhdfmenus(const char *filename, +static GtkWidget *displaywindow_createhdfmenus(struct hdfile *hdfile, DisplayWindow *dw, const char *selectme) { GSList *rg = NULL; GtkWidget *w; - struct hdfile *hdfile; - hdfile = hdfile_open(filename); - if ( hdfile == NULL ) { - return NULL; - } w = displaywindow_addhdfgroup(hdfile, "/", dw, &rg, selectme); - hdfile_close(hdfile); + return w; } -static int displaywindow_update_menus(DisplayWindow *dw, const char * filename, const char *selectme) +struct newev { + DisplayWindow *dw; + GtkWidget *widget; + int new_ev; +}; + + +static int displaywindow_update_menus(DisplayWindow *dw, const char *selectme) { GtkWidget *ms; GtkWidget *w; - ms = displaywindow_createhdfmenus(filename , dw, selectme); + ms = displaywindow_createhdfmenus(dw->hdfile, dw, selectme); if ( ms == NULL ) return 1; @@ -1912,6 +1845,91 @@ static int displaywindow_update_menus(DisplayWindow *dw, const char * filename, } +static gint displaywindow_newevent(GtkMenuItem *item, struct newev *ne) +{ + gboolean a; + int fail; + + if ( ne->dw->not_ready_yet ) return 0; + + a = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(ne->widget)); + if ( !a ) return 0; + + fail = hdf5_read2(ne->dw->hdfile, ne->dw->image, + ne->dw->ev_list->events[ne->new_ev], 0); + if ( fail ) { + ERROR("Couldn't load image"); + return 1; + } + + ne->dw->curr_event = ne->new_ev; + + do_filters(ne->dw); + displaywindow_update(ne->dw); + return 0; +} + + +static int displaywindow_update_event_menu(DisplayWindow *dw, + struct event_list *ev_list, + int curr_event) +{ + + int ei; + GtkWidget *w; + GtkWidget *ww; + GSList *grp = NULL; + + w = gtk_ui_manager_get_widget(dw->ui, + "/ui/displaywindow/events"); + + ww = gtk_menu_new(); + + for ( ei=0; ei< ev_list->num_events; ei++ ) { + + GtkWidget *www; + struct newev *ne; + char *ev_string; + + ev_string = get_event_string(ev_list->events[ei]); + www = gtk_radio_menu_item_new_with_label(grp, ev_string); + free(ev_string); + + ne = malloc(sizeof(struct newev)); + if ( ne != NULL ) { + + ne->widget = www; + ne->dw = dw; + ne->new_ev = ei; + + g_signal_connect(G_OBJECT(www), "toggled", + G_CALLBACK(displaywindow_newevent), ne); + + } + + if ( ei == dw->curr_event ) { + gtk_check_menu_item_set_active( + GTK_CHECK_MENU_ITEM(www), TRUE); + } else { + gtk_check_menu_item_set_active( + GTK_CHECK_MENU_ITEM(www), FALSE); + } + + gtk_menu_shell_append(GTK_MENU_SHELL(ww), www); + + grp = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(www)); + + } + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), ww); + gtk_widget_show_all(w); + + return 0; + +} + + + static gint displaywindow_release(GtkWidget *widget, GdkEventButton *event, DisplayWindow *dw) { @@ -2360,10 +2378,11 @@ static gint displaywindow_keypress(GtkWidget *widget, GdkEventKey *event, } -DisplayWindow *displaywindow_open(const char *filename, const char *peaks, +DisplayWindow *displaywindow_open(char *filename, const char *peaks, double boost, int binning, int noisefilter, int calibmode, int colscale, - const char *element, const char *geometry, + const char *element, + struct detector *det_geom, const char *beam, int show_rings, double *ring_radii, int n_rings, double ring_size, @@ -2374,6 +2393,7 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, GtkWidget *vbox; int check; GtkWidget *w; + GtkWidget *ww; dw = calloc(1, sizeof(DisplayWindow)); if ( dw == NULL ) return NULL; @@ -2385,6 +2405,7 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, dw->boostint = 1; dw->motion_callback = 0; dw->numbers_window = NULL; + dw->simple_geom = NULL; dw->image = NULL; dw->show_rings = show_rings; dw->show_peaks = 0; @@ -2404,6 +2425,9 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, dw->calib_mode_curr_p = NULL; dw->calib_mode_show_focus = 1; dw->statusbar = NULL; + dw->multi_event = 0; + dw->curr_event = 0; + dw->ev_list = NULL; if ( beam != NULL ) { dw->image->beam = get_beam_parameters(beam); @@ -2411,15 +2435,65 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, dw->image->det = det_geom; - check = hdf5_read(filename, dw->image, element, 0); + dw->hdfile = hdfile_open(filename); + if ( dw->hdfile == NULL ) { + ERROR("Couldn't open file: %s\n", filename); + free(dw); + return NULL; + } + + if ( dw->image->det != NULL && ( dw->image->det->path_dim != 0 || + dw->image->det->dim_dim != 0 )) { + + dw->multi_event = 1; + + dw->ev_list = fill_event_list(dw->hdfile, dw->image->det); + + if ( dw->ev_list == NULL ) { + ERROR("Error while parsing file structure\n"); + free_event_list(dw->ev_list); + free(dw); + return NULL; + } + if ( dw->ev_list->num_events == 0 ) { + ERROR("Multi-event geometry file but no events found in data file"); + free_event_list(dw->ev_list); + free(dw); + return NULL; + } else { + dw->curr_event = 0; + } + + } + + if ( dw->image->det != NULL ) { + + if ( dw->multi_event ) { + check = hdf5_read2(dw->hdfile, dw->image, + dw->ev_list->events[dw->curr_event], 0); + } else { + check = hdf5_read2(dw->hdfile, dw->image, NULL, 0); + } + + } else { + check = hdf5_read(dw->hdfile, dw->image, element, 0); + } if (check) { ERROR("Couldn't load file\n"); free(dw); + hdfile_close(dw->hdfile); return NULL; } + dw->image->filename = strdup(filename); + + if ( dw->image->det == NULL ) { + dw->simple_geom = simple_geometry(dw->image); + dw->image->det = dw->simple_geom; + } + /* Filters need geometry */ - do_filters(dw); + do_filters(dw); /* Peak list provided at startup? */ if ( peaks != NULL ) { @@ -2458,12 +2532,19 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, gtk_widget_show_all(dw->window); w = gtk_ui_manager_get_widget(dw->ui, - "/ui/displaywindow/view/images"); + "/ui/displaywindow/view/images"); - if ( !single_panel_data_source(dw->image->det, element) ) { + if ( dw->image->det != dw->simple_geom ) { gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE); } + ww = gtk_ui_manager_get_widget(dw->ui, + "/ui/displaywindow/events"); + + if ( dw->image->det == dw->simple_geom || dw->multi_event == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(ww), FALSE); + } + displaywindow_update(dw); gtk_widget_add_events(GTK_WIDGET(dw->drawingarea), @@ -2482,7 +2563,14 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, g_signal_connect(GTK_OBJECT(dw->drawingarea), "key-press-event", G_CALLBACK(displaywindow_keypress), dw); - displaywindow_update_menus(dw, filename, element); + if ( dw->image->det == dw->simple_geom ) { + displaywindow_update_menus(dw, element); + } else { + if ( dw->multi_event != 0 ) { + displaywindow_update_event_menu(dw, dw->ev_list, dw->curr_event); + } + } + dw->not_ready_yet = 0; return dw; diff --git a/src/dw-hdfsee.h b/src/dw-hdfsee.h index 1d17f85b..b3521702 100644 --- a/src/dw-hdfsee.h +++ b/src/dw-hdfsee.h @@ -9,9 +9,9 @@ * * Authors: * 2009-2012 Thomas White <taw@physics.org> - * 2012 Richard Kirian * 2014 Valerio Mariani * 2014 Takanori Nakane <nakane.t@gmail.com> + * 2012 Richard Kirian * * This file is part of CrystFEL. * @@ -37,6 +37,7 @@ #ifndef DISPLAYWINDOW_H #define DISPLAYWINDOW_H +#include "events.h" #include "image.h" #include <gtk/gtk.h> @@ -89,6 +90,9 @@ typedef struct { int not_ready_yet; + struct detector* simple_geom; + + struct hdfile *hdfile; struct image *image; /* Dialog boxes */ @@ -124,16 +128,22 @@ typedef struct { int scale; GdkPixbuf *col_scale; + int multi_event; + struct event_list *ev_list; + int curr_event; + + + } DisplayWindow; /* Open an image display window showing the given filename, or NULL */ -extern DisplayWindow *displaywindow_open(const char *filename, +extern DisplayWindow *displaywindow_open(char *filename, const char *peaks, double boost, int binning, - int noisefilter, int calibmode, int colscale, - const char *element, - struct detector *det_geom, const char *beam, - int show_rings, + int noisefilter, int calibmode, + int colscale, const char *element, + struct detector *det_geom, + const char *beam, int show_rings, double *ring_radii, int n_rings, double ring_size, int median_filter); diff --git a/src/hdfsee.c b/src/hdfsee.c index 742bec8c..8ae55f9c 100644 --- a/src/hdfsee.c +++ b/src/hdfsee.c @@ -9,8 +9,8 @@ * * Authors: * 2009-2014 Thomas White <taw@physics.org> - * 2012 Richard Kirian * 2014 Valerio Mariani + * 2012 Richard Kirian * * This file is part of CrystFEL. * @@ -76,7 +76,11 @@ static void show_help(const char *s) " -yellow-white.\n" " -e, --image=<element> Start up displaying this image from the\n" " HDF5 file. Example: /data/data0.\n" +" (Only used when a geometry file is not" +" provided. See option -g)" " -g, --geometry=<filename> Use geometry from file for display.\n" +" (When this option is used, the value of\n" +" of the -e parameter is ignored)" " -m, --beam=<filename> Get beam parameters from <filename>.\n" "\n"); } @@ -211,7 +215,7 @@ int main(int argc, char *argv[]) ERROR("Failed to read detector geometry from " "'%s'\n", optarg); return 1; - } + } break; case 'm' : @@ -273,12 +277,6 @@ int main(int argc, char *argv[]) return -1; } - if ( det_geom == NULL ) { - ERROR("You need to provide a geometry file (please read the" - " manual for more details).\n"); - return 1; - } - if ( cscale == NULL ) cscale = strdup("colour"); if ( strcmp(cscale, "mono") == 0 ) { colscale = SCALE_MONO; @@ -298,9 +296,9 @@ int main(int argc, char *argv[]) main_window_list[i] = displaywindow_open(argv[optind+i], peaks, boost, binning, config_noisefilter, - config_calibmode, + config_calibmode, colscale, element, - det_geom, beam, + det_geom, beam, config_showrings, ring_radii, n_rings, diff --git a/src/im-sandbox.c b/src/im-sandbox.c index 42e4a090..48518b82 100644 --- a/src/im-sandbox.c +++ b/src/im-sandbox.c @@ -10,6 +10,7 @@ * * Authors: * 2010-2014 Thomas White <taw@physics.org> + * 2014 Valerio Mariani * 2011 Richard Kirian * 2012 Lorenzo Galli * 2012 Chunhong Yoon @@ -46,6 +47,7 @@ #include <fcntl.h> #include <signal.h> #include <sys/stat.h> +#include <assert.h> #ifdef HAVE_CLOCK_GETTIME #include <time.h> @@ -53,6 +55,10 @@ #include <sys/time.h> #endif +#include <events.h> +#include <hdf5-file.h> +#include <detector.h> + #include "im-sandbox.h" #include "process_image.h" @@ -101,7 +107,7 @@ struct sandbox FILE **result_fhs; int *filename_pipes; int *stream_pipe_write; - char **last_filename; + struct filename_plus_event **last_filename; char *tmpdir; @@ -125,48 +131,210 @@ static void unlock_sandbox(struct sandbox *sb) } -static char *get_pattern(FILE *fh, int config_basename, const char *prefix) +static struct filename_plus_event *get_pattern + (FILE *fh, int config_basename, struct detector *det, + const char *prefix) { - char *line; - char *filename; + char *line = NULL; size_t len; + struct filename_plus_event *fne; + struct hdfile *hdfile; + char filename_buf[2014]; + char event_buf[2014]; - do { + static char *filename = NULL; + static struct event_list *ev_list = NULL; + static int event_index = -1; - /* Get the next filename */ - char *rval; + line = malloc(1024*sizeof(char)); - line = malloc(1024*sizeof(char)); - rval = fgets(line, 1023, fh); - if ( rval == NULL ) { + while ( event_index == -1 ) { + + int scan_check; + + do { + + /* Get the next filename */ + char *rval; + + rval = fgets(line, 1023, fh); + if ( rval == NULL ) { + free(line); + return NULL; + } + + chomp(line); + + } while ( strlen(line) == 0 ); + + if ( config_basename ) { + char *tmp; + tmp = safe_basename(line); free(line); - return NULL; + line = tmp; } - chomp(line); + scan_check = sscanf(line, "%s %s", filename_buf, event_buf ); - } while ( strlen(line) == 0 ); + len = strlen(prefix)+strlen(filename_buf)+1; - if ( config_basename ) { - char *tmp; - tmp = safe_basename(line); - free(line); - line = tmp; - } + /* Round the length of the buffer, too keep Valgrind quiet when it gets + * given to write() a bit later on */ + len += 4 - (len % 4); + + if ( filename == NULL ) { + filename = malloc(len); + } else { + char *new_filename; + new_filename = realloc(filename, len*sizeof(char)); + if ( filename == NULL ) { + return NULL; + } + filename = new_filename; + } + + snprintf(filename, 1023, "%s%s", prefix, filename_buf); + + if ( det->path_dim != 0 || det->dim_dim != 0 ) { + + ev_list = initialize_event_list(); - len = strlen(prefix)+strlen(line)+1; + if ( scan_check == 1) { - /* Round the length of the buffer, too keep Valgrind quiet when it gets - * given to write() a bit later on */ - len += 4 - (len % 4); + hdfile = hdfile_open(filename); + if ( hdfile == NULL ) { + ERROR("Failed to open file %s\n", filename); + free(line); + return NULL; + } + + if ( ev_list != NULL ) { + free_event_list(ev_list); + } - filename = malloc(len); + ev_list = fill_event_list(hdfile, det); + + if ( ev_list->num_events == 0 ) { + event_index = -1; + } else { + event_index = 0; + } + + hdfile_close(hdfile); + + } else { + + struct event *ev_to_add; + + ev_to_add = get_event_from_event_string(event_buf); + append_event_to_event_list(ev_list, ev_to_add); + free_event(ev_to_add); + event_index = 0; + + } + } else { - snprintf(filename, 1023, "%s%s", prefix, line); + event_index = 0; + + } + } + + fne = malloc(sizeof(struct filename_plus_event)); + fne->filename = strdup(filename); + + if ( det->path_dim !=0 || det->dim_dim !=0 ) { + fne->ev = copy_event(ev_list->events[event_index]); + if ( event_index != ev_list->num_events-1 ) { + event_index += 1; + } else { + event_index = -1; + } + } else { + fne->ev = NULL; + event_index = -1; + } free(line); + return fne; +} + + +struct buffer_data +{ + char *rbuffer; + char *line; + int fd; + int rbufpos; + int rbuflen; +}; + + +static int read_fpe_data(struct buffer_data *bd) +{ + int rval; + int no_line = 0; + + rval = read(bd->fd, bd->rbuffer+bd->rbufpos, bd->rbuflen-bd->rbufpos); + if ( (rval == -1) || (rval == 0) ) return 1; + bd->rbufpos += rval; + assert(bd->rbufpos <= bd->rbuflen); + + while ( (!no_line) && (bd->rbufpos > 0) ) { + + int i; + int line_ready = 0; + int line_end = 0; + + /* See if there's a full line in the buffer yet */ + for ( i=0; i<bd->rbufpos; i++ ) { + + /* Is there a line in the buffer? */ + if ( strncmp(&bd->rbuffer[i] ,"\n" ,1 ) == 0 ) { + line_end = i; + line_ready = 1; + break; + } + + } + + if ( line_ready ) { + + int new_rbuflen; + + if ( bd->line != NULL ) { + free(bd->line); + } + + bd->line = strdup(bd->rbuffer); + + /* Now the block's been parsed, it should be + * forgotten about */ + memmove(bd->rbuffer, + bd->rbuffer + line_end + 2, + bd->rbuflen - line_end - 2); + + /* Subtract the number of bytes removed */ + bd->rbufpos = bd->rbufpos - line_end - 1; + new_rbuflen = bd->rbuflen - line_end - 2 ; + if ( new_rbuflen == 0 ) new_rbuflen = 256; + bd->rbuffer = realloc(bd->rbuffer, new_rbuflen*sizeof(char)); + bd->rbuflen = new_rbuflen; + + return 1; + + } else { + + if ( bd->rbufpos == bd->rbuflen ) { + bd->rbuffer = realloc(bd->rbuffer, bd->rbuflen + 256); + bd->rbuflen = bd->rbuflen + 256; + } + no_line = 1; + + } + + } - return filename; + return 0; } @@ -174,9 +342,19 @@ static void run_work(const struct index_args *iargs, int filename_pipe, int results_pipe, Stream *st, int cookie, const char *tmpdir) { - int allDone = 0; FILE *fh; + int allDone = 0; int w; + unsigned int opts; + struct buffer_data *bd; + + bd = malloc(sizeof(struct buffer_data)); + bd->rbuffer = malloc(256*sizeof(char)); + bd->rbuflen = 256; + bd->rbufpos = 0; + bd->line = NULL; + bd->fd = 0; + fh = fdopen(filename_pipe, "r"); if ( fh == NULL ) { @@ -189,36 +367,101 @@ static void run_work(const struct index_args *iargs, ERROR("Failed to send request for first filename.\n"); } + bd->fd = fileno(fh); + + /* Set non-blocking */ + opts = fcntl(bd->fd, F_GETFL); + fcntl(bd->fd, F_SETFL, opts | O_NONBLOCK); + while ( !allDone ) { struct pattern_args pargs; int c; - char *line; - char *rval; + int error; + int rval; char buf[1024]; - line = malloc(1024*sizeof(char)); - rval = fgets(line, 1023, fh); - if ( rval == NULL ) { + error = 0; + pargs.filename_p_e = initialize_filename_plus_event(); - ERROR("Read error!\n"); - free(line); + rval =0; + + do { + + fd_set fds; + struct timeval tv; + int sval; + + FD_ZERO(&fds); + FD_SET(bd->fd, &fds); + + tv.tv_sec = 30; + tv.tv_usec = 0; + + sval = select(bd->fd+1, &fds, NULL, NULL, &tv); + + if ( sval == -1 ) { + + const int err = errno; + + switch ( err ) { + + case EINTR: + STATUS("Restarting select()\n"); + break; + + default: + ERROR("select() failed: %s\n", strerror(err)); + rval = 1; + + } + + } else if ( sval != 0 ) { + rval = read_fpe_data(bd); + } else { + ERROR("No data sent from main process..\n"); + rval = 1; + error = 1; + } + + } while ( !rval ); + + if ( error == 1 ) { allDone = 1; continue; - } - chomp(line); + chomp(bd->line); - if ( strlen(line) == 0 ) { + if ( strlen(bd->line) == 0 ) { allDone = 1; } else { - pargs.filename = line; - pargs.n_crystals = 0; + char filename[1024]; + char event_str[1024]; + struct event* ev; + + sscanf(bd->line, "%s %s", filename, event_str); + pargs.filename_p_e->filename = strdup(filename); + + if ( strcmp(event_str, "/") != 0 ) { + + ev = get_event_from_event_string(event_str); + if ( ev == NULL ) { + ERROR("Error in event recovery\n"); + } + pargs.filename_p_e->ev = ev; + + } else { + + pargs.filename_p_e->ev = NULL; + + } + + pargs.n_crystals = 0; process_image(iargs, &pargs, st, cookie, tmpdir, results_pipe); @@ -229,12 +472,16 @@ static void run_work(const struct index_args *iargs, ERROR("write P0\n"); } - } + free_filename_plus_event(pargs.filename_p_e); - free(line); + } } + free(bd->line); + free(bd->rbuffer); + free(bd); + cleanup_indexing(iargs->indm, iargs->ipriv); free(iargs->indm); free(iargs->ipriv); @@ -603,8 +850,9 @@ static void handle_zombie(struct sandbox *sb) if ( WIFSIGNALED(status) ) { STATUS("Worker %i was killed by signal %i\n", i, WTERMSIG(status)); - STATUS("Last filename was: %s\n", - sb->last_filename[i]); + STATUS("Last filename was: %s (%s)\n", + sb->last_filename[i]->filename, + get_event_string(sb->last_filename[i]->ev) ); sb->n_processed++; start_worker_process(sb, i); } @@ -804,7 +1052,7 @@ void create_sandbox(struct index_args *iargs, int n_proc, char *prefix, lock_sandbox(sb); for ( i=0; i<n_proc; i++ ) { - char *nextImage; + struct filename_plus_event *nextImage; char results[1024]; char *rval; int fd; @@ -857,27 +1105,62 @@ void create_sandbox(struct index_args *iargs, int n_proc, char *prefix, } /* Send next filename */ - nextImage = get_pattern(fh, config_basename, prefix); + nextImage = get_pattern(fh, config_basename, iargs->det, prefix); + + if ( sb->last_filename[i] != NULL ) { + free_filename_plus_event(sb->last_filename[i]); + } - free(sb->last_filename[i]); sb->last_filename[i] = nextImage; if ( nextImage == NULL ) { + /* No more images */ r = write(sb->filename_pipes[i], "\n", 1); if ( r < 0 ) { ERROR("Write pipe\n"); } + } else { - r = write(sb->filename_pipes[i], nextImage, - strlen(nextImage)); - r -= write(sb->filename_pipes[i], "\n", 1); + + r = write(sb->filename_pipes[i], nextImage->filename, + strlen(nextImage->filename)); + if ( r < 0 ) { ERROR("write pipe\n"); } - } + r = write(sb->filename_pipes[i], " ", 1); + if ( r < 0 ) { + ERROR("write pipe\n"); + } + + if ( nextImage->ev != NULL ) { + + r = write(sb->filename_pipes[i], + get_event_string(nextImage->ev), + strlen(get_event_string(nextImage->ev))); + if ( r < 0 ) { + ERROR("write pipe\n"); + } + + } else { + + r = write(sb->filename_pipes[i], "/", 1); + if ( r < 0 ) { + ERROR("write pipe\n"); + } + + } + + r = write(sb->filename_pipes[i], "\n", 1); + if ( r < 0 ) { + ERROR("write pipe\n"); + } + + } } + unlock_sandbox(sb); /* Update progress */ @@ -891,7 +1174,8 @@ void create_sandbox(struct index_args *iargs, int n_proc, char *prefix, "%4i crystals so far. " "%4i images processed since the last message.\n", sb->n_hadcrystals, sb->n_processed, - 100.0 * sb->n_hadcrystals / sb->n_processed, + (sb->n_processed == 0 ? 0 : + 100.0 * sb->n_hadcrystals / sb->n_processed), sb->n_crystals, sb->n_processed - sb->n_processed_last_stats); diff --git a/src/partial_sim.c b/src/partial_sim.c index 9bfe33fe..89ad5a2e 100644 --- a/src/partial_sim.c +++ b/src/partial_sim.c @@ -387,7 +387,7 @@ static void finalise_job(void *vqargs, void *vwargs) struct queue_args *qargs = vqargs; int i; - write_chunk(qargs->stream, &wargs->image, NULL, 0, 1); + write_chunk(qargs->stream, &wargs->image, NULL, 0, 1, NULL); for ( i=0; i<NBINS; i++ ) { qargs->n_ref[i] += wargs->n_ref[i]; diff --git a/src/process_image.c b/src/process_image.c index ec0a7e81..19a3c347 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -57,25 +57,31 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, float *data_for_measurement; size_t data_size; int check; + struct hdfile *hdfile; struct image image; int i; int r; char *rn; - struct hdfile *hdfile; image.features = NULL; image.data = NULL; image.flags = NULL; image.copyme = iargs->copyme; image.id = cookie; - image.filename = pargs->filename; + image.filename = pargs->filename_p_e->filename; + image.event = pargs->filename_p_e->ev; image.beam = iargs->beam; image.det = iargs->det; image.crystals = NULL; image.n_crystals = 0; + hdfile = hdfile_open(image.filename); + if ( hdfile == NULL ) { + ERROR("Couldn't open file: %s\n", image.filename); + return; + } - check = hdf5_read(image.filename, &image, iargs->element, 1); + check = hdf5_read2(hdfile, &image, image.event, 0); if ( check ) { return; } @@ -178,7 +184,8 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, iargs->int_diag_k, iargs->int_diag_l, results_pipe); write_chunk(st, &image, hdfile, - iargs->stream_peaks, iargs->stream_refls); + iargs->stream_peaks, iargs->stream_refls, + pargs->filename_p_e->ev); for ( i=0; i<image.n_crystals; i++ ) { cell_free(crystal_get_cell(image.crystals[i])); diff --git a/src/process_image.h b/src/process_image.h index 8691cd3f..7c48d711 100644 --- a/src/process_image.h +++ b/src/process_image.h @@ -8,6 +8,7 @@ * * Authors: * 2010-2014 Thomas White <taw@physics.org> + * 2014 Valerio Mariani * * This file is part of CrystFEL. * @@ -89,7 +90,7 @@ struct index_args struct pattern_args { /* "Input" */ - char *filename; + struct filename_plus_event *filename_p_e; /* "Output" */ int n_crystals; |