/* * statistics.c * * Structure-factor statistics * * (c) 2006-2010 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "statistics.h" #include "utils.h" struct r_params { const double *ref1; const unsigned int *c1; const double *ref2; const unsigned int *c2; int fom; }; enum { R_2, R_MERGE, }; double stat_scale_intensity(const double *ref1, const unsigned int *c1, const double *ref2, const unsigned int *c2) { double top = 0.0; double bot = 0.0; int i; /* Start from i=1 -> skip central beam */ for ( i=1; i skip central beam */ for ( i=1; i skip central beam */ for ( i=1; i skip central beam */ for ( i=1; ifom) { case R_MERGE : return internal_rmerge(rp->ref1, rp->c1, rp->ref2, rp->c2, scale); case R_2 : return internal_r2(rp->ref1, rp->c1, rp->ref2, rp->c2, scale); } ERROR("No such FoM!\n"); abort(); } static double r_minimised(const double *ref1, const unsigned int *c1, const double *ref2, const unsigned int *c2, double *scalep, int fom) { gsl_function F; gsl_min_fminimizer *s; int status; double scale = 1.0; struct r_params rp; int iter = 0; rp.ref1 = ref1; rp.ref2 = ref2; rp.c1 = c1; rp.c2 = c2; rp.fom = fom; F.function = &calc_r; F.params = &rp; s = gsl_min_fminimizer_alloc(gsl_min_fminimizer_brent); /* Initial guess */ switch ( fom ) { case R_MERGE : scale = stat_scale_sqrti(ref1, c1, ref2, c2); break; case R_2 : scale = stat_scale_intensity(ref1, c1, ref2, c2); break; } //STATUS("Initial scale factor estimate: %5.2e\n", scale); /* Probably within an order of magnitude either side */ gsl_min_fminimizer_set(s, &F, scale, scale/10.0, scale*10.0); do { double lo, up; /* Iterate */ gsl_min_fminimizer_iterate(s); /* Get the current estimate */ scale = gsl_min_fminimizer_x_minimum(s); lo = gsl_min_fminimizer_x_lower(s); up = gsl_min_fminimizer_x_upper(s); /* Check for convergence */ status = gsl_min_test_interval(lo, up, 0.001, 0.0); iter++; } while ( status == GSL_CONTINUE ); if (status != GSL_SUCCESS) { ERROR("Scale factor minimisation failed.\n"); } gsl_min_fminimizer_free(s); //STATUS("Final scale factor: %5.2e\n", scale); *scalep = scale; return calc_r(scale, &rp); } double stat_rmerge(const double *ref1, const unsigned int *c1, const double *ref2, const unsigned int *c2, double *scalep) { return r_minimised(ref1, c1, ref2, c2, scalep, R_MERGE); } double stat_r2(const double *ref1, const unsigned int *c1, const double *ref2, const unsigned int *c2, double *scalep) { return r_minimised(ref1, c1, ref2, c2, scalep, R_2); } double stat_pearson(const double *ref1, const unsigned int *c1, const double *ref2, const unsigned int *c2) { double vec1[4096]; double vec2[4096]; signed int h, k, l; int i = 0; for ( l=-INDMAX; l0.0) && (i2>0.0) ) { vec1[i] = sqrt(i1 / (double)c1s); vec2[i] = sqrt(i2 / (double)c2s); i++; } } } } return gsl_stats_correlation(vec1, 1, vec2, 1, i); }