/* * rejection.c * * Crystal rejection for scaling * * Copyright © 2012-2015 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: * 2010-2015 Thomas White * * This file is part of CrystFEL. * * CrystFEL is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CrystFEL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CrystFEL. If not, see . * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "crystal.h" #include "reflist.h" #include "rejection.h" #include "cell-utils.h" #include "post-refinement.h" static double mean_intensity(RefList *list) { Reflection *refl; RefListIterator *iter; double total = 0.0; int n = 0; for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { total += get_intensity(refl); n++; } return total/n; } /* Reject really obvious outliers */ void early_rejection(Crystal **crystals, int n) { int i; double m = 0.0; double mean_m; FILE *fh = fopen("reject.dat", "w"); int n_flag = 0; for ( i=0; icontribs = realloc(c->contribs, c->max_contrib*sizeof(Reflection *)); c->contrib_crystals = realloc(c->contrib_crystals, c->max_contrib*sizeof(Crystal *)); if ( c->contribs == NULL ) return 1; if ( c->contrib_crystals == NULL ) return 1; return 0; } static void free_contributions(struct contributionlist *clist) { int i; for ( i=0; in; i++ ) { free(clist->contribs[i].contribs); free(clist->contribs[i].contrib_crystals); } free(clist->contribs); free(clist); } static struct contributionlist *find_all_contributions(Crystal **crystals, int n, RefList *full) { Reflection *refl; RefListIterator *iter; struct contributionlist *clist; int nc = 0; clist = malloc(sizeof(struct contributionlist)); if ( clist == NULL ) return NULL; clist->n = num_reflections(full); clist->contribs = malloc(clist->n*sizeof(struct contribs)); if ( clist->contribs == NULL ) { free(clist); return NULL; } for ( refl = first_refl(full, &iter); refl != NULL; refl = next_refl(refl, iter) ) { int i; signed int h, k, l; struct contribs *c; get_indices(refl, &h, &k, &l); c = &clist->contribs[nc++]; c->serial = SERIAL(h, k, l); c->n_contrib = 0; c->max_contrib = 32; c->contribs = NULL; c->contrib_crystals = NULL; if ( alloc_contribs(c) ) return NULL; /* Find all versions of this reflection */ for ( i=0; icontribs[c->n_contrib] = refl2; c->contrib_crystals[c->n_contrib] = crystals[i]; c->n_contrib++; if ( c->n_contrib == c->max_contrib ) { c->max_contrib += 64; if ( alloc_contribs(c) ) return NULL; } refl2 = next_found_refl(refl2); } while ( refl2 != NULL ); } progress_bar(nc, clist->n, "Collecting contributions"); } return clist; } static struct contribs *lookup_contribs(struct contributionlist *clist, signed int h, signed int k, signed int l) { int i, serial; serial = SERIAL(h, k, l); for ( i=0; in; i++ ) { if ( clist->contribs[i].serial == serial ) { return &clist->contribs[i]; } } return NULL; } static double calculate_cchalf(struct contributionlist *clist, Crystal *exclude) { int i; double all_sum_mean = 0.0; double all_sumsq_mean = 0.0; double all_sum_var = 0.0; double sig2E, sig2Y; /* Iterate over all reflections */ for ( i=0; in; i++ ) { struct contribs *c; int j; double refl_sum = 0.0; double refl_sumsq = 0.0; double refl_mean, refl_var; c = &clist->contribs[i]; for ( j=0; jn_contrib; j++ ) { double Ii; if ( c->contrib_crystals[j] == exclude ) { continue; } /* FIXME: Apply corrections */ Ii = get_intensity(c->contribs[j]); refl_sum += Ii; refl_sumsq += Ii * Ii; } refl_mean = refl_sum / c->n_contrib; refl_var = refl_sumsq - refl_sum*refl_sum; all_sum_mean += refl_mean; all_sumsq_mean += refl_mean*refl_mean; all_sum_var += refl_var; } sig2E = all_sum_var / clist->n; sig2Y = all_sumsq_mean - all_sum_mean*all_sum_mean; return (sig2Y - 0.5*sig2E) / (sig2Y + 0.5*sig2E); } static void check_deltacchalf(Crystal **crystals, int n, RefList *full) { struct contributionlist *clist; double cchalf; int i; clist = find_all_contributions(crystals, n, full); cchalf = calculate_cchalf(clist, NULL); STATUS("Overall CChalf = %f\n", cchalf); for ( i=0; i max_B ) { crystal_set_user_flag(crystals[i], PRFLAG_BIGB); } if ( crystal_get_user_flag(crystals[i]) == 0 ) n_acc++; } show_duds(crystals, n); if ( n_acc < 2 ) { ERROR("Not enough crystals left to proceed (%i). Sorry.\n", n_acc); exit(1); } }