aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src/index.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel/src/index.c')
-rw-r--r--libcrystfel/src/index.c274
1 files changed, 274 insertions, 0 deletions
diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c
new file mode 100644
index 00000000..d5e76c50
--- /dev/null
+++ b/libcrystfel/src/index.c
@@ -0,0 +1,274 @@
+/*
+ * index.c
+ *
+ * Perform indexing (somehow)
+ *
+ * (c) 2006-2011 Thomas White <taw@physics.org>
+ * (c) 2010 Richard Kirian <rkirian@asu.edu>
+ *
+ * Part of CrystFEL - crystallography with a FEL
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+
+#include "image.h"
+#include "utils.h"
+#include "peaks.h"
+#include "dirax.h"
+#include "mosflm.h"
+#include "detector.h"
+#include "index.h"
+#include "index-priv.h"
+#include "reax.h"
+#include "geometry.h"
+
+
+/* Base class constructor for unspecialised indexing private data */
+IndexingPrivate *indexing_private(IndexingMethod indm)
+{
+ struct _indexingprivate *priv;
+ priv = calloc(1, sizeof(struct _indexingprivate));
+ priv->indm = indm;
+ return priv;
+}
+
+
+static const char *maybes(int n)
+{
+ if ( n == 1 ) return "";
+ return "s";
+}
+
+
+IndexingPrivate **prepare_indexing(IndexingMethod *indm, UnitCell *cell,
+ const char *filename, struct detector *det,
+ double nominal_photon_energy)
+{
+ int n;
+ int nm = 0;
+ IndexingPrivate **iprivs;
+
+ while ( indm[nm] != INDEXING_NONE ) nm++;
+ STATUS("Preparing %i indexing method%s.\n", nm, maybes(nm));
+ iprivs = malloc((nm+1) * sizeof(IndexingPrivate *));
+
+ for ( n=0; n<nm; n++ ) {
+
+ switch ( indm[n] ) {
+ case INDEXING_NONE :
+ ERROR("Tried to prepare INDEXING_NONE!\n");
+ break;
+ case INDEXING_DIRAX :
+ iprivs[n] = indexing_private(indm[n]);
+ break;
+ case INDEXING_MOSFLM :
+ iprivs[n] = indexing_private(indm[n]);
+ break;
+ case INDEXING_REAX :
+ iprivs[n] = reax_prepare();
+ break;
+ }
+
+ }
+ iprivs[n] = NULL;
+
+ return iprivs;
+}
+
+
+void cleanup_indexing(IndexingPrivate **priv)
+{
+ int n = 0;
+
+ if ( priv == NULL ) return; /* Nothing to do */
+
+ while ( priv[n] != NULL ) {
+
+ switch ( priv[n]->indm ) {
+ case INDEXING_NONE :
+ free(priv[n]);
+ break;
+ case INDEXING_DIRAX :
+ free(priv[n]);
+ break;
+ case INDEXING_MOSFLM :
+ free(priv[n]);
+ break;
+ case INDEXING_REAX :
+ reax_cleanup(priv[n]);
+ break;
+ }
+
+ n++;
+
+ }
+}
+
+
+void map_all_peaks(struct image *image)
+{
+ int i, n;
+
+ n = image_feature_count(image->features);
+
+ /* Map positions to 3D */
+ for ( i=0; i<n; i++ ) {
+
+ struct imagefeature *f;
+ struct rvec r;
+
+ f = image_get_feature(image->features, i);
+ if ( f == NULL ) continue;
+
+ r = get_q(image, f->fs, f->ss, NULL, 1.0/image->lambda);
+ f->rx = r.u; f->ry = r.v; f->rz = r.w;
+
+ }
+}
+
+
+void index_pattern(struct image *image, UnitCell *cell, IndexingMethod *indm,
+ int cellr, int verbose, IndexingPrivate **ipriv,
+ int config_insane)
+{
+ int i;
+ int n = 0;
+
+ if ( indm == NULL ) return;
+
+ map_all_peaks(image);
+ image->indexed_cell = NULL;
+
+ while ( indm[n] != INDEXING_NONE ) {
+
+ image->ncells = 0;
+
+ /* Index as appropriate */
+ switch ( indm[n] ) {
+ case INDEXING_NONE :
+ return;
+ case INDEXING_DIRAX :
+ run_dirax(image);
+ break;
+ case INDEXING_MOSFLM :
+ run_mosflm(image, cell);
+ break;
+ case INDEXING_REAX :
+ reax_index(ipriv[n], image, cell);
+ break;
+ }
+ if ( image->ncells == 0 ) {
+ n++;
+ continue;
+ }
+
+ for ( i=0; i<image->ncells; i++ ) {
+
+ UnitCell *new_cell = NULL;
+ UnitCell *cand = image->candidate_cells[i];
+
+ if ( verbose ) {
+ STATUS("--------------------\n");
+ STATUS("Candidate cell %i (before matching):\n",
+ i);
+ cell_print(image->candidate_cells[i]);
+ STATUS("--------------------\n");
+ }
+
+ /* Match or reduce the cell as appropriate */
+ switch ( cellr ) {
+ case CELLR_NONE :
+ new_cell = cell_new_from_cell(cand);
+ break;
+ case CELLR_REDUCE :
+ new_cell = match_cell(cand, cell, verbose, 1);
+ break;
+ case CELLR_COMPARE :
+ new_cell = match_cell(cand, cell, verbose, 0);
+ break;
+ case CELLR_COMPARE_AB :
+ new_cell = match_cell_ab(cand, cell);
+ break;
+ }
+
+ /* No cell? Move on to the next candidate */
+ if ( new_cell == NULL ) continue;
+
+ /* Sanity check */
+ image->reflections = find_intersections(image, new_cell);
+ image->indexed_cell = new_cell;
+
+ if ( !config_insane && !peak_sanity_check(image) ) {
+ cell_free(new_cell);
+ image->indexed_cell = NULL;
+ continue;
+ }
+
+ goto done; /* Success */
+
+ }
+
+ for ( i=0; i<image->ncells; i++ ) {
+ cell_free(image->candidate_cells[i]);
+ image->candidate_cells[i] = NULL;
+ }
+
+ /* Move on to the next indexing method */
+ n++;
+
+ }
+
+done:
+ for ( i=0; i<image->ncells; i++ ) {
+ /* May free(NULL) if all algorithms were tried and no success */
+ cell_free(image->candidate_cells[i]);
+ }
+}
+
+
+IndexingMethod *build_indexer_list(const char *str, int *need_cell)
+{
+ int n, i;
+ char **methods;
+ IndexingMethod *list;
+ int tmp;
+
+ if ( need_cell == NULL ) need_cell = &tmp;
+ *need_cell = 0;
+
+ n = assplode(str, ",", &methods, ASSPLODE_NONE);
+ list = malloc((n+1)*sizeof(IndexingMethod));
+
+ for ( i=0; i<n; i++ ) {
+
+ if ( strcmp(methods[i], "dirax") == 0) {
+ list[i] = INDEXING_DIRAX;
+ } else if ( strcmp(methods[i], "mosflm") == 0) {
+ list[i] = INDEXING_MOSFLM;
+ } else if ( strcmp(methods[i], "reax") == 0) {
+ list[i] = INDEXING_REAX;
+ *need_cell = 1;
+ } else {
+ ERROR("Unrecognised indexing method '%s'\n",
+ methods[i]);
+ return NULL;
+ }
+
+ free(methods[i]);
+
+ }
+ free(methods);
+ list[i] = INDEXING_NONE;
+
+ return list;
+}