aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel')
-rw-r--r--libcrystfel/CMakeLists.txt12
-rw-r--r--libcrystfel/src/felix.c176
-rw-r--r--libcrystfel/src/felix.h17
-rw-r--r--libcrystfel/src/index.c1
-rw-r--r--libcrystfel/src/index.h2
-rw-r--r--libcrystfel/src/integration.c23
-rw-r--r--libcrystfel/src/pinkindexer.c166
-rw-r--r--libcrystfel/src/pinkindexer.h3
-rw-r--r--libcrystfel/src/taketwo.c104
-rw-r--r--libcrystfel/src/taketwo.h12
-rw-r--r--libcrystfel/src/utils.c2
-rw-r--r--libcrystfel/src/xgandalf.c159
-rw-r--r--libcrystfel/src/xgandalf.h12
13 files changed, 638 insertions, 51 deletions
diff --git a/libcrystfel/CMakeLists.txt b/libcrystfel/CMakeLists.txt
index fdba725e..10e0584d 100644
--- a/libcrystfel/CMakeLists.txt
+++ b/libcrystfel/CMakeLists.txt
@@ -2,8 +2,6 @@ project(libcrystfel VERSION ${CRYSTFEL_SHORT_VERSION} LANGUAGES C)
find_package(Curses)
find_package(XGANDALF)
-find_package(PINKINDEXER)
-find_package(NBP)
find_package(FDIP)
find_package(ZLIB REQUIRED)
find_package(FLEX REQUIRED)
@@ -156,16 +154,6 @@ if (FDIP_FOUND)
target_link_libraries(${PROJECT_NAME} PRIVATE ${FDIP_LIBRARIES})
endif (FDIP_FOUND)
-if (PINKINDEXER_FOUND)
- target_include_directories(${PROJECT_NAME} PRIVATE ${PINKINDEXER_INCLUDES})
- target_link_libraries(${PROJECT_NAME} PRIVATE ${PINKINDEXER_LIBRARIES})
-endif (PINKINDEXER_FOUND)
-
-if (NBP_FOUND)
- target_include_directories(${PROJECT_NAME} PRIVATE ${NBP_INCLUDES})
- target_link_libraries(${PROJECT_NAME} PRIVATE ${NBP_LIBRARIES})
-endif (NBP_FOUND)
-
if (FFTW_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${FFTW_LDFLAGS})
diff --git a/libcrystfel/src/felix.c b/libcrystfel/src/felix.c
index ea27093a..cac12410 100644
--- a/libcrystfel/src/felix.c
+++ b/libcrystfel/src/felix.c
@@ -70,6 +70,21 @@
#define FELIX_VERBOSE 0
+struct felix_options
+{
+ double ttmin; /* radians */
+ double ttmax; /* radians */
+ int min_visits;
+ double min_completeness;
+ double max_uniqueness;
+ int n_voxels;
+ double fraction_max_visits;
+ double sigma;
+ double domega;
+ double max_internal_angle;
+};
+
+
/* Global private data, prepared once */
struct felix_private
{
@@ -789,3 +804,164 @@ const char *felix_probe(UnitCell *cell)
if ( ok ) return "felix";
return NULL;
}
+
+
+static void show_help()
+{
+ printf("Parameters for the Felix indexing algorithm:\n"
+" --felix-domega Degree range of omega (moscaicity) to consider.\n"
+" Default: 2\n"
+" --felix-fraction-max-visits\n"
+" Cutoff for minimum fraction of the max visits.\n"
+" Default: 0.75\n"
+" --felix-max-internal-angle\n"
+" Cutoff for maximum internal angle between observed\n"
+" spots and predicted spots. Default: 0.25\n"
+" --felix-max-uniqueness\n"
+" Cutoff for maximum fraction of found spots which\n"
+" can belong to other crystallites. Default: 0.5\n"
+" --felix-min-completeness\n"
+" Cutoff for minimum fraction of projected spots\n"
+" found in the pattern. Default: 0.001\n"
+" --felix-min-visits\n"
+" Cutoff for minimum number of voxel visits.\n"
+" Default: 15\n"
+" --felix-num-voxels Number of voxels for Rodrigues space search\n"
+" Default: 100\n"
+" --felix-sigma The sigma of the 2theta, eta and omega angles.\n"
+" Default: 0.2\n"
+" --felix-tthrange-max Maximum 2theta to consider for indexing (degrees)\n"
+" Default: 30\n"
+" --felix-tthrange-min Minimum 2theta to consider for indexing (degrees)\n"
+" Default: 0\n"
+);
+}
+
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ struct felix_options **opts_ptr = state->input;
+ float tmp;
+
+ switch ( key ) {
+
+ case ARGP_KEY_INIT :
+ *opts_ptr = malloc(sizeof(struct felix_options));
+ if ( *opts_ptr == NULL ) return ENOMEM;
+ (*opts_ptr)->ttmin = -1.0;
+ (*opts_ptr)->ttmax = -1.0;
+ (*opts_ptr)->min_visits = 0;
+ (*opts_ptr)->min_completeness = -1.0;
+ (*opts_ptr)->max_uniqueness = -1.0;
+ (*opts_ptr)->n_voxels = 0;
+ (*opts_ptr)->fraction_max_visits = -1.0;
+ (*opts_ptr)->sigma = -1.0;
+ (*opts_ptr)->domega = -1.0;
+ (*opts_ptr)->max_internal_angle = -1.0;
+ break;
+
+ case 1 :
+ show_help();
+ return EINVAL;
+
+ case 2 :
+ if ( sscanf(arg, "%f", &tmp) != 1 ) {
+ ERROR("Invalid value for --felix-tthrange-min\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->ttmin = deg2rad(tmp);
+ break;
+
+ case 3 :
+ if ( sscanf(arg, "%f", &tmp) != 1 ) {
+ ERROR("Invalid value for --felix-tthrange-max\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->ttmax = deg2rad(tmp);
+ break;
+
+ case 4 :
+ if ( sscanf(arg, "%d", &(*opts_ptr)->min_visits) != 1 ) {
+ ERROR("Invalid value for --felix-min-visits\n");
+ return EINVAL;
+ }
+ break;
+
+ case 5 :
+ if ( sscanf(arg, "%lf", &(*opts_ptr)->min_completeness) != 1 ) {
+ ERROR("Invalid value for --felix-min-completeness\n");
+ return EINVAL;
+ }
+ break;
+
+ case 6 :
+ if ( sscanf(arg, "%lf", &(*opts_ptr)->max_uniqueness) != 1 ) {
+ ERROR("Invalid value for --felix-max-uniqueness\n");
+ return EINVAL;
+ }
+ break;
+
+ case 7 :
+ if ( sscanf(arg, "%d", &(*opts_ptr)->n_voxels) != 1 ) {
+ ERROR("Invalid value for --felix-num-voxels\n");
+ return EINVAL;
+ }
+ break;
+
+ case 8 :
+ if ( sscanf(arg, "%lf", &(*opts_ptr)->fraction_max_visits) != 1 ) {
+ ERROR("Invalid value for --felix-fraction-max-visits\n");
+ return EINVAL;
+ }
+ break;
+
+ case 9 :
+ if ( sscanf(arg, "%lf", &(*opts_ptr)->sigma) != 1 ) {
+ ERROR("Invalid value for --felix-sigma\n");
+ return EINVAL;
+ }
+ break;
+
+ case 10 :
+ if ( sscanf(arg, "%lf", &(*opts_ptr)->domega) != 1 ) {
+ ERROR("Invalid value for --felix-domega\n");
+ return EINVAL;
+ }
+ break;
+
+ case 11 :
+ if ( sscanf(arg, "%lf", &(*opts_ptr)->max_internal_angle) != 1 ) {
+ ERROR("Invalid value for --felix-max-internal-angle\n");
+ return EINVAL;
+ }
+ break;
+
+ default :
+ return ARGP_ERR_UNKNOWN;
+
+ }
+
+ return 0;
+}
+
+
+static struct argp_option options[] = {
+
+ {"help-felix", 1, NULL, OPTION_NO_USAGE,
+ "Show options for Felix indexing algorithm", 99},
+ {"felix-tthrange-min", 2, "2theta", OPTION_HIDDEN, NULL},
+ {"felix-tthrange-max", 3, "2theta", OPTION_HIDDEN, NULL},
+ {"felix-min-visits", 4, "n", OPTION_HIDDEN, NULL},
+ {"felix-min-completeness", 5, "frac", OPTION_HIDDEN, NULL},
+ {"felix-max-uniqueness", 6, "n", OPTION_HIDDEN, NULL},
+ {"felix-num-voxels", 7, "n", OPTION_HIDDEN, NULL},
+ {"felix-fraction-max-visits", 8, "n", OPTION_HIDDEN, NULL},
+ {"felix-sigma", 9, "n", OPTION_HIDDEN, NULL},
+ {"felix-domega", 10, "n", OPTION_HIDDEN, NULL},
+ {"felix-max-internal-angle", 11, "ang", OPTION_HIDDEN, NULL},
+
+ {0}
+};
+
+
+struct argp felix_argp = { options, parse_arg, NULL, NULL, NULL, NULL, NULL };
diff --git a/libcrystfel/src/felix.h b/libcrystfel/src/felix.h
index 645adaeb..8cec9754 100644
--- a/libcrystfel/src/felix.h
+++ b/libcrystfel/src/felix.h
@@ -34,6 +34,8 @@
#include <config.h>
#endif
+#include <argp.h>
+
#include "cell.h"
/**
@@ -41,19 +43,8 @@
* Felix indexer interface
*/
-struct felix_options
-{
- double ttmin; /* radians */
- double ttmax; /* radians */
- int min_visits;
- double min_completeness;
- double max_uniqueness;
- int n_voxels;
- double fraction_max_visits;
- double sigma;
- double domega;
- double max_internal_angle;
-};
+typedef struct felix_options FelixOptions;
+extern struct argp felix_argp;
extern void *felix_prepare(IndexingMethod *indm, UnitCell *cell,
struct felix_options *opts);
diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c
index 440a5b97..049c3ba0 100644
--- a/libcrystfel/src/index.c
+++ b/libcrystfel/src/index.c
@@ -593,6 +593,7 @@ static int check_cell(IndexingFlags flags, Crystal *cr, UnitCell *target,
tolerance, &rm);
if ( out != NULL ) {
+ /* Replace crystal's cell with new one */
cell_free(crystal_get_cell(cr));
crystal_set_cell(cr, out);
rtnl_mtx_free(rm);
diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h
index 4fc95b1d..5e9e40ad 100644
--- a/libcrystfel/src/index.h
+++ b/libcrystfel/src/index.h
@@ -125,7 +125,7 @@ typedef enum {
INDEXING_CHECK_PEAKS = 32,
/** Check that the unit cell agrees with the target cell */
- INDEXING_CHECK_CELL = 32,
+ INDEXING_CHECK_CELL = 64,
} IndexingFlags;
diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c
index 5270816b..a1655aab 100644
--- a/libcrystfel/src/integration.c
+++ b/libcrystfel/src/integration.c
@@ -1399,9 +1399,9 @@ static void integrate_prof2d(IntegrationMethod meth,
}
-static void integrate_rings_once(Reflection *refl, struct image *image,
- struct intcontext *ic, UnitCell *cell,
- pthread_mutex_t *term_lock)
+static int integrate_rings_once(Reflection *refl, struct image *image,
+ struct intcontext *ic, UnitCell *cell,
+ pthread_mutex_t *term_lock)
{
double pfs, pss;
struct peak_box *bx;
@@ -1423,7 +1423,7 @@ static void integrate_rings_once(Reflection *refl, struct image *image,
pn = panel_number(image->det, p);
if ( pn == image->det->n_panels ) {
ERROR("Couldn't find panel %p\n", p);
- return;
+ return 1;
}
/* Explicit truncation of digits after the decimal point.
@@ -1458,14 +1458,14 @@ static void integrate_rings_once(Reflection *refl, struct image *image,
}
if ( r ) {
delete_box(ic, bx);
- return;
+ return 1;
}
if ( saturated ) {
ic->n_saturated++;
if ( !(ic->meth & INTEGRATION_SATURATED) ) {
delete_box(ic, bx);
- return;
+ return 1;
}
}
@@ -1509,7 +1509,10 @@ static void integrate_rings_once(Reflection *refl, struct image *image,
if ( intensity < -5.0*sigma ) {
ic->n_implausible++;
set_redundancy(refl, 0);
+ return 1;
}
+
+ return 0;
}
@@ -1612,6 +1615,7 @@ static void integrate_rings(IntegrationMethod meth,
RefListIterator *iter;
UnitCell *cell;
struct intcontext ic;
+ int n_rej = 0;
list = crystal_get_reflections(cr);
cell = crystal_get_cell(cr);
@@ -1641,11 +1645,16 @@ static void integrate_rings(IntegrationMethod meth,
refl != NULL;
refl = next_refl(refl, iter) )
{
- integrate_rings_once(refl, image, &ic, cell, term_lock);
+ n_rej += integrate_rings_once(refl, image, &ic, cell, term_lock);
}
free_intcontext(&ic);
+ if ( n_rej > 0 ) {
+ ERROR("WARNING: %i reflections could not be integrated\n",
+ n_rej);
+ }
+
crystal_set_num_saturated_reflections(cr, ic.n_saturated);
crystal_set_num_implausible_reflections(cr, ic.n_implausible);
}
diff --git a/libcrystfel/src/pinkindexer.c b/libcrystfel/src/pinkindexer.c
index eb8ec05e..811aa3c8 100644
--- a/libcrystfel/src/pinkindexer.c
+++ b/libcrystfel/src/pinkindexer.c
@@ -367,3 +367,169 @@ const char *pinkIndexer_probe(UnitCell *cell)
}
#endif /* HAVE_PINKINDEXER */
+
+static void show_help()
+{
+ printf("Parameters for the PinkIndexer indexing algorithm:\n"
+" --pinkIndexer-considered-peaks-count\n"
+" Considered peaks count, 0 (fewest) to 4 (most)\n"
+" Default: 4\n"
+" --pinkIndexer-angle-resolution\n"
+" Angle resolution, 0 (loosest) to 4 (most dense)\n"
+" Default: 2\n"
+" --pinkIndexer-refinement-type\n"
+" Refinement type, 0 (none) to 5 (most accurate)\n"
+" Default: 1\n"
+" --pinkIndexer-tolerance\n"
+" Relative tolerance of the lattice vectors.\n"
+" Default 0.06\n"
+" --pinkIndexer-reflection-radius\n"
+" Radius of the reflections in reciprocal space.\n"
+" Specified in 1/A. Default is 2%% of a*.\n"
+" --pinkIndexer-max-resolution-for-indexing\n"
+" Measured in 1/A\n"
+" --pinkIndexer-multi Use pinkIndexers own multi indexing.\n"
+" --pinkIndexer-thread-count\n"
+" Thread count for internal parallelization \n"
+" Default: 1\n"
+" --pinkIndexer-no-check-indexed\n"
+" Disable internal check for correct indexing\n"
+" solutions\n"
+);
+}
+
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ float tmp;
+ struct pinkIndexer_options **opts_ptr = state->input;
+
+ switch ( key ) {
+
+ case ARGP_KEY_INIT :
+ *opts_ptr = malloc(sizeof(struct pinkIndexer_options));
+ if ( *opts_ptr == NULL ) return ENOMEM;
+ (*opts_ptr)->considered_peaks_count = 4;
+ (*opts_ptr)->angle_resolution = 2;
+ (*opts_ptr)->refinement_type = 1;
+ (*opts_ptr)->tolerance = 0.06;
+ (*opts_ptr)->maxResolutionForIndexing_1_per_A = +INFINITY;
+ (*opts_ptr)->thread_count = 1;
+ (*opts_ptr)->multi = 0;
+ (*opts_ptr)->no_check_indexed = 0;
+ (*opts_ptr)->min_peaks = 2;
+ (*opts_ptr)->reflectionRadius = -1;
+ break;
+
+ case 1 :
+ show_help();
+ return EINVAL;
+
+ case 2 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->considered_peaks_count) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-considered-peaks-count\n");
+ return EINVAL;
+ }
+ break;
+
+ case 3 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->angle_resolution) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-angle_resolution\n");
+ return EINVAL;
+ }
+ break;
+
+ case 4 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->refinement_type) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-refinement-type\n");
+ return EINVAL;
+ }
+ break;
+
+ case 5 :
+ if (sscanf(arg, "%d", &(*opts_ptr)->thread_count) != 1)
+ {
+ ERROR("Invalid value for --pinkIndexer-thread-count\n");
+ return EINVAL;
+ }
+ break;
+
+ case 6 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->maxResolutionForIndexing_1_per_A) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-max-resolution-for-indexing\n");
+ return EINVAL;
+ }
+ break;
+
+ case 7 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->tolerance) != 1)
+ {
+ ERROR("Invalid value for --pinkIndexer-tolerance\n");
+ return EINVAL;
+ }
+ break;
+
+ case 8 :
+ (*opts_ptr)->multi = 1;
+ break;
+
+ case 9 :
+ (*opts_ptr)->no_check_indexed = 1;
+ break;
+
+ case 10 :
+ if (sscanf(arg, "%f", &tmp) != 1) {
+ ERROR("Invalid value for --pinkIndexer-reflection-radius\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->reflectionRadius = tmp / 1e10; /* A^-1 to m^-1 */
+ break;
+
+ }
+
+ return 0;
+}
+
+
+static struct argp_option options[] = {
+
+ {"help-pinkindexer", 1, NULL, OPTION_NO_USAGE,
+ "Show options for PinkIndexer indexing algorithm", 99},
+
+ {"pinkIndexer-considered-peaks-count", 2, "n", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-cpc", 2, "n", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-angle-resolution", 3, "ang", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-ar", 3, "ang", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-refinement-type", 4, "t", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-rt", 4, "t", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-thread-count", 5, "n", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-tc", 5, "n", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-max-resolution-for-indexing", 6, "res", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-mrfi", 6, "res", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-tolerance", 7, "tol", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-tol", 7, "tol", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-multi", 8, NULL, OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-no-check-indexed", 9, NULL, OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-reflection-radius", 10, "r", OPTION_HIDDEN, NULL},
+
+ {0}
+};
+
+
+struct argp pinkIndexer_argp = { options, parse_arg, NULL, NULL, NULL, NULL, NULL };
diff --git a/libcrystfel/src/pinkindexer.h b/libcrystfel/src/pinkindexer.h
index 1fcb3711..0169d028 100644
--- a/libcrystfel/src/pinkindexer.h
+++ b/libcrystfel/src/pinkindexer.h
@@ -33,6 +33,9 @@
#include <config.h>
#endif
+typedef struct pinkIndexer_options PinkIndexerOptions;
+extern struct argp pinkIndexer_argp;
+
struct pinkIndexer_options {
unsigned int considered_peaks_count;
unsigned int angle_resolution;
diff --git a/libcrystfel/src/taketwo.c b/libcrystfel/src/taketwo.c
index ddbfe173..893791e4 100644
--- a/libcrystfel/src/taketwo.c
+++ b/libcrystfel/src/taketwo.c
@@ -100,6 +100,14 @@
#include "peaks.h"
#include "symmetry.h"
+struct taketwo_options
+{
+ int member_thresh;
+ double len_tol;
+ double angle_tol;
+ double trace_tol;
+};
+
/**
* \param obsvec an observed vector between two spots
* \param matches array of matching theoretical vectors from unit cell
@@ -2241,6 +2249,7 @@ void *taketwo_prepare(IndexingMethod *indm, UnitCell *cell)
return tp;
}
+
void taketwo_cleanup(IndexingPrivate *pp)
{
struct taketwo_private *tp = (struct taketwo_private *)pp;
@@ -2257,3 +2266,98 @@ const char *taketwo_probe(UnitCell *cell)
if ( cell_has_parameters(cell) ) return "taketwo";
return NULL;
}
+
+
+static void show_help()
+{
+ printf("Parameters for the TakeTwo indexing algorithm:\n"
+" --taketwo-member-threshold\n"
+" Minimum number of members in network\n"
+" --taketwo-len-tolerance\n"
+" Reciprocal space length tolerance (1/A)\n"
+" --taketwo-angle-tolerance\n"
+" Reciprocal space angle tolerance (in degrees)\n"
+" --taketwo-trace-tolerance\n"
+" Rotation matrix equivalence tolerance (in degrees)\n"
+);
+}
+
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ struct taketwo_options **opts_ptr = state->input;
+ float tmp;
+
+ switch ( key ) {
+
+ case ARGP_KEY_INIT :
+ *opts_ptr = malloc(sizeof(struct taketwo_options));
+ if ( *opts_ptr == NULL ) return ENOMEM;
+ (*opts_ptr)->member_thresh = -1.0;
+ (*opts_ptr)->len_tol = -1.0;
+ (*opts_ptr)->angle_tol = -1.0;
+ (*opts_ptr)->trace_tol = -1.0;
+ break;
+
+ case 1 :
+ show_help();
+ return EINVAL;
+
+ case 2 :
+ if ( sscanf(arg, "%i", &(*opts_ptr)->member_thresh) != 1 )
+ {
+ ERROR("Invalid value for --taketwo-member-threshold\n");
+ return EINVAL;
+ }
+ break;
+
+ case 3 :
+ if ( sscanf(arg, "%f", &tmp) != 1 )
+ {
+ ERROR("Invalid value for --taketwo-len-tol\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->len_tol = tmp * 1e10; /* Convert to m^-1 */
+ break;
+
+ case 4 :
+ if ( sscanf(arg, "%f", &tmp) != 1 )
+ {
+ ERROR("Invalid value for --taketwo-angle-tol\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->angle_tol = deg2rad(tmp);
+ break;
+
+ case 5 :
+ if ( sscanf(arg, "%f", &tmp) != 1 )
+ {
+ ERROR("Invalid value for --taketwo-trace-tol\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->trace_tol = deg2rad(tmp);
+ break;
+
+ default :
+ return ARGP_ERR_UNKNOWN;
+
+ }
+
+ return 0;
+}
+
+
+static struct argp_option options[] = {
+
+ {"help-taketwo", 1, NULL, OPTION_NO_USAGE,
+ "Show options for TakeTwo indexing algorithm", 99},
+
+ {"taketwo-member-threshold", 2, "n", OPTION_HIDDEN, NULL},
+ {"taketwo-len-tolerance", 3, "one_over_A", OPTION_HIDDEN, NULL},
+ {"taketwo-angle-tolerance", 4, "deg", OPTION_HIDDEN, NULL},
+ {"taketwo-trace-tolerance", 5, "deg", OPTION_HIDDEN, NULL},
+ {0}
+};
+
+
+struct argp taketwo_argp = { options, parse_arg, NULL, NULL, NULL, NULL, NULL };
diff --git a/libcrystfel/src/taketwo.h b/libcrystfel/src/taketwo.h
index 6960446d..c489228f 100644
--- a/libcrystfel/src/taketwo.h
+++ b/libcrystfel/src/taketwo.h
@@ -31,19 +31,15 @@
#ifndef TAKETWO_H
#define TAKETWO_H
+#include <argp.h>
+
#include "cell.h"
#include "index.h"
/** \file taketwo.h */
-struct taketwo_options
-{
- int member_thresh;
- double len_tol;
- double angle_tol;
- double trace_tol;
-};
-
+typedef struct taketwo_options TakeTwoOptions;
+extern struct argp taketwo_argp;
extern void *taketwo_prepare(IndexingMethod *indm, UnitCell *cell);
extern const char *taketwo_probe(UnitCell *cell);
diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c
index a2ba2c60..ba6f44c3 100644
--- a/libcrystfel/src/utils.c
+++ b/libcrystfel/src/utils.c
@@ -469,6 +469,8 @@ char *check_prefix(char *prefix)
char *new;
size_t len;
+ if ( prefix[0] == '\0' ) return prefix;
+
/* Is "prefix" a directory? */
r = stat(prefix, &statbuf);
if ( r != 0 ) {
diff --git a/libcrystfel/src/xgandalf.c b/libcrystfel/src/xgandalf.c
index 6a8ba4d5..2b5bd512 100644
--- a/libcrystfel/src/xgandalf.c
+++ b/libcrystfel/src/xgandalf.c
@@ -28,19 +28,32 @@
#include "xgandalf.h"
-#ifdef HAVE_XGANDALF
#include <stdlib.h>
#include "utils.h"
#include "cell-utils.h"
#include "peaks.h"
+#ifdef HAVE_XGANDALF
#include "xgandalf/adaptions/crystfel/Lattice.h"
#include "xgandalf/adaptions/crystfel/ExperimentSettings.h"
#include "xgandalf/adaptions/crystfel/IndexerPlain.h"
+#endif
/** \file xgandalf.h */
+struct xgandalf_options {
+ unsigned int sampling_pitch;
+ unsigned int grad_desc_iterations;
+ float tolerance;
+ unsigned int no_deviation_from_provided_cell;
+ float minLatticeVectorLength_A;
+ float maxLatticeVectorLength_A;
+ int maxPeaksForIndexing;
+};
+
+#ifdef HAVE_XGANDALF
+
struct xgandalf_private_data {
IndexerPlain *indexer;
reciprocalPeaks_1_per_A_t reciprocalPeaks_1_per_A;
@@ -332,3 +345,147 @@ const char *xgandalf_probe(UnitCell *cell)
}
#endif // HAVE_XGANDALF
+
+static void show_help()
+{
+ printf("Parameters for the TakeTwo indexing algorithm:\n"
+" --xgandalf-sampling-pitch\n"
+" Sampling pitch: 0 (loosest) to 4 (most dense)\n"
+" or with secondary Miller indices: 5 (loosest) to\n"
+" 7 (most dense). Default: 6\n"
+" --xgandalf-grad-desc-iterations\n"
+" Gradient descent iterations: 0 (few) to 5 (many)\n"
+" Default: 4\n"
+" --xgandalf-fast-execution Shortcut to set\n"
+" --xgandalf-sampling-pitch=2\n"
+" --xgandalf-grad-desc-iterations=3\n"
+" --xgandalf-tolerance Relative tolerance of the lattice vectors.\n"
+" Default is 0.02\n"
+" --xgandalf-no-deviation-from-provided-cell\n"
+" Force the fitted cell to have the same lattice\n"
+" parameters as the provided one\n"
+" --xgandalf-min-lattice-vector-length\n"
+" Minimum possible lattice vector length in A.\n"
+" Default: 30 A\n"
+" --xgandalf-max-lattice-vector-length\n"
+" Maximum possible lattice vector length in A.\n"
+" Default: 250 A\n"
+" --xgandalf-max-peaks\n"
+" Maximum number of peaks used for indexing.\n"
+" All peaks are used for refinement.\n"
+" Default: 250\n"
+);
+}
+
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ struct xgandalf_options **opts_ptr = state->input;
+
+ switch ( key ) {
+
+ case ARGP_KEY_INIT :
+ *opts_ptr = malloc(sizeof(struct xgandalf_options));
+ if ( *opts_ptr == NULL ) return ENOMEM;
+ (*opts_ptr)->sampling_pitch = 6;
+ (*opts_ptr)->grad_desc_iterations = 4;
+ (*opts_ptr)->tolerance = 0.02;
+ (*opts_ptr)->no_deviation_from_provided_cell = 0;
+ (*opts_ptr)->minLatticeVectorLength_A = 30;
+ (*opts_ptr)->maxLatticeVectorLength_A = 250;
+ (*opts_ptr)->maxPeaksForIndexing = 250;
+ break;
+
+ case 1 :
+ show_help();
+ return EINVAL;
+
+ case 2 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->sampling_pitch) != 1) {
+ ERROR("Invalid value for --xgandalf-sampling-pitch\n");
+ return EINVAL;
+ }
+ break;
+
+ case 3 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->grad_desc_iterations) != 1) {
+ ERROR("Invalid value for --xgandalf-grad-desc-iterations\n");
+ return EINVAL;
+ }
+ break;
+
+ case 4 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->tolerance) != 1) {
+ ERROR("Invalid value for --xgandalf-tolerance\n");
+ return EINVAL;
+ }
+ break;
+
+ case 5 :
+ (*opts_ptr)->no_deviation_from_provided_cell = 1;
+ break;
+
+ case 6 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->minLatticeVectorLength_A) != 1) {
+ ERROR("Invalid value for --xgandalf-min-lattice-vector-length\n");
+ return EINVAL;
+ }
+ break;
+
+ case 7 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->maxLatticeVectorLength_A) != 1) {
+ ERROR("Invalid value for --xgandalf-max-lattice-vector-length\n");
+ return EINVAL;
+ }
+ break;
+
+ case 8 :
+ (*opts_ptr)->sampling_pitch = 2;
+ (*opts_ptr)->grad_desc_iterations = 3;
+ break;
+
+ case 9 :
+ if (sscanf(arg, "%i", &(*opts_ptr)->maxPeaksForIndexing) != 1) {
+ ERROR("Invalid value for --xgandalf-max-peaks\n");
+ return EINVAL;
+ }
+ break;
+
+ }
+
+ return 0;
+}
+
+
+static struct argp_option options[] = {
+
+ {"help-xgandalf", 1, NULL, OPTION_NO_USAGE,
+ "Show options for XGANDALF indexing algorithm", 99},
+
+ {"xgandalf-sampling-pitch", 2, "pitch", OPTION_HIDDEN, NULL},
+ {"xgandalf-sps", 2, "pitch", OPTION_HIDDEN, NULL},
+
+ {"xgandalf-grad-desc-iterations", 3, "n", OPTION_HIDDEN, NULL},
+ {"xgandalf-gdis", 3, "n", OPTION_HIDDEN, NULL},
+
+ {"xgandalf-tolerance", 4, "t", OPTION_HIDDEN, NULL},
+ {"xgandalf-tol", 4, "t", OPTION_HIDDEN, NULL},
+
+ {"xgandalf-no-deviation-from-provided-cell", 5, NULL, OPTION_HIDDEN, NULL},
+ {"xgandalf-ndfpc", 5, NULL, OPTION_HIDDEN, NULL},
+
+ {"xgandalf-min-lattice-vector-length", 6, "len", OPTION_HIDDEN, NULL},
+ {"xgandalf-min-lvl", 6, "len", OPTION_HIDDEN, NULL},
+
+ {"xgandalf-max-lattice-vector-length", 7, "len", OPTION_HIDDEN, NULL},
+ {"xgandalf-max-lvl", 7, "len", OPTION_HIDDEN, NULL},
+
+ {"xgandalf-fast-execution", 8, NULL, OPTION_HIDDEN, NULL},
+
+ {"xgandalf-max-peaks", 9, "n", OPTION_HIDDEN, NULL},
+
+ {0}
+};
+
+
+struct argp xgandalf_argp = { options, parse_arg, NULL, NULL, NULL, NULL, NULL };
diff --git a/libcrystfel/src/xgandalf.h b/libcrystfel/src/xgandalf.h
index 23c5c1b0..7cc85388 100644
--- a/libcrystfel/src/xgandalf.h
+++ b/libcrystfel/src/xgandalf.h
@@ -34,21 +34,15 @@
#endif
#include <stddef.h>
+#include <argp.h>
/**
* \file xgandalf.h
* XGANDALF indexer interface
*/
-struct xgandalf_options {
- unsigned int sampling_pitch;
- unsigned int grad_desc_iterations;
- float tolerance;
- unsigned int no_deviation_from_provided_cell;
- float minLatticeVectorLength_A;
- float maxLatticeVectorLength_A;
- int maxPeaksForIndexing;
-};
+typedef struct xgandalf_options XGandalfOptions;
+extern struct argp xgandalf_argp;
#include "index.h"