diff options
author | Thomas White <taw@physics.org> | 2020-08-25 11:42:21 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2020-08-25 12:31:32 +0200 |
commit | 30a11737e799faa335d049cc9018ada08cf3442e (patch) | |
tree | 4eddb2413ac29d26f05b6cfafa6fb829da7a859e /src/gui_backend_local.c | |
parent | 16d605d60a11b8513bb19829a6e3e851fa46c26a (diff) |
Final (?) version of backend API
Diffstat (limited to 'src/gui_backend_local.c')
-rw-r--r-- | src/gui_backend_local.c | 244 |
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; +}; |