aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2020-11-20 17:34:47 +0100
committerThomas White <taw@physics.org>2020-11-20 17:36:49 +0100
commite9087293e5b7b92e64cb9cb7636e21f52611ac7c (patch)
tree8450d81e5defccaa3e49e6ba5ef3710134f93d35 /src
parentc570bbe16cb68cfb340e4ce3bc8c66831a08a306 (diff)
GUI: Add stream output options including metadata to copy
Diffstat (limited to 'src')
-rw-r--r--src/crystfelindexingopts.c248
-rw-r--r--src/crystfelindexingopts.h24
-rw-r--r--src/gui_index.c49
-rw-r--r--src/gui_project.c55
-rw-r--r--src/gui_project.h7
5 files changed, 363 insertions, 20 deletions
diff --git a/src/crystfelindexingopts.c b/src/crystfelindexingopts.c
index b7b0e9ba..0b6cf515 100644
--- a/src/crystfelindexingopts.c
+++ b/src/crystfelindexingopts.c
@@ -43,6 +43,7 @@
#include <index.h>
#include "crystfelindexingopts.h"
+#include "gtk-util-routines.h"
G_DEFINE_TYPE(CrystFELIndexingOpts,
@@ -460,6 +461,126 @@ static GtkWidget *integration_parameters(CrystFELIndexingOpts *io)
}
+static void add_metadata_item(GtkListStore *model, const char *string)
+{
+ GtkTreeIter iter;
+ gtk_list_store_append(model, &iter);
+ gtk_list_store_set(model, &iter, 0, strdup(string), -1);
+}
+
+
+static gboolean add_metadata_sig(GtkWidget *button, GtkListStore *model)
+{
+ add_metadata_item(model, "/instrument/something");
+ return FALSE;
+}
+
+
+static gboolean edit_metadata_sig(GtkCellRendererText *cell,
+ const gchar *path_str,
+ const gchar *new_text,
+ GtkListStore *model)
+{
+ GtkTreeIter iter;
+ gchar *old_text;
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
+ gtk_tree_path_free(path);
+ gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &old_text, -1);
+ g_free(old_text);
+ gtk_list_store_set(model, &iter,
+ 0, g_strdup(new_text),
+ -1);
+ return FALSE;
+}
+
+
+static gboolean remove_metadata_sig(GtkWidget *button,
+ GtkTreeView *treeview)
+{
+ GtkTreeSelection *sel;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model(treeview);
+ sel = gtk_tree_view_get_selection(treeview);
+ if ( gtk_tree_selection_get_selected(sel, NULL, &iter) != 0 ) {
+ gchar *old_text;
+ gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &old_text, -1);
+ g_free(old_text);
+ gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+ }
+
+ return FALSE;
+}
+
+
+static GtkWidget *stream_parameters(CrystFELIndexingOpts *io)
+{
+ GtkWidget *box;
+ GtkWidget *treeview;
+ GtkCellRenderer *renderer;
+ GtkWidget *button;
+ GtkWidget *hbox;
+
+ box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
+ gtk_container_set_border_width(GTK_CONTAINER(box), 8);
+
+ /* --no-non-hits-in-stream */
+ io->exclude_nonhits = gtk_check_button_new_with_label("Exclude skipped frames from stream");
+ gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(io->exclude_nonhits),
+ FALSE, FALSE, 0);
+
+ /* --no-peaks-in-stream */
+ io->no_peaks_in_stream = gtk_check_button_new_with_label("Exclude peak search results from stream");
+ gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(io->no_peaks_in_stream),
+ FALSE, FALSE, 0);
+
+ /* --no-refls-in-stream */
+ io->no_refls_in_stream = gtk_check_button_new_with_label("Exclude integrated intensities from stream");
+ gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(io->no_refls_in_stream),
+ FALSE, FALSE, 0);
+
+ io->copy_metadata_store = gtk_list_store_new(1, G_TYPE_STRING);
+
+ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(io->copy_metadata_store));
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "editable", TRUE, NULL);
+ g_signal_connect(G_OBJECT(renderer), "edited",
+ G_CALLBACK(edit_metadata_sig),
+ io->copy_metadata_store);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
+ -1,
+ "Metadata to copy to stream",
+ renderer,
+ "text", 0,
+ NULL);
+
+ gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(treeview),
+ FALSE, FALSE, 0);
+
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 8);
+ button = gtk_button_new_from_icon_name("list-add", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_label(GTK_BUTTON(button), "Add item");
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(add_metadata_sig), io->copy_metadata_store);
+ gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(button),
+ FALSE, FALSE, 0);
+ button = gtk_button_new_from_icon_name("list-remove", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_label(GTK_BUTTON(button), "Remove item");
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(remove_metadata_sig), treeview);
+ gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(button),
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(hbox),
+ FALSE, FALSE, 0);
+
+ return box;
+}
+
+
GtkWidget *crystfel_indexing_opts_new()
{
CrystFELIndexingOpts *io;
@@ -476,6 +597,10 @@ GtkWidget *crystfel_indexing_opts_new()
integration_parameters(io),
gtk_label_new("Integration"));
+ io->stream_params = stream_parameters(io);
+ gtk_notebook_append_page(GTK_NOTEBOOK(io), io->stream_params,
+ gtk_label_new("Stream contents"));
+
return GTK_WIDGET(io);
}
@@ -671,6 +796,83 @@ float crystfel_indexing_opts_get_push_res(CrystFELIndexingOpts *opts)
}
+void crystfel_indexing_opts_get_integration_radii(CrystFELIndexingOpts *opts,
+ float *ir_inn,
+ float *ir_mid,
+ float *ir_out)
+{
+ *ir_inn = get_float(opts->ir_inn);
+ *ir_mid = get_float(opts->ir_mid);
+ *ir_out = get_float(opts->ir_out);
+}
+
+
+int crystfel_indexing_opts_get_exclude_blanks(CrystFELIndexingOpts *opts)
+{
+ return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(opts->exclude_nonhits));
+}
+
+
+int crystfel_indexing_opts_get_exclude_peaks(CrystFELIndexingOpts *opts)
+{
+ return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(opts->no_peaks_in_stream));
+}
+
+
+int crystfel_indexing_opts_get_exclude_reflections(CrystFELIndexingOpts *opts)
+{
+ return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(opts->no_refls_in_stream));
+}
+
+
+char **crystfel_indexing_opts_get_metadata_to_copy(CrystFELIndexingOpts *opts,
+ int *pn)
+{
+ GtkTreeIter iter;
+ gboolean r;
+ int n, i;
+ char **arr;
+
+ n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(opts->copy_metadata_store),
+ NULL);
+
+ arr = malloc(n*sizeof(char *));
+ if ( arr == NULL ) return NULL;
+
+ r = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(opts->copy_metadata_store),
+ &iter);
+ if ( r == FALSE ) return NULL;
+
+ i = 0;
+ do {
+ gchar *header;
+ gtk_tree_model_get(GTK_TREE_MODEL(opts->copy_metadata_store),
+ &iter, 0, &header, -1);
+ if ( i == n ) return NULL;
+ arr[i++] = strdup(header);
+ } while ( gtk_tree_model_iter_next(GTK_TREE_MODEL(opts->copy_metadata_store),
+ &iter) != FALSE );
+
+ *pn = n;
+ return arr;
+}
+
+
+/********************** Setters *************************/
+
+
+void crystfel_indexing_opts_set_show_stream_opts(CrystFELIndexingOpts *opts,
+ int val)
+{
+ opts->show_stream_opts = val;
+ if ( val ) {
+ gtk_widget_show_all(opts->stream_params);
+ } else {
+ gtk_widget_hide(opts->stream_params);
+ }
+}
+
+
void crystfel_indexing_opts_set_cell_file(CrystFELIndexingOpts *opts,
const char *cell_file)
{
@@ -878,27 +1080,39 @@ void crystfel_indexing_opts_set_integration_radii(CrystFELIndexingOpts *opts,
}
-static void get_float_val(GtkEntry *entry, float *pval)
+void crystfel_indexing_opts_set_metadata_to_copy(CrystFELIndexingOpts *opts,
+ char *const *headers,
+ int n)
{
- float val;
- char *rval;
- const gchar *text = gtk_entry_get_text(entry);
- errno = 0;
- val = strtod(text, &rval);
- if ( *rval != '\0' ) {
- printf("Invalid integration radius '%s'\n", text);
- } else {
- *pval = val;
+ int i;
+ gtk_list_store_clear(opts->copy_metadata_store);
+ if ( headers == NULL ) return;
+ for ( i=0; i<n; i++ ) {
+ add_metadata_item(opts->copy_metadata_store,
+ headers[i]);
}
}
-void crystfel_indexing_opts_get_integration_radii(CrystFELIndexingOpts *opts,
- float *ir_inn,
- float *ir_mid,
- float *ir_out)
+void crystfel_indexing_opts_set_exclude_blanks(CrystFELIndexingOpts *opts,
+ int flag)
+{
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opts->exclude_nonhits),
+ flag);
+}
+
+
+void crystfel_indexing_opts_set_exclude_peaks(CrystFELIndexingOpts *opts,
+ int flag)
+{
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opts->no_peaks_in_stream),
+ flag);
+}
+
+
+void crystfel_indexing_opts_set_exclude_reflections(CrystFELIndexingOpts *opts,
+ int flag)
{
- get_float_val(GTK_ENTRY(opts->ir_inn), ir_inn);
- get_float_val(GTK_ENTRY(opts->ir_mid), ir_mid);
- get_float_val(GTK_ENTRY(opts->ir_out), ir_out);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opts->no_refls_in_stream),
+ flag);
}
diff --git a/src/crystfelindexingopts.h b/src/crystfelindexingopts.h
index 32c8de44..f5b8ad8c 100644
--- a/src/crystfelindexingopts.h
+++ b/src/crystfelindexingopts.h
@@ -54,6 +54,9 @@ struct _crystfelindexingopts
GtkNotebook parent_instance;
/*< private >*/
+ int show_stream_opts;
+ GtkWidget *stream_params; /* Stream output page */
+
char *cell_file;
GtkWidget *cell_chooser;
GtkWidget *auto_indm;
@@ -76,6 +79,11 @@ struct _crystfelindexingopts
GtkWidget *ir_inn;
GtkWidget *ir_mid;
GtkWidget *ir_out;
+
+ GtkWidget *exclude_nonhits;
+ GtkWidget *no_peaks_in_stream;
+ GtkWidget *no_refls_in_stream;
+ GtkListStore *copy_metadata_store;
};
struct _crystfelindexingoptsclass
@@ -107,7 +115,14 @@ extern void crystfel_indexing_opts_get_integration_radii(CrystFELIndexingOpts *o
float *ir_inn,
float *ir_mid,
float *ir_out);
+extern int crystfel_indexing_opts_get_exclude_blanks(CrystFELIndexingOpts *opts);
+extern int crystfel_indexing_opts_get_exclude_peaks(CrystFELIndexingOpts *opts);
+extern int crystfel_indexing_opts_get_exclude_reflections(CrystFELIndexingOpts *opts);
+extern char **crystfel_indexing_opts_get_metadata_to_copy(CrystFELIndexingOpts *opts,
+ int *n);
+extern void crystfel_indexing_opts_set_show_stream_opts(CrystFELIndexingOpts *opts,
+ int val);
extern void crystfel_indexing_opts_set_cell_file(CrystFELIndexingOpts *opts,
const char *cell_file);
@@ -138,5 +153,14 @@ extern void crystfel_indexing_opts_set_integration_radii(CrystFELIndexingOpts *o
float ir_inn,
float ir_mid,
float ir_out);
+extern void crystfel_indexing_opts_set_metadata_to_copy(CrystFELIndexingOpts *opts,
+ char *const *headers,
+ int n_headers);
+extern void crystfel_indexing_opts_set_exclude_blanks(CrystFELIndexingOpts *opts,
+ int flag);
+extern void crystfel_indexing_opts_set_exclude_peaks(CrystFELIndexingOpts *opts,
+ int flag);
+extern void crystfel_indexing_opts_set_exclude_reflections(CrystFELIndexingOpts *opts,
+ int flag);
#endif /* CRYSTFELINDEXINGOPTS_H */
diff --git a/src/gui_index.c b/src/gui_index.c
index 96c7117f..e260ac12 100644
--- a/src/gui_index.c
+++ b/src/gui_index.c
@@ -184,6 +184,13 @@ static void get_indexing_opts(struct crystfelproject *proj,
&proj->indexing_params.ir_inn,
&proj->indexing_params.ir_mid,
&proj->indexing_params.ir_out);
+
+ /* Stream output */
+ proj->indexing_params.exclude_nonhits = crystfel_indexing_opts_get_exclude_blanks(opts);
+ proj->indexing_params.exclude_peaks = crystfel_indexing_opts_get_exclude_peaks(opts);
+ proj->indexing_params.exclude_refls = crystfel_indexing_opts_get_exclude_reflections(opts);
+ proj->indexing_params.metadata_to_copy = crystfel_indexing_opts_get_metadata_to_copy(opts,
+ &proj->indexing_params.n_metadata);
}
@@ -410,6 +417,17 @@ static void set_indexing_opts(struct crystfelproject *proj,
proj->indexing_params.ir_inn,
proj->indexing_params.ir_mid,
proj->indexing_params.ir_out);
+
+ /* Stream output */
+ crystfel_indexing_opts_set_exclude_blanks(opts,
+ proj->indexing_params.exclude_nonhits);
+ crystfel_indexing_opts_set_exclude_peaks(opts,
+ proj->indexing_params.exclude_peaks);
+ crystfel_indexing_opts_set_exclude_reflections(opts,
+ proj->indexing_params.exclude_refls);
+ crystfel_indexing_opts_set_metadata_to_copy(opts,
+ proj->indexing_params.metadata_to_copy,
+ proj->indexing_params.n_metadata);
}
@@ -452,6 +470,8 @@ gint index_all_sig(GtkWidget *widget, struct crystfelproject *proj)
gtk_container_set_border_width(GTK_CONTAINER(content_area), 8);
proj->indexing_opts = crystfel_indexing_opts_new();
+ crystfel_indexing_opts_set_show_stream_opts(CRYSTFEL_INDEXING_OPTS(proj->indexing_opts),
+ TRUE);
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(proj->indexing_opts),
FALSE, FALSE, 8.0);
set_indexing_opts(proj,
@@ -701,7 +721,8 @@ gint index_one_sig(GtkWidget *widget, struct crystfelproject *proj)
gtk_dialog_set_default_response(GTK_DIALOG(dialog),
GTK_RESPONSE_OK);
gtk_widget_show_all(dialog);
-
+ crystfel_indexing_opts_set_show_stream_opts(CRYSTFEL_INDEXING_OPTS(proj->indexing_opts),
+ FALSE);
return FALSE;
}
@@ -732,6 +753,20 @@ static void add_arg_int(char **args, int pos, const char *label,
}
+static void add_arg_string(char **args, int pos, const char *label,
+ const char *val)
+{
+ size_t len;
+ char *str;
+
+ len = strlen(label)+strlen(val)+4;
+ str = malloc(len);
+ if ( str == NULL ) return;
+ snprintf(str, 63, "--%s=%s", label, val);
+ args[pos] = str;
+}
+
+
char **indexamajig_command_line(const char *geom_filename,
const char *n_thread_str,
const char *files_list,
@@ -742,6 +777,7 @@ char **indexamajig_command_line(const char *geom_filename,
char **args;
char tols[2048];
char *indexamajig_path;
+ int i;
int n_args = 0;
args = malloc(64*sizeof(char *));
@@ -830,12 +866,21 @@ char **indexamajig_command_line(const char *geom_filename,
/* Integration */
add_arg(args, n_args++, "--integration");
add_arg(args, n_args++, indexing_params->integration_method);
- if ( indexing_params->overpredict ) args[n_args++] = "--overpredict";
+ if ( indexing_params->overpredict ) add_arg(args, n_args++, "--overpredict");
if ( !isinf(indexing_params->push_res) ) {
add_arg_float(args, n_args++, "push-res",
indexing_params->push_res);
}
+ /* Stream output */
+ if ( indexing_params->exclude_nonhits ) add_arg(args, n_args++, "--no-non-hits-in-stream");
+ if ( indexing_params->exclude_peaks ) add_arg(args, n_args++, "--no-peaks-in-stream");
+ if ( indexing_params->exclude_refls ) add_arg(args, n_args++, "--no-refls-in-stream");
+ for ( i=0; i<indexing_params->n_metadata; i++ ) {
+ add_arg_string(args, n_args++, "copy-hdf5-field",
+ indexing_params->metadata_to_copy[i]);
+ }
+
args[n_args] = NULL;
return args;
}
diff --git a/src/gui_project.c b/src/gui_project.c
index 5641b0c4..f0d42ea6 100644
--- a/src/gui_project.c
+++ b/src/gui_project.c
@@ -297,6 +297,38 @@ static void parse_integration_opt(const char *key, const char *val,
}
+static void add_metadata_to_copy(struct index_params *ip,
+ const char *header)
+{
+ char **n;
+
+ n = realloc(ip->metadata_to_copy,
+ (ip->n_metadata+1)*sizeof(char *));
+ if ( n == NULL ) return;
+ ip->metadata_to_copy = n;
+
+ ip->metadata_to_copy[ip->n_metadata++] = strdup(header);
+}
+
+
+static void parse_stream_opt(const char *key, const char *val,
+ struct index_params *ip)
+{
+ if ( strcmp(key, "stream.exclude_blanks") == 0 ) {
+ ip->exclude_nonhits = parse_int(val);
+ }
+ if ( strcmp(key, "stream.exclude_peaks") == 0 ) {
+ ip->exclude_peaks = parse_int(val);
+ }
+ if ( strcmp(key, "stream.exclude_refls") == 0 ) {
+ ip->exclude_refls = parse_int(val);
+ }
+ if ( strcmp(key, "stream.metadata") == 0 ) {
+ add_metadata_to_copy(ip, val);
+ }
+}
+
+
static void parse_merging_opt(const char *key, const char *val,
struct crystfelproject *proj)
{
@@ -395,7 +427,9 @@ static void handle_var(const char *key, const char *val,
proj->data_top_folder = strdup(val);
}
- if ( strcmp(key, "stream") == 0 ) {
+ if ( strncmp(key, "stream.", 7) == 0 ) {
+ parse_stream_opt(key, val, &proj->indexing_params);
+ } else if ( strcmp(key, "stream") == 0 ) {
proj->stream_filename = strdup(val);
}
@@ -740,6 +774,20 @@ int save_project(struct crystfelproject *proj)
fprintf(fh, "integration.ir_out %f\n",
proj->indexing_params.ir_out);
+ fprintf(fh, "stream.exclude_blanks %i\n",
+ proj->indexing_params.exclude_nonhits);
+ fprintf(fh, "stream.exclude_peaks %i\n",
+ proj->indexing_params.exclude_peaks);
+ fprintf(fh, "stream.exclude_refls %i\n",
+ proj->indexing_params.exclude_refls);
+ if ( proj->indexing_params.metadata_to_copy != NULL ) {
+ int i;
+ for ( i=0; i<proj->indexing_params.n_metadata; i++ ) {
+ fprintf(fh, "stream.metadata %s\n",
+ proj->indexing_params.metadata_to_copy[i]);
+ }
+ }
+
fprintf(fh, "merging.model %s\n",
proj->merging_params.model);
fprintf(fh, "merging.symmetry %s\n",
@@ -888,6 +936,11 @@ void default_project(struct crystfelproject *proj)
proj->indexing_params.ir_inn = 4.0;
proj->indexing_params.ir_mid = 5.0;
proj->indexing_params.ir_out = 7.0;
+ proj->indexing_params.exclude_nonhits = 0;
+ proj->indexing_params.exclude_peaks = 0;
+ proj->indexing_params.exclude_refls = 0;
+ proj->indexing_params.metadata_to_copy = NULL;
+ proj->indexing_params.n_metadata = 0;
proj->merging_params.model = strdup("unity");
proj->merging_params.symmetry = strdup("1");
diff --git a/src/gui_project.h b/src/gui_project.h
index 315aa4ab..bb35eb0c 100644
--- a/src/gui_project.h
+++ b/src/gui_project.h
@@ -87,6 +87,13 @@ struct index_params {
float ir_inn;
float ir_mid;
float ir_out;
+
+ /* Stream output */
+ int exclude_nonhits;
+ int exclude_peaks;
+ int exclude_refls;
+ char **metadata_to_copy;
+ int n_metadata;
};
struct merging_params {