diff options
author | Thomas White <taw@physics.org> | 2009-11-30 16:59:02 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2009-11-30 17:01:19 +0100 |
commit | 858ea94ad2363a92b9dfc801760a17950711a298 (patch) | |
tree | 5fe51e6e6bcd1e442513917a021ba028949ee210 /src/process_hkl.c | |
parent | 7bf83a230a186c71bcb0640394ed17bfb1441895 (diff) |
Add process_hkl program (replaces integr_sim)
Diffstat (limited to 'src/process_hkl.c')
-rw-r--r-- | src/process_hkl.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/src/process_hkl.c b/src/process_hkl.c new file mode 100644 index 00000000..097a3eb3 --- /dev/null +++ b/src/process_hkl.c @@ -0,0 +1,268 @@ +/* + * process_hkl.c + * + * Assemble and process FEL Bragg intensities + * + * (c) 2006-2009 Thomas White <thomas.white@desy.de> + * + * Part of CrystFEL - crystallography with a FEL + * + */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <getopt.h> + +#include "utils.h" +#include "statistics.h" +#include "sfac.h" + + +static void show_help(const char *s) +{ + printf("Syntax: %s [options]\n\n", s); + printf("Assemble and process FEL Bragg intensities.\n\n"); + printf(" -h Display this help message.\n"); + printf(" -i <filename> Specify input filename (\"-\" for stdin).\n"); +} + + +static void write_RvsQ(const char *name, double *ref, double *trueref, + unsigned int *counts, double scale, UnitCell *cell) +{ + FILE *fh; + double smax, sbracket; + signed int h, k, l; + + fh = fopen(name, "w"); + + smax = 0.0; + for ( h=-INDMAX; h<INDMAX; h++ ) { + for ( k=-INDMAX; k<INDMAX; k++ ) { + for ( l=-INDMAX; l<INDMAX; l++ ) { + double s = resolution(cell, h, k, l); + if ( (lookup_count(counts, h, k, l) > 0) && (s > smax) ) { + smax = s; + } + } + } + } + + for ( sbracket=0.0; sbracket<smax; sbracket+=smax/10.0 ) { + + double top = 0.0; + double bot = 0.0; + int n = 0; + + for ( h=-INDMAX; h<INDMAX; h++ ) { + for ( k=-INDMAX; k<INDMAX; k++ ) { + for ( l=-INDMAX; l<INDMAX; l++ ) { + + double s; + int c; + c = lookup_count(counts, h, k, l); + s = resolution(cell, h, k, l); + if ((s>=sbracket) && (s<sbracket+smax/10.0) && (c>0)) { + + double obs, calc, obsi; + + obs = lookup_intensity(ref, h, k, l); + calc = lookup_intensity(trueref, h, k, l); + + obsi = obs / (double)c; + top += fabs(obsi/scale - calc); + bot += obsi/scale; + n++; + } + + } + } + } + + fprintf(fh, "%8.5f %8.5f %i\n", sbracket+smax/20.0, top/bot, n); + + } + fclose(fh); +} + + +static void write_reflections(const char *filename, unsigned int *counts, + double *ref) +{ + FILE *fh; + signed int h, k, l; + + fh = fopen(filename, "w"); + for ( h=-INDMAX; h<INDMAX; h++ ) { + for ( k=-INDMAX; k<INDMAX; k++ ) { + for ( l=-INDMAX; l<INDMAX; l++ ) { + int N; + N = lookup_count(counts, h, k, l); + if ( N == 0 ) continue; + double F = lookup_intensity(ref, h, k, l) / N; + fprintf(fh, "%3i %3i %3i %f\n", h, k, l, F); + } + } + } + fclose(fh); +} + + +static double *ideal_intensities(double complex *sfac) +{ + double *ref; + signed int h, k, l; + + ref = new_list_intensity(); + + /* Generate ideal reflections from complex structure factors */ + for ( h=-INDMAX; h<=INDMAX; h++ ) { + for ( k=-INDMAX; k<=INDMAX; k++ ) { + for ( l=-INDMAX; l<=INDMAX; l++ ) { + double complex F = lookup_sfac(sfac, h, k, l); + double intensity = pow(cabs(F), 2.0); + set_intensity(ref, h, k, l, intensity); + } + } + } + + return ref; +} + + +static void process_reflections(double *ref, double *trueref, + unsigned int *counts, unsigned int n_patterns, + UnitCell *cell) +{ + int j; + double mean_counts; + int ctot = 0; + int nmeas = 0; + double ff; + char name[64]; + double R, scale; + + for ( j=0; j<LIST_SIZE; j++ ) { + ctot += counts[j]; + if ( counts[j] > 0 ) nmeas++; + } + mean_counts = (double)ctot/nmeas; + + ff = lookup_intensity(ref, 2, 2, 2) / lookup_count(counts, 2, 2, 2); + + R = stat_r2(ref, trueref, counts, LIST_SIZE, &scale); + STATUS("%8u: R=%5.2f%% (sf=%7.4e)" + " mean meas/refl=%5.2f," + " %i reflections measured. %f\n", + n_patterns, R*100.0, scale, mean_counts, nmeas, ff); + + /* Record graph of R against q for this N */ + snprintf(name, 63, "results/R_vs_q-%u.dat", n_patterns); + write_RvsQ(name, ref, trueref, counts, scale, cell); +} + + +int main(int argc, char *argv[]) +{ + int c; + char *filename = NULL; + FILE *fh; + unsigned int n_patterns; + double *ref, *trueref; + unsigned int *counts; + char *rval; + struct molecule *mol; + + /* Long options */ + const struct option longopts[] = { + {"help", 0, NULL, 'h'}, + {"input", 1, NULL, 'i'}, + {0, 0, NULL, 0} + }; + + /* Short options */ + while ((c = getopt_long(argc, argv, "hi:", longopts, NULL)) != -1) { + + switch (c) { + case 'h' : { + show_help(argv[0]); + return 0; + } + + case 'i' : { + filename = strdup(optarg); + break; + } + + case 0 : { + break; + } + + default : { + return 1; + } + } + + } + + if ( filename == NULL ) { + ERROR("Please specify filename using the -i option\n"); + return 1; + } + + mol = load_molecule(); + get_reflections_cached(mol, eV_to_J(2.0e3)); + + ref = new_list_intensity(); + counts = new_list_count(); + trueref = ideal_intensities(mol->reflections); + + if ( strcmp(filename, "-") == 0 ) { + fh = stdin; + } else { + fh = fopen(filename, "r"); + } + free(filename); + if ( fh == NULL ) { + ERROR("Failed to open input file\n"); + return 1; + } + + n_patterns = 0; + do { + + char line[1024]; + int h, k, l, intensity; + int r; + + rval = fgets(line, 1023, fh); + if ( strncmp(line, "New pattern", 11) == 0 ) { + n_patterns++; + if ( n_patterns % 1000 == 0 ) { + process_reflections(ref, trueref, counts, + n_patterns, mol->cell); + } + } + + r = sscanf(line, "%i %i %i %i", &h, &k, &l, &intensity); + if ( r != 4 ) continue; + + integrate_intensity(ref, h, k, l, intensity); + integrate_count(counts, h, k, l, 1); + + } while ( rval != NULL ); + + fclose(fh); + + write_reflections("results/reflections.hkl", counts, ref); + + return 0; +} |