diff options
-rw-r--r-- | src/crystfel_gui.c | 11 | ||||
-rw-r--r-- | src/crystfel_gui.h | 45 | ||||
-rw-r--r-- | src/gui_backend_local.c | 244 | ||||
-rw-r--r-- | src/gui_backend_local.h | 4 | ||||
-rw-r--r-- | src/gui_backend_slurm.c | 92 | ||||
-rw-r--r-- | src/gui_backend_slurm.h | 4 | ||||
-rw-r--r-- | src/gui_index.c | 126 | ||||
-rw-r--r-- | src/gui_index.h | 2 | ||||
-rw-r--r-- | src/gui_peaksearch.c | 2 | ||||
-rw-r--r-- | src/gui_peaksearch.h | 2 | ||||
-rw-r--r-- | src/gui_project.c | 25 | ||||
-rw-r--r-- | src/gui_project.h | 44 |
12 files changed, 386 insertions, 215 deletions
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index d9b9bec1..48c0777a 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -45,13 +45,10 @@ #include "crystfelimageview.h" #include "crystfelimageview.h" -#include "crystfel_gui.h" #include "gui_peaksearch.h" #include "gui_index.h" #include "gui_project.h" #include "version.h" -#include "gui_backend_local.h" -#include "gui_backend_slurm.h" static void show_help(const char *s) @@ -804,9 +801,6 @@ static void add_gui_message(enum log_msg_type type, const char *msg, } -const struct crystfel_backend *backends[16]; - - int main(int argc, char *argv[]) { int c; @@ -820,11 +814,6 @@ int main(int argc, char *argv[]) GtkWidget *toolbar; GtkWidget *button; - backends[0] = backend_local; - backends[1] = backend_slurm; - backends[2] = NULL; - /* Max 16 */ - /* Long options */ const struct option longopts[] = { {"help", 0, NULL, 'h'}, diff --git a/src/crystfel_gui.h b/src/crystfel_gui.h deleted file mode 100644 index 4d2dcf06..00000000 --- a/src/crystfel_gui.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * crystfel_gui.h - * - * CrystFEL's main graphical user interface - * - * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY, - * a research centre of the Helmholtz Association. - * - * Authors: - * 2020 Thomas White <taw@physics.org> - * - * This file is part of CrystFEL. - * - * CrystFEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CrystFEL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef CRYSTFEL_GUI_H -#define CRYSTFEL_GUI_H - -#include "gui_project.h" - -struct crystfel_backend { - const char *name; - const char *friendly_name; - GtkWidget *(*make_parameters)(void); - void *(*run_indexing)(struct crystfelproject *proj, - const char *algo); - void (*cancel)(struct crystfelproject *proj); -}; - -extern const struct crystfel_backend *backends[]; - -#endif 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; +}; diff --git a/src/gui_backend_local.h b/src/gui_backend_local.h index 94724e98..5b3fd7d4 100644 --- a/src/gui_backend_local.h +++ b/src/gui_backend_local.h @@ -29,8 +29,8 @@ #ifndef GUI_BACKEND_LOCAL_H #define GUI_BACKEND_LOCAL_H -#include "crystfel_gui.h" +#include "gui_project.h" -extern const struct crystfel_backend *backend_local; +extern int make_local_backend(struct crystfel_backend *be); #endif diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c index b5c75bb5..cb0cee59 100644 --- a/src/gui_backend_slurm.c +++ b/src/gui_backend_slurm.c @@ -31,39 +31,101 @@ #include <sys/wait.h> #include <gtk/gtk.h> -#include "crystfel_gui.h" +#include "gui_project.h" -struct slurm_backend_priv +struct slurm_indexing_opts { - int dummy; + char *partition; + int block_size; + char *email_address; }; -static void cancel(void *vp) +struct slurm_indexing_job { + double frac_complete; + /* FIXME: List of SLURM job numbers to track */ +}; + + +static void cancel_indexing(void *job_priv) +{ + //struct slurm_indexing_job *job = job_priv; } -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 slurm_indexing_opts *opts = opts_priv; return NULL; } -static GtkWidget *make_parameters(void) +static GtkWidget *make_indexing_parameters_widget(void *opts_priv) { + //struct slurm_indexing_opts *opts = opts_priv; + return gtk_label_new("SLURM params"); } -const struct crystfel_backend _backend_slurm = - { - .name = "slurm", - .friendly_name = "SLURM", - .make_parameters = make_parameters, - .run_indexing = run_indexing, - .cancel = cancel, - }; +static struct slurm_indexing_opts *make_default_slurm_opts() +{ + struct slurm_indexing_opts *opts = malloc(sizeof(struct slurm_indexing_opts)); + if ( opts == NULL ) return NULL; + + opts->partition = NULL; + opts->block_size = 1000; + opts->email_address = NULL; -const struct crystfel_backend *backend_slurm = &_backend_slurm; + return opts; +} + + +static void write_indexing_opts(void *opts_priv, FILE *fh) +{ + struct slurm_indexing_opts *opts = opts_priv; + + fprintf(fh, "indexing.slurm.block_size %i\n", + opts->block_size); + fprintf(fh, "indexing.slurm.partition %s\n", + opts->partition); + fprintf(fh, "indexing.slurm.email_address %s\n", + opts->email_address); +} + + +static void read_indexing_opt(void *opts_priv, + const char *key, + const char *val) +{ + //struct slurm_indexing_opts *opts = opts_priv; + + STATUS("SLURM got %s = '%s'\n", key, val); + /* FIXME: Parse and set */ +} + + +int make_slurm_backend(struct crystfel_backend *be) +{ + be->name = "slurm"; + be->friendly_name = "SLURM"; + + be->make_indexing_parameters_widget = make_indexing_parameters_widget; + be->run_indexing = run_indexing; + be->cancel_indexing = cancel_indexing; + be->write_indexing_opts = write_indexing_opts; + be->read_indexing_opt = read_indexing_opt; + + be->indexing_opts_priv = make_default_slurm_opts(); + if ( be->indexing_opts_priv == NULL ) return 1; + + return 0; +}; diff --git a/src/gui_backend_slurm.h b/src/gui_backend_slurm.h index 9865aa2a..28eec2e3 100644 --- a/src/gui_backend_slurm.h +++ b/src/gui_backend_slurm.h @@ -29,8 +29,8 @@ #ifndef GUI_BACKEND_SLURM_H #define GUI_BACKEND_SLURM_H -#include "crystfel_gui.h" +#include "gui_project.h" -extern const struct crystfel_backend *backend_slurm; +extern int make_slurm_backend(struct crystfel_backend *be); #endif diff --git a/src/gui_index.c b/src/gui_index.c index 9fdc0c4e..45ae943b 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -46,9 +46,9 @@ #include <integration.h> #include <predict-refine.h> -#include "crystfel_gui.h" #include "crystfelimageview.h" #include "crystfelindexingopts.h" +#include "gui_project.h" void cell_explorer_sig(struct crystfelproject *proj) { @@ -68,11 +68,57 @@ void cell_explorer_sig(struct crystfelproject *proj) } +static void get_indexing_opts(struct crystfelproject *proj, + CrystFELIndexingOpts *opts) +{ + /* Indexing */ + proj->indexing_params.cell_file = crystfel_indexing_opts_get_cell_file(opts); + proj->indexing_params.indexing_methods = crystfel_indexing_opts_get_indexing_method_string(opts); + proj->indexing_params.multi = crystfel_indexing_opts_get_multi_lattice(opts); + proj->indexing_params.no_refine = !crystfel_indexing_opts_get_refine(opts); + proj->indexing_params.no_retry = !crystfel_indexing_opts_get_retry(opts); + proj->indexing_params.no_peak_check = !crystfel_indexing_opts_get_peak_check(opts); + proj->indexing_params.no_cell_check = !crystfel_indexing_opts_get_cell_check(opts); + proj->indexing_params.min_peaks = crystfel_indexing_opts_get_min_peaks(opts); + + /* Integration */ + proj->indexing_params.integration_method = crystfel_indexing_opts_get_integration_method_string(opts); + proj->indexing_params.overpredict = crystfel_indexing_opts_get_overpredict(opts); + proj->indexing_params.push_res = crystfel_indexing_opts_get_push_res(opts); +} + + +static void run_indexing_all(struct crystfelproject *proj) +{ + int backend_idx; + struct crystfel_backend *be; + void *job_priv; + + get_indexing_opts(proj, + CRYSTFEL_INDEXING_OPTS(proj->indexing_opts)); + + + backend_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(proj->indexing_backend_combo)); + if ( backend_idx < 0 ) return; + + be = &proj->backends[backend_idx]; + job_priv = be->run_indexing(proj->filenames, + proj->events, + proj->n_frames, + proj->geom_filename, + &proj->peak_search_params, + &proj->indexing_params, + be->indexing_opts_priv); + + STATUS("Started job %p\n", job_priv); +} + + static void index_all_response_sig(GtkWidget *dialog, gint resp, struct crystfelproject *proj) { if ( resp == GTK_RESPONSE_OK ) { - STATUS("OK!\n"); + run_indexing_all(proj); } gtk_widget_destroy(dialog); @@ -80,23 +126,27 @@ static void index_all_response_sig(GtkWidget *dialog, gint resp, } -static void backend_changed_sig(GtkWidget *combo, - struct crystfelproject *proj) +static void indexing_backend_changed_sig(GtkWidget *combo, + struct crystfelproject *proj) { int backend_idx; + struct crystfel_backend *be; backend_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); if ( backend_idx < 0 ) return; - if ( proj->backend_opts != NULL ) { - gtk_widget_destroy(proj->backend_opts); + be = &proj->backends[backend_idx]; + + if ( proj->indexing_backend_opts_widget != NULL ) { + gtk_widget_destroy(proj->indexing_backend_opts_widget); } - proj->backend_opts = backends[backend_idx]->make_parameters(); - gtk_box_pack_start(GTK_BOX(proj->backend_opts_box), - GTK_WIDGET(proj->backend_opts), + proj->indexing_backend_opts_widget = be->make_indexing_parameters_widget(be->indexing_opts_priv); + + gtk_box_pack_start(GTK_BOX(proj->indexing_backend_opts_box), + GTK_WIDGET(proj->indexing_backend_opts_widget), FALSE, FALSE, 0); - gtk_widget_show_all(proj->backend_opts); + gtk_widget_show_all(proj->indexing_backend_opts_widget); } @@ -105,7 +155,6 @@ static GtkWidget *make_backend_opts(struct crystfelproject *proj) GtkWidget *box; GtkWidget *hbox; GtkWidget *label; - GtkWidget *combo; int i; box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); @@ -118,28 +167,27 @@ static GtkWidget *make_backend_opts(struct crystfelproject *proj) gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), FALSE, FALSE, 0); - combo = gtk_combo_box_text_new(); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(combo), + proj->indexing_backend_combo = gtk_combo_box_text_new(); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(proj->indexing_backend_combo), FALSE, FALSE, 0); - i = 0; - do { - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), - backends[i]->name, - backends[i]->friendly_name); - } while ( backends[++i] != NULL ); + for ( i=0; i<proj->n_backends; i++ ) { + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(proj->indexing_backend_combo), + proj->backends[i].name, + proj->backends[i].friendly_name); + } - proj->backend_opts_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, - 0); + proj->indexing_backend_opts_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, + 0); gtk_box_pack_start(GTK_BOX(box), - GTK_WIDGET(proj->backend_opts_box), + GTK_WIDGET(proj->indexing_backend_opts_box), FALSE, FALSE, 0); - proj->backend_opts = NULL; + proj->indexing_backend_opts_widget = NULL; - /* proj->backend_opts{_box} must exist before the following */ - g_signal_connect(G_OBJECT(combo), "changed", - G_CALLBACK(backend_changed_sig), proj); - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); + /* proj->indexing_backend_opts{_box} must exist before the following */ + g_signal_connect(G_OBJECT(proj->indexing_backend_combo), "changed", + G_CALLBACK(indexing_backend_changed_sig), proj); + gtk_combo_box_set_active(GTK_COMBO_BOX(proj->indexing_backend_combo), 0); return box; } @@ -166,26 +214,6 @@ static void set_indexing_opts(struct crystfelproject *proj, } -static void get_indexing_opts(struct crystfelproject *proj, - CrystFELIndexingOpts *opts) -{ - /* Indexing */ - proj->indexing_params.cell_file = crystfel_indexing_opts_get_cell_file(opts); - proj->indexing_params.indexing_methods = crystfel_indexing_opts_get_indexing_method_string(opts); - proj->indexing_params.multi = crystfel_indexing_opts_get_multi_lattice(opts); - proj->indexing_params.no_refine = !crystfel_indexing_opts_get_refine(opts); - proj->indexing_params.no_retry = !crystfel_indexing_opts_get_retry(opts); - proj->indexing_params.no_peak_check = !crystfel_indexing_opts_get_peak_check(opts); - proj->indexing_params.no_cell_check = !crystfel_indexing_opts_get_cell_check(opts); - proj->indexing_params.min_peaks = crystfel_indexing_opts_get_min_peaks(opts); - - /* Integration */ - proj->indexing_params.integration_method = crystfel_indexing_opts_get_integration_method_string(opts); - proj->indexing_params.overpredict = crystfel_indexing_opts_get_overpredict(opts); - proj->indexing_params.push_res = crystfel_indexing_opts_get_push_res(opts); -} - - gint index_all_sig(GtkWidget *widget, struct crystfelproject *proj) { GtkWidget *dialog; @@ -220,9 +248,9 @@ gint index_all_sig(GtkWidget *widget, struct crystfelproject *proj) gtk_notebook_append_page(GTK_NOTEBOOK(proj->indexing_opts), backend_page, gtk_label_new("Cluster/batch system")); - proj->backend_opts_box = gtk_vbox_new(FALSE, 0.0); + proj->indexing_backend_opts_box = gtk_vbox_new(FALSE, 0.0); gtk_box_pack_start(GTK_BOX(backend_page), - proj->backend_opts_box, + proj->indexing_backend_opts_box, FALSE, FALSE, 8.0); gtk_dialog_set_default_response(GTK_DIALOG(dialog), diff --git a/src/gui_index.h b/src/gui_index.h index 474e7c0b..991151ef 100644 --- a/src/gui_index.h +++ b/src/gui_index.h @@ -31,7 +31,7 @@ #include <gtk/gtk.h> -#include "crystfel_gui.h" +#include "gui_project.h" extern gint index_one_sig(GtkWidget *widget, struct crystfelproject *proj); diff --git a/src/gui_peaksearch.c b/src/gui_peaksearch.c index fc82ed80..c3444fe4 100644 --- a/src/gui_peaksearch.c +++ b/src/gui_peaksearch.c @@ -42,8 +42,8 @@ #include <datatemplate.h> #include <peaks.h> -#include "crystfel_gui.h" #include "crystfelimageview.h" +#include "gui_project.h" void update_peaks(struct crystfelproject *proj) diff --git a/src/gui_peaksearch.h b/src/gui_peaksearch.h index 5124acdb..68443d5e 100644 --- a/src/gui_peaksearch.h +++ b/src/gui_peaksearch.h @@ -31,7 +31,7 @@ #include <gtk/gtk.h> -#include "crystfel_gui.h" +#include "gui_project.h" extern gint peaksearch_sig(GtkWidget *widget, struct crystfelproject *proj); diff --git a/src/gui_project.c b/src/gui_project.c index f383f77b..a38cc305 100644 --- a/src/gui_project.c +++ b/src/gui_project.c @@ -36,9 +36,9 @@ #include <string.h> #include <assert.h> -#include "crystfel_gui.h" -#include "gui_backend_local.h" #include "gui_project.h" +#include "gui_backend_local.h" +#include "gui_backend_slurm.h" static double parse_float(const char *val) { @@ -262,10 +262,6 @@ static void handle_var(const char *key, const char *val, proj->show_refls = parse_int(val); } - if ( strcmp(key, "backend") == 0 ) { - proj->backend_name = strdup(val); - } - if ( strcmp(key, "geom") == 0 ) { proj->geom_filename = strdup(val); } @@ -340,6 +336,8 @@ int load_project(struct crystfelproject *proj) fh = fopen("crystfel.project", "r"); if ( fh == NULL ) return 1; + default_project(proj); + do { char *sp; @@ -474,7 +472,6 @@ int save_project(struct crystfelproject *proj) fprintf(fh, "show_peaks %i\n", proj->show_peaks); fprintf(fh, "show_refls %i\n", proj->show_refls); - fprintf(fh, "backend %s\n", proj->backend_name); fprintf(fh, "-----\n"); if ( proj->stream == NULL ) { @@ -503,7 +500,6 @@ void default_project(struct crystfelproject *proj) proj->events = NULL; proj->peak_params = NULL; proj->info_bar = NULL; - proj->backend_name = strdup("local"); proj->data_top_folder = NULL; proj->data_search_pattern = 0; proj->stream_filename = NULL; @@ -512,6 +508,19 @@ void default_project(struct crystfelproject *proj) proj->cur_image = NULL; proj->indexing_opts = NULL; + /* FIXME: Crappy error handling */ + proj->n_backends = 2; + proj->backends = malloc(proj->n_backends*sizeof(struct crystfel_backend)); + if ( proj->backends == NULL ) { + ERROR("Couldn't allocate space for backends\n"); + } + if ( make_local_backend(&proj->backends[0]) ) { + ERROR("Local backend setup failed\n"); + } + if ( make_slurm_backend(&proj->backends[1]) ) { + ERROR("SLURM backend setup failed\n"); + } + /* Default parameter values */ proj->show_peaks = 0; proj->show_refls = 0; diff --git a/src/gui_project.h b/src/gui_project.h index 0c7e9616..42ab43f1 100644 --- a/src/gui_project.h +++ b/src/gui_project.h @@ -34,6 +34,7 @@ #include <peaks.h> #include <stream.h> + enum match_type_id { MATCH_EVERYTHING, @@ -83,6 +84,40 @@ struct index_params { float push_res; }; +struct crystfel_backend { + + const char *name; + const char *friendly_name; + + /* Backend should provide a GTK widget to set options */ + GtkWidget *(*make_indexing_parameters_widget)(void *opts_priv); + + /* Called to ask the backend to start indexing frames. + * It should return a void pointer representing this job */ + 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); + + /* Called to ask the backend to cancel the job */ + void (*cancel_indexing)(void *job_priv); + + /* Called to ask the backend to write its indexing options */ + void (*write_indexing_opts)(void *opts_priv, FILE *fh); + + /* Called when reading a project from file */ + void (*read_indexing_opt)(void *opts_priv, + const char *key, + const char *val); + + /* Backend should store options for indexing here */ + void *indexing_opts_priv; + +}; + struct crystfelproject { GtkWidget *window; @@ -119,15 +154,18 @@ struct crystfelproject { int show_refls; struct index_params indexing_params; GtkWidget *indexing_opts; + GtkWidget *indexing_backend_combo; + GtkWidget *indexing_backend_opts_widget; + GtkWidget *indexing_backend_opts_box; GtkWidget *type_combo; GtkWidget *peak_vbox; /* Box for peak search parameter widgets */ GtkWidget *peak_params; /* Peak search parameter widgets */ struct peak_params original_params; - char *backend_name; - GtkWidget *backend_opts; - GtkWidget *backend_opts_box; + /* All the backends available in this project */ + struct crystfel_backend *backends; + int n_backends; GtkWidget *info_bar; GtkWidget *progressbar; |