From cdaa57c6db66fe243ed00730a18395a2a01e8712 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 17 Dec 2010 15:56:01 -0800 Subject: More work on scaling --- src/hrs-scaling.c | 254 +++++++++++++++++++++++++++++++----------------------- src/partialator.c | 2 +- 2 files changed, 149 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/hrs-scaling.c b/src/hrs-scaling.c index 11306029..80894131 100644 --- a/src/hrs-scaling.c +++ b/src/hrs-scaling.c @@ -28,7 +28,7 @@ /* Maximum number of iterations of NLSq scaling per macrocycle. */ -#define MAX_CYCLES (10) +#define MAX_CYCLES (30) static void show_matrix_eqn(gsl_matrix *M, gsl_vector *v, int r) @@ -45,156 +45,167 @@ static void show_matrix_eqn(gsl_matrix *M, gsl_vector *v, int r) } -static double gradient(int j, signed int h, signed int k, signed int l, - struct image *images, int n, const char *sym) +static void sum_GI(struct image *images, int n, const char *sym, + signed int hat, signed int kat, signed int lat, + double *sigma_GI, double *sigma_Gsq) { - struct image *image; - struct cpeak *spots; - double num1 = 0.0; - double num2 = 0.0; - double den = 0.0; - double num1_this = 0.0; - double num2_this = 0.0; - int m, i; - - /* "Everything" terms */ - for ( m=0; mcpeaks; + *sigma_GI = 0.0; + *sigma_Gsq = 0.0; + for ( k=0; kn_cpeaks; i++ ) { + int hi; + struct image *image = &images[k]; + struct cpeak *spots = images->cpeaks; + int found = 0; - signed int ha, ka, la; + for ( hi=0; hin_cpeaks; hi++ ) { - if ( !spots[i].valid ) continue; - if ( spots[i].p < 0.1 ) continue; + double ic; + signed int ha, ka, la; - get_asymm(spots[i].h, spots[i].k, spots[i].l, - &ha, &ka, &la, sym); + if ( !spots[hi].valid ) continue; + if ( spots[hi].p < 0.1 ) continue; + get_asymm(spots[hi].h, spots[hi].k, spots[hi].l, + &ha, &ka, &la, sym); + if ( ha != hat ) continue; + if ( ka != kat ) continue; + if ( la != lat ) continue; - if ( ha != h ) continue; - if ( ka != k ) continue; - if ( la != l ) continue; + ic = spots[hi].intensity / spots[hi].p; - num1 += pow(image->osf, 2.0) * pow(spots[i].p, 2.0); - num2 += image->osf * spots[i].intensity * spots[i].p; - den += pow(image->osf, 2.0) * pow(spots[i].p, 2.0); + *sigma_GI += ic * image->osf; + found = 1; } + if ( found ) { + *sigma_Gsq += pow(image->osf, 2.0); + } } +} - /* "This frame" terms */ - image = &images[j]; - spots = image->cpeaks; - for ( i=0; in_cpeaks; i++ ) { - signed int ha, ka, la; +static double find_occurrances(struct image *image, const char *sym, + signed int h, signed int k, signed int l) +{ + double Ihl = 0.0; + int find; + struct cpeak *spots = image->cpeaks; - if ( !spots[i].valid ) continue; - if ( spots[i].p < 0.1 ) continue; + for ( find=0; findn_cpeaks; find++ ) { - get_asymm(spots[i].h, spots[i].k, spots[i].l, - &ha, &ka, &la, sym); + signed int ha, ka, la; + if ( !spots[find].valid ) continue; + if ( spots[find].p < 0.1 ) continue; + get_asymm(spots[find].h, spots[find].k, + spots[find].l, &ha, &ka, &la, sym); if ( ha != h ) continue; if ( ka != k ) continue; if ( la != l ) continue; - num1_this += spots[i].intensity * spots[i].p; - num2_this += pow(spots[i].p, 2.0); + Ihl += spots[find].intensity / spots[find].p; } - return (num1*num1_this - num2*num2_this) / den; + return Ihl; } -static double iterate_scale(struct image *images, int n, const char *sym, - double *I_full_old) +static double iterate_scale(struct image *images, int n, + ReflItemList *obs, const char *sym) { gsl_matrix *M; gsl_vector *v; gsl_vector *shifts; - int m; + int l; double max_shift; int crossed = 0; + int n_ref; M = gsl_matrix_calloc(n-1, n-1); v = gsl_vector_calloc(n-1); + n_ref = num_items(obs); - for ( m=0; mcpeaks; + struct image *imagel = &images[l]; - if ( m == crossed ) continue; + if ( l == crossed ) continue; /* Determine the "solution" vector component */ - for ( h=0; hn_cpeaks; h++ ) { + for ( h=0; hh, it->k, it->l, + &sigma_GI, &sigma_Gsq); - get_asymm(spots[h].h, spots[h].k, spots[h].l, - &ha, &ka, &la, sym); - ic = lookup_intensity(I_full_old, ha, ka, la); + /* Add up symmetric equivalents within the pattern */ + Ihl = find_occurrances(imagel, sym, + it->h, it->k, it->l); - v_c = ip - (spots[h].p * image->osf * ic); - v_c *= pow(spots[h].p, 2.0); - v_c *= pow(image->osf, 2.0); - v_c *= ic; - v_c *= gradient(m, ha, ka, la, images, n, sym); - vc_tot += v_c; + vc = Ihl * sigma_GI / sigma_Gsq; + vc -= imagel->osf * pow(sigma_GI, 2.0) / sigma_Gsq; + + vc_tot += vc; } - mcomp = m; - if ( m > crossed ) mcomp--; - gsl_vector_set(v, mcomp, vc_tot); + lcomp = l; + if ( l > crossed ) lcomp--; + gsl_vector_set(v, lcomp, vc_tot); /* Now fill in the matrix components */ - for ( k=0; kn_cpeaks; h++ ) { + for ( h=0; hh, it->k, it->l, + &sigma_GI, &sigma_Gsq); - get_asymm(spots[h].h, spots[h].k, spots[h].l, - &ha, &ka, &la, sym); - ic = lookup_intensity(I_full_old, ha, ka, la); + if ( l == m ) { + mc += pow(sigma_GI, 2.0) + / pow(sigma_Gsq, 2.0); + } + + Ihl = find_occurrances(imagel, sym, + it->h, it->k, it->l); + Ihm = find_occurrances(imagem, sym, + it->h, it->k, it->l); - con = -pow(spots[h].p, 3.0); - con *= pow(image->osf, 3.0); - con *= ic; - con *= gradient(m, ha, ka, la, images, n, sym); - con *= gradient(k, ha, ka, la, images, n, sym); - val += con; + mc += Ihl * Ihm / sigma_Gsq; + + mc += (sigma_GI / pow(sigma_Gsq, 2.0) ) + * ( imagel->osf*Ihm + imagem->osf * Ihl); + + mc_tot += mc; } - kcomp = k; - if ( k > crossed ) kcomp--; - gsl_matrix_set(M, mcomp, kcomp, val); + mcomp = m; + if ( m > crossed ) mcomp--; + gsl_matrix_set(M, lcomp, mcomp, mc_tot); } @@ -205,17 +216,19 @@ static double iterate_scale(struct image *images, int n, const char *sym, shifts = gsl_vector_alloc(n-1); gsl_linalg_HH_solve(M, v, shifts); max_shift = 0.0; - for ( m=0; m= crossed ) mimg++; + limg = l; + if ( limg >= crossed ) limg++; - images[mimg].osf += shift; + images[limg].osf += shift; - if ( shift > max_shift ) max_shift = shift; + if ( fabs(shift) > fabs(max_shift) ) { + max_shift = fabs(shift); + } } gsl_vector_free(shifts); @@ -227,8 +240,8 @@ static double iterate_scale(struct image *images, int n, const char *sym, } -static double *lsq_intensities(struct image *images, int n, const char *sym, - ReflItemList *obs) +static double *lsq_intensities(struct image *images, int n, + ReflItemList *obs, const char *sym) { double *I_full; int i; @@ -287,6 +300,23 @@ static double *lsq_intensities(struct image *images, int n, const char *sym, } +static void normalise_osfs(struct image *images, int n) +{ + int m; + double tot = 0.0; + double mean; + + for ( m=0; m 0.01) && (i < MAX_CYCLES) ); - } while ( (max_shift > 0.1) && (i < MAX_CYCLES) ); + for ( m=0; m