aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2022-08-23 15:56:57 +0200
committerThomas White <taw@physics.org>2022-08-23 16:07:44 +0200
commit4464b2fc8d2840d489a839e4973fab1e71144efc (patch)
tree40efb8a10f7ed0e0ba5cb2b11a257ef6bd08b3b7
parent1179bed2ebc892dc918aae09dae586c516d0e36e (diff)
GUI: Add resolution rings
It will refuse to draw the rings if the detector is too far from being flat (as judged by detgeom_mean_camera_length). Otherwise, the drawing is exactly the same as was done by hdfsee.
-rw-r--r--ChangeLog1
-rw-r--r--src/crystfel_gui.c33
-rw-r--r--src/crystfelimageview.c70
-rw-r--r--src/crystfelimageview.h4
-rw-r--r--src/gui_project.c6
-rw-r--r--src/gui_project.h1
6 files changed, 115 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 6110e4f3..de38c04b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,7 @@ Changes in this development version
- partialator: Use default event ID when none given in --custom-split
- Dropped support for pre-2015 stream formats
- Recognise '.nx5' as HDF5
+- GUI: Optionally show resolution rings
- GUI: Use sbatch/scancel/scontrol instead of SLURM API
- GUI: Honour fixed profile radius for single frame indexing (#61)
- GUI: Better handling of error-filled indexamajig logs
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c
index 066422a3..1c439b18 100644
--- a/src/crystfel_gui.c
+++ b/src/crystfel_gui.c
@@ -275,6 +275,8 @@ void update_imageview(struct crystfelproject *proj)
proj->show_peaks);
crystfel_image_view_set_show_centre(CRYSTFEL_IMAGE_VIEW(proj->imageview),
proj->show_centre);
+ crystfel_image_view_set_resolution_rings(CRYSTFEL_IMAGE_VIEW(proj->imageview),
+ proj->resolution_rings);
crystfel_image_view_set_image(CRYSTFEL_IMAGE_VIEW(proj->imageview),
proj->cur_image);
@@ -670,6 +672,30 @@ static gint show_centre_sig(GtkWidget *w, struct crystfelproject *proj)
}
+static gint resolution_rings_sig(GtkWidget *w, struct crystfelproject *proj)
+{
+ int tr = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
+
+ if ( tr && proj->cur_image == NULL ) {
+ error_box(proj, "Load some images first!\n");
+ return FALSE;
+ }
+
+ if ( tr && isnan(detgeom_mean_camera_length(proj->cur_image->detgeom)) ) {
+ error_box(proj, "Cannot display resolution rings accurately "
+ "because detector is not flat enough");
+ tr = FALSE;
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(w), FALSE);
+ }
+
+ proj->resolution_rings = tr;
+ crystfel_image_view_set_resolution_rings(CRYSTFEL_IMAGE_VIEW(proj->imageview),
+ tr);
+
+ return FALSE;
+}
+
+
static gint show_peaks_sig(GtkWidget *w, struct crystfelproject *proj)
{
proj->show_peaks = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
@@ -711,6 +737,7 @@ static void add_menu_bar(struct crystfelproject *proj, GtkWidget *vbox)
" <menuitem name=\"refls\" action=\"ReflsAction\" />"
" <menuitem name=\"labelrefls\" action=\"LabelReflsAction\" />"
" <menuitem name=\"centre\" action=\"CentreAction\" />"
+ " <menuitem name=\"resrings\" action=\"ResolutionRingsAction\" />"
" <separator />"
" <menuitem name=\"resetzoom\" action=\"ResetZoomAction\" />"
"</menu>"
@@ -757,6 +784,8 @@ static void add_menu_bar(struct crystfelproject *proj, GtkWidget *vbox)
G_CALLBACK(label_refls_sig), FALSE },
{ "CentreAction", NULL, "Beam centre", NULL, NULL,
G_CALLBACK(show_centre_sig), FALSE },
+ { "ResolutionRingsAction", NULL, "Resolution rings", NULL, NULL,
+ G_CALLBACK(resolution_rings_sig), FALSE },
{ "RescanOnChangeAction", NULL, "Rescan streams when changing frame", NULL, NULL,
G_CALLBACK(rescan_on_change_sig), FALSE },
};
@@ -1165,6 +1194,10 @@ int main(int argc, char *argv[])
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act),
proj.label_refls);
+ act = gtk_ui_manager_get_action(proj.ui, "/mainwindow/view/resrings");
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act),
+ proj.resolution_rings);
+
act = gtk_ui_manager_get_action(proj.ui, "/mainwindow/tools/rescanonchange");
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act),
proj.rescan_on_change);
diff --git a/src/crystfelimageview.c b/src/crystfelimageview.c
index 74d8cca5..88cfb149 100644
--- a/src/crystfelimageview.c
+++ b/src/crystfelimageview.c
@@ -603,6 +603,48 @@ static void draw_refls(cairo_t *cr,
}
+static double ring_radius(double d, double wl, double z)
+{
+ double theta = asin(wl / (2.0*d));
+ return z * tan(2.0*theta);
+}
+
+
+static void show_ring(cairo_t *cr, double wl, double mean_z,
+ double d, const char *label,
+ double r, double g, double b)
+{
+ cairo_text_extents_t size;
+ double bs, lw;
+ double radius = ring_radius(d, wl, mean_z);
+
+ if ( isnan(radius) ) return;
+
+ bs = 17.0;
+ lw = 1.0;
+ cairo_device_to_user_distance(cr, &bs, &lw);
+ bs = fabs(bs);
+ lw = fabs(lw);
+
+ cairo_save(cr);
+
+ cairo_arc(cr, 0.0, 0.0, radius, 0.0, 2.0*M_PI);
+ cairo_set_source_rgb(cr, r, g, b);
+ cairo_set_line_width(cr, lw);
+ cairo_stroke(cr);
+
+ cairo_rotate(cr, -M_PI/4.0);
+ cairo_scale(cr, 1.0, -1.0);
+ cairo_set_font_size(cr, bs);
+ cairo_text_extents(cr, label, &size);
+ cairo_translate(cr, -size.width/2.0, radius-5.0*lw);
+ cairo_show_text(cr, label);
+ cairo_fill(cr);
+
+ cairo_restore(cr);
+}
+
+
static double crystal_cols[][3] =
{
{0.0, 1.0, 0.0}, /* bright green */
@@ -673,6 +715,24 @@ static gint draw_sig(GtkWidget *window, cairo_t *cr, CrystFELImageView *iv)
}
}
+ if ( iv->resolution_rings ) {
+ double wl = iv->image->lambda;
+ double mean_z = detgeom_mean_camera_length(iv->image->detgeom);
+ if ( !isnan(mean_z) ) {
+ show_ring(cr, wl, mean_z, 10.0e-10, "10A", 1.0, 0.0, 0.0);
+ show_ring(cr, wl, mean_z, 9.0e-10, "9A", 1.0, 0.0, 0.0);
+ show_ring(cr, wl, mean_z, 8.0e-10, "8A", 1.0, 0.0, 0.0);
+ show_ring(cr, wl, mean_z, 7.0e-10, "7A", 1.0, 0.5, 0.0);
+ show_ring(cr, wl, mean_z, 6.0e-10, "6A", 1.0, 1.0, 0.0);
+ show_ring(cr, wl, mean_z, 5.0e-10, "5A", 0.0, 1.0, 0.0);
+ show_ring(cr, wl, mean_z, 4.0e-10, "4A", 0.2, 1.0, 0.2);
+ show_ring(cr, wl, mean_z, 3.0e-10, "3A", 0.4, 1.0, 0.4);
+ show_ring(cr, wl, mean_z, 2.0e-10, "2A", 0.6, 1.0, 0.6);
+ show_ring(cr, wl, mean_z, 1.0e-10, "1A", 0.8, 1.0, 0.8);
+ show_ring(cr, wl, mean_z, 0.5e-10, "0.5A", 1.0, 1.0, 1.0);
+ }
+ }
+
cairo_restore(cr);
return FALSE;
@@ -847,6 +907,7 @@ GtkWidget *crystfel_image_view_new()
iv->label_refls = 1;
iv->need_rerender = 0;
iv->need_recentre = 1;
+ iv->resolution_rings = 0;
g_signal_connect(G_OBJECT(iv), "destroy",
G_CALLBACK(destroy_sig), iv);
@@ -1165,3 +1226,12 @@ void crystfel_image_view_set_refl_box_size(CrystFELImageView *iv,
iv->need_rerender = 1;
redraw(iv);
}
+
+
+void crystfel_image_view_set_resolution_rings(CrystFELImageView *iv,
+ int rings)
+{
+ iv->resolution_rings = rings;
+ iv->need_rerender = 1;
+ redraw(iv);
+}
diff --git a/src/crystfelimageview.h b/src/crystfelimageview.h
index c53e4980..aa7d61d2 100644
--- a/src/crystfelimageview.h
+++ b/src/crystfelimageview.h
@@ -94,6 +94,7 @@ struct _crystfelimageview
int label_refls;
float peak_box_size;
float refl_box_size;
+ int resolution_rings;
};
struct _crystfelimageviewclass
@@ -133,4 +134,7 @@ extern void crystfel_image_view_set_peak_box_size(CrystFELImageView *iv,
extern void crystfel_image_view_set_refl_box_size(CrystFELImageView *iv,
float box_size);
+extern void crystfel_image_view_set_resolution_rings(CrystFELImageView *iv,
+ int rings);
+
#endif /* CRYSTFELIMAGEVIEW_H */
diff --git a/src/gui_project.c b/src/gui_project.c
index 7ab4e367..00a217af 100644
--- a/src/gui_project.c
+++ b/src/gui_project.c
@@ -534,6 +534,10 @@ static void handle_var(const char *key, const char *val,
proj->show_centre = parse_int(val);
}
+ if ( strcmp(key, "resolution_rings") == 0 ) {
+ proj->resolution_rings = parse_int(val);
+ }
+
if ( strcmp(key, "rescan_on_change") == 0 ) {
proj->rescan_on_change = parse_int(val);
}
@@ -1136,6 +1140,7 @@ int save_project(struct crystfelproject *proj)
}
fprintf(fh, "show_centre %i\n", proj->show_centre);
+ fprintf(fh, "resolution_rings %i\n", proj->resolution_rings);
fprintf(fh, "show_peaks %i\n", proj->show_peaks);
fprintf(fh, "show_refls %i\n", proj->show_refls);
fprintf(fh, "label_refls %i\n", proj->label_refls);
@@ -1229,6 +1234,7 @@ int default_project(struct crystfelproject *proj)
/* Default parameter values */
proj->show_centre = 1;
+ proj->resolution_rings = 0;
proj->show_peaks = 1;
proj->show_refls = 1;
proj->label_refls = 1;
diff --git a/src/gui_project.h b/src/gui_project.h
index 8ec81ee2..546bae9a 100644
--- a/src/gui_project.h
+++ b/src/gui_project.h
@@ -302,6 +302,7 @@ struct crystfelproject {
char **filenames;
char **events;
int show_centre;
+ int resolution_rings;
int rescan_on_change;
int show_peaks;