16 Commits

Author SHA1 Message Date
CV-GPhL 0e258cc8c9 Null terminate buffer in file.c
Ensure the buffer is null terminated after allocation - otherwise correct results from strcmp below is undefined.
2026-02-04 14:52:02 +01:00
Graeme Winter bec44c8691 Do not depend on the strings being NULL terminated
Fixes #28

Instead make them NULL terminated by reading one longer into buffer
2023-08-09 12:47:45 +01:00
Graeme Winter 5d0b7bd104 New flag needed 2022-03-11 14:47:22 +00:00
Graeme Winter 300a980551 Use blocks for imports to prevent reorder; finish clang-format 2020-10-27 09:55:39 +00:00
Graeme Winter 4a6a75af70 clang-format err.* 2020-10-27 09:55:39 +00:00
Graeme Winter b36870935a clang-format file.* 2020-10-27 09:55:39 +00:00
Graeme Winter d73d6d70cb clang-format test.c 2020-10-27 09:55:39 +00:00
Graeme Winter 513bb10bf4 clang-format plugin 2020-10-27 09:55:39 +00:00
Graeme Winter 6ffef7d7c2 Typo; some comment formats 2020-10-27 09:55:39 +00:00
Graeme Winter e3cad6a7c3 Switch to c99 from c89 default - fixes #20
auggested by @jcbollinger
2020-10-26 15:58:25 +00:00
Graeme Winter 9b3236b084 First cut: use H5_USE_110_API (#19)
For #18 - compile against 1.10 API (may need to do more work to make sure this
does what we actually want)
2020-06-08 10:55:24 +01:00
Graeme Winter f25a73c667 Set to NULL after free; though fixes nothing 2020-04-02 14:21:52 +01:00
Tom Schoonjans 6165d14c31 Force linking against HDF5 shared library (#16) 2020-01-22 06:40:22 +00:00
Tom Schoonjans 19b16ad2a1 Fix sprintf usage (#15) 2020-01-21 10:52:49 +00:00
Graeme Winter 4e2b0c7506 Point at release 2019-05-08 09:28:59 +01:00
Charles Mita 34a38e15fd Update README.md 2019-01-29 19:58:27 +00:00
11 changed files with 1234 additions and 1244 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ BSLZ4_BUILD_DIR = ./bslz4/build
BSLZ4_INC_DIR = $(BSLZ4_SRC_DIR) BSLZ4_INC_DIR = $(BSLZ4_SRC_DIR)
CC=h5cc CC=h5cc
CFLAGS=-Wall -g -O2 -fpic -I$(INC_DIR) -I$(BSLZ4_INC_DIR) -std=c89 CFLAGS=-DH5_USE_110_API -Wall -g -O2 -fpic -I$(INC_DIR) -I$(BSLZ4_INC_DIR) -std=c99 -shlib
.PHONY: plugin .PHONY: plugin
plugin: $(BUILD_DIR)/durin-plugin.so plugin: $(BUILD_DIR)/durin-plugin.so
@@ -42,7 +42,7 @@ $(BSLZ4_BUILD_DIR)/bitshuffle_core.o $(BSLZ4_BUILD_DIR)/iochain.o
$(BUILD_DIR)/durin-plugin.so: $(BUILD_DIR)/plugin.o $(BUILD_DIR)/file.o $(BUILD_DIR)/err.o $(BUILD_DIR)/filters.o \ $(BUILD_DIR)/durin-plugin.so: $(BUILD_DIR)/plugin.o $(BUILD_DIR)/file.o $(BUILD_DIR)/err.o $(BUILD_DIR)/filters.o \
$(BUILD_DIR)/bslz4.a $(BUILD_DIR)/bslz4.a
mkdir -p $(BUILD_DIR) mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) -shared $^ -o $(BUILD_DIR)/durin-plugin.so $(CC) $(CFLAGS) -shared -noshlib $^ -o $(BUILD_DIR)/durin-plugin.so
$(BUILD_DIR)/example: $(BUILD_DIR)/test.o $(BUILD_DIR)/file.o $(BUILD_DIR)/err.o $(BUILD_DIR)/filters.o \ $(BUILD_DIR)/example: $(BUILD_DIR)/test.o $(BUILD_DIR)/file.o $(BUILD_DIR)/err.o $(BUILD_DIR)/filters.o \
$(BUILD_DIR)/bslz4.a $(BUILD_DIR)/bslz4.a
+3
View File
@@ -8,6 +8,9 @@ See:
* https://www.dectris.com/features/features-eiger-x/hdf5-and-nexus * https://www.dectris.com/features/features-eiger-x/hdf5-and-nexus
* https://strucbio.biologie.uni-konstanz.de/xdswiki * https://strucbio.biologie.uni-konstanz.de/xdswiki
## Get Durin
Latest release at https://github.com/DiamondLightSource/durin/releases/tag/2019v1
## Usage ## Usage
In your XDS.INP add: In your XDS.INP add:
+14 -15
View File
@@ -3,11 +3,10 @@
* Author: Charles Mita * Author: Charles Mita
*/ */
#include <stdio.h>
#include <hdf5.h> #include <hdf5.h>
#include "err.h" #include <stdio.h>
#include "err.h"
struct error_stack_t { struct error_stack_t {
char **files; char **files;
@@ -30,9 +29,10 @@ static char *messages[ERR_MAX_STACK_SIZE] = {0};
static struct error_stack_t stack = {files, funcs, lines, errors, messages, 0}; static struct error_stack_t stack = {files, funcs, lines, errors, messages, 0};
void push_error_stack(const char *file, const char *func, int line, int err,
void push_error_stack(const char *file, const char *func, int line, int err, const char *message) { const char *message) {
if (stack.size >= ERR_MAX_STACK_SIZE) return; /* unfortunate */ if (stack.size >= ERR_MAX_STACK_SIZE)
return; /* unfortunate */
int idx = stack.size; int idx = stack.size;
/* subtract 1 to ensure room for null byte in buffer */ /* subtract 1 to ensure room for null byte in buffer */
@@ -45,10 +45,11 @@ void push_error_stack(const char *file, const char *func, int line, int err, con
stack.size++; stack.size++;
} }
herr_t h5e_walk_callback(unsigned int n, const struct H5E_error2_t *err,
herr_t h5e_walk_callback(unsigned int n, const struct H5E_error2_t *err, void *client_data) { void *client_data) {
herr_t retval = 0; herr_t retval = 0;
/* only read the message for the innermost stack frame - the rest are just noise */ /* only read the message for the innermost stack frame - the rest are just
* noise */
if (n == 0) { if (n == 0) {
char message[ERR_MAX_MESSAGE_LENGTH] = {0}; char message[ERR_MAX_MESSAGE_LENGTH] = {0};
sprintf(message, "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, err->desc); sprintf(message, "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, err->desc);
@@ -59,7 +60,6 @@ herr_t h5e_walk_callback(unsigned int n, const struct H5E_error2_t *err, void *c
return retval; return retval;
} }
int h5e_error_callback(hid_t stack_id, void *client_data) { int h5e_error_callback(hid_t stack_id, void *client_data) {
int retval = 0; int retval = 0;
herr_t err = 0; herr_t err = 0;
@@ -71,30 +71,29 @@ done:
return retval; return retval;
} }
void reset_error_stack() { void reset_error_stack() {
stack.size = 0; stack.size = 0;
H5Eclear2(H5E_DEFAULT); /* almost certainly unnecessary */ H5Eclear2(H5E_DEFAULT); /* almost certainly unnecessary */
} }
void dump_error_stack(FILE *out) { void dump_error_stack(FILE *out) {
int idx = stack.size; int idx = stack.size;
if (idx > 0) fprintf(out, "Durin plugin error:\n"); if (idx > 0)
fprintf(out, "Durin plugin error:\n");
while (idx-- > 0) { while (idx-- > 0) {
const char *file = stack.files[idx]; const char *file = stack.files[idx];
const char *func = stack.funcs[idx]; const char *func = stack.funcs[idx];
const char *message = stack.messages[idx]; const char *message = stack.messages[idx];
const int line = stack.lines[idx]; const int line = stack.lines[idx];
if (message[0] != '\0') { if (message[0] != '\0') {
fprintf(out, "\t%s - line %d in %s:\n\t\t%s\n", file, line, func, message); fprintf(out, "\t%s - line %d in %s:\n\t\t%s\n", file, line, func,
message);
} else { } else {
fprintf(out, "\t%s - line %d in %s\n", file, line, func); fprintf(out, "\t%s - line %d in %s\n", file, line, func);
} }
} }
} }
int init_h5_error_handling() { int init_h5_error_handling() {
int retval = 0; int retval = 0;
hid_t err = 0; hid_t err = 0;
+13 -15
View File
@@ -3,46 +3,44 @@
* Author: Charles Mita * Author: Charles Mita
*/ */
#ifndef NXS_XDS_ERR_H #ifndef NXS_XDS_ERR_H
#define NXS_XDS_ERR_H #define NXS_XDS_ERR_H
#define ERR_MAX_FILENAME_LENGTH 64 #define ERR_MAX_FILENAME_LENGTH 64
#define ERR_MAX_FUNCNAME_LENGTH 128 #define ERR_MAX_FUNCNAME_LENGTH 128
#define ERR_MAX_MESSAGE_LENGTH 1024 #define ERR_MAX_MESSAGE_LENGTH 1024
#define ERR_MAX_STACK_SIZE 128 #define ERR_MAX_STACK_SIZE 128
/* obtain __func__ from GCC if no C99 */ /* obtain __func__ from GCC if no C99 */
#if __STDC_VERSION__ < 199901L #if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2 #if __GNUC__ >= 2
# define __func__ __FUNCTION__ #define __func__ __FUNCTION__
# else #else
# define __func__ "<unknown>" #define __func__ "<unknown>"
# endif #endif
#endif #endif
#if __GNUC__ >= 2 #if __GNUC__ >= 2
# define __line__ __LINE__ #define __line__ __LINE__
#else #else
# define __line__ 0 #define __line__ 0
#endif #endif
#if __GNUC__ >= 2 #if __GNUC__ >= 2
# define __file__ __FILE__ #define __file__ __FILE__
#else #else
# define __file__ "unknown" #define __file__ "unknown"
#endif #endif
#define ERROR_JUMP(err, target, message) \ #define ERROR_JUMP(err, target, message) \
{ \ { \
push_error_stack(__file__, __func__, __line__, err, message); \ push_error_stack(__file__, __func__, __line__, err, message); \
retval = err; \ retval = err; \
goto target; \ goto target; \
} }
void push_error_stack(const char *file, const char *func, int line, int err, const char *message); void push_error_stack(const char *file, const char *func, int line, int err,
const char *message);
void dump_error_stack(FILE *out); void dump_error_stack(FILE *out);
+153 -142
View File
@@ -3,17 +3,16 @@
* Author: Charles Mita * Author: Charles Mita
*/ */
#include <hdf5.h> #include <hdf5.h>
#include <hdf5_hl.h> #include <hdf5_hl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include "file.h"
#include "err.h"
#include "filters.h"
#include "err.h"
#include "file.h"
#include "filters.h"
void clear_det_visit_objects(struct det_visit_objects_t *objects) { void clear_det_visit_objects(struct det_visit_objects_t *objects) {
if (objects->nxdata) { if (objects->nxdata) {
@@ -26,29 +25,23 @@ void clear_det_visit_objects(struct det_visit_objects_t *objects) {
} }
} }
void free_ds_desc(struct ds_desc_t *desc) { void free_ds_desc(struct ds_desc_t *desc) {
H5Gclose(desc->det_g_id); H5Gclose(desc->det_g_id);
H5Gclose(desc->data_g_id); H5Gclose(desc->data_g_id);
free(desc); free(desc);
} }
void free_nxs_desc(struct ds_desc_t *desc) { void free_nxs_desc(struct ds_desc_t *desc) { free_ds_desc(desc); }
free_ds_desc(desc);
}
void free_eiger_desc(struct ds_desc_t *desc) { void free_eiger_desc(struct ds_desc_t *desc) {
struct eiger_ds_desc_t *e_desc = (struct eiger_ds_desc_t *) desc; struct eiger_ds_desc_t *e_desc = (struct eiger_ds_desc_t *)desc;
free(e_desc->block_sizes); free(e_desc->block_sizes);
free_ds_desc(desc); free_ds_desc(desc);
} }
void free_opt_eiger_desc(struct ds_desc_t *desc) { void free_opt_eiger_desc(struct ds_desc_t *desc) { free_eiger_desc(desc); }
free_eiger_desc(desc);
}
double scale_from_units(const char *unit_string) {
double scale_from_units(const char* unit_string) {
if (strcasecmp("m", unit_string) == 0 || if (strcasecmp("m", unit_string) == 0 ||
strcasecmp("metres", unit_string) == 0 || strcasecmp("metres", unit_string) == 0 ||
strcasecmp("meters", unit_string) == 0) { strcasecmp("meters", unit_string) == 0) {
@@ -77,7 +70,8 @@ int get_nxs_dataset_dims(struct ds_desc_t *desc) {
int retval = 0; int retval = 0;
int ndims = 0; int ndims = 0;
int width = 0; int width = 0;
g_id = desc->data_g_id;; g_id = desc->data_g_id;
;
ds_id = H5Dopen2(g_id, "data", H5P_DEFAULT); ds_id = H5Dopen2(g_id, "data", H5P_DEFAULT);
if (ds_id <= 0) { if (ds_id <= 0) {
@@ -122,10 +116,8 @@ done:
return retval; return retval;
} }
int get_frame_simple(const struct ds_desc_t *desc, int get_frame_simple(const struct ds_desc_t *desc, const char *name,
const char *name, const hsize_t *frame_idx, const hsize_t *frame_size,
const hsize_t *frame_idx,
const hsize_t *frame_size,
void *buffer) { void *buffer) {
int retval = 0; int retval = 0;
@@ -148,7 +140,8 @@ int get_frame_simple(const struct ds_desc_t *desc,
if (t_id <= 0) { if (t_id <= 0) {
ERROR_JUMP(-1, close_type, "Error retrieving datatype"); ERROR_JUMP(-1, close_type, "Error retrieving datatype");
} }
err = H5Sselect_hyperslab(s_id, H5S_SELECT_SET, frame_idx, NULL, frame_size, NULL); err = H5Sselect_hyperslab(s_id, H5S_SELECT_SET, frame_idx, NULL, frame_size,
NULL);
if (err < 0) { if (err < 0) {
ERROR_JUMP(-1, close_space, "Error seleting hyperslab"); ERROR_JUMP(-1, close_space, "Error seleting hyperslab");
} }
@@ -174,11 +167,8 @@ done:
return retval; return retval;
} }
int get_frame_from_chunk(const struct ds_desc_t *desc, const char *ds_name,
int get_frame_from_chunk(const struct ds_desc_t *desc, const hsize_t *frame_idx, const hsize_t *frame_size,
const char *ds_name,
const hsize_t *frame_idx,
const hsize_t *frame_size,
void *buffer) { void *buffer) {
hid_t d_id = 0; hid_t d_id = 0;
@@ -186,12 +176,14 @@ int get_frame_from_chunk(const struct ds_desc_t *desc,
uint32_t c_filter_mask = 0; uint32_t c_filter_mask = 0;
hsize_t c_bytes; hsize_t c_bytes;
void *c_buffer = NULL; void *c_buffer = NULL;
const struct opt_eiger_ds_desc_t *o_eiger_desc = (struct opt_eiger_ds_desc_t *) desc; const struct opt_eiger_ds_desc_t *o_eiger_desc =
(struct opt_eiger_ds_desc_t *)desc;
int retval = 0; int retval = 0;
if (frame_idx[1] != 0 || frame_idx[2] != 0) { if (frame_idx[1] != 0 || frame_idx[2] != 0) {
char message[64]; char message[64];
sprintf(message, "Require frame selection starts at [n, 0, 0], not [n, %llu, %llu]", sprintf(message,
"Require frame selection starts at [n, 0, 0], not [n, %llu, %llu]",
frame_idx[1], frame_idx[2]); frame_idx[1], frame_idx[2]);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
@@ -203,15 +195,16 @@ int get_frame_from_chunk(const struct ds_desc_t *desc,
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
if (H5Dget_chunk_storage_size(d_id, c_offset, &c_bytes) < 0) { if (H5Dget_chunk_storage_size(d_id, c_offset, &c_bytes) < 0) {
char message[96]; char message[96];
sprintf(message, "Error reading chunk size from %.32s for frame %llu", ds_name, frame_idx[0]); sprintf(message, "Error reading chunk size from %.32s for frame %llu",
ds_name, frame_idx[0]);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
if (c_bytes == 0) { if (c_bytes == 0) {
char message[96]; char message[96];
sprintf(message, "Target chunk %llu has zero size for dataset %.32s", frame_idx[0], ds_name); sprintf(message, "Target chunk %llu has zero size for dataset %.32s",
frame_idx[0], ds_name);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
@@ -219,7 +212,9 @@ int get_frame_from_chunk(const struct ds_desc_t *desc,
c_buffer = malloc(c_bytes); c_buffer = malloc(c_bytes);
if (!c_buffer) { if (!c_buffer) {
char message[128]; char message[128];
sprintf(message, "Unable to allocate chunk buffer for dataset %.32s - frame %llu, size %llu bytes", sprintf(message,
"Unable to allocate chunk buffer for dataset %.32s - frame %llu, "
"size %llu bytes",
ds_name, frame_idx[0], c_bytes); ds_name, frame_idx[0], c_bytes);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
@@ -227,38 +222,36 @@ int get_frame_from_chunk(const struct ds_desc_t *desc,
c_buffer = buffer; c_buffer = buffer;
} }
if (H5DOread_chunk(d_id, H5P_DEFAULT, c_offset, &c_filter_mask, c_buffer) < 0) { if (H5DOread_chunk(d_id, H5P_DEFAULT, c_offset, &c_filter_mask, c_buffer) <
0) {
char message[128]; char message[128];
sprintf(message, "Error reading chunk %llu from dataset %.32s - size %llu bytes", sprintf(message,
"Error reading chunk %llu from dataset %.32s - size %llu bytes",
frame_idx[0], ds_name, c_bytes); frame_idx[0], ds_name, c_bytes);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
if (o_eiger_desc->bs_applied) { if (o_eiger_desc->bs_applied) {
if (bslz4_decompress( if (bslz4_decompress(o_eiger_desc->bs_params, c_bytes, c_buffer,
o_eiger_desc->bs_params,
c_bytes,
c_buffer,
desc->data_width * frame_size[1] * frame_size[2], desc->data_width * frame_size[1] * frame_size[2],
buffer) < 0) { buffer) < 0) {
char message[128]; char message[128];
sprintf(message, "Error processing chunk %llu from %.32s with bitshuffle_lz4", sprintf(message,
"Error processing chunk %llu from %.32s with bitshuffle_lz4",
frame_idx[0], ds_name); frame_idx[0], ds_name);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
} }
done: done:
if (c_buffer && (c_buffer != buffer)) free(c_buffer); if (c_buffer && (c_buffer != buffer))
if (d_id) H5Dclose(d_id); free(c_buffer);
if (d_id)
H5Dclose(d_id);
return retval; return retval;
} }
int get_nxs_frame(const struct ds_desc_t *desc, const int n, void *buffer) {
int get_nxs_frame(
const struct ds_desc_t *desc,
const int n,
void *buffer) {
/* detector data are the two inner most indices */ /* detector data are the two inner most indices */
/* TODO: handle ndims > 3 and select appropriately */ /* TODO: handle ndims > 3 and select appropriately */
int retval = 0; int retval = 0;
@@ -266,7 +259,8 @@ int get_nxs_frame(
hsize_t frame_size[3] = {1, desc->dims[1], desc->dims[2]}; hsize_t frame_size[3] = {1, desc->dims[1], desc->dims[2]};
if (n < 0 || n >= desc->dims[0]) { if (n < 0 || n >= desc->dims[0]) {
char message[64]; char message[64];
sprintf(message, "Selected frame %d is out of range valid range [0, %d]", n, (int) desc->dims[0] - 1); sprintf(message, "Selected frame %d is out of range valid range [0, %d]", n,
(int)desc->dims[0] - 1);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
retval = get_frame_simple(desc, "data", frame_idx, frame_size, buffer); retval = get_frame_simple(desc, "data", frame_idx, frame_size, buffer);
@@ -277,33 +271,33 @@ done:
return retval; return retval;
} }
int get_dectris_eiger_frame(const struct ds_desc_t *desc, int n, void *buffer) {
int get_dectris_eiger_frame(
const struct ds_desc_t *desc,
int n,
void *buffer) {
int retval = 0; int retval = 0;
int block, frame_count, idx; int block, frame_count, idx;
struct eiger_ds_desc_t *eiger_desc = (struct eiger_ds_desc_t*) desc; struct eiger_ds_desc_t *eiger_desc = (struct eiger_ds_desc_t *)desc;
char data_name[16] = {0}; char data_name[16] = {0};
hsize_t frame_idx[3] = {0, 0, 0}; hsize_t frame_idx[3] = {0, 0, 0};
hsize_t frame_size[3] = {1, desc->dims[1], desc->dims[2]}; hsize_t frame_size[3] = {1, desc->dims[1], desc->dims[2]};
if (n < 0 || n >= desc->dims[0]) { if (n < 0 || n >= desc->dims[0]) {
char message[64]; char message[64];
sprintf(message, "Selected frame %d is out of range valid range [0, %d]", n, (int) desc->dims[0] - 1); sprintf(message, "Selected frame %d is out of range valid range [0, %d]", n,
(int)desc->dims[0] - 1);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
/* determine the relevant data block */ /* determine the relevant data block */
frame_count = 0; frame_count = 0;
block = 0; block = 0;
while ((frame_count += eiger_desc->block_sizes[block]) <= n) block++; while ((frame_count += eiger_desc->block_sizes[block]) <= n)
idx = n - (frame_count - eiger_desc->block_sizes[block]); /* index in current block */ block++;
idx = n - (frame_count -
eiger_desc->block_sizes[block]); /* index in current block */
frame_idx[0] = idx; frame_idx[0] = idx;
sprintf(data_name, "data_%06d", block + 1); sprintf(data_name, "data_%06d", block + 1);
retval = eiger_desc->frame_func(desc, data_name, frame_idx, frame_size, buffer); retval =
eiger_desc->frame_func(desc, data_name, frame_idx, frame_size, buffer);
if (retval < 0) { if (retval < 0) {
ERROR_JUMP(retval, done, ""); ERROR_JUMP(retval, done, "");
} }
@@ -311,7 +305,6 @@ done:
return retval; return retval;
} }
int get_dectris_eiger_dataset_dims(struct ds_desc_t *desc) { int get_dectris_eiger_dataset_dims(struct ds_desc_t *desc) {
int retval = 0; int retval = 0;
int n_datas = 0; int n_datas = 0;
@@ -321,9 +314,10 @@ int get_dectris_eiger_dataset_dims(struct ds_desc_t *desc) {
char ds_name[16] = {0}; /* 12 chars in "data_xxxxxx\0" */ char ds_name[16] = {0}; /* 12 chars in "data_xxxxxx\0" */
int *frame_counts = NULL; int *frame_counts = NULL;
hsize_t dims[3] = {0}; hsize_t dims[3] = {0};
struct eiger_ds_desc_t *eiger_desc = (struct eiger_ds_desc_t*) desc; struct eiger_ds_desc_t *eiger_desc = (struct eiger_ds_desc_t *)desc;
/* datasets are "data_%06d % n" - need to determine how many of these there are and what the ranges are */ /* datasets are "data_%06d % n" - need to determine how many of these there
* are and what the ranges are */
sprintf(ds_name, "data_%06d", n_datas + 1); sprintf(ds_name, "data_%06d", n_datas + 1);
while (H5Lexists(desc->data_g_id, ds_name, H5P_DEFAULT) > 0) { while (H5Lexists(desc->data_g_id, ds_name, H5P_DEFAULT) > 0) {
@@ -339,7 +333,7 @@ int get_dectris_eiger_dataset_dims(struct ds_desc_t *desc) {
ds_id = H5Dopen2(desc->data_g_id, ds_name, H5P_DEFAULT); ds_id = H5Dopen2(desc->data_g_id, ds_name, H5P_DEFAULT);
if (ds_id < 0) { if (ds_id < 0) {
char message[64]; char message[64];
sprintf("Unable to open dataset %.16s", ds_name); sprintf(message, "Unable to open dataset %.16s", ds_name);
ERROR_JUMP(-1, loop_end, message); ERROR_JUMP(-1, loop_end, message);
} }
t_id = H5Dget_type(ds_id); t_id = H5Dget_type(ds_id);
@@ -359,7 +353,8 @@ int get_dectris_eiger_dataset_dims(struct ds_desc_t *desc) {
ndims = H5Sget_simple_extent_ndims(s_id); ndims = H5Sget_simple_extent_ndims(s_id);
if (ndims != 3) { if (ndims != 3) {
char message[64]; char message[64];
sprintf(message, "Dataset %.16s has rank %d, expected %d", ds_name, ndims, 3); sprintf(message, "Dataset %.16s has rank %d, expected %d", ds_name, ndims,
3);
ERROR_JUMP(-1, close_space, message); ERROR_JUMP(-1, close_space, message);
} }
if (H5Sget_simple_extent_dims(s_id, block_dims, NULL) < 0) { if (H5Sget_simple_extent_dims(s_id, block_dims, NULL) < 0) {
@@ -372,14 +367,15 @@ int get_dectris_eiger_dataset_dims(struct ds_desc_t *desc) {
dims[0] += block_dims[0]; dims[0] += block_dims[0];
frame_counts[n] = block_dims[0]; frame_counts[n] = block_dims[0];
close_space: close_space:
H5Sclose(s_id); H5Sclose(s_id);
close_type: close_type:
H5Tclose(t_id); H5Tclose(t_id);
close_dataset: close_dataset:
H5Dclose(ds_id); H5Dclose(ds_id);
loop_end: loop_end:
if (retval < 0) break; if (retval < 0)
break;
} }
if (retval < 0) { if (retval < 0) {
@@ -393,7 +389,6 @@ loop_end:
return retval; return retval;
} }
int read_pixel_info(hid_t g_id, const char *path, double *size) { int read_pixel_info(hid_t g_id, const char *path, double *size) {
/* /*
* NXdetector allows pixel size to be an array (for varied pixel size), * NXdetector allows pixel size to be an array (for varied pixel size),
@@ -401,7 +396,8 @@ int read_pixel_info(hid_t g_id, const char *path, double *size) {
* TODO: handle array case (return first value maybe?) * TODO: handle array case (return first value maybe?)
*/ */
/* read the scalar dataset value and scale according to the unit in the attribute */ /* read the scalar dataset value and scale according to the unit in the
* attribute */
/* returned value is in metres */ /* returned value is in metres */
int retval = 0; int retval = 0;
herr_t err = 0; herr_t err = 0;
@@ -410,14 +406,15 @@ int read_pixel_info(hid_t g_id, const char *path, double *size) {
ds_id = H5Dopen2(g_id, path, H5P_DEFAULT); ds_id = H5Dopen2(g_id, path, H5P_DEFAULT);
if (ds_id < 0) { if (ds_id < 0) {
char message[64]; char message[64];
sprintf("Error opening dataset %.32s", path); sprintf(message, "Error opening dataset %.32s", path);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
err = H5Dread(ds_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value); err =
H5Dread(ds_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
if (err < 0) { if (err < 0) {
char message[64]; char message[64];
sprintf("Error reading dataset %.32s", path); sprintf(message, "Error reading dataset %.32s", path);
ERROR_JUMP(-1, close_dataset, message); ERROR_JUMP(-1, close_dataset, message);
} }
@@ -429,8 +426,10 @@ int read_pixel_info(hid_t g_id, const char *path, double *size) {
double scale = 1; double scale = 1;
a_id = H5Aopen(ds_id, "units", H5P_DEFAULT); a_id = H5Aopen(ds_id, "units", H5P_DEFAULT);
if (a_id < 0) { if (a_id < 0) {
char message[64]; char message[100];
sprintf("Error openeing units attribute for %.32s after existence check", path); sprintf(message,
"Error openeing units attribute for %.32s after existence check",
path);
ERROR_JUMP(-1, close_dataset, message); ERROR_JUMP(-1, close_dataset, message);
} }
@@ -441,14 +440,16 @@ int read_pixel_info(hid_t g_id, const char *path, double *size) {
/* TODO: handle multiple strings in attribute (just detect and error) */ /* TODO: handle multiple strings in attribute (just detect and error) */
if (H5Tis_variable_str(t_id) > 0) { if (H5Tis_variable_str(t_id) > 0) {
str_size = -1; str_size = -1;
str_buffer = malloc(sizeof(char*)); str_buffer = malloc(sizeof(char *));
} else { } else {
str_size = H5Tget_size(t_id); str_size = H5Tget_size(t_id);
/* do not assume room has been left for null-byte in fixed length string */ /* do not assume room has been left for null-byte in fixed length string
*/
str_buffer = malloc(str_size + 1); str_buffer = malloc(str_size + 1);
} }
if (str_buffer == NULL) { if (str_buffer == NULL) {
ERROR_JUMP(-1, close_datatype, "Unable to allocate space for variable length string"); ERROR_JUMP(-1, close_datatype,
"Unable to allocate space for variable length string");
} }
mt_id = H5Tcopy(H5T_C_S1); mt_id = H5Tcopy(H5T_C_S1);
if (mt_id < 0) { if (mt_id < 0) {
@@ -466,9 +467,11 @@ int read_pixel_info(hid_t g_id, const char *path, double *size) {
ERROR_JUMP(-1, close_mem_datatype, "Error reading units attribute"); ERROR_JUMP(-1, close_mem_datatype, "Error reading units attribute");
} }
/* ensure last byte is null */ /* ensure last byte is null */
if (str_size > 0) ((char*) str_buffer)[str_size] = '\0'; if (str_size > 0)
((char *)str_buffer)[str_size] = '\0';
scale = scale_from_units(str_size == -1 ? *(char**)str_buffer : (char*)str_buffer); scale = scale_from_units(str_size == -1 ? *(char **)str_buffer
: (char *)str_buffer);
value *= scale; value *= scale;
if (str_size == -1) { if (str_size == -1) {
@@ -481,26 +484,26 @@ int read_pixel_info(hid_t g_id, const char *path, double *size) {
H5Dvlen_reclaim(mt_id, s_id, H5P_DEFAULT, str_buffer); H5Dvlen_reclaim(mt_id, s_id, H5P_DEFAULT, str_buffer);
H5Sclose(s_id); H5Sclose(s_id);
} }
close_mem_datatype: close_mem_datatype:
H5Tclose(mt_id); H5Tclose(mt_id);
free_string: free_string:
free(str_buffer); free(str_buffer);
close_datatype: close_datatype:
H5Tclose(t_id); H5Tclose(t_id);
close_attribute: close_attribute:
H5Aclose(a_id); H5Aclose(a_id);
} /* if H5Aexists(...) */ } /* if H5Aexists(...) */
close_dataset: close_dataset:
H5Dclose(ds_id); H5Dclose(ds_id);
done: done:
if (retval == 0) *size = value; if (retval == 0)
*size = value;
return retval; return retval;
} }
int get_nxs_pixel_info(const struct ds_desc_t *desc, double *x_size,
int get_nxs_pixel_info(const struct ds_desc_t *desc, double *x_size, double *y_size) { double *y_size) {
int retval = 0; int retval = 0;
if (read_pixel_info(desc->det_g_id, "x_pixel_size", x_size) < 0) { if (read_pixel_info(desc->det_g_id, "x_pixel_size", x_size) < 0) {
ERROR_JUMP(-1, done, ""); ERROR_JUMP(-1, done, "");
@@ -512,20 +515,21 @@ done:
return retval; return retval;
} }
int get_dectris_eiger_pixel_info(const struct ds_desc_t *desc, double *x_size,
int get_dectris_eiger_pixel_info(const struct ds_desc_t *desc, double *x_size, double *y_size) { double *y_size) {
int retval = 0; int retval = 0;
if (read_pixel_info(desc->det_g_id, "detectorSpecific/x_pixel_size", x_size) < 0) { if (read_pixel_info(desc->det_g_id, "detectorSpecific/x_pixel_size", x_size) <
0) {
ERROR_JUMP(-1, done, ""); ERROR_JUMP(-1, done, "");
} }
if (read_pixel_info(desc->det_g_id, "detectorSpecific/y_pixel_size", y_size) < 0) { if (read_pixel_info(desc->det_g_id, "detectorSpecific/y_pixel_size", y_size) <
0) {
ERROR_JUMP(-1, done, ""); ERROR_JUMP(-1, done, "");
} }
done: done:
return retval; return retval;
} }
int get_nxs_pixel_mask(const struct ds_desc_t *desc, int *buffer) { int get_nxs_pixel_mask(const struct ds_desc_t *desc, int *buffer) {
int retval = 0; int retval = 0;
hid_t ds_id; hid_t ds_id;
@@ -547,7 +551,6 @@ done:
return retval; return retval;
} }
int get_dectris_eiger_pixel_mask(const struct ds_desc_t *desc, int *buffer) { int get_dectris_eiger_pixel_mask(const struct ds_desc_t *desc, int *buffer) {
int retval = 0; int retval = 0;
hid_t ds_id; hid_t ds_id;
@@ -569,19 +572,19 @@ done:
return retval; return retval;
} }
int get_null_pixel_mask(const struct ds_desc_t *desc, int *buffer) { int get_null_pixel_mask(const struct ds_desc_t *desc, int *buffer) {
hsize_t buffer_length = desc->dims[1] * desc->dims[2]; hsize_t buffer_length = desc->dims[1] * desc->dims[2];
memset(buffer, 0, sizeof(*buffer) * buffer_length); memset(buffer, 0, sizeof(*buffer) * buffer_length);
return 0; return 0;
} }
herr_t det_visit_callback(hid_t root_id, const char *name,
herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *info, void *op_data) { const H5O_info_t *info, void *op_data) {
struct det_visit_objects_t *output_data = op_data; struct det_visit_objects_t *output_data = op_data;
hid_t g_id; hid_t g_id;
herr_t retval = 0; herr_t retval = 0;
if (info->type != H5O_TYPE_GROUP) return 0; if (info->type != H5O_TYPE_GROUP)
return 0;
g_id = H5Oopen(root_id, name, H5P_DEFAULT); g_id = H5Oopen(root_id, name, H5P_DEFAULT);
if (g_id < 0) { if (g_id < 0) {
char message[256]; char message[256];
@@ -592,7 +595,7 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
/* check for an "NX_class" attribute */ /* check for an "NX_class" attribute */
{ {
int str_size = 0; int str_size = 0;
void* buffer = NULL; void *buffer = NULL;
hid_t a_id, t_id, mt_id; hid_t a_id, t_id, mt_id;
if (H5Aexists(g_id, "NX_class") <= 0) { if (H5Aexists(g_id, "NX_class") <= 0) {
/* not an error - just close group and allow continuation */ /* not an error - just close group and allow continuation */
@@ -603,7 +606,8 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
if (a_id <= 0) { if (a_id <= 0) {
char message[256]; char message[256];
sprintf(message, sprintf(message,
"H5OVisit callback: Error opening NX_class attribute on %.128s after existence check", "H5OVisit callback: Error opening NX_class attribute on %.128s "
"after existence check",
name); name);
ERROR_JUMP(-1, close_group, message); ERROR_JUMP(-1, close_group, message);
} }
@@ -614,7 +618,7 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
} }
if (H5Tis_variable_str(t_id) > 0) { if (H5Tis_variable_str(t_id) > 0) {
str_size = -1; str_size = -1;
buffer = malloc(sizeof(char*)); buffer = malloc(sizeof(char *));
} else { } else {
str_size = H5Tget_size(t_id); str_size = H5Tget_size(t_id);
buffer = malloc(str_size + 1); buffer = malloc(str_size + 1);
@@ -627,7 +631,12 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
if (mt_id < 0) { if (mt_id < 0) {
ERROR_JUMP(-1, free_buffer, "Error creating HDF5 String datatype"); ERROR_JUMP(-1, free_buffer, "Error creating HDF5 String datatype");
} }
if (H5Tset_size(mt_id, str_size == -1 ? H5T_VARIABLE : str_size) < 0) { // set the target string type to be one longer than the recorded string
// in keeping with the malloc'd buffer - if this is already a null
// terminated string then we will just have two nulls, if it is not
// then we won't clobber the last char in the buffer with a null in the
// H5Aread call
if (H5Tset_size(mt_id, str_size == -1 ? H5T_VARIABLE : str_size + 1) < 0) {
char message[64]; char message[64];
sprintf(message, "Error setting string datatype to size %d", str_size); sprintf(message, "Error setting string datatype to size %d", str_size);
ERROR_JUMP(-1, close_mtype, message); ERROR_JUMP(-1, close_mtype, message);
@@ -635,19 +644,19 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
if (H5Aread(a_id, mt_id, buffer) < 0) { if (H5Aread(a_id, mt_id, buffer) < 0) {
char message[256]; char message[256];
sprintf(message, sprintf(
message,
"H5OVisit callback: Error reading NX_class attribute on group %.128s", "H5OVisit callback: Error reading NX_class attribute on group %.128s",
name); name);
ERROR_JUMP(-1, close_mtype, message); ERROR_JUMP(-1, close_mtype, message);
} }
/* at least one file has been seen where the NX_class attribute was not null terminated /* ensure the buffer is null terminated */
* and extraneous bytes where being read by strcmp - set the end byte to null buffer[H5Tget_size(t_id)] = '\0';
*/
if (str_size > 0) ((char*) buffer)[str_size] = '\0';
/* test for NXdata or NXdetector */ /* test for NXdata or NXdetector */
{ {
char *nxclass = str_size > 0 ? (char*) buffer : *((char**) buffer); char *nxclass = str_size > 0 ? (char *)buffer : *((char **)buffer);
if (strcmp("NXdata", nxclass) == 0) { if (strcmp("NXdata", nxclass) == 0) {
hid_t out_id = H5Gopen(root_id, name, H5P_DEFAULT); hid_t out_id = H5Gopen(root_id, name, H5P_DEFAULT);
output_data->nxdata = out_id; output_data->nxdata = out_id;
@@ -665,13 +674,13 @@ herr_t det_visit_callback(hid_t root_id, const char *name, const H5O_info_t *inf
H5Sclose(s_id); H5Sclose(s_id);
} }
close_mtype: close_mtype:
H5Tclose(mt_id); H5Tclose(mt_id);
free_buffer: free_buffer:
free(buffer); free(buffer);
close_type: close_type:
H5Tclose(t_id); H5Tclose(t_id);
close_attr: close_attr:
H5Aclose(a_id); H5Aclose(a_id);
} }
@@ -684,9 +693,7 @@ done:
return retval; return retval;
} }
int check_for_chunk_read( int check_for_chunk_read(hid_t g_id, const char *ds_name,
hid_t g_id,
const char* ds_name,
struct opt_eiger_ds_desc_t *desc) { struct opt_eiger_ds_desc_t *desc) {
int retval = 0; int retval = 0;
@@ -752,10 +759,8 @@ int check_for_chunk_read(
} }
if (n_filters == 1) { if (n_filters == 1) {
filter = H5Pget_filter2(dcpl, 0, &filter_flags, filter = H5Pget_filter2(dcpl, 0, &filter_flags, &cd_nelems, desc->bs_params,
&cd_nelems, desc->bs_params, name_len, filter_name, &filter_config);
name_len, filter_name,
&filter_config);
if (filter < 0) { if (filter < 0) {
ERROR_JUMP(-1, done, "Error retrieving filter information"); ERROR_JUMP(-1, done, "Error retrieving filter information");
} }
@@ -765,7 +770,8 @@ int check_for_chunk_read(
if (cd_nelems > BS_H5_N_PARAMS) { if (cd_nelems > BS_H5_N_PARAMS) {
char message[128]; char message[128];
sprintf(message, sprintf(message,
"More than expected number of parameters to bitshuffle filter - expected %d, was %lu", "More than expected number of parameters to bitshuffle filter - "
"expected %d, was %lu",
BS_H5_N_PARAMS, cd_nelems); BS_H5_N_PARAMS, cd_nelems);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
@@ -777,31 +783,37 @@ int check_for_chunk_read(
retval = 1; retval = 1;
done: done:
if (dcpl) H5Pclose(dcpl); if (dcpl)
if (s_id) H5Sclose(s_id); H5Pclose(dcpl);
if (ds_id) H5Dclose(ds_id); if (s_id)
H5Sclose(s_id);
if (ds_id)
H5Dclose(ds_id);
return retval; return retval;
} }
int create_dataset_descriptor(struct ds_desc_t **desc, struct det_visit_objects_t *visit_result) { int create_dataset_descriptor(struct ds_desc_t **desc,
struct det_visit_objects_t *visit_result) {
int retval = 0; int retval = 0;
hid_t g_id, ds_id; hid_t g_id, ds_id;
int (*pxl_func)(const struct ds_desc_t*, double*, double*); int (*pxl_func)(const struct ds_desc_t *, double *, double *);
int (*pxl_mask_func)(const struct ds_desc_t*, int*); int (*pxl_mask_func)(const struct ds_desc_t *, int *);
int (*ds_prop_func)(struct ds_desc_t*); int (*ds_prop_func)(struct ds_desc_t *);
int (*frame_func)(const struct ds_desc_t*, int, void*); int (*frame_func)(const struct ds_desc_t *, int, void *);
void (*free_func)(struct ds_desc_t*); void (*free_func)(struct ds_desc_t *);
struct ds_desc_t *output; struct ds_desc_t *output;
g_id = visit_result->nxdetector; g_id = visit_result->nxdetector;
/* determine the pixel information location */ /* determine the pixel information location */
if (H5Lexists(g_id, "x_pixel_size", H5P_DEFAULT) > 0 && if (H5Lexists(g_id, "x_pixel_size", H5P_DEFAULT) > 0 &&
H5Lexists(g_id, "y_pixel_size", H5P_DEFAULT)) { H5Lexists(g_id, "y_pixel_size", H5P_DEFAULT) > 0) {
pxl_func = &get_nxs_pixel_info; pxl_func = &get_nxs_pixel_info;
} else if (H5Lexists(g_id, "detectorSpecific", H5P_DEFAULT) > 0 && } else if (H5Lexists(g_id, "detectorSpecific", H5P_DEFAULT) > 0 &&
H5Lexists(g_id, "detectorSpecific/x_pixel_size", H5P_DEFAULT) > 0 && H5Lexists(g_id, "detectorSpecific/x_pixel_size", H5P_DEFAULT) >
H5Lexists(g_id, "detectorSpecific/y_pixel_size", H5P_DEFAULT) > 0) { 0 &&
H5Lexists(g_id, "detectorSpecific/y_pixel_size", H5P_DEFAULT) >
0) {
pxl_func = &get_dectris_eiger_pixel_info; pxl_func = &get_dectris_eiger_pixel_info;
} else { } else {
ERROR_JUMP(-1, done, "Could not locate x_pixel_size and y_pixel_size"); ERROR_JUMP(-1, done, "Could not locate x_pixel_size and y_pixel_size");
@@ -815,7 +827,9 @@ int create_dataset_descriptor(struct ds_desc_t **desc, struct det_visit_objects_
pxl_mask_func = &get_dectris_eiger_pixel_mask; pxl_mask_func = &get_dectris_eiger_pixel_mask;
} else { } else {
pxl_mask_func = &get_null_pixel_mask; pxl_mask_func = &get_null_pixel_mask;
fprintf(stderr, "WARNING: Could not find pixel mask - no masking will be applied\n"); fprintf(
stderr,
"WARNING: Could not find pixel mask - no masking will be applied\n");
} }
/* determine where the data is stored and what strategy to use */ /* determine where the data is stored and what strategy to use */
@@ -844,7 +858,6 @@ int create_dataset_descriptor(struct ds_desc_t **desc, struct det_visit_objects_
ERROR_JUMP(-1, done, "Could not locate detector dataset"); ERROR_JUMP(-1, done, "Could not locate detector dataset");
} }
if (ds_prop_func == &get_dectris_eiger_dataset_dims) { if (ds_prop_func == &get_dectris_eiger_dataset_dims) {
/* setup the "extra info" structs */ /* setup the "extra info" structs */
@@ -861,7 +874,8 @@ int create_dataset_descriptor(struct ds_desc_t **desc, struct det_visit_objects_
o_eiger_desc = malloc(sizeof(*o_eiger_desc)); o_eiger_desc = malloc(sizeof(*o_eiger_desc));
if (!o_eiger_desc) { if (!o_eiger_desc) {
free(eiger_desc); free(eiger_desc);
ERROR_JUMP(-1, done, "Memory error creating data description for optimised Eiger"); ERROR_JUMP(-1, done,
"Memory error creating data description for optimised Eiger");
} }
o_eiger_desc->base.frame_func = &get_frame_from_chunk; o_eiger_desc->base.frame_func = &get_frame_from_chunk;
@@ -874,11 +888,11 @@ int create_dataset_descriptor(struct ds_desc_t **desc, struct det_visit_objects_
} }
if (retval) { if (retval) {
free(eiger_desc); free(eiger_desc);
*(struct opt_eiger_ds_desc_t**) desc = o_eiger_desc; *(struct opt_eiger_ds_desc_t **)desc = o_eiger_desc;
free_func = &free_opt_eiger_desc; free_func = &free_opt_eiger_desc;
} else { } else {
free(o_eiger_desc); free(o_eiger_desc);
*(struct eiger_ds_desc_t**) desc = eiger_desc; *(struct eiger_ds_desc_t **)desc = eiger_desc;
free_func = &free_eiger_desc; free_func = &free_eiger_desc;
} }
@@ -887,7 +901,7 @@ int create_dataset_descriptor(struct ds_desc_t **desc, struct det_visit_objects_
free_func = &free_nxs_desc; free_func = &free_nxs_desc;
} }
output = *((struct ds_desc_t **) desc); output = *((struct ds_desc_t **)desc);
output->det_g_id = g_id; output->det_g_id = g_id;
output->data_g_id = ds_id; output->data_g_id = ds_id;
output->get_pixel_properties = pxl_func; output->get_pixel_properties = pxl_func;
@@ -901,15 +915,13 @@ done:
return retval; return retval;
} }
int get_detector_info(const hid_t fid, struct ds_desc_t **desc) {
int get_detector_info(
const hid_t fid,
struct ds_desc_t **desc) {
int retval = 0; int retval = 0;
herr_t err = 0; herr_t err = 0;
struct det_visit_objects_t objects = {0}; struct det_visit_objects_t objects = {0};
err = H5Ovisit(fid, H5_INDEX_NAME, H5_ITER_INC, &det_visit_callback, &objects); err =
H5Ovisit(fid, H5_INDEX_NAME, H5_ITER_INC, &det_visit_callback, &objects);
if (err < 0) { if (err < 0) {
clear_det_visit_objects(&objects); clear_det_visit_objects(&objects);
ERROR_JUMP(-1, done, "Error during H5Ovisit callback"); ERROR_JUMP(-1, done, "Error during H5Ovisit callback");
@@ -925,7 +937,6 @@ int get_detector_info(
ERROR_JUMP(retval, done, ""); ERROR_JUMP(retval, done, "");
}; };
done: done:
return retval; return retval;
} }
+7 -8
View File
@@ -3,24 +3,22 @@
* Author: Charles Mita * Author: Charles Mita
*/ */
#ifndef NXS_XDS_FILE_H #ifndef NXS_XDS_FILE_H
#define NXS_XDS_FILE_H #define NXS_XDS_FILE_H
#include <hdf5.h>
#include "err.h" #include "err.h"
#include "filters.h" #include "filters.h"
#include <hdf5.h>
struct ds_desc_t { struct ds_desc_t {
hid_t det_g_id; hid_t det_g_id;
hid_t data_g_id; hid_t data_g_id;
hsize_t dims[3]; hsize_t dims[3];
int data_width; int data_width;
int (*get_pixel_properties)(const struct ds_desc_t*, double*, double*); int (*get_pixel_properties)(const struct ds_desc_t *, double *, double *);
int (*get_pixel_mask)(const struct ds_desc_t*, int*); int (*get_pixel_mask)(const struct ds_desc_t *, int *);
int (*get_data_frame)(const struct ds_desc_t*, const int, void*); int (*get_data_frame)(const struct ds_desc_t *, const int, void *);
void (*free_desc)(struct ds_desc_t*); void (*free_desc)(struct ds_desc_t *);
}; };
struct nxs_ds_desc_t { struct nxs_ds_desc_t {
@@ -31,7 +29,8 @@ struct eiger_ds_desc_t {
struct ds_desc_t base; struct ds_desc_t base;
int n_data_blocks; int n_data_blocks;
int *block_sizes; int *block_sizes;
int (*frame_func)(const struct ds_desc_t*, const char*, const hsize_t*, const hsize_t*, void*); int (*frame_func)(const struct ds_desc_t *, const char *, const hsize_t *,
const hsize_t *, void *);
}; };
struct opt_eiger_ds_desc_t { struct opt_eiger_ds_desc_t {
+14 -14
View File
@@ -4,24 +4,21 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include "filters.h"
#include "err.h"
#include "bitshuffle.h" #include "bitshuffle.h"
#include "err.h"
#include "filters.h"
/* Required prototypes from bitshuffle.c but not included in header */ /* Required prototypes from bitshuffle.c but not included in header */
uint64_t bshuf_read_uint64_BE(const void *buffer); uint64_t bshuf_read_uint64_BE(const void *buffer);
uint32_t bshuf_read_uint32_BE(const void *buffer); uint32_t bshuf_read_uint32_BE(const void *buffer);
/* /*
* Derived from the h5 filter code from the bitshuffle project (not included here) * Derived from the h5 filter code from the bitshuffle project (not included
* here)
*/ */
int bslz4_decompress( int bslz4_decompress(const unsigned int *bs_params, size_t in_size,
const unsigned int* bs_params, void *in_buffer, size_t out_size, void *out_buffer) {
size_t in_size,
void *in_buffer,
size_t out_size,
void *out_buffer) {
int retval = 0; int retval = 0;
size_t size, elem_size, block_size, u_bytes; size_t size, elem_size, block_size, u_bytes;
@@ -31,11 +28,12 @@ int bslz4_decompress(
if (u_bytes != out_size) { if (u_bytes != out_size) {
char message[64]; char message[64];
sprintf(message, "Decompressed chunk is %lu bytes, expected %lu", u_bytes, out_size); sprintf(message, "Decompressed chunk is %lu bytes, expected %lu", u_bytes,
out_size);
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
block_size = bshuf_read_uint32_BE((const char *) in_buffer + 8) / elem_size; block_size = bshuf_read_uint32_BE((const char *)in_buffer + 8) / elem_size;
if (!block_size) { if (!block_size) {
ERROR_JUMP(-1, done, "Read block bitshuffle lz4 block size as 0"); ERROR_JUMP(-1, done, "Read block bitshuffle lz4 block size as 0");
} }
@@ -44,11 +42,13 @@ int bslz4_decompress(
size = u_bytes / elem_size; size = u_bytes / elem_size;
if (bs_params[4] == BS_H5_PARAM_LZ4_COMPRESS) { if (bs_params[4] == BS_H5_PARAM_LZ4_COMPRESS) {
if (bshuf_decompress_lz4(in_buffer, out_buffer, size, elem_size, block_size) < 0) { if (bshuf_decompress_lz4(in_buffer, out_buffer, size, elem_size,
block_size) < 0) {
ERROR_JUMP(-1, done, "Error performing bitshuffle_lz4 decompression"); ERROR_JUMP(-1, done, "Error performing bitshuffle_lz4 decompression");
} }
} else { } else {
if (bshuf_bitunshuffle(in_buffer, out_buffer, size, elem_size, block_size) < 0) { if (bshuf_bitunshuffle(in_buffer, out_buffer, size, elem_size, block_size) <
0) {
ERROR_JUMP(-1, done, "Error performing bit unshuffle"); ERROR_JUMP(-1, done, "Error performing bit unshuffle");
} }
} }
+2 -8
View File
@@ -10,13 +10,7 @@
#define BS_H5_FILTER_ID 32008 #define BS_H5_FILTER_ID 32008
#define BS_H5_PARAM_LZ4_COMPRESS 2 #define BS_H5_PARAM_LZ4_COMPRESS 2
int bslz4_decompress(const unsigned int *bs_params, size_t in_size,
void *in_buffer, size_t out_size, void *out_buffer);
int bslz4_decompress(
const unsigned int* bs_params,
size_t in_size,
void *in_buffer,
size_t out_size,
void *out_buffer);
#endif /* NXS_XDS_FILTER_H */ #endif /* NXS_XDS_FILTER_H */
+44 -49
View File
@@ -3,56 +3,55 @@
* Author: Charles Mita * Author: Charles Mita
*/ */
#include <hdf5.h> #include <hdf5.h>
#include <stdlib.h> #include <stdlib.h>
#include "file.h" #include "file.h"
#include "filters.h" #include "filters.h"
#include "plugin.h" #include "plugin.h"
/* XDS does not provide an error callback facility, so just write to stderr
/* XDS does not provide an error callback facility, so just write to stderr for now */ for now - generally regarded as poor practice */
/* generally regarded as poor practice */
#define ERROR_OUTPUT stderr #define ERROR_OUTPUT stderr
/* mask bits loosely based on what Neggia does and what NeXus says should be
done basically - anything in the low byte (& 0xFF) means "ignore this"
/* mask bits loosely based on what Neggia does and what NeXus says should be done */ Neggia uses the value -2 if bit 1, 2 or 3 are set */
/* basically - anything in the low byte (& 0xFF) means "ignore this" */
/* Neggia usses the value -2 if bit 1, 2 or 3 are set */
#define COPY_AND_MASK(in, out, size, mask) \ #define COPY_AND_MASK(in, out, size, mask) \
{ \ { \
int i; \ int i; \
if (mask) { \ if (mask) { \
for (i = 0; i < size; ++i) { \ for (i = 0; i < size; ++i) { \
out[i] = in[i]; \ out[i] = in[i]; \
if (mask[i] & 0xFF) out[i] = -1; \ if (mask[i] & 0xFF) \
if (mask[i] & 30) out[i] = -2; \ out[i] = -1; \
if (mask[i] & 30) \
out[i] = -2; \
} \ } \
} else { \ } else { \
for (i = 0; i < size; i++) { \ for (i = 0; i < size; i++) { \
out[i] = in[i]; \ out[i] = in[i]; \
} \ } \
} \ } \
} }
#define APPLY_MASK(buffer, mask, size) \ #define APPLY_MASK(buffer, mask, size) \
{ \ { \
int i; \ int i; \
if (mask) { \ if (mask) { \
for (i = 0; i < size; ++i) { \ for (i = 0; i < size; ++i) { \
if (mask[i] & 0xFF) buffer[i] = -1; \ if (mask[i] & 0xFF) \
if (mask[i] & 30) buffer[i] = -2; \ buffer[i] = -1; \
if (mask[i] & 30) \
buffer[i] = -2; \
} \ } \
} \ } \
} }
static hid_t file_id = 0; static hid_t file_id = 0;
static struct ds_desc_t *data_desc = NULL; static struct ds_desc_t *data_desc = NULL;
static int *mask_buffer = NULL; static int *mask_buffer = NULL;
void fill_info_array(int info[1024]) { void fill_info_array(int info[1024]) {
info[0] = DLS_CUSTOMER_ID; info[0] = DLS_CUSTOMER_ID;
info[1] = VERSION_MAJOR; info[1] = VERSION_MAJOR;
@@ -61,11 +60,13 @@ void fill_info_array(int info[1024]) {
info[4] = VERSION_TIMESTAMP; info[4] = VERSION_TIMESTAMP;
} }
int convert_to_int_and_mask(void *in_buffer, int d_width, int *out_buffer, int length, int *mask) { int convert_to_int_and_mask(void *in_buffer, int d_width, int *out_buffer,
int length, int *mask) {
/* transfer data to output buffer, performing data conversion as required */ /* transfer data to output buffer, performing data conversion as required */
int retval = 0; int retval = 0;
/* TODO: decide how conversion of data should work */ /* TODO: decide how conversion of data should work */
/* Should we sign extend? Neggia doesn't (casts from uint*), but may be more intuitive */ /* Should we sign extend? Neggia doesn't (casts from uint*), but may be more
* intuitive */
if (d_width == sizeof(signed char)) { if (d_width == sizeof(signed char)) {
signed char *in = in_buffer; signed char *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask); COPY_AND_MASK(in, out_buffer, length, mask);
@@ -83,7 +84,8 @@ int convert_to_int_and_mask(void *in_buffer, int d_width, int *out_buffer, int l
COPY_AND_MASK(in, out_buffer, length, mask); COPY_AND_MASK(in, out_buffer, length, mask);
} else { } else {
char message[128]; char message[128];
sprintf(message, "Unsupported conversion of data width %d to %ld (int)", d_width, sizeof(int)); sprintf(message, "Unsupported conversion of data width %d to %ld (int)",
d_width, sizeof(int));
ERROR_JUMP(-1, done, message); ERROR_JUMP(-1, done, message);
} }
done: done:
@@ -94,10 +96,7 @@ done:
extern "C" { extern "C" {
#endif #endif
void plugin_open( void plugin_open(const char *filename, int info[1024], int *error_flag) {
const char *filename,
int info[1024],
int *error_flag) {
int retval = 0; int retval = 0;
*error_flag = 0; *error_flag = 0;
@@ -129,7 +128,9 @@ void plugin_open(
if (mask_buffer) { if (mask_buffer) {
retval = data_desc->get_pixel_mask(data_desc, mask_buffer); retval = data_desc->get_pixel_mask(data_desc, mask_buffer);
if (retval < 0) { if (retval < 0) {
fprintf(ERROR_OUTPUT, "WARNING: Could not read pixel mask - no masking will be applied\n"); fprintf(
ERROR_OUTPUT,
"WARNING: Could not read pixel mask - no masking will be applied\n");
dump_error_stack(ERROR_OUTPUT); dump_error_stack(ERROR_OUTPUT);
free(mask_buffer); free(mask_buffer);
mask_buffer = NULL; mask_buffer = NULL;
@@ -148,21 +149,16 @@ done:
} }
} }
void plugin_get_header(int *nx, int *ny, int *nbytes, float *qx, float *qy,
void plugin_get_header( int *number_of_frames, int info[1024], int *error_flag) {
int *nx, int *ny,
int *nbytes,
float *qx, float *qy,
int *number_of_frames,
int info[1024],
int *error_flag) {
int err = 0; int err = 0;
int retval = 0; int retval = 0;
double x_pixel_size, y_pixel_size; double x_pixel_size, y_pixel_size;
reset_error_stack(); reset_error_stack();
fill_info_array(info); fill_info_array(info);
err = data_desc->get_pixel_properties(data_desc, &x_pixel_size, &y_pixel_size); err =
data_desc->get_pixel_properties(data_desc, &x_pixel_size, &y_pixel_size);
if (err < 0) { if (err < 0) {
ERROR_JUMP(err, done, "Failed to retrieve pixel information"); ERROR_JUMP(err, done, "Failed to retrieve pixel information");
} }
@@ -171,8 +167,8 @@ void plugin_get_header(
*ny = data_desc->dims[1]; *ny = data_desc->dims[1];
*nbytes = data_desc->data_width; *nbytes = data_desc->data_width;
*number_of_frames = data_desc->dims[0]; *number_of_frames = data_desc->dims[0];
*qx = (float) x_pixel_size; *qx = (float)x_pixel_size;
*qy = (float) y_pixel_size; *qy = (float)y_pixel_size;
done: done:
*error_flag = retval; *error_flag = retval;
@@ -181,13 +177,8 @@ done:
} }
} }
void plugin_get_data(int *frame_number, int *nx, int *ny, int *data_array,
void plugin_get_data( int info[1024], int *error_flag) {
int *frame_number,
int *nx, int *ny,
int *data_array,
int info[1024],
int *error_flag) {
int retval = 0; int retval = 0;
int frame_size_px = data_desc->dims[1] * data_desc->dims[2]; int frame_size_px = data_desc->dims[1] * data_desc->dims[2];
@@ -211,7 +202,8 @@ void plugin_get_data(
} }
if (buffer != data_array) { if (buffer != data_array) {
if (convert_to_int_and_mask(buffer, data_desc->data_width, data_array, frame_size_px, mask_buffer) < 0) { if (convert_to_int_and_mask(buffer, data_desc->data_width, data_array,
frame_size_px, mask_buffer) < 0) {
char message[64]; char message[64];
sprintf(message, "Error converting data for frame %d", *frame_number); sprintf(message, "Error converting data for frame %d", *frame_number);
ERROR_JUMP(-2, done, message); ERROR_JUMP(-2, done, message);
@@ -225,10 +217,10 @@ done:
if (retval < 0) { if (retval < 0) {
dump_error_stack(ERROR_OUTPUT); dump_error_stack(ERROR_OUTPUT);
} }
if (buffer && (buffer != data_array)) free(buffer); if (buffer && (buffer != data_array))
free(buffer);
} }
void plugin_close(int *error_flag) { void plugin_close(int *error_flag) {
if (file_id) { if (file_id) {
if (H5Fclose(file_id) < 0) { if (H5Fclose(file_id) < 0) {
@@ -238,7 +230,10 @@ void plugin_close(int *error_flag) {
} }
file_id = 0; file_id = 0;
if (mask_buffer) free(mask_buffer); if (mask_buffer) {
free(mask_buffer);
mask_buffer = NULL;
}
if (data_desc->free_desc) { if (data_desc->free_desc) {
data_desc->free_desc(data_desc); data_desc->free_desc(data_desc);
data_desc = NULL; data_desc = NULL;
+7 -23
View File
@@ -15,39 +15,23 @@
extern "C" { extern "C" {
#endif #endif
#define DLS_CUSTOMER_ID 0x01 /* pretend we're Dectris, otherwise XDS doesn't work */ #define DLS_CUSTOMER_ID \
0x01 /* pretend we're Dectris, otherwise XDS doesn't work */
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_TIMESTAMP -1 /* good enough for Dectris apparantely */ #define VERSION_TIMESTAMP -1 /* good enough for Dectris apparantely */
void plugin_open(const char *filename, int info[1024], int *error_flag);
void plugin_open( void plugin_get_header(int *nx, int *ny, int *nbytes, float *qx, float *qy,
const char *filename, int *number_of_frames, int info[1024], int *error_flag);
int info[1024],
int *error_flag);
void plugin_get_header(
int *nx, int *ny,
int *nbytes,
float *qx, float *qy,
int *number_of_frames,
int info[1024],
int *error_flag);
void plugin_get_data(
int *frame_number,
int *nx, int *ny,
int *data_array,
int info[1024],
int *error_flag);
void plugin_get_data(int *frame_number, int *nx, int *ny, int *data_array,
int info[1024], int *error_flag);
void plugin_close(int *error_flag); void plugin_close(int *error_flag);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
+22 -15
View File
@@ -1,24 +1,26 @@
#include "err.h"
#include "file.h"
#include <hdf5.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <hdf5.h>
#include "file.h"
#include "err.h"
#define COPY_AND_MASK(in, out, size, mask) \ #define COPY_AND_MASK(in, out, size, mask) \
{ \ { \
int i; \ int i; \
if (mask) { \ if (mask) { \
for (i = 0; i < size; ++i) { \ for (i = 0; i < size; ++i) { \
out[i] = in[i]; \ out[i] = in[i]; \
if (mask[i] & 0xFE) out[i] = -2; \ if (mask[i] & 0xFE) \
if (mask[i] & 0x01) out[i] = -1; \ out[i] = -2; \
if (mask[i] & 0x01) \
out[i] = -1; \
} \ } \
} else { \ } else { \
for (i = 0; i < size; i++) { \ for (i = 0; i < size; i++) { \
out[i] = in[i]; \ out[i] = in[i]; \
} \ } \
} \ } \
} }
int parse_args(int argc, char **argv, char **file_name, int *frame_idx) { int parse_args(int argc, char **argv, char **file_name, int *frame_idx) {
int retval = 0; int retval = 0;
@@ -35,7 +37,6 @@ done:
return retval; return retval;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
int err = 0; int err = 0;
int retval = 0; int retval = 0;
@@ -58,7 +59,8 @@ int main(int argc, char **argv) {
} }
fid = H5Fopen(test_file, H5F_ACC_RDONLY, H5P_DEFAULT); fid = H5Fopen(test_file, H5F_ACC_RDONLY, H5P_DEFAULT);
if (fid < 0) ERROR_JUMP(-1, done, "Error opening file"); if (fid < 0)
ERROR_JUMP(-1, done, "Error opening file");
err = get_detector_info(fid, &desc); err = get_detector_info(fid, &desc);
if (err < 0) { if (err < 0) {
@@ -118,17 +120,22 @@ int main(int argc, char **argv) {
max_i = max_i < dims[2] ? max_i : dims[2]; max_i = max_i < dims[2] ? max_i : dims[2];
for (j = 0; j < max_j; j++) { for (j = 0; j < max_j; j++) {
for (i = 0; i < max_i; i++) { for (i = 0; i < max_i; i++) {
printf("%3d ", data[i + j*dims[2]]); printf("%3d ", data[i + j * dims[2]]);
} }
printf("\n"); printf("\n");
} }
} }
done: done:
if (fid > 0) H5Fclose(fid); if (fid > 0)
if (data) free(data); H5Fclose(fid);
if (buffer && (data != buffer)) free(buffer); if (data)
if (mask) free(mask); free(data);
if (retval != 0) dump_error_stack(stderr); if (buffer && (data != buffer))
free(buffer);
if (mask)
free(mask);
if (retval != 0)
dump_error_stack(stderr);
return retval; return retval;
} }