/* * check_hkl.c * * Characterise reflection lists * * Copyright © 2012-2013 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: * 2010-2013 Thomas White * * This file is part of CrystFEL. * * CrystFEL is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CrystFEL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CrystFEL. If not, see . * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include "utils.h" #include "statistics.h" #include "symmetry.h" #include "reflist.h" #include "reflist-utils.h" #include "cell-utils.h" static void show_help(const char *s) { printf("Syntax: %s [options] \n\n", s); printf( "Characterise an intensity list.\n" "\n" " -h, --help Display this help message.\n" " -y, --symmetry= The symmetry of the input file.\n" " -p, --pdb= PDB file to use.\n" " --rmin= Fix lower resolution limit for resolution shells. (m^-1).\n" " --rmax= Fix upper resolution limit for resolution shells. (m^-1).\n" " --sigma-cutoff= Discard reflections with I/sigma(I) < n.\n" " --nshells= Use resolution shells.\n" "\n"); } static void plot_shells(RefList *list, UnitCell *cell, const SymOpList *sym, double rmin_fix, double rmax_fix, int nshells) { int *possible; unsigned int *measurements; unsigned int *measured; unsigned int *snr_measured; double total_vol, vol_per_shell; double *rmins; double *rmaxs; double *snr; double *mean; double *var; double rmin, rmax; signed int h, k, l; int i; FILE *fh; double snr_total = 0; int nrefl = 0; int nmeastot = 0; int nout = 0; int nsilly = 0; Reflection *refl; RefListIterator *iter; RefList *counted; int hmax, kmax, lmax; double ax, ay, az; double bx, by, bz; double cx, cy, cz; possible = malloc(nshells*sizeof(int)); measurements = malloc(nshells*sizeof(unsigned int)); measured = malloc(nshells*sizeof(unsigned int)); snr_measured = malloc(nshells*sizeof(unsigned int)); if ( (possible == NULL) || (measurements == NULL) || (measured == NULL) || (snr_measured == NULL) ) { ERROR("Couldn't allocate memory.\n"); free(possible); free(measurements); free(measured); free(snr_measured); return; } rmins = malloc(nshells*sizeof(double)); rmaxs = malloc(nshells*sizeof(double)); snr = malloc(nshells*sizeof(double)); mean = malloc(nshells*sizeof(double)); var = malloc(nshells*sizeof(double)); if ( (rmins == NULL) || (rmaxs == NULL) || (snr == NULL) || (mean == NULL) || (var == NULL) ) { ERROR("Couldn't allocate memory.\n"); free(possible); free(measurements); free(measured); free(snr_measured); free(rmins); free(rmaxs); free(snr); free(mean); free(var); return; } fh = fopen("shells.dat", "w"); if ( fh == NULL ) { ERROR("Couldn't open 'shells.dat'\n"); return; } for ( i=0; i 0.0 ) rmin = rmin_fix; if ( rmax_fix > 0.0 ) rmax = rmax_fix; total_vol = pow(rmax, 3.0) - pow(rmin, 3.0); vol_per_shell = total_vol / nshells; rmins[0] = rmin; for ( i=1; irmins[i]) && (d<=rmaxs[i]) ) { bin = i; break; } } if ( bin == -1 ) continue; get_asymm(sym, h, k, l, &hs, &ks, &ls); if ( find_refl(counted, hs, ks, ls) != NULL ) continue; add_refl(counted, hs, ks, ls); possible[bin]++; } } } reflist_free(counted); /* Calculate means */ for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { signed int h, k, l; double d, val, esd; int bin; int j; get_indices(refl, &h, &k, &l); if ( forbidden_reflection(cell, h, k, l) ) continue; if ( h % 2 ) continue; if ( k % 2 ) continue; if ( l % 2 ) continue; d = resolution(cell, h, k, l) * 2.0; val = get_intensity(refl); esd = get_esd_intensity(refl); bin = -1; for ( j=0; jrmins[j]) && (d<=rmaxs[j]) ) { bin = j; break; } } if ( bin == -1 ) continue; measured[bin]++; mean[bin] += get_intensity(refl); if ( !isfinite(val/esd) ) nsilly++; } for ( i=0; irmins[j]) && (d<=rmaxs[j]) ) { bin = j; break; } } if ( bin == -1 ) { nout++; continue; } /* measured[bin] was done earlier */ measurements[bin] += get_redundancy(refl); if ( isfinite(val/esd) ) { snr[bin] += val / esd; snr_total += val / esd; snr_measured[bin]++; } else { nsilly++; } nrefl++; nmeastot += get_redundancy(refl); var[bin] += pow(val-mean[bin], 2.0); } STATUS("overall = %f\n", snr_total/(double)nrefl); STATUS("%i measurements in total.\n", nmeastot); STATUS("%i reflections in total.\n", nrefl); if ( nout ) { STATUS("Warning; %i reflections outside resolution range.\n", nout); } if ( nsilly ) { STATUS("Warning; %i reflections had infinite or invalid values" " of I/sigma(I).\n", nsilly); } fprintf(fh, "1/d centre # refs Possible Compl " "Meas Red SNR Std dev Mean d(A)\n"); for ( i=0; i