From 623939fb6bd9475935546b9539f404eaaff41a3f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 11 Jul 2011 16:55:35 +0200 Subject: Use new Kabsch algorithm for faster scaling --- src/hrs-scaling.c | 444 +++++++++++++----------------------------------------- 1 file changed, 108 insertions(+), 336 deletions(-) (limited to 'src/hrs-scaling.c') diff --git a/src/hrs-scaling.c b/src/hrs-scaling.c index 45bbd591..cff0b90c 100644 --- a/src/hrs-scaling.c +++ b/src/hrs-scaling.c @@ -31,344 +31,142 @@ #include "reflist.h" -/* Maximum number of iterations of NLSq scaling per macrocycle. */ +/* Maximum number of iterations of scaling per macrocycle. */ #define MAX_CYCLES (50) +/* ESD of restraint driving scale factors to unity */ +#define SCALING_RESTRAINT (1.0) -static char *find_common_reflections(struct image *images, int n) + +static double iterate_scale(struct image *images, int n, RefList *reference) { - int i; - char *cref; + double max_shift = 0.0; + int frame; - cref = calloc(n*n, sizeof(char)); + assert(reference != NULL); - for ( i=0; ireflections, &iter); refl != NULL; - refl = next_refl(refl, iter) ) { - + refl = next_refl(refl, iter) ) + { signed int h, k, l; - int j; + double Ih, Ihl, esd; + Reflection *r; if ( !get_scalable(refl) ) continue; - get_indices(refl, &h, &k, &l); - - for ( j=0; jreflections; - Reflection *refl; - - for ( refl = find_refl(reflections, hat, kat, lat); - refl != NULL; - refl = next_found_refl(refl) ) - { - double ic, sigi; - - if ( !get_scalable(refl) ) continue; - - ic = get_intensity(refl) / get_partiality(refl); - - /* Get the error in the estimated full intensity */ - sigi = get_esd_intensity(refl) / get_partiality(refl); - - uha_val += 1.0 / pow(sigi, 2.0); - vha_val += ic / pow(sigi, 2.0); - } - - *uha = uha_val; - *vha = vha_val; -} - - -static void s_uhvh(struct image *images, int n, - signed int h, signed int k, signed int l, - double *uhp, double *vhp) -{ - int a; - double uh = 0.0; - double vh = 0.0; - - for ( a=0; asize; - if ( v->size != M->size ) return NULL; - - shifts = gsl_vector_alloc(n); - if ( shifts == NULL ) return NULL; - - for ( frame=0; frameosf * uha * Ih; - vc = Ih * rha; - vval = gsl_vector_get(v, a); - gsl_vector_set(v, a, vval+vc); + Ihl = get_intensity(refl) / get_partiality(refl); + esd = get_esd_intensity(refl) / get_partiality(refl); - vval = gsl_vector_get(M, a); - gsl_vector_set(M, a, vval+(pow(Ih, 2.0) * uha)); + num += Ih * (Ihl/image->osf) / pow(esd/image->osf, 2.0); + den += pow(Ih, 2.0)/pow(esd/image->osf, 2.0); } - } - - shifts = solve_diagonal(v, M); - gsl_vector_free(M); - gsl_vector_free(v); - if ( shifts == NULL ) return 0.0; + //num += image->osf / pow(SCALING_RESTRAINT, 2.0); + //den += pow(image->osf, 2.0)/pow(SCALING_RESTRAINT, 2.0); - /* Apply shifts */ - max_shift = 0.0; - for ( frame=0; frame %5.2f\n", - // frame, shift, images[frame].osf); - - if ( fabs(shift) > fabs(max_shift) ) { - max_shift = fabs(shift); + corr = num / den; + if ( !isnan(corr) && !isinf(corr) ) { + image->osf *= corr; } + if ( fabs(corr-1.0) > max_shift ) max_shift = fabs(corr-1.0); } - gsl_vector_free(shifts); - return max_shift; } -static void lsq_intensities(struct image *images, int n, RefList *full) +static RefList *lsq_intensities(struct image *images, int n) { + RefList *full; + int frame; Reflection *refl; RefListIterator *iter; - for ( refl = first_refl(full, &iter); - refl != NULL; - refl = next_refl(refl, iter) ) - { - double num = 0.0; - double den = 0.0; - int m; - int redundancy = 0; - signed int h, k, l; - - get_indices(refl, &h, &k, &l); - - /* For each frame */ - for ( m=0; m 0.01) && (i < MAX_CYCLES) ); - - free(cref); -} - - -static void scale_megatron(struct image *images, int n, RefList *scalable) +/* Scale the stack of images */ +RefList *scale_intensities(struct image *images, int n, RefList *gref) { - int i, m; - double max_shift; - double *old_osfs; - - old_osfs = calloc(n, sizeof(double)); + int i; + double max_corr; + RefList *full = NULL; - /* Start with all scale factors equal */ - for ( m=0; m create an initial list to refine against */ + if ( gref == NULL ) { + full = lsq_intensities(images, n); + } /* Iterate */ i = 0; do { - max_shift = iterate_scale(images, n, scalable, NULL, scalable); - STATUS("Scaling iteration %2i: max shift = %5.2f\n", - i+1, max_shift); - i++; + RefList *reference; - for ( m=0; m 0.01) && (i < MAX_CYCLES) ); -} + max_corr = iterate_scale(images, n, reference); + STATUS("Scaling iteration %2i: max correction = %5.2f\n", + i+1, max_corr); + /* No reference -> generate list for next iteration */ + if ( gref == NULL ) { + reflist_free(full); + full = lsq_intensities(images, n); + } -/* Scale the stack of images */ -RefList *scale_intensities(struct image *images, int n, RefList *reference) -{ - RefList *full; + //show_scale_factors(images, n); - full = guess_scaled_reflections(images, n); + i++; - if ( reference != NULL ) { - scale_matrix(images, n, full, reference); - } else { - scale_megatron(images, n, full); - } + } while ( (max_corr > 0.01) && (i < MAX_CYCLES) ); + + if ( gref != NULL ) { + full = lsq_intensities(images, n); + } /* else we already did it */ - lsq_intensities(images, n, full); return full; } -- cgit v1.2.3