def to_crystal(filename): ''' Get the crystal model from the xparm file Params: filename The xparm/or integrate filename Return: The crystal model ''' from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from dxtbx.model.crystal import crystal_model from cctbx.sgtbx import space_group, space_group_symbols # Get the real space coordinate frame cfc = coordinate_frame_converter(filename) real_space_a = cfc.get('real_space_a') real_space_b = cfc.get('real_space_b') real_space_c = cfc.get('real_space_c') sg = cfc.get('space_group_number') space_group = space_group(space_group_symbols(sg).hall()) mosaicity = cfc.get('mosaicity') # Return the crystal model return crystal_model(real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group=space_group, mosaicity=mosaicity)
def to_crystal(filename): ''' Get the crystal model from the xparm file Params: filename The xparm/or integrate filename Return: The crystal model ''' from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from dxtbx.model.crystal import crystal_model from cctbx.sgtbx import space_group, space_group_symbols # Get the real space coordinate frame cfc = coordinate_frame_converter(filename) real_space_a = cfc.get('real_space_a') real_space_b = cfc.get('real_space_b') real_space_c = cfc.get('real_space_c') sg = cfc.get('space_group_number') space_group = space_group(space_group_symbols(sg).hall()) mosaicity = cfc.get('mosaicity') # Return the crystal model return crystal_model( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group=space_group, mosaicity=mosaicity)
def _convert_to_cbf_convention(self, xparm_filename): '''Get the parameters from the XPARM file and convert them to CBF conventions. Params: xparm_handle The handle to the xparm file. ''' from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # Create a coordinate frame converter and extract other quantities cfc = coordinate_frame_converter(xparm_filename) self._detector_origin = cfc.get('detector_origin') self._rotation_axis = cfc.get('rotation_axis') self._fast_axis = cfc.get('detector_fast') self._slow_axis = cfc.get('detector_slow') self._wavelength = cfc.get('wavelength') self._image_size = cfc.get('detector_size_fast_slow') self._pixel_size = cfc.get('detector_pixel_size_fast_slow') self._starting_angle = cfc.get('starting_angle') self._oscillation_range = cfc.get('oscillation_range') self._starting_frame = cfc.get('starting_frame') self._divergence = 0.0 self._sigma_divergence = cfc.get('sigma_divergence') sample_vector = cfc.get('sample_to_source') self._beam_vector = tuple(matrix.col(sample_vector))
def test(dials_regression): from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from dials.algorithms.spot_prediction import IndexGenerator import numpy from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # The XDS files to read from integrate_filename = os.path.join(dials_regression, 'data', 'sim_mx', 'INTEGRATE.HKL') gxparm_filename = os.path.join(dials_regression, 'data', 'sim_mx', 'GXPARM.XDS') # Read the XDS files integrate_handle = integrate_hkl.reader() integrate_handle.read_file(integrate_filename) gxparm_handle = xparm.reader() gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file d_min = 1.6 space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') unit_cell = cfc.get_unit_cell() UB = matrix.sqr(a_vec + b_vec + c_vec).inverse() ub_matrix = UB # Generate the indices index_generator = IndexGenerator(unit_cell, space_group_type, d_min) miller_indices = index_generator.to_array() # Get individual generated hkl gen_h = [hkl[0] for hkl in miller_indices] gen_k = [hkl[1] for hkl in miller_indices] gen_l = [hkl[2] for hkl in miller_indices] # Get individual xds generated hkl xds_h = [hkl[0] for hkl in integrate_handle.hkl] xds_k = [hkl[1] for hkl in integrate_handle.hkl] xds_l = [hkl[2] for hkl in integrate_handle.hkl] # Get min/max generated hkl min_gen_h, max_gen_h = numpy.min(gen_h), numpy.max(gen_h) min_gen_k, max_gen_k = numpy.min(gen_k), numpy.max(gen_k) min_gen_l, max_gen_l = numpy.min(gen_l), numpy.max(gen_l) # Get min/max xds generated hkl min_xds_h, max_xds_h = numpy.min(xds_h), numpy.max(xds_h) min_xds_k, max_xds_k = numpy.min(xds_k), numpy.max(xds_k) min_xds_l, max_xds_l = numpy.min(xds_l), numpy.max(xds_l) # Ensure we have the whole xds range in the generated set assert min_gen_h <= min_xds_h and max_gen_h >= max_xds_h assert min_gen_k <= min_xds_k and max_gen_k >= max_xds_k assert min_gen_l <= min_xds_l and max_gen_l >= max_xds_l
def _convert_to_cbf_convention(self, xparm_filename): '''Get the parameters from the XPARM file and convert them to CBF conventions. Params: xparm_handle The handle to the xparm file. ''' from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # Create a coordinate frame converter and extract other quantities cfc = coordinate_frame_converter(xparm_filename) self._detector_origin = cfc.get('detector_origin') self._rotation_axis = cfc.get('rotation_axis') self._fast_axis = cfc.get('detector_fast') self._slow_axis = cfc.get('detector_slow') self._wavelength = cfc.get('wavelength') self._image_size = cfc.get('detector_size_fast_slow') self._pixel_size = cfc.get('detector_pixel_size_fast_slow') self._starting_angle = cfc.get('starting_angle') self._oscillation_range = cfc.get('oscillation_range') self._starting_frame = cfc.get('starting_frame') self._data_range = cfc.get('data_range') self._divergence = 0.0 self._sigma_divergence = cfc.get('sigma_divergence') sample_vector = cfc.get('sample_to_source') self._beam_vector = tuple(matrix.col(sample_vector)) self._panel_offset = cfc.get('panel_offset') self._panel_size = cfc.get('panel_size') self._panel_origin = cfc.get('panel_origin') self._panel_fast = cfc.get('panel_fast') self._panel_slow = cfc.get('panel_slow')
def _convert_to_cbf_convention(self, xparm_filename): """Get the parameters from the XPARM file and convert them to CBF conventions. Params: xparm_handle The handle to the xparm file. """ # Create a coordinate frame converter and extract other quantities cfc = coordinate_frame_converter(xparm_filename) self._detector_origin = cfc.get("detector_origin") self._rotation_axis = cfc.get("rotation_axis") self._fast_axis = cfc.get("detector_fast") self._slow_axis = cfc.get("detector_slow") self._wavelength = cfc.get("wavelength") self._image_size = cfc.get("detector_size_fast_slow") self._pixel_size = cfc.get("detector_pixel_size_fast_slow") self._starting_angle = cfc.get("starting_angle") self._oscillation_range = cfc.get("oscillation_range") self._starting_frame = cfc.get("starting_frame") self._data_range = cfc.get("data_range") self._divergence = 0.0 self._sigma_divergence = cfc.get("sigma_divergence") sample_vector = cfc.get("sample_to_source") self._beam_vector = tuple(matrix.col(sample_vector)) self._panel_offset = cfc.get("panel_offset") self._panel_size = cfc.get("panel_size") self._panel_origin = cfc.get("panel_origin") self._panel_fast = cfc.get("panel_fast") self._panel_slow = cfc.get("panel_slow")
def test(dials_regression): import numpy as np from iotbx.xds import integrate_hkl, xparm from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from dials.algorithms.spot_prediction import IndexGenerator from dials.util import ioutil # The XDS files to read from integrate_filename = os.path.join(dials_regression, "data", "sim_mx", "INTEGRATE.HKL") gxparm_filename = os.path.join(dials_regression, "data", "sim_mx", "GXPARM.XDS") # Read the XDS files integrate_handle = integrate_hkl.reader() integrate_handle.read_file(integrate_filename) gxparm_handle = xparm.reader() gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file d_min = 1.6 space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) unit_cell = cfc.get_unit_cell() # Generate the indices index_generator = IndexGenerator(unit_cell, space_group_type, d_min) miller_indices = index_generator.to_array() # Get individual generated hkl gen_h = [hkl[0] for hkl in miller_indices] gen_k = [hkl[1] for hkl in miller_indices] gen_l = [hkl[2] for hkl in miller_indices] # Get individual xds generated hkl xds_h = [hkl[0] for hkl in integrate_handle.hkl] xds_k = [hkl[1] for hkl in integrate_handle.hkl] xds_l = [hkl[2] for hkl in integrate_handle.hkl] # Get min/max generated hkl min_gen_h, max_gen_h = np.min(gen_h), np.max(gen_h) min_gen_k, max_gen_k = np.min(gen_k), np.max(gen_k) min_gen_l, max_gen_l = np.min(gen_l), np.max(gen_l) # Get min/max xds generated hkl min_xds_h, max_xds_h = np.min(xds_h), np.max(xds_h) min_xds_k, max_xds_k = np.min(xds_k), np.max(xds_k) min_xds_l, max_xds_l = np.min(xds_l), np.max(xds_l) # Ensure we have the whole xds range in the generated set assert min_gen_h <= min_xds_h and max_gen_h >= max_xds_h assert min_gen_k <= min_xds_k and max_gen_k >= max_xds_k assert min_gen_l <= min_xds_l and max_gen_l >= max_xds_l
def import_xds_integrate_hkl(xds_integrate_hkl_file, phi_range): from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter cfc = coordinate_frame_converter(xds_integrate_hkl_file) px, py = cfc.get('detector_pixel_size_fast_slow') # read header, get out phi0, frame0, dphi, so can transform frame# to # phi value phi0 = None dphi = None frame0 = None for record in open(xds_integrate_hkl_file): if not record.startswith('!'): break if record.startswith('!STARTING_FRAME'): frame0 = int(record.split()[-1]) continue if record.startswith('!STARTING_ANGLE'): phi0 = float(record.split()[-1]) continue if record.startswith('!OSCILLATION_RANGE'): dphi = float(record.split()[-1]) continue assert(not dphi is None) assert(not phi0 is None) assert(not frame0 is None) xyz_to_hkl = { } for record in open(xds_integrate_hkl_file): if record.startswith('!'): continue values = record.split() hkl = map(int, values[:3]) xyz = map(float, values[5:8]) xyz_mod = (xyz[0] * px, xyz[1] * py, (xyz[2] - frame0) * dphi + phi0) if xyz_mod[2] < phi_range[0]: continue if xyz_mod[2] > phi_range[1]: continue xyz_to_hkl[xyz_mod] = hkl return xyz_to_hkl
def tst_coordinate_frame_converter(): import libtbx.load_env rstbx = libtbx.env.dist_path('rstbx') from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter import os cfc = coordinate_frame_converter( os.path.join(rstbx, 'cftbx', 'tests', 'example-xparm.xds')) from scitbx import matrix x = matrix.col((1, 0, 0)) assert (cfc.move_c(x, convention=cfc.CBF).angle(cfc.get_c('detector_fast')) < 0.1) print 'OK'
def tst_coordinate_frame_converter(): import libtbx.load_env rstbx = libtbx.env.dist_path('rstbx') from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter import os cfc = coordinate_frame_converter(os.path.join(rstbx, 'cftbx', 'tests', 'example-xparm.xds')) from scitbx import matrix x = matrix.col((1, 0, 0)) assert(cfc.move_c(x, convention = cfc.CBF).angle( cfc.get_c('detector_fast')) < 0.1) print 'OK'
def main(args): from scitbx import matrix prefix = os.path.commonprefix(args) from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter cfc = coordinate_frame_converter(find_xparm(args[0])) for j in range(len(args) - 1): print '%s => %s' % (args[j].replace(prefix, ''), args[j + 1].replace(prefix, '')) axis, angle, R = derive_axis_angle(args[j], args[j + 1]) print 'Axis:' print '%6.3f %6.3f %6.3f' % cfc.move(axis, convention = cfc.MOSFLM) print 'Angle:' print '%6.3f' % angle
def to_crystal(filename): """Get the crystal model from the xparm file Params: filename The xparm/or integrate filename Return: The crystal model """ from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from cctbx.sgtbx import space_group, space_group_symbols # Get the real space coordinate frame cfc = coordinate_frame_converter(filename) real_space_a = cfc.get("real_space_a") real_space_b = cfc.get("real_space_b") real_space_c = cfc.get("real_space_c") sg = cfc.get("space_group_number") space_group = space_group(space_group_symbols(sg).hall()) mosaicity = cfc.get("mosaicity") # Return the crystal model if mosaicity is None: from dxtbx.model import Crystal crystal = Crystal( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group=space_group, ) else: from dxtbx.model import MosaicCrystalKabsch2010 crystal = MosaicCrystalKabsch2010( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group=space_group, ) crystal.set_mosaicity(mosaicity) return crystal
def regenerate_predictions_brute(xds_integrate_hkl_file, phi_range): from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from rstbx.diffraction import rotation_angles from rstbx.diffraction import full_sphere_indices from cctbx.sgtbx import space_group, space_group_symbols from cctbx.uctbx import unit_cell import math cfc = coordinate_frame_converter(xds_integrate_hkl_file) d2r = math.pi / 180.0 dmin = cfc.derive_detector_highest_resolution() A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) uc = unit_cell(cell) sg = cfc.get('space_group_number') indices = full_sphere_indices( unit_cell = uc, resolution_limit = dmin, space_group = space_group(space_group_symbols(sg).hall())) u, b = cfc.get_u_b(convention = cfc.ROSSMANN) axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN) ub = u * b wavelength = cfc.get('wavelength') ra = rotation_angles(dmin, ub, wavelength, axis) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad = phi_range[0] * d2r, phi_end_rad = phi_range[1] * d2r, indices = indices) # in here work in internal (i.e. not Rossmann) coordinate frame u, b = cfc.get_u_b() axis = cfc.get_c('rotation_axis') sample_to_source_vec = cfc.get_c('sample_to_source').normalize() s0 = (- 1.0 / wavelength) * sample_to_source_vec ub = u * b detector_origin = cfc.get_c('detector_origin') detector_fast = cfc.get_c('detector_fast') detector_slow = cfc.get_c('detector_slow') detector_normal = detector_fast.cross(detector_slow) distance = detector_origin.dot(detector_normal.normalize()) nx, ny = cfc.get('detector_size_fast_slow') px, py = cfc.get('detector_pixel_size_fast_slow') limits = [0, nx * px, 0, ny * py] xyz_to_hkl = { } for hkl, angle in zip(obs_indices, obs_angles): s = (ub * hkl).rotate(axis, angle) q = (s + s0).normalize() # check if diffracted ray parallel to detector face q_dot_n = q.dot(detector_normal) if q_dot_n == 0: continue r = (q * distance / q_dot_n) - detector_origin x = r.dot(detector_fast) y = r.dot(detector_slow) if x < limits[0] or y < limits[2]: continue if x > limits[1] or y > limits[3]: continue xyz = (x, y, angle / d2r) xyz_to_hkl[xyz] = map(int, hkl) return xyz_to_hkl
def read_spot_xds_apply_corrections( spot_xds, x_crns_file, y_crns_file, xparm_file): '''Read X corrections and Y corrections to arrays; for record in int_hkl read x, y positions and compute r.m.s. deviations between observed and calculated centroids with and without the corrections. N.B. will only compute offsets for reflections with I/sigma > 10.''' from scitbx import matrix import math x_corrections = open_file_return_array(x_crns_file) y_corrections = open_file_return_array(y_crns_file) sumxx_orig = 0.0 n_obs = 0 sumxx_corr = 0.0 # FIXME find code to run prediction of reflection lists... img_start, osc_start, osc_range = parse_xds_xparm_scan_info(xparm_file) from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter cfc = coordinate_frame_converter(xparm_file) fast = cfc.get_c('detector_fast') slow = cfc.get_c('detector_slow') normal = fast.cross(slow) origin = cfc.get_c('detector_origin') distance = origin.dot(normal) A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) u, b = cfc.get_u_b() ub = u * b s0 = - cfc.get_c('sample_to_source') / cfc.get('wavelength') axis = cfc.get_c('rotation_axis') xcal = [] xobs = [] xcor = [] ycal = [] yobs = [] ycor = [] for record in open(spot_xds): values = map(float, record.split()) hkl = map(int, map(round, values[-3:])) if hkl[0] == 0 and hkl[1] == 0 and hkl[2] == 0: continue xc, yc, zc = values[:3] angle = (zc - img_start + 1) * osc_range + osc_start d2r = math.pi / 180.0 s = (ub * hkl).rotate(axis, angle * d2r) + s0 s = s.normalize() r = s * distance / s.dot(normal) - origin xc = r.dot(fast) / 0.172 yc = r.dot(slow) / 0.172 xo, yo, zo = values[:3] xc_orig = matrix.col((xc, yc)) xo_orig = matrix.col((xo, yo)) n_obs += 1 sumxx_orig += (xo_orig - xc_orig).dot() # get the correcions for this pixel... N.B. 1 + ... lost due to C-style # rather than Fortran-style arrays ix4 = int(round((xc - 2) / 4)) iy4 = int(round((yc - 2) / 4)) # hmm.... Fortran multi-dimensional array ordering... identified by # bounds error other way around... dx = 0.1 * x_corrections[iy4, ix4] dy = 0.1 * y_corrections[iy4, ix4] xc_corr = matrix.col((xc + dx, yc + dy)) sumxx_corr += (xo_orig - xc_corr).dot() print n_obs return math.sqrt(sumxx_orig / n_obs), math.sqrt(sumxx_corr / n_obs)
def regenerate_predictions_reeke(xds_integrate_hkl_file, phi_range): from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from rstbx.diffraction import rotation_angles from cctbx.sgtbx import space_group, space_group_symbols from cctbx.uctbx import unit_cell import math from dials.algorithms.refinement.prediction.reeke import reeke_model from cctbx.array_family import flex cfc = coordinate_frame_converter(xds_integrate_hkl_file) d2r = math.pi / 180.0 dmin = cfc.derive_detector_highest_resolution() A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) uc = unit_cell(cell) sg = cfc.get('space_group_number') u, b = cfc.get_u_b() axis = cfc.get_c('rotation_axis') sample_to_source_vec = cfc.get_c('sample_to_source').normalize() wavelength = cfc.get('wavelength') s0 = (- 1.0 / wavelength) * sample_to_source_vec ub = u * b rm = reeke_model(ub, axis, s0, dmin, phi_range[0], phi_range[1], 3) reeke_indices = rm.generate_indices() # the following are in Rossmann coordinate frame to fit in with # Labelit code... ur, br = cfc.get_u_b(convention = cfc.ROSSMANN) axisr = cfc.get('rotation_axis', convention = cfc.ROSSMANN) ubr = ur * br ra = rotation_angles(dmin, ubr, wavelength, axisr) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad = phi_range[0] * d2r, phi_end_rad = phi_range[1] * d2r, indices = reeke_indices) detector_origin = cfc.get_c('detector_origin') detector_fast = cfc.get_c('detector_fast') detector_slow = cfc.get_c('detector_slow') detector_normal = detector_fast.cross(detector_slow) distance = detector_origin.dot(detector_normal.normalize()) nx, ny = cfc.get('detector_size_fast_slow') px, py = cfc.get('detector_pixel_size_fast_slow') limits = [0, nx * px, 0, ny * py] xyz_to_hkl = { } for hkl, angle in zip(obs_indices, obs_angles): s = (ub * hkl).rotate(axis, angle) q = (s + s0).normalize() # check if diffracted ray parallel to detector face q_dot_n = q.dot(detector_normal) if q_dot_n == 0: continue r = (q * distance / q_dot_n) - detector_origin x = r.dot(detector_fast) y = r.dot(detector_slow) if x < limits[0] or y < limits[2]: continue if x > limits[1] or y > limits[3]: continue xyz = (x, y, angle / d2r) xyz_to_hkl[xyz] = map(int, hkl) return xyz_to_hkl
def ersatz_misset_predict(xparm_xds, spot_xds): '''As well as possible, try to predict the misorientation angles as a function of frame # from the indexed spots from the XDS IDXREF step. Calculation will be performed in CBF coordinae frame.''' cfc = coordinate_frame_converter(xparm_xds) axis = cfc.get_c('rotation_axis') wavelength = cfc.get('wavelength') beam = (1.0 / wavelength) * cfc.get_c('sample_to_source').normalize() U, B = cfc.get_u_b() UB = U * B detector_origin = cfc.get_c('detector_origin') detector_fast = cfc.get_c('detector_fast') detector_slow = cfc.get_c('detector_slow') pixel_size_fast, pixel_size_slow = cfc.get('detector_pixel_size_fast_slow') size_fast, size_slow = cfc.get('detector_size_fast_slow') img_start, osc_start, osc_range = parse_xds_xparm_scan_info(xparm_xds) rx_s = {} ry_s = {} rz_s = {} for record in open(spot_xds): values = map(float, record.split()) if len(values) != 7: continue hkl = tuple(map(nint, values[-3:])) if hkl == (0, 0, 0): continue x, y, f = values[:3] phi = ((f - img_start + 1) * osc_range + osc_start) * math.pi / 180.0 lab_xyz = detector_origin + \ detector_fast * x * pixel_size_fast + \ detector_slow * y * pixel_size_slow rec_xyz = ((1.0 / wavelength) * lab_xyz.normalize() + beam).rotate( axis, -phi) calc_xyz = UB * hkl # now compute vector and angle to overlay calculated position on # observed position, then convert this to a matrix shift_axis = calc_xyz.cross(rec_xyz) shift_angle = calc_xyz.angle(rec_xyz) M = matrix.sqr( r3_rotation_axis_and_angle_as_matrix(shift_axis, shift_angle)) rx, ry, rz = xyz_angles(M) j = int(f) if not j in rx_s: rx_s[j] = [] if not j in ry_s: ry_s[j] = [] if not j in rz_s: rz_s[j] = [] rx_s[j].append(rx) ry_s[j].append(ry) rz_s[j].append(rz) j = min(rx_s) ms_x0 = meansd(rx_s[j])[0] ms_y0 = meansd(ry_s[j])[0] ms_z0 = meansd(rz_s[j])[0] for j in sorted(rx_s)[1:]: ms_x = meansd(rx_s[j]) ms_y = meansd(ry_s[j]) ms_z = meansd(rz_s[j]) print '%4d %6.3f %6.3f %6.3f' % \ (j, ms_x[0] - ms_x0, ms_y[0] - ms_y0, ms_z[0] - ms_z0)
dir2 = self._cfc.get_c('detector_slow') px_lim = self._cfc.get('detector_size_fast_slow') px_size_fast, px_size_slow = self._cfc.get('detector_pixel_size_fast_slow') return d(origin, dir1, dir2, px_size_fast, px_size_slow, px_lim[0], px_lim[1]) if __name__ == '__main__': import sys # require XDS configuration file, e.g. xparm-uc1-2.xds if len(sys.argv) != 2: raise RuntimeError('%s configuration-file' % sys.argv[0]) configuration_file = sys.argv[1] cfc = coordinate_frame_converter(configuration_file) df = detector_factory_from_cfc(cfc) d = df.build() # A little test. Intersection at centre of the abstract frame should # be at the centre of the pixel grid s = d.sensors()[0] intersection = ((s.lim1[1] - s.lim1[0]) / 2., (s.lim2[1] - s.lim2[0]) / 2.) assert approx_equal(d.mm_to_px(intersection), (d.npx_fast() / 2, d.npx_slow() / 2)) print "OK"
dir2 = self._cfc.get_c('detector_slow') px_lim = self._cfc.get('detector_size_fast_slow') px_size_fast, px_size_slow = self._cfc.get('detector_pixel_size_fast_slow') return d(origin, dir1, dir2, px_size_fast, px_size_slow, px_lim[0], px_lim[1]) if __name__ == '__main__': import sys # require XDS configuration file, e.g. xparm-uc1-2.xds if len(sys.argv) != 2: raise RuntimeError, '%s configuration-file' % sys.argv[0] configuration_file = sys.argv[1] cfc = coordinate_frame_converter(configuration_file) df = detector_factory_from_cfc(cfc) d = df.build() # A little test. Intersection at centre of the abstract frame should # be at the centre of the pixel grid s = d.sensors()[0] intersection = ((s.lim1[1] - s.lim1[0]) / 2., (s.lim2[1] - s.lim2[0]) / 2.) assert approx_equal(d.mm_to_px(intersection), (d.npx_fast() / 2, d.npx_slow() / 2)) print "OK"
def predict_observations(self): '''Actually perform the prediction calculations.''' d2r = math.pi / 180.0 cfc = coordinate_frame_converter(self._configuration_file) self.img_start, self.osc_start, self.osc_range = parse_xds_xparm_scan_info( self._configuration_file) if self._dmin is None: self._dmin = cfc.derive_detector_highest_resolution() phi_start = ((self._img_range[0] - self.img_start) * self.osc_range + \ self.osc_start) * d2r phi_end = ((self._img_range[1] - self.img_start + 1) * self.osc_range + \ self.osc_start) * d2r self.phi_start_rad = phi_start self.phi_end_rad = phi_end # in principle this should come from the crystal model - should that # crystal model record the cell parameters or derive them from the # axis directions? A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) self.uc = unit_cell(cell) # generate all of the possible indices, then pull out those which should # be systematically absent sg = cfc.get('space_group_number') indices = full_sphere_indices( unit_cell = self.uc, resolution_limit = self._dmin, space_group = space_group(space_group_symbols(sg).hall())) # then get the UB matrix according to the Rossmann convention which # is used within the Labelit code. u, b = cfc.get_u_b(convention = cfc.ROSSMANN) axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN) ub = u * b wavelength = cfc.get('wavelength') self.wavelength = wavelength # work out which reflections should be observed (i.e. pass through the # Ewald sphere) ra = rotation_angles(self._dmin, ub, wavelength, axis) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad = phi_start, phi_end_rad = phi_end, indices = indices) # convert all of these to full scattering vectors in a laboratory frame # (for which I will use the CBF coordinate frame) and calculate which # will intersect with the detector u, b = cfc.get_u_b() axis = cfc.get_c('rotation_axis') # must guarantee that sample_to_source vector is normalized so that # s0 has length of 1/wavelength. sample_to_source_vec = cfc.get_c('sample_to_source').normalize() s0 = (- 1.0 / wavelength) * sample_to_source_vec ub = u * b # need some detector properties for this as well... starting to # abstract these to a detector model. df = detector_factory_from_cfc(cfc) d = df.build() # the Use Case assumes the detector consists of a single sensor sensor = d.sensors()[0] self.pixel_size_fast, self.pixel_size_slow = d.px_size_fast(), \ d.px_size_slow() # used for polarization correction self.distance = sensor.distance rp = reflection_prediction(axis, s0, ub, sensor) if self._rocking_curve is not None: assert self._rocking_curve != "none" rp.set_rocking_curve(self._rocking_curve) rp.set_mosaicity(self._mosaicity_deg, degrees = True) return rp.predict(obs_indices, obs_angles)
def __init__(self): from dials.algorithms.spot_prediction import IndexGenerator from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import ray_intersection from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from math import ceil from os.path import realpath, dirname, join import dxtbx from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # The XDS files to read from test_path = dirname(dirname(dirname(realpath(__file__)))) integrate_filename = join(test_path, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(test_path, 'data/sim_mx/GXPARM.XDS') # Read the XDS files self.integrate_handle = integrate_hkl.reader() self.integrate_handle.read_file(integrate_filename) self.gxparm_handle = xparm.reader() self.gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) self.beam = models.get_beam() self.gonio = models.get_goniometer() self.detector = models.get_detector() self.scan = models.get_scan() assert(len(self.detector) == 1) #print self.detector # Get crystal parameters self.space_group_type = ioutil.get_space_group_type_from_xparm( self.gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') self.unit_cell = cfc.get_unit_cell() self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse() # Get the minimum resolution in the integrate file self.d_min = self.detector[0].get_max_resolution_at_corners( self.beam.get_s0()) # Get the number of frames from the max z value xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal) self.scan.set_image_range((self.scan.get_image_range()[0], self.scan.get_image_range()[0] + int(ceil(max(zcal))))) # Create the index generator generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, dphi) # Predict the spot locations self.reflections = self.predict_rays( generate_indices.to_array(), UB) # Calculate the intersection of the detector and reflection frames success = ray_intersection(self.detector, self.reflections) self.reflections.select(success)
def run(): if not have_dials_regression: print "Skipping test: dials_regression not available." return from scitbx import matrix from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from math import ceil from dials.algorithms.spot_prediction import RotationAngles import dxtbx from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter # The XDS files to read from integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS') # Read the XDS files integrate_handle = integrate_hkl.reader() integrate_handle.read_file(integrate_filename) gxparm_handle = xparm.reader() gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) beam = models.get_beam() gonio = models.get_goniometer() detector = models.get_detector() scan = models.get_scan() # Get the crystal parameters space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') unit_cell = cfc.get_unit_cell() UB = matrix.sqr(a_vec + b_vec + c_vec).inverse() ub_matrix = UB # Get the minimum resolution in the integrate file d = [unit_cell.d(h) for h in integrate_handle.hkl] d_min = min(d) # Get the number of frames from the max z value xcal, ycal, zcal = zip(*integrate_handle.xyzcal) num_frames = int(ceil(max(zcal))) scan.set_image_range((scan.get_image_range()[0], scan.get_image_range()[0] + num_frames - 1)) # Create the rotation angle object ra = RotationAngles(beam.get_s0(), gonio.get_rotation_axis()) # Setup the matrices ub = matrix.sqr(ub_matrix) s0 = matrix.col(beam.get_s0()) m2 = matrix.col(gonio.get_rotation_axis()) # For all the miller indices for h in integrate_handle.hkl: h = matrix.col(h) # Calculate the angles angles = ra(h, ub) # For all the angles for phi in angles: r = m2.axis_and_angle_as_r3_rotation_matrix(angle=phi) pstar = r * ub * h s1 = s0 + pstar assert(abs(s1.length() - s0.length()) < 1e-7) print "OK" # Create a dict of lists of xy for each hkl gen_phi = {} for h in integrate_handle.hkl: # Calculate the angles angles = ra(h, ub) gen_phi[h] = angles # for phi in angles: # try: # a = gen_phi[h] # a.append(phi) # gen_phi[h] = a # except KeyError: # gen_phi[h] = [phi] # For each hkl in the xds file for hkl, xyz in zip(integrate_handle.hkl, integrate_handle.xyzcal): # Calculate the XDS phi value xds_phi = scan.get_oscillation(deg=False)[0] + \ xyz[2]*scan.get_oscillation(deg=False)[1] # Select the nearest xy to use if there are 2 my_phi = gen_phi[hkl] if len(my_phi) == 2: my_phi0 = my_phi[0] my_phi1 = my_phi[1] diff0 = abs(xds_phi - my_phi0) diff1 = abs(xds_phi - my_phi1) if diff0 < diff1: my_phi = my_phi0 else: my_phi = my_phi1 else: my_phi = my_phi[0] # Check the Phi values are the same assert(abs(xds_phi - my_phi) < 0.1) # Test Passed print "OK"
def ersatz_misset_predict(xparm_xds, spot_xds): '''As well as possible, try to predict the misorientation angles as a function of frame # from the indexed spots from the XDS IDXREF step. Calculation will be performed in CBF coordinae frame.''' cfc = coordinate_frame_converter(xparm_xds) axis = cfc.get_c('rotation_axis') wavelength = cfc.get('wavelength') beam = (1.0 / wavelength) * cfc.get_c('sample_to_source').normalize() U, B = cfc.get_u_b() UB = U * B detector_origin = cfc.get_c('detector_origin') detector_fast = cfc.get_c('detector_fast') detector_slow = cfc.get_c('detector_slow') pixel_size_fast, pixel_size_slow = cfc.get('detector_pixel_size_fast_slow') size_fast, size_slow = cfc.get('detector_size_fast_slow') img_start, osc_start, osc_range = parse_xds_xparm_scan_info(xparm_xds) rx_s = {} ry_s = {} rz_s = {} for record in open(spot_xds): values = map(float, record.split()) if len(values) != 7: continue hkl = tuple(map(nint, values[-3:])) if hkl == (0, 0, 0): continue x, y, f = values[:3] phi = ((f - img_start + 1) * osc_range + osc_start) * math.pi / 180.0 lab_xyz = detector_origin + \ detector_fast * x * pixel_size_fast + \ detector_slow * y * pixel_size_slow rec_xyz = ((1.0 / wavelength) * lab_xyz.normalize() + beam).rotate( axis, - phi) calc_xyz = UB * hkl # now compute vector and angle to overlay calculated position on # observed position, then convert this to a matrix shift_axis = calc_xyz.cross(rec_xyz) shift_angle = calc_xyz.angle(rec_xyz) M = matrix.sqr(r3_rotation_axis_and_angle_as_matrix( shift_axis, shift_angle)) rx, ry, rz = xyz_angles(M) j = int(f) if not j in rx_s: rx_s[j] = [] if not j in ry_s: ry_s[j] = [] if not j in rz_s: rz_s[j] = [] rx_s[j].append(rx) ry_s[j].append(ry) rz_s[j].append(rz) j = min(rx_s) ms_x0 = meansd(rx_s[j])[0] ms_y0 = meansd(ry_s[j])[0] ms_z0 = meansd(rz_s[j])[0] for j in sorted(rx_s)[1:]: ms_x = meansd(rx_s[j]) ms_y = meansd(ry_s[j]) ms_z = meansd(rz_s[j]) print '%4d %6.3f %6.3f %6.3f' % \ (j, ms_x[0] - ms_x0, ms_y[0] - ms_y0, ms_z[0] - ms_z0)
def read_integrate_hkl_apply_corrections( int_hkl, x_crns_file, y_crns_file, xparm_file, image_file): '''Read X corrections and Y corrections to arrays; for record in int_hkl read x, y positions and compute r.m.s. deviations between observed and calculated centroids with and without the corrections. N.B. will only compute offsets for reflections with I/sigma > 10.''' from scitbx import matrix import math x_corrections = open_file_return_array(x_crns_file) y_corrections = open_file_return_array(y_crns_file) sumxx_orig = 0.0 n_obs = 0 sumxx_corr = 0.0 # FIXME find code to run prediction of reflection lists... img_start, osc_start, osc_range = parse_xds_xparm_scan_info(xparm_file) from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter cfc = coordinate_frame_converter(xparm_file) fast = cfc.get_c('detector_fast') slow = cfc.get_c('detector_slow') normal = fast.cross(slow) origin = cfc.get_c('detector_origin') distance = origin.dot(normal) A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) u, b = cfc.get_u_b() ub = u * b s0 = - cfc.get_c('sample_to_source') / cfc.get('wavelength') axis = cfc.get_c('rotation_axis') xcal = [] xobs = [] xcor = [] ycal = [] yobs = [] ycor = [] for record in open(int_hkl): if record.startswith('!'): continue values = map(float, record.split()) i, sigi = values[3], values[4] if sigi < 0: continue if i / sigi < 10: continue # FIXME also read the GXPARM.XDS file and recompute the reflection # position from the Miller indices and model of experimental geometry # as xc, yc, zc... Ah, smarter: use the zc from the file to provide the # rotation, not a full prediction: only then need to worry about # computing the intersection. hkl = map(int, map(round, values[:3])) xc, yc, zc = values[5:8] angle = (zc - img_start + 1) * osc_range + osc_start d2r = math.pi / 180.0 s = (ub * hkl).rotate(axis, angle * d2r) + s0 s = s.normalize() r = s * distance / s.dot(normal) - origin xc = r.dot(fast) / 0.172 yc = r.dot(slow) / 0.172 xo, yo, zo = values[12:15] xc_orig = matrix.col((xc, yc)) xo_orig = matrix.col((xo, yo)) n_obs += 1 sumxx_orig += (xo_orig - xc_orig).dot() # get the correcions for this pixel... N.B. 1 + ... lost due to C-style # rather than Fortran-style arrays ix4 = int(round((xc - 2) / 4)) iy4 = int(round((yc - 2) / 4)) # hmm.... Fortran multi-dimensional array ordering... identified by # bounds error other way around... dx = 0.1 * x_corrections[iy4, ix4] dy = 0.1 * y_corrections[iy4, ix4] xc_corr = matrix.col((xc + dx, yc + dy)) sumxx_corr += (xo_orig - xc_corr).dot() # Put coords in array if they're in frame zero if (zo >= 0 and zo < 1): xcal.append(xc) xobs.append(xo) xcor.append(xc + dx) ycal.append(yc) yobs.append(yo) ycor.append(yc + dy) if (image_file): import pycbf cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(image_file, pycbf.MSG_DIGEST) image_array = get_image(cbf_handle) # Correct coords for matplotlib convention xcal = [x - 0.5 for x in xcal] xobs = [x - 0.5 for x in xobs] xcor = [x - 0.5 for x in xcor] ycal = [y - 0.5 for y in ycal] yobs = [y - 0.5 for y in yobs] ycor = [y - 0.5 for y in ycor] # Manually selected a spot # xp = 533 # yp = 342 # ix4 = int(round((xp - 2) / 4)) # iy4 = int(round((yp - 2) / 4)) # dx = 0.1 * x_corrections[iy4, ix4] # dy = 0.1 * y_corrections[iy4, ix4] # xpcor = [xp + dx] # ypcor = [yp + dy] # Show the image with points plotted on it from matplotlib import pylab, cm pylab.imshow(image_array, cmap=cm.Greys_r, interpolation='nearest', origin='bottom') pylab.scatter(xcal, ycal, c='r', marker='x') pylab.scatter(xobs, yobs, c='b', marker='x') pylab.scatter(xcor, ycor, c='y', marker='x') #pylab.scatter(xpcor, ypcor, c='b', marker='8') pylab.show() return math.sqrt(sumxx_orig / n_obs), math.sqrt(sumxx_corr / n_obs)
import sys if len(sys.argv) == 1: regression_test() elif len(sys.argv) < 3: from libtbx.utils import Sorry raise Sorry("Expecting either 3 or 4 arguments: path/to/xparm.xds start_phi end_phi margin=3") else: # take an xparm.xds, phi_beg, phi_end and margin from the command arguments. from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter cfc = coordinate_frame_converter(sys.argv[1]) phi_beg, phi_end = float(sys.argv[2]), float(sys.argv[3]) margin = int(sys.argv[4]) if len(sys.argv) == 5 else 3 # test run for development/debugging. u, b = cfc.get_u_b() ub = matrix.sqr(u * b) axis = matrix.col(cfc.get("rotation_axis")) rub_beg = axis.axis_and_angle_as_r3_rotation_matrix(phi_beg) * ub rub_end = axis.axis_and_angle_as_r3_rotation_matrix(phi_end) * ub wavelength = cfc.get("wavelength") sample_to_source_vec = matrix.col(cfc.get_c("sample_to_source").normalize()) s0 = (-1.0 / wavelength) * sample_to_source_vec dmin = 1.20117776325 r = reeke_model(rub_beg, rub_end, axis, s0, dmin, margin)
def predict_observations(self): '''Actually perform the prediction calculations.''' d2r = math.pi / 180.0 cfc = coordinate_frame_converter(self._configuration_file) self.img_start, self.osc_start, self.osc_range = parse_xds_xparm_scan_info( self._configuration_file) if self._dmin is None: self._dmin = cfc.derive_detector_highest_resolution() phi_start = ((self._img_range[0] - self.img_start) * self.osc_range + \ self.osc_start) * d2r phi_end = ((self._img_range[1] - self.img_start + 1) * self.osc_range + \ self.osc_start) * d2r self.phi_start_rad = phi_start self.phi_end_rad = phi_end # in principle this should come from the crystal model - should that # crystal model record the cell parameters or derive them from the # axis directions? A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) self.uc = unit_cell(cell) # generate all of the possible indices, then pull out those which should # be systematically absent sg = cfc.get('space_group_number') indices = full_sphere_indices( unit_cell = self.uc, resolution_limit = self._dmin, space_group = space_group(space_group_symbols(sg).hall())) # then get the UB matrix according to the Rossmann convention which # is used within the Labelit code. u, b = cfc.get_u_b(convention = cfc.ROSSMANN) axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN) ub = u * b wavelength = cfc.get('wavelength') self.wavelength = wavelength # work out which reflections should be observed (i.e. pass through the # Ewald sphere) ra = rotation_angles(self._dmin, ub, wavelength, axis) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad = phi_start, phi_end_rad = phi_end, indices = indices) # convert all of these to full scattering vectors in a laboratory frame # (for which I will use the CBF coordinate frame) and calculate which # will intersect with the detector u, b = cfc.get_u_b() axis = cfc.get_c('rotation_axis') # must guarantee that sample_to_source vector is normalized so that # s0 has length of 1/wavelength. sample_to_source_vec = cfc.get_c('sample_to_source').normalize() s0 = (- 1.0 / wavelength) * sample_to_source_vec ub = u * b # need some detector properties for this as well... starting to # abstract these to a detector model. df = detector_factory_from_cfc(cfc) d = df.build() # the Use Case assumes the detector consists of a single sensor sensor = d.sensors()[0] self.pixel_size_fast, self.pixel_size_slow = d.px_size_fast(), \ d.px_size_slow() # used for polarization correction self.distance = sensor.distance rp = reflection_prediction(axis, s0, ub, sensor) if self._rocking_curve is not None: assert self._rocking_curve != "none" rp.set_rocking_curve(self._rocking_curve) rp.set_mosaicity(self._mosaicity_deg, degrees = True) return rp.predict(obs_indices, obs_angles)
def test(dials_regression, run_in_tmpdir): import dxtbx from iotbx.xds import integrate_hkl, xparm from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from dials.algorithms.spot_prediction import RotationAngles # The XDS files to read from integrate_filename = os.path.join(dials_regression, "data/sim_mx/INTEGRATE.HKL") gxparm_filename = os.path.join(dials_regression, "data/sim_mx/GXPARM.XDS") # Read the XDS files integrate_handle = integrate_hkl.reader() integrate_handle.read_file(integrate_filename) gxparm_handle = xparm.reader() gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) beam = models.get_beam() gonio = models.get_goniometer() scan = models.get_scan() # Get the crystal parameters cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get("real_space_a") b_vec = cfc.get("real_space_b") c_vec = cfc.get("real_space_c") UB = matrix.sqr(a_vec + b_vec + c_vec).inverse() ub_matrix = UB # Get the number of frames from the max z value xcal, ycal, zcal = zip(*integrate_handle.xyzcal) num_frames = int(math.ceil(max(zcal))) scan.set_image_range((scan.get_image_range()[0], scan.get_image_range()[0] + num_frames - 1)) # Create the rotation angle object ra = RotationAngles(beam.get_s0(), gonio.get_rotation_axis()) # Setup the matrices ub = matrix.sqr(ub_matrix) s0 = matrix.col(beam.get_s0()) m2 = matrix.col(gonio.get_rotation_axis()) # For all the miller indices for h in integrate_handle.hkl: h = matrix.col(h) # Calculate the angles angles = ra(h, ub) # For all the angles for phi in angles: r = m2.axis_and_angle_as_r3_rotation_matrix(angle=phi) pstar = r * ub * h s1 = s0 + pstar assert s1.length() == pytest.approx(s0.length(), abs=1e-7) # Create a dict of lists of xy for each hkl gen_phi = {} for h in integrate_handle.hkl: # Calculate the angles angles = ra(h, ub) gen_phi[h] = angles # for phi in angles: # try: # a = gen_phi[h] # a.append(phi) # gen_phi[h] = a # except KeyError: # gen_phi[h] = [phi] # For each hkl in the xds file for hkl, xyz in zip(integrate_handle.hkl, integrate_handle.xyzcal): # Calculate the XDS phi value xds_phi = (scan.get_oscillation(deg=False)[0] + xyz[2] * scan.get_oscillation(deg=False)[1]) # Select the nearest xy to use if there are 2 my_phi = gen_phi[hkl] if len(my_phi) == 2: my_phi0 = my_phi[0] my_phi1 = my_phi[1] diff0 = abs(xds_phi - my_phi0) diff1 = abs(xds_phi - my_phi1) if diff0 < diff1: my_phi = my_phi0 else: my_phi = my_phi1 else: my_phi = my_phi[0] # Check the Phi values are the same assert xds_phi == pytest.approx(my_phi, abs=0.1)
def __init__(self): from dials.algorithms.spot_prediction import IndexGenerator from dials.algorithms.spot_prediction import ScanStaticRayPredictor from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from math import ceil import dxtbx from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # The XDS files to read from integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS') # Read the XDS files self.integrate_handle = integrate_hkl.reader() self.integrate_handle.read_file(integrate_filename) self.gxparm_handle = xparm.reader() self.gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) self.beam = models.get_beam() self.gonio = models.get_goniometer() self.detector = models.get_detector() self.scan = models.get_scan() # Get crystal parameters self.space_group_type = ioutil.get_space_group_type_from_xparm( self.gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') self.unit_cell = cfc.get_unit_cell() self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse() # Get the minimum resolution in the integrate file d = [self.unit_cell.d(h) for h in self.integrate_handle.hkl] self.d_min = min(d) # extend the resolution shell by epsilon>0 # to account for rounding artifacts on 32-bit platforms self.d_min = self.d_min - 1e-15 # Get the number of frames from the max z value xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal) self.scan.set_image_range((self.scan.get_image_range()[0], self.scan.get_image_range()[0] + int(ceil(max(zcal))))) # Print stuff # print self.beam # print self.gonio # print self.detector # print self.scan # Create the index generator self.generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() setting_rotation = self.gonio.get_setting_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations self.reflections = self.predict_rays( self.generate_indices.to_array(), UB)
def __init__(self): from dials.algorithms.spot_prediction import IndexGenerator from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import ray_intersection from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from math import ceil import dxtbx from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # The XDS files to read from integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS') # Read the XDS files self.integrate_handle = integrate_hkl.reader() self.integrate_handle.read_file(integrate_filename) self.gxparm_handle = xparm.reader() self.gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) self.beam = models.get_beam() self.gonio = models.get_goniometer() self.detector = models.get_detector() self.scan = models.get_scan() assert (len(self.detector) == 1) #print self.detector # Get crystal parameters self.space_group_type = ioutil.get_space_group_type_from_xparm( self.gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') self.unit_cell = cfc.get_unit_cell() self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse() # Get the minimum resolution in the integrate file self.d_min = self.detector[0].get_max_resolution_at_corners( self.beam.get_s0()) # Get the number of frames from the max z value xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal) self.scan.set_image_range( (self.scan.get_image_range()[0], self.scan.get_image_range()[0] + int(ceil(max(zcal))))) # Create the index generator generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() setting_rotation = self.gonio.get_setting_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations self.reflections = self.predict_rays(generate_indices.to_array(), UB) # Calculate the intersection of the detector and reflection frames success = ray_intersection(self.detector, self.reflections) self.reflections.select(success)
def read_integrate_hkl_apply_corrections(int_hkl, x_crns_file, y_crns_file, xparm_file, image_file): """Read X corrections and Y corrections to arrays; for record in int_hkl read x, y positions and compute r.m.s. deviations between observed and calculated centroids with and without the corrections. N.B. will only compute offsets for reflections with I/sigma > 10.""" from scitbx import matrix import math x_corrections = open_file_return_array(x_crns_file) y_corrections = open_file_return_array(y_crns_file) sumxx_orig = 0.0 n_obs = 0 sumxx_corr = 0.0 # FIXME find code to run prediction of reflection lists... img_start, osc_start, osc_range = parse_xds_xparm_scan_info(xparm_file) from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter cfc = coordinate_frame_converter(xparm_file) fast = cfc.get_c("detector_fast") slow = cfc.get_c("detector_slow") normal = fast.cross(slow) origin = cfc.get_c("detector_origin") distance = origin.dot(normal) A = cfc.get_c("real_space_a") B = cfc.get_c("real_space_b") C = cfc.get_c("real_space_c") cell = ( A.length(), B.length(), C.length(), B.angle(C, deg=True), C.angle(A, deg=True), A.angle(B, deg=True), ) u, b = cfc.get_u_b() ub = u * b s0 = -cfc.get_c("sample_to_source") / cfc.get("wavelength") axis = cfc.get_c("rotation_axis") xcal = [] xobs = [] xcor = [] ycal = [] yobs = [] ycor = [] for record in open(int_hkl): if record.startswith("!"): continue values = map(float, record.split()) i, sigi = values[3], values[4] if sigi < 0: continue if i / sigi < 10: continue # FIXME also read the GXPARM.XDS file and recompute the reflection # position from the Miller indices and model of experimental geometry # as xc, yc, zc... Ah, smarter: use the zc from the file to provide the # rotation, not a full prediction: only then need to worry about # computing the intersection. hkl = map(int, map(round, values[:3])) xc, yc, zc = values[5:8] angle = (zc - img_start + 1) * osc_range + osc_start d2r = math.pi / 180.0 s = (ub * hkl).rotate(axis, angle * d2r) + s0 s = s.normalize() r = s * distance / s.dot(normal) - origin xc = r.dot(fast) / 0.172 yc = r.dot(slow) / 0.172 xo, yo, zo = values[12:15] xc_orig = matrix.col((xc, yc)) xo_orig = matrix.col((xo, yo)) n_obs += 1 sumxx_orig += (xo_orig - xc_orig).dot() # get the correcions for this pixel... N.B. 1 + ... lost due to C-style # rather than Fortran-style arrays ix4 = int(round((xc - 2) / 4)) iy4 = int(round((yc - 2) / 4)) # hmm.... Fortran multi-dimensional array ordering... identified by # bounds error other way around... dx = 0.1 * x_corrections[iy4, ix4] dy = 0.1 * y_corrections[iy4, ix4] xc_corr = matrix.col((xc + dx, yc + dy)) sumxx_corr += (xo_orig - xc_corr).dot() # Put coords in array if they're in frame zero if zo >= 0 and zo < 1: xcal.append(xc) xobs.append(xo) xcor.append(xc + dx) ycal.append(yc) yobs.append(yo) ycor.append(yc + dy) if image_file: import pycbf cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(image_file, pycbf.MSG_DIGEST) image_array = get_image(cbf_handle) # Correct coords for matplotlib convention xcal = [x - 0.5 for x in xcal] xobs = [x - 0.5 for x in xobs] xcor = [x - 0.5 for x in xcor] ycal = [y - 0.5 for y in ycal] yobs = [y - 0.5 for y in yobs] ycor = [y - 0.5 for y in ycor] # Manually selected a spot # xp = 533 # yp = 342 # ix4 = int(round((xp - 2) / 4)) # iy4 = int(round((yp - 2) / 4)) # dx = 0.1 * x_corrections[iy4, ix4] # dy = 0.1 * y_corrections[iy4, ix4] # xpcor = [xp + dx] # ypcor = [yp + dy] # Show the image with points plotted on it from matplotlib import pylab, cm pylab.imshow(image_array, cmap=cm.Greys_r, interpolation="nearest", origin="bottom") pylab.scatter(xcal, ycal, c="r", marker="x") pylab.scatter(xobs, yobs, c="b", marker="x") pylab.scatter(xcor, ycor, c="y", marker="x") # pylab.scatter(xpcor, ypcor, c='b', marker='8') pylab.show() return math.sqrt(sumxx_orig / n_obs), math.sqrt(sumxx_corr / n_obs)
def validate_against_xds(xds_directory): """Will look in xds_directory for (i) XPARM.XDS and (ii) X- and Y-CORRECTIONS.cbf files, and will rederive from the former the values for the latter...""" from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter import os import math # read and derive all of the model parameters xparm = os.path.join(xds_directory, "XPARM.XDS") cfc = coordinate_frame_converter(xparm) fast = cfc.get_c("detector_fast") slow = cfc.get_c("detector_slow") origin = cfc.get_c("detector_origin") wavelength = cfc.get("wavelength") normal = fast.cross(slow) energy_kev = 12.3985 / wavelength mu = derive_absorption_coefficient_Si(energy_kev) detector_size = cfc.get("detector_size_fast_slow") pixel_size = cfc.get("detector_pixel_size_fast_slow") beam_centre_fast_slow = cfc.derive_beam_centre_pixels_fast_slow() beam_centre = (beam_centre_fast_slow[0] * pixel_size[0] * fast + beam_centre_fast_slow[1] * pixel_size[1] * slow + origin) min_offset_x = 0 max_offset_x = 0 min_offset_y = 0 max_offset_y = 0 for k in range(0, detector_size[1], 20): for j in range(0, detector_size[0], 20): p = j * pixel_size[0] * fast + k * pixel_size[1] * slow + origin theta = p.angle(normal) # beware this piece of code is in cm not mm - blame particle physicists and # cgs units t0 = 0.032 pixel = 0.0172 offset = compute_offset(t0, theta, mu) / pixel # end weirdness offset_vector = (p - beam_centre).normalize() * offset offset_x = fast.dot(offset_vector) offset_y = slow.dot(offset_vector) if offset_x < min_offset_x: min_offset_x = offset_x if offset_x > max_offset_x: max_offset_x = offset_x if offset_y < min_offset_y: min_offset_y = offset_y if offset_y > max_offset_y: max_offset_y = offset_y print(min_offset_x, max_offset_x) print(min_offset_y, max_offset_y)
def __init__(self, dials_regression): import dxtbx from iotbx.xds import integrate_hkl, xparm from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from dials.algorithms.spot_prediction import ( IndexGenerator, ScanStaticRayPredictor, ) from dials.util import ioutil # The XDS files to read from integrate_filename = os.path.join(dials_regression, "data", "sim_mx", "INTEGRATE.HKL") gxparm_filename = os.path.join(dials_regression, "data", "sim_mx", "GXPARM.XDS") # Read the XDS files self.integrate_handle = integrate_hkl.reader() self.integrate_handle.read_file(integrate_filename) self.gxparm_handle = xparm.reader() self.gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) self.beam = models.get_beam() self.gonio = models.get_goniometer() self.detector = models.get_detector() self.scan = models.get_scan() # Get crystal parameters self.space_group_type = ioutil.get_space_group_type_from_xparm( self.gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get("real_space_a") b_vec = cfc.get("real_space_b") c_vec = cfc.get("real_space_c") self.unit_cell = cfc.get_unit_cell() self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse() # Get the minimum resolution in the integrate file d = [self.unit_cell.d(h) for h in self.integrate_handle.hkl] self.d_min = min(d) # extend the resolution shell by epsilon>0 # to account for rounding artifacts on 32-bit platforms self.d_min = self.d_min - 1e-15 # Get the number of frames from the max z value xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal) self.scan.set_image_range(( self.scan.get_image_range()[0], self.scan.get_image_range()[0] + int(math.ceil(max(zcal))), )) # Print stuff # print self.beam # print self.gonio # print self.detector # print self.scan # Create the index generator self.generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() setting_rotation = self.gonio.get_setting_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations self.reflections = self.predict_rays(self.generate_indices.to_array(), UB)
def read_spot_xds_apply_corrections(spot_xds, x_crns_file, y_crns_file, xparm_file): """Read X corrections and Y corrections to arrays; for record in int_hkl read x, y positions and compute r.m.s. deviations between observed and calculated centroids with and without the corrections. N.B. will only compute offsets for reflections with I/sigma > 10.""" from scitbx import matrix import math x_corrections = open_file_return_array(x_crns_file) y_corrections = open_file_return_array(y_crns_file) sumxx_orig = 0.0 n_obs = 0 sumxx_corr = 0.0 # FIXME find code to run prediction of reflection lists... img_start, osc_start, osc_range = parse_xds_xparm_scan_info(xparm_file) from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter cfc = coordinate_frame_converter(xparm_file) fast = cfc.get_c("detector_fast") slow = cfc.get_c("detector_slow") normal = fast.cross(slow) origin = cfc.get_c("detector_origin") distance = origin.dot(normal) A = cfc.get_c("real_space_a") B = cfc.get_c("real_space_b") C = cfc.get_c("real_space_c") cell = ( A.length(), B.length(), C.length(), B.angle(C, deg=True), C.angle(A, deg=True), A.angle(B, deg=True), ) u, b = cfc.get_u_b() ub = u * b s0 = -cfc.get_c("sample_to_source") / cfc.get("wavelength") axis = cfc.get_c("rotation_axis") xcal = [] xobs = [] xcor = [] ycal = [] yobs = [] ycor = [] for record in open(spot_xds): values = map(float, record.split()) hkl = map(int, map(round, values[-3:])) if hkl[0] == 0 and hkl[1] == 0 and hkl[2] == 0: continue xc, yc, zc = values[:3] angle = (zc - img_start + 1) * osc_range + osc_start d2r = math.pi / 180.0 s = (ub * hkl).rotate(axis, angle * d2r) + s0 s = s.normalize() r = s * distance / s.dot(normal) - origin xc = r.dot(fast) / 0.172 yc = r.dot(slow) / 0.172 xo, yo, zo = values[:3] xc_orig = matrix.col((xc, yc)) xo_orig = matrix.col((xo, yo)) n_obs += 1 sumxx_orig += (xo_orig - xc_orig).dot() # get the correcions for this pixel... N.B. 1 + ... lost due to C-style # rather than Fortran-style arrays ix4 = int(round((xc - 2) / 4)) iy4 = int(round((yc - 2) / 4)) # hmm.... Fortran multi-dimensional array ordering... identified by # bounds error other way around... dx = 0.1 * x_corrections[iy4, ix4] dy = 0.1 * y_corrections[iy4, ix4] xc_corr = matrix.col((xc + dx, yc + dy)) sumxx_corr += (xo_orig - xc_corr).dot() print(n_obs) return math.sqrt(sumxx_orig / n_obs), math.sqrt(sumxx_corr / n_obs)
def validate_against_xds(xds_directory): '''Will look in xds_directory for (i) XPARM.XDS and (ii) X- and Y-CORRECTIONS.cbf files, and will rederive from the former the values for the latter...''' from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter import os import math # read and derive all of the model parameters xparm = os.path.join(xds_directory, 'XPARM.XDS') cfc = coordinate_frame_converter(xparm) fast = cfc.get_c('detector_fast') slow = cfc.get_c('detector_slow') origin = cfc.get_c('detector_origin') wavelength = cfc.get('wavelength') normal = fast.cross(slow) energy_kev = 12.3985 / wavelength mu = derive_absorption_coefficient_Si(energy_kev) detector_size = cfc.get('detector_size_fast_slow') pixel_size = cfc.get('detector_pixel_size_fast_slow') beam_centre_fast_slow = cfc.derive_beam_centre_pixels_fast_slow() beam_centre = beam_centre_fast_slow[0] * pixel_size[0] * fast + \ beam_centre_fast_slow[1] * pixel_size[1] * slow + origin min_offset_x = 0 max_offset_x = 0 min_offset_y = 0 max_offset_y = 0 for k in range(0, detector_size[1], 20): for j in range(0, detector_size[0], 20): p = j * pixel_size[0] * fast + k * pixel_size[1] * slow + origin theta = p.angle(normal) # beware this piece of code is in cm not mm - blame particle physicists and # cgs units t0 = 0.032 pixel = 0.0172 offset = compute_offset(t0, theta, mu) / pixel # end weirdness offset_vector = (p - beam_centre).normalize() * offset offset_x = fast.dot(offset_vector) offset_y = slow.dot(offset_vector) if offset_x < min_offset_x: min_offset_x = offset_x if offset_x > max_offset_x: max_offset_x = offset_x if offset_y < min_offset_y: min_offset_y = offset_y if offset_y > max_offset_y: max_offset_y = offset_y print min_offset_x, max_offset_x print min_offset_y, max_offset_y
# TODO Tests for an oblique cell if __name__ == "__main__": import sys if len(sys.argv) < 3: sys.exit( "Expecting either 3 or 4 arguments: path/to/xparm.xds start_phi end_phi margin=3" ) else: # take an xparm.xds, phi_beg, phi_end and margin from the command arguments. from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter cfc = coordinate_frame_converter(sys.argv[1]) phi_beg, phi_end = float(sys.argv[2]), float(sys.argv[3]) margin = int(sys.argv[4]) if len(sys.argv) == 5 else 3 # test run for development/debugging. u, b = cfc.get_u_b() ub = matrix.sqr(u * b) axis = matrix.col(cfc.get("rotation_axis")) rub_beg = axis.axis_and_angle_as_r3_rotation_matrix(phi_beg) * ub rub_end = axis.axis_and_angle_as_r3_rotation_matrix(phi_end) * ub wavelength = cfc.get("wavelength") sample_to_source_vec = matrix.col( cfc.get_c("sample_to_source").normalize()) s0 = (-1.0 / wavelength) * sample_to_source_vec dmin = 1.20117776325
def run(): from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from dials.algorithms.spot_prediction import IndexGenerator from os.path import realpath, dirname, join import numpy from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # The XDS files to read from test_path = dirname(dirname(dirname(realpath(__file__)))) integrate_filename = join(test_path, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(test_path, 'data/sim_mx/GXPARM.XDS') # Read the XDS files integrate_handle = integrate_hkl.reader() integrate_handle.read_file(integrate_filename) gxparm_handle = xparm.reader() gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file d_min = 1.6 space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') unit_cell = cfc.get_unit_cell() UB = matrix.sqr(a_vec + b_vec + c_vec).inverse() ub_matrix = UB # Generate the indices index_generator = IndexGenerator(unit_cell, space_group_type, d_min) miller_indices = index_generator.to_array() # Get individual generated hkl gen_h = [hkl[0] for hkl in miller_indices] gen_k = [hkl[1] for hkl in miller_indices] gen_l = [hkl[2] for hkl in miller_indices] # Get individual xds generated hkl xds_h = [hkl[0] for hkl in integrate_handle.hkl] xds_k = [hkl[0] for hkl in integrate_handle.hkl] xds_l = [hkl[0] for hkl in integrate_handle.hkl] # Get min/max generated hkl min_gen_h, max_gen_h = numpy.min(gen_h), numpy.max(gen_h) min_gen_k, max_gen_k = numpy.min(gen_k), numpy.max(gen_k) min_gen_l, max_gen_l = numpy.min(gen_l), numpy.max(gen_l) # Get min/max xds generated hkl min_xds_h, max_xds_h = numpy.min(xds_h), numpy.max(xds_h) min_xds_k, max_xds_k = numpy.min(xds_k), numpy.max(xds_k) min_xds_l, max_xds_l = numpy.min(xds_l), numpy.max(xds_l) # Ensure we have the whole xds range in the generated set assert(min_gen_h <= min_xds_h and max_gen_h >= max_xds_h) assert(min_gen_k <= min_xds_k and max_gen_k >= max_xds_k) assert(min_gen_l <= min_xds_l and max_gen_l >= max_xds_l) # Test Passed print "OK"
def run(): if not have_dials_regression: print "Skipping test: dials_regression not available." return from scitbx import matrix from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from math import ceil from dials.algorithms.spot_prediction import RotationAngles import dxtbx from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter # The XDS files to read from integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS') # Read the XDS files integrate_handle = integrate_hkl.reader() integrate_handle.read_file(integrate_filename) gxparm_handle = xparm.reader() gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) beam = models.get_beam() gonio = models.get_goniometer() detector = models.get_detector() scan = models.get_scan() # Get the crystal parameters space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') unit_cell = cfc.get_unit_cell() UB = matrix.sqr(a_vec + b_vec + c_vec).inverse() ub_matrix = UB # Get the minimum resolution in the integrate file d = [unit_cell.d(h) for h in integrate_handle.hkl] d_min = min(d) # Get the number of frames from the max z value xcal, ycal, zcal = zip(*integrate_handle.xyzcal) num_frames = int(ceil(max(zcal))) scan.set_image_range((scan.get_image_range()[0], scan.get_image_range()[0] + num_frames - 1)) # Create the rotation angle object ra = RotationAngles(beam.get_s0(), gonio.get_rotation_axis()) # Setup the matrices ub = matrix.sqr(ub_matrix) s0 = matrix.col(beam.get_s0()) m2 = matrix.col(gonio.get_rotation_axis()) # For all the miller indices for h in integrate_handle.hkl: h = matrix.col(h) # Calculate the angles angles = ra(h, ub) # For all the angles for phi in angles: r = m2.axis_and_angle_as_r3_rotation_matrix(angle=phi) pstar = r * ub * h s1 = s0 + pstar assert(abs(s1.length() - s0.length()) < 1e-7) print "OK" # Create a dict of lists of xy for each hkl gen_phi = {} for h in integrate_handle.hkl: # Calculate the angles angles = ra(h, ub) gen_phi[h] = angles # for phi in angles: # try: # a = gen_phi[h] # a.append(phi) # gen_phi[h] = a # except KeyError: # gen_phi[h] = [phi] # For each hkl in the xds file for hkl, xyz in zip(integrate_handle.hkl, integrate_handle.xyzcal): # Calculate the XDS phi value xds_phi = scan.get_oscillation(deg=False)[0] + \ xyz[2]*scan.get_oscillation(deg=False)[1] # Select the nearest xy to use if there are 2 my_phi = gen_phi[hkl] if len(my_phi) == 2: my_phi0 = my_phi[0] my_phi1 = my_phi[1] diff0 = abs(xds_phi - my_phi0) diff1 = abs(xds_phi - my_phi1) if diff0 < diff1: my_phi = my_phi0 else: my_phi = my_phi1 else: my_phi = my_phi[0] # Check the Phi values are the same assert(abs(xds_phi - my_phi) < 0.1) # Test Passed print "OK"