/* * partialator.c * * Scaling and post refinement for coherent nanocrystallography * * (c) 2006-2011 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include "utils.h" #include "hdf5-file.h" #include "symmetry.h" #include "reflections.h" #include "stream.h" #include "geometry.h" #include "peaks.h" #include "thread-pool.h" #include "beam-parameters.h" #include "post-refinement.h" #include "hrs-scaling.h" #include "reflist.h" static void show_help(const char *s) { printf("Syntax: %s [options]\n\n", s); printf( "Scaling and post refinement for coherent nanocrystallography.\n" "\n" " -h, --help Display this help message.\n" "\n" " -i, --input= Specify the name of the input 'stream'.\n" " (must be a file, not e.g. stdin)\n" " -o, --output= Output filename. Default: facetron.hkl.\n" " -g. --geometry= Get detector geometry from file.\n" " -b, --beam= Get beam parameters from file, which provides\n" " initial values for parameters, and nominal\n" " wavelengths if no per-shot value is found in \n" " an HDF5 file.\n" " -y, --symmetry= Merge according to symmetry .\n" " -n, --iterations= Run cycles of scaling and post-refinement.\n" "\n" " -j Run analyses in parallel.\n"); } struct refine_args { const char *sym; ReflItemList *obs; double *i_full; struct image *image; FILE *graph; FILE *pgraph; }; static void refine_image(int mytask, void *tasks) { struct refine_args *all_args = tasks; struct refine_args *pargs = &all_args[mytask]; struct image *image = pargs->image; pr_refine(image, pargs->i_full, pargs->sym); } static void refine_all(struct image *images, int n_total_patterns, struct detector *det, const char *sym, ReflItemList *obs, double *i_full, int nthreads, FILE *graph, FILE *pgraph) { struct refine_args *tasks; int i; tasks = malloc(n_total_patterns * sizeof(struct refine_args)); for ( i=0; idivergence; images[i].bw = beam->bandwidth; images[i].det = det; images[i].osf = 1.0; images[i].profile_radius = 0.005e9; images[i].reflections = reflist_new(); images[i].lambda = ph_en_to_lambda(eV_to_J(ph_en)); /* Muppet proofing */ images[i].data = NULL; images[i].flags = NULL; images[i].beam = NULL; /* Read integrated intensities from pattern */ peaks = reflist_new(); do { Reflection *refl; signed int h, k, l; float intensity; int r; rval = fgets(line, 1023, fh); chomp(line); if ( (strlen(line) == 0) || (rval == NULL) ) break; r = sscanf(line, "%i %i %i %f", &h, &k, &l, &intensity); if ( r != 4 ) continue; refl = add_refl(peaks, h, k, l); set_int(refl, intensity); } while ( (strlen(line) != 0) && (rval != NULL) ); /* Calculate initial partialities and fill in intensities from * the stream */ transfer = find_intersections(&images[i], cell, 0); images[i].reflections = reflist_new(); for ( refl = first_refl(transfer, &iter); refl != NULL; refl = next_refl(refl, iter) ) { Reflection *peak; Reflection *new; signed int h, k, l, ha, ka, la; double r1, r2, p, x, y; int clamp1, clamp2; get_indices(refl, &h, &k, &l); get_detector_pos(refl, &x, &y); n_expected++; peak = find_refl(peaks, h, k, l); if ( peak == NULL ) { n_notfound++; continue; } n_found++; get_asymm(h, k, l, &ha, &ka, &la, sym); if ( find_item(obs, ha, ka, la) == 0 ) { add_item(obs, ha, ka, la); } new = add_refl(images[i].reflections, ha, ka, la); get_partial(refl, &r1, &r2, &p, &clamp1, &clamp2); get_detector_pos(refl, &x, &y); set_partial(new, r1, r2, p, clamp1, clamp2); set_detector_pos(new, 0.0, x, y); } reflist_free(peaks); reflist_free(transfer); progress_bar(i, n_total_patterns-1, "Loading pattern data"); } fclose(fh); STATUS("Found %5.2f%% of the expected peaks (%i %i %i).\n", 100.0 * (double)n_found / n_expected, n_found, n_notfound, n_expected); cts = new_list_count(); /* Make initial estimates */ STATUS("Performing initial scaling.\n"); select_scalable_reflections(images, n_total_patterns); I_full = scale_intensities(images, n_total_patterns, sym, obs); /* Iterate */ for ( i=0; ipanels); free(det); free(beam); free(cts); for ( i=0; i