diff options
author | Thomas White <taw@physics.org> | 2020-12-16 16:01:58 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2020-12-16 16:01:58 +0100 |
commit | 9da7f1b3f6a4245eb0c35fb32d32c60d60538eb2 (patch) | |
tree | 0af0ee5b82a5966aadcfd5f9446c7889a3eeba5c /libcrystfel/src | |
parent | b4f243ec2c704e510655de8ea34c9fc16f454390 (diff) |
Add flag_{lessthan,morethan,equal} in geometry file
This makes handling Pilatus/Eiger files, as well as many others, much
easier.
Diffstat (limited to 'libcrystfel/src')
-rw-r--r-- | libcrystfel/src/datatemplate.c | 35 | ||||
-rw-r--r-- | libcrystfel/src/datatemplate_priv.h | 13 | ||||
-rw-r--r-- | libcrystfel/src/image.c | 46 |
3 files changed, 92 insertions, 2 deletions
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; i<MAX_FLAG_VALUES; i++ ) { + if ( p->flag_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<MAX_FLAG_VALUES; i++ ) defaults.flag_values[i] = 0; + for ( i=0; i<MAX_FLAG_VALUES; i++ ) defaults.flag_types[i] = FLAG_NOTHING; defaults.max_adu = +INFINITY; defaults.mask = NULL; defaults.mask_file = NULL; diff --git a/libcrystfel/src/datatemplate_priv.h b/libcrystfel/src/datatemplate_priv.h index 9d4f8f26..593ebaa8 100644 --- a/libcrystfel/src/datatemplate_priv.h +++ b/libcrystfel/src/datatemplate_priv.h @@ -55,6 +55,15 @@ enum wavelength_unit WAVELENGTH_PHOTON_EV }; +#define MAX_FLAG_VALUES (16) + +enum flag_value_type +{ + FLAG_NOTHING, + FLAG_EQUAL, + FLAG_MORETHAN, + FLAG_LESSTHAN +}; /* Special values for dimension IDs */ #define DIM_FS (-1) @@ -107,6 +116,10 @@ struct panel_template /** Treat pixel as unreliable if higher than this */ double max_adu; + /** Pixels with exactly this value will be marked as bad */ + enum flag_value_type flag_types[MAX_FLAG_VALUES]; + signed int flag_values[MAX_FLAG_VALUES]; + /** Location of data in file (possibly with placeholders) */ char *data; diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 2b609e51..d50bcf43 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -36,6 +36,7 @@ #include <math.h> #include <stdio.h> #include <sys/stat.h> +#include <fenv.h> #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; i<MAX_FLAG_VALUES; i++ ) { + + float fv = p->flag_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; fs<p_w; fs++ ) { for ( ss=0; ss<p_h; ss++ ) { + float val = image->dp[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) */ |