aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/crystfel_geometry.5.md13
-rw-r--r--libcrystfel/src/crystfel-mille.c3
-rw-r--r--libcrystfel/src/datatemplate.c112
-rw-r--r--src/im-sandbox.c9
-rwxr-xr-xtests/geom_roundtrip11
5 files changed, 99 insertions, 49 deletions
diff --git a/doc/man/crystfel_geometry.5.md b/doc/man/crystfel_geometry.5.md
index ecaf60bf..640771ee 100644
--- a/doc/man/crystfel_geometry.5.md
+++ b/doc/man/crystfel_geometry.5.md
@@ -529,13 +529,20 @@ Groups can themselves be combined into higher-level groups, for example:
group_all = abc,def
-This defines a group called *all** which contains both of the groups created
+This defines a group called **all** which contains both of the groups created
above.
The highest-level group should always be called **all**.
-If the detector consists of only one panel, CrystFEL will automatically create
-the **all** group containing it.
+All members of a group need to be defined before defining the group. This
+means that the group definitions must come **after** the panel definitions, and
+the groups should be defined from the bottom to top level of the hierarchy -
+the **all** group coming last.
+
+If you do not define any groups, CrystFEL will automatically create the **all**
+group for you, containing all panels in a flat hierarchy. This allows basic
+geometry refinement (level zero, see **align_detector**) to work without any
+extra work.
The **group** system replaces the **rigid_group** system used in older versions
of CrystFEL. If the geometry file contains any **rigid_group** lines, they
diff --git a/libcrystfel/src/crystfel-mille.c b/libcrystfel/src/crystfel-mille.c
index 3d02e527..72f89425 100644
--- a/libcrystfel/src/crystfel-mille.c
+++ b/libcrystfel/src/crystfel-mille.c
@@ -327,6 +327,9 @@ void crystfel_mille_write_record(Mille *m)
int ni = 0;
int nw = (m->n * 2)+2;
+ /* Don't write empty records */
+ if ( m->n == 0 ) return;
+
fwrite(&nw, sizeof(int), 1, m->fh);
fwrite(&nf, sizeof(float), 1, m->fh);
diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c
index df0ad343..2f5763a8 100644
--- a/libcrystfel/src/datatemplate.c
+++ b/libcrystfel/src/datatemplate.c
@@ -90,21 +90,13 @@ static struct panel_group_template *add_group(const char *name, DataTemplate *dt
}
-static int parse_group(const char *name, DataTemplate *dt, const char *val)
+static int add_group_members(const char *name, DataTemplate *dt,
+ char **members, int n_members)
{
struct panel_group_template *gt;
- int n_members;
- char **members;
int i;
int fail = 0;
- gt = add_group(name, dt);
- if ( gt == NULL ) {
- ERROR("Failed to add group\n");
- return 1;
- }
-
- n_members = assplode(val, ",", &members, ASSPLODE_NONE);
if ( n_members == 0 ) {
ERROR("Panel group '%s' has no members\n", name);
fail = 1;
@@ -113,33 +105,58 @@ static int parse_group(const char *name, DataTemplate *dt, const char *val)
if ( n_members > MAX_PANEL_GROUP_CHILDREN ) {
ERROR("Panel group '%s' has too many members\n", name);
fail = 1;
- } else {
+ }
- /* A simple typo in the geometry file can segfault other
- * stuff, so check */
- for ( i=0; i<n_members; i++ ) {
- int j;
- for ( j=0; j<i; j++ ) {
- if ( strcmp(members[i], members[j]) == 0 ) {
- ERROR("Duplicate member '%s' in group '%s'\n",
- members[i], name);
- fail = 1;
- }
- }
- }
- for ( i=0; i<n_members; i++ ) {
- gt->children[i] = find_group(dt, members[i]);
- if ( gt->children[i] == NULL ) {
- ERROR("Unknown panel group '%s'\n", members[i]);
+ /* A simple typo in the geometry file can segfault other
+ * stuff, so check */
+ for ( i=0; i<n_members; i++ ) {
+ int j;
+ for ( j=0; j<i; j++ ) {
+ if ( strcmp(members[i], members[j]) == 0 ) {
+ ERROR("Duplicate member '%s' in group '%s'\n",
+ members[i], name);
fail = 1;
}
}
+ }
- gt->n_children = n_members;
+ if ( fail ) return fail;
+ gt = add_group(name, dt);
+ if ( gt == NULL ) {
+ ERROR("Failed to add group\n");
+ return 1;
}
+ for ( i=0; i<n_members; i++ ) {
+ gt->children[i] = find_group(dt, members[i]);
+ if ( gt->children[i] == NULL ) {
+ ERROR("Unknown panel group '%s'\n", members[i]);
+ ERROR("Make sure the hierarchy groups definitions are AFTER the "
+ "panel definitions in the geometry file, and start from "
+ "the lowest hierachy level.\n");
+ fail = 1;
+ }
+ }
+
+ gt->n_children = n_members;
+
+ return fail;
+}
+
+
+static int parse_group(const char *name, DataTemplate *dt, const char *val)
+{
+ int n_members;
+ char **members;
+ int i;
+ int fail = 0;
+
+ n_members = assplode(val, ",", &members, ASSPLODE_NONE);
+
+ fail = add_group_members(name, dt, members, n_members);
+
for ( i=0; i<n_members; i++ ) cffree(members[i]);
cffree(members);
@@ -147,7 +164,6 @@ static int parse_group(const char *name, DataTemplate *dt, const char *val)
}
-
static struct panel_template *new_panel(DataTemplate *det,
const char *name,
struct panel_template *defaults)
@@ -1400,10 +1416,20 @@ DataTemplate *data_template_new_from_string(const char *string_in)
cffree(defaults.masks[i].filename);
}
- /* If this is a single-panel detector, there should only be one group
- * called "all" which points to the panel */
- if ( (dt->n_panels == 1) && (dt->n_groups == 1) ) {
- parse_group("all", dt, dt->groups[0]->name);
+ /* If no groups are defined, put everything in one group.
+ * This allows at least basic geometry refinement to work. */
+ if ( dt->n_groups == dt->n_panels ) {
+ char **allg = malloc(dt->n_groups*sizeof(char *));
+ if ( allg == NULL ) {
+ ERROR("Failed to create top group\n");
+ } else {
+ int i;
+ for ( i=0; i<dt->n_groups; i++ ) {
+ allg[i] = dt->groups[i]->name;
+ }
+ add_group_members("all", dt, allg, dt->n_groups);
+ free(allg);
+ }
}
cffree(string_orig);
@@ -2501,17 +2527,19 @@ int data_template_write_to_fh(const DataTemplate *dtempl, FILE *fh)
/* Bad regions */
for ( i=0; i<dtempl->n_bad; i++ ) {
const struct dt_badregion *bad = &dtempl->bad[i];
+ assert(strncmp(bad->name, "bad", 3) == 0);
if ( bad->is_fsss ) {
- fprintf(fh, "bad_%s/panel = %s\n", bad->name, bad->panel_name);
- fprintf(fh, "bad_%s/min_fs = %i\n", bad->name, bad->min_fs);
- fprintf(fh, "bad_%s/max_fs = %i\n", bad->name, bad->max_fs);
- fprintf(fh, "bad_%s/min_ss = %i\n", bad->name, bad->min_ss);
- fprintf(fh, "bad_%s/max_ss = %i\n", bad->name, bad->max_ss);
+ const struct panel_template *p = &dtempl->panels[bad->panel_number];
+ fprintf(fh, "%s/panel = %s\n", bad->name, p->name);
+ fprintf(fh, "%s/min_fs = %i\n", bad->name, bad->min_fs+p->orig_min_fs);
+ fprintf(fh, "%s/max_fs = %i\n", bad->name, bad->max_fs+p->orig_min_fs);
+ fprintf(fh, "%s/min_ss = %i\n", bad->name, bad->min_ss+p->orig_min_ss);
+ fprintf(fh, "%s/max_ss = %i\n", bad->name, bad->max_ss+p->orig_min_ss);
} else {
- fprintf(fh, "bad_%s/min_x = %f\n", bad->name, bad->min_x);
- fprintf(fh, "bad_%s/max_x = %f\n", bad->name, bad->max_x);
- fprintf(fh, "bad_%s/min_y = %f\n", bad->name, bad->min_y);
- fprintf(fh, "bad_%s/max_y = %f\n", bad->name, bad->max_y);
+ fprintf(fh, "%s/min_x = %f\n", bad->name, bad->min_x);
+ fprintf(fh, "%s/max_x = %f\n", bad->name, bad->max_x);
+ fprintf(fh, "%s/min_y = %f\n", bad->name, bad->min_y);
+ fprintf(fh, "%s/max_y = %f\n", bad->name, bad->max_y);
}
fprintf(fh, "\n");
}
diff --git a/src/im-sandbox.c b/src/im-sandbox.c
index 3d9f1f96..2fa19820 100644
--- a/src/im-sandbox.c
+++ b/src/im-sandbox.c
@@ -343,7 +343,6 @@ static int run_work(const struct index_args *iargs, Stream *st,
struct im_asapo *asapostuff = NULL;
Mille *mille;
ImageDataArrays *ida;
- int asapo_message_id;
if ( sb->profile ) {
profile_init();
@@ -491,6 +490,7 @@ static int run_work(const struct index_args *iargs, Stream *st,
char *filename;
char *event;
int finished = 0;
+ int asapo_message_id;
profile_start("asapo-fetch");
set_last_task(sb->shared->last_task[cookie], "ASAPO fetch");
@@ -533,10 +533,11 @@ static int run_work(const struct index_args *iargs, Stream *st,
sb->shared, sb->shared->last_task[cookie],
asapostuff, mille, ida);
profile_end("process-image");
- }
- if ( sb->asapo_params != NULL ) {
- im_asapo_finalise(asapostuff, asapo_message_id);
+ if ( sb->asapo_params != NULL ) {
+ im_asapo_finalise(asapostuff, ser);
+ }
+
}
/* NB pargs.zmq_data, pargs.asapo_data and pargs.asapo_meta
diff --git a/tests/geom_roundtrip b/tests/geom_roundtrip
index 1d74befd..9e0e2425 100755
--- a/tests/geom_roundtrip
+++ b/tests/geom_roundtrip
@@ -17,6 +17,17 @@ dim0 = %
dim1 = ss
dim2 = fs
+bad_t/panel = q3a15
+bad_t/min_fs = 1360
+bad_t/max_fs = 1365
+bad_t/min_ss = 1298
+bad_t/max_ss = 1300
+
+bad_u/min_x = -2000.000000
+bad_u/max_x = 2000.000000
+bad_u/min_y = -20.000000
+bad_u/max_y = 20.000000
+
q0a0/min_fs = 0
q0a0/max_fs = 193
q0a0/min_ss = 0