aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2020-12-16 16:01:58 +0100
committerThomas White <taw@physics.org>2020-12-16 16:01:58 +0100
commit9da7f1b3f6a4245eb0c35fb32d32c60d60538eb2 (patch)
tree0af0ee5b82a5966aadcfd5f9446c7889a3eeba5c /libcrystfel/src
parentb4f243ec2c704e510655de8ea34c9fc16f454390 (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.c35
-rw-r--r--libcrystfel/src/datatemplate_priv.h13
-rw-r--r--libcrystfel/src/image.c46
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) */