diff options
author | Thomas White <taw@physics.org> | 2019-07-29 16:00:10 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2019-07-29 17:11:16 +0200 |
commit | 82719e4d6fec3c28bcdc310ba382e12aa4f041d4 (patch) | |
tree | d518bcdc0649ac9bb07747619c5dc751744ce72d /libcrystfel/src | |
parent | 83ef79e1642841966690e4c9643a8716e8521112 (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/src')
-rw-r--r-- | libcrystfel/src/detector.c | 104 |
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; |