From 77d007d51024787ec6eb06fad022dde275bd33ac Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 22 Jan 2012 16:03:48 -0800 Subject: More ReAx improvements --- libcrystfel/src/reax.c | 165 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 143 insertions(+), 22 deletions(-) (limited to 'libcrystfel/src/reax.c') diff --git a/libcrystfel/src/reax.c b/libcrystfel/src/reax.c index 80353a2c..ea8f143a 100644 --- a/libcrystfel/src/reax.c +++ b/libcrystfel/src/reax.c @@ -838,35 +838,97 @@ static int right_handed(struct rvec a, struct rvec b, struct rvec c) } -static int check_twinning(UnitCell *c1, UnitCell *c2) +struct cell_candidate +{ + UnitCell *cell; + double fom; +}; + + +struct cell_candidate_list +{ + struct cell_candidate *cand; + int n_cand; +}; + + +static int check_twinning(UnitCell *c1, UnitCell *c2, int verbose) { int i; + int n_dup; + const int n_trials = 40; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; + double ax, ay, az; + double bx, by, bz; + double cx, cy, cz; + + cell_get_reciprocal(c1, &asx, &asy, &asz, + &bsx, &bsy, &bsz, + &csx, &csy, &csz); + cell_get_cartesian(c2, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); + + n_dup = 0; + for ( i=0; i %5.2f %5.2f %5.2f -> " + "%3i %3i %3i -> %5.2f\n", h, k, l, + h2, k2, l2, h2i, k2i, l2i, dev); + } + + if ( dev < 0.1 ) { + n_dup++; + } + + } + + if ( verbose ) { + STATUS("%i duplicates.\n", n_dup); } + if ( n_dup > 10 ) return 1; return 0; } /* Return true if "cnew" accounts for more than 25% of the peaks predicted by * any of the "ncells" cells in "cells". */ -static int twinned(UnitCell *cnew, UnitCell **cells, int ncells) +static int twinned(UnitCell *cnew, struct cell_candidate_list *cl) { int i; - for ( i=0; in_cand; i++ ) { + if ( check_twinning(cnew, cl->cand[i].cell, 0) ) return 1; } return 0; @@ -885,26 +947,64 @@ static int check_vector_combination(struct dvec *vi, struct dvec *vj, ang = angle_between(vi->x, vi->y, vi->z, vj->x, vj->y, vj->z); if ( fabs(ang-ga) > angtol ) return 0; - ang = angle_between(vi->x, vi->y, vi->z, - vk->x, vk->y, vk->z); + ang = angle_between(vi->x, vi->y, vi->z, vk->x, vk->y, vk->z); if ( fabs(ang-be) > angtol ) return 0; - ang = angle_between(vj->x, vj->y, vj->z, - vk->x, vk->y, vk->z); + ang = angle_between(vj->x, vj->y, vj->z, vk->x, vk->y, vk->z); if ( fabs(ang-al) > angtol ) return 0; return 1; } +static void add_cell_candidate(struct cell_candidate_list *cl, UnitCell *cnew, + double fom) +{ + struct cell_candidate cshift; + int i, cpos; + + cpos = cl->n_cand; + for ( i=0; in_cand; i++ ) { + if ( fom > cl->cand[i].fom ) { + cpos = i; + break; + } + } + + cshift.cell = cnew; + cshift.fom = fom; + + for ( i=cpos; in_cand; i++ ) { + + struct cell_candidate cshift2; + cshift2 = cl->cand[i]; + cl->cand[i] = cshift; + cshift = cshift2; + + } + + if ( cl->n_cand >= MAX_CELL_CANDIDATES ) { + /* "cshift" just fell off the end of the list */ + } else { + cl->cand[cl->n_cand++] = cshift; + } +} + + static void assemble_cells_from_candidates(struct image *image, struct reax_search *s, UnitCell *cell) { int i, j, k; signed int ti, tj, tk; - UnitCell *cells[MAX_CELL_CANDIDATES]; - int ncells = 0; + struct cell_candidate_list cl; + + cl.cand = calloc(MAX_CELL_CANDIDATES, sizeof(struct cell_candidate)); + if ( cl.cand == NULL ) { + ERROR("Failed to allocate cell candidate list.\n"); + return; + } + cl.n_cand = 0; /* Find candidates for axes 0 and 1 which have the right angle */ for ( i=0; isearch[0].n_cand; i++ ) { @@ -917,6 +1017,7 @@ static void assemble_cells_from_candidates(struct image *image, struct dvec vi, vj, vk; struct rvec ai, bi, ci; UnitCell *cnew; + double fom; vi = s->search[0].cand[i].v; vj = s->search[1].cand[j].v; @@ -937,17 +1038,15 @@ static void assemble_cells_from_candidates(struct image *image, /* We have three vectors with the right angles */ cnew = cell_new_from_direct_axes(ai, bi, ci); - if ( twinned(cnew, cells, ncells) ) { + refine_cell(image, cnew, image->features); + + if ( twinned(cnew, &cl) ) { cell_free(cnew); continue; } - refine_cell(image, cnew, image->features); - - /* FIXME: Rank according to quality of prediction */ - if ( ncells < MAX_CELL_CANDIDATES ) { - cells[ncells++] = cnew; - } + peak_lattice_agreement(image, cnew, &fom); + add_cell_candidate(&cl, cnew, fom); } } @@ -956,11 +1055,33 @@ static void assemble_cells_from_candidates(struct image *image, } } - image->ncells = ncells; - assert(ncells <= MAX_CELL_CANDIDATES); - for ( i=0; icandidate_cells[i] = cells[i]; + for ( i=0; i aA/10.0 ) w = 1; + if ( (b - bA) > bA/10.0 ) w = 1; + if ( (c - cA) > cA/10.0 ) w = 1; + if ( (al - alA) > deg2rad(5.0) ) w = 1; + if ( (be - beA) > deg2rad(5.0) ) w = 1; + if ( (ga - gaA) > deg2rad(5.0) ) w = 1; + if ( w ) { + STATUS("This cell is a long way from that sought:\n"); + cell_print(cl.cand[i].cell); + } } + + image->ncells = cl.n_cand; + assert(image->ncells <= MAX_CELL_CANDIDATES); + for ( i=0; icandidate_cells[i] = cl.cand[i].cell; + } + + free(cl.cand); } -- cgit v1.2.3