aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/hdfsee.ui1
-rw-r--r--src/dw-hdfsee.c394
-rw-r--r--src/dw-hdfsee.h10
-rw-r--r--src/hdfsee.c12
4 files changed, 396 insertions, 21 deletions
diff --git a/data/hdfsee.ui b/data/hdfsee.ui
index 0d00164b..873fe062 100644
--- a/data/hdfsee.ui
+++ b/data/hdfsee.ui
@@ -25,6 +25,7 @@
</menu>
<menu name="tools" action="ToolsAction">
+ <menuitem name="calibmode" action="CalibModeAction" />
<menuitem name="numbers" action="NumbersAction" />
<menuitem name="peaks" action="PeaksAction" />
<menuitem name="geometry" action="LoadGeomAction" />
diff --git a/src/dw-hdfsee.c b/src/dw-hdfsee.c
index 75232b12..7fa7f3e2 100644
--- a/src/dw-hdfsee.c
+++ b/src/dw-hdfsee.c
@@ -10,6 +10,7 @@
* Authors:
* 2009-2013 Thomas White <taw@physics.org>
* 2012 Richard Kirian
+ * 2014 Valerio Mariani
*
* This file is part of CrystFEL.
*
@@ -39,6 +40,7 @@
#include <string.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdkkeysyms.h>
#include "dw-hdfsee.h"
#include "hdfsee-render.h"
@@ -139,6 +141,31 @@ static void draw_panel_rectangle(cairo_t *cr, cairo_matrix_t *basic_m,
}
+static void draw_calib_focus_rectangle(cairo_t *cr, cairo_matrix_t *basic_m,
+ DisplayWindow *dw, int i)
+{
+ struct panel p = dw->image->det->panels[i];
+ int w = gdk_pixbuf_get_width(dw->pixbufs[i]);
+ int h = gdk_pixbuf_get_height(dw->pixbufs[i]);
+ cairo_matrix_t m;
+
+ /* Start with the basic coordinate system */
+ cairo_set_matrix(cr, basic_m);
+
+ /* Move to the right location */
+ cairo_translate(cr, p.cnx/dw->binning, p.cny/dw->binning);
+
+ /* Twiddle directions according to matrix */
+ cairo_matrix_init(&m, p.fsx, p.fsy, p.ssx, p.ssy, 0.0, 0.0);
+ cairo_transform(cr, &m);
+
+ cairo_set_line_width (cr, 3.0);
+ cairo_set_source_rgb (cr, 255, 255, 255);
+ cairo_rectangle(cr, 0.0, 0.0, w, h);
+
+}
+
+
static void show_ring(cairo_t *cr, DisplayWindow *dw,
double d, const char *label, cairo_matrix_t *basic_m,
double r, double g, double b)
@@ -200,6 +227,28 @@ static void show_simple_ring(cairo_t *cr, DisplayWindow *dw,
}
+static void maybe_draw_focus(DisplayWindow *dw, cairo_t *cr, int i,
+ cairo_matrix_t *basic_m)
+{
+ if ( dw->calib_mode_groups ) {
+
+ if ( dw->image->det->panels[i].rigid_group
+ == dw->calib_mode_curr_rg )
+ {
+ draw_calib_focus_rectangle(cr, basic_m, dw, i);
+ cairo_stroke(cr);
+ }
+
+ } else {
+
+ if ( &dw->image->det->panels[i] == dw->calib_mode_curr_p) {
+ draw_calib_focus_rectangle(cr, basic_m, dw, i);
+ cairo_stroke(cr);
+ }
+
+ }
+}
+
static int draw_stuff(cairo_surface_t *surf, DisplayWindow *dw)
{
cairo_t *cr;
@@ -232,6 +281,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);
+ }
+
}
}
@@ -244,16 +297,6 @@ static int draw_stuff(cairo_surface_t *surf, DisplayWindow *dw)
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_fill(cr);
- //cairo_rectangle(cr, -370.0, 800.0, 120.0, 60.0);
- //cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.3);
- //cairo_fill(cr);
-
- //show_simple_ring(cr, dw, 80.0, &basic_m);
- //show_simple_ring(cr, dw, 186.0, &basic_m);
- //show_simple_ring(cr, dw, 230.0, &basic_m);
- //show_simple_ring(cr, dw, 320.0, &basic_m);
- //show_simple_ring(cr, dw, 380.0, &basic_m);
-
/* Draw resolution circles */
if ( dw->n_rings == -1 ) {
/* n_rings == -1 means default behavior */
@@ -350,7 +393,7 @@ static int draw_stuff(cairo_surface_t *surf, DisplayWindow *dw)
cairo_set_line_width(cr, 0.75/dw->binning);
cairo_stroke(cr);
-
+;
}
}
@@ -404,7 +447,7 @@ static void set_window_size(DisplayWindow *dw)
dw->height = (max_y - min_y) / dw->binning;
/* Add a thin border */
- dw->width += 2.0;
+ dw->width += 2.0;;
dw->height += 2.0;
}
@@ -935,7 +978,7 @@ static gint displaywindow_peaklist_response(GtkWidget *d, gint response,
gtk_widget_destroy(d);
- return 0;
+ return 0;;
}
@@ -1013,6 +1056,28 @@ static int load_geometry_file(DisplayWindow *dw, struct image *image,
}
+static int save_geometry_file(DisplayWindow *dw)
+{
+ GtkWidget *d;
+ gchar * filename;
+ int w;
+
+ d = gtk_file_chooser_dialog_new("Save Detector Geometry",
+ GTK_WINDOW(dw->window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_run (GTK_DIALOG (d));
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (d));
+ w = write_detector_geometry(filename, dw->image->det);
+ gtk_widget_destroy(d);
+ g_free(filename);
+ return w;
+}
+
+
static gint displaywindow_loadgeom_response(GtkWidget *d, gint response,
DisplayWindow *dw)
{
@@ -1096,6 +1161,54 @@ static gint displaywindow_set_usegeom(GtkWidget *d, DisplayWindow *dw)
return 0;
}
+static gint displaywindow_set_calibmode(GtkWidget *d, DisplayWindow *dw)
+{
+
+ GtkWidget *w, *vbox;
+
+ w = gtk_ui_manager_get_widget(dw->ui,
+ "/ui/displaywindow/tools/calibmode");
+ if ( !dw->use_geom ) {
+ gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM(w), 0);
+ return 0;
+ }
+
+ /* Get new value */
+ dw->calib_mode = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w));
+
+ /* When entering calibration mode */
+ if ( dw->calib_mode ) {
+
+ guint cc;
+
+ if ( (dw->calib_mode_curr_rg == NULL)
+ && (dw->calib_mode_curr_p == NULL) )
+ {
+ dw->calib_mode_curr_rg = dw->image->det->rigid_groups[0];
+ dw->calib_mode_curr_p = dw->calib_mode_curr_rg->panels[0];
+ }
+
+ dw->calibmode_statusbar = gtk_statusbar_new();
+ gtk_widget_show(dw->calibmode_statusbar);
+ vbox = gtk_bin_get_child(GTK_BIN(dw->window));
+ gtk_box_pack_end(GTK_BOX(vbox), dw->calibmode_statusbar,
+ TRUE, TRUE, 0);
+ cc = gtk_statusbar_get_context_id(GTK_STATUSBAR(dw->calibmode_statusbar),
+ "calibmode");
+ gtk_statusbar_push(GTK_STATUSBAR(dw->calibmode_statusbar), cc,
+ "Last clicked position: Not available");
+ displaywindow_update(dw);
+
+ } else {
+
+ gtk_widget_destroy(dw->calibmode_statusbar);
+ dw->calibmode_statusbar = NULL;
+ displaywindow_update(dw);
+
+ }
+
+ return 0;
+}
static gint displaywindow_set_rings(GtkWidget *d, DisplayWindow *dw)
{
@@ -1495,6 +1608,8 @@ static void displaywindow_addmenubar(DisplayWindow *dw, GtkWidget *vbox,
GtkToggleActionEntry toggles[] = {
{ "GeometryAction", NULL, "Use Detector Geometry", NULL, NULL,
G_CALLBACK(displaywindow_set_usegeom), FALSE },
+ { "CalibModeAction", NULL, "Calibration Mode", NULL, NULL,
+ G_CALLBACK(displaywindow_set_calibmode), FALSE },
{ "ColScaleAction", NULL, "Colour Scale", NULL, NULL,
G_CALLBACK(displaywindow_set_colscale), FALSE },
{ "RingsAction", NULL, "Resolution Rings", "F9", NULL,
@@ -1790,6 +1905,39 @@ static gint displaywindow_motion(GtkWidget *widget, GdkEventMotion *event,
}
+static void calibmode_press(DisplayWindow *dw, GdkEventButton *event)
+{
+ int x,y;
+ double dfs, dss;
+ int fs, ss, revmap_return_value;
+ char statusbar_string[80];
+ guint cc;
+
+ cc = gtk_statusbar_get_context_id(GTK_STATUSBAR(dw->calibmode_statusbar),
+ "calibmode");
+
+ x = dw->binning * (event->x);
+ y = dw->binning * (dw->height - 1 - event->y);
+ x += dw->min_x;
+ y += dw->min_x;
+ snprintf(statusbar_string, 80,
+ "Last clicked position: x: %i, y: %i (Not in panel)", x, y);
+
+ revmap_return_value = reverse_2d_mapping(x, y, &dfs, &dss,
+ dw->image->det);
+ if ( revmap_return_value == 0 ) {
+ fs = dfs;
+ ss = dss;
+ snprintf(statusbar_string, 80,
+ "Last clicked position: x: %i, y: %i, fs: %u, ss: %u,"
+ " (panel %s)",
+ x, y, fs, ss, find_panel(dw->image->det, fs, ss)->name);
+ }
+ gtk_statusbar_push(GTK_STATUSBAR(dw->calibmode_statusbar),
+ cc, statusbar_string);
+}
+
+
static gint displaywindow_press(GtkWidget *widget, GdkEventButton *event,
DisplayWindow *dw)
{
@@ -1811,16 +1959,208 @@ static gint displaywindow_press(GtkWidget *widget, GdkEventButton *event,
numbers_update(dw);
}
+ if ( dw->calibmode_statusbar != NULL ) {
+ calibmode_press(dw, event);
+ }
+
}
return 0;
+}
+
+
+static int curr_rg_pointer_index(DisplayWindow *dw)
+{
+ int r;
+ for ( r=0; r<dw->image->det->n_rigid_groups; ++r) {
+ if ( dw->image->det->rigid_groups[r] == dw->calib_mode_curr_rg ) {
+ return r;
+ }
+ }
+
+ // should never be reached. Here just to make the compiler happy
+ return -1;
+}
+
+
+static int curr_p_pointer_index_in_rg(DisplayWindow *dw)
+{
+ int p;
+
+ for ( p=0; p<dw->calib_mode_curr_rg->n_panels; ++p) {
+ if ( dw->calib_mode_curr_rg->panels[p] == dw->calib_mode_curr_p ) {
+ return p;
+ }
+ }
+
+ // should never be reached. Here just to make the compiler happy
+ return -1;
+}
+
+
+static void select_next_group(DisplayWindow *dw, int num_rg)
+{
+ if ( dw->calib_mode_curr_rg == dw->image->det->rigid_groups[num_rg-1] ) {
+ dw->calib_mode_curr_rg = dw->image->det->rigid_groups[0];
+ } else {
+ dw->calib_mode_curr_rg =
+ dw->image->det->rigid_groups[curr_rg_pointer_index(dw)+1];
+ }
+}
+
+
+static void select_prev_group(DisplayWindow *dw, int num_rg)
+{
+ if ( dw->calib_mode_curr_rg == dw->image->det->rigid_groups[0] ) {
+ dw->calib_mode_curr_rg = dw->image->det->rigid_groups[num_rg-1];
+ } else {
+ dw->calib_mode_curr_rg =
+ dw->image->det->rigid_groups[curr_rg_pointer_index(dw)-1];
+ }
+}
+
+
+static void select_next_panel(DisplayWindow *dw, int num_p)
+{
+ if ( dw->calib_mode_curr_p == dw->calib_mode_curr_rg->panels[num_p-1] ) {
+ dw->calib_mode_curr_p = dw->calib_mode_curr_rg->panels[0];
+ } else {
+ dw->calib_mode_curr_p =
+ dw->calib_mode_curr_rg->panels[curr_p_pointer_index_in_rg(dw)+1];
+ }
+}
+
+
+static void select_prev_panel(DisplayWindow *dw, int num_p)
+{
+ if ( dw->calib_mode_curr_p == dw->calib_mode_curr_rg->panels[0] ) {
+ dw->calib_mode_curr_p = dw->calib_mode_curr_rg->panels[num_p-1];
+ } else {
+ dw->calib_mode_curr_p =
+ dw->calib_mode_curr_rg->panels[curr_p_pointer_index_in_rg(dw)-1];
+ }
+}
+
+
+static gint displaywindow_keypress(GtkWidget *widget, GdkEventKey *event,
+ DisplayWindow *dw)
+{
+ int pi, s, num_rg, num_p;
+
+ if ( dw->calib_mode == 0 ) {
+ return 0;
+ }
+
+ num_rg = dw->image->det->n_rigid_groups;
+
+ switch ( event->keyval ) {
+
+ case GDK_Up:
+ case GDK_KP_Up:
+ if ( dw->calib_mode_groups ) {
+ for ( pi=0; pi<dw->calib_mode_curr_rg->n_panels; ++pi ) {
+ dw->calib_mode_curr_rg->panels[pi]->cny += 1.0;
+ }
+ } else {
+ dw->calib_mode_curr_p->cny += 1.0;
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_Down:
+ case GDK_KP_Down:
+ if ( dw->calib_mode_groups ) {
+ for ( pi=0; pi<dw->calib_mode_curr_rg->n_panels; ++pi ) {
+ dw->calib_mode_curr_rg->panels[pi]->cny -= 1.0;
+ }
+ } else {
+ dw->calib_mode_curr_p->cny -= 1.0;
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_Left:
+ case GDK_KP_Left:
+ if ( dw->calib_mode_groups ) {
+ for ( pi=0; pi<dw->calib_mode_curr_rg->n_panels; ++pi ) {
+ dw->calib_mode_curr_rg->panels[pi]->cnx -= 1.0;
+ }
+ } else {
+ dw->calib_mode_curr_p->cnx -= 1.0;
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_Right:
+ case GDK_KP_Right:
+ if ( dw->calib_mode_groups ) {
+ for ( pi=0; pi<dw->calib_mode_curr_rg->n_panels; ++pi ) {
+ dw->calib_mode_curr_rg->panels[pi]->cnx += 1.0;
+ }
+ } else {
+ dw->calib_mode_curr_p->cnx -= 1.0;
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_plus:
+ case GDK_KP_Add:
+ num_p = dw->calib_mode_curr_rg->n_panels;
+ if ( dw->calib_mode_groups ) {
+ select_next_group(dw, num_rg);
+ } else {
+ select_next_panel(dw, num_p);
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_minus:
+ case GDK_KP_Subtract:
+ num_p = dw->calib_mode_curr_rg->n_panels;
+ if ( dw->calib_mode_groups ) {
+ select_prev_group(dw, num_rg);
+ } else {
+ select_prev_panel(dw, num_p);
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_f:
+ dw->calib_mode_show_focus = 1 - dw->calib_mode_show_focus;
+ redraw_window(dw);
+ break;
+
+ case GDK_g:
+ if ( dw->calib_mode_groups ) {
+ dw->calib_mode_groups = 0;
+ dw->calib_mode_curr_p = dw->calib_mode_curr_rg->panels[0];
+ } else {
+ dw->calib_mode_groups = 1;
+ dw->calib_mode_curr_rg = dw->calib_mode_curr_p->rigid_group;
+ }
+ redraw_window(dw);
+ break;
+
+ case GDK_s:
+ s = save_geometry_file(dw);
+ if ( s != 0 ) {
+ if ( s != 2 ) {
+ displaywindow_error(dw,
+ "Unable to save the detector geometry.");
+ }
+ }
+ break;
+
+ }
+
+ return 0;
}
DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
double boost, int binning,
- int noisefilter, int colscale,
+ int noisefilter, int calibmode, int colscale,
const char *element, const char *geometry,
const char *beam,
int show_rings, double *ring_radii,
@@ -1831,6 +2171,7 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
char *title;
GtkWidget *vbox;
GtkWidget *w;
+ GtkWidget *ww;
dw = calloc(1, sizeof(DisplayWindow));
if ( dw == NULL ) return NULL;
@@ -1857,6 +2198,12 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
dw->n_rings = n_rings;
dw->median_filter = median_filter;
dw->image = calloc(1, sizeof(struct image));
+ dw->calib_mode = 0;
+ dw->calib_mode_curr_rg = NULL;
+ dw->calib_mode_curr_p = NULL;
+ dw->calib_mode_show_focus = 1;
+ dw->calib_mode_groups = 1;
+ dw->calibmode_statusbar = NULL;
if ( beam != NULL ) {
dw->image->beam = get_beam_parameters(beam);
@@ -1896,7 +2243,6 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
free(dw);
return NULL;
}
-
dw->loaded_geom = NULL;
dw->simple_geom = simple_geometry(dw->image);
dw->image->det = dw->simple_geom;
@@ -1940,18 +2286,34 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
load_geometry_file(dw, dw->image, geometry);
}
+ if (dw->use_geom == 1) {
+ dw->calib_mode = calibmode;
+ }
+
+ if (dw->calib_mode == 1) {
+ ww = gtk_ui_manager_get_widget(dw->ui,
+ "/ui/displaywindow/tools/calibmode");
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ww), TRUE);
+ }
+
+
displaywindow_update(dw);
gtk_widget_add_events(GTK_WIDGET(dw->drawingarea),
GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
- | GDK_BUTTON1_MOTION_MASK);
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_KEY_PRESS_MASK);
g_object_set(G_OBJECT(dw->drawingarea), "can-focus", TRUE, NULL);
+ gtk_widget_grab_focus(dw->drawingarea);
+
g_signal_connect(GTK_OBJECT(dw->drawingarea), "button-press-event",
G_CALLBACK(displaywindow_press), dw);
g_signal_connect(GTK_OBJECT(dw->drawingarea), "button-release-event",
G_CALLBACK(displaywindow_release), dw);
+ g_signal_connect(GTK_OBJECT(dw->drawingarea), "key-press-event",
+ G_CALLBACK(displaywindow_keypress), dw);
displaywindow_update_menus(dw, element);
dw->not_ready_yet = 0;
diff --git a/src/dw-hdfsee.h b/src/dw-hdfsee.h
index 92ca9d42..b469e79d 100644
--- a/src/dw-hdfsee.h
+++ b/src/dw-hdfsee.h
@@ -10,6 +10,7 @@
* Authors:
* 2009-2012 Thomas White <taw@physics.org>
* 2012 Richard Kirian
+ * 2014 Valerio Mariani
*
* This file is part of CrystFEL.
*
@@ -108,6 +109,13 @@ typedef struct {
double ring_radius;
double *ring_radii;
int n_rings;
+ int calib_mode;
+ struct rigid_group *calib_mode_curr_rg;
+ struct panel *calib_mode_curr_p;
+ int calib_mode_show_focus;
+ int calib_mode_groups;
+
+ GtkWidget *calibmode_statusbar;
int show_col_scale;
int scale;
@@ -119,7 +127,7 @@ typedef struct {
extern DisplayWindow *displaywindow_open(const char *filename,
const char *peaks, double boost,
int binning,
- int noisefilter, int colscale,
+ int noisefilter, int calibmode, int colscale,
const char *element,
const char *geometry, const char *beam,
int show_rings,
diff --git a/src/hdfsee.c b/src/hdfsee.c
index df0bd281..ea6de2b2 100644
--- a/src/hdfsee.c
+++ b/src/hdfsee.c
@@ -3,13 +3,14 @@
*
* Quick yet non-crappy HDF viewer
*
- * Copyright © 2012 Deutsches Elektronen-Synchrotron DESY,
- * a research centre of the Helmholtz Association.
+ * Copyright © 2012-2014 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
* Copyright © 2012 Richard Kirian
*
* Authors:
- * 2009-2012 Thomas White <taw@physics.org>
+ * 2009-2014 Thomas White <taw@physics.org>
* 2012 Richard Kirian
+ * 2014 Valerio Mariani
*
* This file is part of CrystFEL.
*
@@ -61,7 +62,7 @@ static void show_help(const char *s)
" --filter-noise Apply an aggressive noise filter to the\n"
" image data.\n"
" --median-filter=<n> Apply a median filter to the image data.\n"
-
+" --calibration-mode Start in calibration mode\n"
" --show-rings Overlay rings that indicate resolution.\n"
" --simple-rings=XX,YY,... Overlay rings at specified radii XX, YY, ...\n"
" in pixel units.\n"
@@ -115,6 +116,7 @@ int main(int argc, char *argv[])
int binning = 2;
int config_noisefilter = 0;
int config_showrings = 0;
+ int config_calibmode =0;
int colscale = SCALE_COLOUR;
char *cscale = NULL;
char *element = NULL;
@@ -141,6 +143,7 @@ int main(int argc, char *argv[])
{"ring-size", 1, NULL, 2},
{"simple-rings", 1, NULL, 'r'},
{"median-filter", 1, NULL, 3},
+ {"calibration-mode", 0, &config_calibmode, 1},
{0, 0, NULL, 0}
};
@@ -276,6 +279,7 @@ int main(int argc, char *argv[])
main_window_list[i] = displaywindow_open(argv[optind+i], peaks,
boost, binning,
config_noisefilter,
+ config_calibmode,
colscale, element,
geometry, beam,
config_showrings,