/* * compare_hkl.c * * Compare reflection lists * * (c) 2006-2011 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #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) 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 (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(RefList *list1, double *arr2, 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; Reflection *refl1; RefListIterator *iter; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; int hmax, kmax, lmax; 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; i 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; /* 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[i]) && (d<=rmaxs[i]) ) { bin = i; break; } } if ( bin == -1 ) continue; possible[bin]++; } } } free(counted); den = 0.0; ctot = 0; nout = 0; for ( refl1 = first_refl(list1, &iter); refl1 != NULL; refl1 = next_refl(refl1, iter) ) { signed int h, k, l; double d; int bin; double i1, i2; int j; get_indices(refl1, &h, &k, &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 = get_intensity(refl1); i2 = scale * lookup_intensity(arr2, h, k, l); num[bin] += fabs(i1 - i2); den += i1; ctot++; cts[bin]++; } if ( nout ) { STATUS("Warning; %i reflections outside resolution range.\n", nout); } for ( i=0; i 55.0e-10 ) ig = 1; //if ( d < 15.0e-10 ) ig = 1; //if ( ig ) continue; /* Add the old data from 'refl2' to a new list with the same * indices as its equivalent in 'list1' */ tr = add_refl(list2_transformed, h, k, l); copy_data(tr, refl2); /* Add divided version to 'output' list */ tr = add_refl(ratio, h, k, l); set_int(tr, val1/val2); set_redundancy(tr, 1); } if ( ratiofile != NULL ) { write_reflist(ratiofile, ratio, cell); } reflist_free(ratio); gsl_set_error_handler_off(); STATUS("%i reflections in '%s' had I < 3.0*sigma(I)\n", rej1, afile); STATUS("%i reflections in '%s' had I < 3.0*sigma(I)\n", rej2, bfile); ncom = num_reflections(list2_transformed); STATUS("%i,%i reflections: %i in common\n", num_reflections(list1), num_reflections(list2), ncom); /* Trim reflections from 'list1' which had no equivalents in 'list2' */ for ( refl1 = first_refl(deleteme, &iter); refl1 != NULL; refl1 = next_refl(refl1, iter) ) { signed int h, k, l; Reflection *del; get_indices(refl1, &h, &k, &l); del = find_refl(list1, h, k, l); assert(del != NULL); delete_refl(del); } reflist_free(deleteme); reflist_free(list2); /* Trimming the other way round is not necessary, * because of these two lines */ arr2 = intensities_from_list(list2_transformed); reflist_free(list2_transformed); R1 = stat_r1_ignore(list1, arr2, &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, arr2, &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, arr2, &scale_r2, config_unity); STATUS("R2(I) = %5.4f %% (scale=%5.2e)\n", R2*100.0, scale_r2); R1i = stat_r1_i(list1, arr2, &scale_r1i, config_unity); STATUS("R1(I) = %5.4f %% (scale=%5.2e)\n", R1i*100.0, scale_r1i); Rdiff = stat_rdiff_ignore(list1, arr2, &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, arr2, &scale, config_unity); STATUS("Rint(F) = %5.4f %% (scale=%5.2e)" " (zeroing negative intensities)\n", Rdiff*100.0, scale); Rdiff = stat_rdiff_intensity(list1, arr2, &scale_rintint, config_unity); STATUS("Rint(I) = %5.4f %% (scale=%5.2e)\n", Rdiff*100.0, scale_rintint); pearson = stat_pearson_i(list1, arr2); STATUS("Pearson r(I) = %5.4f\n", pearson); pearson = stat_pearson_f_ignore(list1, arr2); STATUS("Pearson r(F) = %5.4f (ignoring negative intensities)\n", pearson); pearson = stat_pearson_f_zero(list1, arr2); STATUS("Pearson r(F) = %5.4f (zeroing negative intensities)\n", pearson); if ( config_shells ) { plot_shells(list1, arr2, scale_r1i, cell, sym, rmin_fix, rmax_fix); } return 0; }