/* * compare_hkl.c * * Compare reflection lists * * (c) 2006-2010 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include "utils.h" #include "sfac.h" #include "reflections.h" #include "statistics.h" #include "symmetry.h" /* Number of bins for plot of resolution shells */ #define NBINS (10) 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, --output= Specify output filename for correction factor.\n" " -y, --symmetry= The symmetry of both the input files.\n" " -p, --pdb= PDB file to use (default: molecule.pdb).\n" " --shells Plot the figures of merit by resolution.\n" " --rmin= Fix lower resolution limit for --shells (m^-1).\n" " --rmax= Fix upper resolution limit for --shells (m^-1).\n" "\n"); } static void plot_shells(const double *ref1, const double *ref2, ReflItemList *items, double scale, UnitCell *cell, const char *sym, double rmin_fix, double rmax_fix) { double num[NBINS]; int cts[NBINS]; int possible[NBINS]; unsigned int *counted; unsigned int measurements[NBINS]; unsigned int measured[NBINS]; double total_vol, vol_per_shell; double rmins[NBINS]; double rmaxs[NBINS]; double snr[NBINS]; double den; double rmin, rmax; signed int h, k, l; int i; int ctot; FILE *fh; int nout = 0; if ( cell == NULL ) { ERROR("Need the unit cell to plot resolution shells.\n"); return; } fh = fopen("shells.dat", "w"); if ( fh == NULL ) { ERROR("Couldn't open 'shells.dat'\n"); return; } for ( i=0; ih; k = it->k; l = it->l; d = resolution(cell, h, k, l) * 2.0; if ( d > rmax ) rmax = d; if ( d < rmin ) rmin = d; } STATUS("1/d goes from %f to %f nm^-1\n", rmin/1e9, rmax/1e9); /* Widen the range just a little bit */ rmin -= 0.001e9; rmax += 0.001e9; /* Fixed resolution shells if needed */ if ( rmin_fix > 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 / NBINS; rmins[0] = rmin; for ( i=1; irmins[i]) && (d<=rmaxs[i]) ) { bin = i; break; } } if ( bin == -1 ) continue; possible[bin]++; } } } free(counted); den = 0.0; ctot = 0; nout = 0; for ( i=0; ih; k = it->k; l = it->l; d = resolution(cell, h, k, l) * 2.0; bin = -1; for ( j=0; jrmins[j]) && (d<=rmaxs[j]) ) { bin = j; break; } } /* Outside resolution range? */ if ( bin == -1 ) { nout++; continue; } i1 = lookup_intensity(ref1, h, k, l); i2 = lookup_intensity(ref2, h, k, l); i2 *= scale; num[bin] += fabs(i1 - i2); den += i1; ctot++; cts[bin]++; } if ( nout ) { STATUS("Warning; %i reflections outside resolution range.\n", nout); } for ( i=0; ih; k = it->k; l = it->l; if ( !find_unique_equiv(i2, h, k, l, sym, &he, &ke, &le) ) { //STATUS("%i %i %i not matched (%f nm).\n", h, k, l, // 1.0/(2.0*resolution(cell, h, k, l)/1e9)); continue; } val1 = lookup_intensity(ref1, h, k, l); val2 = lookup_intensity(ref2, he, ke, le); sig1 = lookup_sigma(esd1, h, k, l); sig2 = lookup_sigma(esd2, he, ke, le); if ( val1 < 3.0 * sig1 ) { rej1++; ig = 1; } if ( val2 < 3.0 * sig2 ) { rej2++; ig = 1; } d = 0.5/resolution(cell, h, k, l); if ( d > 55.0e-10 ) ig = 1; //if ( d < 15.0e-10 ) ig = 1; //if ( ig ) continue; set_intensity(ref2_transformed, h, k, l, val2); set_intensity(out, h, k, l, val1/val2); add_item(icommon, h, k, l); } ncom = num_items(icommon); STATUS("%i reflections with I < 3.0*sigma(I) rejected from '%s'\n", rej1, afile); STATUS("%i reflections with I < 3.0*sigma(I) rejected from '%s'\n", rej2, bfile); STATUS("%i,%i reflections: %i in common\n", num_items(i1), num_items(i2), ncom); R1 = stat_r1_ignore(ref1, ref2_transformed, icommon, &scale_r1fi); STATUS("R1(F) = %5.4f %% (scale=%5.2e) (ignoring negative intensities)\n", R1*100.0, scale_r1fi); R1 = stat_r1_zero(ref1, ref2_transformed, icommon, &scale_r1); STATUS("R1(F) = %5.4f %% (scale=%5.2e) (zeroing negative intensities)\n", R1*100.0, scale_r1); R2 = stat_r2(ref1, ref2_transformed, icommon, &scale_r2); STATUS("R2(I) = %5.4f %% (scale=%5.2e)\n", R2*100.0, scale_r2); R1i = stat_r1_i(ref1, ref2_transformed, icommon, &scale_r1i); STATUS("R1(I) = %5.4f %% (scale=%5.2e)\n", R1i*100.0, scale_r1i); Rdiff = stat_rdiff_ignore(ref1, ref2_transformed, icommon, &scale_rdig); STATUS("Rint(F) = %5.4f %% (scale=%5.2e) (ignoring negative intensities)\n", Rdiff*100.0, scale_rdig); Rdiff = stat_rdiff_zero(ref1, ref2_transformed, icommon, &scale); STATUS("Rint(F) = %5.4f %% (scale=%5.2e) (zeroing negative intensities)\n", Rdiff*100.0, scale); Rdiff = stat_rdiff_intensity(ref1, ref2_transformed, icommon, &scale_rintint); STATUS("Rint(I) = %5.4f %% (scale=%5.2e)\n", Rdiff*100.0, scale_rintint); pearson = stat_pearson_i(ref1, ref2_transformed, icommon); STATUS("Pearson r(I) = %5.4f\n", pearson); pearson = stat_pearson_f_ignore(ref1, ref2_transformed, icommon); STATUS("Pearson r(F) = %5.4f (ignoring negative intensities)\n", pearson); pearson = stat_pearson_f_zero(ref1, ref2_transformed, icommon); STATUS("Pearson r(F) = %5.4f (zeroing negative intensities)\n", pearson); if ( config_shells ) { plot_shells(ref1, ref2_transformed, icommon, scale_r1fi, cell, sym, rmin_fix, rmax_fix); } if ( outfile != NULL ) { write_reflections(outfile, icommon, out, NULL, NULL, NULL, cell); STATUS("Sigma(I) values in output file are not meaningful.\n"); } return 0; }