From 192b3acc937155a1851c7c8547d912dcdf5ff759 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 24 May 2011 11:40:06 +0200 Subject: compare_hkl: Fix appalling scaling behaviour --- src/compare_hkl.c | 39 +++++++------- src/statistics.c | 149 +++++++++++++++++++++--------------------------------- src/statistics.h | 22 ++++---- 3 files changed, 87 insertions(+), 123 deletions(-) diff --git a/src/compare_hkl.c b/src/compare_hkl.c index adbc7fe4..1eae1849 100644 --- a/src/compare_hkl.c +++ b/src/compare_hkl.c @@ -49,7 +49,7 @@ static void show_help(const char *s) } -static void plot_shells(RefList *list1, RefList *list2, double scale, +static void plot_shells(RefList *list1, double *arr2, double scale, UnitCell *cell, const char *sym, double rmin_fix, double rmax_fix) { @@ -106,11 +106,8 @@ static void plot_shells(RefList *list1, RefList *list2, double scale, signed int h, k, l; double d; - Reflection *refl2; 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; @@ -207,11 +204,8 @@ static void plot_shells(RefList *list1, RefList *list2, double scale, int bin; double i1, i2; int j; - Reflection *refl2; 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; @@ -230,8 +224,7 @@ static void plot_shells(RefList *list1, RefList *list2, double scale, } i1 = get_intensity(refl1); - i2 = get_intensity(refl2); - i2 *= scale; + i2 = scale * lookup_intensity(arr2, h, k, l); num[bin] += fabs(i1 - i2); den += i1; @@ -282,6 +275,7 @@ int main(int argc, char *argv[]) float rmax_fix = -1.0; Reflection *refl1; RefListIterator *iter; + double *arr2; /* Long options */ const struct option longopts[] = { @@ -471,49 +465,54 @@ int main(int argc, char *argv[]) reflist_free(deleteme); reflist_free(list2); - R1 = stat_r1_ignore(list1, list2_transformed, &scale_r1fi); + /* 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); STATUS("R1(F) = %5.4f %% (scale=%5.2e)" " (ignoring negative intensities)\n", R1*100.0, scale_r1fi); - R1 = stat_r1_zero(list1, list2_transformed, &scale_r1); + R1 = stat_r1_zero(list1, arr2, &scale_r1); STATUS("R1(F) = %5.4f %% (scale=%5.2e)" " (zeroing negative intensities)\n", R1*100.0, scale_r1); - R2 = stat_r2(list1, list2_transformed, &scale_r2); + R2 = stat_r2(list1, arr2, &scale_r2); STATUS("R2(I) = %5.4f %% (scale=%5.2e)\n", R2*100.0, scale_r2); - R1i = stat_r1_i(list1, list2_transformed, &scale_r1i); + R1i = stat_r1_i(list1, arr2, &scale_r1i); STATUS("R1(I) = %5.4f %% (scale=%5.2e)\n", R1i*100.0, scale_r1i); - Rdiff = stat_rdiff_ignore(list1, list2_transformed, &scale_rdig); + Rdiff = stat_rdiff_ignore(list1, arr2, &scale_rdig); STATUS("Rint(F) = %5.4f %% (scale=%5.2e)" " (ignoring negative intensities)\n", Rdiff*100.0, scale_rdig); - Rdiff = stat_rdiff_zero(list1, list2_transformed, &scale); + Rdiff = stat_rdiff_zero(list1, arr2, &scale); STATUS("Rint(F) = %5.4f %% (scale=%5.2e)" " (zeroing negative intensities)\n", Rdiff*100.0, scale); - Rdiff = stat_rdiff_intensity(list1, list2_transformed, &scale_rintint); + Rdiff = stat_rdiff_intensity(list1, arr2, &scale_rintint); STATUS("Rint(I) = %5.4f %% (scale=%5.2e)\n", Rdiff*100.0, scale_rintint); - pearson = stat_pearson_i(list1, list2_transformed); + pearson = stat_pearson_i(list1, arr2); STATUS("Pearson r(I) = %5.4f\n", pearson); - pearson = stat_pearson_f_ignore(list1, list2_transformed); + pearson = stat_pearson_f_ignore(list1, arr2); STATUS("Pearson r(F) = %5.4f (ignoring negative intensities)\n", pearson); - pearson = stat_pearson_f_zero(list1, list2_transformed); + pearson = stat_pearson_f_zero(list1, arr2); STATUS("Pearson r(F) = %5.4f (zeroing negative intensities)\n", pearson); if ( config_shells ) { - plot_shells(list1, list2_transformed, scale_r1i, + plot_shells(list1, arr2, scale_r1i, cell, sym, rmin_fix, rmax_fix); } diff --git a/src/statistics.c b/src/statistics.c index 77e7919f..da9a06c6 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -26,7 +26,7 @@ struct r_params { RefList *list1; - RefList *list2; + double *arr2; int fom; /* Which FoM to use (see the enum just below) */ }; @@ -42,10 +42,10 @@ enum { /* Return the least squares optimal scaling factor when comparing intensities. - * list1,list2 are the two intensity lists to compare. "items" is a ReflItemList + * list1,arr2 are the two intensity lists to compare. "items" is a ReflItemList * containing the reflections which should be taken into account. */ -double stat_scale_intensity(RefList *list1, RefList *list2) +double stat_scale_intensity(RefList *list1, double *arr2) { double top = 0.0; double bot = 0.0; @@ -58,14 +58,11 @@ double stat_scale_intensity(RefList *list1, RefList *list2) double i1, i2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); top += i1 * i2; bot += i2 * i2; @@ -79,11 +76,11 @@ double stat_scale_intensity(RefList *list1, RefList *list2) /* Return the least squares optimal scaling factor when comparing the square * roots of the intensities (i.e. one approximation to the structure factor * moduli). - * list1,list2 are the two intensity lists to compare (they contain intensities, + * list1,arr2 are the two intensity lists to compare (they contain intensities, * not square rooted intensities). "items" is a ReflItemList containing the * reflections which should be taken into account. */ -static double stat_scale_sqrti(RefList *list1, RefList *list2) +static double stat_scale_sqrti(RefList *list1, double *arr2) { double top = 0.0; double bot = 0.0; @@ -97,14 +94,11 @@ static double stat_scale_sqrti(RefList *list1, RefList *list2) double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); if ( i1 < 0.0 ) continue; f1 = sqrt(i1); @@ -121,7 +115,7 @@ static double stat_scale_sqrti(RefList *list1, RefList *list2) } -static double internal_r1_ignorenegs(RefList *list1, RefList *list2, +static double internal_r1_ignorenegs(RefList *list1, double *arr2, double scale) { double top = 0.0; @@ -136,14 +130,11 @@ static double internal_r1_ignorenegs(RefList *list1, RefList *list2, double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); if ( i1 < 0.0 ) continue; f1 = sqrt(i1); @@ -161,7 +152,7 @@ static double internal_r1_ignorenegs(RefList *list1, RefList *list2, } -static double internal_r1_negstozero(RefList *list1, RefList *list2, +static double internal_r1_negstozero(RefList *list1, double *arr2, double scale) { double top = 0.0; @@ -176,14 +167,11 @@ static double internal_r1_negstozero(RefList *list1, RefList *list2, double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); f1 = i1 > 0.0 ? sqrt(i1) : 0.0; @@ -199,7 +187,7 @@ static double internal_r1_negstozero(RefList *list1, RefList *list2, } -static double internal_r2(RefList *list1, RefList *list2, double scale) +static double internal_r2(RefList *list1, double *arr2, double scale) { double top = 0.0; double bot = 0.0; @@ -212,14 +200,12 @@ static double internal_r2(RefList *list1, RefList *list2, double scale) double i1, i2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = scale * get_intensity(refl2); + i2 *= scale; top += pow(i1 - i2, 2.0); bot += pow(i1, 2.0); @@ -230,7 +216,7 @@ static double internal_r2(RefList *list1, RefList *list2, double scale) } -static double internal_r_i(RefList *list1, RefList *list2, double scale) +static double internal_r_i(RefList *list1, double *arr2, double scale) { double top = 0.0; double bot = 0.0; @@ -243,14 +229,12 @@ static double internal_r_i(RefList *list1, RefList *list2, double scale) double i1, i2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = scale * get_intensity(refl2); + i2 *= scale; top += fabs(i1-i2); bot += fabs(i1); @@ -261,7 +245,7 @@ static double internal_r_i(RefList *list1, RefList *list2, double scale) } -static double internal_rdiff_intensity(RefList *list1, RefList *list2, +static double internal_rdiff_intensity(RefList *list1, double *arr2, double scale) { double top = 0.0; @@ -275,14 +259,11 @@ static double internal_rdiff_intensity(RefList *list1, RefList *list2, double i1, i2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); i2 *= scale; @@ -295,7 +276,7 @@ static double internal_rdiff_intensity(RefList *list1, RefList *list2, } -static double internal_rdiff_negstozero(RefList *list1, RefList *list2, +static double internal_rdiff_negstozero(RefList *list1, double *arr2, double scale) { double top = 0.0; @@ -310,14 +291,11 @@ static double internal_rdiff_negstozero(RefList *list1, RefList *list2, double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); f1 = i1 > 0.0 ? sqrt(i1) : 0.0; @@ -333,7 +311,7 @@ static double internal_rdiff_negstozero(RefList *list1, RefList *list2, } -static double internal_rdiff_ignorenegs(RefList *list1, RefList *list2, +static double internal_rdiff_ignorenegs(RefList *list1, double *arr2, double scale) { double top = 0.0; @@ -348,14 +326,11 @@ static double internal_rdiff_ignorenegs(RefList *list1, RefList *list2, double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); if ( i1 < 0.0 ) continue; f1 = sqrt(i1); @@ -379,21 +354,21 @@ static double calc_r(double scale, void *params) switch ( rp->fom) { case R_1_ZERO : - return internal_r1_negstozero(rp->list1, rp->list2, scale); + return internal_r1_negstozero(rp->list1, rp->arr2, scale); case R_1_IGNORE : - return internal_r1_ignorenegs(rp->list1, rp->list2, scale); + return internal_r1_ignorenegs(rp->list1, rp->arr2, scale); case R_2 : - return internal_r2(rp->list1, rp->list2, scale); + return internal_r2(rp->list1, rp->arr2, scale); case R_1_I : - return internal_r_i(rp->list1, rp->list2, scale); + return internal_r_i(rp->list1, rp->arr2, scale); case R_DIFF_ZERO : - return internal_rdiff_negstozero(rp->list1, rp->list2,scale); + return internal_rdiff_negstozero(rp->list1, rp->arr2,scale); case R_DIFF_IGNORE : - return internal_rdiff_ignorenegs(rp->list1, rp->list2, scale); + return internal_rdiff_ignorenegs(rp->list1, rp->arr2, scale); case R_DIFF_INTENSITY : - return internal_rdiff_intensity(rp->list1, rp->list2, scale); + return internal_rdiff_intensity(rp->list1, rp->arr2, scale); } ERROR("No such FoM!\n"); @@ -401,8 +376,7 @@ static double calc_r(double scale, void *params) } -static double r_minimised(RefList *list1, RefList *list2, - double *scalep, int fom) +static double r_minimised(RefList *list1, double *arr2, double *scalep, int fom) { gsl_function F; gsl_min_fminimizer *s; @@ -412,7 +386,7 @@ static double r_minimised(RefList *list1, RefList *list2, int iter = 0; rp.list1 = list1; - rp.list2 = list2; + rp.arr2 = arr2; rp.fom = fom; F.function = &calc_r; @@ -426,12 +400,12 @@ static double r_minimised(RefList *list1, RefList *list2, case R_1_IGNORE : case R_DIFF_ZERO : case R_DIFF_IGNORE : - scale = stat_scale_sqrti(list1, list2); + scale = stat_scale_sqrti(list1, arr2); break; case R_2 : case R_1_I : case R_DIFF_INTENSITY : - scale = stat_scale_intensity(list1, list2); + scale = stat_scale_intensity(list1, arr2); break; } //STATUS("Initial scale factor estimate: %5.2e\n", scale); @@ -470,52 +444,52 @@ static double r_minimised(RefList *list1, RefList *list2, } -double stat_r1_ignore(RefList *list1, RefList *list2, double *scalep) +double stat_r1_ignore(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_1_IGNORE); + return r_minimised(list1, arr2, scalep, R_1_IGNORE); } -double stat_r1_zero(RefList *list1, RefList *list2, double *scalep) +double stat_r1_zero(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_1_ZERO); + return r_minimised(list1, arr2, scalep, R_1_ZERO); } -double stat_r2(RefList *list1, RefList *list2, double *scalep) +double stat_r2(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_2); + return r_minimised(list1, arr2, scalep, R_2); } -double stat_r1_i(RefList *list1, RefList *list2, double *scalep) +double stat_r1_i(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_1_I); + return r_minimised(list1, arr2, scalep, R_1_I); } -double stat_rdiff_zero(RefList *list1, RefList *list2, double *scalep) +double stat_rdiff_zero(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_DIFF_ZERO); + return r_minimised(list1, arr2, scalep, R_DIFF_ZERO); } -double stat_rdiff_ignore(RefList *list1, RefList *list2, double *scalep) +double stat_rdiff_ignore(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_DIFF_IGNORE); + return r_minimised(list1, arr2, scalep, R_DIFF_IGNORE); } -double stat_rdiff_intensity(RefList *list1, RefList *list2, double *scalep) +double stat_rdiff_intensity(RefList *list1, double *arr2, double *scalep) { - return r_minimised(list1, list2, scalep, R_DIFF_INTENSITY); + return r_minimised(list1, arr2, scalep, R_DIFF_INTENSITY); } -double stat_pearson_i(RefList *list1, RefList *list2) +double stat_pearson_i(RefList *list1, double *arr2) { double *vec1, *vec2; - int ni = num_reflections(list1) + num_reflections(list2); + int ni = num_reflections(list1); double val; int nacc = 0; Reflection *refl1; @@ -530,14 +504,11 @@ double stat_pearson_i(RefList *list1, RefList *list2) double i1, i2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); vec1[nacc] = i1; vec2[nacc] = i2; @@ -552,10 +523,10 @@ double stat_pearson_i(RefList *list1, RefList *list2) } -double stat_pearson_f_ignore(RefList *list1, RefList *list2) +double stat_pearson_f_ignore(RefList *list1, double *arr2) { double *vec1, *vec2; - int ni = num_reflections(list1) + num_reflections(list2); + int ni = num_reflections(list1); double val; int nacc = 0; Reflection *refl1; @@ -571,15 +542,12 @@ double stat_pearson_f_ignore(RefList *list1, RefList *list2) double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; int ig = 0; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); if ( i1 < 0.0 ) ig = 1; f1 = sqrt(i1); @@ -603,10 +571,10 @@ double stat_pearson_f_ignore(RefList *list1, RefList *list2) } -double stat_pearson_f_zero(RefList *list1, RefList *list2) +double stat_pearson_f_zero(RefList *list1, double *arr2) { double *vec1, *vec2; - int ni = num_reflections(list1) + num_reflections(list2); + int ni = num_reflections(list1); double val; int nacc = 0; Reflection *refl1; @@ -622,14 +590,11 @@ double stat_pearson_f_zero(RefList *list1, RefList *list2) double i1, i2; double f1, f2; signed int h, k, l; - Reflection *refl2; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; /* No common reflection */ + i2 = lookup_intensity(arr2, h, k, l); i1 = get_intensity(refl1); - i2 = get_intensity(refl2); f1 = i1 > 0.0 ? sqrt(i1) : 0.0; f2 = i2 > 0.0 ? sqrt(i2) : 0.0; diff --git a/src/statistics.h b/src/statistics.h index 34ef2406..e1d7244e 100644 --- a/src/statistics.h +++ b/src/statistics.h @@ -19,23 +19,23 @@ #include "reflist.h" -extern double stat_scale_intensity(RefList *list1, RefList *list2); +extern double stat_scale_intensity(RefList *list1, double *arr2); -extern double stat_r1_zero(RefList *list1, RefList *list2, double *scalep); -extern double stat_r1_ignore(RefList *list1, RefList *list2, double *scalep); +extern double stat_r1_zero(RefList *list1, double *arr2, double *scalep); +extern double stat_r1_ignore(RefList *list1, double *arr2, double *scalep); -extern double stat_r2(RefList *list1, RefList *list2, double *scalep); +extern double stat_r2(RefList *list1, double *arr2, double *scalep); -extern double stat_r1_i(RefList *list1, RefList *list2, double *scalep); +extern double stat_r1_i(RefList *list1, double *arr2, double *scalep); -extern double stat_rdiff_zero(RefList *list1, RefList *list2, double *scalep); -extern double stat_rdiff_ignore(RefList *list1, RefList *list2, double *scalep); -extern double stat_rdiff_intensity(RefList *list1, RefList *list2, +extern double stat_rdiff_zero(RefList *list1, double *arr2, double *scalep); +extern double stat_rdiff_ignore(RefList *list1, double *arr2, double *scalep); +extern double stat_rdiff_intensity(RefList *list1, double *arr2, double *scalep); -extern double stat_pearson_i(RefList *list1, RefList *list2); -extern double stat_pearson_f_zero(RefList *list1, RefList *list2); -extern double stat_pearson_f_ignore(RefList *list1, RefList *list2); +extern double stat_pearson_i(RefList *list1, double *arr2); +extern double stat_pearson_f_zero(RefList *list1, double *arr2); +extern double stat_pearson_f_ignore(RefList *list1, double *arr2); #endif /* STATISTICS_H */ -- cgit v1.2.3