/* * 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" "\n"); } static void plot_shells(const double *ref1, const double *ref2, ReflItemList *items, double scale, UnitCell *cell, const char *sym, ReflItemList *characterise, unsigned int *char_counts) { 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 den; double rmin, rmax; signed int h, k, l; int i; int ctot; FILE *fh; 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("%f -> %f\n", rmin/1e9, rmax/1e9); /* Increase the max just a little bit */ rmax += 0.001e9; 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); /* Characterise the first data set (only) */ for ( i=0; ih; k = it->k; l = it->l; /* FIXME: Reflection condition */ //if ( (h==0) && (k==0) && (l%2) ) continue; d = resolution(cell, h, k, l) * 2.0; bin = -1; for ( j=0; jrmins[j]) && (d<=rmaxs[j]) ) { bin = j; break; } } if ( bin == -1 ) { ERROR("Warnung! %i %i %i %f\n", h, k, l, d/1e9); continue; } measured[bin]++; measurements[bin] += lookup_count(char_counts, h, k, l); } den = 0.0; ctot = 0; for ( i=0; ih; k = it->k; l = it->l; /* FIXME: Reflection condition */ //if ( (h==0) && (k==0) && (l%2) ) continue; d = resolution(cell, h, k, l) * 2.0; bin = -1; for ( j=0; jrmins[j]) && (d<=rmaxs[j]) ) { bin = j; break; } } if ( bin == -1 ) { ERROR("Warnung! %i %i %i %f\n", h, k, l, d/1e9); abort(); continue; } i1 = lookup_intensity(ref1, h, k, l); if ( i1 < 0.0 ) continue; f1 = sqrt(i1); i2 = lookup_intensity(ref2, h, k, l); if ( i2 < 0.0 ) continue; f2 = sqrt(i2); f2 *= scale; num[bin] += fabs(f1 - f2); den += (f1 + f2) / 2.0; ctot++; cts[bin]++; } 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); STATUS("R1(F) = %5.4f %% (scale=%5.2e) (ignoring negative intensities)\n", R1*100.0, scale); R1 = stat_r1_zero(ref1, ref2_transformed, icommon, &scale); STATUS("R1(F) = %5.4f %% (scale=%5.2e) (zeroing negative intensities)\n", R1*100.0, scale); 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); STATUS("R1(I) = %5.4f %% (scale=%5.2e)\n", R1i*100.0, scale); 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); 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); 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_rdig, cell, sym, i1, cts1); } if ( outfile != NULL ) { write_reflections(outfile, icommon, out, NULL, NULL, cell); } return 0; }