diff options
Diffstat (limited to 'libcrystfel/src/detector.c')
-rw-r--r-- | libcrystfel/src/detector.c | 499 |
1 files changed, 449 insertions, 50 deletions
diff --git a/libcrystfel/src/detector.c b/libcrystfel/src/detector.c index f5f6bb57..ecb0ea99 100644 --- a/libcrystfel/src/detector.c +++ b/libcrystfel/src/detector.c @@ -59,6 +59,19 @@ */ + +struct rg_definition { + char *name; + char *pns; +}; + + +struct rgc_definition { + char *name; + char *rgs; +}; + + static int atob(const char *a) { if ( strcasecmp(a, "true") == 0 ) return 1; @@ -203,6 +216,57 @@ static int dir_conv(const char *a, double *sx, double *sy) } +static int count_trailing_spaces(const char *string) { + + int i; + + for ( i=0; i<strlen(string); i++ ) { + if ( !isspace(string[i]) ) { + return i; + } + } + + return -1; +} + + +static void build_output_line (const char *line, char *new_line, + const char *string_to_write) +{ + int nsp, i, w, ww; + int trailsp; + int n_bits; + char **bits; + + n_bits = assplode(line, "=", &bits, ASSPLODE_NONE); + trailsp = count_trailing_spaces(bits[1]); + + strcat(new_line, bits[0]); + strcat(new_line, "="); + + for ( nsp=0; nsp < trailsp; nsp++ ) { + strcat(new_line, " "); + } + strcat(new_line, string_to_write); + + for ( w=0; w<strlen(line); w++ ) { + if ( strncmp(&line[w],";",1) == 0 ) { + for ( ww=w-1; ww>=0; ww-- ) { + if ( !isspace(line[ww])) { + strcat(new_line, &line[ww]); + break; + } + } + break; + } + } + if ( w == strlen(line) ) strcat(new_line, "\n"); + + for ( i=0; i<n_bits; i++) free(bits[i]); + free(bits); +} + + struct rvec get_q_for_panel(struct panel *p, double fs, double ss, double *ttp, double k) { @@ -509,6 +573,52 @@ void fill_in_values(struct detector *det, struct hdfile *f, struct event* ev) } +int panel_is_in_rigid_group(const struct rigid_group *rg, struct panel *p) +{ + int i; + + for ( i=0; i<rg->n_panels; i++ ) { + if ( rg->panels[i] == p ) { + return 1; + } + } + + return 0; +} + + +int rigid_group_is_in_collection(struct rg_collection *c, + struct rigid_group *rg) +{ + int i; + + for ( i=0; i<c->n_rigid_groups; i++ ) { + if ( c->rigid_groups[i] == rg ) { + return 1; + } + } + + return 0; +} + + +struct rg_collection *find_rigid_group_collection_by_name(struct detector *det, + const char *name) +{ + int i; + + for ( i=0; i<det->n_rg_collections; i++ ) { + if ( strcmp(det->rigid_group_collections[i]->name, + name) == 0 ) { + return det->rigid_group_collections[i]; + } + } + + return NULL; + +} + + static struct panel *new_panel(struct detector *det, const char *name) { struct panel *new; @@ -643,6 +753,41 @@ static struct rigid_group *find_or_add_rg(struct detector *det, } +static struct rg_collection *find_or_add_rg_coll(struct detector *det, + const char *name) +{ + int i; + struct rg_collection **new; + struct rg_collection *rgc; + + for ( i=0; i<det->n_rg_collections; i++ ) { + + if ( strcmp(det->rigid_group_collections[i]->name, name) == 0 ) { + return det->rigid_group_collections[i]; + } + + } + + new = realloc(det->rigid_group_collections, + (1+det->n_rg_collections)* + sizeof(struct rg_collection *)); + if ( new == NULL ) return NULL; + + det->rigid_group_collections = new; + + rgc = malloc(sizeof(struct rg_collection)); + if ( rgc == NULL ) return NULL; + + det->rigid_group_collections[det->n_rg_collections++] = rgc; + + rgc->name = strdup(name); + rgc->rigid_groups = NULL; + rgc->n_rigid_groups = 0; + + return rgc; +} + + static void add_to_rigid_group(struct rigid_group *rg, struct panel *p) { struct panel **pn; @@ -653,12 +798,27 @@ static void add_to_rigid_group(struct rigid_group *rg, struct panel *p) return; } - assert(p->rigid_group == rg); rg->panels = pn; rg->panels[rg->n_panels++] = p; } +static void add_to_rigid_group_coll(struct rg_collection *rgc, + struct rigid_group *rg) +{ + struct rigid_group **r; + + r = realloc(rgc->rigid_groups, (1+rgc->n_rigid_groups)* + sizeof(struct rigid_group *)); + if ( r == NULL ) { + ERROR("Couldn't add rigid group to collection.\n"); + return; + } + + rgc->rigid_groups = r; + rgc->rigid_groups[rgc->n_rigid_groups++] = rg; +} + static void rigid_groups_free(struct detector *det) { int i; @@ -672,19 +832,33 @@ static void rigid_groups_free(struct detector *det) free(det->rigid_groups); } - -static void fix_up_rigid_groups(struct detector *det) +static void rigid_groups_collection_free(struct detector *det) { int i; - for ( i=0; i<det->n_panels; i++ ) { + if ( det->rigid_group_collections == NULL ) return; + for ( i=0; i<det->n_rg_collections; i++ ) { + free(det->rigid_group_collections[i]->name); + free(det->rigid_group_collections[i]->rigid_groups); + free(det->rigid_group_collections[i]); + } + free(det->rigid_group_collections); +} - struct panel *p = &det->panels[i]; - if ( p->rigid_group != NULL ) { - add_to_rigid_group(p->rigid_group, p); - } +static struct rigid_group *find_rigid_group_by_name(struct detector *det, + char *name) +{ + int i; + + for ( i=0; i<det->n_rigid_groups; i++ ) { + if ( strcmp(det->rigid_groups[i]->name, name) == 0 ) { + return det->rigid_groups[i]; + } } + + return NULL; + } @@ -708,7 +882,7 @@ static int parse_field_for_panel(struct panel *panel, const char *key, } else if ( strcmp(key, "adu_per_eV") == 0 ) { panel->adu_per_eV = atof(val); } else if ( strcmp(key, "rigid_group") == 0 ) { - panel->rigid_group = find_or_add_rg(det, val); + add_to_rigid_group(find_or_add_rg(det, val), panel); } else if ( strcmp(key, "clen") == 0 ) { char *end; @@ -824,8 +998,12 @@ static int parse_field_bad(struct badregion *panel, const char *key, static void parse_toplevel(struct detector *det, struct beam_params *beam, - const char *key, const char *val) + const char *key, const char *val, + struct rg_definition ***rg_defl, + struct rgc_definition ***rgc_defl, int *n_rg_defs, + int *n_rgc_defs) { + if ( strcmp(key, "mask_bad") == 0 ) { char *end; @@ -860,6 +1038,33 @@ static void parse_toplevel(struct detector *det, struct beam_params *beam, if ( beam != NULL ) { beam->photon_energy_scale = atof(val); } + } else if (strncmp(key, "rigid_group", 11) == 0 && + strncmp(key, "rigid_group_collection", 22) != 0 ) { + + struct rg_definition **new; + + new = realloc(*rg_defl, + ((*n_rg_defs)+1)*sizeof(struct rg_definition*)); + *rg_defl = new; + + (*rg_defl)[*n_rg_defs] = malloc(sizeof(struct rg_definition)); + (*rg_defl)[*n_rg_defs]->name = strdup(key+12); + (*rg_defl)[*n_rg_defs]->pns = strdup(val); + *n_rg_defs = *n_rg_defs+1; + + } else if ( strncmp(key, "rigid_group_collection", 22) == 0 ) { + + struct rgc_definition **new; + + new = realloc(*rgc_defl, ((*n_rgc_defs)+1)* + sizeof(struct rgc_definition*)); + *rgc_defl = new; + + (*rgc_defl)[*n_rgc_defs] = + malloc(sizeof(struct rgc_definition)); + (*rgc_defl)[*n_rgc_defs]->name = strdup(key+23); + (*rgc_defl)[*n_rgc_defs]->rgs = strdup(val); + *n_rgc_defs = *n_rgc_defs+1; } else if ( parse_field_for_panel(&det->defaults, key, val, det) ) { ERROR("Unrecognised top level field '%s'\n", key); @@ -933,6 +1138,7 @@ struct detector *get_detector_geometry(const char *filename, char *rval; char **bits; int i; + int rgi, rgci; int reject = 0; int path_dim; int dim_dim; @@ -940,6 +1146,10 @@ struct detector *get_detector_geometry(const char *filename, int x, y, max_fs, max_ss; int dim_reject = 0; int dim_dim_reject = 0; + struct rg_definition **rg_defl = NULL; + struct rgc_definition **rgc_defl = NULL; + int n_rg_definitions = 0; + int n_rgc_definitions = 0; fh = fopen(filename, "r"); if ( fh == NULL ) return NULL; @@ -966,6 +1176,8 @@ struct detector *get_detector_geometry(const char *filename, det->rigid_groups = NULL; det->path_dim = 0; det->dim_dim = 0; + det->n_rg_collections = 0; + det->rigid_group_collections = NULL; /* The default defaults... */ det->defaults.min_fs = -1; @@ -987,7 +1199,6 @@ struct detector *get_detector_geometry(const char *filename, det->defaults.fsy = 0.0; det->defaults.ssx = 0.0; det->defaults.ssy = 1.0; - det->defaults.rigid_group = NULL; det->defaults.adu_per_eV = NAN; det->defaults.max_adu = +INFINITY; det->defaults.mask = NULL; @@ -1034,7 +1245,9 @@ struct detector *get_detector_geometry(const char *filename, if ( n2 < 2 ) { /* This was a top-level option, not handled above. */ - parse_toplevel(det, beam, bits[0], bits[2]); + parse_toplevel(det, beam, bits[0], bits[2], &rg_defl, + &rgc_defl, &n_rg_definitions, + &n_rgc_definitions); for ( i=0; i<n1; i++ ) free(bits[i]); free(bits); for ( i=0; i<n2; i++ ) free(path[i]); @@ -1338,6 +1551,90 @@ out: free(det->defaults.data); free(det->defaults.mask); + for ( rgi=0; rgi<n_rg_definitions; rgi++) { + + int pi, n1; + struct rigid_group *rigidgroup = NULL; + + rigidgroup = find_or_add_rg(det, rg_defl[rgi]->name); + + n1 = assplode(rg_defl[rgi]->pns, ",", &bits, ASSPLODE_NONE); + + for ( pi=0; pi<n1; pi++ ) { + + struct panel *p; + + p = find_panel_by_name(det, bits[pi]); + if ( p == NULL ) { + ERROR("Cannot add panel to rigid group\n"); + ERROR("Panel not found: %s\n", bits[pi]); + } + add_to_rigid_group(rigidgroup, p); + free(bits[pi]); + } + free(bits); + free(rg_defl[rgi]->name); + free(rg_defl[rgi]->pns); + free(rg_defl[rgi]); + } + free(rg_defl); + + for ( rgci=0; rgci<n_rgc_definitions; rgci++) { + + int rgi, n2; + struct rg_collection *rgcollection = NULL; + + rgcollection = find_or_add_rg_coll(det, rgc_defl[rgci]->name); + + n2 = assplode(rgc_defl[rgci]->rgs, ",", &bits, ASSPLODE_NONE); + + for ( rgi=0; rgi<n2; rgi++ ) { + + struct rigid_group *r; + + r = find_rigid_group_by_name(det, bits[rgi]); + if ( r == NULL ) { + ERROR("Cannot add rigid group to collection\n"); + ERROR("Rigid groups not found: %s\n", bits[rgi]); + } + add_to_rigid_group_coll(rgcollection, r); + free(bits[rgi]); + } + free(rgc_defl[rgci]->name); + free(rgc_defl[rgci]->rgs); + free(rgc_defl[rgci]); + } + free(rgc_defl); + + if ( n_rg_definitions == 0) { + + int pi; + + for ( pi=0; pi<det->n_panels; pi++ ) { + + struct rigid_group *rigidgroup = NULL; + + rigidgroup = find_or_add_rg(det, det->panels[pi].name); + add_to_rigid_group(rigidgroup, &det->panels[pi]); + + } + } + + if ( n_rgc_definitions == 0) { + + int rgi; + struct rg_collection *rgcollection = NULL; + + rgcollection = find_or_add_rg_coll(det, "default"); + + for ( rgi=0; rgi<det->n_rigid_groups; rgi++ ) { + + add_to_rigid_group_coll(rgcollection, + det->rigid_groups[rgi]); + + } + } + /* Calculate matrix inverses and other stuff */ for ( i=0; i<det->n_panels; i++ ) { @@ -1348,7 +1645,6 @@ out: if ( p->fsx*p->ssy == p->ssx*p->fsy ) { ERROR("Panel %i transformation singular.\n", i); - reject = 1; } d = (double)p->fsx*p->ssy - p->ssx*p->fsy; @@ -1360,15 +1656,9 @@ out: p->w = p->max_fs - p->min_fs + 1; p->h = p->max_ss - p->min_ss + 1; - if ( p->rigid_group == NULL ) { - p->rigid_group = find_or_add_rg(det, p->name); - } - } - /* Fix up rigid group panel pointers now that the panels and RGs have - * stopped being realloc()ed */ - fix_up_rigid_groups(det); + find_min_max_d(det); @@ -1385,6 +1675,7 @@ void free_detector_geometry(struct detector *det) int i; rigid_groups_free(det); + rigid_groups_collection_free(det); for ( i=0; i<det->n_panels; i++ ) { free(det->panels[i].clen_from); @@ -1460,16 +1751,34 @@ struct detector *copy_geom(const struct detector *in) for ( i=0; i<in->n_panels; i++ ) { - struct rigid_group *rg; + int rgi; - rg = in->panels[i].rigid_group; - if ( rg == NULL ) continue; - - out->panels[i].rigid_group = find_or_add_rg(out, rg->name); + for ( rgi=0; rgi<in->n_rigid_groups; rgi++ ) { + if ( panel_is_in_rigid_group(in->rigid_groups[rgi], + &in->panels[i])) { + add_to_rigid_group(find_or_add_rg(out, + in->rigid_groups[rgi]->name), + &out->panels[i]); + } + } } - fix_up_rigid_groups(out); + for ( i=0; i<in->n_rigid_groups; i++ ) { + + int rgci; + + for ( rgci=0; rgci<in->n_rg_collections; rgci++ ) { + if ( rigid_group_is_in_collection( + in->rigid_group_collections[rgci], + in->rigid_groups[i]) ) + { + add_to_rigid_group_coll(find_or_add_rg_coll(out, + in->rigid_group_collections[rgci]->name), + out->rigid_groups[i]); + } + } + } return out; } @@ -1494,7 +1803,6 @@ struct detector *simple_geometry(const struct image *image) geom->panels[0].orig_max_ss = image->height-1; geom->panels[0].cnx = -image->width / 2.0; geom->panels[0].cny = -image->height / 2.0; - geom->panels[0].rigid_group = NULL; geom->panels[0].max_adu = INFINITY; geom->panels[0].orig_min_fs = -1; geom->panels[0].orig_max_fs = -1; @@ -1642,7 +1950,9 @@ void get_pixel_extents(struct detector *det, int write_detector_geometry(const char *geometry_filename, - const char *output_filename, struct detector *det) + const char *output_filename, struct detector *det, + const char *additional_comment, + int write_panel_coffset) { FILE *ifh; FILE *fh; @@ -1655,53 +1965,142 @@ int write_detector_geometry(const char *geometry_filename, if ( ifh == NULL ) return 1; fh = fopen(output_filename, "w"); - if ( fh == NULL ) return 1; + if ( fh == NULL ) { + fclose(fh); + return 1; + } + + if ( additional_comment != NULL ) { + + char additional_comment_tmp[1024]; + + strcpy(additional_comment_tmp, "; "); + strncat(additional_comment_tmp, additional_comment, 1021); + strcat(additional_comment_tmp, "\n"); + if ( strlen(additional_comment) > 1021 ) { + strncpy(&additional_comment_tmp[1023], "\0", 1); + } + fputs(additional_comment_tmp, fh); + } + if ( write_panel_coffset ) { + + char new_line[1024]; + strcpy(new_line,"; Optimized panel offsets can be found at the " + "end of the file\n"); + fputs(new_line, fh); + + } do { char *rval; char line[1024]; + char new_line[1024]; + char string_to_write[512]; + int n_bits; char **bits; + int i; struct panel *p; + strcpy(new_line,"\0"); + strcpy(string_to_write,"\0"); + rval = fgets(line, 1023, ifh); if ( rval == NULL ) break; - n_bits = assplode(line, "/", &bits, ASSPLODE_NONE); + n_bits = assplode(line, "/=", &bits, ASSPLODE_NONE); - if ( n_bits < 2 || n_bits > 2 ) { - for ( i=0; i<n_bits; i++ ) free(bits[i]); - fputs(line, fh); + if ( n_bits != 3 ) { + if ( strstr(bits[0], "coffset" ) != NULL && + write_panel_coffset ) { + continue; + } else { + fputs(line, fh); + } } else { + p = find_panel_by_name(det, bits[0]); - if ( strncmp(bits[1], "fs = ", 5) == 0) { - fprintf(fh, "%s/fs = %+fx %+fy\n", - p->name, p->fsx, p->fsy); + if ( p != NULL ) { + + if(strstr(bits[1], "fs") != NULL && + strstr(bits[1], "min_fs") == NULL && + strstr(bits[1], "max_fs") == NULL) { + + sprintf(string_to_write, "%+fx %+fy", + p->fsx, p->fsy); + build_output_line(line, new_line, + string_to_write); + fputs(new_line, fh); + continue; + + } else if ( strstr(bits[1], "ss") != NULL && + strstr(bits[1], "min_ss") == NULL && + strstr(bits[1], "max_ss") == NULL) { + + sprintf(string_to_write, "%+fx %+fy", + p->ssx, p->ssy); + build_output_line(line, new_line, + string_to_write); + fputs(new_line, fh); + continue; + + } else if ( strstr(bits[1], "corner_x") != NULL) { + + sprintf(string_to_write, "%g", + p->cnx); + build_output_line(line, new_line, + string_to_write); + fputs(new_line, fh); + continue; + + } else if ( strstr(bits[1], "corner_y") != NULL) { + + sprintf(string_to_write, "%g", + p->cny); + build_output_line(line, new_line, + string_to_write); + fputs(new_line, fh); + continue; + + } else if ( strstr(bits[1], "coffset") != NULL) { + + if ( write_panel_coffset ) { + continue; + } else { + fputs(line, fh); + continue; + } + + } else { + fputs(line, fh); + } + } else { + fputs(line, fh); + } + } - } else if ( strncmp(bits[1], "ss = ", 5) == 0) { - fprintf(fh, "%s/ss = %+fx %+fy\n", - p->name, p->ssx, p->ssy); + for ( i=0; i<n_bits; i++ ) free(bits[i]); - } else if ( strncmp(bits[1], "corner_x = ", 11) == 0) { - fprintf(fh, "%s/corner_x = %g\n", - p->name, p->cnx); + } while ( 1 ); - } else if ( strncmp(bits[1], "corner_y = ", 11) == 0) { - fprintf(fh, "%s/corner_y = %g\n", - p->name, p->cny); + if ( write_panel_coffset ) { - } else { - fputs(line, fh); - } + int pi; + char new_line[1024]; - for ( i=0; i<n_bits; i++ ) free(bits[i]); + strcpy(new_line, "\n"); + fputs(new_line, fh); + for ( pi=0; pi<det->n_panels; pi++ ) { + sprintf(new_line, "%s/coffset = %f\n", + det->panels[pi].name, det->panels[pi].coffset); + fputs(new_line, fh); } + } - } while ( 1 ); fclose(ifh); fclose(fh); |