aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2022-09-21 16:22:47 +0200
committerThomas White <taw@physics.org>2022-09-21 16:22:47 +0200
commitef7157ef517cf66dfc5b2c2cfc6602e30a31d060 (patch)
treee5475b0996d02df47b088920e1197f62bfbf4263
parent1f53f659e757cc7d4704a885bab50f7060231d16 (diff)
Move create_detgeom to DataTemplate module
It seems to make more sense here, because it's all about interpreting the contents of the DataTemplate structure.
-rw-r--r--libcrystfel/src/datatemplate.c227
-rw-r--r--libcrystfel/src/datatemplate_priv.h2
-rw-r--r--libcrystfel/src/image.c225
-rw-r--r--libcrystfel/src/image.h3
-rw-r--r--libcrystfel/src/stream.c1
5 files changed, 230 insertions, 228 deletions
diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c
index 1ffa2777..94a8de2a 100644
--- a/libcrystfel/src/datatemplate.c
+++ b/libcrystfel/src/datatemplate.c
@@ -36,6 +36,7 @@
#include "utils.h"
#include "datatemplate.h"
+#include "image.h"
#include "datatemplate_priv.h"
@@ -1734,3 +1735,229 @@ double data_template_get_wavelength_if_possible(const DataTemplate *dt)
return NAN;
}
}
+
+
+static int separate_value_and_units(const char *from,
+ char **pvalue,
+ char **punits)
+{
+ char *sp;
+ char *fromcpy;
+ char *unitscpy;
+
+ if ( from == NULL ) return 1;
+
+ fromcpy = strdup(from);
+ if ( fromcpy == NULL ) return 1;
+
+ sp = strchr(fromcpy, ' ');
+ if ( sp == NULL ) {
+ unitscpy = NULL;
+ } else {
+ unitscpy = strdup(sp+1);
+ sp[0] = '\0';
+ }
+
+ *pvalue = fromcpy;
+ *punits = unitscpy;
+ return 0;
+}
+
+
+/* default_scale is a value to be used if both of the following
+ * conditions are met:
+ *
+ * 1. The value is a reference to image headers/metadata,
+ * rather than a literal number.
+ * 2. No units are specified in the number.
+ *
+ * This is totally horrible. Sorry. Blame history.
+ */
+static int im_get_length(struct image *image, const char *from,
+ double default_scale, double *pval)
+{
+ char *value_str;
+ char *units;
+
+ if ( from == NULL ) return 1;
+
+ if ( separate_value_and_units(from, &value_str, &units) ) return 1;
+
+ if ( units == NULL ) {
+
+ /* No units given */
+
+ if ( convert_float(value_str, pval) == 0 ) {
+
+ /* Literal value with no units */
+ free(value_str);
+ return 0;
+
+ } else {
+
+ int r;
+ r = image_read_header_float(image, value_str, pval);
+ free(value_str);
+
+ if ( r == 0 ) {
+ /* Value read from headers with no units */
+ *pval *= default_scale;
+ return 0;
+ } else {
+ /* Failed to read value from headers */
+ return 1;
+ }
+ }
+
+ } else {
+
+ /* Units are specified */
+
+ double scale;
+
+ if ( strcmp(units, "mm") == 0 ) {
+ scale = 1e-3;
+ } else if ( strcmp(units, "m") == 0 ) {
+ scale = 1.0;
+ } else {
+ ERROR("Invalid length unit '%s'\n", units);
+ free(value_str);
+ free(units);
+ return 1;
+ }
+
+ if ( convert_float(value_str, pval) == 0 ) {
+
+ /* Literal value, units specified */
+ free(value_str);
+ free(units);
+ *pval *= scale;
+ return 0;
+
+ } else {
+
+ int r;
+ r = image_read_header_float(image, value_str, pval);
+ free(value_str);
+
+ if ( r == 0 ) {
+ /* Value read from headers, units specified */
+ *pval *= scale;
+ return 0;
+ } else {
+ /* Failed to read value from headers */
+ return 1;
+ }
+ }
+ }
+}
+
+
+
+int create_detgeom(struct image *image, const DataTemplate *dtempl)
+{
+ struct detgeom *detgeom;
+ int i;
+
+ if ( dtempl == NULL ) {
+ ERROR("NULL data template!\n");
+ return 1;
+ }
+
+ detgeom = malloc(sizeof(struct detgeom));
+ if ( detgeom == NULL ) return 1;
+
+ detgeom->panels = malloc(dtempl->n_panels*sizeof(struct detgeom_panel));
+ if ( detgeom->panels == NULL ) {
+ free(detgeom);
+ return 1;
+ }
+
+ detgeom->n_panels = dtempl->n_panels;
+
+ for ( i=0; i<dtempl->n_panels; i++ ) {
+
+ struct detgeom_panel *p = &detgeom->panels[i];
+ struct panel_template *tmpl = &dtempl->panels[i];
+ double shift_x, shift_y;
+
+ p->name = safe_strdup(tmpl->name);
+
+ p->pixel_pitch = tmpl->pixel_pitch;
+
+ /* NB cnx,cny are in pixels, cnz is in m */
+ p->cnx = tmpl->cnx;
+ p->cny = tmpl->cny;
+ if ( im_get_length(image, tmpl->cnz_from,
+ 1e-3, &p->cnz) )
+ {
+ ERROR("Failed to read length from '%s'\n", tmpl->cnz_from);
+ return 1;
+ }
+
+ /* Apply offset (in m) and then convert cnz from
+ * m to pixels */
+ p->cnz += tmpl->cnz_offset;
+ p->cnz /= p->pixel_pitch;
+
+ /* Apply overall shift (already in m) */
+ if ( dtempl->shift_x_from != NULL ) {
+ if ( im_get_length(image, dtempl->shift_x_from, 1.0, &shift_x) ) {
+ ERROR("Failed to read length from '%s'\n",
+ dtempl->shift_x_from);
+ return 1;
+ }
+ if ( im_get_length(image, dtempl->shift_y_from, 1.0, &shift_y) ) {
+ ERROR("Failed to read length from '%s'\n",
+ dtempl->shift_y_from);
+ return 1;
+ }
+ } else {
+ shift_x = 0.0;
+ shift_y = 0.0;
+ }
+
+ if ( !isnan(shift_x) ) {
+ p->cnx += shift_x / p->pixel_pitch;
+ }
+ if ( !isnan(shift_y) ) {
+ p->cny += shift_y / p->pixel_pitch;
+ }
+
+ p->max_adu = tmpl->max_adu;
+
+ switch ( tmpl->adu_scale_unit ) {
+
+ case ADU_PER_PHOTON:
+ p->adu_per_photon = tmpl->adu_scale;
+ break;
+
+ case ADU_PER_EV:
+ p->adu_per_photon = tmpl->adu_scale
+ * ph_lambda_to_eV(image->lambda);
+ break;
+
+ default:
+ p->adu_per_photon = 1.0;
+ ERROR("Invalid ADU/ph scale unit (%i)\n",
+ tmpl->adu_scale_unit);
+ break;
+
+ }
+
+ p->w = tmpl->orig_max_fs - tmpl->orig_min_fs + 1;
+ p->h = tmpl->orig_max_ss - tmpl->orig_min_ss + 1;
+
+ p->fsx = tmpl->fsx;
+ p->fsy = tmpl->fsy;
+ p->fsz = tmpl->fsz;
+ p->ssx = tmpl->ssx;
+ p->ssy = tmpl->ssy;
+ p->ssz = tmpl->ssz;
+
+ }
+
+ image->detgeom = detgeom;
+
+ return 0;
+}
diff --git a/libcrystfel/src/datatemplate_priv.h b/libcrystfel/src/datatemplate_priv.h
index ff383705..7ade9ff8 100644
--- a/libcrystfel/src/datatemplate_priv.h
+++ b/libcrystfel/src/datatemplate_priv.h
@@ -234,5 +234,7 @@ struct _datatemplate
};
extern double convert_to_m(double val, int units);
+extern int create_detgeom(struct image *image,
+ const DataTemplate *dtempl);
#endif /* DATATEMPLATE_PRIV_H */
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c
index 3448421e..3ce8914e 100644
--- a/libcrystfel/src/image.c
+++ b/libcrystfel/src/image.c
@@ -486,231 +486,6 @@ static DataSourceType file_type(const char *filename)
}
-static int separate_value_and_units(const char *from,
- char **pvalue,
- char **punits)
-{
- char *sp;
- char *fromcpy;
- char *unitscpy;
-
- if ( from == NULL ) return 1;
-
- fromcpy = strdup(from);
- if ( fromcpy == NULL ) return 1;
-
- sp = strchr(fromcpy, ' ');
- if ( sp == NULL ) {
- unitscpy = NULL;
- } else {
- unitscpy = strdup(sp+1);
- sp[0] = '\0';
- }
-
- *pvalue = fromcpy;
- *punits = unitscpy;
- return 0;
-}
-
-
-/* default_scale is a value to be used if both of the following
- * conditions are met:
- *
- * 1. The value is a reference to image headers/metadata,
- * rather than a literal number.
- * 2. No units are specified in the number.
- *
- * This is totally horrible. Sorry. Blame history.
- */
-static int im_get_length(struct image *image, const char *from,
- double default_scale, double *pval)
-{
- char *value_str;
- char *units;
-
- if ( from == NULL ) return 1;
-
- if ( separate_value_and_units(from, &value_str, &units) ) return 1;
-
- if ( units == NULL ) {
-
- /* No units given */
-
- if ( convert_float(value_str, pval) == 0 ) {
-
- /* Literal value with no units */
- free(value_str);
- return 0;
-
- } else {
-
- int r;
- r = image_read_header_float(image, value_str, pval);
- free(value_str);
-
- if ( r == 0 ) {
- /* Value read from headers with no units */
- *pval *= default_scale;
- return 0;
- } else {
- /* Failed to read value from headers */
- return 1;
- }
- }
-
- } else {
-
- /* Units are specified */
-
- double scale;
-
- if ( strcmp(units, "mm") == 0 ) {
- scale = 1e-3;
- } else if ( strcmp(units, "m") == 0 ) {
- scale = 1.0;
- } else {
- ERROR("Invalid length unit '%s'\n", units);
- free(value_str);
- free(units);
- return 1;
- }
-
- if ( convert_float(value_str, pval) == 0 ) {
-
- /* Literal value, units specified */
- free(value_str);
- free(units);
- *pval *= scale;
- return 0;
-
- } else {
-
- int r;
- r = image_read_header_float(image, value_str, pval);
- free(value_str);
-
- if ( r == 0 ) {
- /* Value read from headers, units specified */
- *pval *= scale;
- return 0;
- } else {
- /* Failed to read value from headers */
- return 1;
- }
- }
- }
-}
-
-
-int create_detgeom(struct image *image, const DataTemplate *dtempl)
-{
- struct detgeom *detgeom;
- int i;
-
- if ( dtempl == NULL ) {
- ERROR("NULL data template!\n");
- return 1;
- }
-
- detgeom = malloc(sizeof(struct detgeom));
- if ( detgeom == NULL ) return 1;
-
- detgeom->panels = malloc(dtempl->n_panels*sizeof(struct detgeom_panel));
- if ( detgeom->panels == NULL ) {
- free(detgeom);
- return 1;
- }
-
- detgeom->n_panels = dtempl->n_panels;
-
- for ( i=0; i<dtempl->n_panels; i++ ) {
-
- struct detgeom_panel *p = &detgeom->panels[i];
- struct panel_template *tmpl = &dtempl->panels[i];
- double shift_x, shift_y;
-
- p->name = safe_strdup(tmpl->name);
-
- p->pixel_pitch = tmpl->pixel_pitch;
-
- /* NB cnx,cny are in pixels, cnz is in m */
- p->cnx = tmpl->cnx;
- p->cny = tmpl->cny;
- if ( im_get_length(image, tmpl->cnz_from,
- 1e-3, &p->cnz) )
- {
- ERROR("Failed to read length from '%s'\n", tmpl->cnz_from);
- return 1;
- }
-
- /* Apply offset (in m) and then convert cnz from
- * m to pixels */
- p->cnz += tmpl->cnz_offset;
- p->cnz /= p->pixel_pitch;
-
- /* Apply overall shift (already in m) */
- if ( dtempl->shift_x_from != NULL ) {
- if ( im_get_length(image, dtempl->shift_x_from, 1.0, &shift_x) ) {
- ERROR("Failed to read length from '%s'\n",
- dtempl->shift_x_from);
- return 1;
- }
- if ( im_get_length(image, dtempl->shift_y_from, 1.0, &shift_y) ) {
- ERROR("Failed to read length from '%s'\n",
- dtempl->shift_y_from);
- return 1;
- }
- } else {
- shift_x = 0.0;
- shift_y = 0.0;
- }
-
- if ( !isnan(shift_x) ) {
- p->cnx += shift_x / p->pixel_pitch;
- }
- if ( !isnan(shift_y) ) {
- p->cny += shift_y / p->pixel_pitch;
- }
-
- p->max_adu = tmpl->max_adu;
-
- switch ( tmpl->adu_scale_unit ) {
-
- case ADU_PER_PHOTON:
- p->adu_per_photon = tmpl->adu_scale;
- break;
-
- case ADU_PER_EV:
- p->adu_per_photon = tmpl->adu_scale
- * ph_lambda_to_eV(image->lambda);
- break;
-
- default:
- p->adu_per_photon = 1.0;
- ERROR("Invalid ADU/ph scale unit (%i)\n",
- tmpl->adu_scale_unit);
- break;
-
- }
-
- p->w = tmpl->orig_max_fs - tmpl->orig_min_fs + 1;
- p->h = tmpl->orig_max_ss - tmpl->orig_min_ss + 1;
-
- p->fsx = tmpl->fsx;
- p->fsy = tmpl->fsy;
- p->fsz = tmpl->fsz;
- p->ssx = tmpl->ssx;
- p->ssy = tmpl->ssy;
- p->ssz = tmpl->ssz;
-
- }
-
- image->detgeom = detgeom;
-
- return 0;
-}
-
-
int image_set_zero_data(struct image *image,
const DataTemplate *dtempl)
{
diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h
index 3f1ed219..10ae0ba7 100644
--- a/libcrystfel/src/image.h
+++ b/libcrystfel/src/image.h
@@ -270,9 +270,6 @@ extern int image_write(const struct image *image,
const DataTemplate *dtempl,
const char *filename);
-/* Use within libcrystfel only */
-extern int create_detgeom(struct image *image,
- const DataTemplate *dtempl);
#ifdef __cplusplus
}
diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c
index 95345f40..960d0a02 100644
--- a/libcrystfel/src/stream.c
+++ b/libcrystfel/src/stream.c
@@ -49,6 +49,7 @@
#include "reflist.h"
#include "reflist-utils.h"
#include "datatemplate.h"
+#include "datatemplate_priv.h"
#include "detgeom.h"
#include "libcrystfel-version.h"