static void scan_partialities(RefList *reflections, RefList *compare, int *valid, long double *vals[3], int idx, PartialityModel pmodel) { int i; Reflection *refl; RefListIterator *iter; i = 0; for ( refl = first_refl(reflections, &iter); refl != NULL; refl = next_refl(refl, iter) ) { signed int h, k, l; Reflection *refl2; double rlow, rhigh, p; get_indices(refl, &h, &k, &l); refl2 = find_refl(compare, h, k, l); if ( refl2 == NULL ) { valid[i] = 0; i++; continue; } get_partial(refl2, &rlow, &rhigh, &p); vals[idx][i] = p; if ( unlikely(p < 0.0) ) { ERROR("Negative partiality! %3i %3i %3i %f\n", h, k, l, p); } i++; } }
int get_bucket(DBC *cursorp, struct rec_key *k, struct rec_val *v) { int bucket_size_idx, key_level = -1; struct rec_key cur_k; for (bucket_size_idx = NBUCKETSIZES-1; bucket_size_idx >= 0; bucket_size_idx--) { /* find the start of the current bucket */ cur_k.stream_id = k->stream_id; cur_k.timestamp = k->timestamp - (k->timestamp % bucket_sizes[bucket_size_idx]); /* key query */ /* acquire write locks to avoid deadlock */ if (get_partial(cursorp, DB_SET | DB_RMW, &cur_k, v, sizeof(struct rec_val), 0) == 0) { if (cur_k.timestamp <= k->timestamp && cur_k.timestamp + v->period_length > k->timestamp) { *k = cur_k; return 1; } } else if (key_level == -1) { key_level = bucket_size_idx; } } if (key_level < 0) { warn("CONFUSED streamid: %u timestamp: %u\n", k->stream_id, k->timestamp); return 1; } debug("Should be in new bin; size idx %i\n", key_level); k->timestamp -= (k->timestamp % bucket_sizes[key_level]); return -key_level; }
/* Return the gradient of partiality wrt parameter 'k' given the current status * of 'image'. */ double p_gradient(Crystal *cr, int k, Reflection *refl, PartialityModel pmodel) { double glow, ghigh; double rlow, rhigh, p; struct image *image = crystal_get_image(cr); double R = crystal_get_profile_radius(cr); get_partial(refl, &rlow, &rhigh, &p); if ( k == GPARAM_R ) { double Rglow, Rghigh; double D, psph; D = rlow - rhigh; psph = volume_fraction(rlow, rhigh, R, pmodel); Rglow = volume_fraction_rgradient(rlow, R, pmodel); Rghigh = volume_fraction_rgradient(rhigh, R, pmodel); return 4.0*psph/(3.0*D) + (4.0*R/(3.0*D))*(Rglow - Rghigh); } /* Calculate the gradient of partiality wrt excitation error. */ glow = partiality_gradient(rlow, R, pmodel, rlow, rhigh); ghigh = partiality_gradient(rhigh, R, pmodel, rlow, rhigh); if ( k == GPARAM_DIV ) { double D, psph, ds; signed int hs, ks, ls; D = rlow - rhigh; psph = volume_fraction(rlow, rhigh, R, pmodel); get_symmetric_indices(refl, &hs, &ks, &ls); ds = 2.0 * resolution(crystal_get_cell(cr), hs, ks, ls); return (ds/2.0)*(glow+ghigh) - 4.0*R*psph*ds/(3.0*D*D); } return r_gradient(crystal_get_cell(cr), k, refl, image) * (glow-ghigh); }
static double test_gradients(Crystal *cr, double incr_val, int refine, const char *str, const char *file, PartialityModel pmodel, int quiet, int plot) { Reflection *refl; RefListIterator *iter; long double *vals[3]; int i; int *valid; int nref; int n_good, n_invalid, n_small, n_nan, n_bad; RefList *reflections; FILE *fh = NULL; int ntot = 0; double total = 0.0; char tmp[32]; double *vec1; double *vec2; int n_line; double cc; reflections = find_intersections(crystal_get_image(cr), cr, pmodel); crystal_set_reflections(cr, reflections); nref = num_reflections(reflections); if ( nref < 10 ) { ERROR("Too few reflections found. Failing test by default.\n"); return 0.0; } vals[0] = malloc(nref*sizeof(long double)); vals[1] = malloc(nref*sizeof(long double)); vals[2] = malloc(nref*sizeof(long double)); if ( (vals[0] == NULL) || (vals[1] == NULL) || (vals[2] == NULL) ) { ERROR("Couldn't allocate memory.\n"); return 0.0; } valid = malloc(nref*sizeof(int)); if ( valid == NULL ) { ERROR("Couldn't allocate memory.\n"); return 0.0; } for ( i=0; i<nref; i++ ) valid[i] = 1; scan_partialities(reflections, reflections, valid, vals, 1, pmodel); calc_either_side(cr, incr_val, valid, vals, refine, pmodel); if ( plot ) { snprintf(tmp, 32, "gradient-test-%s.dat", file); fh = fopen(tmp, "w"); } vec1 = malloc(nref*sizeof(double)); vec2 = malloc(nref*sizeof(double)); if ( (vec1 == NULL) || (vec2 == NULL) ) { ERROR("Couldn't allocate memory.\n"); return 0.0; } n_invalid = 0; n_good = 0; n_nan = 0; n_small = 0; n_bad = 0; n_line = 0; i = 0; for ( refl = first_refl(reflections, &iter); refl != NULL; refl = next_refl(refl, iter) ) { long double grad1, grad2, grad; double cgrad; signed int h, k, l; get_indices(refl, &h, &k, &l); if ( !valid[i] ) { n_invalid++; i++; } else { double r1, r2, p; grad1 = (vals[1][i] - vals[0][i]) / incr_val; grad2 = (vals[2][i] - vals[1][i]) / incr_val; grad = (grad1 + grad2) / 2.0; i++; cgrad = p_gradient(cr, refine, refl, pmodel); get_partial(refl, &r1, &r2, &p); if ( isnan(cgrad) ) { n_nan++; continue; } if ( plot ) { fprintf(fh, "%e %Le\n", cgrad, grad); } vec1[n_line] = cgrad; vec2[n_line] = grad; n_line++; if ( (fabs(cgrad) < 5e-8) && (fabs(grad) < 5e-8) ) { n_small++; continue; } total += fabs(cgrad - grad); ntot++; if ( !within_tolerance(grad, cgrad, 5.0) || !within_tolerance(cgrad, grad, 5.0) ) { if ( !quiet ) { STATUS("!- %s %3i %3i %3i" " %10.2Le %10.2e ratio = %5.2Lf" " %10.2e %10.2e\n", str, h, k, l, grad, cgrad, cgrad/grad, r1, r2); } n_bad++; } else { //STATUS("OK %s %3i %3i %3i" // " %10.2Le %10.2e ratio = %5.2Lf" // " %10.2e %10.2e\n", // str, h, k, l, grad, cgrad, cgrad/grad, // r1, r2); n_good++; } } } STATUS("%3s: %3i within 5%%, %3i outside, %3i nan, %3i invalid, " "%3i small. ", str, n_good, n_bad, n_nan, n_invalid, n_small); if ( plot ) { fclose(fh); } cc = gsl_stats_correlation(vec1, 1, vec2, 1, n_line); STATUS("CC = %+f\n", cc); return cc; }