aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2020-02-21 17:04:20 +0100
committerThomas White <taw@physics.org>2020-07-29 18:39:50 +0200
commite7d338d5e697526df8843f45c8044533212bbb38 (patch)
treea677b84fb2478caf524df2e0c22cd21f0cb2ed4b /libcrystfel
parentb0676fb5d4d0bbf37e278bfaa5371e1a1938f434 (diff)
Basic image loading via new DataTemplate API
Diffstat (limited to 'libcrystfel')
-rw-r--r--libcrystfel/src/image.c346
-rw-r--r--libcrystfel/src/image.h15
2 files changed, 358 insertions, 3 deletions
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c
index 6358a9d0..84f9391a 100644
--- a/libcrystfel/src/image.c
+++ b/libcrystfel/src/image.c
@@ -42,6 +42,9 @@
#include "hdf5-file.h"
#include "detector.h"
+#include "datatemplate.h"
+#include "datatemplate_priv.h"
+
/** \file image.h */
struct imagefile
@@ -1236,3 +1239,346 @@ void imagefile_close(struct imagefile *f)
free(f->filename);
free(f);
}
+
+
+/************************** New API (DataTemplate) ****************************/
+
+static struct image *image_new()
+{
+ struct image *image;
+
+ image = malloc(sizeof(struct image));
+ if ( image == NULL ) return NULL;
+
+ image->dp = NULL;
+ image->bad = NULL;
+ image->sat = NULL;
+ image->hit = 0;
+ image->crystals = NULL;
+ image->n_crystals = 0;
+ image->indexed_by = INDEXING_NONE;
+ image->det = NULL;
+ image->filename = NULL;
+ image->ev = NULL;
+ image->copyme = NULL;
+ image->stuff_from_stream = NULL;
+ image->avg_clen = -1.0;
+ image->id = 0;
+ image->serial = 0;
+ image->spectrum = NULL;
+ image->lambda = -1.0;
+ image->div = -1.0;
+ image->bw = -1.0;
+ image->peak_resolution = -1.0;
+ image->features = NULL;
+
+ /* Deprecated stuff */
+ image->beam = NULL;
+ image->event = NULL;
+
+ return image;
+}
+
+
+static struct image *image_read_hdf5(DataTemplate *dtempl, const char *filename,
+ const char *event)
+{
+ struct image *image;
+ struct event *ev;
+ hid_t fh;
+ herr_t r;
+ int pi;
+ int i;
+
+ if ( access(filename, R_OK) == -1 ) {
+ ERROR("File does not exist or cannot be read: %s\n", filename);
+ return NULL;
+ }
+
+ fh = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
+ if ( fh < 0 ) {
+ ERROR("Couldn't open file: %s\n", filename);
+ return NULL;
+ }
+
+ image = image_new();
+ if ( image == NULL ) {
+ ERROR("Couldn't allocate image structure.\n");
+ H5Fclose(fh);
+ return NULL;
+ }
+
+ ev = get_event_from_event_string(event);
+ if ( (ev == NULL) && (event != NULL) ) {
+ ERROR("Invalid event identifier '%s'\n", event);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+
+ image->dp = malloc(dtempl->n_panels*sizeof(float *));
+ image->bad = malloc(dtempl->n_panels*sizeof(int *));
+ image->sat = malloc(dtempl->n_panels*sizeof(float *));
+ if ( (image->dp==NULL) || (image->bad==NULL) || (image->sat==NULL) ) {
+ ERROR("Failed to allocate data arrays.\n");
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+
+ for ( pi=0; pi<dtempl->n_panels; pi++ ) {
+
+ hsize_t *f_offset, *f_count;
+ hid_t dh;
+ int hsi;
+ herr_t check;
+ hid_t dataspace, memspace;
+ struct panel_template *p;
+ hsize_t dims[2];
+ char *panel_full_path;
+
+ p = &dtempl->panels[pi];
+
+ panel_full_path = retrieve_full_path(ev, p->data);
+
+ if ( !check_path_existence(fh, panel_full_path) ) {
+ ERROR("Cannot find data for panel %s (%s)\n",
+ p->name, panel_full_path);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+
+ dh = H5Dopen2(fh, panel_full_path, H5P_DEFAULT);
+ if ( dh < 0 ) {
+ ERROR("Cannot open data for panel %s (%s)\n",
+ p->name, panel_full_path);
+ free(panel_full_path);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+
+ free(panel_full_path);
+
+ /* Determine where to read the data from in the file */
+ f_offset = malloc(p->dim_structure->num_dims*sizeof(hsize_t));
+ f_count = malloc(p->dim_structure->num_dims*sizeof(hsize_t));
+ if ( (f_offset == NULL) || (f_count == NULL ) ) {
+ ERROR("Failed to allocate offset or count.\n");
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+ for ( hsi=0; hsi<p->dim_structure->num_dims; hsi++ ) {
+
+ if ( p->dim_structure->dims[hsi] == HYSL_FS ) {
+ f_offset[hsi] = p->orig_min_fs;
+ f_count[hsi] = p->orig_max_fs - p->orig_min_fs+1;
+ } else if ( p->dim_structure->dims[hsi] == HYSL_SS ) {
+ f_offset[hsi] = p->orig_min_ss;
+ f_count[hsi] = p->orig_max_ss - p->orig_min_ss+1;
+ } else if (p->dim_structure->dims[hsi] == HYSL_PLACEHOLDER ) {
+ f_offset[hsi] = ev->dim_entries[0];
+ f_count[hsi] = 1;
+ } else {
+ f_offset[hsi] = p->dim_structure->dims[hsi];
+ f_count[hsi] = 1;
+ }
+
+ }
+
+ /* Set up dataspace for file */
+ dataspace = H5Dget_space(dh);
+ check = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
+ f_offset, NULL, f_count, NULL);
+ if ( check < 0 ) {
+ ERROR("Error selecting file dataspace for panel %s\n",
+ p->name);
+ free(f_offset);
+ free(f_count);
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+
+ dims[0] = p->orig_max_ss - p->orig_min_ss + 1;
+ dims[1] = p->orig_max_fs - p->orig_min_fs + 1;
+ memspace = H5Screate_simple(2, dims, NULL);
+
+ image->dp[pi] = malloc(dims[0]*dims[1]*sizeof(float));
+ image->sat[pi] = malloc(dims[0]*dims[1]*sizeof(float));
+ if ( (image->dp[pi] == NULL) || (image->sat[pi] == NULL) ) {
+ ERROR("Failed to allocate panel %s\n", p->name);
+ free(f_offset);
+ free(f_count);
+ for ( i=0; i<=pi; i++ ) {
+ free(image->dp[i]);
+ free(image->sat[i]);
+ }
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+ for ( i=0; i<dims[0]*dims[1]; i++ ) image->sat[pi][i] = INFINITY;
+
+ r = H5Dread(dh, H5T_NATIVE_FLOAT, memspace, dataspace,
+ H5P_DEFAULT, image->dp[pi]);
+ if ( r < 0 ) {
+ ERROR("Couldn't read data for panel %s\n",
+ p->name);
+ free(f_offset);
+ free(f_count);
+ for ( i=0; i<=pi; i++ ) {
+ free(image->dp[i]);
+ free(image->sat[i]);
+ }
+ free(image->dp);
+ free(image->bad);
+ free(image->sat);
+ free_event(ev);
+ H5Fclose(fh);
+ free(image);
+ return NULL;
+ }
+
+ H5Dclose(dh);
+ H5Sclose(dataspace);
+ free(f_offset);
+ free(f_count);
+
+ }
+
+ free_event(ev);
+ H5Fclose(fh);
+
+ #if 0
+ /* FIXME: Fill in crap */
+ hdfile_fill_in_clen(image->det, f, ev);
+
+ if ( image->beam != NULL ) {
+
+ hdfile_fill_in_beam_parameters(image->beam, f, ev, image);
+
+ if ( (image->lambda > 1.0) || (image->lambda < 1e-20) ) {
+
+ ERROR("WARNING: Nonsensical wavelength (%e m) value "
+ "for file: %s, event: %s.\n",
+ image->lambda, image->filename,
+ get_event_string(image->event));
+ }
+
+ }
+
+ fill_in_adu(image);
+ #endif
+
+ return image;
+}
+
+
+#if 0
+static struct image *read_mask_hdf5(DataTemplate *dtempl, const char *filename,
+ const char *event)
+{
+ if ( p->mask != NULL ) {
+ int *flags = malloc(dims[0]*dims[1]*sizeof(int));
+ if ( !load_mask(f, ev, p, flags, f_offset, f_count, p->dim_structure) ) {
+ image->bad[pi] = make_badmask(flags, image->det,
+ image->dp[pi], p);
+ } else {
+ image->bad[pi] = make_badmask(NULL, image->det,
+ image->dp[pi], p);
+ }
+ free(flags);
+ } else {
+ image->bad[pi] = make_badmask(NULL, image->det,
+ image->dp[pi], p);
+ }
+
+ if ( p->satmap != NULL ) {
+ if ( load_satmap(f, ev, p, f_offset, f_count, p->dim_structure,
+ image->sat[pi]) )
+ {
+ ERROR("Failed to load sat map for panel %s\n",
+ p->name);
+ }
+ }
+}
+#endif
+
+
+struct image *image_read_cbf(DataTemplate *dtempl, const char *filename,
+ const char *event)
+{
+ return NULL;
+}
+
+
+struct image *image_read_gzcbf(DataTemplate *dtempl, const char *filename,
+ const char *event)
+{
+ return NULL;
+}
+
+
+struct image *image_read(DataTemplate *dtempl, const char *filename,
+ const char *event)
+{
+ struct image *image;
+
+
+ printf("loading '%s'\n", filename);
+ if ( H5Fis_hdf5(filename) > 0 ) {
+ image = image_read_hdf5(dtempl, filename, event);
+
+ } else if ( is_cbf_file(filename) > 0 ) {
+ image = image_read_cbf(dtempl, filename, event);
+
+ } else if ( is_cbfgz_file(filename) ) {
+ image = image_read_gzcbf(dtempl, filename, event);
+
+ } else {
+ ERROR("Unrecognised file type: %s\n", filename);
+ return NULL;
+ }
+
+ if ( image == NULL ) return NULL;
+
+ /* FIXME: Load mask */
+ /* FIXME: Load saturation map */
+
+ return image;
+}
+
+
+void image_free(struct image *image)
+{
+ if ( image == NULL ) return;
+ image_feature_list_free(image->features);
+ free_all_crystals(image);
+ free(image->filename);
+ free(image->ev);
+ free(image);
+}
diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h
index d3bb56e5..6330d824 100644
--- a/libcrystfel/src/image.h
+++ b/libcrystfel/src/image.h
@@ -55,6 +55,7 @@ struct imagefile_field_list;
#include "index.h"
#include "events.h"
#include "spectrum.h"
+#include "datatemplate.h"
/**
* \file image.h
@@ -145,12 +146,13 @@ struct image
struct detector *det;
/** The nominal beam parameters (or where to get them) */
- struct beam_params *beam;
+ struct beam_params *beam; /* FIXME: Deprecated */
/** \name The filename and event ID for the image
* @{ */
char *filename;
- struct event *event;
+ struct event *event; /* FIXME: Deprecated */
+ char *ev;
/** @} */
/** A list of image file headers to copy to the stream */
@@ -223,7 +225,7 @@ extern void image_add_crystal(struct image *image, Crystal *cryst);
extern int remove_flagged_crystals(struct image *image);
extern void free_all_crystals(struct image *image);
-/* Image files */
+/* Image files (old API) */
extern struct imagefile *imagefile_open(const char *filename);
extern int imagefile_read(struct imagefile *f, struct image *image,
struct event *event);
@@ -236,6 +238,13 @@ extern void imagefile_copy_fields(struct imagefile *f,
extern void imagefile_close(struct imagefile *f);
extern signed int is_cbf_file(const char *filename);
+
+/* New API */
+extern struct image *image_read(DataTemplate *dtempl, const char *filename,
+ const char *event);
+extern void image_free(struct image *image);
+
+
/* Field lists */
extern struct imagefile_field_list *new_imagefile_field_list(void);
extern void free_imagefile_field_list(struct imagefile_field_list *f);