From c0fa862b74eb54da3e4d5e859ef6ac5775509f29 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 29 Oct 2020 11:41:18 +0100 Subject: Tedious option plumbing --- src/gui_backend_local.c | 52 +++++++++++++-- src/gui_merge.c | 42 ++++++------ src/gui_project.c | 173 ++++++++++++++++++++++++++++++++++++++++++++---- src/gui_project.h | 61 ++++++++++++----- 4 files changed, 271 insertions(+), 57 deletions(-) diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c index 28b6e0ec..4c5bf907 100644 --- a/src/gui_backend_local.c +++ b/src/gui_backend_local.c @@ -45,7 +45,7 @@ struct local_indexing_opts }; -struct local_merge_opts +struct local_merging_opts { int n_threads; }; @@ -376,7 +376,7 @@ static void read_indexing_opt(void *opts_priv, static void n_threads_activate_sig(GtkEntry *entry, gpointer data) { - struct local_merge_opts *opts = data; + struct local_merging_opts *opts = data; convert_int(gtk_entry_get_text(entry), &opts->n_threads); } @@ -389,9 +389,9 @@ static gboolean n_threads_focus_sig(GtkEntry *entry, GdkEvent *event, } -static GtkWidget *make_merge_parameters_widget(void *opts_priv) +static GtkWidget *make_merging_parameters_widget(void *opts_priv) { - struct local_merge_opts *opts = opts_priv; + struct local_merging_opts *opts = opts_priv; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *entry; @@ -423,21 +423,59 @@ static GtkWidget *make_merge_parameters_widget(void *opts_priv) } +static void *run_merging(const char *job_title, + const char *job_notes, + struct crystfelproject *proj, + void *opts_priv) +{ + return NULL; +} + + +static void write_merging_opts(void *opts_priv, FILE *fh) +{ + struct local_merging_opts *opts = opts_priv; + + fprintf(fh, "merging.local.n_threads %i\n", + opts->n_threads); +} + + +static void read_merging_opt(void *opts_priv, + const char *key, + const char *val) +{ + struct local_merging_opts *opts = opts_priv; + + if ( strcmp(key, "merging.local.n_threads") == 0 ) { + if ( convert_int(val, &opts->n_threads) ) { + ERROR("Invalid number of threads: %s\n", val); + } + } +} + + 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_task = cancel_task; be->task_status = get_task_status; + + be->make_indexing_parameters_widget = make_indexing_parameters_widget; + be->run_indexing = run_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; - be->make_merge_parameters_widget = make_merge_parameters_widget; + be->make_merging_parameters_widget = make_merging_parameters_widget; + be->run_merging = run_merging; + be->merging_opts_priv = make_default_local_opts(); + if ( be->merging_opts_priv == NULL ) return 1; + be->write_merging_opts = write_merging_opts; + be->read_merging_opt = read_merging_opt; return 0; }; diff --git a/src/gui_merge.c b/src/gui_merge.c index ad108933..b3320ac0 100644 --- a/src/gui_merge.c +++ b/src/gui_merge.c @@ -42,7 +42,7 @@ #include "crystfelmergeopts.h" -struct new_merge_job_params { +struct new_merging_job_params { struct crystfelproject *proj; GtkWidget *backend_combo; GtkWidget *backend_opts_widget; @@ -53,14 +53,14 @@ struct new_merge_job_params { }; -static void free_new_merge_job_params(gpointer njp, GClosure *closure) +static void free_new_merging_job_params(gpointer njp, GClosure *closure) { free(njp); } -static void merge_response_sig(GtkWidget *dialog, gint resp, - struct new_merge_job_params *njp) +static void merging_response_sig(GtkWidget *dialog, gint resp, + struct new_merging_job_params *njp) { if ( resp == GTK_RESPONSE_OK ) { STATUS("Doing it!\n"); @@ -68,8 +68,8 @@ static void merge_response_sig(GtkWidget *dialog, gint resp, } -static GtkWidget *make_merge_job_opts(struct crystfelproject *proj, - struct new_merge_job_params *njp) +static GtkWidget *make_merging_job_opts(struct crystfelproject *proj, + struct new_merging_job_params *njp) { GtkWidget *box; GtkWidget *hbox; @@ -88,9 +88,9 @@ static GtkWidget *make_merge_job_opts(struct crystfelproject *proj, njp->job_title_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(njp->job_title_entry), TRUE, TRUE, 2.0); - if ( proj->merge_new_job_title != NULL ) { + if ( proj->merging_new_job_title != NULL ) { gtk_entry_set_text(GTK_ENTRY(njp->job_title_entry), - proj->merge_new_job_title); + proj->merging_new_job_title); } label = gtk_label_new("This name will be used for a working subfolder"); @@ -125,15 +125,15 @@ static GtkWidget *make_merge_job_opts(struct crystfelproject *proj, } -static void merge_backend_changed_sig(GtkWidget *combo, - struct new_merge_job_params *njp) +static void merging_backend_changed_sig(GtkWidget *combo, + struct new_merging_job_params *njp) { int backend_idx; struct crystfel_backend *be; backend_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); if ( backend_idx < 0 ) return; - njp->proj->merge_backend_selected = backend_idx; + njp->proj->merging_backend_selected = backend_idx; be = &njp->proj->backends[backend_idx]; @@ -141,7 +141,7 @@ static void merge_backend_changed_sig(GtkWidget *combo, gtk_widget_destroy(njp->backend_opts_widget); } - njp->backend_opts_widget = be->make_merge_parameters_widget(be->merge_opts_priv); + njp->backend_opts_widget = be->make_merging_parameters_widget(be->merging_opts_priv); gtk_box_pack_start(GTK_BOX(njp->backend_opts_box), GTK_WIDGET(njp->backend_opts_widget), @@ -150,7 +150,7 @@ static void merge_backend_changed_sig(GtkWidget *combo, } -static GtkWidget *make_merge_backend_opts(struct new_merge_job_params *njp) +static GtkWidget *make_merging_backend_opts(struct new_merging_job_params *njp) { GtkWidget *box; GtkWidget *hbox; @@ -186,9 +186,9 @@ static GtkWidget *make_merge_backend_opts(struct new_merge_job_params *njp) /* njp->backend_opts{_box} must exist before the following */ g_signal_connect(G_OBJECT(njp->backend_combo), "changed", - G_CALLBACK(merge_backend_changed_sig), njp); + G_CALLBACK(merging_backend_changed_sig), njp); gtk_combo_box_set_active(GTK_COMBO_BOX(njp->backend_combo), - njp->proj->merge_backend_selected); + njp->proj->merging_backend_selected); return box; } @@ -202,9 +202,9 @@ gint merge_sig(GtkWidget *widget, struct crystfelproject *proj) GtkWidget *backend_page; GtkWidget *job_page; GtkWidget *notebook; - struct new_merge_job_params *njp; + struct new_merging_job_params *njp; - njp = malloc(sizeof(struct new_merge_job_params)); + njp = malloc(sizeof(struct new_merging_job_params)); if ( njp == NULL ) return FALSE; njp->proj = proj; @@ -217,8 +217,8 @@ gint merge_sig(GtkWidget *widget, struct crystfelproject *proj) NULL); g_signal_connect_data(G_OBJECT(dialog), "response", - G_CALLBACK(merge_response_sig), - njp, free_new_merge_job_params, 0); + G_CALLBACK(merging_response_sig), + njp, free_new_merging_job_params, 0); vbox = gtk_vbox_new(FALSE, 0.0); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); @@ -229,12 +229,12 @@ gint merge_sig(GtkWidget *widget, struct crystfelproject *proj) gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(notebook), FALSE, FALSE, 8.0); - job_page = make_merge_job_opts(proj, njp); + job_page = make_merging_job_opts(proj, njp); gtk_notebook_prepend_page(GTK_NOTEBOOK(notebook), job_page, gtk_label_new("Job name/notes")); - backend_page = make_merge_backend_opts(njp); + backend_page = make_merging_backend_opts(njp); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), backend_page, gtk_label_new("Cluster/batch system")); diff --git a/src/gui_project.c b/src/gui_project.c index 0c7d5502..3e28e806 100644 --- a/src/gui_project.c +++ b/src/gui_project.c @@ -154,8 +154,8 @@ static int find_backend(const char *name, struct crystfelproject *proj) } -static void handle_var(const char *key, const char *val, - struct crystfelproject *proj) +static void parse_peaksearch_opt(const char *key, const char *val, + struct crystfelproject *proj) { if ( strcmp(key, "peak_search_params.method") == 0 ) { proj->peak_search_params.method = parse_peaksearch(val); @@ -224,7 +224,12 @@ static void handle_var(const char *key, const char *val, if ( strcmp(key, "peak_search_params.revalidate") == 0 ) { proj->peak_search_params.revalidate = parse_int(val); } +} + +static void parse_indexing_opt(const char *key, const char *val, + struct crystfelproject *proj) +{ if ( strcmp(key, "indexing.cell_file") == 0 ) { proj->indexing_params.cell_file = strdup(val); } @@ -260,16 +265,12 @@ static void handle_var(const char *key, const char *val, if ( strcmp(key, "indexing.min_peaks") == 0 ) { proj->indexing_params.min_peaks = parse_int(val); } +} - if ( strcmp(key, "indexing.new_job_title") == 0 ) { - free(proj->indexing_new_job_title); - proj->indexing_new_job_title = strdup(val); - } - - if ( strcmp(key, "indexing.backend") == 0 ) { - proj->indexing_backend_selected = find_backend(val, proj); - } +static void parse_integration_opt(const char *key, const char *val, + struct crystfelproject *proj) +{ if ( strcmp(key, "integration.method") == 0 ) { proj->indexing_params.integration_method = strdup(val); } @@ -293,6 +294,90 @@ static void handle_var(const char *key, const char *val, if ( strcmp(key, "integration.ir_out") == 0 ) { proj->indexing_params.ir_out = parse_float(val); } +} + + +static void parse_merging_opt(const char *key, const char *val, + struct crystfelproject *proj) +{ + if ( strcmp(key, "merging.model") == 0 ) { + proj->merging_params.model = strdup(val); + } + + if ( strcmp(key, "merging.symmetry") == 0 ) { + proj->merging_params.symmetry = strdup(val); + } + + if ( strcmp(key, "merging.scale") == 0 ) { + proj->merging_params.scale = parse_int(val); + } + + if ( strcmp(key, "merging.bscale") == 0 ) { + proj->merging_params.bscale = parse_int(val); + } + + if ( strcmp(key, "merging.postref") == 0 ) { + proj->merging_params.postref = parse_int(val); + } + + if ( strcmp(key, "merging.niter") == 0 ) { + proj->merging_params.niter = parse_int(val); + } + + if ( strcmp(key, "merging.polarisation") == 0 ) { + proj->merging_params.polarisation = strdup(val); + } + + if ( strcmp(key, "merging.deltacchalf") == 0 ) { + proj->merging_params.deltacchalf = parse_int(val); + } + + if ( strcmp(key, "merging.min_measurements") == 0 ) { + proj->merging_params.min_measurements = parse_int(val); + } + + if ( strcmp(key, "merging.max_adu") == 0 ) { + proj->merging_params.max_adu = parse_float(val); + } + + if ( strcmp(key, "merging.custom_split") == 0 ) { + proj->merging_params.custom_split = strdup(val); + } + + if ( strcmp(key, "merging.twin_sym") == 0 ) { + proj->merging_params.twin_sym = strdup(val); + } + + if ( strcmp(key, "merging.min_res") == 0 ) { + proj->merging_params.min_res = parse_float(val); + } + + if ( strcmp(key, "merging.push_res") == 0 ) { + proj->merging_params.push_res = parse_float(val); + } +} + + +static void handle_var(const char *key, const char *val, + struct crystfelproject *proj) +{ + if ( strcmp(key, "indexing.new_job_title") == 0 ) { + free(proj->indexing_new_job_title); + proj->indexing_new_job_title = strdup(val); + } + + if ( strcmp(key, "merging.new_job_title") == 0 ) { + free(proj->merging_new_job_title); + proj->merging_new_job_title = strdup(val); + } + + if ( strcmp(key, "indexing.backend") == 0 ) { + proj->indexing_backend_selected = find_backend(val, proj); + } + + if ( strcmp(key, "merging.backend") == 0 ) { + proj->merging_backend_selected = find_backend(val, proj); + } if ( strcmp(key, "show_peaks") == 0 ) { proj->show_peaks = parse_int(val); @@ -318,9 +403,13 @@ static void handle_var(const char *key, const char *val, proj->data_search_pattern = decode_matchtype(val); } - /* Backend indexing option? */ + if ( strncmp(key, "peak_search_params.", 19) == 0 ) { + parse_peaksearch_opt(key, val, proj); + } + if ( strncmp(key, "indexing.", 9) == 0 ) { int i; + parse_indexing_opt(key, val, proj); for ( i=0; in_backends; i++ ) { struct crystfel_backend *be; be = &proj->backends[i]; @@ -329,6 +418,20 @@ static void handle_var(const char *key, const char *val, } } + if ( strncmp(key, "integration.", 12) == 0 ) { + parse_integration_opt(key, val, proj); + } + + if ( strncmp(key, "merging.", 9) == 0 ) { + int i; + parse_merging_opt(key, val, proj); + for ( i=0; in_backends; i++ ) { + struct crystfel_backend *be; + be = &proj->backends[i]; + be->read_merging_opt(be->merging_opts_priv, + key, val); + } + } } @@ -637,6 +740,35 @@ int save_project(struct crystfelproject *proj) fprintf(fh, "integration.ir_out %f\n", proj->indexing_params.ir_out); + fprintf(fh, "merging.model %s\n", + proj->merging_params.model); + fprintf(fh, "merging.symmetry %s\n", + proj->merging_params.symmetry); + fprintf(fh, "merging.scale %i\n", + proj->merging_params.scale); + fprintf(fh, "merging.bscale %i\n", + proj->merging_params.bscale); + fprintf(fh, "merging.postref %i\n", + proj->merging_params.postref); + fprintf(fh, "merging.niter %i\n", + proj->merging_params.niter); + fprintf(fh, "merging.polarisation %s\n", + proj->merging_params.polarisation); + fprintf(fh, "merging.deltacchalf %i\n", + proj->merging_params.deltacchalf); + fprintf(fh, "merging.min_measurements %i\n", + proj->merging_params.min_measurements); + fprintf(fh, "merging.max_adu %f\n", + proj->merging_params.max_adu); + fprintf(fh, "merging.custom_split %s\n", + proj->merging_params.custom_split); + fprintf(fh, "merging.twin_sym %s\n", + proj->merging_params.twin_sym); + fprintf(fh, "merging.min_res %f\n", + proj->merging_params.min_res); + fprintf(fh, "merging.push_res %f\n", + proj->merging_params.push_res); + fprintf(fh, "show_peaks %i\n", proj->show_peaks); fprintf(fh, "show_refls %i\n", proj->show_refls); @@ -684,10 +816,10 @@ void default_project(struct crystfelproject *proj) proj->indexing_opts = NULL; proj->n_running_tasks = 0; proj->indexing_new_job_title = NULL; - proj->merge_new_job_title = NULL; + proj->merging_new_job_title = NULL; proj->indexing_backend_selected = 0; - proj->merge_backend_selected = 0; + proj->merging_backend_selected = 0; proj->n_backends = 0; proj->backends = malloc(2*sizeof(struct crystfel_backend)); /* FIXME: Crappy error handling */ @@ -749,6 +881,21 @@ void default_project(struct crystfelproject *proj) proj->indexing_params.ir_mid = 5.0; proj->indexing_params.ir_out = 7.0; + proj->merging_params.model = strdup("unity"); + proj->merging_params.symmetry = strdup("1"); + proj->merging_params.scale = 1; + proj->merging_params.bscale = 1; + proj->merging_params.postref = 0; + proj->merging_params.niter = 3; + proj->merging_params.polarisation = "horiz"; + proj->merging_params.deltacchalf = 1; + proj->merging_params.min_measurements = 2; + proj->merging_params.max_adu = INFINITY; + proj->merging_params.custom_split = NULL; + proj->merging_params.twin_sym = NULL; + proj->merging_params.min_res = 0.0; + proj->merging_params.push_res = INFINITY; + proj->results = NULL; proj->n_results = 0; } diff --git a/src/gui_project.h b/src/gui_project.h index af4b1037..315aa4ab 100644 --- a/src/gui_project.h +++ b/src/gui_project.h @@ -89,8 +89,22 @@ struct index_params { float ir_out; }; -struct merge_params { - int nothing; +struct merging_params { + + char *model; /* "process_hkl" in addition to xsphere/unity etc */ + char *symmetry; + int scale; + int bscale; + int postref; + int niter; + char *polarisation; + int deltacchalf; + int min_measurements; + float max_adu; + char *custom_split; + char *twin_sym; + float min_res; + float push_res; }; struct crystfelproject; @@ -100,6 +114,14 @@ struct crystfel_backend { const char *name; const char *friendly_name; + /* Called to ask the backend to cancel the job */ + void (*cancel_task)(void *job_priv); + + /* Called to get the status of a task */ + int (*task_status)(void *job_priv, + int *running, + float *fraction_complete); + /* Backend should provide a GTK widget to set options */ GtkWidget *(*make_indexing_parameters_widget)(void *opts_priv); @@ -110,14 +132,6 @@ struct crystfel_backend { struct crystfelproject *proj, void *opts_priv); - /* Called to ask the backend to cancel the job */ - void (*cancel_task)(void *job_priv); - - /* Called to get the status of a task */ - int (*task_status)(void *job_priv, - int *running, - float *fraction_complete); - /* Called to ask the backend to write its indexing options */ void (*write_indexing_opts)(void *opts_priv, FILE *fh); @@ -130,10 +144,25 @@ struct crystfel_backend { void *indexing_opts_priv; /* Backend should provide a GTK widget to set options */ - GtkWidget *(*make_merge_parameters_widget)(void *opts_priv); + GtkWidget *(*make_merging_parameters_widget)(void *opts_priv); + + /* Called to ask the backend to start merging data. + * It should return a void pointer representing this job */ + void *(*run_merging)(const char *job_title, + const char *job_notes, + struct crystfelproject *proj, + void *opts_priv); + + /* Called to ask the backend to write its merging options */ + void (*write_merging_opts)(void *opts_priv, FILE *fh); + + /* Called when reading a project from file */ + void (*read_merging_opt)(void *opts_priv, + const char *key, + const char *val); /* Backend should store options for merging here */ - void *merge_opts_priv; + void *merging_opts_priv; }; @@ -199,10 +228,10 @@ struct crystfelproject { GtkWidget *indexing_opts; char *indexing_new_job_title; - struct merge_params merge_params; - int merge_backend_selected; - GtkWidget *merge_opts; - char *merge_new_job_title; + struct merging_params merging_params; + int merging_backend_selected; + GtkWidget *merging_opts; + char *merging_new_job_title; GtkWidget *type_combo; GtkWidget *peak_vbox; /* Box for peak search parameter widgets */ -- cgit v1.2.3