def _setup_detector(self, detector, beam): nx_detector = detector.handle nx_module = detector.modules[0].handle # Get the detector name and type if "type" in nx_detector: detector_type = str(nx_detector["type"][()]) else: detector_type = "unknown" detector_name = str(nx_detector.name) # Get the trusted range of pixel values if "saturation_value" in nx_detector: trusted_range = (-1, float(nx_detector["saturation_value"][()])) else: trusted_range = (-1, 99999999) # Get the detector thickness thickness = nx_detector["sensor_thickness"] thickness_value = float(thickness[()]) thickness_units = thickness.attrs["units"] thickness_value = float(convert_units(thickness_value, thickness_units, "mm")) # Get the detector material material = nx_detector["sensor_material"][()] if hasattr(material, "shape"): material = "".join(m.decode() for m in material) detector_material = clean_string(str(material)) material = { "Si": "Si", np.string_("Si"): "Si", np.string_("Silicon"): "Si", np.string_("Sillicon"): "Si", np.string_("CdTe"): "CdTe", np.string_("GaAs"): "GaAs", }.get(detector_material) if not material: raise RuntimeError("Unknown material: %s" % detector_material) try: x_pixel = nx_detector["x_pixel_size"][()] * 1000.0 y_pixel = nx_detector["y_pixel_size"][()] * 1000.0 legacy_beam_x = float(x_pixel * nx_detector["beam_center_x"][()]) legacy_beam_y = float(y_pixel * nx_detector["beam_center_y"][()]) legacy_distance = float(1000 * nx_detector["detector_distance"][()]) except KeyError: legacy_beam_x = 0 legacy_beam_y = 0 # Get the fast pixel size and vector fast_pixel_direction = nx_module["fast_pixel_direction"] fast_pixel_direction_value = float(fast_pixel_direction[()]) fast_pixel_direction_units = fast_pixel_direction.attrs["units"] fast_pixel_direction_vector = fast_pixel_direction.attrs["vector"] fast_pixel_direction_value = convert_units( fast_pixel_direction_value, fast_pixel_direction_units, "mm" ) fast_axis = matrix.col(fast_pixel_direction_vector).normalize() # Get the slow pixel size and vector slow_pixel_direction = nx_module["slow_pixel_direction"] slow_pixel_direction_value = float(slow_pixel_direction[()]) slow_pixel_direction_units = slow_pixel_direction.attrs["units"] slow_pixel_direction_vector = slow_pixel_direction.attrs["vector"] slow_pixel_direction_value = convert_units( slow_pixel_direction_value, slow_pixel_direction_units, "mm" ) slow_axis = matrix.col(slow_pixel_direction_vector).normalize() origin = matrix.col((0.0, 0.0, -legacy_distance)) if origin.elems[0] == 0.0 and origin.elems[1] == 0: origin = -(origin + legacy_beam_x * fast_axis + legacy_beam_y * slow_axis) # Change of basis to convert from NeXus to IUCr/ImageCIF convention cob = matrix.sqr((-1, 0, 0, 0, 1, 0, 0, 0, -1)) origin = cob * matrix.col(origin) fast_axis = cob * fast_axis slow_axis = cob * slow_axis # Ensure that fast and slow axis are orthogonal normal = fast_axis.cross(slow_axis) slow_axis = -fast_axis.cross(normal) # Compute the attenuation coefficient. # This will fail for undefined composite materials # mu_at_angstrom returns cm^-1, but need mu in mm^-1 table = attenuation_coefficient.get_table(material) wavelength = beam.get_wavelength() mu = table.mu_at_angstrom(wavelength) / 10.0 # Construct the detector model pixel_size = (fast_pixel_direction_value, slow_pixel_direction_value) # image size stored slow to fast but dxtbx needs fast to slow image_size = tuple(int(x) for x in reversed(nx_module["data_size"][-2:])) image_size = (1030, 1064) self.model = Detector() self.model.add_panel( Panel( detector_type, detector_name, tuple(fast_axis), tuple(slow_axis), tuple(origin), pixel_size, image_size, trusted_range, thickness_value, material, mu, ) ) # Set the parallax correction for panel in self.model: panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, thickness_value)) panel.set_type("SENSOR_PAD") self._detector_model = self.model
def read(handle, key): from dxtbx.format.nexus import convert_units if key == "miller_index": h = flex.int(handle["h"][:].astype(np.int32)) k = flex.int(handle["k"][:].astype(np.int32)) l = flex.int(handle["l"][:].astype(np.int32)) return flex.miller_index(h, k, l) elif key == "id": return flex.int(handle["id"][:].astype(int)) elif key == "partial_id": return flex.size_t(handle["reflection_id"][:].astype(int)) elif key == "entering": return flex.bool(handle["entering"][:]) elif key == "flags": return flex.size_t(handle["flags"][:].astype(int)) elif key == "panel": return flex.size_t(handle["det_module"][:].astype(int)) elif key == "d": return flex.double(handle["d"][:]) elif key == "partiality": return flex.double(handle["partiality"][:]) elif key == "xyzcal.px": x = flex.double(handle["predicted_px_x"][:]) y = flex.double(handle["predicted_px_y"][:]) z = flex.double(handle["predicted_frame"][:]) return flex.vec3_double(x, y, z) elif key == "xyzcal.mm": x = convert_units( flex.double(handle["predicted_x"][:]), handle["predicted_x"].attrs["units"], "mm", ) y = convert_units( flex.double(handle["predicted_y"][:]), handle["predicted_y"].attrs["units"], "mm", ) z = convert_units( flex.double(handle["predicted_phi"][:]), handle["predicted_phi"].attrs["units"], "rad", ) return flex.vec3_double(x, y, z) elif key == "bbox": b = flex.int(handle["bounding_box"][:].astype(np.int32)) return flex.int6(b.as_1d()) elif key == "xyzobs.px.value": x = flex.double(handle["observed_px_x"][:]) y = flex.double(handle["observed_px_y"][:]) z = flex.double(handle["observed_frame"][:]) return flex.vec3_double(x, y, z) elif key == "xyzobs.px.variance": x = flex.double(handle["observed_px_x_var"][:]) y = flex.double(handle["observed_px_y_var"][:]) z = flex.double(handle["observed_frame_var"][:]) return flex.vec3_double(x, y, z) elif key == "xyzobs.mm.value": x = convert_units( flex.double(handle["observed_x"][:]), handle["observed_x"].attrs["units"], "mm", ) y = convert_units( flex.double(handle["observed_y"][:]), handle["observed_y"].attrs["units"], "mm", ) z = convert_units( flex.double(handle["observed_phi"][:]), handle["observed_phi"].attrs["units"], "rad", ) return flex.vec3_double(x, y, z) elif key == "xyzobs.mm.variance": x = convert_units( flex.double(handle["observed_x_var"][:]), handle["observed_x_var"].attrs["units"], "mm", ) y = convert_units( flex.double(handle["observed_y_var"][:]), handle["observed_y_var"].attrs["units"], "mm", ) z = convert_units( flex.double(handle["observed_phi_var"][:]), handle["observed_phi_var"].attrs["units"], "rad", ) return flex.vec3_double(x, y, z) elif key == "background.mean": return flex.double(handle["background_mean"][:]) elif key == "intensity.sum.value": return flex.double(handle["int_sum"][:]) elif key == "intensity.sum.variance": return flex.double(handle["int_sum_var"][:]) elif key == "intensity.prf.value": return flex.double(handle["int_prf"][:]) elif key == "intensity.prf.variance": return flex.double(handle["int_prf_var"][:]) elif key == "profile.correlation": return flex.double(handle["prf_cc"][:]) elif key == "lp": return flex.double(handle["lp"][:]) elif key == "num_pixels.background": return flex.int(handle["num_bg"][:].astype(np.int32)) elif key == "num_pixels.background_used": return flex.int(handle["num_bg_used"][:].astype(np.int32)) elif key == "num_pixels.foreground": return flex.int(handle["num_fg"][:].astype(np.int32)) elif key == "num_pixels.valid": return flex.int(handle["num_valid"][:].astype(np.int32)) elif key == "profile.rmsd": return flex.double(handle["prf_rmsd"][:]) else: raise KeyError("Column %s not read from file" % key)
def read(handle, key): from dials.array_family import flex from dxtbx.format.nexus import convert_units import numpy as np if key == 'miller_index': h = flex.int(handle['h'][:].astype(np.int32)) k = flex.int(handle['k'][:].astype(np.int32)) l = flex.int(handle['l'][:].astype(np.int32)) return flex.miller_index(h, k, l) elif key == 'id': return flex.int(handle['id'][:].astype(int)) elif key == 'partial_id': return flex.size_t(handle['reflection_id'][:].astype(int)) elif key == 'entering': return flex.bool(handle['entering'][:]) elif key == 'flags': return flex.size_t(handle['flags'][:].astype(int)) elif key == 'panel': return flex.size_t(handle['det_module'][:].astype(int)) elif key == 'd': return flex.double(handle['d'][:]) elif key == 'partiality': return flex.double(handle['partiality'][:]) elif key == 'xyzcal.px': x = flex.double(handle['predicted_px_x'][:]) y = flex.double(handle['predicted_px_y'][:]) z = flex.double(handle['predicted_frame'][:]) return flex.vec3_double(x, y, z) elif key == 'xyzcal.mm': x = convert_units(flex.double(handle['predicted_x'][:]), handle['predicted_x'].attrs['units'], 'mm') y = convert_units(flex.double(handle['predicted_y'][:]), handle['predicted_y'].attrs['units'], 'mm') z = convert_units(flex.double(handle['predicted_phi'][:]), handle['predicted_phi'].attrs['units'], 'rad') return flex.vec3_double(x, y, z) elif key == 'bbox': b = flex.int(handle['bounding_box'][:].astype(np.int32)) return flex.int6(b.as_1d()) elif key == 'xyzobs.px.value': x = flex.double(handle['observed_px_x'][:]) y = flex.double(handle['observed_px_y'][:]) z = flex.double(handle['observed_frame'][:]) return flex.vec3_double(x, y, z) elif key == 'xyzobs.px.variance': x = flex.double(handle['observed_px_x_var'][:]) y = flex.double(handle['observed_px_y_var'][:]) z = flex.double(handle['observed_frame_var'][:]) return flex.vec3_double(x, y, z) elif key == 'xyzobs.mm.value': x = convert_units(flex.double(handle['observed_x'][:]), handle['observed_x'].attrs['units'], 'mm') y = convert_units(flex.double(handle['observed_y'][:]), handle['observed_y'].attrs['units'], 'mm') z = convert_units(flex.double(handle['observed_phi'][:]), handle['observed_phi'].attrs['units'], 'rad') return flex.vec3_double(x, y, z) elif key == 'xyzobs.mm.variance': x = convert_units(flex.double(handle['observed_x_var'][:]), handle['observed_x_var'].attrs['units'], 'mm') y = convert_units(flex.double(handle['observed_y_var'][:]), handle['observed_y_var'].attrs['units'], 'mm') z = convert_units(flex.double(handle['observed_phi_var'][:]), handle['observed_phi_var'].attrs['units'], 'rad') return flex.vec3_double(x, y, z) elif key == 'background.mean': return flex.double(handle['background_mean'][:]) elif key == 'intensity.sum.value': return flex.double(handle['int_sum'][:]) elif key == 'intensity.sum.variance': return flex.double(handle['int_sum_var'][:]) elif key == 'intensity.prf.value': return flex.double(handle['int_prf'][:]) elif key == 'intensity.prf.variance': return flex.double(handle['int_prf_var'][:]) elif key == 'profile.correlation': return flex.double(handle['prf_cc'][:]) elif key == 'lp': return flex.double(handle['lp'][:]) elif key == 'num_pixels.background': return flex.int(handle['num_bg'][:].astype(np.int32)) elif key == 'num_pixels.background_used': return flex.int(handle['num_bg_used'][:].astype(np.int32)) elif key == 'num_pixels.foreground': return flex.int(handle['num_fg'][:].astype(np.int32)) elif key == 'num_pixels.valid': return flex.int(handle['num_valid'][:].astype(np.int32)) elif key == 'profile.rmsd': return flex.double(handle['prf_rmsd'][:]) else: raise KeyError('Column %s not read from file' % key)