diff options
-rw-r--r-- | doc/man/render_hkl.1 | 5 | ||||
-rw-r--r-- | libcrystfel/src/asdf.c | 45 | ||||
-rw-r--r-- | libcrystfel/src/geometry.c | 26 | ||||
-rw-r--r-- | libcrystfel/src/index.c | 13 | ||||
-rw-r--r-- | libcrystfel/src/index.h | 7 | ||||
-rw-r--r-- | libcrystfel/src/stream.c | 58 | ||||
-rw-r--r-- | libcrystfel/src/symmetry.c | 21 | ||||
-rw-r--r-- | libcrystfel/src/symmetry.h | 8 | ||||
-rw-r--r-- | src/ambigator.c | 2 | ||||
-rw-r--r-- | src/cell_explorer.c | 77 | ||||
-rw-r--r-- | src/get_hkl.c | 3 | ||||
-rw-r--r-- | src/im-sandbox.c | 36 | ||||
-rw-r--r-- | src/im-sandbox.h | 5 | ||||
-rw-r--r-- | src/partialator.c | 113 | ||||
-rw-r--r-- | src/pattern_sim.c | 1 | ||||
-rw-r--r-- | src/process_hkl.c | 1 | ||||
-rw-r--r-- | src/process_image.c | 15 | ||||
-rw-r--r-- | src/render_hkl.c | 6 | ||||
-rwxr-xr-x | tests/first_merge_check | 4 | ||||
-rwxr-xr-x | tests/fourth_merge_check | 2 | ||||
-rwxr-xr-x | tests/second_merge_check | 4 | ||||
-rwxr-xr-x | tests/third_merge_check | 4 |
22 files changed, 345 insertions, 111 deletions
diff --git a/doc/man/render_hkl.1 b/doc/man/render_hkl.1 index d78e3343..eadbba34 100644 --- a/doc/man/render_hkl.1 +++ b/doc/man/render_hkl.1 @@ -93,6 +93,11 @@ The raw numbers of observations of the reflections, without performing the corre The default is \fB--weighting=I\fR. .PD 0 +.IP \fB--scale-top=\fIn\fR +.PD +Force the top of the colour scale to correspond to a value of \fIn\fR. Any value you give for \fB--boost\fR will be ignored. + +.PD 0 .IP \fB--colour-key\fR .PD Write the selected colour scale out to 'key.pdf' in the current directory. diff --git a/libcrystfel/src/asdf.c b/libcrystfel/src/asdf.c index df20f7ef..49917ad9 100644 --- a/libcrystfel/src/asdf.c +++ b/libcrystfel/src/asdf.c @@ -322,6 +322,15 @@ static int compare_doubles(const void *a, const void *b) } +static double max(double a, double b, double c) +{ + double m = a; + if ( m < b ) m = b; + if ( m < c ) m = c; + return m; +} + + /* Compares tvectors by length */ static int compare_tvectors(const void *a, const void *b) { @@ -889,12 +898,14 @@ static int find_cell(struct tvector *tvectors, int N_tvectors, double IndexFit, return 0; } + void swap(int *a, int *b) { int c = *a; *a = *b; *b = c; } + /* Generate triplets of integers < N_reflections in random sequence */ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) { @@ -904,10 +915,13 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) int N_triplets = N_reflections * (N_reflections - 1) * (N_reflections - 2) / 6; - if ( N_triplets > N_triplets_max ) N_triplets = N_triplets_max; + if ( N_triplets > N_triplets_max || N_reflections > 1000 ) { + N_triplets = N_triplets_max; + } *N = N_triplets; int **triplets = malloc(N_triplets * sizeof(int *)); + if (triplets == NULL) { ERROR("Failed to allocate triplets in generate_triplets!\n"); return 0; @@ -962,6 +976,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) return triplets; } + static int index_refls(gsl_vector **reflections, int N_reflections, double d_max, double volume_min, double volume_max, double LevelFit, double IndexFit, int N_triplets_max, @@ -1094,20 +1109,38 @@ int run_asdf(struct image *image, IndexingPrivate *ipriv) double LevelFit = 1./1000; double IndexFit = 1./500; - double d_max = 220.; // thrice the maximum expected axis length + double d_max = 1000.; // thrice the maximum expected axis length double volume_min = 100.; - double volume_max = 1000000.; + double volume_max = 100000000.; int N_triplets_max = 10000; // maximum number of triplets struct asdf_private *dp = (struct asdf_private *)ipriv; - if ( dp->indm & INDEXING_CHECK_CELL_AXES ) { + if ( dp->indm & INDEXING_CHECK_CELL_AXES || + dp->indm & INDEXING_CHECK_CELL_COMBINATIONS) { + double a, b, c, gamma, beta, alpha; + cell_get_parameters(dp->template, &a, &b, &c, + &alpha, &beta, &gamma); + + d_max = max(a, b, c) * 3 * 1e10; + double volume = cell_get_volume(dp->template); double vtol = (dp->ltl[0] + dp->ltl[1] + dp->ltl[2]) / 100 + dp->ltl[3] / 180 * M_PI; - volume_min = volume * (1 - vtol); - volume_max = volume * (1 + vtol); + + /* Divide volume constraints by number of lattice points per + * unit cell since asdf always finds primitive cell */ + int latt_points_per_uc = 1; + char centering = cell_get_centering(dp->template); + if ( centering == 'A' || + centering == 'B' || + centering == 'C' || + centering == 'I' ) latt_points_per_uc = 2; + else if ( centering == 'F' ) latt_points_per_uc = 4; + + volume_min = volume * (1 - vtol)/latt_points_per_uc; + volume_max = volume * (1 + vtol)/latt_points_per_uc; } int n = image_feature_count(image->features); diff --git a/libcrystfel/src/geometry.c b/libcrystfel/src/geometry.c index 266d6267..b968dc06 100644 --- a/libcrystfel/src/geometry.c +++ b/libcrystfel/src/geometry.c @@ -52,16 +52,15 @@ static int locate_peak_on_panel(double x, double y, double z, double k, struct panel *p, double *pfs, double *pss) { - double r2, ctt, tta, phi; + double ctt, tta, phi; gsl_vector *v; gsl_vector *t; gsl_matrix *M; double fs, ss, one_over_mu; /* Calculate 2theta (scattering angle) and azimuth (phi) */ - r2 = x*x + y*y + z*z; - ctt = 1.0 - r2 / (2.0*k*k); /* cos(2theta) */ - tta = acos(ctt); + tta = atan2(sqrt(x*x+y*y), k+z); + ctt = cos(tta); phi = atan2(y, x); /* Set up matrix equation */ @@ -637,25 +636,18 @@ void polarisation_correction(RefList *list, UnitCell *cell, struct image *image) refl != NULL; refl = next_refl(refl, iter) ) { - double pol, pa, pb, phi, tt, ool; + double pol; double intensity; - double xl, yl, zl; + double xl, yl; signed int h, k, l; + const double P = 1.0; /* degree of polarisation */ get_indices(refl, &h, &k, &l); - /* Polarisation correction assuming 100% polarisation - * along the x direction */ - xl = h*asx + k*bsx + l*csx; - yl = h*asy + k*bsy + l*csy; - zl = h*asz + k*bsz + l*csz; + xl = (h*asx + k*bsx + l*csx)*image->lambda; + yl = (h*asy + k*bsy + l*csy)*image->lambda; - ool = 1.0 / image->lambda; - tt = angle_between(0.0, 0.0, 1.0, xl, yl, zl+ool); - phi = atan2(yl, xl); - pa = pow(sin(phi)*sin(tt), 2.0); - pb = pow(cos(tt), 2.0); - pol = 1.0 - 2.0*(1.0-pa) + (1.0+pb); + pol = P*(1.0 - xl*xl) + (1.0-P)*(1.0 - yl*yl); intensity = get_intensity(refl); set_intensity(refl, intensity / pol); diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index e0bebfa4..e7fd879d 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -3,12 +3,12 @@ * * Perform indexing (somehow) * - * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * Copyright © 2012 Lorenzo Galli * * Authors: - * 2010-2016 Thomas White <taw@physics.org> + * 2010-2017 Thomas White <taw@physics.org> * 2010-2011 Richard Kirian <rkirian@asu.edu> * 2012 Lorenzo Galli * 2013 Cornelius Gati <cornelius.gati@cfel.de> @@ -434,10 +434,16 @@ static int finished_retry(IndexingMethod indm, int r, struct image *image) } } - void index_pattern(struct image *image, IndexingMethod *indms, IndexingPrivate **iprivs) { + index_pattern_2(image, indms, iprivs, NULL); +} + + +void index_pattern_2(struct image *image, IndexingMethod *indms, + IndexingPrivate **iprivs, int *ping) +{ int n = 0; ImageFeatureList *orig; @@ -465,6 +471,7 @@ void index_pattern(struct image *image, ntry++; done = finished_retry(indms[n], r, image); if ( ntry > 5 ) done = 1; + if ( ping != NULL ) (*ping)++; } while ( !done ); diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h index 23545506..33d568f6 100644 --- a/libcrystfel/src/index.h +++ b/libcrystfel/src/index.h @@ -3,13 +3,13 @@ * * Perform indexing (somehow) * - * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * Copyright © 2012 Richard Kirian * Copyright © 2012 Lorenzo Galli * * Authors: - * 2010-2016 Thomas White <taw@physics.org> + * 2010-2017 Thomas White <taw@physics.org> * 2010 Richard Kirian * 2012 Lorenzo Galli * 2015 Kenneth Beyerlein <kenneth.beyerlein@desy.de> @@ -161,6 +161,9 @@ extern IndexingPrivate **prepare_indexing(IndexingMethod *indm, UnitCell *cell, extern void index_pattern(struct image *image, IndexingMethod *indms, IndexingPrivate **iprivs); +extern void index_pattern_2(struct image *image, IndexingMethod *indms, + IndexingPrivate **iprivs, int *ping); + extern void cleanup_indexing(IndexingMethod *indms, IndexingPrivate **privs); #ifdef __cplusplus diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c index 789a9d7a..e858172e 100644 --- a/libcrystfel/src/stream.c +++ b/libcrystfel/src/stream.c @@ -65,9 +65,11 @@ struct _stream int major_version; int minor_version; + + long long int ln; }; -static int read_peaks(FILE *fh, struct image *image) +static int read_peaks(Stream *st, struct image *image) { char *rval = NULL; int first = 1; @@ -82,7 +84,8 @@ static int read_peaks(FILE *fh, struct image *image) struct panel *p = NULL; float add_x, add_y; - rval = fgets(line, 1023, fh); + rval = fgets(line, 1023, st->fh); + st->ln++; if ( rval == NULL ) continue; chomp(line); @@ -126,7 +129,7 @@ static int read_peaks(FILE *fh, struct image *image) } -static int read_peaks_2_3(FILE *fh, struct image *image) +static int read_peaks_2_3(Stream *st, struct image *image) { char *rval = NULL; int first = 1; @@ -142,7 +145,8 @@ static int read_peaks_2_3(FILE *fh, struct image *image) struct panel *p = NULL; float add_x, add_y; - rval = fgets(line, 1023, fh); + rval = fgets(line, 1023, st->fh); + st->ln++; if ( rval == NULL ) continue; chomp(line); @@ -269,7 +273,7 @@ static int write_peaks_2_3(struct image *image, FILE *ofh) } -static RefList *read_stream_reflections_2_3(FILE *fh, struct detector *det) +static RefList *read_stream_reflections_2_3(Stream *st, struct detector *det) { char *rval = NULL; int first = 1; @@ -290,7 +294,8 @@ static RefList *read_stream_reflections_2_3(FILE *fh, struct detector *det) int r; Reflection *refl; - rval = fgets(line, 1023, fh); + rval = fgets(line, 1023, st->fh); + st->ln++; if ( rval == NULL ) continue; chomp(line); @@ -342,7 +347,7 @@ static RefList *read_stream_reflections_2_3(FILE *fh, struct detector *det) } -static RefList *read_stream_reflections_2_1(FILE *fh, struct detector *det) +static RefList *read_stream_reflections_2_1(Stream *st, struct detector *det) { char *rval = NULL; int first = 1; @@ -364,7 +369,8 @@ static RefList *read_stream_reflections_2_1(FILE *fh, struct detector *det) int r; Reflection *refl; - rval = fgets(line, 1023, fh); + rval = fgets(line, 1023, st->fh); + st->ln++; if ( rval == NULL ) continue; chomp(line); @@ -426,7 +432,7 @@ static RefList *read_stream_reflections_2_1(FILE *fh, struct detector *det) } -static RefList *read_stream_reflections_2_2(FILE *fh, struct detector *det) +static RefList *read_stream_reflections_2_2(Stream *st, struct detector *det) { char *rval = NULL; int first = 1; @@ -442,7 +448,8 @@ static RefList *read_stream_reflections_2_2(FILE *fh, struct detector *det) int r; Reflection *refl; - rval = fgets(line, 1023, fh); + rval = fgets(line, 1023, st->fh); + st->ln++; if ( rval == NULL ) continue; chomp(line); @@ -887,14 +894,15 @@ int write_chunk(Stream *st, struct image *i, struct hdfile *hdfile, } -static int find_start_of_chunk(FILE *fh) +static int find_start_of_chunk(Stream *st) { char *rval = NULL; char line[1024]; do { - rval = fgets(line, 1023, fh); + rval = fgets(line, 1023, st->fh); + st->ln++; /* Trouble? */ if ( rval == NULL ) return 1; @@ -942,6 +950,7 @@ static void read_crystal(Stream *st, struct image *image, StreamReadFlags srf) char c; rval = fgets(line, 1023, st->fh); + st->ln++; /* Trouble? */ if ( rval == NULL ) break; @@ -975,7 +984,8 @@ static void read_crystal(Stream *st, struct image *image, StreamReadFlags srf) centering = c; have_cen = 1; } else { - ERROR("Duplicate centering ignored.\n"); + ERROR("Duplicate centering (line %lli) - " + "stream may be corrupted!\n", st->ln); } } @@ -986,7 +996,8 @@ static void read_crystal(Stream *st, struct image *image, StreamReadFlags srf) unique_axis = c; have_ua = 1; } else { - ERROR("Duplicate unique axis ignored.\n"); + ERROR("Duplicate unique axis (line %lli) - " + "stream may be corrupted!\n", st->ln); } } @@ -997,7 +1008,8 @@ static void read_crystal(Stream *st, struct image *image, StreamReadFlags srf) lattice_type = lattice_from_str(line+15); have_latt = 1; } else { - ERROR("Duplicate lattice type ignored.\n"); + ERROR("Duplicate lattice type (line %lli) - " + "stream may be corrupted!\n", st->ln); } } @@ -1030,13 +1042,13 @@ static void read_crystal(Stream *st, struct image *image, StreamReadFlags srf) /* The reflection list format in the stream diverges * after 2.2 */ if ( AT_LEAST_VERSION(st, 2, 3) ) { - reflist = read_stream_reflections_2_3(st->fh, + reflist = read_stream_reflections_2_3(st, image->det); } else if ( AT_LEAST_VERSION(st, 2, 2) ) { - reflist = read_stream_reflections_2_2(st->fh, + reflist = read_stream_reflections_2_2(st, image->det); } else { - reflist = read_stream_reflections_2_1(st->fh, + reflist = read_stream_reflections_2_1(st, image->det); } if ( reflist == NULL ) { @@ -1148,7 +1160,7 @@ int read_chunk_2(Stream *st, struct image *image, StreamReadFlags srf) int have_filename = 0; int have_ev = 0; - if ( find_start_of_chunk(st->fh) ) return 1; + if ( find_start_of_chunk(st) ) return 1; image->lambda = -1.0; image->features = NULL; @@ -1167,6 +1179,7 @@ int read_chunk_2(Stream *st, struct image *image, StreamReadFlags srf) float div, bw; rval = fgets(line, 1023, st->fh); + st->ln++; /* Trouble? */ if ( rval == NULL ) break; @@ -1257,9 +1270,9 @@ int read_chunk_2(Stream *st, struct image *image, StreamReadFlags srf) int fail; if ( AT_LEAST_VERSION(st, 2, 3) ) { - fail = read_peaks_2_3(st->fh, image); + fail = read_peaks_2_3(st, image); } else { - fail = read_peaks(st->fh, image); + fail = read_peaks(st, image); } if ( fail ) { ERROR("Failed while reading peaks\n"); @@ -1358,6 +1371,8 @@ Stream *open_stream_for_read(const char *filename) return NULL; } + st->ln = 1; + return st; } @@ -1656,6 +1671,7 @@ void write_geometry_file(Stream *st, const char *geom_filename) { */ int rewind_stream(Stream *st) { + st->ln = 0; return fseek(st->fh, 0, SEEK_SET); } diff --git a/libcrystfel/src/symmetry.c b/libcrystfel/src/symmetry.c index 503078a7..d675fb30 100644 --- a/libcrystfel/src/symmetry.c +++ b/libcrystfel/src/symmetry.c @@ -3,12 +3,12 @@ * * Symmetry * - * Copyright © 2012-2014 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2010-2014 Thomas White <taw@physics.org> - * 2014 Kenneth Beyerlein <kenneth.beyerlein@desy.de> + * 2010-2014,2016 Thomas White <taw@physics.org> + * 2014 Kenneth Beyerlein <kenneth.beyerlein@desy.de> * * This file is part of CrystFEL. * @@ -1088,6 +1088,21 @@ SymOpList *get_pointgroup(const char *sym) } +void pointgroup_warning(const char *sym) +{ + if ( (strcmp(sym, "m") == 0) + || (strcmp(sym, "2/m") == 0) + || (strcmp(sym, "2") == 0) ) + { + ERROR("WARNING: You have specified a monoclinic point group " + "without a unique axis. The default unique axis is 'c'. " + "If you want unique axis b, append '_uab' to your point " + "group.\n"); + } + +} + + static void do_op(const IntegerMatrix *op, signed int h, signed int k, signed int l, signed int *he, signed int *ke, signed int *le) diff --git a/libcrystfel/src/symmetry.h b/libcrystfel/src/symmetry.h index c29164ef..a61ca96f 100644 --- a/libcrystfel/src/symmetry.h +++ b/libcrystfel/src/symmetry.h @@ -3,12 +3,12 @@ * * Symmetry * - * Copyright © 2012-2014 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2010-2014 Thomas White <taw@physics.org> - * 2014 Kenneth Beyerlein <kenneth.beyerlein@desy.de> + * 2010-2014,2016 Thomas White <taw@physics.org> + * 2014 Kenneth Beyerlein <kenneth.beyerlein@desy.de> * * This file is part of CrystFEL. * @@ -90,6 +90,8 @@ extern void describe_symmetry(const SymOpList *s); extern int is_centric(signed int h, signed int k, signed int l, const SymOpList *ops); +extern void pointgroup_warning(const char *sym); + extern void add_symop(SymOpList *ops, IntegerMatrix *m); extern SymOpList *parse_symmetry_operations(const char *s); extern char *get_matrix_name(const IntegerMatrix *m, int row); diff --git a/src/ambigator.c b/src/ambigator.c index 659b17dc..f7837721 100644 --- a/src/ambigator.c +++ b/src/ambigator.c @@ -1099,6 +1099,7 @@ int main(int argc, char *argv[]) if ( s_sym_str == NULL ) { s_sym_str = strdup("1"); } + pointgroup_warning(s_sym_str); s_sym = get_pointgroup(s_sym_str); if ( s_sym == NULL ) return 1; free(s_sym_str); @@ -1113,6 +1114,7 @@ int main(int argc, char *argv[]) w_sym = NULL; amb = NULL; } else { + pointgroup_warning(w_sym_str); w_sym = get_pointgroup(w_sym_str); free(w_sym_str); if ( w_sym == NULL ) return 1; diff --git a/src/cell_explorer.c b/src/cell_explorer.c index 914e4740..c8bbb069 100644 --- a/src/cell_explorer.c +++ b/src/cell_explorer.c @@ -3,11 +3,11 @@ * * Examine cell parameter histograms * - * Copyright © 2014 Deutsches Elektronen-Synchrotron DESY, - * a research centre of the Helmholtz Association. + * Copyright © 2014-2017 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. * * Authors: - * 2014 Thomas White <taw@physics.org> + * 2014,2017 Thomas White <taw@physics.org> * * This file is part of CrystFEL. * @@ -270,6 +270,52 @@ static void draw_axis(cairo_t *cr, HistoBox *b, int width, int height) } +static void draw_label(cairo_t *cr, HistoBox *b, int width, int height) +{ + PangoLayout *layout; + PangoFontDescription *fontdesc; + PangoRectangle ext; + char label[256]; + double sz; + + layout = pango_cairo_create_layout(cr); + + if ( b->have_fit ) { + snprintf(label, 255, "%s = %.2f ± %.2f%s", + b->label, b->fit_b, b->fit_c/sqrt(2), b->units); + } else { + strncpy(label, b->label, 255); + } + pango_layout_set_text(layout, label, -1); + + sz = (height*PANGO_SCALE)/10.0; + + fontdesc = pango_font_description_new(); + pango_font_description_set_family_static(fontdesc, "Serif"); + pango_font_description_set_style(fontdesc, PANGO_STYLE_ITALIC); + pango_font_description_set_absolute_size(fontdesc, sz); + pango_layout_set_font_description(layout, fontdesc); + + /* If text is too wide for box, adjust the size so it fits */ + pango_layout_get_extents(layout, NULL, &ext); + if ( ext.width > PANGO_SCALE*(width-20.0) ) { + sz = ((double)PANGO_SCALE*(width-20.0) / ext.width)*sz; + pango_font_description_set_absolute_size(fontdesc, sz); + pango_layout_set_font_description(layout, fontdesc); + } + + + cairo_move_to(cr, 10.0, 10.0); + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); + pango_cairo_update_layout(cr, layout); + pango_cairo_show_layout(cr, layout); + cairo_fill(cr); + + g_object_unref(layout); + pango_font_description_free(fontdesc); +} + + static gboolean draw_sig(GtkWidget *da, GdkEventExpose *event, HistoBox *b) { int width, height; @@ -431,24 +477,7 @@ static gboolean draw_sig(GtkWidget *da, GdkEventExpose *event, HistoBox *b) cairo_restore(cr); draw_axis(cr, b, width, height); - - cairo_text_extents_t ext; - char label[256]; - - cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_ITALIC, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(cr, height/10.0); - - if ( b->have_fit ) { - snprintf(label, 255, "%s = %.2f ± %.2f%s", - b->label, b->fit_b, b->fit_c/sqrt(2), b->units); - } else { - strncpy(label, b->label, 255); - } - - cairo_text_extents(cr, label, &ext); - cairo_move_to(cr, 10.0, 10.0+ext.height); - cairo_show_text(cr, label); + draw_label(cr, b, width, height); cairo_destroy(cr); @@ -1598,9 +1627,9 @@ int main(int argc, char *argv[]) w.cols_on[0] = 1; for ( i=1; i<8; i++ ) w.cols_on[i] = 2; - w.hist_a = histobox_new(&w, " A", "a"); - w.hist_b = histobox_new(&w, " A", "b"); - w.hist_c = histobox_new(&w, " A", "c"); + w.hist_a = histobox_new(&w, " Å", "a"); + w.hist_b = histobox_new(&w, " Å", "b"); + w.hist_c = histobox_new(&w, " Å", "c"); w.hist_al = histobox_new(&w, "°", "α"); w.hist_be = histobox_new(&w, "°", "β"); w.hist_ga = histobox_new(&w, "°", "γ"); diff --git a/src/get_hkl.c b/src/get_hkl.c index 62c9e608..d6efe747 100644 --- a/src/get_hkl.c +++ b/src/get_hkl.c @@ -561,18 +561,21 @@ int main(int argc, char *argv[]) } if ( holo_str != NULL ) { + pointgroup_warning(holo_str); holo = get_pointgroup(holo_str); free(holo_str); } else { holo = NULL; } if ( mero_str != NULL ) { + pointgroup_warning(mero_str); mero = get_pointgroup(mero_str); free(mero_str); } else { mero = NULL; } if ( expand_str != NULL ) { + pointgroup_warning(expand_str); expand = get_pointgroup(expand_str); free(expand_str); } else { diff --git a/src/im-sandbox.c b/src/im-sandbox.c index 51cd5903..f5493453 100644 --- a/src/im-sandbox.c +++ b/src/im-sandbox.c @@ -3,13 +3,13 @@ * * Sandbox for indexing * - * Copyright © 2012-2016 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * Copyright © 2012 Richard Kirian * Copyright © 2012 Lorenzo Galli * * Authors: - * 2010-2016 Thomas White <taw@physics.org> + * 2010-2017 Thomas White <taw@physics.org> * 2014 Valerio Mariani * 2011 Richard Kirian * 2012 Lorenzo Galli @@ -73,10 +73,18 @@ struct sandbox struct index_args *iargs; + /* Worker processes */ int n_proc; pid_t *pids; - int *running; + time_t *last_response; + int last_ping[MAX_NUM_WORKERS]; + + /* Streams to read from (NB not the same indices as the above) */ + int n_read; + FILE **fhs; + int *fds; + int serial; struct sb_shm *shared; @@ -84,14 +92,6 @@ struct sandbox char *tmpdir; - /* The last time each worker was heard from */ - time_t *last_response; - - /* Streams to read from */ - int n_read; - FILE **fhs; - int *fds; - /* Final output */ Stream *stream; }; @@ -124,6 +124,7 @@ static time_t get_monotonic_seconds() static void stamp_response(struct sandbox *sb, int n) { sb->last_response[n] = get_monotonic_seconds(); + sb->last_ping[n] = sb->shared->pings[n]; } @@ -131,14 +132,21 @@ static void check_hung_workers(struct sandbox *sb) { int i; time_t tnow = get_monotonic_seconds(); - for ( i=0; i<sb->n_read; i++ ) { + for ( i=0; i<sb->n_proc; i++ ) { + if ( !sb->running[i] ) continue; + + if ( sb->shared->pings[i] != sb->last_ping[i] ) { + stamp_response(sb, i); + } + if ( tnow - sb->last_response[i] > 240 ) { STATUS("Worker %i did not respond for 240 seconds - " "sending it SIGKILL.\n", i); kill(sb->pids[i], SIGKILL); stamp_response(sb, i); } + } } @@ -516,7 +524,6 @@ static void try_read(struct sandbox *sb, TimeAccounts *taccs) /* If the chunk cannot be read, assume the connection * is broken and that the process will die soon. */ time_accounts_set(taccs, TACC_STREAMREAD); - stamp_response(sb, i); if ( pump_chunk(sb->fhs[i], ofd) ) { remove_pipe(sb, i); } @@ -535,6 +542,9 @@ static void start_worker_process(struct sandbox *sb, int slot) return; } + sb->shared->pings[slot] = 0; + sb->last_ping[slot] = 0; + p = fork(); if ( p == -1 ) { ERROR("fork() failed!\n"); diff --git a/src/im-sandbox.h b/src/im-sandbox.h index b39f9566..b58e4b9e 100644 --- a/src/im-sandbox.h +++ b/src/im-sandbox.h @@ -3,13 +3,13 @@ * * Sandbox for indexing * - * Copyright © 2012-2015 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * Copyright © 2012 Richard Kirian * Copyright © 2012 Lorenzo Galli * * Authors: - * 2010-2015 Thomas White <taw@physics.org> + * 2010-2017 Thomas White <taw@physics.org> * 2011 Richard Kirian * 2012 Lorenzo Galli * 2012 Chunhong Yoon @@ -61,6 +61,7 @@ struct sb_shm char queue[QUEUE_SIZE][MAX_EV_LEN]; int no_more; char last_ev[MAX_NUM_WORKERS][MAX_EV_LEN]; + int pings[MAX_NUM_WORKERS]; pthread_mutex_t totals_lock; int n_processed; diff --git a/src/partialator.c b/src/partialator.c index b246571d..09feebb4 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -274,6 +274,12 @@ static void write_custom_split(struct custom_split *csplit, int dsn, tmp = insert_into_filename(outfile, csplit->dataset_names[dsn]); + if ( n_crystalsn == 0 ) { + ERROR("Not writing dataset '%s' because it contains no " + "crystals\n", csplit->dataset_names[dsn]); + return; + } + STATUS("Writing dataset '%s' to %s (%i crystals)\n", csplit->dataset_names[dsn], tmp, n_crystalsn); split = merge_intensities(crystalsn, n_crystalsn, nthreads, @@ -317,6 +323,101 @@ static void show_help(const char *s) } +static signed int find_first_crystal(Crystal **crystals, int n_crystals, + struct custom_split *csplit, int dsn) +{ + int i; + + for ( i=0; i<n_crystals; i++ ) { + const char *fn; + struct event *ev; + char *evs; + char *id; + int dsn_crystal; + + fn = crystal_get_image(crystals[i])->filename; + ev = crystal_get_image(crystals[i])->event; + evs = get_event_string(ev); + + id = malloc(strlen(evs)+strlen(fn)+2); + if ( id == NULL ) { + ERROR("Failed to allocate ID\n"); + return -1; + } + strcpy(id, fn); + strcat(id, " "); + strcat(id, evs); + dsn_crystal = find_dsn_for_id(csplit, id); + free(id); + + if ( dsn == dsn_crystal ) return i; + } + return -1; +} + + +static void check_csplit(Crystal **crystals, int n_crystals, + struct custom_split *csplit) +{ + int i; + int n_nosplit = 0; + int n_split = 0; + int n_cry = 0; + int n_nocry = 0; + + STATUS("Checking your custom split datasets...\n"); + + for ( i=0; i<n_crystals; i++ ) { + + const char *fn; + struct event *ev; + char *evs; + char *id; + int dsn_crystal; + + fn = crystal_get_image(crystals[i])->filename; + ev = crystal_get_image(crystals[i])->event; + evs = get_event_string(ev); + + id = malloc(strlen(evs)+strlen(fn)+2); + if ( id == NULL ) { + ERROR("Failed to allocate ID\n"); + return; + } + strcpy(id, fn); + strcat(id, " "); + strcat(id, evs); + dsn_crystal = find_dsn_for_id(csplit, id); + free(id); + if ( dsn_crystal == -1 ) { + n_nosplit++; + } else { + n_split++; + } + + } + + for ( i=0; i<csplit->n_datasets; i++ ) { + + /* Try to find a crystal with dsn = i */ + if ( find_first_crystal(crystals, n_crystals, csplit, i) != -1 ) + { + n_cry++; + } else { + n_nocry++; + STATUS("Dataset %s has no crystals.\n", + csplit->dataset_names[i]); + } + } + + STATUS("Please check that these numbers match your expectations:\n"); + STATUS(" Number of crystals assigned to a dataset: %i\n", n_split); + STATUS("Number of crystals with no dataset asssigned: %i\n", n_nosplit); + STATUS("Number of datasets with at least one crystal: %i\n", n_cry); + STATUS(" Number of datasets with no crystals: %i\n", n_nocry); +} + + static struct custom_split *load_custom_split(const char *filename) { struct custom_split *csplit; @@ -655,7 +756,6 @@ int main(int argc, char *argv[]) int n_iter = 10; RefList *full; int n_images = 0; - int n_images_seen = 0; int n_crystals = 0; int n_crystals_seen = 0; char cmdline[1024]; @@ -861,8 +961,10 @@ int main(int argc, char *argv[]) } if ( sym_str == NULL ) sym_str = strdup("1"); + pointgroup_warning(sym_str); sym = get_pointgroup(sym_str); free(sym_str); + if ( sym == NULL ) return 1; if ( pmodel_str != NULL ) { if ( strcmp(pmodel_str, "unity") == 0 ) { @@ -899,7 +1001,6 @@ int main(int argc, char *argv[]) /* Fill in what we know about the images so far */ n_images = 0; - n_images_seen = 0; n_crystals = 0; n_crystals_seen = 0; images = NULL; @@ -947,8 +1048,6 @@ int main(int argc, char *argv[]) return 1; } - n_images_seen++; - for ( i=0; i<cur->n_crystals; i++ ) { Crystal *cr; @@ -1001,9 +1100,7 @@ int main(int argc, char *argv[]) } - if ( n_crystals > 0 ) { - n_images++; - } + n_images++; if ( n_images % 100 == 0 ) { display_progress(n_images, n_crystals); @@ -1034,6 +1131,8 @@ int main(int argc, char *argv[]) } } + if (csplit != NULL) check_csplit(crystals, n_crystals, csplit); + /* Make a first pass at cutting out crap */ STATUS("Checking patterns.\n"); //early_rejection(crystals, n_crystals); diff --git a/src/pattern_sim.c b/src/pattern_sim.c index c60b3280..e1e04789 100644 --- a/src/pattern_sim.c +++ b/src/pattern_sim.c @@ -533,6 +533,7 @@ int main(int argc, char *argv[]) } if ( sym_str == NULL ) sym_str = strdup("1"); + pointgroup_warning(sym_str); sym = get_pointgroup(sym_str); /* sym_str is used below */ diff --git a/src/process_hkl.c b/src/process_hkl.c index 29ef29a1..d2cf640b 100644 --- a/src/process_hkl.c +++ b/src/process_hkl.c @@ -692,6 +692,7 @@ int main(int argc, char *argv[]) } if ( sym_str == NULL ) sym_str = strdup("1"); + pointgroup_warning(sym_str); sym = get_pointgroup(sym_str); free(sym_str); diff --git a/src/process_image.c b/src/process_image.c index 62ef732c..bcaee543 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -3,11 +3,11 @@ * * The processing pipeline for one image * - * Copyright © 2012-2015 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2012-2017 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2010-2015 Thomas White <taw@physics.org> + * 2010-2017 Thomas White <taw@physics.org> * 2014 Valerio Mariani * * This file is part of CrystFEL. @@ -124,6 +124,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, image.indexed_by = INDEXING_NONE; time_accounts_set(taccs, TACC_HDF5OPEN); + sb_shared->pings[cookie]++; hdfile = hdfile_open(image.filename); if ( hdfile == NULL ) { ERROR("Couldn't open file: %s\n", image.filename); @@ -131,6 +132,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, } time_accounts_set(taccs, TACC_HDF5READ); + sb_shared->pings[cookie]++; check = hdf5_read2(hdfile, &image, image.event, 0); if ( check ) { return; @@ -138,6 +140,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, /* Take snapshot of image before applying horrible noise filters */ time_accounts_set(taccs, TACC_FILTER); + sb_shared->pings[cookie]++; prefilter = backup_image_data(image.dp, image.det); if ( iargs->median_filter > 0 ) { @@ -149,9 +152,11 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, } time_accounts_set(taccs, TACC_RESRANGE); + sb_shared->pings[cookie]++; mark_resolution_range_as_bad(&image, iargs->highres, +INFINITY); time_accounts_set(taccs, TACC_PEAKSEARCH); + sb_shared->pings[cookie]++; switch ( iargs->peaks ) { case PEAK_HDF5: @@ -214,7 +219,8 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, /* Index the pattern */ time_accounts_set(taccs, TACC_INDEXING); - index_pattern(&image, iargs->indm, iargs->ipriv); + index_pattern_2(&image, iargs->indm, iargs->ipriv, + &sb_shared->pings[cookie]); r = chdir(rn); if ( r ) { @@ -247,6 +253,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, /* Integrate! */ time_accounts_set(taccs, TACC_INTEGRATION); + sb_shared->pings[cookie]++; integrate_all_4(&image, iargs->int_meth, PMODEL_SCSPHERE, iargs->push_res, iargs->ir_inn, iargs->ir_mid, iargs->ir_out, @@ -255,6 +262,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, &sb_shared->term_lock); time_accounts_set(taccs, TACC_WRITESTREAM); + sb_shared->pings[cookie]++; ret = write_chunk(st, &image, hdfile, iargs->stream_peaks, iargs->stream_refls, pargs->filename_p_e->ev); @@ -274,6 +282,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, /* Count crystals which are still good */ time_accounts_set(taccs, TACC_TOTALS); + sb_shared->pings[cookie]++; pthread_mutex_lock(&sb_shared->totals_lock); any_crystals = 0; for ( i=0; i<image.n_crystals; i++ ) { diff --git a/src/render_hkl.c b/src/render_hkl.c index f9398c3d..3996814a 100644 --- a/src/render_hkl.c +++ b/src/render_hkl.c @@ -90,6 +90,7 @@ static void show_help(const char *s) " rawcts : the raw number of measurements for the\n" " reflection (no 'epsilon' correction).\n" "\n" +" --scale-top=<n> Manually set the top of the colour scale\n" " --res-ring=<r> Draw a resolution ring at <r> Angstroms.\n" " --highres=<r> Render spots only up to <r> Angstroms.\n" " --no-axes Do not draw reciprocal space axes.\n" @@ -477,7 +478,11 @@ static void render_za(UnitCell *cell, RefList *list, /* Use manual scale top if specified */ if ( scale_top > 0.0 ) { max_val = scale_top; + STATUS("Ignoring boost value (%f) because you used " + "--scale-top\n", boost); + boost = 1.0; } + STATUS("Top of colour scale = %e\n", max_val/boost); scale1 = ((double)wh-border) / (2.0*rmax); scale2 = ((double)ht-border) / (2.0*rmax); @@ -914,6 +919,7 @@ int main(int argc, char *argv[]) if ( sym_str == NULL ) { sym_str = strdup("1"); } + pointgroup_warning(sym_str); sym = get_pointgroup(sym_str); free(sym_str); diff --git a/tests/first_merge_check b/tests/first_merge_check index bb1484bd..17b9f87b 100755 --- a/tests/first_merge_check +++ b/tests/first_merge_check @@ -38,10 +38,10 @@ cat > first_merge_check_ans.hkl << EOF CrystFEL reflection list version 2.0 Symmetry: 1 h k l I phase sigma(I) nmeas - 1 0 0 150.03 - 35.36 2 + 1 0 0 150.00 - 35.36 2 EOF -src/process_hkl -i first_merge_check.stream -o first_merge_check.hkl +src/process_hkl -i first_merge_check.stream -o first_merge_check.hkl --no-polarisation ex -c '/End of reflections/ .,$d x' first_merge_check.hkl diff --git a/tests/fourth_merge_check b/tests/fourth_merge_check index 1c738da7..b0935bc9 100755 --- a/tests/fourth_merge_check +++ b/tests/fourth_merge_check @@ -25,7 +25,7 @@ Symmetry: 1 h k l I phase sigma(I) nmeas EOF -src/process_hkl -i fourth_merge_check.stream -o fourth_merge_check.hkl +src/process_hkl -i fourth_merge_check.stream -o fourth_merge_check.hkl --no-polarisation ex -c '/End of reflections/ .,$d x' fourth_merge_check.hkl diff --git a/tests/second_merge_check b/tests/second_merge_check index ed2ba9f9..1283cb0a 100755 --- a/tests/second_merge_check +++ b/tests/second_merge_check @@ -38,10 +38,10 @@ cat > second_merge_check_ans.hkl << EOF CrystFEL reflection list version 2.0 Symmetry: -1 h k l I phase sigma(I) nmeas - 1 0 0 150.03 - 35.36 2 + 1 0 0 150.00 - 35.36 2 EOF -src/process_hkl -y -1 -i second_merge_check.stream -o second_merge_check.hkl +src/process_hkl -y -1 -i second_merge_check.stream -o second_merge_check.hkl --no-polarisation ex -c '/End of reflections/ .,$d x' second_merge_check.hkl diff --git a/tests/third_merge_check b/tests/third_merge_check index 714afb7f..d4f5f9ef 100755 --- a/tests/third_merge_check +++ b/tests/third_merge_check @@ -53,10 +53,10 @@ cat > third_merge_check_ans.hkl << EOF CrystFEL reflection list version 2.0 Symmetry: 1 h k l I phase sigma(I) nmeas - 1 0 0 133.36 - 27.22 3 + 1 0 0 133.33 - 27.22 3 EOF -src/process_hkl -i third_merge_check.stream -o third_merge_check.hkl +src/process_hkl -i third_merge_check.stream -o third_merge_check.hkl --no-polarisation ex -c '/End of reflections/ .,$d x' third_merge_check.hkl |