aboutsummaryrefslogtreecommitdiff
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
parent16d605d60a11b8513bb19829a6e3e851fa46c26a (diff)
Final (?) version of backend API
-rw-r--r--src/crystfel_gui.c11
-rw-r--r--src/crystfel_gui.h45
-rw-r--r--src/gui_backend_local.c244
-rw-r--r--src/gui_backend_local.h4
-rw-r--r--src/gui_backend_slurm.c92
-rw-r--r--src/gui_backend_slurm.h4
-rw-r--r--src/gui_index.c126
-rw-r--r--src/gui_index.h2
-rw-r--r--src/gui_peaksearch.c2
-rw-r--r--src/gui_peaksearch.h2
-rw-r--r--src/gui_project.c25
-rw-r--r--src/gui_project.h44
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;