From 9da7f1b3f6a4245eb0c35fb32d32c60d60538eb2 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 16 Dec 2020 16:01:58 +0100 Subject: Add flag_{lessthan,morethan,equal} in geometry file This makes handling Pilatus/Eiger files, as well as many others, much easier. --- doc/man/crystfel_geometry.5 | 6 +++++ libcrystfel/src/datatemplate.c | 35 ++++++++++++++++++++++++++++ libcrystfel/src/datatemplate_priv.h | 13 +++++++++++ libcrystfel/src/image.c | 46 +++++++++++++++++++++++++++++++++++-- 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/doc/man/crystfel_geometry.5 b/doc/man/crystfel_geometry.5 index b8674f13..9435a900 100644 --- a/doc/man/crystfel_geometry.5 +++ b/doc/man/crystfel_geometry.5 @@ -210,6 +210,12 @@ The corner of this panel, defined as the first point in the panel to appear in t .IP \fBmax_adu\fR The maximum value, in ADU, before the pixel will be considered as bad. That is, the saturation value for the panel. +.PD 0 +.IP \fBflag_lessthan +.IP \fBflag_morethan +.IP \fBflag_equal +Mark pixels as "bad" if their values are respectively less than, more than or equal to the given value. Note carefully that the inequalities are strict, not inclusive: "less than", not "less than or equal to". + .PD 0 .IP \fBmask\fR If you have a bad pixel mask, you can include it in the HDF5 file as data blocks with the same structure and size as the panel data. You need to specify the location of each panel's mask data block using this property, and two bitmasks (see below). The number of placeholders ('%') in the \fBmask\fR must be the same for all panels. They will be substituted with the same values as used for the placeholders in the \fBdata\fR fields, although there may be fewer of them for \fBmask\fR than for \fBdata\fR. diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c index 76a61893..18b09c12 100644 --- a/libcrystfel/src/datatemplate.c +++ b/libcrystfel/src/datatemplate.c @@ -466,6 +466,25 @@ int set_dim(struct panel_template *panel, int dimension, } +static int add_flag_value(struct panel_template *p, + float val, + enum flag_value_type type) +{ + int i; + + for ( i=0; iflag_types[i] == FLAG_NOTHING ) { + p->flag_types[i] = type; + p->flag_values[i] = val; + return 0; + } + } + + ERROR("Too many flag values.\n"); + return 1; +} + + static int parse_field_for_panel(struct panel_template *panel, const char *key, const char *val, DataTemplate *det) { @@ -531,6 +550,20 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key, panel->pixel_pitch = 1.0/atof(val); } else if ( strcmp(key, "max_adu") == 0 ) { panel->max_adu = atof(val); + + } else if ( strcmp(key, "flag_equal") == 0 ) { + if ( add_flag_value(panel, atof(val), FLAG_EQUAL) ) { + reject = -1; + } + } else if ( strcmp(key, "flag_lessthan") == 0 ) { + if ( add_flag_value(panel, atof(val), FLAG_LESSTHAN) ) { + reject = -1; + } + } else if ( strcmp(key, "flag_morethan") == 0 ) { + if ( add_flag_value(panel, atof(val), FLAG_MORETHAN) ) { + reject = -1; + } + } else if ( strcmp(key, "badrow_direction") == 0 ) { ERROR("WARNING 'badrow_direction' is ignored in this version.\n"); } else if ( strcmp(key, "no_index") == 0 ) { @@ -915,6 +948,8 @@ DataTemplate *data_template_new_from_string(const char *string_in) defaults.clen_for_centering = NAN; defaults.adu_scale = NAN; defaults.adu_scale_unit = ADU_PER_PHOTON; + for ( i=0; i #include #include +#include #include "image.h" #include "utils.h" @@ -629,6 +630,36 @@ static void set_image_parameters(struct image *image, } +static int flag_value(float pixel, struct panel_template *p) +{ + int i; + for ( i=0; iflag_values[i]; + + switch ( p->flag_types[i] ) { + + case FLAG_NOTHING: + break; + + case FLAG_LESSTHAN: + if ( pixel < fv ) return 1; + break; + + case FLAG_MORETHAN: + if ( pixel > fv ) return 1; + break; + + case FLAG_EQUAL: + if ( rint(pixel) == fv) return 1; + break; + + } + } + return 0; +} + + static int create_badmap(struct image *image, const DataTemplate *dtempl, int no_mask_data) @@ -665,17 +696,28 @@ static int create_badmap(struct image *image, /* Add bad regions (skip if panel is bad anyway) */ if ( !p->bad ) { + int fs, ss; + fenv_t envp; + + fegetenv(&envp); + fesetround(1); /* Round to nearest + * (for flag_value) */ + for ( fs=0; fsdp[i][fs+ss*p_w]; if ( data_template_in_bad_region(dtempl, i, fs, ss) - || isnan(image->dp[i][fs+ss*p_w]) - || isinf(image->dp[i][fs+ss*p_w]) ) + || isnan(val) + || isinf(val) + || flag_value(val, p) ) { image->bad[i][fs+ss*p_w] = 1; } } } + + fesetenv(&envp); } /* Load mask (skip if panel is bad anyway) */ -- cgit v1.2.3