def exercise(): from dials.algorithms.indexing import compare_orientation_matrices from dxtbx.model.crystal import crystal_model from cctbx import sgtbx from scitbx import matrix from scitbx.math import euler_angles as euler # try and see if we can get back the original rotation matrix and euler angles real_space_a = matrix.col((10,0,0)) real_space_b = matrix.col((0,10,10)) real_space_c = matrix.col((0,0,10)) euler_angles = (1.3, 5.6, 7.8) R = matrix.sqr( euler.xyz_matrix(euler_angles[0], euler_angles[1], euler_angles[2])) crystal_a = crystal_model(real_space_a, real_space_b, real_space_c, space_group=sgtbx.space_group('P 1')) crystal_b = crystal_model(R * real_space_a, R * real_space_b, R * real_space_c, space_group=sgtbx.space_group('P 1')) assert approx_equal(crystal_b.get_U() * crystal_a.get_U().transpose(), R) best_R_ab, best_euler_angles, best_cb_op = \ compare_orientation_matrices.difference_rotation_matrix_and_euler_angles( crystal_a, crystal_b) assert approx_equal(best_euler_angles, euler_angles) assert best_cb_op.is_identity_op() assert approx_equal(best_R_ab, R) # now see if we can deconvolute the original euler angles after applying # a change of basis to one of the crystals crystal_a = crystal_model(real_space_a, real_space_b, real_space_c, space_group=sgtbx.space_group('I 2 3')) crystal_b = crystal_model(R * real_space_a, R * real_space_b, R * real_space_c, space_group=sgtbx.space_group('I 2 3')) cb_op = sgtbx.change_of_basis_op('z,x,y') crystal_b = crystal_b.change_basis(cb_op) best_R_ab, best_euler_angles, best_cb_op = \ compare_orientation_matrices.difference_rotation_matrix_and_euler_angles( crystal_a, crystal_b) assert approx_equal(best_euler_angles, euler_angles) assert best_cb_op.c() == cb_op.inverse().c() assert approx_equal(best_R_ab, R)
def run(args): import libtbx.load_env from libtbx.utils import Sorry usage = "%s [options] experiments.json indexed.pickle" % libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0 and len(reflections) == 0: parser.print_help() return elif len(experiments.crystals()) > 1: raise Sorry("Only one crystal can be processed at a time") if params.change_of_basis_op is None: raise Sorry("Please provide a change_of_basis_op.") reference_crystal = None if params.reference is not None: from dxtbx.serialize import load reference_experiments = load.experiment_list(params.reference, check_format=False) assert len(reference_experiments.crystals()) == 1 reference_crystal = reference_experiments.crystals()[0] if len(experiments) and params.change_of_basis_op is libtbx.Auto: if reference_crystal is not None: from dials.algorithms.indexing.compare_orientation_matrices import ( difference_rotation_matrix_and_euler_angles, ) cryst = experiments.crystals()[0] R, euler_angles, change_of_basis_op = difference_rotation_matrix_and_euler_angles(cryst, reference_crystal) print "Change of basis op: %s" % change_of_basis_op print "Rotation matrix to transform input crystal to reference::" print R.mathematica_form(format="%.3f", one_row_per_line=True) print "Euler angles (xyz): %.2f, %.2f, %.2f" % euler_angles elif len(reflections): assert len(reflections) == 1 # always re-map reflections to reciprocal space from dials.algorithms.indexing import indexer refl_copy = flex.reflection_table() for i, imageset in enumerate(experiments.imagesets()): if "imageset_id" in reflections[0]: sel = reflections[0]["imageset_id"] == i else: sel = reflections[0]["id"] == i refl = indexer.indexer_base.map_spots_pixel_to_mm_rad( reflections[0].select(sel), imageset.get_detector(), imageset.get_scan() ) indexer.indexer_base.map_centroids_to_reciprocal_space( refl, imageset.get_detector(), imageset.get_beam(), imageset.get_goniometer() ) refl_copy.extend(refl) # index the reflection list using the input experiments list refl_copy["id"] = flex.int(len(refl_copy), -1) from dials.algorithms.indexing import index_reflections index_reflections(refl_copy, experiments, tolerance=0.2) hkl_expt = refl_copy["miller_index"] hkl_input = reflections[0]["miller_index"] change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt) # reset experiments list since we don't want to reindex this experiments = [] else: change_of_basis_op = sgtbx.change_of_basis_op(params.change_of_basis_op) if len(experiments): experiment = experiments[0] cryst_orig = copy.deepcopy(experiment.crystal) cryst_reindexed = cryst_orig.change_basis(change_of_basis_op) if params.space_group is not None: a, b, c = cryst_reindexed.get_real_space_vectors() cryst_reindexed = crystal_model(a, b, c, space_group=params.space_group.group()) experiment.crystal.update(cryst_reindexed) print "Old crystal:" print cryst_orig print print "New crystal:" print cryst_reindexed print print "Saving reindexed experimental models to %s" % params.output.experiments dump.experiment_list(experiments, params.output.experiments) if len(reflections): assert len(reflections) == 1 reflections = reflections[0] miller_indices = reflections["miller_index"] if params.hkl_offset is not None: h, k, l = miller_indices.as_vec3_double().parts() h += params.hkl_offset[0] k += params.hkl_offset[1] l += params.hkl_offset[2] miller_indices = flex.miller_index(h.iround(), k.iround(), l.iround()) non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(miller_indices) if non_integral_indices.size() > 0: print "Removing %i/%i reflections (change of basis results in non-integral indices)" % ( non_integral_indices.size(), miller_indices.size(), ) sel = flex.bool(miller_indices.size(), True) sel.set_selected(non_integral_indices, False) miller_indices_reindexed = change_of_basis_op.apply(miller_indices.select(sel)) reflections["miller_index"].set_selected(sel, miller_indices_reindexed) reflections["miller_index"].set_selected(~sel, (0, 0, 0)) print "Saving reindexed reflections to %s" % params.output.reflections easy_pickle.dump(params.output.reflections, reflections)
def run(args): import libtbx.load_env from dials.util.options import OptionParser from dials.util.options import flatten_experiments # The script usage usage = "usage: %s [options] [param.phil] experiments.json" %libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: parser.print_help() return if len(params.hkl) == 0 and params.hkl_limit is None: from libtbx.utils import Sorry raise Sorry("Please provide hkl or hkl_limit parameters.") if params.hkl is not None and len(params.hkl): miller_indices = flex.miller_index(params.hkl) elif params.hkl_limit is not None: limit = params.hkl_limit miller_indices = flex.miller_index() for h in range(-limit, limit+1): for k in range(-limit, limit+1): for l in range(-limit, limit+1): if (h,k,l) == (0,0,0): continue miller_indices.append((h,k,l)) crystals = experiments.crystals() symmetry = crystal.symmetry( unit_cell=crystals[0].get_unit_cell(), space_group=crystals[0].get_space_group()) miller_set = miller.set(symmetry, miller_indices) d_spacings = miller_set.d_spacings() if params.eliminate_sys_absent: d_spacings = d_spacings.eliminate_sys_absent() if params.expand_to_p1: d_spacings = d_spacings.as_non_anomalous_array().expand_to_p1() d_spacings = d_spacings.generate_bijvoet_mates() miller_indices = d_spacings.indices() # find the greatest common factor (divisor) between miller indices miller_indices_unique = flex.miller_index() for hkl in miller_indices: gcd = gcd_list(hkl) if gcd > 1: miller_indices_unique.append(tuple(int(h/gcd) for h in hkl)) elif gcd < 1: pass else: miller_indices_unique.append(hkl) miller_indices = miller_indices_unique miller_indices = flex.miller_index(list(set(miller_indices))) ref_crystal = crystals[0] A = ref_crystal.get_A() U = ref_crystal.get_U() B = ref_crystal.get_B() R = matrix.identity(3) if params.frame == 'laboratory': reference_poles = reference_poles_perpendicular_to_beam( experiments[0].beam, experiments[0].goniometer) if params.use_starting_angle: rotation_axis = matrix.col( experiments[0].goniometer.get_rotation_axis()) R = rotation_axis.axis_and_angle_as_r3_rotation_matrix( experiments[0].scan.get_oscillation()[0], deg=True) elif params.phi_angle != 0: rotation_axis = matrix.col( experiments[0].goniometer.get_rotation_axis()) R = rotation_axis.axis_and_angle_as_r3_rotation_matrix( params.phi_angle, deg=True) else: if params.plane_normal is not None: plane_normal = params.plane_normal else: plane_normal = (0,0,1) reference_poles = reference_poles_crystal( ref_crystal, plane_normal=plane_normal) if params.frame == 'crystal': U = matrix.identity(3) reciprocal_space_points = list(R * U * B) * miller_indices.as_vec3_double() projections_ref = stereographic_projection( reciprocal_space_points, reference_poles) projections_all = [projections_ref] if len(experiments) > 0: from dials.algorithms.indexing.compare_orientation_matrices import \ difference_rotation_matrix_and_euler_angles for expt in experiments[1:]: cryst = expt.crystal if params.frame == 'crystal': R_ij, euler_angles, cb_op = difference_rotation_matrix_and_euler_angles( ref_crystal, cryst) U = R_ij elif params.use_starting_angle: if params.use_starting_angle: rotation_axis = matrix.col( expt.goniometer.get_rotation_axis()) R = rotation_axis.axis_and_angle_as_r3_rotation_matrix( expt.scan.get_oscillation()[0], deg=True) else: U = cryst.get_U() reciprocal_space_points = list(R * U * cryst.get_B()) * miller_indices.as_vec3_double() projections = stereographic_projection( reciprocal_space_points, reference_poles) projections_all.append(projections) if params.save_coordinates: with open('projections.txt', 'wb') as f: print >> f, "crystal h k l x y" for i_cryst, projections in enumerate(projections_all): for hkl, proj in zip(miller_indices, projections): print >> f, "%i" %(i_cryst+1), print >> f, "%i %i %i" %hkl, print >> f, "%f %f" %proj if params.plot.show or params.plot.filename: plot_projections( projections_all, filename=params.plot.filename, show=params.plot.show, colours=params.plot.colours, marker_size=params.plot.marker_size, font_size=params.plot.font_size, label_indices=params.plot.label_indices)