/* * rejection.c * * Crystal rejection for scaling * * Copyright © 2012-2018 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: * 2010-2018 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; icontrib_crystals[0]), h, k, l); /* Mean of contributions */ for ( j=0; jn_contrib; j++ ) { double Ii, G, B; G = crystal_get_osf(c->contrib_crystals[j]); B = crystal_get_Bfac(c->contrib_crystals[j]); Ii = get_intensity(c->contribs[j]); /* Total (multiplicative) correction factor */ Ii *= 1.0/G * exp(B*res*res) * get_lorentz(c->contribs[j]) / get_partiality(c->contribs[j]); Ex += Ii - K; Ex2 += (Ii - K) * (Ii - K); } if ( c->n_contrib < 2 ) continue; set_temp1(refl, Ex); set_temp2(refl, Ex2); } } static double calculate_cchalf(RefList *template, RefList *full, Crystal *exclude, int *pnref) { Reflection *trefl; RefListIterator *iter; double sig2E, sig2Y; int n = 0; double wSum = 0.0; double wSum2 = 0.0; double mean = 0.0; double S = 0.0; double all_sum_var = 0.0; signed int oh = 0; signed int ok = 0; signed int ol = 0; /* "template" is the list of reflections to be included in CChalf */ for ( trefl = first_refl(template, &iter); trefl != NULL; trefl = next_refl(trefl, iter) ) { signed int h, k, l; double refl_mean, refl_var; double Ex, Ex2, K; int n_removed = 0; double w = 1.0; double meanOld; double res; struct reflection_contributions *c; Reflection *refl; /* The values we need are stored in the "full" list, not the * template list */ get_indices(trefl, &h, &k, &l); if ( (h==oh) && (k==ok) && (l==ol) ) continue; oh = h; ok = k; ol = l; refl = find_refl(full, h, k, l); if ( refl == NULL ) continue; /* However, there might not have * been enough measurements for * it to appear in "full" */ /* We use the mean (merged) intensity as the reference point * for shifting the data in the variance calculation */ K = get_intensity(refl); Ex = get_temp1(refl); Ex2 = get_temp2(refl); c = get_contributions(refl); assert(c != NULL); /* Resolution from first contributing crystal, like above */ res = resolution(crystal_get_cell(c->contrib_crystals[0]), h, k, l); /* Remove contribution(s) from the excluded crystal */ if ( exclude != NULL ) { refl = find_refl(crystal_get_reflections(exclude), h, k, l); } else { refl = NULL; } while ( refl != NULL ) { double G, B; double Ii = get_intensity(refl); G = crystal_get_osf(exclude); B = crystal_get_Bfac(exclude); /* Total (multiplicative) correction factor */ Ii *= 1.0/G * exp(B*res*res) * get_lorentz(refl) / get_partiality(refl); /* Remove contribution of this reflection */ Ex -= Ii - K; Ex2 -= (Ii - K)*(Ii - K); n_removed++; refl = next_found_refl(refl); } if ( c->n_contrib - n_removed < 2 ) continue; refl_mean = K + (Ex / (c->n_contrib - n_removed)); refl_var = (Ex2 - (Ex*Ex)/(c->n_contrib - n_removed)) / (c->n_contrib - n_removed - 1); refl_var /= (c->n_contrib - n_removed) / 2.0; all_sum_var += refl_var; n++; /* Running variance calculation to get sig2Y */ wSum += w; wSum2 += w*w; meanOld = mean; mean = meanOld + (w/wSum) * (refl_mean - meanOld); S += w * (refl_mean - meanOld) * (refl_mean - mean); } sig2E = all_sum_var / n; sig2Y = S / (wSum - 1.0); if ( pnref != NULL ) { *pnref = n; } return (sig2Y - 0.5*sig2E) / (sig2Y + 0.5*sig2E); } static void check_deltacchalf(Crystal **crystals, int n, RefList *full) { double cchalf; int i; double *vals; double mean, sd; int nref = 0; calculate_refl_mean_var(full); cchalf = calculate_cchalf(full, full, NULL, &nref); STATUS("Overall CChalf = %f %% (%i reflections)\n", cchalf*100.0, nref); vals = malloc(n*sizeof(double)); if ( vals == NULL ) { ERROR("Not enough memory for deltaCChalf check\n"); return; } 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); } }