aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel')
-rw-r--r--libcrystfel/src/cell-utils.c77
-rw-r--r--libcrystfel/src/crystfel-mille.c3
-rw-r--r--libcrystfel/src/datatemplate.c128
-rw-r--r--libcrystfel/src/datatemplate_priv.h1
-rw-r--r--libcrystfel/src/indexers/pinkindexer.c1
-rw-r--r--libcrystfel/src/predict-refine.c4
6 files changed, 96 insertions, 118 deletions
diff --git a/libcrystfel/src/cell-utils.c b/libcrystfel/src/cell-utils.c
index d751172e..a25accbc 100644
--- a/libcrystfel/src/cell-utils.c
+++ b/libcrystfel/src/cell-utils.c
@@ -2178,19 +2178,6 @@ IntegerMatrix *reduce_g6(struct g6 g, double epsrel)
}
-static double cell_diff(UnitCell *cell, double a, double b, double c,
- double al, double be, double ga)
-{
- double ta, tb, tc, tal, tbe, tga;
- double diff = 0.0;
- cell_get_parameters(cell, &ta, &tb, &tc, &tal, &tbe, &tga);
- diff += fabs(a - ta);
- diff += fabs(b - tb);
- diff += fabs(c - tc);
- return diff;
-}
-
-
static int random_int(int max)
{
int r;
@@ -2210,7 +2197,7 @@ static IntegerMatrix *check_permutations(UnitCell *cell_reduced, UnitCell *refer
IntegerMatrix *m;
int i[9];
double a, b, c, al, be, ga;
- double min_dist = +INFINITY;
+ double best_diff = +INFINITY;
int s, sel;
IntegerMatrix *best_m[24];
int n_best = 0;
@@ -2246,30 +2233,32 @@ static IntegerMatrix *check_permutations(UnitCell *cell_reduced, UnitCell *refer
cell_free(tmp);
if ( compare_cell_parameters(nc, reference, tols) ) {
- double dist = cell_diff(nc, a, b, c, al, be, ga);
- if ( dist < min_dist ) {
- /* If the new solution is significantly better,
+ double diff = g6_distance(nc, reference);
+ if ( diff < 0.999*best_diff ) {
+
+ /* New solution is significantly better,
* dump all the previous ones */
for ( s=0; s<n_best; s++ ) {
intmat_free(best_m[s]);
}
- min_dist = dist;
- best_m[0] = intmat_copy(m);
- n_best = 1;
+ best_diff = diff;
+ n_best = 0;
+
+ best_m[n_best++] = intmat_copy(m);
- } else if ( dist == min_dist ) {
+ } else if ( diff < 1.001*best_diff ) {
+ /* If the new solution is the same as the
+ * previous one, add it to the list */
if ( n_best == 24 ) {
ERROR("WARNING: Too many equivalent "
"reindexed lattices\n");
} else {
- /* If the new solution is the same as the
- * previous one, add it to the list */
best_m[n_best++] = intmat_copy(m);
}
- }
+ } /* else worse, so ignore */
}
cell_free(nc);
@@ -2288,38 +2277,9 @@ static IntegerMatrix *check_permutations(UnitCell *cell_reduced, UnitCell *refer
if ( n_best == 0 ) return NULL;
- sel = n_best;
- if ( n_best == 1 ) {
-
- /* If there's one solution, choose that one, of course */
- sel = 0;
-
- } else {
-
- /* If one of the solutions results in an identity applied to the
- * original cell, choose that one */
-
- for ( s=0; s<n_best; s++ ) {
- RationalMatrix *tmp;
- RationalMatrix *comb;
- tmp = rtnlmtx_times_intmat(CiARA, best_m[s]);
- comb = rtnlmtx_times_intmat(tmp, RiBCB);
- if ( rtnl_mtx_is_identity(comb) ) {
- sel = s;
- }
- rtnl_mtx_free(tmp);
- rtnl_mtx_free(comb);
- }
-
- }
-
- /* Still undecided? Choose randomly, to avoid weird distributions
- * in the cell parameters */
- if ( sel == n_best ) {
- sel = random_int(n_best);
- }
-
- /* Free all the others */
+ /* Select a transformation at random from the equivalent versions,
+ * and then free all the others */
+ sel = random_int(n_best);
for ( s=0; s<n_best; s++ ) {
if ( s != sel ) intmat_free(best_m[s]);
}
@@ -2345,11 +2305,10 @@ static IntegerMatrix *check_permutations(UnitCell *cell_reduced, UnitCell *refer
* irrelevant. The tolerances will be applied to the transformed copy of
* \p cell_in, i.e. the version of the input cell which looks similar to
* \p reference_in. Subject to the tolerances, the cell will be chosen which
- * has the lowest total absolute error in unit cell axis lengths.
+ * has the lowest distance measured in G^6 unit cell space.
*
* There will usually be several transformation matrices which produce exactly
- * the same total absolute error. If one of the matrices is an identity, that
- * one will be used. Otherwise, the matrix will be selected at random from the
+ * the same total absolute error. A matrix will be selected at random from the
* possibilities. This avoids skewed distributions of unit cell parameters,
* e.g. the angles always being greater than 90 degrees.
*
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..a7b8950f 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;
}
}
+ }
+
+ if ( fail ) return fail;
- gt->n_children = n_members;
+ 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)
@@ -575,7 +591,6 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key,
} else if ( strcmp(key, "coffset") == 0) {
panel->cnz_offset = atof(val);
- panel->cnz_offset_default = def;
} else if ( strcmp(key, "res") == 0 ) {
panel->pixel_pitch = 1.0/atof(val);
panel->pixel_pitch_default = def;
@@ -1051,7 +1066,6 @@ DataTemplate *data_template_new_from_string(const char *string_in)
defaults.cnx = NAN;
defaults.cny = NAN;
defaults.cnz_offset = 0.0;
- defaults.cnz_offset_default = 1;
defaults.pixel_pitch = -1.0;
defaults.pixel_pitch_default = 1;
defaults.bad = 0;
@@ -1400,10 +1414,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);
@@ -2377,7 +2401,6 @@ int data_template_write_to_fh(const DataTemplate *dtempl, FILE *fh)
}
/* Other top-levels */
- int cnz_offset_done = 0;
int mask_done[MAX_MASKS] = {0};
int satmap_done = 0;
int satmap_file_done = 0;
@@ -2393,11 +2416,6 @@ int data_template_write_to_fh(const DataTemplate *dtempl, FILE *fh)
const struct panel_template *p = &dtempl->panels[i];
int j;
- if ( p->cnz_offset_default && !cnz_offset_done ) {
- fprintf(fh, "coffset = %f\n", p->cnz_offset);
- cnz_offset_done = 1;
- }
-
for ( j=0; j<MAX_MASKS; j++ ) {
if ( p->masks[j].data_location == NULL ) continue;
if ( !p->masks[j].mask_default ) continue;
@@ -2405,7 +2423,7 @@ int data_template_write_to_fh(const DataTemplate *dtempl, FILE *fh)
fprintf(fh, "mask%i_data = %s\n",
j, p->masks[j].data_location);
if ( p->masks[j].filename != NULL ) {
- fprintf(fh, "mask%i_filename = %s\n",
+ fprintf(fh, "mask%i_file = %s\n",
j, p->masks[j].filename);
}
fprintf(fh, "mask%i_goodbits = 0x%x\n",
@@ -2501,17 +2519,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");
}
@@ -2533,9 +2553,7 @@ int data_template_write_to_fh(const DataTemplate *dtempl, FILE *fh)
fprintf(fh, "%s/ss = %fx %+fy %+fz\n", p->name,
p->ssx, p->ssy, p->ssz);
- if ( !p->cnz_offset_default ) {
- fprintf(fh, "%s/coffset = %f\n", p->name, p->cnz_offset);
- }
+ fprintf(fh, "%s/coffset = %f\n", p->name, p->cnz_offset);
for ( j=0; j<MAX_MASKS; j++ ) {
if ( p->masks[j].data_location == NULL ) continue;
@@ -2543,7 +2561,7 @@ int data_template_write_to_fh(const DataTemplate *dtempl, FILE *fh)
fprintf(fh, "%s/mask%i_data = %s\n",
p->name, j, p->masks[j].data_location);
if ( p->masks[j].filename != NULL ) {
- fprintf(fh, "%smask%i_filename = %s\n",
+ fprintf(fh, "%smask%i_file = %s\n",
p->name, j, p->masks[j].filename);
}
fprintf(fh, "%s/mask%i_goodbits = 0x%x\n",
diff --git a/libcrystfel/src/datatemplate_priv.h b/libcrystfel/src/datatemplate_priv.h
index ab40ac2f..26ee91ed 100644
--- a/libcrystfel/src/datatemplate_priv.h
+++ b/libcrystfel/src/datatemplate_priv.h
@@ -130,7 +130,6 @@ struct panel_template
/** The offset to be applied from clen */
double cnz_offset;
- int cnz_offset_default;
/** Mask definitions */
struct mask_template masks[MAX_MASKS];
diff --git a/libcrystfel/src/indexers/pinkindexer.c b/libcrystfel/src/indexers/pinkindexer.c
index 180246c2..14e18548 100644
--- a/libcrystfel/src/indexers/pinkindexer.c
+++ b/libcrystfel/src/indexers/pinkindexer.c
@@ -33,7 +33,6 @@
#include <stdlib.h>
-#include <sys/errno.h>
#include <argp.h>
#include "utils.h"
diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c
index 6da0d3d1..adbb418f 100644
--- a/libcrystfel/src/predict-refine.c
+++ b/libcrystfel/src/predict-refine.c
@@ -811,7 +811,7 @@ int refine_prediction(struct image *image, Crystal *cr,
reflist = reflist_new();
n = pair_peaks(image, cr, reflist, rps);
- if ( n < 10 ) {
+ if ( n < 3 ) {
cffree(rps);
reflist_free(reflist);
return 1;
@@ -887,7 +887,7 @@ int refine_prediction(struct image *image, Crystal *cr,
n = pair_peaks(image, cr, NULL, rps);
free_rps_noreflist(rps, n);
- if ( n < 10 ) {
+ if ( n < 3 ) {
if ( mille != NULL ) {
crystfel_mille_delete_last_record(mille);
}