aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2022-12-07 16:59:23 +0100
committerThomas White <taw@physics.org>2022-12-13 17:10:16 +0100
commit55d3d665c140621497d1aec44c80deb3f0e614d1 (patch)
treeac54809289ce52174cc01a856392f837d164937c
parent6379e859edfa6003acca688ecabf09a55dfa05d8 (diff)
GUI: FoM graph, part 3: x-axis
-rw-r--r--src/crystfelfomgraph.c212
-rw-r--r--src/crystfelfomgraph.h7
-rw-r--r--src/gui_fom.c8
3 files changed, 225 insertions, 2 deletions
diff --git a/src/crystfelfomgraph.c b/src/crystfelfomgraph.c
index f8457808..ade0fa62 100644
--- a/src/crystfelfomgraph.c
+++ b/src/crystfelfomgraph.c
@@ -60,14 +60,205 @@ static gint configure_sig(GtkWidget *window, GdkEventConfigure *rec,
}
+static void fom_colour(enum fom_type t, double *col)
+{
+ switch ( t ) {
+ case FOM_R1I :
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_R1F:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_R2:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_RSPLIT:
+ col[0] = 0.5; col[1] = 0.0; col[2] = 0.5; break;
+ case FOM_CC:
+ col[0] = 0.0; col[1] = 0.0; col[2] = 0.3; break;
+ case FOM_CCSTAR:
+ col[0] = 0.0; col[1] = 0.0; col[2] = 0.5; break;
+ case FOM_CCANO:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_CRDANO:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_RANO:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_RANORSPLIT:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_D1SIG:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_D2SIG:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_REDUNDANCY:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_SNR:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ case FOM_COMPLETENESS:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ default:
+ col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; break;
+ }
+}
+
+
+static void fom_range(enum fom_type t, double *min, double *max)
+{
+ switch ( t ) {
+ case FOM_R1I: *min = 0.0; *max = 0.8; break;
+ case FOM_R1F: *min = 0.0; *max = 0.8; break;
+ case FOM_R2: *min = 0.0; *max = 0.8; break;
+ case FOM_RSPLIT: *min = 0.0; *max = 0.8; break;
+ case FOM_CC: *min = 0.9; *max = 1.0; break;
+ case FOM_CCSTAR: *min = 0.9; *max = 1.0; break;
+ case FOM_CCANO: *min = 0.9; *max = 1.0; break;
+ case FOM_CRDANO: *min = 0.9; *max = 1.0; break;
+ case FOM_RANO: *min = 0.0; *max = 0.7; break;
+ case FOM_RANORSPLIT: *min = 0.0; *max = 8.0; break;
+ case FOM_D1SIG: *min = 0.0; *max = 1.0; break;
+ case FOM_D2SIG: *min = 0.0; *max = 1.0; break;
+ case FOM_REDUNDANCY: *min = 0.0; *max = 100; break;
+ case FOM_SNR: *min = 0.0; *max = 10.0; break;
+ case FOM_COMPLETENESS: *min = 0.0; *max = 1.0; break;
+ default: *min = 0.0; *max = 1.0; break;
+ }
+}
+
+
+static void draw_x_axis(cairo_t *cr, double *tics, int n_tics,
+ double x1, double x2, double ox, double w, double axsp)
+{
+ int i;
+
+ cairo_new_path(cr);
+ cairo_move_to(cr, ox, axsp);
+ cairo_line_to(cr, w, axsp);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+
+ for ( i=0; i<15; i++ ) {
+
+ cairo_text_extents_t ext;
+ char label[128];
+ double x;
+
+ if ( (1e10/tics[i] > x1) && (1e10/tics[i] < x2) ) {
+
+ x = ox + (w-ox) * (1e10/tics[i]-x1)/(x2-x1);
+
+ cairo_move_to(cr, x, axsp);
+ cairo_line_to(cr, x, axsp-5.0);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+
+ cairo_save(cr);
+ snprintf(label, 127, "%.1f A", tics[i]);
+ cairo_text_extents(cr, label, &ext);
+ cairo_move_to(cr, x-ext.x_advance/2, -3.0);
+ cairo_scale(cr, 1.0, -1.0);
+ cairo_show_text(cr, label);
+ cairo_restore(cr);
+
+ }
+ }
+}
+
+
+static void draw_y_axis(cairo_t *cr, double h, double oy,
+ double y1, double y2)
+{
+ int i;
+
+ cairo_new_path(cr);
+ cairo_move_to(cr, oy, oy);
+ cairo_line_to(cr, oy, h);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+
+ for ( i=0; i<5; i++ ) {
+
+ cairo_text_extents_t ext;
+ char label[128];
+ double y;
+
+ y = oy + (h-oy) * i*(y2-y1)/5.0;
+
+ cairo_move_to(cr, 0.0, y);
+ cairo_line_to(cr, -5.0, y);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+
+ cairo_save(cr);
+ snprintf(label, 127, "%.1f", y);
+ cairo_text_extents(cr, label, &ext);
+ cairo_move_to(cr, -ext.x_advance-3.0, y-ext.y_advance/2.0);
+ cairo_scale(cr, 1.0, -1.0);
+ cairo_show_text(cr, label);
+ cairo_restore(cr);
+
+ }
+}
+
+
static gint draw_sig(GtkWidget *window, cairo_t *cr, CrystFELFoMGraph *fg)
{
+ int j;
+
cairo_save(cr);
/* Overall background */
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_paint(cr);
+ double border = 10.0;
+ double w = fg->visible_width;
+ double h = fg->visible_height;
+ double axsp = 20.0;
+ double x1 = fg->shell_centers[0];
+ double x2 = fg->shell_centers[fg->n_shells-1];
+
+ /* Logical coordinates */
+ cairo_translate(cr, 0.0, h);
+ cairo_scale(cr, 1.0, -1.0);
+
+ /* Add empty border */
+ cairo_translate(cr, border, border);
+ w -= border*2.0;
+ h -= border*2.0;
+
+ /* y-axes (multiple) */
+ double ox = 0.0;
+ cairo_save(cr);
+ for ( j=0; j<fg->n_foms; j++ ) {
+ double col[3];
+ double y1, y2;
+ fom_colour(fg->fom_types[j], col);
+ fom_range(fg->fom_types[j], &y1, &y2);
+ cairo_set_source_rgb(cr, col[0], col[1], col[2]);
+ draw_y_axis(cr, h, axsp, y1, y2);
+ ox += axsp;
+ cairo_translate(cr, axsp, 0.0);
+ }
+ cairo_restore(cr);
+
+ /* x-axis */
+ double tics[] = {20.0, 15.0, 10.0, 5.0, 4.0, 3.0, 2.5, 2.0, 1.7, 1.5,
+ 1.4, 1.3, 1.2, 1.1, 1.0};
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ draw_x_axis(cr, tics, 15, x1, x2, ox, w, axsp);
+
+ //for ( j=0; j<fg->n_foms; j++ ) {
+ // int i;
+ // double col[3];
+ // cairo_new_path(cr);
+ // cairo_move_to(cr, aw*fg->shell_centers[0]/mx,
+ // ah*fg->fom_values[j][0]/my);
+ // for ( i=1; i<fg->n_shells; i++ ) {
+ // cairo_line_to(cr, aw*fg->shell_centers[i]/mx,
+ // ah*fg->fom_values[j][i]/my);
+ // }
+ // cairo_set_line_width(cr, 1.0);
+ // fom_colour(fg->fom_types[j], col);
+ // cairo_set_source_rgb(cr, col[0], col[1], col[2]);
+ // cairo_stroke(cr);
+ //}
cairo_restore(cr);
@@ -115,6 +306,12 @@ GtkWidget *crystfel_fom_graph_new()
fg = g_object_new(CRYSTFEL_TYPE_FOM_GRAPH, NULL);
+ fg->n_shells = 0;
+ fg->shell_centers = NULL;
+ fg->n_foms = 0;
+ fg->fom_types = NULL;
+ fg->fom_values = NULL;
+
g_signal_connect(G_OBJECT(fg), "destroy",
G_CALLBACK(destroy_sig), fg);
g_signal_connect(G_OBJECT(fg), "configure-event",
@@ -135,4 +332,19 @@ void crystfel_fom_graph_set_data(CrystFELFoMGraph *fg,
enum fom_type *fom_types, double **fom_values,
int n_foms)
{
+ int i;
+ for ( i=0; i<fg->n_foms; i++ ) {
+ free(fg->fom_values[i]);
+ }
+ free(fg->shell_centers);
+ free(fg->fom_types);
+ free(fg->fom_values);
+
+ fg->n_shells = n_shells;
+ fg->shell_centers = shell_centers;
+ fg->n_foms = n_foms;
+ fg->fom_types = fom_types;
+ fg->fom_values= fom_values;
+
+ gtk_widget_queue_draw(GTK_WIDGET(fg));
}
diff --git a/src/crystfelfomgraph.h b/src/crystfelfomgraph.h
index ebe1e1ba..98c10cd1 100644
--- a/src/crystfelfomgraph.h
+++ b/src/crystfelfomgraph.h
@@ -61,6 +61,13 @@ struct _crystfelfomgraph
GtkDrawingArea parent_instance;
double visible_width;
double visible_height;
+
+ int n_shells;
+ double *shell_centers;
+
+ int n_foms;
+ enum fom_type *fom_types;
+ double **fom_values;
};
struct _crystfelfomgraphclass
diff --git a/src/gui_fom.c b/src/gui_fom.c
index 3aaa3602..37a8bf52 100644
--- a/src/gui_fom.c
+++ b/src/gui_fom.c
@@ -420,7 +420,9 @@ static void fom_response_sig(GtkWidget *dialog, gint resp,
double *shell_centers = malloc(shells->nshells*sizeof(double));
double **fom_values = malloc(f->n_foms*sizeof(double *));
+ enum fom_type *fom_types = malloc(f->n_foms*sizeof(enum fom_type));
+ int fomi = 0;
for ( fom=0; fom<f->n_foms; fom++ ) {
struct fom_context *fctx;
@@ -439,14 +441,16 @@ static void fom_response_sig(GtkWidget *dialog, gint resp,
}
show_fom(f->fom_types[fom], fctx, shells);
- fom_values[fom] = make_fom_vals(fctx, shells);
+ fom_types[fomi] = f->fom_types[fom];
+ fom_values[fomi] = make_fom_vals(fctx, shells);
+ fomi++;
}
shell_centers = make_shell_centers(shells);
crystfel_fom_graph_set_data(CRYSTFEL_FOM_GRAPH(f->graph),
shell_centers, shells->nshells,
- f->fom_types, fom_values, f->n_foms);
+ fom_types, fom_values, fomi);
reflist_free(all_refls);
reflist_free(all_refls_anom);