From f50d2f8a6bad4e1fbac7ef078cf51471848b3b31 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 7 Jul 2015 11:01:47 +0200 Subject: Add mask_file to geometry file, to allow bad pixel mask to be stored separately --- doc/man/crystfel_geometry.5 | 11 +++++++---- libcrystfel/src/detector.c | 4 ++++ libcrystfel/src/detector.h | 1 + libcrystfel/src/hdf5-file.c | 24 +++++++++++++++++++----- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/doc/man/crystfel_geometry.5 b/doc/man/crystfel_geometry.5 index 974d602b..074fbc8f 100644 --- a/doc/man/crystfel_geometry.5 +++ b/doc/man/crystfel_geometry.5 @@ -87,7 +87,7 @@ Example: .IP data = /data/%/rawdata -The CrystFEL programs will look for the first event at /data/event1_name/rawdata, for the second at /data/event2_name/rawdata, etc. +The CrystFEL programs will look for the first event at /data/\fIevent1_name\fR/rawdata, for the second at /data/\fIevent2_name\fR/rawdata, etc., where \fIevent_name\fR and \fIevent2_name\fR are simply whatever the program could find in the HDF5 file which matched the pattern you gave. .PD 0 .IP \fBdim\fIn\fR\fR @@ -175,11 +175,11 @@ The maximum value, in ADU, before the pixel will be considered as bad. That is, .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). +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. .PD 0 -.IP \fBno_index\fR -Set this to 1 or "true" to ignore this panel completely. +.IP \fBmask_file\fR +Use this option to specify that the bad pixel mask should be read from a different file to the image data. The \fBmask\fR field, if it contains placeholders, will be expanded in exactly the same way as normal, it's just that the data will be read from the file you specify instead of the image data file. The \fBmask_file\fR may be specified as an absolute filename, or relative to the working directory. .PD 0 .IP \fBmask_good\fR @@ -193,6 +193,9 @@ mask_good = 0x27 .br mask_bad = 0x00 +.PD 0 +.IP \fBno_index\fR +Set this to 1 or "true" to ignore this panel completely. .SH BAD REGIONS diff --git a/libcrystfel/src/detector.c b/libcrystfel/src/detector.c index 9bbd4208..ae70e406 100644 --- a/libcrystfel/src/detector.c +++ b/libcrystfel/src/detector.c @@ -941,6 +941,9 @@ static int parse_field_for_panel(struct panel *panel, const char *key, } panel->mask = strdup(val); + } else if ( strcmp(key, "mask_file") == 0 ) { + panel->mask_file = strdup(val); + } else if ( strcmp(key, "coffset") == 0) { panel->coffset = atof(val); } else if ( strcmp(key, "res") == 0 ) { @@ -1247,6 +1250,7 @@ struct detector *get_detector_geometry(const char *filename, det->defaults.adu_per_eV = NAN; det->defaults.max_adu = +INFINITY; det->defaults.mask = NULL; + det->defaults.mask_file = NULL; det->defaults.data = NULL; det->defaults.dim_structure = NULL; strncpy(det->defaults.name, "", 1023); diff --git a/libcrystfel/src/detector.h b/libcrystfel/src/detector.h index acb6609f..582f82b8 100644 --- a/libcrystfel/src/detector.h +++ b/libcrystfel/src/detector.h @@ -96,6 +96,7 @@ struct panel double clen; /* Camera length in metres */ char *clen_from; char *mask; + char *mask_file; double res; /* Resolution in pixels per metre */ char badrow; /* 'x' or 'y' */ int no_index; /* Don't index peaks in this panel if non-zero */ diff --git a/libcrystfel/src/hdf5-file.c b/libcrystfel/src/hdf5-file.c index 3a08884a..9953b3e0 100644 --- a/libcrystfel/src/hdf5-file.c +++ b/libcrystfel/src/hdf5-file.c @@ -1133,8 +1133,8 @@ static int unpack_panels(struct image *image, struct detector *det) flags = image->flags[idx]; /* Bad if it's missing any of the "good" bits */ - if ( !((flags & image->det->mask_good) - == image->det->mask_good) ) bad = 1; + if ( (flags & image->det->mask_good) + != image->det->mask_good ) bad = 1; /* Bad if it has any of the "bad" bits. */ if ( flags & image->det->mask_bad ) bad = 1; @@ -1433,6 +1433,7 @@ int hdf5_read(struct hdfile *f, struct image *image, const char *element, static void load_mask(struct hdfile *f, struct event *ev, char *mask, + const char *mask_file, const char *pname, struct image *image, size_t p_w, size_t sum_p_h, hsize_t *f_offset, hsize_t *f_count, @@ -1443,18 +1444,29 @@ static void load_mask(struct hdfile *f, struct event *ev, char *mask, int check, r; hid_t memspace; hsize_t dimsm[2]; + hid_t fh; + + if ( mask_file != NULL ) { + fh = H5Fopen(mask_file, H5F_ACC_RDONLY, H5P_DEFAULT); + if ( fh < 0 ) { + ERROR("Couldn't open mask file '%s'\n", mask_file); + return; + } + } else { + fh = f->fh; + } if ( ev != NULL ) { mask = retrieve_full_path(ev, mask); } - exists = check_path_existence(f->fh, mask); + exists = check_path_existence(fh, mask); if ( !exists ) { ERROR("Cannot find flags for panel %s\n", pname); goto err; } - mask_dh = H5Dopen2(f->fh, mask, H5P_DEFAULT); + mask_dh = H5Dopen2(fh, mask, H5P_DEFAULT); if ( mask_dh <= 0 ) { ERROR("Couldn't open flags for panel %s\n", pname); goto err; @@ -1492,6 +1504,7 @@ static void load_mask(struct hdfile *f, struct event *ev, char *mask, return; err: + if ( mask_file != NULL ) H5Fclose(fh); if ( ev != NULL ) free(mask); free(image->flags); image->flags = NULL; @@ -1682,7 +1695,8 @@ int hdf5_read2(struct hdfile *f, struct image *image, struct event *ev, H5Sclose(memspace); if ( p->mask != NULL ) { - load_mask(f, ev, p->mask, p->name, image, p_w, sum_p_h, + load_mask(f, ev, p->mask, p->mask_file, p->name, + image, p_w, sum_p_h, f_offset, f_count, m_offset, m_count); } -- cgit v1.2.3