aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/geoptimiser.110
-rw-r--r--src/geoptimiser.c159
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;