aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2019-07-29 16:00:10 +0200
committerThomas White <taw@physics.org>2019-07-29 17:11:16 +0200
commit82719e4d6fec3c28bcdc310ba382e12aa4f041d4 (patch)
treed518bcdc0649ac9bb07747619c5dc751744ce72d /libcrystfel
parent83ef79e1642841966690e4c9643a8716e8521112 (diff)
Re-implement copy_geom()
The old version assumed that the rigid groups appeared in the new list in the same order as the old one. Note the use of subscript "i" for both arrays here: if ( rigid_group_is_in_collection( in->rigid_group_collections[rgci], in->rigid_groups[i]) ) [....] add_to_rigid_group_coll(rgcoll, out->rigid_groups[i]); However, the new list of rigid groups, out->rigid_groups, was constructed not by copying the old list (in->rigid_groups), but rather by iterating over the panels and adding the groups as they were encountered. Therefore, the assumption of same ordering was invalid, and the new rigid group collection incorrect.
Diffstat (limited to 'libcrystfel')
-rw-r--r--libcrystfel/src/detector.c104
1 files changed, 69 insertions, 35 deletions
diff --git a/libcrystfel/src/detector.c b/libcrystfel/src/detector.c
index b23db054..9617788d 100644
--- a/libcrystfel/src/detector.c
+++ b/libcrystfel/src/detector.c
@@ -1780,6 +1780,16 @@ void free_detector_geometry(struct detector *det)
}
+static int rg_number(const struct detector *det, const struct rigid_group *rg)
+{
+ int i;
+ for ( i=0; i<det->n_rigid_groups; i++ ) {
+ if ( det->rigid_groups[i] == rg ) return i;
+ }
+ return det->n_rigid_groups;
+}
+
+
struct detector *copy_geom(const struct detector *in)
{
struct detector *out;
@@ -1796,17 +1806,19 @@ struct detector *copy_geom(const struct detector *in)
out->bad = malloc(out->n_bad * sizeof(struct badregion));
memcpy(out->bad, in->bad, out->n_bad * sizeof(struct badregion));
- out->n_rigid_groups = 0;
- out->rigid_groups = NULL;
- out->n_rg_collections = 0;
- out->rigid_group_collections = NULL;
+ /* Copy all fields */
+ *out = *in;
+ /* Copy the panels */
for ( i=0; i<out->n_panels; i++ ) {
struct panel *p;
+ /* Copy all fields */
p = &out->panels[i];
+ /* Now fix up everything involving pointers... */
+
if ( p->clen_from != NULL ) {
/* Make a copy of the clen_from fields unique to this
* copy of the structure. */
@@ -1837,24 +1849,6 @@ struct detector *copy_geom(const struct detector *in)
}
- }
-
- for ( i=0; i<in->n_panels; i++ ) {
-
- int rgi;
-
- for ( rgi=0; rgi<in->n_rigid_groups; rgi++ ) {
-
- if ( panel_is_in_rigid_group(in->rigid_groups[rgi],
- &in->panels[i]) )
- {
- struct rigid_group *g;
- g = find_or_add_rg(out,
- in->rigid_groups[rgi]->name);
- add_to_rigid_group(g, &out->panels[i]);
- }
- }
-
if ( &in->panels[i] == in->furthest_out_panel ) {
out->furthest_out_panel = &out->panels[i];
}
@@ -1862,27 +1856,67 @@ struct detector *copy_geom(const struct detector *in)
out->furthest_in_panel = &out->panels[i];
}
+ }
+
+ /* Copy all the rigid groups */
+ out->rigid_groups = malloc(out->n_rigid_groups*sizeof(struct rigid_group));
+ if ( out->rigid_groups == NULL ) return NULL;
+ for ( i=0; i<out->n_rigid_groups; i++ ) {
+
+ struct rigid_group *inrg;
+ struct rigid_group *rg;
+ int j;
+
+ rg = malloc(sizeof(struct rigid_group));
+ if ( rg == NULL ) return NULL;
+
+ out->rigid_groups[i] = rg;
+
+ inrg = in->rigid_groups[i];
+
+ rg->name = strdup(inrg->name);
+ if ( rg->name == NULL ) return NULL;
+
+ rg->n_panels = inrg->n_panels;
+ rg->panels = malloc(inrg->n_panels*sizeof(struct panel *));
+ if ( rg->panels == NULL ) return NULL;
+
+ for ( j=0; j<rg->n_panels; j++ ) {
+ int k = panel_number(in, inrg->panels[j]);
+ rg->panels[j] = &out->panels[k];
+ }
}
- for ( i=0; i<in->n_rigid_groups; i++ ) {
+ /* Copy all the rigid group collections */
+ out->rigid_group_collections = malloc(out->n_rg_collections*sizeof(struct rg_collection));
+ if ( out->rigid_group_collections == NULL ) return NULL;
+ for ( i=0; i<out->n_rg_collections; i++ ) {
- int rgci;
+ struct rg_collection *inrgc;
+ struct rg_collection *rgc;
+ int j;
- for ( rgci=0; rgci<in->n_rg_collections; rgci++ ) {
+ rgc = malloc(sizeof(struct rg_collection));
+ if ( rgc == NULL ) return NULL;
- const char *n = in->rigid_group_collections[rgci]->name;
+ out->rigid_group_collections[i] = rgc;
- if ( rigid_group_is_in_collection(
- in->rigid_group_collections[rgci],
- in->rigid_groups[i]) )
- {
- struct rg_collection *rgcoll;
- rgcoll = find_or_add_rg_coll(out, n);
- add_to_rigid_group_coll(rgcoll,
- out->rigid_groups[i]);
- }
+ inrgc = in->rigid_group_collections[i];
+
+ rgc->name = strdup(inrgc->name);
+ if ( rgc->name == NULL ) return NULL;
+
+ rgc->n_rigid_groups = inrgc->n_rigid_groups;
+ rgc->rigid_groups = malloc(rgc->n_rigid_groups*sizeof(struct rg_collection));
+ if ( rgc->rigid_groups == NULL ) return NULL;
+
+ for ( j=0; j<rgc->n_rigid_groups; j++ ) {
+ int k = rg_number(in, inrgc->rigid_groups[j]);
+ if ( k == in->n_rigid_groups ) return NULL;
+ rgc->rigid_groups[j] = out->rigid_groups[k];
}
+
}
return out;