aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/align_detector.c25
-rw-r--r--src/crystfel_gui.c34
-rw-r--r--src/crystfelindexingopts.c35
-rw-r--r--src/crystfelindexingopts.h8
-rw-r--r--src/gui_align.c235
-rw-r--r--src/gui_align.h38
-rw-r--r--src/gui_backend_local.c17
-rw-r--r--src/gui_backend_slurm.c4
-rw-r--r--src/gui_index.c13
-rw-r--r--src/gui_index.h1
-rw-r--r--src/gui_project.c12
-rw-r--r--src/gui_project.h2
-rw-r--r--src/indexamajig.c17
-rw-r--r--src/process_image.c2
-rw-r--r--src/process_image.h1
15 files changed, 408 insertions, 36 deletions
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 <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -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();
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c
index d0fab3b1..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"
@@ -467,34 +468,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; i<MIN(res->n_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 +798,6 @@ static void add_menu_bar(struct crystfelproject *proj, GtkWidget *vbox)
" <menuitem name=\"rescan\" action=\"RescanAction\" />"
" <menuitem name=\"jumpframe\" action=\"JumpFrameAction\" />"
" <separator />"
- " <menuitem name=\"detectorshift\" action=\"DetectorShiftAction\" />"
" <menuitem name=\"peakogram\" action=\"PeakogramAction\" />"
"</menu>"
"<menu name=\"help\" action=\"HelpAction\">"
@@ -852,8 +824,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) },
@@ -933,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/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);
diff --git a/src/gui_align.c b/src/gui_align.c
new file mode 100644
index 00000000..b712681b
--- /dev/null
+++ b/src/gui_align.c
@@ -0,0 +1,235 @@
+/*
+ * 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 <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/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <assert.h>
+
+#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 *input_combo;
+ GtkWidget *out_of_plane;
+ GtkWidget *level;
+};
+
+
+
+static int run_align(const char *input_name, int level, int out_of_plane,
+ const char *out_geom, struct crystfelproject *proj)
+{
+ 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;
+}
+
+
+static void align_response_sig(GtkWidget *dialog, gint resp,
+ struct align_window *win)
+{
+ int r = 0;
+
+ if ( resp == GTK_RESPONSE_ACCEPT ) {
+
+ 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, win->proj);
+
+ g_free(filename);
+ }
+
+ if ( !r ) gtk_widget_destroy(dialog);
+}
+
+
+gint align_sig(GtkWidget *widget, struct crystfelproject *proj)
+{
+ GtkWidget *hbox;
+ GtkWidget *label;
+ struct align_window *win;
+ int i;
+
+ win = malloc(sizeof(struct align_window));
+ if ( win == NULL ) return 0;
+
+ win->proj = proj;
+
+ win->window = gtk_file_chooser_dialog_new("Align detector",
+ GTK_WINDOW(proj->window),
+ 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);
+
+ 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; i<proj->n_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));
+
+ 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);
+ 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("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");
+
+ 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 <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 GUI_ALIGN_H
+#define GUI_ALIGN_H
+
+#include <gtk/gtk.h>
+
+#include "gui_project.h"
+
+extern gint align_sig(GtkWidget *widget, struct crystfelproject *proj);
+
+#endif
diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c
index 03761474..71c94871 100644
--- a/src/gui_backend_local.c
+++ b/src/gui_backend_local.c
@@ -534,6 +534,10 @@ static void *run_indexing(const char *job_title,
gchar *files_rel_filename;
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;
@@ -555,6 +559,17 @@ 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");
+
+ /* 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,
@@ -564,6 +579,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 +614,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 aa2301ef..2cc8e8db 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);
@@ -846,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,
@@ -997,6 +1003,11 @@ 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++, "--mille");
+ add_arg_string(args, n_args++, "mille-dir", mille_filename);
+ add_arg_int(args, n_args++, "max-mille-level", indexing_params->max_mille_level);
+ }
for ( i=0; i<indexing_params->n_metadata; i++ ) {
add_arg_string(args, n_args++, "copy-header",
indexing_params->metadata_to_copy[i]);
@@ -1079,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,
@@ -1095,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,
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; i<proj->indexing_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 {
diff --git a/src/indexamajig.c b/src/indexamajig.c
index cca7dbba..ce8b2cbf 100644
--- a/src/indexamajig.c
+++ b/src/indexamajig.c
@@ -748,6 +748,18 @@ 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;
+ }
+ if ( args->iargs.max_mille_level < 0 ) {
+ ERROR("Invalid value for --max-mille-level\n");
+ return EINVAL;
+ }
+ break;
+
/* ---------- Integration ---------- */
case 501 :
@@ -996,6 +1008,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 +1135,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.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);
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;