From e13b2276d3949b3e7a185ddc8479ac65bfdfbf18 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 10 Jan 2024 14:19:26 +0100 Subject: GUI: Remove detector-shift The script has been replaced with align_detector --level=0. --- src/crystfel_gui.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index d0fab3b1..a51ec016 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -467,34 +467,6 @@ static gint rescan_sig(GtkWidget *widget, struct crystfelproject *proj) } -static gint detector_shift_sig(GtkWidget *widget, struct crystfelproject *proj) -{ - struct gui_indexing_result *res = current_result(proj); - if ( res != NULL ) { - GError *error = NULL; - const gchar *args[64]; - GSubprocess *sp; - int i; - args[0] = "detector-shift"; - args[1] = "--"; - for ( i=0; in_streams, 60); i++ ) { - args[2+i] = res->streams[i]; - } - args[2+res->n_streams] = NULL; - - sp = g_subprocess_newv(args, G_SUBPROCESS_FLAGS_NONE, &error); - if ( sp == NULL ) { - ERROR("Failed to invoke detector-shift: %s\n", - error->message); - g_error_free(error); - } - } else { - ERROR("Select indexing result first!\n"); - } - return FALSE; -} - - static gint peakogram_sig(GtkWidget *widget, struct crystfelproject *proj) { struct gui_indexing_result *res = current_result(proj); @@ -825,7 +797,6 @@ static void add_menu_bar(struct crystfelproject *proj, GtkWidget *vbox) " " " " " " - " " " " "" "" @@ -852,8 +823,6 @@ static void add_menu_bar(struct crystfelproject *proj, GtkWidget *vbox) G_CALLBACK(rescan_sig) }, { "JumpFrameAction", NULL, "Jump to frame", NULL, NULL, G_CALLBACK(goto_frame_sig) }, - { "DetectorShiftAction", NULL, "Check detector shift", NULL, NULL, - G_CALLBACK(detector_shift_sig) }, { "PeakogramAction", NULL, "Check detector saturation (peakogram)", NULL, NULL, G_CALLBACK(peakogram_sig) }, -- cgit v1.2.3 From 7c96ec848d3487d95b6733bbd4e29b5e2b77f5c6 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 10 Jan 2024 16:34:28 +0100 Subject: CrystFELIndexingOpts: Add Millepede output options --- src/crystfelindexingopts.c | 35 +++++++++++++++++++++++++++++++++++ src/crystfelindexingopts.h | 8 ++++++++ 2 files changed, 43 insertions(+) diff --git a/src/crystfelindexingopts.c b/src/crystfelindexingopts.c index d1cf515f..50a36748 100644 --- a/src/crystfelindexingopts.c +++ b/src/crystfelindexingopts.c @@ -734,6 +734,7 @@ static GtkWidget *stream_parameters(CrystFELIndexingOpts *io) GtkCellRenderer *renderer; GtkWidget *button; GtkWidget *hbox; + GtkWidget *label; box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); gtk_container_set_border_width(GTK_CONTAINER(box), 8); @@ -759,6 +760,24 @@ static GtkWidget *stream_parameters(CrystFELIndexingOpts *io) gtk_widget_set_tooltip_text(io->no_refls_in_stream, "--no-refls-in-stream"); + io->millepede = gtk_check_button_new_with_label("Write calibration data for detector alignment"); + gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(io->millepede), + FALSE, FALSE, 4.0); + gtk_widget_set_tooltip_text(io->millepede, "--mille"); + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(hbox), + FALSE, FALSE, 0.0); + label = gtk_label_new("Maximum refinement level:"); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), + FALSE, FALSE, 16.0); + io->max_mille = gtk_spin_button_new_with_range(0.0, 9.0, 1.0); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(io->max_mille), + FALSE, FALSE, 4.0); + gtk_widget_set_tooltip_text(io->max_mille, "--max-mille-level"); + i_disable_if_not(io->millepede, io->max_mille); + i_disable_if_not(io->millepede, label); + io->copy_metadata_store = gtk_list_store_new(1, G_TYPE_STRING); treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(io->copy_metadata_store)); @@ -1055,6 +1074,14 @@ int crystfel_indexing_opts_get_exclude_reflections(CrystFELIndexingOpts *opts) } +int crystfel_indexing_opts_get_millepede(CrystFELIndexingOpts *opts, + int *pmax_level) +{ + *pmax_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(opts->max_mille)); + return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(opts->millepede)); +} + + char **crystfel_indexing_opts_get_metadata_to_copy(CrystFELIndexingOpts *opts, int *pn) { @@ -1381,6 +1408,14 @@ void crystfel_indexing_opts_set_integration_radii(CrystFELIndexingOpts *opts, } +void crystfel_indexing_opts_set_millepede(CrystFELIndexingOpts *opts, + int enable, int max_level) +{ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(opts->max_mille), max_level); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opts->millepede), enable); +} + + void crystfel_indexing_opts_set_metadata_to_copy(CrystFELIndexingOpts *opts, char *const *headers, int n) diff --git a/src/crystfelindexingopts.h b/src/crystfelindexingopts.h index 567bdb8e..e87d2dac 100644 --- a/src/crystfelindexingopts.h +++ b/src/crystfelindexingopts.h @@ -96,6 +96,8 @@ struct _crystfelindexingopts GtkWidget *exclude_nonhits; GtkWidget *no_peaks_in_stream; GtkWidget *no_refls_in_stream; + GtkWidget *millepede; + GtkWidget *max_mille; GtkListStore *copy_metadata_store; }; @@ -133,6 +135,8 @@ extern int crystfel_indexing_opts_get_exclude_peaks(CrystFELIndexingOpts *opts); extern int crystfel_indexing_opts_get_exclude_reflections(CrystFELIndexingOpts *opts); extern char **crystfel_indexing_opts_get_metadata_to_copy(CrystFELIndexingOpts *opts, int *n); +extern int crystfel_indexing_opts_get_millepede(CrystFELIndexingOpts *opts, + int *pmax_level); extern double crystfel_indexing_opts_get_fixed_profile_radius(CrystFELIndexingOpts *opts, int *active); extern double crystfel_indexing_opts_get_fixed_divergence(CrystFELIndexingOpts *opts); @@ -191,6 +195,10 @@ extern void crystfel_indexing_opts_set_exclude_peaks(CrystFELIndexingOpts *opts, int flag); extern void crystfel_indexing_opts_set_exclude_reflections(CrystFELIndexingOpts *opts, int flag); + +extern void crystfel_indexing_opts_set_millepede(CrystFELIndexingOpts *opts, + int enable, int max_level); + extern void crystfel_indexing_opts_set_fixed_profile_radius(CrystFELIndexingOpts *opts, int active, double val); -- cgit v1.2.3 From 185941439dd7aa7211a5d98b0a543d8ad717d65e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 10 Jan 2024 16:43:29 +0100 Subject: GUI: Track Millepede options through project Note that the indexamajig option --max-mille-level isn't implemented yet. --- src/gui_index.c | 7 +++++++ src/gui_project.c | 12 ++++++++++++ src/gui_project.h | 2 ++ 3 files changed, 21 insertions(+) diff --git a/src/gui_index.c b/src/gui_index.c index aa2301ef..14f0906c 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -140,6 +140,8 @@ static void get_indexing_opts(struct crystfelproject *proj, proj->indexing_params.exclude_nonhits = crystfel_indexing_opts_get_exclude_blanks(opts); proj->indexing_params.exclude_peaks = crystfel_indexing_opts_get_exclude_peaks(opts); proj->indexing_params.exclude_refls = crystfel_indexing_opts_get_exclude_reflections(opts); + proj->indexing_params.millepede = crystfel_indexing_opts_get_millepede(opts, + &proj->indexing_params.max_mille_level); proj->indexing_params.metadata_to_copy = crystfel_indexing_opts_get_metadata_to_copy(opts, &proj->indexing_params.n_metadata); } @@ -383,6 +385,9 @@ static void set_indexing_opts(struct crystfelproject *proj, proj->indexing_params.exclude_peaks); crystfel_indexing_opts_set_exclude_reflections(opts, proj->indexing_params.exclude_refls); + crystfel_indexing_opts_set_millepede(opts, + proj->indexing_params.millepede, + proj->indexing_params.max_mille_level); crystfel_indexing_opts_set_metadata_to_copy(opts, proj->indexing_params.metadata_to_copy, proj->indexing_params.n_metadata); @@ -997,6 +1002,8 @@ static char **indexamajig_command_line(const char *geom_filename, if ( indexing_params->exclude_nonhits ) add_arg(args, n_args++, "--no-non-hits-in-stream"); if ( indexing_params->exclude_peaks ) add_arg(args, n_args++, "--no-peaks-in-stream"); if ( indexing_params->exclude_refls ) add_arg(args, n_args++, "--no-refls-in-stream"); + if ( indexing_params->millepede ) add_arg(args, n_args++, "--millepede"); + if ( indexing_params->max_mille_level ) add_arg(args, n_args++, "--max-mille-level"); for ( i=0; in_metadata; i++ ) { add_arg_string(args, n_args++, "copy-header", indexing_params->metadata_to_copy[i]); diff --git a/src/gui_project.c b/src/gui_project.c index 32d6473c..c77e2704 100644 --- a/src/gui_project.c +++ b/src/gui_project.c @@ -429,6 +429,12 @@ static void parse_stream_opt(const char *key, const char *val, if ( strcmp(key, "stream.exclude_refls") == 0 ) { ip->exclude_refls = parse_int(val); } + if ( strcmp(key, "stream.millepede") == 0 ) { + ip->millepede = parse_int(val); + } + if ( strcmp(key, "stream.max_mille_level") == 0 ) { + ip->max_mille_level = parse_int(val); + } if ( strcmp(key, "stream.metadata") == 0 ) { add_metadata_to_copy(ip, val); } @@ -1048,6 +1054,10 @@ int save_project(struct crystfelproject *proj) proj->indexing_params.exclude_peaks); fprintf(fh, "stream.exclude_refls %i\n", proj->indexing_params.exclude_refls); + fprintf(fh, "stream.millepede %i\n", + proj->indexing_params.millepede); + fprintf(fh, "stream.max_mille_level %i\n", + proj->indexing_params.max_mille_level); if ( proj->indexing_params.metadata_to_copy != NULL ) { int i; for ( i=0; iindexing_params.n_metadata; i++ ) { @@ -1287,6 +1297,8 @@ int default_project(struct crystfelproject *proj) proj->indexing_params.exclude_nonhits = 0; proj->indexing_params.exclude_peaks = 0; proj->indexing_params.exclude_refls = 0; + proj->indexing_params.millepede = 1; + proj->indexing_params.max_mille_level = 1; proj->indexing_params.metadata_to_copy = NULL; proj->indexing_params.n_metadata = 0; proj->indexing_params.fix_profile_radius = 0.01e9; diff --git a/src/gui_project.h b/src/gui_project.h index 318f9453..6d704b81 100644 --- a/src/gui_project.h +++ b/src/gui_project.h @@ -87,6 +87,8 @@ struct index_params { int exclude_refls; char **metadata_to_copy; int n_metadata; + int millepede; + int max_mille_level; }; struct merging_params { -- cgit v1.2.3 From 8ad1eddff0b3f020581e1852448752145656d16d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 10 Jan 2024 16:50:40 +0100 Subject: indexamajig: Start implementing --max-mille-level --- src/indexamajig.c | 13 +++++++++++-- src/process_image.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/indexamajig.c b/src/indexamajig.c index cca7dbba..fd95a01c 100644 --- a/src/indexamajig.c +++ b/src/indexamajig.c @@ -748,6 +748,14 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) args->iargs.milledir = strdup(arg); break; + case 418 : + if (sscanf(arg, "%d", &args->iargs.max_mille_level) != 1) + { + ERROR("Invalid value for --max-mille-level\n"); + return EINVAL; + } + break; + /* ---------- Integration ---------- */ case 501 : @@ -996,6 +1004,7 @@ int main(int argc, char *argv[]) args.iargs.data_format = DATA_SOURCE_TYPE_UNKNOWN; args.iargs.mille = 0; args.iargs.milledir = strdup("."); + args.iargs.max_mille_level = 99; argp_program_version_hook = show_version; @@ -1122,8 +1131,8 @@ int main(int argc, char *argv[]) "Estimate of the camera length, in metres."}, {"mille", 416, NULL, 0, "Generate data for detector geometry refinement using Millepede"}, - {"mille-dir", 417, "dirname", 0, - "Save Millepede data in folder"}, + {"mille-dir", 417, "dirname", 0, "Save Millepede data in folder"}, + {"max-mille-level", 418, "n", 0, "Maximum geometry refinement level"}, {NULL, 0, 0, OPTION_DOC, "Integration options:", 5}, {"integration", 501, "method", OPTION_NO_USAGE, "Integration method"}, diff --git a/src/process_image.h b/src/process_image.h index f5e27631..10c9ec31 100644 --- a/src/process_image.h +++ b/src/process_image.h @@ -76,6 +76,7 @@ struct index_args int n_threads; int mille; char *milledir; + int max_mille_level; /* Integration */ IntegrationMethod int_meth; -- cgit v1.2.3 From 2058e8e032575c6b267271522778c9beb3d8b0aa Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 10 Jan 2024 16:49:41 +0100 Subject: GUI: Skeleton task for detector alignment --- data/crystfel.gresource.xml | 1 + meson.build | 1 + src/crystfel_gui.c | 3 ++ src/gui_align.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ src/gui_align.h | 38 ++++++++++++++ 5 files changed, 166 insertions(+) create mode 100644 src/gui_align.c create mode 100644 src/gui_align.h diff --git a/data/crystfel.gresource.xml b/data/crystfel.gresource.xml index c000973a..fa7a1752 100644 --- a/data/crystfel.gresource.xml +++ b/data/crystfel.gresource.xml @@ -21,5 +21,6 @@ crystfel-merge.png crystfel-peak-detection.png crystfel-unitcell.png + crystfel-geometry.png diff --git a/meson.build b/meson.build index 248a75fa..d0cb0081 100644 --- a/meson.build +++ b/meson.build @@ -218,6 +218,7 @@ if gtkdep.found() 'src/gui_fom.c', 'src/gui_export.c', 'src/gui_ambi.c', + 'src/gui_align.c', 'src/gui_backend_local.c', 'src/gui_backend_slurm.c', 'src/gui_project.c', diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index a51ec016..b3d3bc3f 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -56,6 +56,7 @@ #include "gui_merge.h" #include "gui_fom.h" #include "gui_export.h" +#include "gui_align.h" #include "gui_ambi.h" #include "gui_project.h" #include "version.h" @@ -902,6 +903,8 @@ static void add_task_buttons(GtkWidget *vbox, struct crystfelproject *proj) G_CALLBACK(index_all_sig), proj); add_button(vbox, "Determine unit cell", "crystfel-unitcell", G_CALLBACK(cell_explorer_sig), proj); + add_button(vbox, "Refine detector geometry", "crystfel-geometry", + G_CALLBACK(align_sig), proj); add_button(vbox, "Indexing ambiguity", "crystfel-ambiguity", G_CALLBACK(ambi_sig), proj); add_button(vbox, "Merge", "crystfel-merge", diff --git a/src/gui_align.c b/src/gui_align.c new file mode 100644 index 00000000..5c559878 --- /dev/null +++ b/src/gui_align.c @@ -0,0 +1,123 @@ +/* + * gui_align.c + * + * Align detector via CrystFEL GUI + * + * Copyright © 2024 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2024 Thomas White + * + * 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 . + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "version.h" +#include "gui_project.h" +#include "crystfel_gui.h" +#include "gtk-util-routines.h" + + +struct align_window +{ + struct crystfelproject *proj; + GtkWidget *window; + GtkWidget *out_of_plane; + GtkWidget *level; +}; + + +static int run_align(struct align_window *win) +{ + STATUS("Mock detector alignment!\n"); + return 0; +} + + +static void align_response_sig(GtkWidget *dialog, gint resp, + struct align_window *win) +{ + int r = 0; + + if ( resp == GTK_RESPONSE_ACCEPT ) { + r = run_align(win); + } + + if ( !r ) gtk_widget_destroy(dialog); +} + + +gint align_sig(GtkWidget *widget, struct crystfelproject *proj) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *content_area; + struct align_window *win; + + win = malloc(sizeof(struct align_window)); + if ( win == NULL ) return 0; + + win->proj = proj; + + win->window = gtk_dialog_new_with_buttons("Align detector", + GTK_WINDOW(proj->window), + GTK_DIALOG_DESTROY_WITH_PARENT, + "Cancel", GTK_RESPONSE_CANCEL, + "Run", GTK_RESPONSE_OK, + NULL); + + vbox = gtk_vbox_new(FALSE, 0.0); + content_area = gtk_dialog_get_content_area(GTK_DIALOG(win->window)); + gtk_box_pack_start(GTK_BOX(content_area), GTK_WIDGET(vbox), TRUE, TRUE, 0.0); + gtk_container_set_border_width(GTK_CONTAINER(content_area), 8); + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), + FALSE, FALSE, 0.0); + label = gtk_label_new("Refinement level:"); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), + FALSE, FALSE, 16.0); + win->level = gtk_spin_button_new_with_range(0.0, 9.0, 1.0); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(win->level), + FALSE, FALSE, 4.0); + gtk_widget_set_tooltip_text(win->level, "--level"); + + win->out_of_plane = gtk_check_button_new_with_label("Refine out-of-plane positions and tilts"); + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(win->out_of_plane), + FALSE, FALSE, 4.0); + gtk_widget_set_tooltip_text(win->out_of_plane, "--out-of-plane"); + + g_signal_connect(G_OBJECT(win->window), "response", + G_CALLBACK(align_response_sig), win); + + gtk_dialog_set_default_response(GTK_DIALOG(win->window), + GTK_RESPONSE_CLOSE); + gtk_widget_show_all(win->window); + + return FALSE; +} diff --git a/src/gui_align.h b/src/gui_align.h new file mode 100644 index 00000000..50250e6a --- /dev/null +++ b/src/gui_align.h @@ -0,0 +1,38 @@ +/* + * gui_align.h + * + * Align detector via CrystFEL GUI + * + * Copyright © 2024 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2024 Thomas White + * + * 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 . + * + */ + +#ifndef GUI_ALIGN_H +#define GUI_ALIGN_H + +#include + +#include "gui_project.h" + +extern gint align_sig(GtkWidget *widget, struct crystfelproject *proj); + +#endif -- cgit v1.2.3 From 9df20aacc1225ca94e0889c51371a96d626df5bd Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 11 Jan 2024 15:14:56 +0100 Subject: GUI: Switch to GtkFileChooserDialog for detector alignment Rationale: the refinement is very quick, and the output geometry file name is central to the process. --- src/gui_align.c | 74 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/src/gui_align.c b/src/gui_align.c index 5c559878..853919ae 100644 --- a/src/gui_align.c +++ b/src/gui_align.c @@ -46,14 +46,19 @@ struct align_window { struct crystfelproject *proj; GtkWidget *window; + GtkWidget *input_combo; GtkWidget *out_of_plane; GtkWidget *level; }; -static int run_align(struct align_window *win) +static int run_align(const char *input_name, int level, int out_of_plane, + const char *out_geom) { - STATUS("Mock detector alignment!\n"); + STATUS("Mock detector alignment from run '%s', level %i, %s -----> %s\n", + input_name, level, out_of_plane ? "out of plane" : "in plane", + out_geom); + return 0; } @@ -64,7 +69,26 @@ static void align_response_sig(GtkWidget *dialog, gint resp, int r = 0; if ( resp == GTK_RESPONSE_ACCEPT ) { - r = run_align(win); + + int level; + const char *input_name; + int out_of_plane; + gchar *filename; + + level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(win->level)); + + input_name = get_combo_id(win->input_combo); + if ( input_name == NULL ) { + ERROR("Please select the input\n"); + r = 1; + } + + out_of_plane = get_bool(win->out_of_plane); + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + r = run_align(input_name, level, out_of_plane, filename); + + g_free(filename); } if ( !r ) gtk_widget_destroy(dialog); @@ -73,33 +97,45 @@ static void align_response_sig(GtkWidget *dialog, gint resp, gint align_sig(GtkWidget *widget, struct crystfelproject *proj) { - GtkWidget *vbox; GtkWidget *hbox; GtkWidget *label; - GtkWidget *content_area; struct align_window *win; + int i; win = malloc(sizeof(struct align_window)); if ( win == NULL ) return 0; win->proj = proj; - win->window = gtk_dialog_new_with_buttons("Align detector", + win->window = gtk_file_chooser_dialog_new("Align detector", GTK_WINDOW(proj->window), - GTK_DIALOG_DESTROY_WITH_PARENT, - "Cancel", GTK_RESPONSE_CANCEL, - "Run", GTK_RESPONSE_OK, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(win->window), + TRUE); + + hbox = gtk_hbox_new(FALSE, 0.0); + gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(win->window), + GTK_WIDGET(hbox)); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 4); - vbox = gtk_vbox_new(FALSE, 0.0); - content_area = gtk_dialog_get_content_area(GTK_DIALOG(win->window)); - gtk_box_pack_start(GTK_BOX(content_area), GTK_WIDGET(vbox), TRUE, TRUE, 0.0); - gtk_container_set_border_width(GTK_CONTAINER(content_area), 8); + label = gtk_label_new("Refine using indexing result:"); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), + FALSE, FALSE, 4.0); + win->input_combo = gtk_combo_box_text_new(); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(win->input_combo), + FALSE, FALSE, 4.0); + for ( i=0; in_results; i++ ) { + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(win->input_combo), + proj->results[i].name, + proj->results[i].name); + } + gtk_combo_box_set_active_id(GTK_COMBO_BOX(win->input_combo), + selected_result(proj)); - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), - FALSE, FALSE, 0.0); - label = gtk_label_new("Refinement level:"); + label = gtk_label_new("Hierarchy level:"); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), FALSE, FALSE, 16.0); win->level = gtk_spin_button_new_with_range(0.0, 9.0, 1.0); @@ -107,8 +143,8 @@ gint align_sig(GtkWidget *widget, struct crystfelproject *proj) FALSE, FALSE, 4.0); gtk_widget_set_tooltip_text(win->level, "--level"); - win->out_of_plane = gtk_check_button_new_with_label("Refine out-of-plane positions and tilts"); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(win->out_of_plane), + win->out_of_plane = gtk_check_button_new_with_label("Include out-of-plane positions and tilts"); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(win->out_of_plane), FALSE, FALSE, 4.0); gtk_widget_set_tooltip_text(win->out_of_plane, "--out-of-plane"); -- cgit v1.2.3 From ee91037250512f7fad13411799633e7cda99ac15 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 11 Jan 2024 16:57:02 +0100 Subject: GUI: Implement align_detector --- src/gui_align.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/src/gui_align.c b/src/gui_align.c index 853919ae..b712681b 100644 --- a/src/gui_align.c +++ b/src/gui_align.c @@ -52,12 +52,88 @@ struct align_window }; + static int run_align(const char *input_name, int level, int out_of_plane, - const char *out_geom) + const char *out_geom, struct crystfelproject *proj) { - STATUS("Mock detector alignment from run '%s', level %i, %s -----> %s\n", - input_name, level, out_of_plane ? "out of plane" : "in plane", - out_geom); + GSubprocess *sp; + struct gui_indexing_result *res; + GError *error; + const char *cmdline[16]; + char level_str[64]; + GFile *gstream; + GFile *gworkdir; + GFile *ggeom; + GFile *gmilledir; + char *input_geom; + int i; + char *mille_dir; + + res = find_indexing_result_by_name(proj, input_name); + if ( res == NULL ) { + ERROR("Results for '%s' not found!\n", input_name); + return 1; + } + + /* Figure out working directory for indexing job */ + if ( res->n_streams < 1 ) { + ERROR("No streams?\n"); + return 1; + } + gstream = g_file_new_for_path(res->streams[0]); + gworkdir = g_file_get_parent(gstream); + g_object_unref(gstream); + + /* Look for Millepede files */ + gmilledir = g_file_get_child(gworkdir, "mille-data"); + if ( !g_file_query_exists(gmilledir, NULL) ) { + ERROR("No detector alignment data found for indexing run '%s'\n", input_name); + return 1; + } + mille_dir = g_file_get_path(gmilledir); + g_object_unref(gmilledir); + + /* Input geometry file */ + ggeom = g_file_get_child(gworkdir, "detector.geom"); + input_geom = g_file_get_path(ggeom); + g_object_unref(ggeom); + + /* Build command line */ + snprintf(level_str, 63, "%i", level); + cmdline[0] = "align_detector"; + cmdline[1] = "-g"; + cmdline[2] = input_geom; + cmdline[3] = "--level"; + cmdline[4] = level_str; + cmdline[5] = "-o"; + cmdline[6] = out_geom; + if ( out_of_plane ) { + cmdline[7] = "--out-of-plane"; + cmdline[8] = mille_dir; + cmdline[9] = NULL; + } else { + cmdline[7] = mille_dir; + cmdline[8] = NULL; + } + + STATUS("Running program: "); + i = 0; + while ( cmdline[i] != NULL ) { + STATUS("%s ", cmdline[i++]); + } + STATUS("\n"); + + error = NULL; + sp = g_subprocess_newv(cmdline, G_SUBPROCESS_FLAGS_NONE, &error); + if ( sp == NULL ) { + ERROR("Failed to run align_detector: %s\n", error->message); + g_error_free(error); + return 1; + } + + g_object_unref(gworkdir); + g_free(mille_dir); + g_free(input_geom); return 0; } @@ -86,7 +162,7 @@ static void align_response_sig(GtkWidget *dialog, gint resp, out_of_plane = get_bool(win->out_of_plane); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - r = run_align(input_name, level, out_of_plane, filename); + r = run_align(input_name, level, out_of_plane, filename, win->proj); g_free(filename); } -- cgit v1.2.3 From c2ba0eb77f0da8ba825ede18eb1c6e6d5bee424a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 11 Jan 2024 17:05:29 +0100 Subject: GUI: Write Millepede data into folder --- src/gui_backend_local.c | 4 ++++ src/gui_backend_slurm.c | 4 ++++ src/gui_index.c | 8 +++++++- src/gui_index.h | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c index 03761474..d2068250 100644 --- a/src/gui_backend_local.c +++ b/src/gui_backend_local.c @@ -534,6 +534,7 @@ static void *run_indexing(const char *job_title, gchar *files_rel_filename; gchar *stream_rel_filename; gchar *harvest_rel_filename; + gchar *mille_rel_filename; workdir = make_job_folder(job_title, job_notes); if ( workdir == NULL ) return NULL; @@ -555,6 +556,7 @@ static void *run_indexing(const char *job_title, files_rel_filename = relative_to_cwd(workdir, "files.lst"); stream_rel_filename = relative_to_cwd(workdir, "crystfel.stream"); harvest_rel_filename = relative_to_cwd(workdir, "parameters.json"); + mille_rel_filename = relative_to_cwd(workdir, "mille-data"); if ( !write_indexamajig_script(sc_rel_filename, proj->geom_filename, @@ -564,6 +566,7 @@ static void *run_indexing(const char *job_title, stdout_rel_filename, stderr_rel_filename, harvest_rel_filename, + mille_rel_filename, NULL, &proj->peak_search_params, &proj->indexing_params, @@ -598,6 +601,7 @@ static void *run_indexing(const char *job_title, free(stdout_rel_filename); free(stderr_rel_filename); free(harvest_rel_filename); + free(mille_rel_filename); return job; } diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c index 3961a92d..f5ad31c5 100644 --- a/src/gui_backend_slurm.c +++ b/src/gui_backend_slurm.c @@ -797,6 +797,7 @@ static void *run_indexing(const char *job_title, gchar *files_rel_filename; gchar *stream_rel_filename; gchar *harvest_rel_filename; + gchar *mille_rel_filename; char *slurm_prologue; workdir = make_job_folder(job_title, job_notes); @@ -842,6 +843,7 @@ static void *run_indexing(const char *job_title, stdout_rel_filename = relative_to_cwd(workdir, "stdout-%a.log"); stderr_rel_filename = relative_to_cwd(workdir, "stderr-%a.log"); harvest_rel_filename = relative_to_cwd(workdir, "parameters.json"); + mille_rel_filename = relative_to_cwd(workdir, "mille-data"); slurm_prologue = sbatch_bits(&opts->common, job_title, array_inx, stdout_rel_filename, stderr_rel_filename); @@ -853,6 +855,7 @@ static void *run_indexing(const char *job_title, stream_rel_filename, NULL, NULL, harvest_rel_filename, + mille_rel_filename, serial_offs, &proj->peak_search_params, &proj->indexing_params, @@ -888,6 +891,7 @@ static void *run_indexing(const char *job_title, free(stdout_rel_filename); free(stderr_rel_filename); free(harvest_rel_filename); + free(mille_rel_filename); g_object_unref(workdir); return job; diff --git a/src/gui_index.c b/src/gui_index.c index 14f0906c..3241503c 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -851,6 +851,7 @@ static char **indexamajig_command_line(const char *geom_filename, const char *files_list, const char *stream_filename, const char *harvest_filename, + const char *mille_filename, const char *serial_start, struct peak_params *peak_search_params, struct index_params *indexing_params, @@ -1002,7 +1003,10 @@ static char **indexamajig_command_line(const char *geom_filename, if ( indexing_params->exclude_nonhits ) add_arg(args, n_args++, "--no-non-hits-in-stream"); if ( indexing_params->exclude_peaks ) add_arg(args, n_args++, "--no-peaks-in-stream"); if ( indexing_params->exclude_refls ) add_arg(args, n_args++, "--no-refls-in-stream"); - if ( indexing_params->millepede ) add_arg(args, n_args++, "--millepede"); + if ( indexing_params->millepede ) { + add_arg(args, n_args++, "--mille"); + add_arg_string(args, n_args++, "--mille-dir", mille_filename); + } if ( indexing_params->max_mille_level ) add_arg(args, n_args++, "--max-mille-level"); for ( i=0; in_metadata; i++ ) { add_arg_string(args, n_args++, "copy-header", @@ -1086,6 +1090,7 @@ int write_indexamajig_script(const char *script_filename, const char *stdout_filename, const char *stderr_filename, const char *harvest_filename, + const char *mille_filename, const char *serial_start, struct peak_params *peak_search_params, struct index_params *indexing_params, @@ -1102,6 +1107,7 @@ int write_indexamajig_script(const char *script_filename, files_list, stream_filename, harvest_filename, + mille_filename, serial_start, peak_search_params, indexing_params, diff --git a/src/gui_index.h b/src/gui_index.h index 2f5c1a56..33594e8e 100644 --- a/src/gui_index.h +++ b/src/gui_index.h @@ -51,6 +51,7 @@ extern int write_indexamajig_script(const char *script_filename, const char *stdout_filename, const char *stderr_filename, const char *harvest_filename, + const char *mille_filename, const char *serial_start, struct peak_params *peak_search_params, struct index_params *indexing_params, -- cgit v1.2.3 From 25cfcc9e110ff087f22e5c7945ff1ec37ac76e22 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Jan 2024 10:01:40 +0100 Subject: GUI: Copy geometry file into indexing job folder This could be used for indexing, but it seems more transparent to have the "real" filename in the script for auditing. The geometry copy will be used for detector alignment. The alternative - extracting the geometry from the stream - seems quite a lot more complicated. --- src/gui_backend_local.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c index d2068250..71c94871 100644 --- a/src/gui_backend_local.c +++ b/src/gui_backend_local.c @@ -535,6 +535,9 @@ static void *run_indexing(const char *job_title, gchar *stream_rel_filename; gchar *harvest_rel_filename; gchar *mille_rel_filename; + GFile *ggeom; + GFile *ggeomcopy; + GError *error; workdir = make_job_folder(job_title, job_notes); if ( workdir == NULL ) return NULL; @@ -558,6 +561,16 @@ static void *run_indexing(const char *job_title, harvest_rel_filename = relative_to_cwd(workdir, "parameters.json"); mille_rel_filename = relative_to_cwd(workdir, "mille-data"); + /* Copy geometry file into working directory + * Used for geometry refinement, not indexing! */ + ggeom = g_file_new_for_path(proj->geom_filename); + ggeomcopy = g_file_get_child(workdir, "detector.geom"); + error = NULL; + g_file_copy(ggeom, ggeomcopy, G_FILE_COPY_BACKUP | G_FILE_COPY_ALL_METADATA, + NULL, NULL, NULL, &error); + g_object_unref(ggeom); + g_object_unref(ggeomcopy); + if ( !write_indexamajig_script(sc_rel_filename, proj->geom_filename, n_thread_str, -- cgit v1.2.3 From 2d72edc620c6746bed5c10d148b45bb49a58c73a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Jan 2024 10:06:27 +0100 Subject: GUI: Fix Millepede options --- src/gui_index.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui_index.c b/src/gui_index.c index 3241503c..2cc8e8db 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -1005,9 +1005,9 @@ static char **indexamajig_command_line(const char *geom_filename, if ( indexing_params->exclude_refls ) add_arg(args, n_args++, "--no-refls-in-stream"); if ( indexing_params->millepede ) { add_arg(args, n_args++, "--mille"); - add_arg_string(args, n_args++, "--mille-dir", mille_filename); + add_arg_string(args, n_args++, "mille-dir", mille_filename); + add_arg_int(args, n_args++, "max-mille-level", indexing_params->max_mille_level); } - if ( indexing_params->max_mille_level ) add_arg(args, n_args++, "--max-mille-level"); for ( i=0; in_metadata; i++ ) { add_arg_string(args, n_args++, "copy-header", indexing_params->metadata_to_copy[i]); -- cgit v1.2.3 From a397af95ba722b10ae552158ea1b343b5899451a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Jan 2024 10:46:10 +0100 Subject: align_detector: Enumerate directory contents if necessary --- libcrystfel/src/utils.c | 14 ++++++++++++++ libcrystfel/src/utils.h | 1 + src/align_detector.c | 25 +++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c index 10e4c38e..44faa7ee 100644 --- a/libcrystfel/src/utils.c +++ b/libcrystfel/src/utils.c @@ -933,6 +933,20 @@ int file_exists(const char *filename) } +int is_dir(const char *filename) +{ + struct stat statbuf; + int r; + + r = stat(filename, &statbuf); + if ( r != 0 ) { + return 0; + } + + return S_ISDIR(statbuf.st_mode); +} + + int compare_double(const void *av, const void *bv) { double a = *(double *)av; diff --git a/libcrystfel/src/utils.h b/libcrystfel/src/utils.h index 3a228b22..cb68069e 100644 --- a/libcrystfel/src/utils.h +++ b/libcrystfel/src/utils.h @@ -247,6 +247,7 @@ extern char *safe_strdup(const char *in); extern void strip_extension(char *bfn); extern char *load_entire_file(const char *filename); extern int file_exists(const char *filename); +extern int is_dir(const char *filename); extern const char *filename_extension(const char *fn, const char **ext2); diff --git a/src/align_detector.c b/src/align_detector.c index bdad7039..bb2eb029 100644 --- a/src/align_detector.c +++ b/src/align_detector.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,22 @@ static int run_pede() } +static void write_children(FILE *fh, const char *dir) +{ + DIR *d = opendir(dir); + struct dirent *dent = readdir(d); + + while ( dent != NULL ) { + if ( dent->d_name[0] == 'm' ) { + fprintf(fh, "%s/%s\n", dir, dent->d_name); + } + dent = readdir(d); + } + + closedir(d); +} + + int main(int argc, char *argv[]) { int c; @@ -352,7 +369,7 @@ int main(int argc, char *argv[]) r = stat(argv[i], &statbuf); if ( r != 0 ) { - ERROR("File '%s' not found\n", argv[i]); + ERROR("File/directory '%s' not found\n", argv[i]); return 1; } @@ -364,7 +381,11 @@ int main(int argc, char *argv[]) } } - fprintf(fh, "%s\n", argv[i]); + if ( is_dir(argv[i]) ) { + write_children(fh, argv[i]); + } else { + fprintf(fh, "%s\n", argv[i]); + } } if ( warn_times ) print_time_warning(); -- cgit v1.2.3 From 9918b000068b7daceb0c62921a47922f88b17161 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Jan 2024 12:57:01 +0100 Subject: GUI: Add missing icon files --- data/crystfel-geometry.png | Bin 0 -> 1008 bytes data/crystfel-geometry.svg | 132 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 data/crystfel-geometry.png create mode 100644 data/crystfel-geometry.svg diff --git a/data/crystfel-geometry.png b/data/crystfel-geometry.png new file mode 100644 index 00000000..df5ee8b2 Binary files /dev/null and b/data/crystfel-geometry.png differ diff --git a/data/crystfel-geometry.svg b/data/crystfel-geometry.svg new file mode 100644 index 00000000..7cac81a1 --- /dev/null +++ b/data/crystfel-geometry.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From c6448075aef8607ac370bb69782b5b18f82ef120 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Jan 2024 13:59:41 +0100 Subject: indexamajig: Implement --max-mille-level --- libcrystfel/src/crystfel-mille.c | 26 ++++++++++++++++++++++++-- libcrystfel/src/crystfel-mille.h | 2 +- libcrystfel/src/index.c | 14 +++++++------- libcrystfel/src/index.h | 3 ++- libcrystfel/src/predict-refine.c | 6 ++++-- libcrystfel/src/predict-refine.h | 3 ++- src/indexamajig.c | 4 ++++ src/process_image.c | 2 +- 8 files changed, 45 insertions(+), 15 deletions(-) diff --git a/libcrystfel/src/crystfel-mille.c b/libcrystfel/src/crystfel-mille.c index 0fca6f30..8eacaa60 100644 --- a/libcrystfel/src/crystfel-mille.c +++ b/libcrystfel/src/crystfel-mille.c @@ -145,11 +145,28 @@ static void mille_add_measurement(Mille *m, } +/* group must not be NULL + * count_depth() = 0 means this is the top group */ +static int count_depth(const struct detgeom_panel_group *group) +{ + int depth = 0; + assert(group != NULL); + do { + depth++; + group = group->parent; + } while ( group != NULL ); + return depth-1; +} + + void write_mille(Mille *mille, int n, UnitCell *cell, struct reflpeak *rps, struct image *image, - gsl_matrix **Minvs) + int max_level, gsl_matrix **Minvs) { int i; + int depth; + + assert(max_level >= 0); /* No groups -> no refinement */ if ( image->detgeom->top_group == NULL ) { @@ -212,8 +229,13 @@ void write_mille(Mille *mille, int n, UnitCell *cell, /* Global gradients for each hierarchy level, starting at the * individual panel and working up to the top level */ j = 0; - levels = 0; group = image->detgeom->panels[rps[i].peak->pn].group; + depth = count_depth(group); + while ( depth > max_level ) { + depth--; + group = group->parent; + } + levels = 0; while ( group != NULL ) { double cx, cy, cz; diff --git a/libcrystfel/src/crystfel-mille.h b/libcrystfel/src/crystfel-mille.h index a4b83815..d6602ef0 100644 --- a/libcrystfel/src/crystfel-mille.h +++ b/libcrystfel/src/crystfel-mille.h @@ -51,7 +51,7 @@ extern enum gparam mille_unlabel(int n); extern void write_mille(Mille *mille, int n, UnitCell *cell, struct reflpeak *rps, struct image *image, - gsl_matrix **Minvs); + int max_level, gsl_matrix **Minvs); extern void crystfel_mille_delete_last_record(Mille *m); diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index f519c3b9..d93664b1 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -592,7 +592,7 @@ static float real_time() /* Return non-zero for "success" */ static int try_indexer(struct image *image, IndexingMethod indm, IndexingPrivate *ipriv, void *mpriv, char *last_task, - Mille *mille) + Mille *mille, int max_mille_level) { int i, r; int n_bad = 0; @@ -720,7 +720,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, { int r; profile_start("refine"); - r = refine_prediction(image, cr, mille); + r = refine_prediction(image, cr, mille, max_mille_level); profile_end("refine"); if ( r ) { crystal_set_user_flag(cr, 1); @@ -921,25 +921,25 @@ static int finished_retry(IndexingMethod indm, IndexingFlags flags, void index_pattern(struct image *image, IndexingPrivate *ipriv) { - index_pattern_4(image, ipriv, NULL, NULL, NULL); + index_pattern_4(image, ipriv, NULL, NULL, NULL, 0); } void index_pattern_2(struct image *image, IndexingPrivate *ipriv, int *ping) { - index_pattern_4(image, ipriv, ping, NULL, NULL); + index_pattern_4(image, ipriv, ping, NULL, NULL, 0); } void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, char *last_task) { - index_pattern_4(image, ipriv, ping, last_task, NULL); + index_pattern_4(image, ipriv, ping, last_task, NULL, 0); } void index_pattern_4(struct image *image, IndexingPrivate *ipriv, int *ping, - char *last_task, Mille *mille) + char *last_task, Mille *mille, int max_mille_level) { int n = 0; ImageFeatureList *orig; @@ -994,7 +994,7 @@ void index_pattern_4(struct image *image, IndexingPrivate *ipriv, int *ping, r = try_indexer(image, ipriv->methods[n], ipriv, ipriv->engine_private[n], - last_task, mille); + last_task, mille, max_mille_level); success += r; ntry++; done = finished_retry(ipriv->methods[n], ipriv->flags, diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h index fa371276..10d07f08 100644 --- a/libcrystfel/src/index.h +++ b/libcrystfel/src/index.h @@ -253,7 +253,8 @@ extern void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, char *last_task); extern void index_pattern_4(struct image *image, IndexingPrivate *ipriv, - int *ping, char *last_task, Mille *mille); + int *ping, char *last_task, Mille *mille, + int max_mille_level); extern void cleanup_indexing(IndexingPrivate *ipriv); diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c index 32d0f77b..d5a3b403 100644 --- a/libcrystfel/src/predict-refine.c +++ b/libcrystfel/src/predict-refine.c @@ -796,7 +796,8 @@ static void free_rps_noreflist(struct reflpeak *rps, int n) } -int refine_prediction(struct image *image, Crystal *cr, Mille *mille) +int refine_prediction(struct image *image, Crystal *cr, + Mille *mille, int max_mille_level) { int n; int i; @@ -879,7 +880,8 @@ int refine_prediction(struct image *image, Crystal *cr, Mille *mille) if ( mille != NULL ) { profile_start("mille-calc"); - write_mille(mille, n, crystal_get_cell(cr), rps, image, Minvs); + write_mille(mille, n, crystal_get_cell(cr), rps, image, + max_mille_level, Minvs); profile_end("mille-calc"); } diff --git a/libcrystfel/src/predict-refine.h b/libcrystfel/src/predict-refine.h index 604799c0..080e5923 100644 --- a/libcrystfel/src/predict-refine.h +++ b/libcrystfel/src/predict-refine.h @@ -67,7 +67,8 @@ struct reflpeak { * Prediction refinement: refinement of indexing solutions before integration. */ -extern int refine_prediction(struct image *image, Crystal *cr, Mille *mille); +extern int refine_prediction(struct image *image, Crystal *cr, + Mille *mille, int max_mille_level); extern int refine_radius(Crystal *cr, struct image *image); diff --git a/src/indexamajig.c b/src/indexamajig.c index fd95a01c..ce8b2cbf 100644 --- a/src/indexamajig.c +++ b/src/indexamajig.c @@ -754,6 +754,10 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) ERROR("Invalid value for --max-mille-level\n"); return EINVAL; } + if ( args->iargs.max_mille_level < 0 ) { + ERROR("Invalid value for --max-mille-level\n"); + return EINVAL; + } break; /* ---------- Integration ---------- */ diff --git a/src/process_image.c b/src/process_image.c index 57a994ac..2f856594 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -420,7 +420,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, set_last_task(last_task, "indexing"); profile_start("index"); index_pattern_4(image, iargs->ipriv, &sb_shared->pings[cookie], - last_task, mille); + last_task, mille, iargs->max_mille_level); profile_end("index"); r = chdir(rn); -- cgit v1.2.3 From a863e7fc05feb892ffbb7957b4fe74a886992800 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Jan 2024 14:05:28 +0100 Subject: Update docs about --max-mille-level. --- doc/man/align_detector.1.md | 4 ++++ doc/man/indexamajig.1.md | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/doc/man/align_detector.1.md b/doc/man/align_detector.1.md index aa5f5061..f5991641 100644 --- a/doc/man/align_detector.1.md +++ b/doc/man/align_detector.1.md @@ -45,6 +45,10 @@ panel "dominoes", and level **3** would refine the individual (roughly square) ASICs. Higher refinement levels will generally require more and higher-resolution diffraction data. +You can use **indexamajig** option **--max-mille-level** to reduce the size of +the calibration data files, at the cost of limiting the maximum refinement +level. + The default behaviour is to refine only the position components in the x-y plane, perpendicular to the beam. In favourable circumstances, you can add option **--out-of-plane** to refine the panel tilts and shifts out of this diff --git a/doc/man/indexamajig.1.md b/doc/man/indexamajig.1.md index 85566240..1955ef76 100644 --- a/doc/man/indexamajig.1.md +++ b/doc/man/indexamajig.1.md @@ -594,6 +594,13 @@ INDEXING OPTIONS **--mille-dir=dirname** : Write the Millepede-II data into _dirname_. +**--max-mille-level=n** +: Write the Millepede-II data up to a maximum hierarchy depth _n_. If _n_ is +: 0, only the overall detector position can be refined. Larger numbers allow +: finer-grained refinement. Set this to a large number (9 is high enough!) +: to disable the limit, although this can make the Millepede-II files quite +: large. + **--wavelength-estimate=m** **--camera-length-estimate=m** : Some indexing algorithms need to know the camera length or the wavelength of : the incident radiation in advance, e.g. to prepare an internal look-up table. -- cgit v1.2.3