aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel/src')
-rw-r--r--libcrystfel/src/taketwo.c83
1 files changed, 50 insertions, 33 deletions
diff --git a/libcrystfel/src/taketwo.c b/libcrystfel/src/taketwo.c
index 7d934ceb..c269a44d 100644
--- a/libcrystfel/src/taketwo.c
+++ b/libcrystfel/src/taketwo.c
@@ -82,7 +82,13 @@ struct TakeTwoCell
unsigned int numOps;
struct SpotVec **obs_vecs; // Pointer to an array
int obs_vec_count;
- struct taketwo_options *options;
+
+ /* Options */
+ int member_thresh;
+ double len_tol; /* In reciprocal metres */
+ double angle_tol; /* In radians */
+ double trace_tol; /* Contains sqrt(4*(1-cos(angle))) */
+
gsl_matrix *twiz1Tmp;
gsl_matrix *twiz2Tmp;
gsl_vector *vec1Tmp;
@@ -99,9 +105,6 @@ struct TakeTwoCell
/* Threshold for network members to consider a potential solution */
#define NETWORK_MEMBER_THRESHOLD (20)
-/* Maximum network members (obviously a solution so should stop) */
-#define MAX_NETWORK_MEMBERS (NETWORK_MEMBER_THRESHOLD + 3)
-
/* Maximum dead ends for a single branch extension during indexing */
#define MAX_DEAD_ENDS (10)
@@ -412,7 +415,7 @@ static int rot_mats_are_similar(gsl_matrix *rot1, gsl_matrix *rot2,
tr = matrix_trace(mul);
if (score != NULL) *score = tr;
- return (tr < cell->options->trace_tol);
+ return (tr < cell->trace_tol);
}
static int symm_rot_mats_are_similar(gsl_matrix *rot1, gsl_matrix *rot2,
@@ -580,7 +583,8 @@ static int obs_vecs_match_angles(struct SpotVec *her_obs,
double angle_diff = fabs(theory_angle - obs_angle);
- if ( angle_diff < cell->options->angle_tol ) {
+ if ( angle_diff < cell->angle_tol ) {
+
// in the case of a brief check only
if (!her_match_idxs || !his_match_idxs) {
return 1;
@@ -882,10 +886,16 @@ static int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2,
{
struct SpotVec *obs_vecs = *(cell->obs_vecs);
int obs_vec_count = cell->obs_vec_count;
+ int *obs_members;
+ int *match_members;
/* indices of members of the self-consistent network of vectors */
- int obs_members[MAX_NETWORK_MEMBERS];
- int match_members[MAX_NETWORK_MEMBERS];
+ obs_members = malloc((cell->member_thresh+3)*sizeof(int));
+ match_members = malloc((cell->member_thresh+3)*sizeof(int));
+ if ( (obs_members == NULL) || (match_members == NULL) ) {
+ apologise();
+ return 0;
+ }
/* initialise the ones we know already */
obs_members[0] = obs_idx1;
@@ -949,13 +959,17 @@ static int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2,
}
/* If member_num is high enough, we want to return a yes */
- if ( member_num > cell->options->member_thresh ) break;
+ if ( member_num > cell->member_thresh ) break;
+
}
finish_solution(rot, obs_vecs, obs_members,
- match_members, member_num, cell);
+ match_members, member_num, cell);
+
+ free(obs_members);
+ free(match_members);
- return ( member_num > cell->options->member_thresh );
+ return ( member_num > cell->member_thresh );
}
@@ -1201,7 +1215,7 @@ static int match_obs_to_cell_vecs(struct rvec *cell_vecs, int cell_vec_count,
/* check if this matches the observed length */
double dist_diff = fabs(cell_length - obs_length);
- if ( dist_diff > cell->options->len_tol ) continue;
+ if ( dist_diff > cell->len_tol ) continue;
/* we have a match, add to array! */
@@ -1456,7 +1470,6 @@ static UnitCell *run_taketwo(UnitCell *cell, struct taketwo_options *opts,
struct TakeTwoCell ttCell;
ttCell.cell = cell;
- ttCell.options = opts;
ttCell.rotSymOps = NULL;
ttCell.twiz1Tmp = gsl_matrix_calloc(3, 3);
ttCell.twiz2Tmp = gsl_matrix_calloc(3, 3);
@@ -1476,6 +1489,30 @@ static UnitCell *run_taketwo(UnitCell *cell, struct taketwo_options *opts,
ttCell.obs_vecs = &obs_vecs;
ttCell.obs_vec_count = obs_vec_count;
+ if ( opts->member_thresh < 0 ) {
+ ttCell.member_thresh = NETWORK_MEMBER_THRESHOLD;
+ } else {
+ ttCell.member_thresh = opts->member_thresh;
+ }
+
+ if ( opts->len_tol < 0.0 ) {
+ ttCell.len_tol = RECIP_TOLERANCE;
+ } else {
+ ttCell.len_tol = opts->len_tol; /* Already in m^-1 */
+ }
+
+ if ( opts->angle_tol < 0.0 ) {
+ ttCell.angle_tol = ANGLE_TOLERANCE;
+ } else {
+ ttCell.angle_tol = opts->angle_tol; /* Already in radians */
+ }
+
+ if ( opts->trace_tol < 0.0 ) {
+ ttCell.trace_tol = sqrt(4.0*(1.0-cos(TRACE_TOLERANCE)));
+ } else {
+ ttCell.trace_tol = sqrt(4.0*(1.0-cos(opts->trace_tol)));
+ }
+
success = match_obs_to_cell_vecs(asym_vecs, asym_vec_count,
obs_vecs, obs_vec_count, 1, &ttCell);
@@ -1514,26 +1551,6 @@ int taketwo_index(struct image *image, struct taketwo_options *opts, void *priv)
int i;
struct taketwo_private *tp = (struct taketwo_private *)priv;
- /* Replace negative values in options with defaults */
-
- if (opts->member_thresh < 0) {
- opts->member_thresh = NETWORK_MEMBER_THRESHOLD;
- }
-
- if (opts->len_tol < 0) {
- opts->len_tol = RECIP_TOLERANCE;
- }
-
- if (opts->angle_tol < 0) {
- opts->angle_tol = ANGLE_TOLERANCE;
- }
-
- if (opts->trace_tol < 0) {
- opts->trace_tol = TRACE_TOLERANCE;
- }
-
- opts->trace_tol = sqrt(4.0*(1.0-cos(opts->trace_tol)));
-
rlps = malloc((image_feature_count(image->features)+1)*sizeof(struct rvec));
for ( i=0; i<image_feature_count(image->features); i++ ) {
struct imagefeature *pk = image_get_feature(image->features, i);