diff options
Diffstat (limited to 'libcrystfel/src')
-rw-r--r-- | libcrystfel/src/fom.c | 612 | ||||
-rw-r--r-- | libcrystfel/src/fom.h | 89 |
2 files changed, 557 insertions, 144 deletions
diff --git a/libcrystfel/src/fom.c b/libcrystfel/src/fom.c index 19f35a86..c2de704a 100644 --- a/libcrystfel/src/fom.c +++ b/libcrystfel/src/fom.c @@ -43,6 +43,33 @@ #include "reflist.h" #include "reflist-utils.h" +struct fom_context +{ + enum fom_type fom; + int nshells; + int *cts; + + /* For R-factors */ + double *num; + double *den; + + /* For "double" R-factors */ + double *num2; + double *den2; + + /* For CCs */ + double **vec1; + double **vec2; + int *n; + int nmax; + + /* For "counting" things e.g. d1sig or d2sig */ + int *n_within; + + long int *n_meas; + long int *possible; +}; + enum fom_type fom_type_from_string(const char *s) { if ( strcasecmp(s, "r1i") == 0 ) return FOM_R1I; @@ -78,6 +105,12 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) fctx->cts[i] = 0; } + fctx->num = NULL; + fctx->den = NULL; + fctx->num2 = NULL; + fctx->den2 = NULL; + fctx->possible = NULL; + switch ( fctx->fom ) { case FOM_RANORSPLIT : @@ -95,6 +128,10 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_R2 : case FOM_RSPLIT : case FOM_RANO : + case FOM_MEAN_INTENSITY : + case FOM_STDDEV_INTENSITY : + case FOM_SNR : + case FOM_REDUNDANCY : fctx->num = malloc(nshells*sizeof(double)); fctx->den = malloc(nshells*sizeof(double)); if ( (fctx->num == NULL) || (fctx->den == NULL) ) return NULL; @@ -104,6 +141,15 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) } break; + case FOM_COMPLETENESS : + /* Uses 'cts' and 'possible' only */ + break; + + case FOM_NUM_MEASUREMENTS : + fctx->n_meas = calloc(nshells, sizeof(long int)); + if ( fctx->n_meas == NULL ) return NULL; + break; + case FOM_CC : case FOM_CCSTAR : case FOM_CCANO : @@ -140,37 +186,45 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) } -static void add_to_fom(struct fom_context *fctx, double i1, double i2, - double i1bij, double i2bij, double sig1, double sig2, - int bin) +static int add_to_fom(struct fom_context *fctx, + Reflection *refl1, + Reflection *refl2, + Reflection *refl1bij, + Reflection *refl2bij, + int bin) { - double f1, f2; + double i1, i2, i1bij, i2bij, sig1, sig2; double im, imbij; + int bad = 0; fctx->cts[bin]++; - /* Negative intensities have already been weeded out. */ - f1 = sqrt(i1); - f2 = sqrt(i2); - switch ( fctx->fom ) { case FOM_R1I : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); fctx->num[bin] += fabs(i1 - i2); fctx->den[bin] += i1; break; case FOM_R1F : - fctx->num[bin] += fabs(f1 - f2); - fctx->den[bin] += f1; + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); + fctx->num[bin] += fabs(sqrt(i1) - sqrt(i2)); + fctx->den[bin] += sqrt(i1); break; case FOM_R2 : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); fctx->num[bin] += pow(i1 - i2, 2.0); fctx->den[bin] += pow(i1, 2.0); break; case FOM_RSPLIT : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); fctx->num[bin] += fabs(i1 - i2); fctx->den[bin] += i1 + i2; break; @@ -178,6 +232,8 @@ static void add_to_fom(struct fom_context *fctx, double i1, double i2, case FOM_CC : case FOM_CCSTAR : assert(fctx->n[bin] < fctx->nmax); + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); fctx->vec1[bin][fctx->n[bin]] = i1; fctx->vec2[bin][fctx->n[bin]] = i2; fctx->n[bin]++; @@ -186,17 +242,27 @@ static void add_to_fom(struct fom_context *fctx, double i1, double i2, case FOM_CCANO : case FOM_CRDANO : assert(fctx->n[bin] < fctx->nmax); + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); + i1bij = get_intensity(refl1bij); + i2bij = get_intensity(refl2bij); fctx->vec1[bin][fctx->n[bin]] = i1 - i1bij; fctx->vec2[bin][fctx->n[bin]] = i2 - i2bij; fctx->n[bin]++; break; case FOM_RANORSPLIT : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); fctx->num2[bin] += fabs(i1 - i2); fctx->den2[bin] += i1 + i2; /* Intentional fall-through (no break) */ case FOM_RANO : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); + i1bij = get_intensity(refl1bij); + i2bij = get_intensity(refl2bij); im = (i1 + i2)/2.0; imbij = (i1bij + i2bij)/2.0; fctx->num[bin] += fabs(im - imbij); @@ -204,22 +270,69 @@ static void add_to_fom(struct fom_context *fctx, double i1, double i2, break; case FOM_D1SIG : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); + sig1 = get_esd_intensity(refl1); + sig2 = get_esd_intensity(refl2); if ( fabs(i1-i2) < sqrt(sig1*sig1 + sig2*sig2) ) { fctx->n_within[bin]++; } break; case FOM_D2SIG : + i1 = get_intensity(refl1); + i2 = get_intensity(refl2); + sig1 = get_esd_intensity(refl1); + sig2 = get_esd_intensity(refl2); if ( fabs(i1-i2) < 2.0*sqrt(sig1*sig1 + sig2*sig2) ) { fctx->n_within[bin]++; } break; + case FOM_NUM_MEASUREMENTS : + fctx->n_meas[bin] += get_redundancy(refl1); + break; + + case FOM_REDUNDANCY : + fctx->num[bin] += get_redundancy(refl1); + fctx->den[bin] += 1.0; + break; + + case FOM_SNR : + i1 = get_intensity(refl1); + sig1 = get_esd_intensity(refl1); + if ( isfinite(i1/sig1) ) { + fctx->num[bin] += i1/sig1; + fctx->den[bin] += 1.0; + } else { + bad = 1; + } + break; + + case FOM_MEAN_INTENSITY : + i1 = get_intensity(refl1); + fctx->num[bin] += i1; + fctx->den[bin] += 1.0; + break; + + /* FIXME: Delete this FoM? */ + case FOM_STDDEV_INTENSITY : + fctx->num[bin] += 1.0; + fctx->den[bin] += 1.0; + break; + + case FOM_COMPLETENESS : + /* fctx->cts already incremented, as needed. + * Will calculate possible reflections later */ + break; + } + + return bad; } -double fom_overall(struct fom_context *fctx) +double fom_overall_value(struct fom_context *fctx) { double overall_num = INFINITY; double overall_den = 0.0; @@ -234,6 +347,9 @@ double fom_overall(struct fom_context *fctx) double variance_signal; double variance_error; double cc = INFINITY; + long int total_meas = 0; + long int overall_cts = 0; + long int overall_possible = 0; switch ( fctx->fom ) { @@ -242,6 +358,10 @@ double fom_overall(struct fom_context *fctx) case FOM_R2 : case FOM_RSPLIT : case FOM_RANO : + case FOM_REDUNDANCY : + case FOM_SNR : + case FOM_MEAN_INTENSITY : + case FOM_STDDEV_INTENSITY : overall_num = 0.0; overall_den = 0.0; for ( i=0; i<fctx->nshells; i++ ) { @@ -321,14 +441,38 @@ double fom_overall(struct fom_context *fctx) } break; + case FOM_NUM_MEASUREMENTS : + total_meas = 0; + for ( i=0; i<fctx->nshells; i++ ) { + total_meas += fctx->n_meas[i]; + } + break; + + case FOM_COMPLETENESS : + for ( i=0; i<fctx->nshells; i++ ) { + overall_cts += fctx->cts[i]; + overall_possible += fctx->possible[i]; + } + break; + } switch ( fctx->fom ) { case FOM_R1I : case FOM_R1F : + case FOM_REDUNDANCY : + case FOM_SNR : + case FOM_MEAN_INTENSITY : + case FOM_STDDEV_INTENSITY : return overall_num/overall_den; + case FOM_COMPLETENESS : + return (double)overall_cts / overall_possible; + + case FOM_NUM_MEASUREMENTS : + return total_meas; + case FOM_R2 : return sqrt(overall_num/overall_den); @@ -361,7 +505,7 @@ double fom_overall(struct fom_context *fctx) } -double fom_shell(struct fom_context *fctx, int i) +double fom_shell_value(struct fom_context *fctx, int i) { double cc; int j; @@ -374,6 +518,10 @@ double fom_shell(struct fom_context *fctx, int i) case FOM_R1I : case FOM_R1F : + case FOM_REDUNDANCY : + case FOM_SNR : + case FOM_MEAN_INTENSITY : + case FOM_STDDEV_INTENSITY : return fctx->num[i]/fctx->den[i]; case FOM_R2 : @@ -420,6 +568,12 @@ double fom_shell(struct fom_context *fctx, int i) case FOM_D2SIG : return (double)fctx->n_within[i] / fctx->cts[i]; + case FOM_NUM_MEASUREMENTS : + return fctx->n_meas[i]; + + case FOM_COMPLETENESS : + return (double)fctx->cts[i] / fctx->possible[i]; + } ERROR("This point is never reached.\n"); @@ -469,7 +623,7 @@ struct fom_shells *fom_make_resolution_shells(double rmin, double rmax, } -double fom_shell_label(struct fom_shells *s, int i) +double fom_shell_centre(struct fom_shells *s, int i) { return s->rmins[i] + (s->rmaxs[i] - s->rmins[i])/2.0; } @@ -605,15 +759,143 @@ static int wilson_scale(RefList *list1, RefList *list2, UnitCell *cell) } +static int calculate_possible(struct fom_context *fctx, + struct fom_shells *shells, + UnitCell *cell, + const SymOpList *sym) +{ + RefList *counted; + int hmax, kmax, lmax; + double ax, ay, az; + double bx, by, bz; + double cx, cy, cz; + signed int h, k, l; + + fctx->possible = calloc(fctx->nshells, sizeof(long int)); + if ( fctx->possible == NULL ) return 1; + + counted = reflist_new(); + if ( counted == NULL ) { + free(fctx->possible); + return 1; + } + + cell_get_cartesian(cell, &ax, &ay, &az, + &bx, &by, &bz, + &cx, &cy, &cz); + hmax = shells->rmaxs[fctx->nshells-1] * modulus(ax, ay, az); + kmax = shells->rmaxs[fctx->nshells-1] * modulus(bx, by, bz); + lmax = shells->rmaxs[fctx->nshells-1] * modulus(cx, cy, cz); + for ( h=-hmax; h<=hmax; h++ ) { + for ( k=-kmax; k<=kmax; k++ ) { + for ( l=-lmax; l<=lmax; l++ ) { + + double d; + signed int hs, ks, ls; + int bin; + int i; + + get_asymm(sym, h, k, l, &hs, &ks, &ls); + d = 2.0 * resolution(cell, hs, ks, ls); + + if ( forbidden_reflection(cell, h, k, l) ) continue; + + bin = -1; + for ( i=0; i<fctx->nshells; i++ ) { + if ( (d>shells->rmins[i]) && (d<=shells->rmaxs[i]) ) { + bin = i; + break; + } + } + if ( bin == -1 ) continue; + + if ( find_refl(counted, hs, ks, ls) != NULL ) continue; + add_refl(counted, hs, ks, ls); + + fctx->possible[bin]++; + + } + } + } + reflist_free(counted); + + return 0; +} + + +static int is_anomalous(enum fom_type fom) +{ + switch ( fom ) { + + case FOM_CCANO: + case FOM_RANO: + case FOM_CRDANO: + case FOM_RANORSPLIT: + return 1; + + case FOM_R1I: + case FOM_R1F: + case FOM_R2: + case FOM_RSPLIT: + case FOM_CC: + case FOM_CCSTAR: + case FOM_D1SIG: + case FOM_D2SIG: + case FOM_NUM_MEASUREMENTS: + case FOM_REDUNDANCY: + case FOM_SNR: + case FOM_MEAN_INTENSITY: + case FOM_STDDEV_INTENSITY: + case FOM_COMPLETENESS: + return 0; + } + + ERROR("This point never reached\n"); + abort(); +} + + +static int is_single_list(enum fom_type fom) +{ + switch ( fom ) { + + case FOM_CCANO: + case FOM_RANO: + case FOM_CRDANO: + case FOM_RANORSPLIT: + case FOM_R1I: + case FOM_R1F: + case FOM_R2: + case FOM_RSPLIT: + case FOM_CC: + case FOM_CCSTAR: + case FOM_D1SIG: + case FOM_D2SIG: + return 0; + + case FOM_NUM_MEASUREMENTS: + case FOM_REDUNDANCY: + case FOM_SNR: + case FOM_MEAN_INTENSITY: + case FOM_STDDEV_INTENSITY: + case FOM_COMPLETENESS: + return 1; + } + + ERROR("This point never reached\n"); + abort(); +} + struct fom_context *fom_calculate(RefList *list1, RefList *list2, UnitCell *cell, struct fom_shells *shells, enum fom_type fom, - int noscale, SymOpList *sym) + int noscale, const SymOpList *sym) { Reflection *refl1; RefListIterator *iter; struct fom_context *fctx; - int n_out; + long int n_out = 0; + long int n_rej = 0; fctx = init_fom(fom, num_reflections(list1), shells->nshells); @@ -622,40 +904,44 @@ struct fom_context *fom_calculate(RefList *list1, RefList *list2, UnitCell *cell return NULL; } - if ( !noscale && wilson_scale(list1, list2, cell) ) { - ERROR("Error with scaling.\n"); - return NULL; - } + if ( !is_single_list(fom) ) { + if ( !noscale && wilson_scale(list1, list2, cell) ) { + ERROR("Error with scaling.\n"); + return NULL; + } - for ( refl1 = first_refl(list1, &iter); - refl1 != NULL; - refl1 = next_refl(refl1, iter) ) - { - Reflection *refl2; - signed int h, k, l; - set_flag(refl1, 0); - get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - assert(refl2 != NULL); - set_flag(refl2, 0); + for ( refl1 = first_refl(list1, &iter); + refl1 != NULL; + refl1 = next_refl(refl1, iter) ) + { + Reflection *refl2; + signed int h, k, l; + set_flag(refl1, 0); + get_indices(refl1, &h, &k, &l); + refl2 = find_refl(list2, h, k, l); + assert(refl2 != NULL); + set_flag(refl2, 0); + } } - n_out = 0; for ( refl1 = first_refl(list1, &iter); refl1 != NULL; refl1 = next_refl(refl1, iter) ) { signed int h, k, l; int bin; - double i1, i2; - double i1bij, i2bij; - double sig1, sig2; Reflection *refl2; + Reflection *refl1_bij = NULL; + Reflection *refl2_bij = NULL; get_indices(refl1, &h, &k, &l); - refl2 = find_refl(list2, h, k, l); - if ( refl2 == NULL ) continue; + if ( is_single_list(fom) ) { + refl2 = NULL; + } else { + refl2 = find_refl(list2, h, k, l); + if ( refl2 == NULL ) continue; + } bin = get_bin(shells, refl1, cell); if ( bin == -1 ) { @@ -663,17 +949,8 @@ struct fom_context *fom_calculate(RefList *list1, RefList *list2, UnitCell *cell continue; } - i1 = get_intensity(refl1); - i2 = get_intensity(refl2); - sig1 = get_esd_intensity(refl1); - sig2 = get_esd_intensity(refl2); + if ( is_anomalous(fom) ) { - if ( (fom == FOM_CCANO) || (fom == FOM_CRDANO) - || (fom == FOM_RANO) || (fom == FOM_RANORSPLIT) ) - { - - Reflection *refl1_bij = NULL; - Reflection *refl2_bij = NULL; signed int hb, kb, lb; if ( find_equiv_in_list(list1, -h, -k, -l, sym, @@ -700,46 +977,59 @@ struct fom_context *fom_calculate(RefList *list1, RefList *list2, UnitCell *cell assert(refl1_bij != NULL); assert(refl2_bij != NULL); - i1bij = get_intensity(refl1_bij); - i2bij = get_intensity(refl2_bij); - - } else { - - /* Make it obvious if these get used by mistake */ - i1bij = +INFINITY; - i2bij = +INFINITY; - } - add_to_fom(fctx, i1, i2, i1bij, i2bij, sig1, sig2, bin); + n_rej += add_to_fom(fctx, refl1, refl2, refl1_bij, refl2_bij, bin); + } - if ( n_out) { + if ( n_out ) { ERROR("WARNING: %i reflection pairs outside range.\n", n_out); } + if ( n_rej ) { + if ( fom == FOM_SNR ) { + ERROR("WARNING: %li reflections had infinite or " + "invalid values of I/sigma(I).\n", n_rej); + } else { + ERROR("WARNING: %li reflections rejected by add_to_fom\n", + n_rej); + } + } + + if ( fom == FOM_COMPLETENESS ) { + calculate_possible(fctx, shells, cell, sym); + } return fctx; } -int fom_select_reflections(RefList *list1, RefList *list2, - RefList *list1_acc, RefList *list2_acc, - UnitCell *cell, SymOpList *sym, - int anom, double rmin_fix, double rmax_fix, - double sigma_cutoff, int ignore_negs, - int zero_negs, int mul_cutoff) +struct fom_rejections fom_select_reflection_pairs(RefList *list1, RefList *list2, + RefList **plist1_acc, + RefList **plist2_acc, + UnitCell *cell, SymOpList *sym, + int anom, double rmin_fix, double rmax_fix, + double sigma_cutoff, int ignore_negs, + int zero_negs, int mul_cutoff) { Reflection *refl1; RefListIterator *iter; - int ncom, nrej, nmul, nneg, nres, nbij, ncen; - - /* Select reflections to be used */ - ncom = 0; - nrej = 0; - nmul = 0; - nneg = 0; - nres = 0; - nbij = 0; - ncen = 0; + struct fom_rejections rej; + RefList *list1_acc; + RefList *list2_acc; + + rej.common = 0; + rej.low_snr = 0; + rej.negative_deleted = 0; + rej.negative_zeroed = 0; + rej.few_measurements = 0; + rej.outside_resolution_range = 0; + rej.no_bijvoet = 0; + rej.centric = 0; + rej.nan_inf_value = 0; + + list1_acc = reflist_new(); + list2_acc = reflist_new(); + for ( refl1 = first_refl(list1, &iter); refl1 != NULL; refl1 = next_refl(refl1, iter) ) @@ -766,20 +1056,27 @@ int fom_select_reflections(RefList *list1, RefList *list2, mul1 = get_redundancy(refl1); mul2 = get_redundancy(refl2); + if ( !isfinite(val1) || !isfinite(val2) + || !isfinite(esd1) || !isfinite(esd2) ) + { + rej.nan_inf_value++; + continue; + } + if ( (val1 < sigma_cutoff * esd1) || (val2 < sigma_cutoff * esd2) ) { - nrej++; + rej.low_snr++; continue; } if ( ignore_negs && ((val1 < 0.0) || (val2 < 0.0)) ) { - nneg++; + rej.negative_deleted++; continue; } if ( (mul1 < mul_cutoff) || (mul2 < mul_cutoff) ) { - nmul++; + rej.few_measurements++; continue; } @@ -793,13 +1090,14 @@ int fom_select_reflections(RefList *list1, RefList *list2, val2 = 0.0; d = 1; } - if ( d ) nneg++; + if ( d ) rej.negative_zeroed++; + continue; } if ( rmin_fix > 0.0 ) { double res = 2.0*resolution(cell, h, k, l); if ( res < rmin_fix ) { - nres++; + rej.outside_resolution_range++; continue; } } @@ -807,7 +1105,7 @@ int fom_select_reflections(RefList *list1, RefList *list2, if ( rmax_fix > 0.0 ) { double res = 2.0*resolution(cell, h, k, l); if ( res > rmax_fix ) { - nres++; + rej.outside_resolution_range++; continue; } } @@ -820,7 +1118,7 @@ int fom_select_reflections(RefList *list1, RefList *list2, copy_data(refl2_acc, refl2); set_intensity(refl2_acc, val2); - ncom++; + rej.common++; } @@ -833,7 +1131,7 @@ int fom_select_reflections(RefList *list1, RefList *list2, list1_acc = reflist_new(); list2_acc = reflist_new(); - ncom = 0; + rej.common = 0; for ( refl1 = first_refl(list1, &iter); refl1 != NULL; @@ -857,7 +1155,7 @@ int fom_select_reflections(RefList *list1, RefList *list2, val2 = get_intensity(refl2); if ( is_centric(h, k, l, sym) ) { - ncen++; + rej.centric++; continue; } @@ -874,7 +1172,7 @@ int fom_select_reflections(RefList *list1, RefList *list2, } if ( (refl1_bij == NULL) || (refl2_bij == NULL) ) { - nbij++; + rej.no_bijvoet++; continue; } @@ -886,44 +1184,138 @@ int fom_select_reflections(RefList *list1, RefList *list2, copy_data(refl2_acc, refl2); set_intensity(refl2_acc, val2); - ncom++; + rej.common++; } } - if ( nrej > 0 ) { - STATUS("Discarded %i reflection pairs because either or both" - " versions had I/sigma(I) < %f.\n", nrej, sigma_cutoff); - } + *plist1_acc = list1_acc; + *plist2_acc = list2_acc; + return rej; +} - if ( ignore_negs && (nneg > 0) ) { - STATUS("Discarded %i reflection pairs because either or both" - " versions had negative intensities.\n", nneg); - } - if ( zero_negs && (nneg > 0) ) { - STATUS("For %i reflection pairs, either or both versions had" - " negative intensities which were set to zero.\n", nneg); - } +struct fom_rejections fom_select_reflections(RefList *raw_list, + RefList **plist_acc, + UnitCell *cell, SymOpList *sym, + double rmin_fix, double rmax_fix, + double sigma_cutoff, int ignore_negs, + int zero_negs, int mul_cutoff) +{ + RefList *list; + Reflection *refl; + RefListIterator *iter; + struct fom_rejections rej; - if ( nmul > 0 ) { - STATUS("%i reflection pairs rejected because either or both" - " versions had too few measurements.\n", nmul); - } + *plist_acc = NULL; + + rej.common = 0; + rej.low_snr = 0; + rej.negative_deleted = 0; + rej.negative_zeroed = 0; + rej.few_measurements = 0; + rej.outside_resolution_range = 0; + rej.no_bijvoet = 0; + rej.centric = 0; + rej.nan_inf_value = 0; + + list = reflist_new(); + if ( list == NULL ) return rej; + + for ( refl = first_refl(raw_list, &iter); + refl != NULL; + refl = next_refl(refl, iter) ) { + + signed int h, k, l; + double val, sig; + int ig = 0; + Reflection *new; + + get_indices(refl, &h, &k, &l); + + val = get_intensity(refl); + sig = get_esd_intensity(refl); + + if ( !isfinite(val) || !isfinite(sig) ) { + rej.nan_inf_value++; + continue; + } + + if ( val < sigma_cutoff * sig ) { + rej.low_snr++; + ig = 1; + } + + if ( ignore_negs && (val < 0.0) ) { + rej.negative_deleted++; + ig = 1; + } + + if ( zero_negs && (val < 0.0) ) { + set_intensity(refl, 0.0); + rej.negative_zeroed++; + } + + if ( rmin_fix > 0.0 ) { + double res = 2.0*resolution(cell, h, k, l); + if ( res < rmin_fix ) { + rej.outside_resolution_range++; + continue; + } + } - if ( nres > 0 ) { - STATUS("%i reflection pairs rejected because either or both" - " versions were outside the resolution range.\n", nres); + if ( rmax_fix > 0.0 ) { + double res = 2.0*resolution(cell, h, k, l); + if ( res > rmax_fix ) { + rej.outside_resolution_range++; + continue; + } + } + + if ( ig ) continue; + + new = add_refl(list, h, k, l); + copy_data(new, refl); } - if ( nbij > 0 ) { - STATUS("%i reflection pairs rejected because either or both" - " versions did not have Bijvoet partners.\n", nres); + *plist_acc = list; + return rej; +} + + +int fom_overall_num_reflections(struct fom_context *fctx) +{ + int i; + long int n = 0; + + for ( i=0; i<fctx->nshells; i++ ) { + n += fctx->cts[i]; } + return n; +} + - if ( ncen > 0 ) { - STATUS("%i reflection pairs rejected because they were" - " centric.\n", ncen); +int fom_shell_num_reflections(struct fom_context *fctx, int i) +{ + return fctx->cts[i]; +} + + +int fom_overall_num_possible(struct fom_context *fctx) +{ + int i; + long int n = 0; + + assert(fctx->fom == FOM_COMPLETENESS); + + for ( i=0; i<fctx->nshells; i++ ) { + n += fctx->possible[i]; } + return n; +} + - return ncom; +int fom_shell_num_possible(struct fom_context *fctx, int i) +{ + assert(fctx->fom == FOM_COMPLETENESS); + return fctx->possible[i]; } diff --git a/libcrystfel/src/fom.h b/libcrystfel/src/fom.h index d3373044..c9c8dbfe 100644 --- a/libcrystfel/src/fom.h +++ b/libcrystfel/src/fom.h @@ -38,6 +38,19 @@ #include <reflist.h> #include <symmetry.h> +struct fom_rejections +{ + int common; + int low_snr; + int negative_deleted; + int negative_zeroed; + int few_measurements; + int outside_resolution_range; + int no_bijvoet; + int centric; + int nan_inf_value; +}; + enum fom_type { FOM_R1I, @@ -51,7 +64,13 @@ enum fom_type FOM_RANO, FOM_RANORSPLIT, FOM_D1SIG, - FOM_D2SIG + FOM_D2SIG, + FOM_NUM_MEASUREMENTS, + FOM_REDUNDANCY, + FOM_SNR, + FOM_MEAN_INTENSITY, + FOM_STDDEV_INTENSITY, + FOM_COMPLETENESS, }; struct fom_shells @@ -61,51 +80,53 @@ struct fom_shells double *rmaxs; }; -struct fom_context -{ - enum fom_type fom; - int nshells; - int *cts; - - /* For R-factors */ - double *num; - double *den; +struct fom_context; + +extern struct fom_rejections fom_select_reflection_pairs(RefList *list1, + RefList *list2, + RefList **plist1_acc, + RefList **plist2_acc, + UnitCell *cell, + SymOpList *sym, + int anom, + double rmin_fix, + double rmax_fix, + double sigma_cutoff, + int ignore_negs, + int zero_negs, + int mul_cutoff); + +extern struct fom_rejections fom_select_reflections(RefList *list, + RefList **plist_acc, + UnitCell *cell, + SymOpList *sym, + double rmin_fix, + double rmax_fix, + double sigma_cutoff, + int ignore_negs, + int zero_negs, + int mul_cutoff); - /* For "double" R-factors */ - double *num2; - double *den2; - - /* For CCs */ - double **vec1; - double **vec2; - int *n; - int nmax; - - /* For "counting" things e.g. d1sig or d2sig */ - int *n_within; -}; - -extern int fom_select_reflections(RefList *list1, RefList *list2, - RefList *list1_acc, RefList *list2_acc, - UnitCell *cell, SymOpList *sym, - int anom, double rmin_fix, double rmax_fix, - double sigma_cutoff, int ignore_negs, - int zero_negs, int mul_cutoff); extern struct fom_context *fom_calculate(RefList *list1, RefList *list2, UnitCell *cell, struct fom_shells *shells, enum fom_type fom, int noscale, - SymOpList *sym); + const SymOpList *sym); extern struct fom_shells *fom_make_resolution_shells(double rmin, double rmax, int nshells); -extern double fom_shell_label(struct fom_shells *s, int i); +extern double fom_shell_centre(struct fom_shells *s, int i); + +extern double fom_overall_value(struct fom_context *fctx); +extern double fom_shell_value(struct fom_context *fctx, int i); -extern double fom_shell(struct fom_context *fctx, int i); +extern int fom_overall_num_reflections(struct fom_context *fctx); +extern int fom_shell_num_reflections(struct fom_context *fctx, int i); -extern double fom_overall(struct fom_context *fctx); +extern int fom_overall_num_possible(struct fom_context *fctx); +extern int fom_shell_num_possible(struct fom_context *fctx, int i); extern enum fom_type fom_type_from_string(const char *s); |