diff options
author | Thomas White <taw@physics.org> | 2021-02-11 17:15:59 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2021-02-11 17:15:59 +0100 |
commit | 1480f1bde9b40e7579334c9f94e3b995971dac7d (patch) | |
tree | 4a59c1a7729eb1d28d76a5b478ccc67d33950744 /src/gui_export.c | |
parent | dbb004d260cd2e2f1ae6b2e6575596a95c577978 (diff) |
GUI: Implement export to XDS_ASCII
Diffstat (limited to 'src/gui_export.c')
-rw-r--r-- | src/gui_export.c | 139 |
1 files changed, 138 insertions, 1 deletions
diff --git a/src/gui_export.c b/src/gui_export.c index 6a41b548..08b6219d 100644 --- a/src/gui_export.c +++ b/src/gui_export.c @@ -39,6 +39,7 @@ #include <utils.h> #include <reflist-utils.h> #include <cell-utils.h> +#include <symmetry.h> #include "gui_project.h" #include "crystfel_gui.h" @@ -73,11 +74,147 @@ static int export_to_mtz_bij(struct gui_merge_result *result, } +struct point_group_conversion +{ + char centering; + const char *crystfel; + int friedel; + + int xds_spgnum; + char *xds_reindex; + + const char *ccp4; +}; + + +struct point_group_conversion pg_conversions[] = { + + /* Triclinic */ + {'P', "1", 0, 1, "h,k,l", "P 1"}, + + /* Monoclinic */ + {'P', "2_uaa", 0, 3, "k,-h,l", "P211"}, + {'P', "2/m_uaa", 1, 3, "k,-h,l", "P211"}, + {'P', "2_uab", 0, 3, "h,k,l", "P121"}, + {'P', "2/m_uab", 1, 3, "h,k,l", "P121"}, + {'P', "2_uac", 0, 3, "h,l,-k", "P112"}, + {'P', "2/m_uac", 1, 3, "h,l,-k", "P112"}, + {'P', "2", 0, 3, "h,l,-k", "P121"}, /* unique axis c */ + {'P', "2/m", 1, 3, "h,l,-k", "P121"}, /* unique axis c */ + + {'C', "2_uaa", 0, 5, "k,-h,l", "C211"}, + {'C', "2/m_uaa", 1, 5, "k,-h,l", "C211"}, + {'C', "2_uab", 0, 5, "h,k,l", "C121"}, + {'C', "2/m_uab", 1, 5, "h,k,l", "C121"}, + {'C', "2_uac", 0, 5, "h,l,-k", "C112"}, + {'C', "2/m_uac", 1, 5, "h,l,-k", "C112"}, + {'C', "2", 0, 5, "h,l,-k", "C121"}, /* unique axis c */ + {'C', "2/m", 1, 5, "h,l,-k", "C121"}, /* unique axis c */ + + /* Orthorhombic */ + {'P', "222", 0, 16, "h,k,l", "P222"}, + {'P', "mmm", 1, 16, "h,k,l", "P222"}, + {'C', "222", 0, 21, "h,k,l", "C222"}, + {'C', "mmm", 1, 21, "h,k,l", "C222"}, + + /* FIXME: Complete this list. Ugh. */ + + {'*', NULL, 0, 0, NULL, NULL} +}; + + +static int space_group_for_xds(const char *sym_str, char cen, + const char **reindex) +{ + int i = 0; + do { + if ( (pg_conversions[i].centering == cen) + && (strcmp(sym_str, pg_conversions[i].crystfel) == 0) ) + { + *reindex = pg_conversions[i].xds_reindex; + return pg_conversions[i].xds_spgnum; + } + i++; + } while (pg_conversions[i].centering != '*'); + + ERROR("Couldn't derive XDS representation of symmetry.\n"); + *reindex = "h,k,l"; + return 1; +} + + static int export_to_xds(struct gui_merge_result *result, const char *filename, UnitCell *cell, double min_res, double max_res) { - return 1; + FILE *fh; + RefList *reflist; + RefListIterator *iter; + Reflection *refl; + double a, b, c, al, be,ga; + char *sym_str; + SymOpList *sym; + const char *reindex_str; + SymOpList *reindex; + + fh = fopen(filename, "w"); + if ( fh == NULL ) return 1; + + reflist = read_reflections_2(result->hkl, &sym_str); + if ( reflist == NULL ) return 1; + if ( sym_str == NULL ) return 1; + + sym = get_pointgroup(sym_str); + if ( sym == NULL ) return 1; + + cell_get_parameters(cell, &a, &b, &c, &al, &be, &ga); + + fprintf(fh, "!FORMAT=XDS_ASCII MERGE=TRUE FRIEDEL'S_LAW=%s\n", + is_centrosymmetric(sym) ? "TRUE" : "FALSE"); + fprintf(fh, "!SPACE_GROUP_NUMBER=%i\n", + space_group_for_xds(sym_str, cell_get_centering(cell), + &reindex_str)); + fprintf(fh, "!UNIT_CELL_CONSTANT= %.2f %.2f %.2f %.2f %.2f %.2f\n", + a*1e10, b*1e10, c*1e10, rad2deg(al), rad2deg(be), rad2deg(ga)); + fprintf(fh, "!NUMBER_OF_ITEMS_IN_EACH_DATA_RECORD=5\n"); + fprintf(fh, "!ITEM_H=1\n"); + fprintf(fh, "!ITEM_K=2\n"); + fprintf(fh, "!ITEM_L=3\n"); + fprintf(fh, "!ITEM_IOBS=4\n"); + fprintf(fh, "!ITEM_SIGMA(IOBS)=5\n"); + fprintf(fh, "!END_OF_HEADER\n"); + + reindex = parse_symmetry_operations(reindex_str); + if ( reindex == NULL ) return 1; + + for ( refl = first_refl(reflist, &iter); + refl != NULL; + refl = next_refl(refl, iter) ) + { + signed int h, k, l; + double one_over_d; + + get_indices(refl, &h, &k, &l); + get_equiv(reindex, NULL, 0, h, k, l, &h, &k, &l); + + one_over_d = 2.0*resolution(cell, h, k, l); + if ( (one_over_d > min_res) && (one_over_d < max_res) ) { + + fprintf(fh, "%6i %6i %6i %9.2f %9.2f\n", + h, k, l, + get_intensity(refl), + get_esd_intensity(refl)); + + } + } + + fprintf(fh, "!END_OF_DATA\n"); + free_symoplist(sym); + free(sym_str); + reflist_free(reflist); + + fclose(fh); + return 0; } |