def failover_dxtbx(image_file): '''Failover to use the dxtbx to read the image headers...''' # replacement dxtbx for rigaku saturns sometimes from dxtbx.format.Registry import Registry from dxtbx.model.detector_helpers_types import detector_helpers_types global last_format if last_format: iformat = last_format else: iformat = Registry.find(image_file) from xia2.Handlers.Streams import Debug Debug.write('Using dxtbx format instance: %s' % iformat.__name__) if not iformat.understand(image_file): raise RuntimeError('image file %s not understood by dxtbx' % \ image_file) last_format = iformat i = iformat(image_file) b = i.get_beam() g = i.get_goniometer() d = i.get_detector() s = i.get_scan() header = {} if not hasattr(d, 'get_image_size'): # cope with new detector as array of panels dxtbx api fast, slow = map(int, d[0].get_image_size()) _f, _s = d[0].get_pixel_size() F = matrix.col(d[0].get_fast_axis()) S = matrix.col(d[0].get_slow_axis()) N = F.cross(S) origin = matrix.col(d[0].get_origin()) else: fast, slow = map(int, d.get_image_size()) _f, _s = d.get_pixel_size() F = matrix.col(d.get_fast_axis()) S = matrix.col(d.get_slow_axis()) N = F.cross(S) origin = matrix.col(d.get_origin()) beam = matrix.col(b.get_direction()) # FIXME detector has methods to compute the beam centre now... centre = -(origin - origin.dot(N) * N) x = centre.dot(F) y = centre.dot(S) header['fast_direction'] = F.elems header['slow_direction'] = S.elems header['rotation_axis'] = g.get_rotation_axis() if hasattr(s, 'get_exposure_time'): header['exposure_time'] = s.get_exposure_time() else: header['exposure_time'] = s.get_exposure_times()[0] header['distance'] = math.fabs(origin.dot(N)) if math.fabs(beam.angle(N, deg=True) - 180) < 0.1: header['two_theta'] = 180 - beam.angle(N, deg=True) else: header['two_theta'] = -beam.angle(N, deg=True) header['raw_beam'] = x, y header['phi_start'] = s.get_oscillation()[0] header['phi_width'] = s.get_oscillation()[1] header['phi_end'] = sum(s.get_oscillation()) header['pixel'] = _f, _s # FIXME this is very bad as it relates to teh legacy backwards Mosflm # beam centre standard still... FIXME-SCI-948 header['beam'] = y, x header['epoch'] = s.get_image_epoch(s.get_image_range()[0]) header['date'] = time.ctime(header['epoch']) header['wavelength'] = b.get_wavelength() header['size'] = fast, slow if hasattr(i, 'detector_class'): header['detector_class'] = i.detector_class header['detector'] = i.detector else: if hasattr(d, 'get_type'): # cope with new detector as array of panels API dtype = d.get_type() else: dtype = d[0].get_type() detector_type = detector_helpers_types.get(dtype, fast, slow, int(1000 * _f), int(1000 * _s)) header['detector_class'] = detector_type.replace('-', ' ') header['detector'] = detector_type.split('-')[0] return header
def XDS(self): sensor = self.get_detector().get_type() fast, slow = map(int, self.get_detector().get_image_size()) f, s = self.get_detector().get_pixel_size() df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis R = matrix.col( (1.0, 0.0, 0.0)).axis_and_angle_as_r3_rotation_matrix(180.0, deg=True) detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = self.get_detector().get_trusted_range() print("DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d" % (detector, trusted[0] + 1, trusted[1])) if detector == "PILATUS": print("SENSOR_THICKNESS= 0.32") print("DIRECTION_OF_DETECTOR_X-AXIS= %.3f %.3f %.3f" % (R * self.get_detector().get_fast_axis()).elems) print("DIRECTION_OF_DETECTOR_Y-AXIS= %.3f %.3f %.3f" % (R * self.get_detector().get_slow_axis()).elems) print("NX=%d NY=%d QX=%.4f QY=%.4f" % (fast, slow, f, s)) F = R * self.get_detector().get_fast_axis() S = R * self.get_detector().get_slow_axis() N = F.cross(S) origin = R * self.get_detector().get_origin() beam = (R * self.get_beam().get_direction() / math.sqrt(matrix.col(self.get_beam().get_direction()).dot())) centre = -(origin - origin.dot(N) * N) x = centre.dot(F) y = centre.dot(S) print("DETECTOR_DISTANCE= %.3f" % origin.dot(N)) print("ORGX= %.1f ORGY= %.1f" % (x / f, y / s)) print("ROTATION_AXIS= %.3f %.3f %.3f" % (R * self.get_goniometer().get_rotation_axis()).elems) print("STARTING_ANGLE= %.3f" % self.get_scan().get_oscillation()[0]) print("OSCILLATION_RANGE= %.3f" % self.get_scan().get_oscillation()[1]) print("X-RAY_WAVELENGTH= %.5f" % self.get_beam().get_wavelength()) print("INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f" % (-beam).elems) print("FRACTION_OF_POLARIZATION= %.3f" % self.get_beam().get_polarization_fraction()) print("POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f" % self.get_beam().get_polarization_normal()) print("NAME_TEMPLATE_OF_DATA_FRAMES= %s" % self._template.replace("#", "?")) print("TRUSTED_REGION= 0.0 1.41") for f0, f1, s0, s1 in self.get_detector().get_mask(): print("UNTRUSTED_RECTANGLE= %d %d %d %d" % (f0, f1 + 1, s0, s1 + 1)) start_end = self.get_scan().get_image_range() if start_end[0] == 0: start_end = (1, start_end[1]) print("DATA_RANGE= %d %d" % start_end) print("JOB=XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT")
def imageset_to_xds( imageset, synchrotron=None, refined_beam_vector=None, refined_rotation_axis=None, refined_distance=None, ): """A function to take an input header dictionary from Diffdump and generate a list of records to start XDS - see Doc/INP.txt.""" # decide if we are at a synchrotron if we don't know already... # that is, the wavelength is around either the Copper or Chromium # K-alpha edge and this is an image plate. beam = imageset.get_beam() from dxtbx.serialize.xds import to_xds, xds_detector_name converter = to_xds(imageset) h5_names = ["h5", "nxs"] if imageset.get_template().split(".")[-1] in h5_names: if not check_xds_ok_with_h5(): raise RuntimeError("HDF5 input with no converter for XDS") detector_class_is_square = { "adsc q4": True, "adsc q4 2x2 binned": True, "adsc q210": True, "adsc q210 2x2 binned": True, "adsc q270": True, "adsc q270 2x2 binned": True, "adsc q315": True, "adsc q315 2x2 binned": True, "adsc HF4M": True, "holton fake 01": True, "unknown electron 57": True, "mar 345": False, "mar 180": False, "mar 240": False, "mar 300 ccd": True, "mar 325 ccd": True, "mar 225 ccd": True, "mar ccd 225 hs": True, "rayonix ccd 165": False, "rayonix ccd 135": False, "rayonix ccd 300": True, "rayonix ccd 325": True, "rayonix ccd 225": True, "rayonix ccd 225 hs": True, "rayonix ccd 300 hs": True, "mar 165 ccd": False, "mar 135 ccd": False, "pilatus 12M": True, "pilatus 6M": True, "pilatus 2M": True, "pilatus 1M": True, "pilatus 200K": True, "pilatus 300K": True, "eiger 4M": True, "eiger 9M": True, "eiger 16M": True, "rigaku saturn 92 2x2 binned": True, "rigaku saturn 944 2x2 binned": True, "rigaku saturn 724 2x2 binned": True, "rigaku saturn 92": True, "rigaku saturn 944": True, "rigaku saturn 724": True, "rigaku saturn a200": True, "raxis IV": True, "NOIR1": True, } sensor = converter.get_detector()[0].get_type() fast, slow = converter.detector_size f, s = converter.pixel_size df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis result = [] from dxtbx.model.detector_helpers_types import detector_helpers_types detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = converter.get_detector()[0].get_trusted_range() # if CCD; undo dxtbx pedestal offset, hard code minimum 1; else use trusted # range verbatim (i.e. for PAD) (later in pipeline sensor is SENSOR_UNKNOWN # so additional test) if sensor == "SENSOR_CCD" or detector == "CCDCHESS": trusted = 1, trusted[1] - trusted[0] # XDS upset if we trust < 0 see #193 if trusted[0] < 0: trusted = 0, trusted[1] result.append("DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d" % (detector, trusted[0], trusted[1])) result.append("DIRECTION_OF_DETECTOR_X-AXIS=%f %f %f" % converter.detector_x_axis) result.append("DIRECTION_OF_DETECTOR_Y-AXIS=%f %f %f" % converter.detector_y_axis) from xia2.Handlers.Phil import PhilIndex params = PhilIndex.get_python_object() if params.xds.trusted_region: result.append("TRUSTED_REGION= %.2f %.2f" % tuple(params.xds.trusted_region)) elif detector_class_is_square[detector_helpers_types.get( sensor, fast, slow, df, ds).replace("-", " ")]: result.append("TRUSTED_REGION=0.0 1.41") else: result.append("TRUSTED_REGION=0.0 0.99") result.append("NX=%d NY=%d QX=%.4f QY=%.4f" % (fast, slow, f, s)) # RAXIS detectors have the distance written negative - why???? # this is ONLY for XDS - SATURN are the same - probably left handed # goniometer rotation on rigaku X-ray sets. if refined_distance: result.append("DETECTOR_DISTANCE=%7.3f" % refined_distance) else: result.append("DETECTOR_DISTANCE=%7.3f" % converter.detector_distance) result.append("OSCILLATION_RANGE=%4.2f" % converter.oscillation_range) result.append("X-RAY_WAVELENGTH=%8.6f" % converter.wavelength) # if user specified reversephi and this was not picked up in the # format class reverse phi: n.b. double-negative warning! if refined_rotation_axis: result.append("ROTATION_AXIS= %f %f %f" % refined_rotation_axis) else: result.append("ROTATION_AXIS= %.3f %.3f %.3f" % converter.rotation_axis) if refined_beam_vector: result.append("INCIDENT_BEAM_DIRECTION=%f %f %f" % refined_beam_vector) else: result.append("INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f" % converter.beam_vector) if hasattr(beam, "get_polarization_fraction"): R = converter.imagecif_to_xds_transformation_matrix result.append("FRACTION_OF_POLARIZATION= %.3f" % beam.get_polarization_fraction()) result.append("POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f" % (R * matrix.col(beam.get_polarization_normal())).elems) # 24/NOV/14 XDS determines the air absorption automatically # based on wavelength. May be useful to override this for in vacuo exps # result.append('AIR=0.001') if detector == "PILATUS": try: thickness = converter.get_detector()[0].get_thickness() if not thickness: thickness = 0.32 Debug.write( "Could not determine sensor thickness. Assuming default PILATUS 0.32mm" ) except e: thickness = 0.32 Debug.write( "Error occured during sensor thickness determination. Assuming default PILATUS 0.32mm" ) result.append("SENSOR_THICKNESS=%f" % thickness) # FIXME: Sensor absorption coefficient calculation probably requires a more general solution # if converter.get_detector()[0].get_material() == 'CdTe': # print "CdTe detector detected. Beam wavelength is %8.6f Angstrom" % converter.wavelength if len(converter.panel_x_axis) > 1: for panel_id in range(len(converter.panel_x_axis)): result.append("") result.append("!") result.append("! SEGMENT %d" % (panel_id + 1)) result.append("!") result.append("SEGMENT= %d %d %d %d" % converter.panel_limits[panel_id]) result.append("DIRECTION_OF_SEGMENT_X-AXIS= %.3f %.3f %.3f" % converter.panel_x_axis[panel_id]) result.append("DIRECTION_OF_SEGMENT_Y-AXIS= %.3f %.3f %.3f" % converter.panel_y_axis[panel_id]) result.append("SEGMENT_DISTANCE= %.3f" % converter.panel_distance[panel_id]) result.append("SEGMENT_ORGX= %.1f SEGMENT_ORGY= %.1f" % converter.panel_origin[panel_id]) result.append("") for f0, s0, f1, s1 in converter.get_detector()[0].get_mask(): result.append("UNTRUSTED_RECTANGLE= %d %d %d %d" % (f0 - 1, f1 + 1, s0 - 1, s1 + 1)) if params.xds.untrusted_ellipse: for untrusted_ellipse in params.xds.untrusted_ellipse: result.append("UNTRUSTED_ELLIPSE= %d %d %d %d" % tuple(untrusted_ellipse)) Debug.write(result[-1]) if params.xds.untrusted_rectangle: for untrusted_rectangle in params.xds.untrusted_rectangle: result.append("UNTRUSTED_RECTANGLE= %d %d %d %d" % tuple(untrusted_rectangle)) Debug.write(result[-1]) return result
def XDS_INP( self, space_group_number=None, real_space_a=None, real_space_b=None, real_space_c=None, job_card="XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT", as_str=None, ): # as_str is deprecated and will be removed in the future result = [] assert [real_space_a, real_space_b, real_space_c].count(None) in (0, 3) sensor = self.get_detector()[0].get_type() fast, slow = self.detector_size f, s = self.pixel_size df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = self.get_detector()[0].get_trusted_range() result.append("DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d" % (detector, trusted[0] + 1, trusted[1])) if detector == "PILATUS": result.append("SENSOR_THICKNESS= %.3f" % self.get_detector()[0].get_thickness()) if self.get_detector()[0].get_material(): from cctbx.eltbx import attenuation_coefficient material = self.get_detector()[0].get_material() table = attenuation_coefficient.get_table(material) mu = table.mu_at_angstrom(self.wavelength) / 10.0 result.append( "!SENSOR_MATERIAL / THICKNESS %s %.3f" % (material, self.get_detector()[0].get_thickness())) result.append("!SILICON= %f" % mu) result.append("DIRECTION_OF_DETECTOR_X-AXIS= %.5f %.5f %.5f" % self.detector_x_axis) result.append("DIRECTION_OF_DETECTOR_Y-AXIS= %.5f %.5f %.5f" % self.detector_y_axis) result.append("NX=%d NY=%d QX=%.4f QY=%.4f" % (fast, slow, f, s)) result.append("DETECTOR_DISTANCE= %.6f" % self.detector_distance) result.append("ORGX= %.2f ORGY= %.2f" % self.detector_origin) result.append("ROTATION_AXIS= %.5f %.5f %.5f" % self.rotation_axis) result.append("STARTING_ANGLE= %.3f" % self.starting_angle) result.append("OSCILLATION_RANGE= %.3f" % self.oscillation_range) result.append("X-RAY_WAVELENGTH= %.5f" % self.wavelength) result.append("INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f" % tuple([b / self.wavelength for b in self.beam_vector])) # FIXME LATER if hasattr(self.get_beam(), "get_polarization_fraction"): result.append("FRACTION_OF_POLARIZATION= %.3f" % self.get_beam().get_polarization_fraction()) result.append("POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f" % self.get_beam().get_polarization_normal()) template = self.get_template() if template.endswith("master.h5"): template = template.replace("master", "??????") result.append("NAME_TEMPLATE_OF_DATA_FRAMES= %s" % template.replace("#", "?")) result.append("TRUSTED_REGION= 0.0 1.41") for f0, s0, f1, s1 in self.get_detector()[0].get_mask(): result.append("UNTRUSTED_RECTANGLE= %d %d %d %d" % (f0, f1 + 1, s0, s1 + 1)) start_end = self.get_scan().get_image_range() if start_end[0] == 0: start_end = (1, start_end[1]) result.append("DATA_RANGE= %d %d" % start_end) result.append("JOB=%s" % job_card) if space_group_number is not None: result.append("SPACE_GROUP_NUMBER= %i" % space_group_number) if [real_space_a, real_space_b, real_space_c].count(None) == 0: R = self.imagecif_to_xds_transformation_matrix unit_cell_a_axis = R * matrix.col(real_space_a) unit_cell_b_axis = R * matrix.col(real_space_b) unit_cell_c_axis = R * matrix.col(real_space_c) result.append("UNIT_CELL_A-AXIS= %.6f %.6f %.6f" % unit_cell_a_axis.elems) result.append("UNIT_CELL_B-AXIS= %.6f %.6f %.6f" % unit_cell_b_axis.elems) result.append("UNIT_CELL_C-AXIS= %.6f %.6f %.6f" % unit_cell_c_axis.elems) if len(self.panel_x_axis) > 1: for panel_id, panel_x_axis in enumerate(self.panel_x_axis): result.append("") result.append("!") result.append("! SEGMENT %d" % (panel_id + 1)) result.append("!") result.append("SEGMENT= %d %d %d %d" % self.panel_limits[panel_id]) result.append("DIRECTION_OF_SEGMENT_X-AXIS= %.5f %.5f %.5f" % panel_x_axis) result.append("DIRECTION_OF_SEGMENT_Y-AXIS= %.5f %.5f %.5f" % self.panel_y_axis[panel_id]) result.append("SEGMENT_DISTANCE= %.3f" % self.panel_distance[panel_id]) result.append("SEGMENT_ORGX= %.2f SEGMENT_ORGY= %.2f" % self.panel_origin[panel_id]) return "\n".join(result)
def failover_dxtbx(image_file): '''Failover to use the dxtbx to read the image headers...''' # replacement dxtbx for rigaku saturns sometimes from dxtbx.format.Registry import Registry from dxtbx.model.detector_helpers_types import detector_helpers_types global last_format if last_format: iformat = last_format else: iformat = Registry.find(image_file) from xia2.Handlers.Streams import Debug Debug.write('Using dxtbx format instance: %s' % iformat.__name__) if not iformat.understand(image_file): raise RuntimeError, 'image file %s not understood by dxtbx' % \ image_file last_format = iformat i = iformat(image_file) b = i.get_beam() g = i.get_goniometer() d = i.get_detector() s = i.get_scan() header = { } if not hasattr(d, 'get_image_size'): # cope with new detector as array of panels dxtbx api fast, slow = map(int, d[0].get_image_size()) _f, _s = d[0].get_pixel_size() F = matrix.col(d[0].get_fast_axis()) S = matrix.col(d[0].get_slow_axis()) N = F.cross(S) origin = matrix.col(d[0].get_origin()) else: fast, slow = map(int, d.get_image_size()) _f, _s = d.get_pixel_size() F = matrix.col(d.get_fast_axis()) S = matrix.col(d.get_slow_axis()) N = F.cross(S) origin = matrix.col(d.get_origin()) beam = matrix.col(b.get_direction()) # FIXME detector has methods to compute the beam centre now... centre = - (origin - origin.dot(N) * N) x = centre.dot(F) y = centre.dot(S) header['fast_direction'] = F.elems header['slow_direction'] = S.elems header['rotation_axis'] = g.get_rotation_axis() if hasattr(s, 'get_exposure_time'): header['exposure_time'] = s.get_exposure_time() else: header['exposure_time'] = s.get_exposure_times()[0] header['distance'] = math.fabs(origin.dot(N)) if math.fabs(beam.angle(N, deg = True) - 180) < 0.1: header['two_theta'] = 180 - beam.angle(N, deg = True) else: header['two_theta'] = - beam.angle(N, deg = True) header['raw_beam'] = x, y header['phi_start'] = s.get_oscillation()[0] header['phi_width'] = s.get_oscillation()[1] header['phi_end'] = sum(s.get_oscillation()) header['pixel'] = _f, _s # FIXME this is very bad as it relates to teh legacy backwards Mosflm # beam centre standard still... FIXME-SCI-948 header['beam'] = y, x header['epoch'] = s.get_image_epoch(s.get_image_range()[0]) header['date'] = time.ctime(header['epoch']) header['wavelength'] = b.get_wavelength() header['size'] = fast, slow if hasattr(i, 'detector_class'): header['detector_class'] = i.detector_class header['detector'] = i.detector else: if hasattr(d, 'get_type'): # cope with new detector as array of panels API dtype = d.get_type() else: dtype = d[0].get_type() detector_type = detector_helpers_types.get( dtype, fast, slow, int(1000 * _f), int(1000 * _s)) header['detector_class'] = detector_type.replace('-', ' ') header['detector'] = detector_type.split('-')[0] return header
def XDS_INP(self, out=None, space_group_number=None, real_space_a=None, real_space_b=None, real_space_c=None, job_card="XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT", as_str=False): if out is None: out = sys.stdout # horrible hack to allow returning result as string; would be nice if the # structure of this was to make the XDS.INP in memory then print it... # see also show() method on things. str_result = [] if as_str: def print(str='', file=None): str_result.append(str) else: from dxtbx import get_print print = get_print() assert [real_space_a, real_space_b, real_space_c].count(None) in (0, 3) sensor = self.get_detector()[0].get_type() fast, slow = self.detector_size f, s = self.pixel_size df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = self.get_detector()[0].get_trusted_range() print('DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' % \ (detector, trusted[0] + 1, trusted[1]), file=out) if detector == 'PILATUS': print('SENSOR_THICKNESS= %.3f' % \ self.get_detector()[0].get_thickness(), file=out) if self.get_detector()[0].get_material(): from cctbx.eltbx import attenuation_coefficient material = self.get_detector()[0].get_material() table = attenuation_coefficient.get_table(material) mu = table.mu_at_angstrom(self.wavelength) / 10.0 print('!SENSOR_MATERIAL / THICKNESS %s %.3f' % \ (material, self.get_detector()[0].get_thickness()), file=out) print('!SILICON= %f' % mu, file=out) print('DIRECTION_OF_DETECTOR_X-AXIS= %.5f %.5f %.5f' % \ self.detector_x_axis, file=out) print('DIRECTION_OF_DETECTOR_Y-AXIS= %.5f %.5f %.5f' % \ self.detector_y_axis, file=out) print('NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s), file=out) print('DETECTOR_DISTANCE= %.6f' % self.detector_distance, file=out) print('ORGX= %.2f ORGY= %.2f' % self.detector_origin, file=out) print('ROTATION_AXIS= %.5f %.5f %.5f' % \ self.rotation_axis, file=out) print('STARTING_ANGLE= %.3f' % \ self.starting_angle, file=out) print('OSCILLATION_RANGE= %.3f' % \ self.oscillation_range, file=out) print('X-RAY_WAVELENGTH= %.5f' % \ self.wavelength, file=out) print('INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % \ tuple([b / self.wavelength for b in self.beam_vector]), file=out) # FIXME LATER if hasattr(self.get_beam(), "get_polarization_fraction"): print('FRACTION_OF_POLARIZATION= %.3f' % \ self.get_beam().get_polarization_fraction(), file=out) print('POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' % \ self.get_beam().get_polarization_normal(), file=out) template = self.get_template() if template.endswith('master.h5'): master_file = template g = glob.glob(template.split('master.h5')[0] + 'data_*[0-9].h5') assert g, 'No associated data files found for %s' % master_file template = template_regex(g[0])[0] template = master_file.split('master.h5')[0] + template.split( 'data_')[-1] print('NAME_TEMPLATE_OF_DATA_FRAMES= %s' % \ template.replace('#', '?'), file=out) print('TRUSTED_REGION= 0.0 1.41', file=out) for f0, s0, f1, s1 in self.get_detector()[0].get_mask(): print('UNTRUSTED_RECTANGLE= %d %d %d %d' % \ (f0, f1 + 1, s0, s1 + 1), file=out) start_end = self.get_scan().get_image_range() if start_end[0] == 0: start_end = (1, start_end[1]) print('DATA_RANGE= %d %d' % start_end, file=out) print('JOB=%s' % job_card, file=out) if space_group_number is not None: print('SPACE_GROUP_NUMBER= %i' % space_group_number, file=out) if [real_space_a, real_space_b, real_space_c].count(None) == 0: R = self.imagecif_to_xds_transformation_matrix unit_cell_a_axis = R * matrix.col(real_space_a) unit_cell_b_axis = R * matrix.col(real_space_b) unit_cell_c_axis = R * matrix.col(real_space_c) print("UNIT_CELL_A-AXIS= %.6f %.6f %.6f" % unit_cell_a_axis.elems, file=out) print("UNIT_CELL_B-AXIS= %.6f %.6f %.6f" % unit_cell_b_axis.elems, file=out) print("UNIT_CELL_C-AXIS= %.6f %.6f %.6f" % unit_cell_c_axis.elems, file=out) if len(self.panel_x_axis) > 1: for panel_id, panel_x_axis in enumerate(self.panel_x_axis): print(file=out) print("!", file=out) print("! SEGMENT %d" % (panel_id + 1), file=out) print("!", file=out) print('SEGMENT= %d %d %d %d' % self.panel_limits[panel_id], file=out) print('DIRECTION_OF_SEGMENT_X-AXIS= %.5f %.5f %.5f' % \ panel_x_axis, file=out) print('DIRECTION_OF_SEGMENT_Y-AXIS= %.5f %.5f %.5f' % \ self.panel_y_axis[panel_id], file=out) print('SEGMENT_DISTANCE= %.3f' % self.panel_distance[panel_id], file=out) print('SEGMENT_ORGX= %.2f SEGMENT_ORGY= %.2f' % self.panel_origin[panel_id], file=out) print(file=out) if as_str: return '\n'.join(str_result)
def XDS(self): sensor = self.get_detector().get_type() fast, slow = map(int, self.get_detector().get_image_size()) f, s = self.get_detector().get_pixel_size() df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis R = matrix.col((1.0, 0.0, 0.0)).axis_and_angle_as_r3_rotation_matrix( 180.0, deg = True) detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = self.get_detector().get_trusted_range() print 'DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' % \ (detector, trusted[0] + 1, trusted[1]) if detector == 'PILATUS': print 'SENSOR_THICKNESS= 0.32' print 'DIRECTION_OF_DETECTOR_X-AXIS= %.3f %.3f %.3f' % \ (R * self.get_detector().get_fast_axis()).elems print 'DIRECTION_OF_DETECTOR_Y-AXIS= %.3f %.3f %.3f' % \ (R * self.get_detector().get_slow_axis()).elems print 'NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s) F = R * self.get_detector().get_fast_axis() S = R * self.get_detector().get_slow_axis() N = F.cross(S) origin = R * self.get_detector().get_origin() beam = R * self.get_beam().get_direction() / \ math.sqrt(matrix.col(self.get_beam().get_direction()).dot()) centre = -(origin - origin.dot(N) * N) x = centre.dot(F) y = centre.dot(S) print 'DETECTOR_DISTANCE= %.3f' % origin.dot(N) print 'ORGX= %.1f ORGY= %.1f' % (x / f, y / s) print 'ROTATION_AXIS= %.3f %.3f %.3f' % \ (R * self.get_goniometer().get_rotation_axis()).elems print 'STARTING_ANGLE= %.3f' % \ self.get_scan().get_oscillation()[0] print 'OSCILLATION_RANGE= %.3f' % \ self.get_scan().get_oscillation()[1] print 'X-RAY_WAVELENGTH= %.5f' % \ self.get_beam().get_wavelength() print 'INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % \ (- beam).elems print 'FRACTION_OF_POLARIZATION= %.3f' % \ self.get_beam().get_polarization_fraction() print 'POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' % \ self.get_beam().get_polarization_normal() print 'NAME_TEMPLATE_OF_DATA_FRAMES= %s' % self._template.replace( '#', '?') print 'TRUSTED_REGION= 0.0 1.41' for f0, f1, s0, s1 in self.get_detector().get_mask(): print 'UNTRUSTED_RECTANGLE= %d %d %d %d' % \ (f0 - 1, f1 + 1, s0 - 1, s1 + 1) start_end = self.get_scan().get_image_range() if start_end[0] == 0: start_end = (1, start_end[1]) print 'DATA_RANGE= %d %d' % start_end print 'JOB=XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT'
def XDS_INP(self, out=None, space_group_number=None, real_space_a=None, real_space_b=None, real_space_c=None, job_card="XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT"): if out is None: out = sys.stdout assert [real_space_a, real_space_b, real_space_c].count(None) in (0,3) sensor = self.get_detector()[0].get_type() fast, slow = self.detector_size f, s = self.pixel_size df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = self.get_detector()[0].get_trusted_range() print >> out, 'DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' % \ (detector, trusted[0] + 1, trusted[1]) if detector == 'PILATUS': print >> out, 'SENSOR_THICKNESS= %.3f' % \ self.get_detector()[0].get_thickness() if self.get_detector()[0].get_material(): from cctbx.eltbx import attenuation_coefficient material = self.get_detector()[0].get_material() table = attenuation_coefficient.get_table(material) mu = table.mu_at_angstrom(self.wavelength) / 10.0 print >> out, '!SENSOR_MATERIAL / THICKNESS %s %.3f' % \ (material, self.get_detector()[0].get_thickness()) print >> out, '!SILICON= %f' % mu print >> out, 'DIRECTION_OF_DETECTOR_X-AXIS= %.3f %.3f %.3f' % \ self.detector_x_axis print >> out, 'DIRECTION_OF_DETECTOR_Y-AXIS= %.3f %.3f %.3f' % \ self.detector_y_axis print >> out, 'NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s) print >> out, 'DETECTOR_DISTANCE= %.3f' % self.detector_distance print >> out, 'ORGX= %.1f ORGY= %.1f' % self.detector_origin print >> out, 'ROTATION_AXIS= %.3f %.3f %.3f' % \ self.rotation_axis print >> out, 'STARTING_ANGLE= %.3f' % \ self.starting_angle print >> out, 'OSCILLATION_RANGE= %.3f' % \ self.oscillation_range print >> out, 'X-RAY_WAVELENGTH= %.5f' % \ self.wavelength print >> out, 'INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % \ self.beam_vector # FIXME LATER if hasattr(self.get_beam(), "get_polarization_fraction"): print >> out, 'FRACTION_OF_POLARIZATION= %.3f' % \ self.get_beam().get_polarization_fraction() print >> out, 'POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' % \ self.get_beam().get_polarization_normal() print >> out, 'NAME_TEMPLATE_OF_DATA_FRAMES= %s' % \ self.get_template().replace('#', '?') print >> out, 'TRUSTED_REGION= 0.0 1.41' for f0, s0, f1, s1 in self.get_detector()[0].get_mask(): print >> out, 'UNTRUSTED_RECTANGLE= %d %d %d %d' % \ (f0 - 1, f1 + 1, s0 - 1, s1 + 1) start_end = self.get_scan().get_image_range() if start_end[0] == 0: start_end = (1, start_end[1]) print >> out, 'DATA_RANGE= %d %d' % start_end print >> out, 'JOB=%s' %job_card if space_group_number is not None: print >> out, 'SPACE_GROUP_NUMBER= %i' %space_group_number if [real_space_a, real_space_b, real_space_c].count(None) == 0: R = self.imagecif_to_xds_transformation_matrix unit_cell_a_axis = R * matrix.col(real_space_a) unit_cell_b_axis = R * matrix.col(real_space_b) unit_cell_c_axis = R * matrix.col(real_space_c) print >> out, "UNIT_CELL_A-AXIS= %.6f %.6f %.6f" %unit_cell_a_axis.elems print >> out, "UNIT_CELL_B-AXIS= %.6f %.6f %.6f" %unit_cell_b_axis.elems print >> out, "UNIT_CELL_C-AXIS= %.6f %.6f %.6f" %unit_cell_c_axis.elems
def XDS_INP( self, out=None, space_group_number=None, real_space_a=None, real_space_b=None, real_space_c=None, job_card="XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT"): if out is None: out = sys.stdout assert [real_space_a, real_space_b, real_space_c].count(None) in (0, 3) sensor = self.get_detector()[0].get_type() fast, slow = self.detector_size f, s = self.pixel_size df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = self.get_detector()[0].get_trusted_range() print >> out, 'DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' % \ (detector, trusted[0] + 1, trusted[1]) if detector == 'PILATUS': print >> out, 'SENSOR_THICKNESS= %.3f' % \ self.get_detector()[0].get_thickness() if self.get_detector()[0].get_material(): from cctbx.eltbx import attenuation_coefficient material = self.get_detector()[0].get_material() table = attenuation_coefficient.get_table(material) mu = table.mu_at_angstrom(self.wavelength) / 10.0 print >> out, '!SENSOR_MATERIAL / THICKNESS %s %.3f' % \ (material, self.get_detector()[0].get_thickness()) print >> out, '!SILICON= %f' % mu print >> out, 'DIRECTION_OF_DETECTOR_X-AXIS= %.5f %.5f %.5f' % \ self.detector_x_axis print >> out, 'DIRECTION_OF_DETECTOR_Y-AXIS= %.5f %.5f %.5f' % \ self.detector_y_axis print >> out, 'NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s) print >> out, 'DETECTOR_DISTANCE= %.6f' % self.detector_distance print >> out, 'ORGX= %.2f ORGY= %.2f' % self.detector_origin print >> out, 'ROTATION_AXIS= %.5f %.5f %.5f' % \ self.rotation_axis print >> out, 'STARTING_ANGLE= %.3f' % \ self.starting_angle print >> out, 'OSCILLATION_RANGE= %.3f' % \ self.oscillation_range print >> out, 'X-RAY_WAVELENGTH= %.5f' % \ self.wavelength print >> out, 'INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % \ tuple([b / self.wavelength for b in self.beam_vector]) # FIXME LATER if hasattr(self.get_beam(), "get_polarization_fraction"): print >> out, 'FRACTION_OF_POLARIZATION= %.3f' % \ self.get_beam().get_polarization_fraction() print >> out, 'POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' % \ self.get_beam().get_polarization_normal() print >> out, 'NAME_TEMPLATE_OF_DATA_FRAMES= %s' % \ self.get_template().replace('#', '?') print >> out, 'TRUSTED_REGION= 0.0 1.41' for f0, s0, f1, s1 in self.get_detector()[0].get_mask(): print >> out, 'UNTRUSTED_RECTANGLE= %d %d %d %d' % \ (f0 - 1, f1 + 1, s0 - 1, s1 + 1) start_end = self.get_scan().get_image_range() if start_end[0] == 0: start_end = (1, start_end[1]) print >> out, 'DATA_RANGE= %d %d' % start_end print >> out, 'JOB=%s' % job_card if space_group_number is not None: print >> out, 'SPACE_GROUP_NUMBER= %i' % space_group_number if [real_space_a, real_space_b, real_space_c].count(None) == 0: R = self.imagecif_to_xds_transformation_matrix unit_cell_a_axis = R * matrix.col(real_space_a) unit_cell_b_axis = R * matrix.col(real_space_b) unit_cell_c_axis = R * matrix.col(real_space_c) print >> out, "UNIT_CELL_A-AXIS= %.6f %.6f %.6f" % unit_cell_a_axis.elems print >> out, "UNIT_CELL_B-AXIS= %.6f %.6f %.6f" % unit_cell_b_axis.elems print >> out, "UNIT_CELL_C-AXIS= %.6f %.6f %.6f" % unit_cell_c_axis.elems if len(self.panel_x_axis) > 1: for panel_id, panel_x_axis in enumerate(self.panel_x_axis): print >> out print >> out, "!" print >> out, "! SEGMENT %d" % (panel_id + 1) print >> out, "!" print >> out, 'SEGMENT= %d %d %d %d' % self.panel_limits[ panel_id] print >> out, 'DIRECTION_OF_SEGMENT_X-AXIS= %.5f %.5f %.5f' % \ panel_x_axis print >> out, 'DIRECTION_OF_SEGMENT_Y-AXIS= %.5f %.5f %.5f' % \ self.panel_y_axis[panel_id] print >> out, 'SEGMENT_DISTANCE= %.3f' % self.panel_distance[ panel_id] print >> out, 'SEGMENT_ORGX= %.2f SEGMENT_ORGY= %.2f' % self.panel_origin[ panel_id] print >> out
def imageset_to_xds(imageset, synchrotron = None, refined_beam_vector = None, refined_rotation_axis = None, refined_distance = None): '''A function to take an input header dictionary from Diffdump and generate a list of records to start XDS - see Doc/INP.txt.''' # decide if we are at a synchrotron if we don't know already... # that is, the wavelength is around either the Copper or Chromium # K-alpha edge and this is an image plate. beam = imageset.get_beam() from dxtbx.serialize.xds import to_xds, xds_detector_name converter = to_xds(imageset) detector_class_is_square = { 'adsc q4':True, 'adsc q4 2x2 binned':True, 'adsc q210':True, 'adsc q210 2x2 binned':True, 'adsc q270':True, 'adsc q270 2x2 binned':True, 'adsc q315':True, 'adsc q315 2x2 binned':True, 'adsc HF4M':True, 'holton fake 01':True, 'mar 345':False, 'mar 180':False, 'mar 240':False, 'mar 300 ccd':True, 'mar 325 ccd':True, 'mar 225 ccd':True, 'mar ccd 225 hs':True, 'rayonix ccd 165':False, 'rayonix ccd 135':False, 'rayonix ccd 300':True, 'rayonix ccd 325':True, 'rayonix ccd 225':True, 'rayonix ccd 225 hs':True, 'rayonix ccd 300 hs':True, 'mar 165 ccd':False, 'mar 135 ccd':False, 'pilatus 12M':True, 'pilatus 6M':True, 'pilatus 2M':True, 'pilatus 1M':True, 'pilatus 200K':True, 'pilatus 300K':True, 'eiger 4M':True, 'eiger 9M':True, 'eiger 16M':True, 'rigaku saturn 92 2x2 binned':True, 'rigaku saturn 944 2x2 binned':True, 'rigaku saturn 724 2x2 binned':True, 'rigaku saturn 92':True, 'rigaku saturn 944':True, 'rigaku saturn 724':True, 'rigaku saturn a200':True, 'raxis IV':True, 'NOIR1':True} sensor = converter.get_detector()[0].get_type() fast, slow = converter.detector_size f, s = converter.pixel_size df = int(1000 * f) ds = int(1000 * s) # FIXME probably need to rotate by pi about the X axis result = [] from dxtbx.model.detector_helpers_types import detector_helpers_types detector = xds_detector_name( detector_helpers_types.get(sensor, fast, slow, df, ds)) trusted = converter.get_detector()[0].get_trusted_range() # FIXME what follows below should perhaps be 0 for the really weak # pilatus data sets? result.append('DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' % (detector, trusted[0] + 1, trusted[1])) result.append('DIRECTION_OF_DETECTOR_X-AXIS=%f %f %f' % converter.detector_x_axis) result.append('DIRECTION_OF_DETECTOR_Y-AXIS=%f %f %f' % converter.detector_y_axis) from xia2.Handlers.Phil import PhilIndex params = PhilIndex.get_python_object() if params.xds.trusted_region: result.append( 'TRUSTED_REGION= %.2f %.2f' % tuple(params.xds.trusted_region)) elif detector_class_is_square[ detector_helpers_types.get(sensor, fast, slow, df, ds).replace('-', ' ')]: result.append('TRUSTED_REGION=0.0 1.41') else: result.append('TRUSTED_REGION=0.0 0.99') result.append('NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s)) # RAXIS detectors have the distance written negative - why???? # this is ONLY for XDS - SATURN are the same - probably left handed # goniometer rotation on rigaku X-ray sets. if refined_distance: result.append('DETECTOR_DISTANCE=%7.3f' % refined_distance) else: result.append('DETECTOR_DISTANCE=%7.3f' % converter.detector_distance) result.append('OSCILLATION_RANGE=%4.2f' % converter.oscillation_range) result.append('X-RAY_WAVELENGTH=%8.6f' % converter.wavelength) # if user specified reversephi and this was not picked up in the # format class reverse phi: n.b. double-negative warning! if refined_rotation_axis: result.append('ROTATION_AXIS= %f %f %f' % \ refined_rotation_axis) else: result.append('ROTATION_AXIS= %.3f %.3f %.3f' % \ converter.rotation_axis) if refined_beam_vector: result.append('INCIDENT_BEAM_DIRECTION=%f %f %f' % \ refined_beam_vector) else: result.append( 'INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % converter.beam_vector) if hasattr(beam, "get_polarization_fraction"): R = converter.imagecif_to_xds_transformation_matrix result.append('FRACTION_OF_POLARIZATION= %.3f' % beam.get_polarization_fraction()) result.append('POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' % (R * matrix.col(beam.get_polarization_normal())).elems) # 24/NOV/14 XDS determines the air absorption automatically # based on wavelength. May be useful to override this for in vacuo exps # result.append('AIR=0.001') if detector == 'PILATUS': try: thickness = converter.get_detector()[0].get_thickness() if not thickness: thickness = 0.32 Debug.write('Could not determine sensor thickness. Assuming default PILATUS 0.32mm') except e: thickness = 0.32 Debug.write('Error occured during sensor thickness determination. Assuming default PILATUS 0.32mm') result.append('SENSOR_THICKNESS=%f' % thickness) # # FIXME: Sensor absorption coefficient calculation probably requires a more general solution # if converter.get_detector()[0].get_material() == 'CdTe': # print "CdTe detector detected. Beam wavelength is %8.6f Angstrom" % converter.wavelength if len(converter.panel_x_axis) > 1: for panel_id in range(len(converter.panel_x_axis)): result.append('') result.append('!') result.append('! SEGMENT %d' %(panel_id+1)) result.append('!') result.append('SEGMENT= %d %d %d %d' % converter.panel_limits[panel_id]) result.append('DIRECTION_OF_SEGMENT_X-AXIS= %.3f %.3f %.3f' % \ converter.panel_x_axis[panel_id]) result.append('DIRECTION_OF_SEGMENT_Y-AXIS= %.3f %.3f %.3f' % \ converter.panel_y_axis[panel_id]) result.append('SEGMENT_DISTANCE= %.3f' % converter.panel_distance[panel_id]) result.append( 'SEGMENT_ORGX= %.1f SEGMENT_ORGY= %.1f' % converter.panel_origin[panel_id]) result.append('') for f0, s0, f1, s1 in converter.get_detector()[0].get_mask(): result.append('UNTRUSTED_RECTANGLE= %d %d %d %d' % (f0 - 1, f1 + 1, s0 - 1, s1 + 1)) if params.xds.untrusted_ellipse: for untrusted_ellipse in params.xds.untrusted_ellipse: result.append( 'UNTRUSTED_ELLIPSE= %d %d %d %d' % tuple(untrusted_ellipse)) Debug.write(result[-1]) if params.xds.untrusted_rectangle: for untrusted_rectangle in params.xds.untrusted_rectangle: result.append( 'UNTRUSTED_RECTANGLE= %d %d %d %d' % tuple(untrusted_rectangle)) Debug.write(result[-1]) return result