/* * index.c * * Perform indexing (somehow) * * Copyright © 2012 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * Copyright © 2012 Lorenzo Galli * * Authors: * 2010-2012 Thomas White * 2010-2011 Richard Kirian * 2012 Lorenzo Galli * * 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 "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" #include "cell-utils.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; nindm ) { 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; ifeatures, 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, const float *ltl) { 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; incells; 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, ltl, 1); break; case CELLR_COMPARE : new_cell = match_cell(cand, cell, verbose, ltl, 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->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; incells; i++ ) { cell_free(image->candidate_cells[i]); image->candidate_cells[i] = NULL; } /* Move on to the next indexing method */ n++; } done: for ( i=0; incells; 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