aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorValerio Mariani <valerio.mariani@desy.de>2014-05-09 11:02:17 +0200
committerThomas White <taw@physics.org>2014-09-05 18:12:38 +0200
commit45492b842c3af2af542256417a8bab5bbc7bd5f7 (patch)
tree53fc320ad0734940c5a3fe2d075ae7417787432a /src
parentae9fa9e6bfd1ed98a2b146d2e228c69a9cd651cc (diff)
Multi-event mode
Diffstat (limited to 'src')
-rw-r--r--src/dw-hdfsee.c344
-rw-r--r--src/dw-hdfsee.h22
-rw-r--r--src/hdfsee.c18
-rw-r--r--src/im-sandbox.c386
-rw-r--r--src/partial_sim.c2
-rw-r--r--src/process_image.c15
-rw-r--r--src/process_image.h3
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;