diff options
author | Helen Ginn <helen@strubi.ox.ac.uk> | 2017-06-14 14:29:52 +0100 |
---|---|---|
committer | Helen Ginn <helen@strubi.ox.ac.uk> | 2017-06-14 14:29:52 +0100 |
commit | 185484f94e6b5dbabad8d72c0ade8f2d6cd570ab (patch) | |
tree | 44eaa29f62e9cd6b74040258b55ea09e8bbb9487 | |
parent | 68ecea6c609544db3086a146c3ead2c91aa1cb76 (diff) |
Added symmetry checking - better indexing rate but something's holding back a number of crystals
-rw-r--r-- | libcrystfel/src/taketwo.c | 572 |
1 files changed, 374 insertions, 198 deletions
diff --git a/libcrystfel/src/taketwo.c b/libcrystfel/src/taketwo.c index 8751d6d1..791af586 100644 --- a/libcrystfel/src/taketwo.c +++ b/libcrystfel/src/taketwo.c @@ -71,6 +71,8 @@ struct SpotVec struct rvec obsvec; struct rvec *matches; int match_num; + struct rvec *asym_matches; + int asym_match_num; double distance; struct rvec *her_rlp; struct rvec *his_rlp; @@ -100,19 +102,19 @@ struct TakeTwoCell #define RECIP_TOLERANCE (0.001*1e10) /* Threshold for network members to consider a potential solution */ -#define NETWORK_MEMBER_THRESHOLD (20) +#define NETWORK_MEMBER_THRESHOLD (30) /* Maximum network members (obviously a solution so should stop) */ -#define MAX_NETWORK_MEMBERS (NETWORK_MEMBER_THRESHOLD + 5) +#define MAX_NETWORK_MEMBERS (NETWORK_MEMBER_THRESHOLD + 3) /* Maximum dead ends for a single branch extension during indexing */ -#define MAX_DEAD_ENDS (5) +#define MAX_DEAD_ENDS (10) /* Tolerance for two angles to be considered the same */ -#define ANGLE_TOLERANCE (deg2rad(3.0)) +#define ANGLE_TOLERANCE (deg2rad(0.7)) /* Tolerance for rot_mats_are_similar */ -#define TRACE_TOLERANCE (deg2rad(3.0)) +#define TRACE_TOLERANCE (deg2rad(5.0)) /** TODO: * @@ -316,10 +318,94 @@ static double matrix_trace(gsl_matrix *a) return tr; } -static int symm_rot_mats_are_similar(gsl_matrix *rot1, gsl_matrix *rot2, - struct TakeTwoCell *cell) +static char *add_ua(const char *inp, char ua) +{ + char *pg = malloc(64); + if ( pg == NULL ) return NULL; + snprintf(pg, 63, "%s_ua%c", inp, ua); + return pg; +} + + +static char *get_chiral_holohedry(UnitCell *cell) +{ + LatticeType lattice = cell_get_lattice_type(cell); + char *pg = malloc(64); + char *pgout = 0; + + if ( pg == NULL ) return NULL; + + switch (lattice) + { + case L_TRICLINIC: + pg = "1"; + break; + + case L_MONOCLINIC: + pg = "2"; + break; + + case L_ORTHORHOMBIC: + pg = "222"; + break; + + case L_TETRAGONAL: + pg = "422"; + break; + + case L_RHOMBOHEDRAL: + pg = "3_R"; + break; + + case L_HEXAGONAL: + if ( cell_get_centering(cell) == 'H' ) { + pg = "3_H"; + } else { + pg = "622"; + } + break; + + case L_CUBIC: + pg = "432"; + break; + + default: + pg = "error"; + break; + } + + switch (lattice) + { + case L_TRICLINIC: + case L_ORTHORHOMBIC: + case L_RHOMBOHEDRAL: + case L_CUBIC: + pgout = strdup(pg); + break; + + case L_MONOCLINIC: + case L_TETRAGONAL: + case L_HEXAGONAL: + pgout = add_ua(pg, cell_get_unique_axis(cell)); + break; + + default: + break; + } + + return pgout; +} + + +static SymOpList *sym_ops_for_cell(UnitCell *cell) { + SymOpList *rawList; + char *pg = get_chiral_holohedry(cell); + rawList = get_pointgroup(pg); + free(pg); + + return rawList; } static int rot_mats_are_similar(gsl_matrix *rot1, gsl_matrix *rot2, @@ -346,6 +432,27 @@ static int rot_mats_are_similar(gsl_matrix *rot1, gsl_matrix *rot2, return (tr < max); } +static int symm_rot_mats_are_similar(gsl_matrix *rot1, gsl_matrix *rot2, + struct TakeTwoCell *cell) +{ + int i; + + for (i = 0; i < cell->numOps; i++) { + gsl_matrix *testRot = gsl_matrix_alloc(3, 3); + gsl_matrix *symOp = cell->rotSymOps[i]; + + gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, rot1, symOp, + 0.0, testRot); + + if (rot_mats_are_similar(testRot, rot2, NULL)) { + return 1; + } + + gsl_matrix_free(testRot); + } + + return 0; +} static gsl_matrix *rotation_between_vectors(struct rvec a, struct rvec b) { @@ -469,6 +576,9 @@ static int obs_vecs_match_angles(struct SpotVec *her_obs, int i, j; *match_count = 0; + double min_angle = deg2rad(2.5); + double max_angle = deg2rad(187.5); + // *her_match_idx = -1; // *his_match_idx = -1; @@ -478,49 +588,57 @@ static int obs_vecs_match_angles(struct SpotVec *her_obs, /* calculate angle between all potential theoretical vectors */ for ( i=0; i<her_obs->match_num; i++ ) { - for ( j=0; j<his_obs->match_num; j++ ) { - - struct rvec *her_match = &her_obs->matches[i]; - struct rvec *his_match = &his_obs->matches[j]; - - double theory_angle = rvec_angle(*her_match, - *his_match); - - /* is this angle a match? */ + for ( j=0; j<his_obs->match_num; j++ ) { - double angle_diff = fabs(theory_angle - obs_angle); + struct rvec *her_match = &her_obs->matches[i]; + struct rvec *his_match = &his_obs->matches[j]; - if ( angle_diff < ANGLE_TOLERANCE ) { - size_t new_size = (*match_count + 1) * - sizeof(int); - if (her_match_idxs && his_match_idxs) - { - /* Reallocate the array to fit in another match */ - int *temp_hers; - temp_hers = realloc(*her_match_idxs, new_size); - int *temp_his; - temp_his = realloc(*his_match_idxs, new_size); + double theory_angle = rvec_angle(*her_match, + *his_match); - if ( temp_hers == NULL || temp_his == NULL ) { - apologise(); - } + /* is this angle a match? */ + + /* If the angles are too close to 0 + or 180, one axis ill-determined */ + if (theory_angle < min_angle || + theory_angle > max_angle) { + continue; + } - (*her_match_idxs) = temp_hers; - (*his_match_idxs) = temp_his; + double angle_diff = fabs(theory_angle - obs_angle); - (*her_match_idxs)[*match_count] = i; - (*his_match_idxs)[*match_count] = j; + if ( angle_diff < ANGLE_TOLERANCE ) { + + size_t new_size = (*match_count + 1) * + sizeof(int); + if (her_match_idxs && his_match_idxs) + { + /* Reallocate the array to fit in another match */ + int *temp_hers; + temp_hers = realloc(*her_match_idxs, new_size); + int *temp_his; + temp_his = realloc(*his_match_idxs, new_size); + + if ( temp_hers == NULL || temp_his == NULL ) { + apologise(); } - (*match_count)++; + (*her_match_idxs) = temp_hers; + (*his_match_idxs) = temp_his; + + (*her_match_idxs)[*match_count] = i; + (*his_match_idxs)[*match_count] = j; } + + (*match_count)++; } } + } return (*match_count > 0); } - +// DELETE ME IF UNUSED static int obs_angles_match_array(struct SpotVec *obs_vecs, int test_idx, int *obs_members, int *match_members, int num) { @@ -530,7 +648,7 @@ static int obs_angles_match_array(struct SpotVec *obs_vecs, int test_idx, * is identical - too much faff. **/ - int i, j; + int i = 0; struct SpotVec *her_obs = &obs_vecs[test_idx]; for ( i=0; i<num; i++ ) { @@ -555,7 +673,7 @@ static int obs_angles_match_array(struct SpotVec *obs_vecs, int test_idx, * core functions regarding the meat of the TakeTwo algorithm (Level 2) * ------------------------------------------------------------------------*/ -static signed int finalise_solution(gsl_matrix *rot, struct SpotVec *obs_vecs, +static signed int finish_solution(gsl_matrix *rot, struct SpotVec *obs_vecs, int *obs_members, int *match_members, int member_num) { @@ -652,7 +770,7 @@ static signed int find_next_index(gsl_matrix *rot, struct SpotVec *obs_vecs, * checking the next value of j */ int j, k; - for ( j=match_start; j<match_num; j++ ) { + for ( j=0; j<match_num; j++ ) { int all_ok = 1; for ( k=0; k<member_num; k++ ) { @@ -723,8 +841,8 @@ static int grow_network(gsl_matrix *rot, struct SpotVec *obs_vecs, * before it is reset in an additional branch */ int dead_ends = 0; - /* we can start from after the 2nd observed vector in the seed */ - int start = obs_idx2 + 1; + /* we start from 0 */ + int start = 0; while ( 1 ) { @@ -770,6 +888,7 @@ static int grow_network(gsl_matrix *rot, struct SpotVec *obs_vecs, start = next_index + 1; member_num++; + if (member_num > *max_members) { *max_members = member_num; } @@ -777,10 +896,23 @@ static int grow_network(gsl_matrix *rot, struct SpotVec *obs_vecs, /* If member_num is high enough, we want to return a yes */ if ( member_num > NETWORK_MEMBER_THRESHOLD ) break; } + + /* + int i; + for (i = 0; i < member_num; i++) + { + STATUS("."); + } - finalise_solution(rot, obs_vecs, obs_members, - match_members, member_num); + if ( member_num > NETWORK_MEMBER_THRESHOLD ) { + STATUS(" yes (%i)\n", member_num); + } else { + STATUS(" nope (%i)\n", member_num); + }*/ + finish_solution(rot, obs_vecs, obs_members, + match_members, member_num); + return ( member_num > NETWORK_MEMBER_THRESHOLD ); } @@ -808,18 +940,26 @@ static int start_seed(struct SpotVec *obs_vecs, int obs_vec_count, int i, } static int weed_duplicate_matches(struct SpotVec *her_obs, - struct SpotVec *his_obs, - int **her_match_idxs, int **his_match_idxs, - int *match_count, struct TakeTwoCell *cell) + struct SpotVec *his_obs, + int **her_match_idxs, int **his_match_idxs, + int *match_count, struct TakeTwoCell *cell) { int num_occupied = 0; gsl_matrix **old_mats = calloc(*match_count, sizeof(gsl_matrix *)); + if (old_mats == NULL) + { + apologise(); + return 0; + } + signed int i, j; - for (i = *match_count - 1; i >= 0; i++) { + int duplicates = 0; + + for (i = *match_count - 1; i >= 0; i--) { int her_match = (*her_match_idxs)[i]; int his_match = (*his_match_idxs)[i]; - + struct rvec i_obsvec = her_obs->obsvec; struct rvec j_obsvec = his_obs->obsvec; struct rvec i_cellvec = her_obs->matches[her_match]; @@ -828,6 +968,8 @@ static int weed_duplicate_matches(struct SpotVec *her_obs, gsl_matrix *mat = generate_rot_mat(i_obsvec, j_obsvec, i_cellvec, j_cellvec); + int found = 0; + for (j = 0; j < num_occupied; j++) { if (old_mats[j] && symm_rot_mats_are_similar(old_mats[j], mat, cell)) @@ -835,16 +977,21 @@ static int weed_duplicate_matches(struct SpotVec *her_obs, // we have found a duplicate, so flag as bad. (*her_match_idxs)[i] = -1; (*his_match_idxs)[i] = -1; + found = 1; + + duplicates++; gsl_matrix_free(mat); - } else { - // we have not found a duplicate, add to list. - old_mats[num_occupied] = mat; - num_occupied++; } } + + if (!found) { + // we have not found a duplicate, add to list. + old_mats[num_occupied] = mat; + num_occupied++; + } } - + for (i = 0; i < num_occupied; i++) { if (old_mats[i]) { gsl_matrix_free(old_mats[i]); @@ -852,6 +999,8 @@ static int weed_duplicate_matches(struct SpotVec *her_obs, } free(old_mats); + + return 1; } static int find_seed(struct SpotVec *obs_vecs, int obs_vec_count, @@ -861,7 +1010,7 @@ static int find_seed(struct SpotVec *obs_vecs, int obs_vec_count, int max_max_members = 0; gsl_matrix *best_rotation = NULL; - unsigned long start_time = time(NULL); +// unsigned long start_time = time(NULL); /* loop round pairs of vectors to try and find a suitable * seed to start building a self-consistent network of vectors @@ -885,7 +1034,10 @@ static int find_seed(struct SpotVec *obs_vecs, int obs_vec_count, int *i_idx = 0; int *j_idx = 0; int matches; - + + // double dist1Pc = 100 * obs_vecs[i].distance / MAX_RECIP_DISTANCE; +// double dist2Pc = 100 * obs_vecs[j].distance / MAX_RECIP_DISTANCE; + /* Check to see if any angles match from the cell vectors */ obs_vecs_match_angles(&obs_vecs[i], &obs_vecs[j], &i_idx, &j_idx, &matches); @@ -932,8 +1084,8 @@ static int find_seed(struct SpotVec *obs_vecs, int obs_vec_count, } } - unsigned long now_time = time(NULL); - unsigned int seconds = now_time - start_time; +// unsigned long now_time = time(NULL); +// unsigned int seconds = now_time - start_time; // Commented out for the time being. /* @@ -957,121 +1109,96 @@ static int find_seed(struct SpotVec *obs_vecs, int obs_vec_count, return (best_rotation != NULL); } - -static char *add_ua(const char *inp, char ua) -{ - char *pg = malloc(64); - if ( pg == NULL ) return NULL; - snprintf(pg, 63, "%s_ua%c", inp, ua); - return pg; -} - - -static char *get_chiral_holohedry(UnitCell *cell) +static void set_gsl_matrix(gsl_matrix *mat, double asx, double asy, double asz, + double bsx, double bsy, double bsz, + double csx, double csy, double csz) { - LatticeType lattice = cell_get_lattice_type(cell); - char *pg = malloc(64); - char *pgout; - - if ( pg == NULL ) return NULL; - - switch (lattice) - { - case L_TRICLINIC: - pg = "1"; - break; - - case L_MONOCLINIC: - pg = "2"; - break; - - case L_ORTHORHOMBIC: - pg = "222"; - break; - - case L_TETRAGONAL: - pg = "422"; - break; - - case L_RHOMBOHEDRAL: - pg = "3_R"; - break; - - case L_HEXAGONAL: - if ( cell_get_centering(cell) == 'H' ) { - pg = "3_H"; - } else { - pg = "622"; - } - break; - - case L_CUBIC: - pg = "432"; - break; - - default: - pg = "error"; - break; - } - - switch (lattice) - { - case L_TRICLINIC: - case L_ORTHORHOMBIC: - case L_RHOMBOHEDRAL: - case L_CUBIC: - pgout = strdup(pg); - break; - - case L_MONOCLINIC: - case L_TETRAGONAL: - case L_HEXAGONAL: - pgout = add_ua(pg, cell_get_unique_axis(cell)); - break; - - default: - break; - } - - return pgout; + gsl_matrix_set(mat, 0, 0, asx); + gsl_matrix_set(mat, 0, 1, asy); + gsl_matrix_set(mat, 0, 2, asz); + gsl_matrix_set(mat, 1, 0, bsx); + gsl_matrix_set(mat, 1, 1, bsy); + gsl_matrix_set(mat, 1, 2, bsz); + gsl_matrix_set(mat, 2, 0, csx); + gsl_matrix_set(mat, 2, 1, csy); + gsl_matrix_set(mat, 2, 2, csz); } - static int generate_rotation_sym_ops(struct TakeTwoCell *ttCell) { - SymOpList *rawList; - - char *pg = get_chiral_holohedry(ttCell->cell); - rawList = get_pointgroup(pg); - free(pg); + SymOpList *rawList = sym_ops_for_cell(ttCell->cell); /* Now we must convert these into rotation matrices rather than hkl * transformations (affects triclinic, monoclinic, rhombohedral and * hexagonal space groups only) */ + + double asx, asy, asz; + double bsx, bsy, bsz; + double csx, csy, csz; + gsl_matrix *recip = gsl_matrix_alloc(3, 3); + gsl_matrix *cart = gsl_matrix_alloc(3, 3); cell_get_reciprocal(ttCell->cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); - inv = gsl_matrix_alloc(3, 3); - gsl_matrix_set(inv, 0, 0, asx); - gsl_matrix_set(inv, 0, 1, asy); - gsl_matrix_set(inv, 0, 2, asz); - gsl_matrix_set(inv, 1, 0, bsx); - gsl_matrix_set(inv, 1, 1, bsy); - gsl_matrix_set(inv, 1, 2, bsz); - gsl_matrix_set(inv, 2, 0, csx); - gsl_matrix_set(inv, 2, 1, csy); - gsl_matrix_set(inv, 2, 2, csz); + set_gsl_matrix(recip, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); - // FIXME: Finish me! Along the lines of: - /* - MatrixPtr newMat = matFromCCP4(&spaceGroup->symop[j]); - MatrixPtr ortho = newMat; - ortho->preMultiply(*unitCell); - ortho->multiply(*reverse); - */ + cell_get_cartesian(ttCell->cell, &asx, &asy, &asz, &bsx, &bsy, + &bsz, &csx, &csy, &csz); + + set_gsl_matrix(cart, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); + + int i, j, k; + int numOps = num_equivs(rawList, NULL); + + ttCell->rotSymOps = malloc(numOps * sizeof(gsl_matrix *)); + ttCell->numOps = numOps; + + if (ttCell->rotSymOps == NULL) { + apologise(); + return 0; + } + + for (i = 0; i < numOps; i++) + { + gsl_matrix *symOp = gsl_matrix_alloc(3, 3); + IntegerMatrix *op = get_symop(rawList, NULL, i); + + for (j = 0; j < 3; j++) { + for (k = 0; k < 3; k++) { + gsl_matrix_set(symOp, j, k, intmat_get(op, j, k)); + } + } + + gsl_matrix *first = gsl_matrix_calloc(3, 3); + gsl_matrix *second = gsl_matrix_calloc(3, 3); + + /* Each equivalence is of the form: + cartesian * symOp * reciprocal. + First multiplication: symOp * reciprocal */ + + gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, + 1.0, symOp, recip, + 0.0, first); + + /* Second multiplication: cartesian * first */ + + gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, + 1.0, cart, first, + 0.0, second); + + ttCell->rotSymOps[i] = second; + + gsl_matrix_free(symOp); + gsl_matrix_free(first); + } - gsl_matrix_free(inv); + // FIXME: Finish me! Along the lines of: + + gsl_matrix_free(cart); + gsl_matrix_free(recip); + + return 1; } @@ -1090,7 +1217,8 @@ static int sort_func(const void *av, const void *bv) static int match_obs_to_cell_vecs(struct rvec *cell_vecs, int cell_vec_count, - struct SpotVec *obs_vecs, int obs_vec_count) + struct SpotVec *obs_vecs, int obs_vec_count, + int is_asymmetric) { int i, j; @@ -1098,9 +1226,8 @@ static int match_obs_to_cell_vecs(struct rvec *cell_vecs, int cell_vec_count, int count = 0; struct sortme *for_sort = NULL; - + for ( j=0; j<cell_vec_count; j++ ) { - /* get distance for unit cell vector */ double cell_length = rvec_length(cell_vecs[j]); double obs_length = obs_vecs[i].distance; @@ -1123,15 +1250,28 @@ static int match_obs_to_cell_vecs(struct rvec *cell_vecs, int cell_vec_count, } + /* Pointers to relevant things */ + + struct rvec **match_array; + int *match_count; + + if (!is_asymmetric) { + match_array = &(obs_vecs[i].matches); + match_count = &(obs_vecs[i].match_num); + } else { + match_array = &(obs_vecs[i].asym_matches); + match_count = &(obs_vecs[i].asym_match_num); + } + /* Sort in order to get most agreeable matches first */ qsort(for_sort, count, sizeof(struct sortme), sort_func); - obs_vecs[i].matches = malloc(count*sizeof(struct rvec)); - obs_vecs[i].match_num = count; + *match_array = malloc(count*sizeof(struct rvec)); + *match_count = count; for ( j=0; j<count; j++ ) { - obs_vecs[i].matches[j] = for_sort[j].v; + (*match_array)[j] = for_sort[j].v; + } free(for_sort); - } return 1; @@ -1203,7 +1343,8 @@ static int gen_observed_vecs(struct rvec *rlps, int rlp_count, static int gen_theoretical_vecs(UnitCell *cell, struct rvec **cell_vecs, - int *vec_count) + struct rvec **asym_vecs, int *vec_count, + int *asym_vec_count) { double a, b, c, alpha, beta, gamma; int h_max, k_max, l_max; @@ -1211,6 +1352,12 @@ static int gen_theoretical_vecs(UnitCell *cell, struct rvec **cell_vecs, double bsx, bsy, bsz; double csx, csy, csz; + cell_get_reciprocal(cell, &asx, &asy, &asz, + &bsx, &bsy, &bsz, + &csx, &csy, &csz); + + SymOpList *rawList = sym_ops_for_cell(cell); + cell_get_parameters(cell, &a, &b, &c, &alpha, &beta, &gamma); /* find maximum Miller (h, k, l) indices for a given resolution */ @@ -1219,42 +1366,64 @@ static int gen_theoretical_vecs(UnitCell *cell, struct rvec **cell_vecs, l_max = MAX_RECIP_DISTANCE * c; int h, k, l; + int _h, _k, _l; int count = 0; - - cell_get_reciprocal(cell, &asx, &asy, &asz, - &bsx, &bsy, &bsz, - &csx, &csy, &csz); + int asym_count = 0; for ( h=-h_max; h<=+h_max; h++ ) { - for ( k=-k_max; k<=+k_max; k++ ) { - for ( l=-l_max; l<=+l_max; l++ ) { + for ( k=-k_max; k<=+k_max; k++ ) { + for ( l=-l_max; l<=+l_max; l++ ) { - struct rvec cell_vec; + struct rvec cell_vec; - /* Exclude systematic absences from centering concerns */ - if ( forbidden_reflection(cell, h, k, l) ) continue; + /* Exclude systematic absences from centering concerns */ + if ( forbidden_reflection(cell, h, k, l) ) continue; - cell_vec.u = h*asx + k*bsx + l*csx; - cell_vec.v = h*asy + k*bsy + l*csy; - cell_vec.w = h*asz + k*bsz + l*csz; + int asymmetric = 0; + get_asymm(rawList, h, k, l, &_h, &_k, &_l); + + if (h == _h && k == _k && l == _l) { + asymmetric = 1; + asym_count++; + } + + cell_vec.u = h*asx + k*bsx + l*csx; + cell_vec.v = h*asy + k*bsy + l*csy; + cell_vec.w = h*asz + k*bsz + l*csz; - /* add this to our array - which may require expanding */ - count++; + /* add this to our array - which may require expanding */ + count++; - struct rvec *temp_cell_vecs; - temp_cell_vecs = realloc(*cell_vecs, count*sizeof(struct rvec)); + struct rvec *temp_cell_vecs; + temp_cell_vecs = realloc(*cell_vecs, count*sizeof(struct rvec)); + struct rvec *temp_asym_vecs = NULL; - if ( temp_cell_vecs == NULL ) { - return 0; - } else { - *cell_vecs = temp_cell_vecs; - (*cell_vecs)[count - 1] = cell_vec; - } + if (asymmetric) { + temp_asym_vecs = realloc(*asym_vecs, + count*sizeof(struct rvec)); + } + + if ( temp_cell_vecs == NULL ) { + return 0; + } else if (asymmetric && temp_asym_vecs == NULL) { + return 0; + } else { + *cell_vecs = temp_cell_vecs; + (*cell_vecs)[count - 1] = cell_vec; + + if (!asymmetric) { + continue; } + + *asym_vecs = temp_asym_vecs; + (*asym_vecs)[asym_count - 1] = cell_vec; } } + } + } *vec_count = count; + *asym_vec_count = asym_count; return 1; } @@ -1297,41 +1466,48 @@ static void cleanup_taketwo_obs_vecs(struct SpotVec *obs_vecs, static UnitCell *run_taketwo(UnitCell *cell, struct rvec *rlps, int rlp_count) { int cell_vec_count = 0; + int asym_vec_count = 0; struct rvec *cell_vecs = NULL; + struct rvec *asym_vecs = NULL; UnitCell *result; int obs_vec_count = 0; struct SpotVec *obs_vecs = NULL; int success = 0; gsl_matrix *solution = NULL; + + struct TakeTwoCell ttCell; + ttCell.cell = cell; + ttCell.rotSymOps = NULL; + ttCell.numOps = 0; + + success = generate_rotation_sym_ops(&ttCell); - success = gen_theoretical_vecs(cell, &cell_vecs, &cell_vec_count); + success = gen_theoretical_vecs(cell, &cell_vecs, &asym_vecs, + &cell_vec_count, &asym_vec_count); if ( !success ) return NULL; success = gen_observed_vecs(rlps, rlp_count, &obs_vecs, &obs_vec_count); if ( !success ) return NULL; + success = match_obs_to_cell_vecs(asym_vecs, asym_vec_count, + obs_vecs, obs_vec_count, 1); + success = match_obs_to_cell_vecs(cell_vecs, cell_vec_count, - obs_vecs, obs_vec_count); + obs_vecs, obs_vec_count, 0); cleanup_taketwo_cell_vecs(cell_vecs); if ( !success ) return NULL; - struct TakeTwoCell ttCell; - ttCell.cell = cell; - ttCell.rotSymOps = NULL; - ttCell.numOps = 0; - - int success = generate_rotation_sym_ops(&ttCell); - - int threshold_reached = find_seed(obs_vecs, obs_vec_count, - &solution, cell); + find_seed(obs_vecs, obs_vec_count, &solution, &ttCell); if ( solution == NULL ) { cleanup_taketwo_obs_vecs(obs_vecs, obs_vec_count); return NULL; } +// STATUS("Returning result.\n"); + result = transform_cell_gsl(cell, solution); gsl_matrix_free(solution); cleanup_taketwo_obs_vecs(obs_vecs, obs_vec_count); |