aboutsummaryrefslogtreecommitdiff
path: root/src/gui_export.c
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-02-11 17:15:59 +0100
committerThomas White <taw@physics.org>2021-02-11 17:15:59 +0100
commit1480f1bde9b40e7579334c9f94e3b995971dac7d (patch)
tree4a59c1a7729eb1d28d76a5b478ccc67d33950744 /src/gui_export.c
parentdbb004d260cd2e2f1ae6b2e6575596a95c577978 (diff)
GUI: Implement export to XDS_ASCII
Diffstat (limited to 'src/gui_export.c')
-rw-r--r--src/gui_export.c139
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;
}