aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-02-17 17:22:28 +0100
committerThomas White <taw@physics.org>2021-02-17 17:22:28 +0100
commite0437375017e504124cab53e5d19f4da499e88e7 (patch)
tree2963056cf418fbaeecf0e398b5e7a1000b004cd7 /src
parent5a549e4fdc6265748fa2eabacb19f5ff850d27eb (diff)
GUI: Re-work local backend plumbing
A single command line is not expressive enough for at least two cases: process_hkl, which needs to be run two extra times to generate the splits, and ambigator, which needs to have its input streams concatenated first. This also splits out the routine for creating the working folder and writing the notes file.
Diffstat (limited to 'src')
-rw-r--r--src/gui_ambi.c36
-rw-r--r--src/gui_ambi.h6
-rw-r--r--src/gui_backend_local.c201
-rw-r--r--src/gui_merge.c135
-rw-r--r--src/gui_merge.h6
5 files changed, 330 insertions, 54 deletions
diff --git a/src/gui_ambi.c b/src/gui_ambi.c
index 294196fc..8ab0acc3 100644
--- a/src/gui_ambi.c
+++ b/src/gui_ambi.c
@@ -452,3 +452,39 @@ gint ambi_sig(GtkWidget *widget, struct crystfelproject *proj)
return FALSE;
}
+
+
+int write_ambigator_script(const char *filename,
+ struct gui_indexing_result *input,
+ const char *n_thread_str,
+ struct ambi_params *params,
+ const char *out_stream)
+{
+ FILE *fh;
+ char *exe_path;
+ int i;
+
+ fh = fopen(filename, "w");
+ if ( fh == NULL ) return 1;
+
+ fprintf(fh, "cat \\\n");
+ for ( i=0; i<input->n_streams; i++ ) {
+ fprintf(fh, "%s \\\n", input->streams[i]);
+ }
+
+ exe_path = get_crystfel_exe("ambigator");
+ if ( exe_path == NULL ) return 1;
+ fprintf(fh, "| %s - \\\n", exe_path);
+
+ fprintf(fh, " -j %s", n_thread_str);
+ fprintf(fh, " -o %s", out_stream);
+ fprintf(fh, " -y %s", params->sym);
+// if ( params->source_sym != NULL ) {
+// fprintf(fh, " -w %s", params->source_sym);
+// }
+
+ fprintf(fh, " --iterations=%i", params->niter);
+
+ fclose(fh);
+ return 0;
+}
diff --git a/src/gui_ambi.h b/src/gui_ambi.h
index f63c29a0..f577e3c1 100644
--- a/src/gui_ambi.h
+++ b/src/gui_ambi.h
@@ -36,4 +36,10 @@
extern gint ambi_sig(GtkWidget *widget,
struct crystfelproject *proj);
+extern int write_ambigator_script(const char *filename,
+ struct gui_indexing_result *input,
+ const char *n_thread_str,
+ struct ambi_params *params,
+ const char *out_stream);
+
#endif
diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c
index 3af63ea0..21d12aad 100644
--- a/src/gui_backend_local.c
+++ b/src/gui_backend_local.c
@@ -38,6 +38,7 @@
#include "gui_project.h"
#include "gui_index.h"
#include "gui_merge.h"
+#include "gui_ambi.h"
struct local_indexing_opts
@@ -123,14 +124,23 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond,
}
-static int write_file_list(char **filenames,
+static int write_file_list(GFile *workdir,
+ const char *listname,
+ char **filenames,
char **events,
int n_frames)
{
FILE *fh;
int i;
+ GFile *list_gfile;
+ char *list_str;
- fh = fopen("files.lst", "w");
+ list_gfile = g_file_get_child(workdir, listname);
+ list_str = g_file_get_path(list_gfile);
+ if ( list_str == NULL ) return 1;
+
+ fh = fopen(list_str, "w");
+ free(list_str);
if ( fh == NULL ) return 1;
for ( i=0; i<n_frames; i++ ) {
@@ -157,21 +167,11 @@ void setup_subprocess(gpointer user_data)
}
-static struct local_job *start_local_job(char **args,
- const char *job_title,
- const char *job_notes,
- struct crystfelproject *proj,
- GIOFunc readable_func)
+static GFile *make_job_folder(const char *job_title,
+ const char *job_notes)
{
- GIOChannel *ioch;
- int i;
- int r;
- int ch_stderr;
- GError *error;
- struct local_job *job;
struct stat s;
char *workdir;
- const char *old_pwd;
GFile *workdir_file;
GFile *cwd_file;
GFile *notes_file;
@@ -197,6 +197,7 @@ static struct local_job *start_local_job(char **args,
workdir_file = g_file_get_child(cwd_file, workdir);
g_object_unref(cwd_file);
+ /* Write the notes into notes.txt */
notes_file = g_file_get_child(workdir_file, "notes.txt");
notes_path = g_file_get_path(notes_file);
fh = fopen(notes_path, "w");
@@ -205,18 +206,31 @@ static struct local_job *start_local_job(char **args,
g_free(notes_path);
g_object_unref(notes_file);
+ return workdir_file;
+}
+
+
+
+static struct local_job *start_local_job(char **args,
+ const char *job_title,
+ GFile *workdir_file,
+ struct crystfelproject *proj,
+ GIOFunc readable_func)
+{
+ GIOChannel *ioch;
+ int i;
+ int r;
+ int ch_stderr;
+ GError *error;
+ struct local_job *job;
+ char *workdir_str;
+
+ workdir_str = g_file_get_path(workdir_file);
+ if ( workdir_str == NULL ) return NULL;
+
job = malloc(sizeof(struct local_job));
if ( job == NULL ) return NULL;
- old_pwd = getcwd(NULL, 0);
- chdir(workdir);
- if ( write_file_list(proj->filenames, proj->events, proj->n_frames) ) {
- STATUS("Failed to write list\n");
- free(job);
- return NULL;
- }
- chdir(old_pwd);
-
job->frac_complete = 0.0;
job->workdir = workdir_file;
@@ -227,17 +241,16 @@ static struct local_job *start_local_job(char **args,
}
STATUS("\n");
+ error = NULL;
r = g_spawn_async_with_pipes(NULL, args, NULL,
G_SPAWN_SEARCH_PATH
| G_SPAWN_DO_NOT_REAP_CHILD,
- setup_subprocess, workdir,
+ setup_subprocess, workdir_str,
&job->pid,
NULL, NULL, &ch_stderr,
&error);
if ( r == FALSE ) {
- ERROR("Failed to start program: %s\n",
- error->message);
- g_object_unref(workdir_file);
+ ERROR("Failed to start program: %s\n", error->message);
free(job);
return NULL;
}
@@ -442,13 +455,63 @@ static gboolean merge_readable(GIOChannel *source, GIOCondition cond,
}
+static gboolean ambi_readable(GIOChannel *source, GIOCondition cond,
+ void *vp)
+{
+ /* FIXME: Implementation */
+ return TRUE;
+}
+
+
static void *run_ambi(const char *job_title,
const char *job_notes,
struct crystfelproject *proj,
struct gui_indexing_result *input,
void *opts_priv)
{
- return NULL;
+ char n_thread_str[64];
+ struct local_job *job;
+ struct local_merging_opts *opts = opts_priv;
+ GFile *workdir;
+ GFile *sc_gfile;
+ gchar *sc_filename;
+ GFile *stream_gfile;
+ char *stream_str;
+
+ workdir = make_job_folder(job_title, job_notes);
+ if ( workdir == NULL ) return NULL;
+
+ stream_gfile = g_file_get_child(workdir, "ambi.stream");
+ stream_str = g_file_get_path(stream_gfile);
+ g_object_unref(stream_gfile);
+
+ snprintf(n_thread_str, 64, "%i", opts->n_threads);
+ sc_gfile = g_file_get_child(workdir, "run_merge.sh");
+ sc_filename = g_file_get_path(sc_gfile);
+ g_object_unref(sc_gfile);
+ if ( sc_filename == NULL ) return NULL;
+ if ( !write_ambigator_script(sc_filename, input, n_thread_str,
+ &proj->ambi_params, stream_str) )
+ {
+ char *args[2];
+ args[0] = "run_ambigator.sh";
+ args[1] = NULL;
+ job = start_local_job(args, job_title, workdir,
+ proj, ambi_readable);
+ } else {
+ job = NULL;
+ }
+
+ if ( job != NULL ) {
+ char **streams = malloc(sizeof(char *));
+ if ( streams != NULL ) {
+ streams[0] = stream_str;
+ add_indexing_result(proj, strdup(job_title), streams, 1);
+ }
+ }
+
+ g_object_unref(workdir);
+ return job;
}
@@ -459,41 +522,58 @@ static void *run_merging(const char *job_title,
void *opts_priv)
{
char n_thread_str[64];
- char **args;
struct local_job *job;
struct local_merging_opts *opts = opts_priv;
- GFile *hkl_gfile;
- char *hkl;
- char *hkl1;
- char *hkl2;
+ GFile *workdir;
+ GFile *sc_gfile;
+ gchar *sc_filename;
+
+ workdir = make_job_folder(job_title, job_notes);
+ if ( workdir == NULL ) return NULL;
snprintf(n_thread_str, 63, "%i", opts->n_threads);
- args = merging_command_line(n_thread_str,
- input,
- &proj->merging_params);
+ sc_gfile = g_file_get_child(workdir, "run_merge.sh");
+ sc_filename = g_file_get_path(sc_gfile);
+ g_object_unref(sc_gfile);
+ if ( sc_filename == NULL ) return NULL;
+
+ if ( !write_merge_script(sc_filename, input, n_thread_str,
+ &proj->merging_params, "crystfel.hkl") )
+ {
+ char *args[3];
+ args[0] = "sh";
+ args[1] = sc_filename;
+ args[2] = NULL;
+ job = start_local_job(args, job_title, workdir,
+ proj, merge_readable);
+ } else {
+ job = NULL;
+ }
+ g_free(sc_filename);
- job = start_local_job(args, job_title, job_notes, proj,
- merge_readable);
+ if ( job != NULL ) {
- if ( job == NULL ) return NULL;
+ GFile *hkl_gfile;
+ char *hkl;
+ char *hkl1;
+ char *hkl2;
- hkl_gfile = g_file_get_child(job->workdir,
- "crystfel.hkl");
- hkl = g_file_get_path(hkl_gfile);
- g_object_unref(hkl_gfile);
+ hkl_gfile = g_file_get_child(workdir, "crystfel.hkl");
+ hkl = g_file_get_path(hkl_gfile);
+ g_object_unref(hkl_gfile);
- hkl_gfile = g_file_get_child(job->workdir,
- "crystfel.hkl1");
- hkl1 = g_file_get_path(hkl_gfile);
- g_object_unref(hkl_gfile);
+ hkl_gfile = g_file_get_child(workdir, "crystfel.hkl1");
+ hkl1 = g_file_get_path(hkl_gfile);
+ g_object_unref(hkl_gfile);
- hkl_gfile = g_file_get_child(job->workdir,
- "crystfel.hkl2");
- hkl2 = g_file_get_path(hkl_gfile);
- g_object_unref(hkl_gfile);
+ hkl_gfile = g_file_get_child(workdir, "crystfel.hkl2");
+ hkl2 = g_file_get_path(hkl_gfile);
+ g_object_unref(hkl_gfile);
- add_merge_result(proj, strdup(job_title), hkl, hkl1, hkl2);
+ add_merge_result(proj, strdup(job_title), hkl, hkl1, hkl2);
+ }
+ g_object_unref(workdir);
return job;
}
@@ -509,6 +589,19 @@ static void *run_indexing(const char *job_title,
char **args;
char **streams;
int i;
+ GFile *workdir;
+
+ workdir = make_job_folder(job_title, job_notes);
+ if ( workdir == NULL ) return NULL;
+
+ if ( write_file_list(workdir, "files.lst",
+ proj->filenames,
+ proj->events,
+ proj->n_frames) )
+ {
+ STATUS("Failed to write list\n");
+ return NULL;
+ }
snprintf(n_thread_str, 63, "%i", opts->n_processes);
args = indexamajig_command_line(proj->geom_filename,
@@ -524,8 +617,8 @@ static void *run_indexing(const char *job_title,
}
STATUS("\n");
- job = start_local_job(args, job_title, job_notes, proj,
- index_readable);
+ job = start_local_job(args, job_title, workdir,
+ proj, index_readable);
if ( job == NULL ) return NULL;
/* Indexing-specific job data */
diff --git a/src/gui_merge.c b/src/gui_merge.c
index ae94fd30..11d48117 100644
--- a/src/gui_merge.c
+++ b/src/gui_merge.c
@@ -522,3 +522,138 @@ char **merging_command_line(const char *n_thread_str,
return arg_strings;
}
+
+
+static int write_partialator_script(const char *filename,
+ struct gui_indexing_result *input,
+ const char *n_thread_str,
+ struct merging_params *params,
+ const char *out_hkl)
+{
+ FILE *fh;
+ char *exe_path;
+ int i;
+
+ fh = fopen(filename, "w");
+ if ( fh == NULL ) return 1;
+
+ exe_path = get_crystfel_exe("partialator");
+ if ( exe_path == NULL ) return 1;
+ fprintf(fh, "%s \\\n", exe_path);
+
+ for ( i=0; i<input->n_streams; i++ ) {
+ fprintf(fh, "%s \\\n", input->streams[i]);
+ }
+
+ fprintf(fh, " -j %s", n_thread_str);
+ fprintf(fh, " -o %s", out_hkl);
+ fprintf(fh, " -y %s", params->symmetry);
+
+ fprintf(fh, " --polarisation=%s", params->polarisation);
+ fprintf(fh, " --min-measurements=%i", params->min_measurements);
+ fprintf(fh, " --max-adu=%f", params->max_adu);
+ fprintf(fh, " --min-res=%f", params->min_res);
+ fprintf(fh, " --push-res=%f", params->push_res);
+
+ if ( params->twin_sym != NULL ) {
+ fprintf(fh, " -w %s", params->twin_sym);
+ }
+
+ if ( params->custom_split != NULL ) {
+ fprintf(fh, " --custom-split=%s", params->custom_split);
+ }
+
+ if ( !params->scale ) {
+ fprintf(fh, " --no-scale");
+ }
+
+ if ( !params->bscale ) {
+ fprintf(fh, " --no-bscale");
+ }
+
+ if ( !params->postref ) {
+ fprintf(fh, " --no-pr");
+ }
+
+ if ( !params->deltacchalf ) {
+ fprintf(fh, " --no-deltacchalf");
+ }
+
+ fprintf(fh, " --iterations=%i", params->niter);
+
+ fprintf(fh, "\n");
+
+ fclose(fh);
+ return 0;
+}
+
+
+static void add_process_hkl(FILE *fh,
+ const char *exe_path,
+ struct gui_indexing_result *input,
+ struct merging_params *params,
+ const char *out_hkl,
+ const char *extra_arg,
+ const char *out_suffix)
+{
+ int i;
+
+ fprintf(fh, "%s \\\n", exe_path);
+
+ for ( i=0; i<input->n_streams; i++ ) {
+ fprintf(fh, " %s \\\n", input->streams[i]);
+ }
+
+ fprintf(fh, " -o %s%s", out_hkl, out_suffix);
+ fprintf(fh, " -y %s", params->symmetry);
+
+ if ( params->scale ) {
+ fprintf(fh, " --scale");
+ }
+
+ fprintf(fh, " --polarisation=%s", params->polarisation);
+ fprintf(fh, " --min-measurements=%i", params->min_measurements);
+ fprintf(fh, " --max-adu=%f", params->max_adu);
+ fprintf(fh, " --min-res=%f", params->min_res);
+ fprintf(fh, " --push-res=%f", params->push_res);
+ fprintf(fh, " %s\n", extra_arg);
+}
+
+
+static int write_process_hkl_script(const char *filename,
+ struct gui_indexing_result *input,
+ struct merging_params *params,
+ const char *out_hkl)
+{
+ FILE *fh;
+ char *exe_path;
+
+ fh = fopen(filename, "w");
+ if ( fh == NULL ) return 1;
+
+ exe_path = get_crystfel_exe("process_hkl");
+ if ( exe_path == NULL ) return 1;
+
+ add_process_hkl(fh, exe_path, input, params, out_hkl, "", "");
+ add_process_hkl(fh, exe_path, input, params, out_hkl, "--even-only", "1");
+ add_process_hkl(fh, exe_path, input, params, out_hkl, "--odd-only", "2");
+
+ fclose(fh);
+ return 0;
+}
+
+
+int write_merge_script(const char *filename,
+ struct gui_indexing_result *input,
+ const char *n_thread_str,
+ struct merging_params *params,
+ const char *out_hkl)
+{
+ if ( strcmp(params->model, "process_hkl") == 0 ) {
+ return write_process_hkl_script(filename, input,
+ params, out_hkl);
+ } else {
+ return write_partialator_script(filename, input, n_thread_str,
+ params, out_hkl);
+ }
+}
diff --git a/src/gui_merge.h b/src/gui_merge.h
index 978a3dcd..46d6dcaf 100644
--- a/src/gui_merge.h
+++ b/src/gui_merge.h
@@ -40,4 +40,10 @@ extern char **merging_command_line(const char *n_thread_str,
struct gui_indexing_result *input,
struct merging_params *params);
+extern int write_merge_script(const char *filename,
+ struct gui_indexing_result *input,
+ const char *n_thread_str,
+ struct merging_params *params,
+ const char *out_hkl);
+
#endif