aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel/src')
-rw-r--r--libcrystfel/src/asdf.c6
-rw-r--r--libcrystfel/src/asdf.h8
-rw-r--r--libcrystfel/src/dirax.c52
-rw-r--r--libcrystfel/src/dirax.h1
-rw-r--r--libcrystfel/src/felix.c56
-rw-r--r--libcrystfel/src/felix.h2
-rw-r--r--libcrystfel/src/index.c81
-rw-r--r--libcrystfel/src/index.h3
-rw-r--r--libcrystfel/src/mosflm.c78
-rw-r--r--libcrystfel/src/mosflm.h1
-rw-r--r--libcrystfel/src/reflist-utils.c48
-rw-r--r--libcrystfel/src/reflist-utils.h6
-rw-r--r--libcrystfel/src/stream.c20
-rw-r--r--libcrystfel/src/stream.h1
-rw-r--r--libcrystfel/src/taketwo.c6
-rw-r--r--libcrystfel/src/taketwo.h1
-rw-r--r--libcrystfel/src/xds.c61
-rw-r--r--libcrystfel/src/xds.h2
18 files changed, 413 insertions, 20 deletions
diff --git a/libcrystfel/src/asdf.c b/libcrystfel/src/asdf.c
index 869d9256..9dc5f9d5 100644
--- a/libcrystfel/src/asdf.c
+++ b/libcrystfel/src/asdf.c
@@ -1188,3 +1188,9 @@ void asdf_cleanup(void *pp)
fftw_vars_free(p->fftw);
free(p);
}
+
+
+const char *asdf_probe(UnitCell *cell)
+{
+ return "asdf";
+}
diff --git a/libcrystfel/src/asdf.h b/libcrystfel/src/asdf.h
index 7f110960..896f65a8 100644
--- a/libcrystfel/src/asdf.h
+++ b/libcrystfel/src/asdf.h
@@ -46,6 +46,7 @@ extern "C" {
extern int run_asdf(struct image *image, void *ipriv);
extern void *asdf_prepare(IndexingMethod *indm, UnitCell *cell);
+extern const char *asdf_probe(UnitCell *cell);
extern void asdf_cleanup(void *pp);
@@ -65,6 +66,13 @@ void *asdf_prepare(IndexingMethod *indm, UnitCell *cell)
return NULL;
}
+
+const char *asdf_probe(UnitCell *cell)
+{
+ return NULL;
+}
+
+
void asdf_cleanup(void *pp)
{
}
diff --git a/libcrystfel/src/dirax.c b/libcrystfel/src/dirax.c
index f781d7e2..512a61e1 100644
--- a/libcrystfel/src/dirax.c
+++ b/libcrystfel/src/dirax.c
@@ -604,6 +604,12 @@ void *dirax_prepare(IndexingMethod *indm, UnitCell *cell)
{
struct dirax_private *dp;
+ if ( dirax_probe(cell) == NULL ) {
+ ERROR("DirAx does not appear to run properly.\n");
+ ERROR("Please check your DirAx installation.\n");
+ return NULL;
+ }
+
/* Flags that DirAx knows about */
*indm &= INDEXING_METHOD_MASK;
@@ -623,3 +629,49 @@ void dirax_cleanup(void *pp)
p = (struct dirax_private *)pp;
free(p);
}
+
+
+const char *dirax_probe(UnitCell *cell)
+{
+ pid_t pid;
+ int pty;
+ int status;
+ FILE *fh;
+ char line[1024];
+ int ok = 0;
+
+ pid = forkpty(&pty, NULL, NULL, NULL);
+ if ( pid == -1 ) {
+ return NULL;
+ }
+ if ( pid == 0 ) {
+
+ /* Child process: invoke DirAx */
+ struct termios t;
+
+ /* Turn echo off */
+ tcgetattr(STDIN_FILENO, &t);
+ t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+ tcsetattr(STDIN_FILENO, TCSANOW, &t);
+
+ execlp("dirax", "dirax", (char *)NULL);
+ _exit(1);
+
+ }
+
+ fh = fdopen(pty, "r");
+ if ( fgets(line, 1024, fh) == NULL ) {
+ ERROR("Failed to probe for DirAx\n");
+ } else {
+ if ( strncmp(line, "dirax", 5) == 0 ) {
+ ok = 1;
+ }
+ }
+
+ fclose(fh);
+ close(pty);
+ waitpid(pid, &status, 0);
+
+ if ( ok ) return "dirax";
+ return NULL;
+}
diff --git a/libcrystfel/src/dirax.h b/libcrystfel/src/dirax.h
index db03abf8..dce27c57 100644
--- a/libcrystfel/src/dirax.h
+++ b/libcrystfel/src/dirax.h
@@ -42,6 +42,7 @@ extern "C" {
extern int run_dirax(struct image *image, void *ipriv);
extern void *dirax_prepare(IndexingMethod *indm, UnitCell *cell);
+extern const char *dirax_probe(UnitCell *cell);
extern void dirax_cleanup(void *pp);
diff --git a/libcrystfel/src/felix.c b/libcrystfel/src/felix.c
index 9de926f6..bbd82b0e 100644
--- a/libcrystfel/src/felix.c
+++ b/libcrystfel/src/felix.c
@@ -610,6 +610,12 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell,
{
struct felix_private *gp;
+ if ( felix_probe(cell) == NULL ) {
+ ERROR("Felix does not appear to run properly.\n");
+ ERROR("Please check your Felix installation.\n");
+ return NULL;
+ }
+
if ( !cell_has_parameters(cell) ) {
ERROR("Felix needs a unit cell.\n");
return NULL;
@@ -695,3 +701,53 @@ void felix_cleanup(IndexingPrivate *pp)
free(p->readhkl_file);
free(p);
}
+
+
+const char *felix_probe(UnitCell *cell)
+{
+ pid_t pid;
+ int pty;
+ int status;
+ FILE *fh;
+ char line[1024];
+ int ok = 0;
+
+ if ( !cell_has_parameters(cell) ) {
+ return NULL;
+ }
+
+ pid = forkpty(&pty, NULL, NULL, NULL);
+ if ( pid == -1 ) {
+ return NULL;
+ }
+ if ( pid == 0 ) {
+
+ /* Child process: invoke DirAx */
+ struct termios t;
+
+ /* Turn echo off */
+ tcgetattr(STDIN_FILENO, &t);
+ t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+ tcsetattr(STDIN_FILENO, TCSANOW, &t);
+
+ execlp("Felix", "Felix", (char *)NULL);
+ _exit(1);
+
+ }
+
+ fh = fdopen(pty, "r");
+ if ( fgets(line, 1024, fh) == NULL ) {
+ ERROR("Failed to probe for Felix\n");
+ } else {
+ if ( strncmp(line, "Felix", 5) == 0 ) {
+ ok = 1;
+ }
+ }
+
+ fclose(fh);
+ close(pty);
+ waitpid(pid, &status, 0);
+
+ if ( ok ) return "felix";
+ return NULL;
+}
diff --git a/libcrystfel/src/felix.h b/libcrystfel/src/felix.h
index ab9ba744..48ffbe9c 100644
--- a/libcrystfel/src/felix.h
+++ b/libcrystfel/src/felix.h
@@ -51,6 +51,8 @@ struct felix_options
extern void *felix_prepare(IndexingMethod *indm, UnitCell *cell,
struct felix_options *opts);
+extern const char *felix_probe(UnitCell *cell);
+
extern void felix_cleanup(IndexingPrivate *pp);
extern int felix_index(struct image *image, IndexingPrivate *p);
diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c
index 03bd6ae3..62f22c13 100644
--- a/libcrystfel/src/index.c
+++ b/libcrystfel/src/index.c
@@ -284,10 +284,13 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
}
for ( i=0; i<n; i++ ) {
- methods[i] = get_indm_from_string(method_strings[i]);
- if ( methods[i] == INDEXING_ERROR ) {
+ int err = 0;
+ methods[i] = get_indm_from_string_2(method_strings[i], &err);
+ if ( err ) {
ERROR("----- Notice -----\n");
- ERROR("The way indexing options are used has changed in this CrystFEL version.\n");
+ ERROR("The way indexing options are given has changed in this CrystFEL version.\n");
+ ERROR("The indexing method should contain only the method itself and ");
+ ERROR("prior information modifiers ('cell' or 'latt')\n");
ERROR("To disable prediction refinement ('norefine'), use --no-refine.\n");
ERROR("To check cell axes only ('axes'), use --no-cell-combinations.\n");
ERROR("To disable all unit cell checks ('raw'), use --no-check-cell.\n");
@@ -298,6 +301,7 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
free(methods);
return NULL;
}
+
}
/* No cell parameters -> no cell checking, no prior cell */
@@ -878,13 +882,15 @@ static IndexingMethod warn_method(const char *str)
}
-IndexingMethod get_indm_from_string(const char *str)
+IndexingMethod get_indm_from_string_2(const char *str, int *err)
{
int n, i;
char **bits;
IndexingMethod method = INDEXING_NONE;
int have_method = 0;
+ if ( err != NULL ) *err = 0;
+
n = assplode(str, "-", &bits, ASSPLODE_NONE);
for ( i=0; i<n; i++ ) {
@@ -946,6 +952,28 @@ IndexingMethod get_indm_from_string(const char *str)
} else if ( strcmp(bits[i], "nocell") == 0) {
method = set_nocellparams(method);
+ /* Deprecated options */
+ } else if ( strcmp(bits[i], "retry") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "noretry") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "multi") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "nomulti") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "refine") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "norefine") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "raw") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "bad") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "comb") == 0) {
+ if ( err != NULL ) *err = 1;
+ } else if ( strcmp(bits[i], "axes") == 0) {
+ if ( err != NULL ) *err = 1;
+
} else {
ERROR("Bad list of indexing methods: '%s'\n", str);
return INDEXING_ERROR;
@@ -960,3 +988,48 @@ IndexingMethod get_indm_from_string(const char *str)
return method;
}
+
+
+IndexingMethod get_indm_from_string(const char *str)
+{
+ return get_indm_from_string_2(str, NULL);
+}
+
+
+static void do_probe(const char *(*func)(UnitCell *cell),
+ UnitCell *cell, char *methods)
+{
+ const char *probe;
+ probe = func(cell);
+ if ( probe != NULL ) {
+ if ( methods[0] != '\0' ) {
+ strcat(methods, ",");
+ }
+ strcat(methods, probe);
+ }
+}
+
+
+char *detect_indexing_methods(UnitCell *cell)
+{
+ char *methods;
+
+ methods = malloc(1024);
+ if ( methods == NULL ) return NULL;
+ methods[0] = '\0';
+
+ do_probe(mosflm_probe, cell, methods);
+ do_probe(dirax_probe, cell, methods);
+ do_probe(asdf_probe, cell, methods);
+ do_probe(xds_probe, cell, methods);
+ do_probe(taketwo_probe, cell, methods);
+ /* Don't automatically use Felix (yet) */
+ //do_probe(felix_probe, cell, methods);
+
+ if ( strlen(methods) == 0 ) {
+ free(methods);
+ return NULL;
+ }
+
+ return methods;
+}
diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h
index 15843b2a..8ece9227 100644
--- a/libcrystfel/src/index.h
+++ b/libcrystfel/src/index.h
@@ -130,6 +130,7 @@ typedef struct _indexingprivate IndexingPrivate;
/* Convert indexing methods to/from text */
extern char *indexer_str(IndexingMethod indm);
extern IndexingMethod get_indm_from_string(const char *method);
+extern IndexingMethod get_indm_from_string_2(const char *method, int *err);
#include "detector.h"
#include "cell.h"
@@ -144,6 +145,8 @@ extern IndexingPrivate *setup_indexing(const char *methods, UnitCell *cell,
struct taketwo_options *ttopts,
struct felix_options *felix_opts);
+extern char *detect_indexing_methods(UnitCell *cell);
+
extern void index_pattern(struct image *image, IndexingPrivate *ipriv);
extern void index_pattern_2(struct image *image, IndexingPrivate *ipriv,
diff --git a/libcrystfel/src/mosflm.c b/libcrystfel/src/mosflm.c
index 4cf21103..7ebf6e19 100644
--- a/libcrystfel/src/mosflm.c
+++ b/libcrystfel/src/mosflm.c
@@ -821,6 +821,12 @@ void *mosflm_prepare(IndexingMethod *indm, UnitCell *cell)
{
struct mosflm_private *mp;
+ if ( mosflm_probe(cell) == NULL ) {
+ ERROR("Mosflm does not appear to run properly.\n");
+ ERROR("Please check your Mosflm installation.\n");
+ return NULL;
+ }
+
/* Flags that MOSFLM knows about */
*indm &= INDEXING_METHOD_MASK
| INDEXING_USE_LATTICE_TYPE | INDEXING_USE_CELL_PARAMETERS;
@@ -841,3 +847,75 @@ void mosflm_cleanup(void *pp)
p = (struct mosflm_private *)pp;
free(p);
}
+
+
+static void chop_word(char *s)
+{
+ int i;
+ size_t l = strlen(s);
+ for ( i=0; i<l; i++ ) {
+ if ( s[i] == ' ' ) {
+ s[i] = '\0';
+ return;
+ }
+ }
+}
+
+
+const char *mosflm_probe(UnitCell *cell)
+{
+ pid_t pid;
+ int pty;
+ int status;
+ FILE *fh;
+ char line[1024];
+ int ok = 0;
+ int l;
+
+ pid = forkpty(&pty, NULL, NULL, NULL);
+ if ( pid == -1 ) {
+ return NULL;
+ }
+ if ( pid == 0 ) {
+
+ /* Child process */
+ struct termios t;
+
+ /* Turn echo off */
+ tcgetattr(STDIN_FILENO, &t);
+ t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+ tcsetattr(STDIN_FILENO, TCSANOW, &t);
+
+ execlp("mosflm", "mosflm", (char *)NULL);
+ execlp("ipmosflm", "ipmosflm", (char *)NULL);
+ _exit(1);
+
+ }
+
+ fh = fdopen(pty, "r");
+
+ for ( l=0; l<10; l++ ) {
+ char *pos;
+ if ( fgets(line, 1024, fh) == NULL ) {
+ ERROR("Failed to probe for Mosflm\n");
+ } else {
+ pos = strstr(line, "Mosflm version ");
+ if ( pos != NULL ) {
+ char *vers = pos+15;
+ ok = 1;
+ chop_word(vers);
+ /* FIXME: Set capabilities based on version */
+ }
+ }
+ }
+
+ fclose(fh);
+ close(pty);
+ waitpid(pid, &status, 0);
+
+ if ( !ok ) return NULL;
+
+ if ( cell_has_parameters(cell) ) return "mosflm-cell-nolatt,mosflm-latt-nocell";
+ if ( cell != NULL ) return "mosflm-latt-nocell";
+ return "mosflm-nolatt-nocell";
+}
diff --git a/libcrystfel/src/mosflm.h b/libcrystfel/src/mosflm.h
index cd7804a8..9339b856 100644
--- a/libcrystfel/src/mosflm.h
+++ b/libcrystfel/src/mosflm.h
@@ -44,6 +44,7 @@ extern "C" {
extern int run_mosflm(struct image *image, void *ipriv);
extern void *mosflm_prepare(IndexingMethod *indm, UnitCell *cell);
+extern const char *mosflm_probe(UnitCell *cell);
extern void mosflm_cleanup(void *pp);
diff --git a/libcrystfel/src/reflist-utils.c b/libcrystfel/src/reflist-utils.c
index 1aee6018..7ff78f52 100644
--- a/libcrystfel/src/reflist-utils.c
+++ b/libcrystfel/src/reflist-utils.c
@@ -3,11 +3,11 @@
*
* Utilities to complement the core reflist.c
*
- * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY,
+ * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY,
* a research centre of the Helmholtz Association.
*
* Authors:
- * 2011-2016 Thomas White <taw@physics.org>
+ * 2011-2017 Thomas White <taw@physics.org>
* 2014 Valerio Mariani
*
* This file is part of CrystFEL.
@@ -283,15 +283,13 @@ int write_reflist(const char *filename, RefList *list)
#define HEADER_2_0 "CrystFEL reflection list version 2.0"
-/**
- * read_reflections_from_file:
- * @fh: File handle to read from
- *
- * This function reads a reflection list from @fh.
+/* fh: File handle to read from
+ * sym: Location at which to store pointer to symmetry, or NULL if you don't
+ * need it
*
* Returns: a %RefList read from the file, or NULL on error
- **/
-RefList *read_reflections_from_file(FILE *fh)
+ */
+static RefList *read_reflections_from_file(FILE *fh, char **sym)
{
char *rval = NULL;
RefList *out;
@@ -317,7 +315,9 @@ RefList *read_reflections_from_file(FILE *fh)
chomp(line);
if ( strncmp(line, "Symmetry: ", 10) != 0 ) return NULL;
- /* FIXME: Do something with the symmetry */
+ if ( sym != NULL ) {
+ *sym = strdup(line+10);
+ }
/* Read (and ignore) the header */
rval = fgets(line, 1023, fh);
@@ -418,7 +418,17 @@ RefList *read_reflections_from_file(FILE *fh)
}
-RefList *read_reflections(const char *filename)
+/**
+ * read_reflections_2:
+ * @filename: Filename to read from
+ * @sym: Pointer to a "char *" at which to store the symmetry
+ *
+ * This function reads a reflection list from a file, including the
+ * symmetry from the header (e.g. "Symmetry: 4/mmm").
+ *
+ * Returns: A %RefList read from the file, or NULL on error
+ */
+RefList *read_reflections_2(const char *filename, char **sym)
{
FILE *fh;
RefList *out;
@@ -434,7 +444,7 @@ RefList *read_reflections(const char *filename)
return NULL;
}
- out = read_reflections_from_file(fh);
+ out = read_reflections_from_file(fh, sym);
fclose(fh);
@@ -443,6 +453,20 @@ RefList *read_reflections(const char *filename)
/**
+ * read_reflections:
+ * @filename: Filename to read from
+ *
+ * This function reads a reflection list from a file.
+ *
+ * Returns: A %RefList read from the file, or NULL on error
+ */
+RefList *read_reflections(const char *filename)
+{
+ return read_reflections_2(filename, NULL);
+}
+
+
+/**
* asymmetric_indices:
* @in: A %RefList
* @sym: A %SymOpList
diff --git a/libcrystfel/src/reflist-utils.h b/libcrystfel/src/reflist-utils.h
index 50838b86..f64e9f51 100644
--- a/libcrystfel/src/reflist-utils.h
+++ b/libcrystfel/src/reflist-utils.h
@@ -3,11 +3,11 @@
*
* Utilities to complement the core reflist.c
*
- * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY,
+ * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY,
* a research centre of the Helmholtz Association.
*
* Authors:
- * 2011-2016 Thomas White <taw@physics.org>
+ * 2011-2017 Thomas White <taw@physics.org>
* 2014 Valerio Mariani
*
* This file is part of CrystFEL.
@@ -49,8 +49,8 @@ extern "C" {
extern int write_reflist(const char *filename, RefList *list);
extern int write_reflist_2(const char *filename, RefList *list, SymOpList *sym);
-extern RefList *read_reflections_from_file(FILE *fh);
extern RefList *read_reflections(const char *filename);
+extern RefList *read_reflections_2(const char *filename, char **sym);
extern int check_list_symmetry(RefList *list, const SymOpList *sym);
extern int find_equiv_in_list(RefList *list, signed int h, signed int k,
diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c
index fb4b0c70..d7d997cf 100644
--- a/libcrystfel/src/stream.c
+++ b/libcrystfel/src/stream.c
@@ -67,8 +67,18 @@ struct _stream
int minor_version;
long long int ln;
+
+ int old_indexers; /* True if the stream reader encountered a deprecated
+ * indexing method */
};
+
+int stream_has_old_indexers(Stream *st)
+{
+ return st->old_indexers;
+}
+
+
static int read_peaks(Stream *st, struct image *image)
{
char *rval = NULL;
@@ -1196,10 +1206,14 @@ int read_chunk_2(Stream *st, struct image *image, StreamReadFlags srf)
}
if ( strncmp(line, "indexed_by = ", 13) == 0 ) {
- image->indexed_by = get_indm_from_string(line+13);
+ int err = 0;
+ image->indexed_by = get_indm_from_string_2(line+13, &err);
if ( image->indexed_by == INDEXING_ERROR ) {
ERROR("Failed to read indexer list\n");
}
+ if ( err ) {
+ st->old_indexers = 1;
+ }
}
if ( strncmp(line, "photon_energy_eV = ", 19) == 0 ) {
@@ -1327,6 +1341,7 @@ Stream *open_stream_for_read(const char *filename)
st = malloc(sizeof(struct _stream));
if ( st == NULL ) return NULL;
+ st->old_indexers = 0;
if ( strcmp(filename, "-") == 0 ) {
st->fh = stdin;
@@ -1393,6 +1408,7 @@ Stream *open_stream_fd_for_write(int fd)
st = malloc(sizeof(struct _stream));
if ( st == NULL ) return NULL;
+ st->old_indexers = 0;
st->fh = fdopen(fd, "w");
if ( st->fh == NULL ) {
@@ -1442,6 +1458,7 @@ Stream *open_stream_for_write_3(const char *filename,
st = malloc(sizeof(struct _stream));
if ( st == NULL ) return NULL;
+ st->old_indexers = 0;
st->fh = fopen(filename, "w");
if ( st->fh == NULL ) {
@@ -1493,6 +1510,7 @@ Stream *open_stream_for_write_2(const char *filename,
st = malloc(sizeof(struct _stream));
if ( st == NULL ) return NULL;
+ st->old_indexers = 0;
st->fh = fopen(filename, "w");
if ( st->fh == NULL ) {
diff --git a/libcrystfel/src/stream.h b/libcrystfel/src/stream.h
index 764e3e36..2ed7b050 100644
--- a/libcrystfel/src/stream.h
+++ b/libcrystfel/src/stream.h
@@ -106,6 +106,7 @@ extern void close_stream(Stream *st);
extern int read_chunk(Stream *st, struct image *image);
extern int read_chunk_2(Stream *st, struct image *image,
StreamReadFlags srf);
+extern int stream_has_old_indexers(Stream *st);
extern int write_chunk(Stream *st, struct image *image, struct imagefile *imfile,
int include_peaks, int include_reflections,
diff --git a/libcrystfel/src/taketwo.c b/libcrystfel/src/taketwo.c
index 757c6c52..0857f813 100644
--- a/libcrystfel/src/taketwo.c
+++ b/libcrystfel/src/taketwo.c
@@ -1642,3 +1642,9 @@ void taketwo_cleanup(IndexingPrivate *pp)
free(tp);
}
+
+const char *taketwo_probe(UnitCell *cell)
+{
+ if ( cell_has_parameters(cell) ) return "taketwo";
+ return NULL;
+}
diff --git a/libcrystfel/src/taketwo.h b/libcrystfel/src/taketwo.h
index e82dda68..fcd7aebc 100644
--- a/libcrystfel/src/taketwo.h
+++ b/libcrystfel/src/taketwo.h
@@ -44,6 +44,7 @@ struct taketwo_options
extern void *taketwo_prepare(IndexingMethod *indm, UnitCell *cell);
+extern const char *taketwo_probe(UnitCell *cell);
extern int taketwo_index(struct image *image,
const struct taketwo_options *opts, void *priv);
extern void taketwo_cleanup(IndexingPrivate *pp);
diff --git a/libcrystfel/src/xds.c b/libcrystfel/src/xds.c
index ba053d2f..bfb977ea 100644
--- a/libcrystfel/src/xds.c
+++ b/libcrystfel/src/xds.c
@@ -45,6 +45,7 @@
#include <sys/ioctl.h>
#include <errno.h>
+#include "xds.h"
#include "cell.h"
#include "image.h"
#include "utils.h"
@@ -596,6 +597,12 @@ void *xds_prepare(IndexingMethod *indm, UnitCell *cell)
{
struct xds_private *xp;
+ if ( xds_probe(cell) == NULL ) {
+ ERROR("XDS does not appear to run properly.\n");
+ ERROR("Please check your XDS installation.\n");
+ return NULL;
+ }
+
/* Either cell,latt and cell provided, or nocell-nolatt and no cell
* - complain about anything else. Could figure this out automatically,
* but we'd have to decide whether the user just forgot the cell, or
@@ -637,3 +644,57 @@ void xds_cleanup(void *pp)
xp = (struct xds_private *)pp;
free(xp);
}
+
+
+const char *xds_probe(UnitCell *cell)
+{
+ pid_t pid;
+ int pty;
+ int status;
+ FILE *fh;
+ char line[1024];
+ int ok = 0;
+ int l;
+
+ pid = forkpty(&pty, NULL, NULL, NULL);
+ if ( pid == -1 ) {
+ return NULL;
+ }
+ if ( pid == 0 ) {
+
+ /* Child process */
+ struct termios t;
+
+ /* Turn echo off */
+ tcgetattr(STDIN_FILENO, &t);
+ t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+ tcsetattr(STDIN_FILENO, TCSANOW, &t);
+
+ execlp("xds", "xds", (char *)NULL);
+ _exit(1);
+
+ }
+
+ fh = fdopen(pty, "r");
+
+ for ( l=0; l<10; l++ ) {
+ char *pos;
+ if ( fgets(line, 1024, fh) == NULL ) {
+ ERROR("Failed to probe for XDS\n");
+ } else {
+ pos = strstr(line, "** XDS **");
+ if ( pos != NULL ) {
+ ok = 1;
+ }
+ }
+ }
+
+ fclose(fh);
+ close(pty);
+ waitpid(pid, &status, 0);
+
+ if ( !ok ) return NULL;
+
+ if ( cell_has_parameters(cell) ) return "xds-cell-latt";
+ return "xds-nocell-nolatt";
+}
diff --git a/libcrystfel/src/xds.h b/libcrystfel/src/xds.h
index 8777df10..c89b615c 100644
--- a/libcrystfel/src/xds.h
+++ b/libcrystfel/src/xds.h
@@ -46,6 +46,8 @@ extern int run_xds(struct image *image, void *ipriv);
extern void *xds_prepare(IndexingMethod *indm, UnitCell *cell);
+extern const char *xds_probe(UnitCell *cell);
+
extern void xds_cleanup(void *pp);
#ifdef __cplusplus