/* * compare_hkl.c * * Compare reflection lists * * Copyright © 2012 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: * 2010-2012 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 #include #include "utils.h" #include "statistics.h" #include "symmetry.h" #include "reflist-utils.h" /* Number of bins for plot of resolution shells */ #define NBINS (10) enum r_shell { R_SHELL_NONE, R_SHELL_R1I, R_SHELL_R1F, R_SHELL_RSPLIT, }; static enum r_shell get_r_shell(const char *s) { if ( strcasecmp(s, "r1i") == 0 ) return R_SHELL_R1I; if ( strcasecmp(s, "r1f") == 0 ) return R_SHELL_R1F; if ( strcasecmp(s, "rsplit") == 0 ) return R_SHELL_RSPLIT; ERROR("Unknown R-factor '%s' - try '--shells=rsplit', or --help for" " more possibilities.\n", s); exit(1); } static void show_help(const char *s) { printf("Syntax: %s [options] \n\n", s); printf( "Compare intensity lists.\n" "\n" " -h, --help Display this help message.\n" " -o, --ratio= Specify output filename for ratios.\n" " -y, --symmetry= The symmetry of both the input files.\n" " -p, --pdb= PDB file to use.\n" " --shells= Plot this figure of merit in resolution shells.\n" " Choose from: 'Rsplit', 'R1f' and 'R1i'.\n" " --rmin= Fix lower resolution limit for --shells (m^-1).\n" " --rmax= Fix upper resolution limit for --shells (m^-1).\n" " --sigma-cutoff= Discard reflections with I/sigma(I) < n.\n" "\n"); } static void plot_shells(RefList *list1, RefList *list2, double scale, UnitCell *cell, double rmin_fix, double rmax_fix, enum r_shell config_shells) { double num[NBINS]; int cts[NBINS]; double total_vol, vol_per_shell; double rmins[NBINS]; double rmaxs[NBINS]; double rmin, rmax; int i; Reflection *refl1; RefListIterator *iter; FILE *fh; double den[NBINS]; int ctot, nout; if ( cell == NULL ) { ERROR("Need the unit cell to plot resolution shells.\n"); return; } for ( i=0; i 0.0 ) rmin = rmin_fix; if ( rmax_fix > 0.0 ) rmax = rmax_fix; /* Calculate the resolution bins */ total_vol = pow(rmax, 3.0) - pow(rmin, 3.0); vol_per_shell = total_vol / NBINS; rmins[0] = rmin; for ( i=1; irmins[j]) && (d<=rmaxs[j]) ) { bin = j; break; } } /* Outside resolution range? */ if ( bin == -1 ) { nout++; continue; } refl2 = find_refl(list2, h, k, l); if ( refl2 == NULL ) continue; i1 = get_intensity(refl1); i2 = get_intensity(refl2); f1 = i1 > 0.0 ? sqrt(i1) : 0.0; f2 = i2 > 0.0 ? sqrt(i2) : 0.0; switch ( config_shells ) { case R_SHELL_RSPLIT : num[bin] += fabs(i1 - i2); den[bin] += i1 + i2; break; case R_SHELL_R1I : num[bin] += fabs(i1 - scale*i2); den[bin] += i1; break; case R_SHELL_R1F : num[bin] += fabs(f1 - scale*f2); den[bin] += f1; break; default : break; } ctot++; cts[bin]++; } if ( nout ) { STATUS("Warning; %i reflections outside resolution range.\n", nout); } fh = fopen("shells.dat", "w"); if ( fh == NULL ) { ERROR("Couldn't open 'shells.dat'\n"); return; } switch ( config_shells ) { case R_SHELL_RSPLIT : fprintf(fh, "1/d centre Rsplit / %% nref d (A)\n"); break; case R_SHELL_R1I : fprintf(fh, "1/d centre R1(I) / %% nref d (A)\n"); break; case R_SHELL_R1F : fprintf(fh, "1/d centre R1(F) ign -/%% nref d (A)\n"); break; default : fprintf(fh, "1/d centre 0.0 nref d (A)\n"); break; } for ( i=0; i= %f.\n", num_reflections(list1), num_reflections(list2), ncom, sigma_cutoff); STATUS("Discarded %i reflections because either or both versions " " had I/sigma(I) < %f\n", nrej, sigma_cutoff); R1 = stat_r1_ignore(list1, list2, &scale_r1fi, config_unity); STATUS("R1(F) = %5.4f %% (scale=%5.2e)" " (ignoring negative intensities)\n", R1*100.0, scale_r1fi); R1 = stat_r1_zero(list1, list2, &scale_r1, config_unity); STATUS("R1(F) = %5.4f %% (scale=%5.2e)" " (zeroing negative intensities)\n", R1*100.0, scale_r1); R2 = stat_r2(list1, list2, &scale_r2, config_unity); STATUS("R2(I) = %5.4f %% (scale=%5.2e)\n", R2*100.0, scale_r2); R1i = stat_r1_i(list1, list2, &scale_r1i, config_unity); STATUS("R1(I) = %5.4f %% (scale=%5.2e)\n", R1i*100.0, scale_r1i); Rdiff = stat_rdiff_ignore(list1, list2, &scale_rdig, config_unity); STATUS("Rint(F) = %5.4f %% (scale=%5.2e)" " (ignoring negative intensities)\n", Rdiff*100.0, scale_rdig); Rdiff = stat_rdiff_zero(list1, list2, &scale, config_unity); STATUS("Rint(F) = %5.4f %% (scale=%5.2e)" " (zeroing negative intensities)\n", Rdiff*100.0, scale); Rdiff = stat_rdiff_intensity(list1, list2, &scale_rintint, config_unity); STATUS("Rint(I) = %5.4f %% (scale=%5.2e)\n", Rdiff*100.0, scale_rintint); pearson = stat_pearson_i(list1, list2); STATUS("Pearson r(I) = %5.4f\n", pearson); pearson = stat_pearson_f_ignore(list1, list2); STATUS("Pearson r(F) = %5.4f (ignoring negative intensities)\n", pearson); pearson = stat_pearson_f_zero(list1, list2); STATUS("Pearson r(F) = %5.4f (zeroing negative intensities)\n", pearson); switch ( config_shells ) { case R_SHELL_R1I : scale_for_shells = scale_r1i; break; case R_SHELL_R1F : scale_for_shells = scale_r1; break; case R_SHELL_RSPLIT : scale_for_shells = scale_rintint; break; default : scale_for_shells = 0.0; } if ( config_shells != R_SHELL_NONE ) { plot_shells(list1, list2, scale_for_shells, cell, rmin_fix, rmax_fix, config_shells); } return 0; }