aboutsummaryrefslogtreecommitdiff
path: root/src/compare_hkl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compare_hkl.c')
-rw-r--r--src/compare_hkl.c220
1 files changed, 132 insertions, 88 deletions
diff --git a/src/compare_hkl.c b/src/compare_hkl.c
index abe8bc6a..16a744ea 100644
--- a/src/compare_hkl.c
+++ b/src/compare_hkl.c
@@ -20,11 +20,12 @@
#include <string.h>
#include <unistd.h>
#include <getopt.h>
+#include <assert.h>
#include "utils.h"
-#include "reflections.h"
#include "statistics.h"
#include "symmetry.h"
+#include "reflist-utils.h"
/* Number of bins for plot of resolution shells */
@@ -38,7 +39,7 @@ static void show_help(const char *s)
"Compare intensity lists.\n"
"\n"
" -h, --help Display this help message.\n"
-" -o, --output=<filename> Specify output filename for correction factor.\n"
+" -o, --ratio=<filename> Specify output filename for ratios.\n"
" -y, --symmetry=<sym> The symmetry of both the input files.\n"
" -p, --pdb=<filename> PDB file to use (default: molecule.pdb).\n"
" --shells Plot the figures of merit by resolution.\n"
@@ -48,9 +49,9 @@ static void show_help(const char *s)
}
-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)
+static void plot_shells(RefList *list1, RefList *list2, double scale,
+ UnitCell *cell, const char *sym,
+ double rmin_fix, double rmax_fix)
{
double num[NBINS];
int cts[NBINS];
@@ -69,6 +70,12 @@ static void plot_shells(const double *ref1, const double *ref2,
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");
@@ -90,16 +97,20 @@ static void plot_shells(const double *ref1, const double *ref2,
snr[i] = 0;
}
- rmin = +INFINITY;
- rmax = 0.0;
- for ( i=0; i<num_items(items); i++ ) {
+ /* Iterate over all common reflections and calculate min and max
+ * resolution */
+ rmin = +INFINITY; rmax = 0.0;
+ for ( refl1 = first_refl(list1, &iter);
+ refl1 != NULL;
+ refl1 = next_refl(refl1, iter) ) {
- struct refl_item *it;
signed int h, k, l;
double d;
+ Reflection *refl2;
- it = get_item(items, i);
- h = it->h; k = it->k; l = it->l;
+ get_indices(refl1, &h, &k, &l);
+ refl2 = find_refl(list2, h, k, l);
+ if ( refl2 == NULL ) continue; /* No common reflection */
d = resolution(cell, h, k, l) * 2.0;
if ( d > rmax ) rmax = d;
@@ -117,6 +128,7 @@ static void plot_shells(const double *ref1, const double *ref2,
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;
@@ -145,9 +157,16 @@ static void plot_shells(const double *ref1, const double *ref2,
/* Count the number of reflections possible in each shell */
counted = new_list_count();
- for ( h=-50; h<=+50; h++ ) {
- for ( k=-50; k<=+50; k++ ) {
- for ( l=-50; l<=+50; l++ ) {
+ cell_get_reciprocal(cell, &asx, &asy, &asz,
+ &bsx, &bsy, &bsz,
+ &csx, &csy, &csz);
+ hmax = rmax / modulus(asx, asy, asz);
+ kmax = rmax / modulus(bsx, bsy, bsz);
+ lmax = rmax / modulus(csx, csy, csz);
+
+ for ( h=-hmax; h<hmax; h++ ) {
+ for ( k=-kmax; k<kmax; k++ ) {
+ for ( l=-lmax; l<lmax; l++ ) {
double d;
signed int hs, ks, ls;
@@ -178,17 +197,21 @@ static void plot_shells(const double *ref1, const double *ref2,
den = 0.0;
ctot = 0;
nout = 0;
- for ( i=0; i<num_items(items); i++ ) {
- struct refl_item *it;
+ 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;
+ Reflection *refl2;
- it = get_item(items, i);
- h = it->h; k = it->k; l = it->l;
+ get_indices(refl1, &h, &k, &l);
+ refl2 = find_refl(list2, h, k, l);
+ if ( refl2 == NULL ) continue; /* No common reflection */
d = resolution(cell, h, k, l) * 2.0;
@@ -206,8 +229,8 @@ static void plot_shells(const double *ref1, const double *ref2,
continue;
}
- i1 = lookup_intensity(ref1, h, k, l);
- i2 = lookup_intensity(ref2, h, k, l);
+ i1 = get_intensity(refl1);
+ i2 = get_intensity(refl2);
i2 *= scale;
num[bin] += fabs(i1 - i2);
@@ -238,33 +261,32 @@ static void plot_shells(const double *ref1, const double *ref2,
int main(int argc, char *argv[])
{
int c;
- double *ref1;
- double *ref2;
- double *ref2_transformed;
- double *out;
UnitCell *cell;
- char *outfile = NULL;
+ char *ratiofile = NULL;
char *afile = NULL;
char *bfile = NULL;
char *sym = NULL;
double scale, scale_r2, scale_rdig, R1, R2, R1i, Rdiff, pearson;
double scale_rintint, scale_r1i, scale_r1, scale_r1fi;
- int i, ncom;
- ReflItemList *i1, *i2, *icommon;
+ int ncom;
+ RefList *list1;
+ RefList *list2;
+ RefList *list2_transformed;
+ RefList *ratio;
+ RefList *deleteme;
int config_shells = 0;
char *pdb = NULL;
- double *esd1;
- double *esd2;
int rej1 = 0;
int rej2 = 0;
- unsigned int *cts1;
float rmin_fix = -1.0;
float rmax_fix = -1.0;
+ Reflection *refl1;
+ RefListIterator *iter;
/* Long options */
const struct option longopts[] = {
{"help", 0, NULL, 'h'},
- {"output", 1, NULL, 'o'},
+ {"ratio" , 1, NULL, 'o'},
{"symmetry", 1, NULL, 'y'},
{"shells", 0, &config_shells, 1},
{"pdb", 1, NULL, 'p'},
@@ -282,7 +304,7 @@ int main(int argc, char *argv[])
return 0;
case 'o' :
- outfile = strdup(optarg);
+ ratiofile = strdup(optarg);
break;
case 'y' :
@@ -335,63 +357,62 @@ int main(int argc, char *argv[])
cell = load_cell_from_pdb(pdb);
free(pdb);
- ref1 = new_list_intensity();
- esd1 = new_list_sigma();
- cts1 = new_list_count();
- i1 = read_reflections(afile, ref1, NULL, cts1, esd1);
- if ( i1 == NULL ) {
- ERROR("Couldn't open file '%s'\n", afile);
+ list1 = read_reflections(afile);
+ if ( list1 == NULL ) {
+ ERROR("Couldn't read file '%s'\n", afile);
return 1;
}
- ref2 = new_list_intensity();
- esd2 = new_list_sigma();
- i2 = read_reflections(bfile, ref2, NULL, NULL, esd2);
- if ( i2 == NULL ) {
- ERROR("Couldn't open file '%s'\n", bfile);
+
+ list2 = read_reflections(bfile);
+ if ( list2 == NULL ) {
+ ERROR("Couldn't read file '%s'\n", bfile);
return 1;
}
/* Check that the intensities have the correct symmetry */
- if ( check_symmetry(i1, sym) ) {
+ if ( check_list_symmetry(list1, sym) ) {
ERROR("The first input reflection list does not appear to"
" have symmetry %s\n", sym);
return 1;
}
- if ( check_symmetry(i2, sym) ) {
+ if ( check_list_symmetry(list2, sym) ) {
ERROR("The second input reflection list does not appear to"
" have symmetry %s\n", sym);
return 1;
}
- /* List for output scale factor map */
- out = new_list_intensity();
-
/* Find common reflections (taking symmetry into account) */
- icommon = new_items();
- ref2_transformed = new_list_intensity();
- for ( i=0; i<num_items(i1); i++ ) {
+ list2_transformed = reflist_new();
+ ratio = reflist_new();
+ deleteme = reflist_new();
+ for ( refl1 = first_refl(list1, &iter);
+ refl1 != NULL;
+ refl1 = next_refl(refl1, iter) ) {
- struct refl_item *it;
signed int h, k, l;
signed int he, ke, le;
double val1, val2;
double sig1, sig2;
int ig = 0;
double d;
+ Reflection *refl2;
+ Reflection *tr;
- it = get_item(i1, i);
- h = it->h; k = it->k; l = it->l;
+ get_indices(refl1, &h, &k, &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));
+ if ( !find_equiv_in_list(list2, h, k, l, sym, &he, &ke, &le) ) {
+ /* No common reflection */
+ add_refl(deleteme, h, k, l);
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);
+ refl2 = find_refl(list2, he, ke, le);
+ assert(refl2 != NULL);
+
+ val1 = get_intensity(refl1);
+ val2 = get_intensity(refl2);
+ sig1 = get_esd_intensity(refl1);
+ sig2 = get_esd_intensity(refl2);
if ( val1 < 3.0 * sig1 ) {
rej1++;
@@ -408,67 +429,90 @@ int main(int argc, char *argv[])
//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);
+ /* 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);
}
- ncom = num_items(icommon);
+
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_items(i1), num_items(i2), ncom);
+ 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) ) {
- R1 = stat_r1_ignore(ref1, ref2_transformed, icommon, &scale_r1fi);
- STATUS("R1(F) = %5.4f %% (scale=%5.2e) (ignoring negative intensities)\n",
+ 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);
+
+ R1 = stat_r1_ignore(list1, list2_transformed, &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 = stat_r1_zero(list1, list2_transformed, &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);
+ R2 = stat_r2(list1, list2_transformed, &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);
+ R1i = stat_r1_i(list1, list2_transformed, &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 = stat_rdiff_ignore(list1, list2_transformed, &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 = stat_rdiff_zero(list1, list2_transformed, &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);
+ Rdiff = stat_rdiff_intensity(list1, list2_transformed, &scale_rintint);
STATUS("Rint(I) = %5.4f %% (scale=%5.2e)\n",
Rdiff*100.0, scale_rintint);
- pearson = stat_pearson_i(ref1, ref2_transformed, icommon);
+ pearson = stat_pearson_i(list1, list2_transformed);
STATUS("Pearson r(I) = %5.4f\n", pearson);
- pearson = stat_pearson_f_ignore(ref1, ref2_transformed, icommon);
+ pearson = stat_pearson_f_ignore(list1, list2_transformed);
STATUS("Pearson r(F) = %5.4f (ignoring negative intensities)\n",
pearson);
- pearson = stat_pearson_f_zero(ref1, ref2_transformed, icommon);
+ pearson = stat_pearson_f_zero(list1, list2_transformed);
STATUS("Pearson r(F) = %5.4f (zeroing negative intensities)\n",
pearson);
if ( config_shells ) {
- plot_shells(ref1, ref2_transformed, icommon, scale_r1fi,
+ plot_shells(list1, list2_transformed, 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");
-
+ if ( ratiofile != NULL ) {
+ write_reflist(ratiofile, ratio, cell);
}
return 0;