diff options
-rw-r--r-- | doc/man/geoptimiser.1 | 10 | ||||
-rw-r--r-- | src/geoptimiser.c | 159 |
2 files changed, 154 insertions, 15 deletions
diff --git a/doc/man/geoptimiser.1 b/doc/man/geoptimiser.1 index 90a04c74..2a544830 100644 --- a/doc/man/geoptimiser.1 +++ b/doc/man/geoptimiser.1 @@ -117,6 +117,16 @@ to be included in the optimization process. The default maximum distance is 8 pi .PD By default, geoptimiser refines the distance between the detector and the sample. This option turns off this optimization. +.PD 0 +.IP \fB--no-cspad\fR +.PD +If a geometry file containing 64 panels (ASICs) is provided by the user, geoptimiser assumes that the detector described by the geometry file is a CSPAD, and performs some sanity-checks on the relative ditance and orientation of connected panels. If the checks fail, the geometry optimization is stopped. This option turns off these checks. + +.PD 0 +.IP \fB--enforce-cspad-layout\fR +.PD +When this option is used, geoptimiser tries to fix the CSPAD layout problems detected by the checks described in the entry for the \fB--no-cspad\fR option. Immediately after performing this operation, geoptimser saves the new detector layout in the output refined geometry file and exits. + .SH AUTHOR This page was written by Valerio Mariani, Oleksandr Yefanov and Thomas White. diff --git a/src/geoptimiser.c b/src/geoptimiser.c index cea22029..1605e363 100644 --- a/src/geoptimiser.c +++ b/src/geoptimiser.c @@ -2288,12 +2288,86 @@ static void compute_abs_displ(struct rg_collection *connected, } +int check_and_enforce_cspad_dist(struct detector *det, int enforce) +{ + int np = 0; + int num_errors_found = 0; + + double dist_to_check = 197.0; + double tol = 0.2; + + for ( np=0; np<det->n_panels; np = np+2 ) { + + double dist2; + + struct panel *ep = &det->panels[np]; + struct panel *op = &det->panels[np+1]; + + dist2 = (( ep->cnx - op->cnx )*( ep->cnx - op->cnx ) + + ( ep->cny - op->cny )*( ep->cny - op->cny )); + + if ( dist2 > (dist_to_check+tol)*(dist_to_check+tol) || + dist2 < (dist_to_check-tol)*(dist_to_check-tol) ) { + + num_errors_found += 1; + + STATUS("Warning: distance between panels %s and %s " + "is outside acceptable margins.\n", ep->name, + op->name); + + if ( enforce ) { + + double new_op_cx, new_op_cy; + + new_op_cx = ep->cnx + ep->fsx*dist_to_check; + new_op_cy = ep->cny + ep->fsy*dist_to_check; + + op->cnx = new_op_cx; + op->cny = new_op_cy; + + STATUS("Enforcing distance....\n"); + } + + } + + if ( ep->fsx != op->fsx || ep->ssx != op->ssx || + ep->fsy != op->fsy || ep->ssx != op->ssx ) { + + num_errors_found += 1; + + STATUS("Warning: relative orientation between panels " + "%s and %s is incorrect.\n", ep->name, op->name); + + if ( enforce ) { + + STATUS("Enforcing relative orientation....\n"); + + op->fsx = ep->fsx; + op->ssx = ep->ssx; + op->fsy = ep->fsy; + op->ssy = ep->ssy; + + op->xfs = ep->xfs; + op->xss = ep->xss; + op->yfs = ep->yfs; + op->yss = ep->yss; + } + + } + + } + return num_errors_found; +} + + + int optimize_geometry(char *infile, char *outfile, char *geometry_filename, struct detector *det, struct rg_collection* quadrants, struct rg_collection* connected, int min_num_peaks_per_pixel, int min_num_peaks_per_panel, int only_best_distance, int nostretch, int individual_coffset, int error_maps, + int enforce_cspad_layout, int no_cspad, double max_peak_dist, const char *command_line) { int num_pix_in_slab; @@ -2304,6 +2378,7 @@ int optimize_geometry(char *infile, char *outfile, char *geometry_filename, int ret1, ret2; int ret; int write_ret; + int maybe_cspad = 0; int *num_pix_displ; @@ -2343,6 +2418,55 @@ int optimize_geometry(char *infile, char *outfile, char *geometry_filename, STATUS("Minimum number of measurements for panel for accurate estimation " "of position/orientation: %i\n", min_num_peaks_per_panel); + if ( det->n_panels == 64 ) { + maybe_cspad = 1; + } + + if ( maybe_cspad && !no_cspad ) { + + int num_errors = 0; + + STATUS("It looks like the detector is a CSPAD. " + "Checking relative distance and orientation of " + "connected ASICS.\n"); + STATUS("If the detector is not a CSPAD, please rerun the " + "program with the --no-cspad option.\n"); + if ( enforce_cspad_layout ) { + STATUS("Enforcing CSPAD layout...\n"); + } + + num_errors = check_and_enforce_cspad_dist(det, + enforce_cspad_layout); + + if ( enforce_cspad_layout ) { + + int geom_wr; + + STATUS("Saving geometry with enforced CSPAD layout.\n" + "Please restart geometry optimization using the " + "optimized geometry from this run as input geometry " + "file.\n"); + geom_wr = write_detector_geometry_2(geometry_filename, + outfile, det, + command_line, 1); + if ( geom_wr != 0 ) { + ERROR("Error in writing output geometry file.\n"); + return 1; + } + STATUS("All done!\n"); + return 0; + } + + if ( !enforce_cspad_layout && num_errors > 0 ) { + ERROR("Relative distance and orientation of connected " + "ASICS do not respect the CSPAD layout.\n" + "Geometry optimization cannot continue.\n" + "Please rerun the program with the " + "--enforce-cspad-layout option.\n"); + return 1; + } + } + pattern_list = read_patterns_from_steam_file(infile, det); if ( pattern_list->n_patterns < 1 ) { ERROR("Error reading stream file\n"); @@ -2703,8 +2827,10 @@ int main(int argc, char *argv[]) int min_num_peaks_per_pixel = 3; int min_num_peaks_per_panel = 100; int only_best_distance = 0; + int enforce_cspad_layout = 0; int nostretch = 0; int individual_coffset = 0; + int no_cspad = 0; int error_maps = 1; double max_peak_dist = 4.0; @@ -2716,22 +2842,24 @@ int main(int argc, char *argv[]) const struct option longopts[] = { /* Options with long and short versions */ - {"help", 0, NULL, 'h'}, - {"version", 0, NULL, 10 }, - {"input", 1, NULL, 'i'}, - {"output", 1, NULL, 'o'}, - {"geometry", 1, NULL, 'g'}, - {"quadrants", 1, NULL, 'q'}, - {"connected", 1, NULL, 'c'}, - {"min-num-peaks-per-pixel",1, NULL, 'x'}, - {"min-num-peaks-per-panel",1, NULL, 'p'}, - {"most-few-clen", 0, NULL, 'l'}, - {"max-peak-dist", 1, NULL, 'm'}, - {"individual-dist-offset", 0, NULL, 's'}, + {"help", 0, NULL, 'h'}, + {"version", 0, NULL, 10 }, + {"input", 1, NULL, 'i'}, + {"output", 1, NULL, 'o'}, + {"geometry", 1, NULL, 'g'}, + {"quadrants", 1, NULL, 'q'}, + {"connected", 1, NULL, 'c'}, + {"min-num-peaks-per-pixel", 1, NULL, 'x'}, + {"min-num-peaks-per-panel", 1, NULL, 'p'}, + {"most-few-clen", 0, NULL, 'l'}, + {"max-peak-dist", 1, NULL, 'm'}, + {"individual-dist-offset", 0, NULL, 's'}, /* Long-only options with no arguments */ - {"no-stretch", 0, &nostretch, 1}, - {"no-error-maps", 0, &error_maps, 0}, + {"no-stretch", 0, &nostretch, 1}, + {"no-error-maps", 0, &error_maps, 0}, + {"enforce-cspad-layout", 0, &enforce_cspad_layout, 1}, + {"no-cspad", 0, &no_cspad, 1}, {0, 0, NULL, 0} }; @@ -2854,7 +2982,8 @@ int main(int argc, char *argv[]) ret_val = optimize_geometry(infile, outfile, geometry_filename, det, quadrants, connected, min_num_peaks_per_pixel, min_num_peaks_per_panel, only_best_distance, - nostretch, individual_coffset, error_maps, + nostretch, individual_coffset, error_maps, + enforce_cspad_layout, no_cspad, max_peak_dist, command_line); return ret_val; |