diff options
author | Thomas White <taw@physics.org> | 2022-08-18 14:20:16 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2022-08-18 15:57:46 +0200 |
commit | eaf9e6250654e65daabbe98b6b4d5b5f8cd6924f (patch) | |
tree | ecaa9a88d1bfe1b03d36961d58f26f1dc2ab7c1d /libcrystfel/src/image.c | |
parent | e8847558c3831e309d0325382589f34b273e96c8 (diff) |
Restructure image data array creation
This adds a central procedure (image_create_dp_bad_sat) to create all
the arrays. Then it's up to the loading procedure to put the values
into the arrays.
This also makes the loading procedures responsible for marking NaN/inf
pixels in the bad pixel map. This avoids an additional sweep through
the image data, and makes it possible to skip the NaN/inf check
altogether if the image data comes, as it often does, in format which
can't represent NaN/inf anyway.
Finally, it removes quite a lot of duplicated code.
Diffstat (limited to 'libcrystfel/src/image.c')
-rw-r--r-- | libcrystfel/src/image.c | 144 |
1 files changed, 77 insertions, 67 deletions
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 5d67ae2d..3593f52b 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -716,54 +716,75 @@ int image_set_zero_data(struct image *image, { int pi; - image->dp = malloc(dtempl->n_panels*sizeof(float *)); - if ( image->dp == NULL ) return 1; - for ( pi=0; pi<dtempl->n_panels; pi++ ) { - struct panel_template *p; - int p_w, p_h; - + long int i; p = &dtempl->panels[pi]; - p_w = p->orig_max_fs - p->orig_min_fs + 1; - p_h = p->orig_max_ss - p->orig_min_ss + 1; - - image->dp[pi] = calloc(p_w*p_h, sizeof(float)); - if ( image->dp[pi] == NULL ) return 1; - + for ( i=0; i<PANEL_WIDTH(p)*PANEL_HEIGHT(p); i++ ) { + image->dp[pi][i] = 0.0; + } } return 0; } -int image_set_zero_mask(struct image *image, - const DataTemplate *dtempl) +int image_create_dp_bad_sat(struct image *image, + const DataTemplate *dtempl) { - int pi; + int i; + + image->dp = malloc(dtempl->n_panels*sizeof(float *)); + if ( image->dp == NULL ) { + ERROR("Failed to allocate data array.\n"); + return 1; + } image->bad = malloc(dtempl->n_panels*sizeof(int *)); + if ( image->bad == NULL ) { + ERROR("Failed to allocate bad pixel mask\n"); + free(image->dp); + return 1; + } + image->sat = malloc(dtempl->n_panels*sizeof(float *)); - if ( (image->bad == NULL) || (image->sat == NULL) ) return 1; + if ( image->sat == NULL ) { + ERROR("Failed to allocate saturation map\n"); + free(image->dp); + free(image->bad); + return 1; + } - for ( pi=0; pi<dtempl->n_panels; pi++ ) { + /* Set all pointers to NULL for easier clean-up */ + for ( i=0; i<dtempl->n_panels; i++ ) { + image->dp[i] = NULL; + image->bad[i] = NULL; + image->sat[i] = NULL; + } - struct panel_template *p; - int p_w, p_h; - long int i; + for ( i=0; i<dtempl->n_panels; i++ ) { - p = &dtempl->panels[pi]; - p_w = p->orig_max_fs - p->orig_min_fs + 1; - p_h = p->orig_max_ss - p->orig_min_ss + 1; + size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]); - image->bad[pi] = calloc(p_w*p_h, sizeof(int)); - image->sat[pi] = calloc(p_w*p_h, sizeof(float)); - if ( image->bad[pi] == NULL ) return 1; - if ( image->sat[pi] == NULL ) return 1; + image->dp[i] = malloc(nel*sizeof(float)); + image->bad[i] = calloc(nel, sizeof(int)); + image->sat[i] = malloc(nel*sizeof(float)); - for ( i=0; i<p_w*p_h; i++ ) { - image->sat[pi][i] = INFINITY; + if ( (image->dp[i] == NULL) + || (image->bad[i] == NULL) + || (image->sat[i] == NULL) ) { + ERROR("Failed to allocate panel data arrays\n"); + for ( i=0; i<dtempl->n_panels; i++ ) { + free(image->dp[i]); + free(image->bad[i]); + free(image->sat[i]); + } + free(image->dp); + free(image->bad); + free(image->sat); + return 1; } + } return 0; @@ -882,16 +903,6 @@ static void mark_flagged_pixels_equal(float *dp, int *bad, } -static void mark_flagged_pixels_naninf(float *dp, int *bad, - long int n) -{ - long int i; - for ( i=0; i<n; i++ ) { - if ( !isfinite(dp[i]) ) bad[i] = 1; - } -} - - static void mark_flagged_pixels(struct panel_template *p, float *dp, int *bad) { @@ -903,10 +914,6 @@ static void mark_flagged_pixels(struct panel_template *p, p_h = p->orig_max_ss - p->orig_min_ss + 1; n = p_w * p_h; - profile_start("nan-inf"); - mark_flagged_pixels_naninf(dp, bad, n); - profile_end("nan-inf"); - profile_start("flag-values"); for ( i=0; i<MAX_FLAG_VALUES; i++ ) { @@ -1033,17 +1040,17 @@ static int load_mask(struct panel_template *p, { if ( is_hdf5_file(mask_fn) ) { #ifdef HAVE_HDF5 - image_hdf5_read_mask(p, mask_fn, ev, bad, mask_location, - mask_good, mask_bad); + return image_hdf5_read_mask(p, mask_fn, ev, bad, mask_location, + mask_good, mask_bad); #endif } else if ( is_cbf_file(mask_fn) ) { - image_cbf_read_mask(p, mask_fn, ev, 0, bad, - mask_good, mask_bad); + return image_cbf_read_mask(p, mask_fn, ev, 0, bad, + mask_good, mask_bad); } else if ( is_cbfgz_file(mask_fn) ) { - image_cbf_read_mask(p, mask_fn, ev, 1, bad, - mask_good, mask_bad); + return image_cbf_read_mask(p, mask_fn, ev, 1, bad, + mask_good, mask_bad); } else { ERROR("Unrecognised mask file type (%s)\n", mask_fn); @@ -1083,11 +1090,9 @@ static int create_badmap(struct image *image, { int i; - image->bad = malloc(dtempl->n_panels * sizeof(int *)); - if ( image->bad == NULL ) { - ERROR("Failed to allocate bad pixel mask\n"); - return 1; - } + /* The bad pixel map array is already created (see image_create_dp_bad_sat), + * and a preliminary mask (with NaN/inf pixels marked) has already been + * created when the image data was loaded. */ for ( i=0; i<dtempl->n_panels; i++ ) { @@ -1097,12 +1102,6 @@ static int create_badmap(struct image *image, p_w = p->orig_max_fs - p->orig_min_fs + 1; p_h = p->orig_max_ss - p->orig_min_ss + 1; - image->bad[i] = calloc(p_w*p_h, sizeof(int)); - if ( image->bad[i] == NULL ) { - ERROR("Failed to allocate bad pixel mask\n"); - return 1; - } - /* Panel marked as bad? */ if ( p->bad ) { profile_start("whole-panel"); @@ -1148,10 +1147,16 @@ static int create_badmap(struct image *image, mask_fn = p->masks[j].filename; } - load_mask(p, mask_fn, image->ev, image->bad[i], - p->masks[j].data_location, - p->masks[j].good_bits, - p->masks[j].bad_bits); + if ( load_mask(p, mask_fn, image->ev, image->bad[i], + p->masks[j].data_location, + p->masks[j].good_bits, + p->masks[j].bad_bits) ) + { + ERROR("Failed to load mask for %s\n", + p->name); + profile_end("load-masks"); + return 1; + } } profile_end("load-masks"); @@ -1226,9 +1231,7 @@ static int create_satmap(struct image *image, if ( is_hdf5_file(map_fn) ) { #ifdef HAVE_HDF5 - image->sat[i] = image_hdf5_read_satmap(p, map_fn, - image->ev, - p->satmap); + image_hdf5_read_satmap(p, map_fn, image->ev, p->satmap); #endif } else { @@ -1276,6 +1279,11 @@ struct image *image_create_for_simulation(const DataTemplate *dtempl) return NULL; } + if ( image_create_dp_bad_sat(image, dtempl) ) { + image_free(image); + return NULL; + } + if ( image_set_zero_data(image, dtempl) ) { image_free(image); return NULL; @@ -1311,6 +1319,8 @@ static int do_image_read(struct image *image, const DataTemplate *dtempl, int i; int r; + if ( image_create_dp_bad_sat(image, dtempl) ) return 1; + /* Load the image data */ if ( !no_image_data ) { int r; |