aboutsummaryrefslogtreecommitdiff
path: root/src/gui_backend_local.c
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2020-08-25 11:42:21 +0200
committerThomas White <taw@physics.org>2020-08-25 12:31:32 +0200
commit30a11737e799faa335d049cc9018ada08cf3442e (patch)
tree4eddb2413ac29d26f05b6cfafa6fb829da7a859e /src/gui_backend_local.c
parent16d605d60a11b8513bb19829a6e3e851fa46c26a (diff)
Final (?) version of backend API
Diffstat (limited to 'src/gui_backend_local.c')
-rw-r--r--src/gui_backend_local.c244
1 files changed, 167 insertions, 77 deletions
diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c
index 2ddf2488..c82e2f2b 100644
--- a/src/gui_backend_local.c
+++ b/src/gui_backend_local.c
@@ -31,16 +31,24 @@
#include <sys/wait.h>
#include <gtk/gtk.h>
-#include "crystfel_gui.h"
#include "gui_project.h"
-struct local_backend_priv
+struct local_indexing_opts
{
- struct crystfelproject *proj; /* FIXME: Once started, the process should
- * be considered detatched. Therefore, this
- * shouldn't be stored */
+ int n_processes;
+};
+
+
+struct local_indexing_job
+{
+ double frac_complete;
+ int n_frames;
+
+ /* When both these are true, free the job resources */
int indexamajig_running;
+ int cancelled;
+
guint indexamajig_watch;
GPid indexamajig_pid;
guint child_watch_source;
@@ -50,12 +58,10 @@ struct local_backend_priv
static void watch_indexamajig(GPid pid, gint status, gpointer vp)
{
- struct local_backend_priv *priv = vp;
- struct crystfelproject *proj = priv->proj;
+ struct local_indexing_job *job = vp;
STATUS("Indexamajig exited with status %i\n", status);
- priv->indexamajig_running = 0;
- g_spawn_close_pid(priv->indexamajig_pid);
- remove_infobar(proj);
+ job->indexamajig_running = 0;
+ g_spawn_close_pid(job->indexamajig_pid);
}
@@ -64,8 +70,7 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond,
{
GIOStatus r;
GError *err = NULL;
- struct local_backend_priv *priv = priv;
- struct crystfelproject *proj = priv->proj;
+ struct local_indexing_job *job = vp;
gchar *line;
r = g_io_channel_read_line(source, &line, NULL, NULL, &err);
@@ -74,7 +79,7 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond,
return FALSE;
}
if ( r != G_IO_STATUS_NORMAL ) {
- if ( priv->indexamajig_pid != 0 ) {
+ if ( job->indexamajig_pid != 0 ) {
STATUS("Read error?\n");
} else {
STATUS("End of output (indexamajig exited)\n");
@@ -84,12 +89,9 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond,
chomp(line);
if ( strstr(line, " images processed, ") != NULL ) {
- double frac;
int n_proc;
sscanf(line, "%i ", &n_proc);
- frac = (double)n_proc/proj->n_frames;
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(proj->progressbar),
- frac);
+ job->frac_complete = (double)n_proc/job->n_frames;
} else {
STATUS("%s\n", line);
}
@@ -100,7 +102,9 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond,
}
-static int write_file_list(struct crystfelproject *proj)
+static int write_file_list(char **filenames,
+ char **events,
+ int n_frames)
{
FILE *fh;
int i;
@@ -108,10 +112,10 @@ static int write_file_list(struct crystfelproject *proj)
fh = fopen("files.lst", "w");
if ( fh == NULL ) return 1;
- for ( i=0; i<proj->n_frames; i++ ) {
- fprintf(fh, "%s", proj->filenames[i]);
- if ( proj->events[i] != NULL ) {
- fprintf(fh, " %s\n", proj->events[i]);
+ for ( i=0; i<n_frames; i++ ) {
+ fprintf(fh, "%s", filenames[i]);
+ if ( events[i] != NULL ) {
+ fprintf(fh, " %s\n", events[i]);
} else {
fprintf(fh, "\n");
}
@@ -143,78 +147,82 @@ void setup_subprocess(gpointer user_data)
}
-static void *run_indexing(struct crystfelproject *proj)
+static void *run_indexing(char **filenames,
+ char **events,
+ int n_frames,
+ char *geom_filename,
+ struct peak_params *peak_search_params,
+ struct index_params *indexing_params,
+ void *opts_priv)
{
+ struct local_indexing_opts *opts = opts_priv;
GIOChannel *ioch;
char *args[64];
char index_str[64];
char peaks_str[64];
+ char n_thread_str[64];
int n_args;
int i;
int r;
int ch_stderr;
GError *error;
- struct local_backend_priv *priv;
+ struct local_indexing_job *job;
- if ( priv->indexamajig_running != 0 ) {
- STATUS("Indexamajig already running.\n");
- return NULL;
- }
-
- priv = malloc(sizeof(struct local_backend_priv));
- if ( priv == NULL ) return NULL;
+ job = malloc(sizeof(struct local_indexing_job));
+ if ( job == NULL ) return NULL;
- priv->proj = proj;
-
- if ( write_file_list(proj) ) {
+ if ( write_file_list(filenames, events, n_frames) ) {
STATUS("Failed to write list\n");
- free(priv);
+ free(job);
return NULL;
}
+ job->n_frames = job->n_frames;
strcpy(index_str, "--indexing=dirax"); /* FIXME */
strcpy(peaks_str, "--peaks=");
strncat(peaks_str,
- str_peaksearch(proj->peak_search_params.method), 50);
+ str_peaksearch(peak_search_params->method), 50);
+
+ snprintf(n_thread_str, 63, "%i", opts->n_processes);
args[0] = "indexamajig";
args[1] = "-i";
args[2] = "files.lst";
args[3] = "-g";
- args[4] = proj->geom_filename;
+ args[4] = geom_filename;
args[5] = "-o";
args[6] = "test.stream";
args[7] = index_str;
args[8] = "--no-check-cell";
args[9] = "-j";
- args[10] = "1";
+ args[10] = n_thread_str;
args[11] = "--integration=none";
args[12] = peaks_str;
n_args = 13;
- if ( proj->peak_search_params.method == PEAK_ZAEF ) {
+ if ( peak_search_params->method == PEAK_ZAEF ) {
add_arg(args, n_args++, "threshold",
- proj->peak_search_params.threshold);
+ peak_search_params->threshold);
add_arg(args, n_args++, "min-squared-gradient",
- proj->peak_search_params.min_sq_gradient);
+ peak_search_params->min_sq_gradient);
add_arg(args, n_args++, "min-snr",
- proj->peak_search_params.min_snr);
- } else if ( proj->peak_search_params.method == PEAK_PEAKFINDER8 ) {
+ peak_search_params->min_snr);
+ } else if ( peak_search_params->method == PEAK_PEAKFINDER8 ) {
add_arg(args, n_args++, "threshold",
- proj->peak_search_params.threshold);
+ peak_search_params->threshold);
add_arg(args, n_args++, "min-snr",
- proj->peak_search_params.min_snr);
+ peak_search_params->min_snr);
add_arg(args, n_args++, "min-pix-count",
- proj->peak_search_params.min_pix_count);
+ peak_search_params->min_pix_count);
add_arg(args, n_args++, "max-pix-count",
- proj->peak_search_params.max_pix_count);
+ peak_search_params->max_pix_count);
add_arg(args, n_args++, "local-bg-radius",
- proj->peak_search_params.local_bg_radius);
+ peak_search_params->local_bg_radius);
add_arg(args, n_args++, "min-res",
- proj->peak_search_params.min_res);
+ peak_search_params->min_res);
add_arg(args, n_args++, "max-res",
- proj->peak_search_params.max_res);
+ peak_search_params->max_res);
}
args[n_args] = NULL;
@@ -228,55 +236,137 @@ static void *run_indexing(struct crystfelproject *proj)
G_SPAWN_SEARCH_PATH
| G_SPAWN_DO_NOT_REAP_CHILD,
setup_subprocess, NULL,
- &priv->indexamajig_pid,
+ &job->indexamajig_pid,
NULL, NULL, &ch_stderr,
&error);
if ( r == FALSE ) {
ERROR("Failed to run indexamajig: %s\n",
error->message);
- free(priv);
+ free(job);
return NULL;
}
- priv->indexamajig_running = 1;
+ job->indexamajig_running = 1;
- priv->child_watch_source = g_child_watch_add(priv->indexamajig_pid,
- watch_indexamajig,
- priv);
+ job->child_watch_source = g_child_watch_add(job->indexamajig_pid,
+ watch_indexamajig,
+ job);
ioch = g_io_channel_unix_new(ch_stderr);
- priv->index_readable_source = g_io_add_watch(ioch,
- G_IO_IN | G_IO_ERR | G_IO_HUP,
- index_readable,
- priv);
+ job->index_readable_source = g_io_add_watch(ioch,
+ G_IO_IN | G_IO_ERR | G_IO_HUP,
+ index_readable,
+ job);
+
+ return job;
+}
+
+
+static void cancel_indexing(void *job_priv)
+{
+ struct local_indexing_job *job = job_priv;
+
+ if ( !job->indexamajig_running ) return;
+
+ ERROR("Stopping indexamajig (pid %i).\n", job->indexamajig_pid);
+ kill(-job->indexamajig_pid, SIGINT);
+}
+
+
+static int convert_int(const char *str, int *pval)
+{
+ int val;
+ char *rval;
- return priv;
+ val = strtod(str, &rval);
+ if ( *rval != '\0' ) {
+ return 1;
+ } else {
+ *pval = val;
+ return 0;
+ }
}
-static void cancel(void *vp)
+static void n_processes_activate_sig(GtkEntry *entry, gpointer data)
{
- struct local_backend_priv *priv = vp;
+ struct local_indexing_opts *opts = data;
+ convert_int(gtk_entry_get_text(entry), &opts->n_processes);
+}
- if ( !priv->indexamajig_running ) return;
- ERROR("Stopping indexamajig (pid %i).\n", priv->indexamajig_pid);
- kill(-priv->indexamajig_pid, SIGINT);
+static GtkWidget *make_indexing_parameters_widget(void *opts_priv)
+{
+ struct local_indexing_opts *opts = opts_priv;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *entry;
+ GtkWidget *label;
+ char tmp[64];
+
+ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox),
+ FALSE, FALSE, 0);
+ label = gtk_label_new("Number of threads:");
+ gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label),
+ FALSE, FALSE, 0);
+ entry = gtk_entry_new();
+ snprintf(tmp, 63, "%i", opts->n_processes);
+ gtk_entry_set_width_chars(GTK_ENTRY(entry), 5);
+ gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry),
+ FALSE, FALSE, 0);
+
+ g_signal_connect(G_OBJECT(entry), "activate",
+ G_CALLBACK(n_processes_activate_sig),
+ opts);
+ return vbox;
}
-static GtkWidget *make_parameters(void)
+static struct local_indexing_opts *make_default_local_opts()
{
- return gtk_label_new("Local params");
+ struct local_indexing_opts *opts = malloc(sizeof(struct local_indexing_opts));
+ if ( opts == NULL ) return NULL;
+
+ opts->n_processes = 4;
+
+ return opts;
}
-struct crystfel_backend _backend_local =
- {
- .name = "local",
- .friendly_name = "Local (run on this computer)",
- .make_parameters = make_parameters,
- .run_indexing = run_indexing,
- .cancel = cancel,
- };
+static void write_indexing_opts(void *opts_priv, FILE *fh)
+{
+ struct local_indexing_opts *opts = opts_priv;
+
+ fprintf(fh, "indexing.local.n_processes %i\n",
+ opts->n_processes);
+}
+
-const struct crystfel_backend *backend_local = &_backend_local;
+static void read_indexing_opt(void *opts_priv,
+ const char *key,
+ const char *val)
+{
+ //struct local_indexing_opts *opts = opts_priv;
+
+ STATUS("Local got %s = '%s'\n", key, val);
+ /* FIXME: Parse and set */
+}
+
+
+int make_local_backend(struct crystfel_backend *be)
+{
+ be->name = "local";
+ be->friendly_name = "Local (run on this computer)";
+
+ be->make_indexing_parameters_widget = make_indexing_parameters_widget;
+ be->run_indexing = run_indexing;
+ be->cancel_indexing = cancel_indexing;
+ be->indexing_opts_priv = make_default_local_opts();
+ if ( be->indexing_opts_priv == NULL ) return 1;
+ be->write_indexing_opts = write_indexing_opts;
+ be->read_indexing_opt = read_indexing_opt;
+
+ return 0;
+};