From 8f53e56cc8e52eadba447b0fd8349a0e53007627 Mon Sep 17 00:00:00 2001 From: David Waterman Date: Mon, 26 Feb 2024 12:54:53 +0000 Subject: [PATCH] Allow distance override for multi-panel detectors (#698) Allow distance override for multi-panel detectors. If a multi-panel detector has a hierarchy, it will have its root node distance set. If there is no hierarchy then each panel will individually have distance set, but only if those panels are coplanar and already at the same distance. --- newsfragments/698.feature | 1 + src/dxtbx/model/detector_helpers.py | 37 ++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 newsfragments/698.feature diff --git a/newsfragments/698.feature b/newsfragments/698.feature new file mode 100644 index 000000000..34add9eac --- /dev/null +++ b/newsfragments/698.feature @@ -0,0 +1 @@ +Manual override of the detector distance is now available for multi-panel detectors. diff --git a/src/dxtbx/model/detector_helpers.py b/src/dxtbx/model/detector_helpers.py index 248e44b64..3240caf7e 100644 --- a/src/dxtbx/model/detector_helpers.py +++ b/src/dxtbx/model/detector_helpers.py @@ -303,15 +303,34 @@ def set_detector_distance(detector, distance): """ Set detector origin from distance along normal """ - assert len(detector) == 1 - normal = matrix.col(detector[0].get_normal()) - origin = matrix.col(detector[0].get_origin()) - d = origin.dot(normal) - x = origin - d * normal - origin = distance * normal + x - fast_axis = detector[0].get_fast_axis() - slow_axis = detector[0].get_slow_axis() - detector[0].set_frame(fast_axis, slow_axis, origin) + # If the detector has a hierarchy, just update the root note + try: + h = detector.hierarchy() + normal = matrix.col(h.get_normal()) + origin = matrix.col(h.get_origin()) + d = origin.dot(normal) + x = origin - d * normal + origin = distance * normal + x + fast_axis = h.get_fast_axis() + slow_axis = h.get_slow_axis() + h.set_frame(fast_axis, slow_axis, origin) + except AttributeError: + # Check all panels are at the same distance and share the same normal + dists = [p.get_distance() for p in detector] + norm_vecs = [p.get_normal() for p in detector] + assert all(v == norm_vecs[0] for v in norm_vecs[1:]) and all( + d == dists[0] for d in dists + ) + + for panel in detector: + normal = matrix.col(panel.get_normal()) + origin = matrix.col(panel.get_origin()) + d = origin.dot(normal) + x = origin - d * normal + origin = distance * normal + x + fast_axis = panel.get_fast_axis() + slow_axis = panel.get_slow_axis() + panel.set_frame(fast_axis, slow_axis, origin) def get_detector_projection_2d_axes(