/* * symmetry.c * * Symmetry * * (c) 2006-2010 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "utils.h" #ifdef DEBUG #define SYM_DEBUG STATUS #else /* DEBUG */ #define SYM_DEBUG(...) #endif /* DEBUG */ /* Check if a reflection is in the asymmetric unit cell */ static int check_cond(signed int h, signed int k, signed int l, const char *sym) { if ( strcmp(sym, "1") == 0 ) return ( 1 ); if ( strcmp(sym, "6") == 0 ) return ( (h>=0) && (k>=0) ); if ( strcmp(sym, "6/m") == 0 ) return ( (h>=0) && (k>=0) && (l>=0) ); if ( strcmp(sym, "6/mmm") == 0 ) return ( (h>=0) && (k>=0) && (l>=0) && (h>=k) ); /* TODO: Add more groups here */ return 1; } /* Macros for checking the above conditions and returning if satisfied */ #define CHECK_COND(h, k, l, sym) \ if ( check_cond((h), (k), (l), (sym)) ) { \ *hp = (h); *kp = (k); *lp = (l); \ return; \ } /* FIXME: Should take into account special indices * e.g. l==0 has fewer equivalent reflections */ int num_equivs(signed int h, signed int k, signed int l, const char *sym) { if ( strcmp(sym, "1") == 0 ) return 1; if ( strcmp(sym, "6") == 0 ) return 6; if ( strcmp(sym, "6/m") == 0 ) return 12; if ( strcmp(sym, "6/mmm") == 0 ) return 24; /* TODO: Add more groups here */ return 1; } void get_equiv(signed int h, signed int k, signed int l, signed int *he, signed int *ke, signed int *le, const char *sym, int idx) { if ( strcmp(sym, "1") == 0 ) { *he = h; *ke = k; *le = l; return; } if ( strcmp(sym, "6") == 0 ) { signed int i = -h-k; switch ( idx ) { case 0 : *he = h; *ke = k; *le = l; return; case 1 : *he = i; *ke = h; *le = l; return; case 2 : *he = k; *ke = i; *le = l; return; case 3 : *he = -h; *ke = -k; *le = l; return; case 4 : *he = -i; *ke = -h; *le = l; return; case 5 : *he = -k; *ke = -i; *le = l; return; } } if ( strcmp(sym, "6/m") == 0 ) { signed int i = -h-k; switch ( idx ) { case 0 : *he = h; *ke = k; *le = l; return; case 1 : *he = i; *ke = h; *le = l; return; case 2 : *he = k; *ke = i; *le = l; return; case 3 : *he = -h; *ke = -k; *le = l; return; case 4 : *he = -i; *ke = -h; *le = l; return; case 5 : *he = -k; *ke = -i; *le = l; return; case 6 : *he = h; *ke = k; *le = -l; return; case 7 : *he = i; *ke = h; *le = -l; return; case 8 : *he = k; *ke = i; *le = -l; return; case 9 : *he = -h; *ke = -k; *le = -l; return; case 10 : *he = -i; *ke = -h; *le = -l; return; case 11 : *he = -k; *ke = -i; *le = -l; return; } } if ( strcmp(sym, "6/mmm") == 0 ) { signed int i = -h-k; switch ( idx ) { case 0 : *he = h; *ke = k; *le = l; return; case 1 : *he = i; *ke = h; *le = l; return; case 2 : *he = k; *ke = i; *le = l; return; case 3 : *he = -h; *ke = -k; *le = l; return; case 4 : *he = -i; *ke = -h; *le = l; return; case 5 : *he = -k; *ke = -i; *le = l; return; case 6 : *he = k; *ke = h; *le = -l; return; case 7 : *he = h; *ke = i; *le = -l; return; case 8 : *he = i; *ke = k; *le = -l; return; case 9 : *he = -k; *ke = -h; *le = -l; return; case 10 : *he = -h; *ke = -i; *le = -l; return; case 11 : *he = -i; *ke = -k; *le = -l; return; case 12 : *he = -h; *ke = -k; *le = -l; return; case 13 : *he = -i; *ke = -h; *le = -l; return; case 14 : *he = -k; *ke = -i; *le = -l; return; case 15 : *he = h; *ke = k; *le = -l; return; case 16 : *he = i; *ke = h; *le = -l; return; case 17 : *he = k; *ke = i; *le = -l; return; case 18 : *he = -k; *ke = -h; *le = l; return; case 19 : *he = -h; *ke = -i; *le = l; return; case 20 : *he = -i; *ke = -k; *le = l; return; case 21 : *he = k; *ke = h; *le = l; return; case 22 : *he = h; *ke = i; *le = l; return; case 23 : *he = i; *ke = k; *le = l; return; } } /* TODO: Add more groups here */ /* Fallback for unrecognised groups */ *he = h; *ke = k; *le = l; } void get_asymm(signed int h, signed int k, signed int l, signed int *hp, signed int *kp, signed int *lp, const char *sym) { int nequiv = num_equivs(h, k, l, sym); int p; SYM_DEBUG("------ %i %i %i\n", h, k, l); for ( p=0; p