/* * hrs-scaling.c * * Intensity scaling using generalised HRS target function * * (c) 2006-2011 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "image.h" #include "peaks.h" #include "symmetry.h" #include "geometry.h" #include "cell.h" #include "utils.h" #include "reflist.h" /* Maximum number of iterations of NLSq scaling per macrocycle. */ #define MAX_CYCLES (50) static char *find_common_reflections(struct image *images, int n) { int i; char *cref; cref = calloc(n*n, sizeof(char)); for ( i=0; ireflections; 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); vval = gsl_vector_get(M, a); gsl_vector_set(M, a, vval+(pow(Ih, 2.0) * uha)); } } shifts = solve_diagonal(v, M); gsl_vector_free(M); gsl_vector_free(v); if ( shifts == NULL ) return 0.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); } } gsl_vector_free(shifts); return max_shift; } static void lsq_intensities(struct image *images, int n, RefList *full) { 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; mreflections, &iter); refl != NULL; refl = next_refl(refl, iter) ) { double G, p; signed int h, k, l; Reflection *full_version; double I_full, I_partial; if ( !get_scalable(refl) ) continue; get_indices(refl, &h, &k, &l); assert((h!=0) || (k!=0) || (l!=0)); full_version = find_refl(full, h, k, l); if ( full_version == NULL ) continue; /* Some reflections may have recently become scalable, but * scale_intensities() might not yet have been called, so the * full version may not have been calculated yet. */ G = image->osf; p = get_partiality(refl); I_partial = get_intensity(refl); I_full = get_intensity(full_version); //STATUS("%3i %3i %3i %5.2f %5.2f %5.2f %5.2f %5.2f\n", // h, k, l, G, p, I_partial, I_full, // I_partial - p*G*I_full); dev += pow(I_partial - p*G*I_full, 2.0); } return dev; } static UNUSED void plot_graph(struct image *image, RefList *reference) { double sc; for ( sc=0.0; sc<3.0; sc+=0.1 ) { image->osf = sc; STATUS("%5.2f: %e\n", sc, total_dev(image, reference)); } } static void scale_matrix(struct image *images, int n, RefList *scalable, RefList *reference) { int i, m; double max_shift; char *cref; /* Start with all scale factors equal */ for ( m=0; m 0.01) && (i < MAX_CYCLES) ); free(cref); } static void scale_megatron(struct image *images, int n, RefList *scalable) { int i, m; double max_shift; double *old_osfs; old_osfs = calloc(n, sizeof(double)); /* Start with all scale factors equal */ for ( m=0; m 0.01) && (i < MAX_CYCLES) ); } /* Scale the stack of images */ RefList *scale_intensities(struct image *images, int n, RefList *reference) { RefList *full; full = guess_scaled_reflections(images, n); if ( reference != NULL ) { scale_matrix(images, n, full, reference); } else { scale_megatron(images, n, full); } lsq_intensities(images, n, full); return full; }