diff options
author | Thomas White <taw@physics.org> | 2016-10-19 10:35:35 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2016-10-19 10:35:35 +0200 |
commit | 59a2678647cd5df865a72c83543a4b1bc5e46be8 (patch) | |
tree | cfa5c2866b8dc2a2cad3b21a73252f8117b6678d | |
parent | e711b80ba12fd1393628cb15a838281566195b2c (diff) |
Fussiness (extreme)
-rw-r--r-- | libcrystfel/src/taketwo.c | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/libcrystfel/src/taketwo.c b/libcrystfel/src/taketwo.c index 21686cd1..90a32891 100644 --- a/libcrystfel/src/taketwo.c +++ b/libcrystfel/src/taketwo.c @@ -117,6 +117,7 @@ static struct rvec new_rvec(double new_u, double new_v, double new_w) return new_rvector; } + static struct rvec diff_vec(struct rvec from, struct rvec to) { struct rvec diff = new_rvec(to.u - from.u, @@ -133,11 +134,13 @@ static double sq_length(struct rvec vec) return sqlength; } + static double rvec_length(struct rvec vec) { return sqrt(sq_length(vec)); } + static void normalise_rvec(struct rvec *vec) { double length = rvec_length(*vec); @@ -146,6 +149,7 @@ static void normalise_rvec(struct rvec *vec) vec->w /= length; } + static double rvec_cosine(struct rvec v1, struct rvec v2) { double dot_prod = v1.u * v2.u + v1.v * v2.v + v1.w * v2.w; @@ -157,6 +161,7 @@ static double rvec_cosine(struct rvec v1, struct rvec v2) return cos_theta; } + static double rvec_angle(struct rvec v1, struct rvec v2) { double cos_theta = rvec_cosine(v1, v2); @@ -165,6 +170,7 @@ static double rvec_angle(struct rvec v1, struct rvec v2) return angle; } + static struct rvec rvec_cross(struct rvec a, struct rvec b) { struct rvec c; @@ -280,32 +286,40 @@ struct rvec gsl_to_rvec(gsl_vector *a) * in cppxfel (IndexingSolution::createSolution). This function is quite * intensive on the number crunching side so simple angle checks are used * to 'pre-scan' vectors beforehand. */ -static int generate_rot_mat(struct rvec obs1, struct rvec obs2, - struct rvec cell1, struct rvec cell2, - gsl_matrix *mat) +static gsl_matrix *generate_rot_mat(struct rvec obs1, struct rvec obs2, + struct rvec cell1, struct rvec cell2) { gsl_matrix *rotateSpotDiffMatrix; gsl_matrix *secondTwizzleMatrix; gsl_matrix *fullMat; - gsl_vector *obs2v = rvec_to_gsl(obs2); - gsl_vector *obs2vr = gsl_vector_calloc(3); + gsl_vector *cell2v = rvec_to_gsl(cell2); + gsl_vector *cell2vr = gsl_vector_calloc(3); - /* Rotate reciprocal space so that the first observed vector lines up - * with the simulated vector. */ - rotateSpotDiffMatrix = rotation_between_vectors(obs1, cell1); + /* Rotate reciprocal space so that the first simulated vector lines up + * with the observed vector. */ + rotateSpotDiffMatrix = rotation_between_vectors(cell1, obs1); - normalise_rvec(&cell1); + normalise_rvec(&obs1); - /* Multiply obs2 by rotateSpotDiffMatrix --> obs2vr */ - gsl_blas_dgemv(CblasNoTrans, 1.0, rotateSpotDiffMatrix, obs2v, - 0.0, obs2vr); + /* Multiply cell2 by rotateSpotDiffMatrix --> cell2vr */ + gsl_blas_dgemv(CblasNoTrans, 1.0, rotateSpotDiffMatrix, cell2v, + 0.0, cell2vr); - /* Now we twirl around the firstAxisUnit until the rotated observed - * vector matches the second simulated vector as closely as possible. */ - secondTwizzleMatrix = closest_rot_mat(gsl_to_rvec(obs2vr), cell2, cell1); - return 1; + /* Now we twirl around the firstAxisUnit until the rotated simulated + * vector matches the second observed vector as closely as possible. */ + secondTwizzleMatrix = closest_rot_mat(gsl_to_rvec(cell2vr), + obs2, obs1); + + /* We want to apply the first matrix and then the second matrix, + * so we multiply these. */ + fullMat = gsl_matrix_calloc(3, 3); + gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, + secondTwizzleMatrix, rotateSpotDiffMatrix, 0.0, fullMat); + + return fullMat; } + static int obs_vecs_share_spot(struct SpotVec *her_obs, struct SpotVec *his_obs) { /* FIXME: Disgusting... can I tone this down a bit? */ @@ -319,6 +333,7 @@ static int obs_vecs_share_spot(struct SpotVec *her_obs, struct SpotVec *his_obs) return 0; } + static int obs_shares_spot_w_array(struct SpotVec *obs_vecs, int test_idx, int *members[MAX_NETWORK_MEMBERS], int num) { @@ -338,6 +353,7 @@ static int obs_shares_spot_w_array(struct SpotVec *obs_vecs, int test_idx, return 0; } + /** Note: this could potentially (and cautiously) converted to comparing * cosines rather than angles, to lose an "acos" but different parts of the * cosine graph are more sensitive than others, so may be a trade off... or not. @@ -377,6 +393,7 @@ static int obs_vecs_match_angles(struct SpotVec *her_obs, return 0; } + static int obs_angles_match_array(struct SpotVec *obs_vecs, int test_idx, int *members[MAX_NETWORK_MEMBERS], int num) { @@ -467,10 +484,10 @@ static int find_next_index(gsl_matrix *rot, struct SpotVec *obs_vecs, gsl_matrix *test_rot = gsl_matrix_calloc(3, 3); int j_idx = (*members)[j]; - generate_rot_mat(obs_vecs[j_idx].obsvec, - obs_vecs[i].obsvec, - *member_match, - *test_match, test_rot); + test_rot = generate_rot_mat(obs_vecs[j_idx].obsvec, + obs_vecs[i].obsvec, + *member_match, + *test_match); ok = rot_mats_are_similar(rot, test_rot); } @@ -489,6 +506,7 @@ static int find_next_index(gsl_matrix *rot, struct SpotVec *obs_vecs, return -1; } + static int grow_network(gsl_matrix *rot, struct SpotVec *obs_vecs, int obs_vec_count, int obs_idx1, int obs_idx2) { @@ -551,6 +569,7 @@ static int grow_network(gsl_matrix *rot, struct SpotVec *obs_vecs, return ( member_num > NETWORK_MEMBER_THRESHOLD ); } + static int find_seed_and_network(struct SpotVec *obs_vecs, int obs_vec_count, gsl_matrix **rotation) { @@ -590,9 +609,10 @@ static int find_seed_and_network(struct SpotVec *obs_vecs, int obs_vec_count, gsl_matrix *rot_mat = gsl_matrix_calloc(3, 3); - generate_rot_mat(obs_vecs[i].obsvec, obs_vecs[j].obsvec, - obs_vecs[i].matches[i_idx], - obs_vecs[j].matches[j_idx], rot_mat); + rot_mat = generate_rot_mat(obs_vecs[i].obsvec, + obs_vecs[j].obsvec, + obs_vecs[i].matches[i_idx], + obs_vecs[j].matches[j_idx]); /* try to expand this rotation matrix to a larger network */ @@ -613,6 +633,7 @@ static int find_seed_and_network(struct SpotVec *obs_vecs, int obs_vec_count, return 0; } + static int match_obs_to_cell_vecs(struct rvec *cell_vecs, int cell_vec_count, struct SpotVec *obs_vecs, int obs_vec_count) { @@ -655,6 +676,7 @@ static int match_obs_to_cell_vecs(struct rvec *cell_vecs, int cell_vec_count, return 1; } + static int gen_observed_vecs(struct rvec *rlps, int rlp_count, struct SpotVec **obs_vecs, int *obs_vec_count) { @@ -709,6 +731,7 @@ static int gen_observed_vecs(struct rvec *rlps, int rlp_count, return 1; } + static int gen_theoretical_vecs(UnitCell *cell, struct rvec **cell_vecs, int *vec_count) { @@ -767,6 +790,7 @@ static int gen_theoretical_vecs(UnitCell *cell, struct rvec **cell_vecs, return 1; } + static void generate_basis_vectors(UnitCell *cell, gsl_matrix *rot, struct rvec *a_star, struct rvec *b_star, struct rvec *c_star) @@ -785,6 +809,7 @@ static void cleanup_taketwo_cell_vecs(struct rvec *cell_vecs) free(cell_vecs); } + static void cleanup_taketwo_obs_vecs(struct SpotVec *obs_vecs, int obs_vec_count) { @@ -796,6 +821,7 @@ static void cleanup_taketwo_obs_vecs(struct SpotVec *obs_vecs, free(obs_vecs); } + /* ------------------------------------------------------------------------ * external functions - top level functions (Level 1) * ------------------------------------------------------------------------*/ |