def test_crystal_with_scan_points(example_crystal): c1 = Crystal(**example_crystal) A = c1.get_A() c1.set_A_at_scan_points([A for i in range(5)]) # Set the B covariance. The values are nonsense, just ensure they are # all different cov_B = flex.double(range(9 * 9)) * 1e-5 c1.set_B_covariance(cov_B) cov_B.reshape(flex.grid(1, 9, 9)) cov_B_array = flex.double(flex.grid(5, 9, 9)) for i in range(5): cov_B_array[i:(i + 1), :, :] = cov_B c1.set_B_covariance_at_scan_points(cov_B_array) cov_B = c1.get_B_covariance() d = c1.to_dict() c2 = CrystalFactory.from_dict(d) eps = 1e-9 for Acomp in d["A_at_scan_points"]: for e1, e2 in zip(A, Acomp): assert abs(e1 - e2) <= eps for covBcomp in d["B_covariance_at_scan_points"]: for e1, e2 in zip(cov_B, covBcomp): assert abs(e1 - e2) <= eps assert c1 == c2
def from_dict(d): ''' Convert the dictionary to a crystal model Params: d The dictionary of parameters Returns: The crystal model ''' from dxtbx.model import Crystal # If None, return None if d is None: return None # Check the version and id if str(d['__id__']) != "crystal": raise ValueError("\"__id__\" does not equal \"crystal\"") # Extract from the dictionary real_space_a = d['real_space_a'] real_space_b = d['real_space_b'] real_space_c = d['real_space_c'] # str required to force unicode to ascii conversion space_group = str("Hall:" + d['space_group_hall_symbol']) xl = Crystal(real_space_a, real_space_b, real_space_c, space_group_symbol=space_group) # Isoforms used for stills try: xl.identified_isoform = d['identified_isoform'] except KeyError: pass # Extract scan point setting matrices, if present try: A_at_scan_points = d['A_at_scan_points'] xl.set_A_at_scan_points(A_at_scan_points) except KeyError: pass # Extract covariance of B, if present try: cov_B = d['B_covariance'] xl.set_B_covariance(cov_B) except KeyError: pass # Extract covariance of B at scan points, if present cov_B_at_scan_points = d.get('B_covariance_at_scan_points') if cov_B_at_scan_points is not None: from scitbx.array_family import flex cov_B_at_scan_points = flex.double(cov_B_at_scan_points).as_1d() cov_B_at_scan_points.reshape(flex.grid(xl.num_scan_points, 9, 9)) xl.set_B_covariance_at_scan_points(cov_B_at_scan_points) return xl
def tst_crystal_with_scan_points(self): from dxtbx.model import Crystal, CrystalFactory from scitbx import matrix real_space_a = matrix.col( (35.2402102454, -7.60002142787, 22.080026774)) real_space_b = matrix.col( (22.659572494, 1.47163505925, -35.6586361881)) real_space_c = matrix.col( (5.29417246554, 38.9981792999, 4.97368666613)) c1 = Crystal(real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group_symbol="P 1 2/m 1") A = c1.get_A() c1.set_A_at_scan_points([A for i in range(5)]) d = c1.to_dict() c2 = CrystalFactory.from_dict(d) eps = 1e-9 for Acomp in (d['A_at_scan_points']): for e1, e2 in zip(A, Acomp): assert (abs(e1 - e2) <= eps) assert (c1 == c2) print 'OK'
def test_crystal_with_scan_points(): from dxtbx.model import Crystal, CrystalFactory from scitbx import matrix real_space_a = matrix.col((35.2402102454, -7.60002142787, 22.080026774)) real_space_b = matrix.col((22.659572494, 1.47163505925, -35.6586361881)) real_space_c = matrix.col((5.29417246554, 38.9981792999, 4.97368666613)) c1 = Crystal( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group_symbol="P 1 2/m 1", ) A = c1.get_A() c1.set_A_at_scan_points([A for i in range(5)]) # Set the B covariance. The values are nonsense, just ensure they are # all different from scitbx.array_family import flex cov_B = flex.double(range((9 * 9))) * 1e-5 c1.set_B_covariance(cov_B) cov_B.reshape(flex.grid(1, 9, 9)) cov_B_array = flex.double(flex.grid(5, 9, 9)) for i in range(5): cov_B_array[i : (i + 1), :, :] = cov_B c1.set_B_covariance_at_scan_points(cov_B_array) cov_B = c1.get_B_covariance() d = c1.to_dict() c2 = CrystalFactory.from_dict(d) eps = 1e-9 for Acomp in d["A_at_scan_points"]: for e1, e2 in zip(A, Acomp): assert abs(e1 - e2) <= eps for covBcomp in d["B_covariance_at_scan_points"]: for e1, e2 in zip(cov_B, covBcomp): assert abs(e1 - e2) <= eps assert c1 == c2
def test_reindex_experiments(): # See also https://github.com/cctbx/cctbx_project/issues/424 cs = sgtbx.space_group_info("I23").any_compatible_crystal_symmetry( volume=100000) B = scitbx.matrix.sqr( cs.unit_cell().fractionalization_matrix()).transpose() cryst = Crystal(B, cs.space_group()) n_scan_points = 10 A_at_scan_points = [(1, 0, 0, 0, 1, 0, 0, 0, 1)] * n_scan_points cryst.set_A_at_scan_points(A_at_scan_points) groups = metric_subgroups(cs, max_delta=5) for group in groups.result_groups: best_subsym = group["best_subsym"] cb_op = group["cb_op_inp_best"] expts = ExperimentList([Experiment(crystal=cryst)]) reindexed_expts = reindex_experiments( experiments=expts, cb_op=cb_op, space_group=best_subsym.space_group()) assert (reindexed_expts[0].crystal.get_crystal_symmetry(). is_similar_symmetry(best_subsym)) # Check that the scan-varying A matrices have been copied as well assert cryst.num_scan_points == n_scan_points
def test_crystal_model(): real_space_a = matrix.col((10, 0, 0)) real_space_b = matrix.col((0, 11, 0)) real_space_c = matrix.col((0, 0, 12)) model = Crystal( real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group_symbol="P 1", ) # This doesn't work as python class uctbx.unit_cell(uctbx_ext.unit_cell) # so C++ and python classes are different types # assert isinstance(model.get_unit_cell(), uctbx.unit_cell) assert model.get_unit_cell().parameters() == (10.0, 11.0, 12.0, 90.0, 90.0, 90.0) assert approx_equal(model.get_A(), (1 / 10, 0, 0, 0, 1 / 11, 0, 0, 0, 1 / 12)) assert approx_equal( matrix.sqr(model.get_A()).inverse(), (10, 0, 0, 0, 11, 0, 0, 0, 12)) assert approx_equal(model.get_B(), model.get_A()) assert approx_equal(model.get_U(), (1, 0, 0, 0, 1, 0, 0, 0, 1)) assert approx_equal(model.get_real_space_vectors(), (real_space_a, real_space_b, real_space_c)) assert (model.get_crystal_symmetry().unit_cell().parameters() == model.get_unit_cell().parameters()) assert model.get_crystal_symmetry().space_group() == model.get_space_group( ) model2 = Crystal( real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group_symbol="P 1", ) assert model == model2 model2a = Crystal(model.get_A(), model.get_space_group()) assert model == model2a model2b = Crystal( matrix.sqr(model.get_A()).inverse().elems, model.get_space_group().type().lookup_symbol(), reciprocal=False, ) assert model == model2b # rotate 45 degrees about x-axis R1 = matrix.sqr(( 1, 0, 0, 0, math.cos(math.pi / 4), -math.sin(math.pi / 4), 0, math.sin(math.pi / 4), math.cos(math.pi / 4), )) # rotate 30 degrees about y-axis R2 = matrix.sqr(( math.cos(math.pi / 6), 0, math.sin(math.pi / 6), 0, 1, 0, -math.sin(math.pi / 6), 0, math.cos(math.pi / 6), )) # rotate 60 degrees about z-axis R3 = matrix.sqr(( math.cos(math.pi / 3), -math.sin(math.pi / 3), 0, math.sin(math.pi / 3), math.cos(math.pi / 3), 0, 0, 0, 1, )) R = R1 * R2 * R3 model.set_U(R) # B is unchanged assert approx_equal(model.get_B(), (1 / 10, 0, 0, 0, 1 / 11, 0, 0, 0, 1 / 12)) assert approx_equal(model.get_U(), R) assert approx_equal(model.get_A(), matrix.sqr(model.get_U()) * matrix.sqr(model.get_B())) a_, b_, c_ = model.get_real_space_vectors() assert approx_equal(a_, R * real_space_a) assert approx_equal(b_, R * real_space_b) assert approx_equal(c_, R * real_space_c) assert (str(model).replace("-0.0000", " 0.0000") == """\ Crystal: Unit cell: (10.000, 11.000, 12.000, 90.000, 90.000, 90.000) Space group: P 1 U matrix: {{ 0.4330, -0.7500, 0.5000}, { 0.7891, 0.0474, -0.6124}, { 0.4356, 0.6597, 0.6124}} B matrix: {{ 0.1000, 0.0000, 0.0000}, { 0.0000, 0.0909, 0.0000}, { 0.0000, 0.0000, 0.0833}} A = UB: {{ 0.0433, -0.0682, 0.0417}, { 0.0789, 0.0043, -0.0510}, { 0.0436, 0.0600, 0.0510}} """) model.set_B((1 / 12, 0, 0, 0, 1 / 12, 0, 0, 0, 1 / 12)) assert approx_equal(model.get_unit_cell().parameters(), (12, 12, 12, 90, 90, 90)) U = matrix.sqr((0.3455, -0.2589, -0.9020, 0.8914, 0.3909, 0.2293, 0.2933, -0.8833, 0.3658)) B = matrix.sqr((1 / 13, 0, 0, 0, 1 / 13, 0, 0, 0, 1 / 13)) model.set_A(U * B) assert approx_equal(model.get_A(), U * B) assert approx_equal(model.get_U(), U, 1e-4) assert approx_equal(model.get_B(), B, 1e-5) model3 = Crystal( real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group=sgtbx.space_group_info("P 222").group(), ) assert model3.get_space_group().type().hall_symbol() == " P 2 2" assert model != model3 # sgi_ref = sgtbx.space_group_info(number=230) model_ref = Crystal( real_space_a=(44, 0, 0), real_space_b=(0, 44, 0), real_space_c=(0, 0, 44), space_group=sgi_ref.group(), ) assert approx_equal(model_ref.get_U(), (1, 0, 0, 0, 1, 0, 0, 0, 1)) assert approx_equal(model_ref.get_B(), (1 / 44, 0, 0, 0, 1 / 44, 0, 0, 0, 1 / 44)) assert approx_equal(model_ref.get_A(), model_ref.get_B()) assert approx_equal(model_ref.get_unit_cell().parameters(), (44, 44, 44, 90, 90, 90)) a_ref, b_ref, c_ref = map(matrix.col, model_ref.get_real_space_vectors()) cb_op_to_primitive = sgi_ref.change_of_basis_op_to_primitive_setting() model_primitive = model_ref.change_basis(cb_op_to_primitive) cb_op_to_reference = (model_primitive.get_space_group().info(). change_of_basis_op_to_reference_setting()) a_prim, b_prim, c_prim = map(matrix.col, model_primitive.get_real_space_vectors()) assert (cb_op_to_primitive.as_abc() == "-1/2*a+1/2*b+1/2*c,1/2*a-1/2*b+1/2*c,1/2*a+1/2*b-1/2*c") assert approx_equal(a_prim, -1 / 2 * a_ref + 1 / 2 * b_ref + 1 / 2 * c_ref) assert approx_equal(b_prim, 1 / 2 * a_ref - 1 / 2 * b_ref + 1 / 2 * c_ref) assert approx_equal(c_prim, 1 / 2 * a_ref + 1 / 2 * b_ref - 1 / 2 * c_ref) assert cb_op_to_reference.as_abc() == "b+c,a+c,a+b" assert approx_equal(a_ref, b_prim + c_prim) assert approx_equal(b_ref, a_prim + c_prim) assert approx_equal(c_ref, a_prim + b_prim) assert approx_equal( model_primitive.get_U(), [ -0.5773502691896258, 0.40824829046386285, 0.7071067811865476, 0.5773502691896257, -0.4082482904638631, 0.7071067811865476, 0.5773502691896257, 0.8164965809277259, 0.0, ], ) assert approx_equal( model_primitive.get_B(), [ 0.0262431940540739, 0.0, 0.0, 0.00927837023781507, 0.02783511071344521, 0.0, 0.01607060866333063, 0.01607060866333063, 0.03214121732666125, ], ) assert approx_equal( model_primitive.get_A(), (0, 1 / 44, 1 / 44, 1 / 44, 0, 1 / 44, 1 / 44, 1 / 44, 0), ) assert approx_equal( model_primitive.get_unit_cell().parameters(), [ 38.1051177665153, 38.1051177665153, 38.1051177665153, 109.47122063449069, 109.47122063449069, 109.47122063449069, ], ) assert model_ref != model_primitive model_ref_recycled = model_primitive.change_basis(cb_op_to_reference) assert approx_equal(model_ref.get_U(), model_ref_recycled.get_U()) assert approx_equal(model_ref.get_B(), model_ref_recycled.get_B()) assert approx_equal(model_ref.get_A(), model_ref_recycled.get_A()) assert approx_equal( model_ref.get_unit_cell().parameters(), model_ref_recycled.get_unit_cell().parameters(), ) assert model_ref == model_ref_recycled uc = uctbx.unit_cell( (58.2567, 58.1264, 39.7093, 46.9077, 46.8612, 62.1055)) sg = sgtbx.space_group_info(symbol="P1").group() cs = crystal.symmetry(unit_cell=uc, space_group=sg) cb_op_to_minimum = cs.change_of_basis_op_to_minimum_cell() # the reciprocal matrix B = matrix.sqr(uc.fractionalization_matrix()).transpose() U = random_rotation() direct_matrix = (U * B).inverse() model = Crystal(direct_matrix[:3], direct_matrix[3:6], direct_matrix[6:9], space_group=sg) assert uc.is_similar_to(model.get_unit_cell()) uc_minimum = uc.change_basis(cb_op_to_minimum) model_minimum = model.change_basis(cb_op_to_minimum) assert uc_minimum.is_similar_to(model_minimum.get_unit_cell()) assert model_minimum != model model_minimum.update(model) assert model_minimum == model # lgtm A_static = matrix.sqr(model.get_A()) A_as_scan_points = [A_static] num_scan_points = 11 for i in range(num_scan_points - 1): A_as_scan_points.append( A_as_scan_points[-1] * matrix.sqr(euler_angles.xyz_matrix(0.1, 0.2, 0.3))) model.set_A_at_scan_points(A_as_scan_points) model_minimum = model.change_basis(cb_op_to_minimum) assert model.num_scan_points == model_minimum.num_scan_points == num_scan_points M = matrix.sqr(cb_op_to_minimum.c_inv().r().transpose().as_double()) M_inv = M.inverse() for i in range(num_scan_points): A_orig = matrix.sqr(model.get_A_at_scan_point(i)) A_min = matrix.sqr(model_minimum.get_A_at_scan_point(i)) assert approx_equal(A_min, A_orig * M_inv) assert model.get_unit_cell().parameters() == pytest.approx( (58.2567, 58.1264, 39.7093, 46.9077, 46.8612, 62.1055)) uc = uctbx.unit_cell((10, 11, 12, 91, 92, 93)) model.set_unit_cell(uc) assert model.get_unit_cell().parameters() == pytest.approx(uc.parameters())
def test_check_old_vs_new(): from dxtbx.tests.model.crystal_model_old import crystal_model_old model_1 = Crystal( real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group_symbol="P 1", ) model_2 = crystal_model_old( real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group_symbol="P 1", ) cov_B = matrix.sqr([1] * (9 * 9)) model_1.set_B_covariance(cov_B) model_2.set_B_covariance(cov_B) A_list = [model_1.get_A() for i in range(20)] model_1.set_A_at_scan_points(A_list) model_2.set_A_at_scan_points(A_list) A1 = model_1.get_A() A2 = model_2.get_A() U1 = model_1.get_U() U2 = model_2.get_U() B1 = model_1.get_B() B2 = model_2.get_B() UC1 = model_1.get_unit_cell() UC2 = model_2.get_unit_cell() RSV1 = model_1.get_real_space_vectors() RSV2 = model_2.get_real_space_vectors() SG1 = model_1.get_space_group() SG2 = model_2.get_space_group() assert model_1.num_scan_points == model_2.num_scan_points A_list_1 = [ model_1.get_A_at_scan_point(i) for i in range(model_1.get_num_scan_points()) ] A_list_2 = [ model_2.get_A_at_scan_point(i) for i in range(model_1.get_num_scan_points()) ] B_list_1 = [ model_1.get_B_at_scan_point(i) for i in range(model_1.get_num_scan_points()) ] B_list_2 = [ model_2.get_B_at_scan_point(i) for i in range(model_1.get_num_scan_points()) ] U_list_1 = [ model_1.get_U_at_scan_point(i) for i in range(model_1.get_num_scan_points()) ] U_list_2 = [ model_2.get_U_at_scan_point(i) for i in range(model_1.get_num_scan_points()) ] assert approx_equal(A1, A2) assert approx_equal(B1, B2) assert approx_equal(U1, U2) assert approx_equal(UC1.parameters(), UC2.parameters()) assert approx_equal(RSV1[0], RSV2[0]) assert approx_equal(RSV1[1], RSV2[1]) assert approx_equal(RSV1[2], RSV2[2]) assert str(SG1.info()) == str(SG2.info()) for i in range(model_1.get_num_scan_points()): assert approx_equal(A_list_1[i], A_list_2[i]) assert approx_equal(B_list_1[i], B_list_2[i]) assert approx_equal(U_list_1[i], U_list_2[i]) cell_sd_1 = model_1.get_cell_parameter_sd() cell_sd_2 = model_2.get_cell_parameter_sd() cell_volume_sd_1 = model_1.get_cell_volume_sd() cell_volume_sd_2 = model_2.get_cell_volume_sd() covB1 = model_1.get_B_covariance() covB2 = model_1.get_B_covariance() assert approx_equal(covB1, covB2) assert approx_equal(cell_volume_sd_1, cell_volume_sd_2) assert approx_equal(cell_sd_1, cell_sd_2)
def load_crystal(entry): from cctbx import uctbx from dxtbx.model import Crystal from scitbx.array_family import flex # Get the sample nx_sample = get_nx_sample(entry, "sample") # Set the space group space_group_symbol = nx_sample["unit_cell_group"][()] # Get depends on if nx_sample["depends_on"][()] != ".": assert nx_sample["depends_on"][()] == str( nx_sample["transformations/phi"].name) # Read the average unit cell data average_unit_cell = flex.double(np.array(nx_sample["average_unit_cell"])) assert nx_sample["average_unit_cell"].attrs["angles_units"] == "deg" assert nx_sample["average_unit_cell"].attrs["length_units"] == "angstrom" assert len(average_unit_cell.all()) == 1 assert len(average_unit_cell) == 6 average_orientation_matrix = flex.double( np.array(nx_sample["average_orientation_matrix"])) assert len(average_orientation_matrix.all()) == 2 assert average_orientation_matrix.all()[0] == 3 assert average_orientation_matrix.all()[1] == 3 # Get the real space vectors uc = uctbx.unit_cell(tuple(average_unit_cell)) U = matrix.sqr(average_orientation_matrix) B = matrix.sqr(uc.fractionalization_matrix()).transpose() A = U * B A = A.inverse() real_space_a = A[0:3] real_space_b = A[3:6] real_space_c = A[6:9] # Read the unit cell data unit_cell = flex.double(np.array(nx_sample["unit_cell"])) assert nx_sample["unit_cell"].attrs["angles_units"] == "deg" assert nx_sample["unit_cell"].attrs["length_units"] == "angstrom" # Read the orientation matrix orientation_matrix = flex.double(np.array(nx_sample["orientation_matrix"])) assert len(unit_cell.all()) == 2 assert len(orientation_matrix.all()) == 3 assert unit_cell.all()[0] == orientation_matrix.all()[0] assert unit_cell.all()[1] == 6 assert orientation_matrix.all()[1] == 3 assert orientation_matrix.all()[2] == 3 # Construct the crystal model crystal = Crystal(real_space_a, real_space_b, real_space_c, space_group_symbol) # Sort out scan points if unit_cell.all()[0] > 1: A_list = [] for i in range(unit_cell.all()[0]): uc = uctbx.unit_cell(tuple(unit_cell[i:i + 1, :])) U = matrix.sqr(tuple(orientation_matrix[i:i + 1, :, :])) B = matrix.sqr(uc.fractionalization_matrix()).transpose() A_list.append(U * B) crystal.set_A_at_scan_points(A_list) else: assert unit_cell.all_eq(average_unit_cell) assert orientation_matrix.all_eq(average_orientation_matrix) # Return the crystal return crystal
def run(args): import libtbx.load_env from dials.util import Sorry usage = "dials.reindex [options] indexed.expt indexed.refl" 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 if params.change_of_basis_op is None: raise Sorry("Please provide a change_of_basis_op.") reference_crystal = None if params.reference.experiments is not None: from dxtbx.serialize import load reference_experiments = load.experiment_list( params.reference.experiments, check_format=False) assert len(reference_experiments.crystals()) == 1 reference_crystal = reference_experiments.crystals()[0] if params.reference.reflections is not None: # First check that we have everything as expected for the reference reindexing # Currently only supports reindexing one dataset at a time if params.reference.experiments is None: raise Sorry( """For reindexing against a reference dataset, a reference experiments file must also be specified with the option: reference= """) if not os.path.exists(params.reference.reflections): raise Sorry("Could not locate reference dataset reflection file") if len(experiments) != 1 or len(reflections) != 1: raise Sorry( "Only one dataset can be reindexed to a reference at a time") reference_reflections = flex.reflection_table().from_file( params.reference.reflections) test_reflections = reflections[0] if (reference_crystal.get_space_group().type().number() != experiments.crystals()[0].get_space_group().type().number()): raise Sorry("Space group of input does not match reference") # Set some flags to allow filtering, if wanting to reindex against # reference with data that has not yet been through integration if (test_reflections.get_flags( test_reflections.flags.integrated_sum).count(True) == 0): assert ( "intensity.sum.value" in test_reflections), "No 'intensity.sum.value' in reflections" test_reflections.set_flags( flex.bool(test_reflections.size(), True), test_reflections.flags.integrated_sum, ) if (reference_reflections.get_flags( reference_reflections.flags.integrated_sum).count(True) == 0): assert ("intensity.sum.value" in test_reflections ), "No 'intensity.sum.value in reference reflections" reference_reflections.set_flags( flex.bool(reference_reflections.size(), True), reference_reflections.flags.integrated_sum, ) # Make miller array of the two datasets try: test_miller_set = filtered_arrays_from_experiments_reflections( experiments, [test_reflections])[0] except ValueError: raise Sorry( "No reflections remain after filtering the test dataset") try: reference_miller_set = filtered_arrays_from_experiments_reflections( reference_experiments, [reference_reflections])[0] except ValueError: raise Sorry( "No reflections remain after filtering the reference dataset") from dials.algorithms.symmetry.reindex_to_reference import ( determine_reindex_operator_against_reference, ) change_of_basis_op = determine_reindex_operator_against_reference( test_miller_set, reference_miller_set) elif len(experiments) and params.change_of_basis_op is libtbx.Auto: if reference_crystal is not None: if len(experiments.crystals()) > 1: raise Sorry("Only one crystal can be processed at a time") from dials.algorithms.indexing.compare_orientation_matrices import ( difference_rotation_matrix_axis_angle, ) cryst = experiments.crystals()[0] R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle( 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( "Rotation of %.3f degrees" % angle, "about axis (%.3f, %.3f, %.3f)" % axis, ) elif len(reflections): assert len(reflections) == 1 # always re-map reflections to reciprocal space 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 = reflections[0].select(sel) refl.centroid_px_to_mm(imageset.get_detector(), imageset.get_scan()) refl.map_centroids_to_reciprocal_space( 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) index = AssignIndicesGlobal(tolerance=0.2) index(refl_copy, experiments) 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): for crystal in experiments.crystals(): cryst_orig = copy.deepcopy(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() A_varying = [ cryst_reindexed.get_A_at_scan_point(i) for i in range(cryst_reindexed.num_scan_points) ] cryst_reindexed = Crystal( a, b, c, space_group=params.space_group.group()) cryst_reindexed.set_A_at_scan_points(A_varying) 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) experiments.as_file(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 load_crystal(entry): from dxtbx.model import Crystal from scitbx.array_family import flex from scitbx import matrix from cctbx import uctbx import numpy # Get the sample nx_sample = get_nx_sample(entry, "sample") # Set the space group space_group_symbol = nx_sample['unit_cell_group'].value # Get depends on if nx_sample['depends_on'].value != '.': assert (nx_sample['depends_on'].value == str( nx_sample['transformations/phi'].name)) # Read the average unit cell data average_unit_cell = flex.double(numpy.array( nx_sample['average_unit_cell'])) assert (nx_sample['average_unit_cell'].attrs['angles_units'] == 'deg') assert (nx_sample['average_unit_cell'].attrs['length_units'] == 'angstrom') assert (len(average_unit_cell.all()) == 1) assert (len(average_unit_cell) == 6) average_orientation_matrix = flex.double( numpy.array(nx_sample['average_orientation_matrix'])) assert (len(average_orientation_matrix.all()) == 2) assert (average_orientation_matrix.all()[0] == 3) assert (average_orientation_matrix.all()[1] == 3) # Get the real space vectors uc = uctbx.unit_cell(tuple(average_unit_cell)) U = matrix.sqr(average_orientation_matrix) B = matrix.sqr(uc.fractionalization_matrix()).transpose() A = U * B A = A.inverse() real_space_a = A[0:3] real_space_b = A[3:6] real_space_c = A[6:9] # Read the unit cell data unit_cell = flex.double(numpy.array(nx_sample['unit_cell'])) assert (nx_sample['unit_cell'].attrs['angles_units'] == 'deg') assert (nx_sample['unit_cell'].attrs['length_units'] == 'angstrom') # Read the orientation matrix orientation_matrix = flex.double( numpy.array(nx_sample['orientation_matrix'])) assert (len(unit_cell.all()) == 2) assert (len(orientation_matrix.all()) == 3) assert (unit_cell.all()[0] == orientation_matrix.all()[0]) assert (unit_cell.all()[1] == 6) assert (orientation_matrix.all()[1] == 3) assert (orientation_matrix.all()[2] == 3) # Construct the crystal model crystal = Crystal(real_space_a, real_space_b, real_space_c, space_group_symbol) # Sort out scan points if unit_cell.all()[0] > 1: A_list = [] for i in range(unit_cell.all()[0]): uc = uctbx.unit_cell(tuple(unit_cell[i:i + 1, :])) U = matrix.sqr(tuple(orientation_matrix[i:i + 1, :, :])) B = matrix.sqr(uc.fractionalization_matrix()).transpose() A_list.append(U * B) crystal.set_A_at_scan_points(A_list) else: assert (unit_cell.all_eq(average_unit_cell)) assert (orientation_matrix.all_eq(average_orientation_matrix)) # Return the crystal return crystal
def from_dict(d): ''' Convert the dictionary to a crystal model Params: d The dictionary of parameters Returns: The crystal model ''' from dxtbx.model import Crystal # If None, return None if d is None: return None # Check the version and id if str(d['__id__']) != "crystal": raise ValueError("\"__id__\" does not equal \"crystal\"") # Extract from the dictionary real_space_a = d['real_space_a'] real_space_b = d['real_space_b'] real_space_c = d['real_space_c'] # str required to force unicode to ascii conversion space_group = str("Hall:" + d['space_group_hall_symbol']) xl = Crystal(real_space_a, real_space_b, real_space_c, space_group_symbol=space_group) # New parameters for maximum likelihood values try: xl._ML_half_mosaicity_deg = d['ML_half_mosaicity_deg'] except KeyError: pass try: xl._ML_domain_size_ang = d['ML_domain_size_ang'] except KeyError: pass # Isoforms used for stills try: xl.identified_isoform = d['identified_isoform'] except KeyError: pass # Extract scan point setting matrices, if present try: A_at_scan_points = d['A_at_scan_points'] xl.set_A_at_scan_points(A_at_scan_points) except KeyError: pass # Extract covariance of B, if present try: cov_B = d['B_covariance'] xl.set_B_covariance(cov_B) except KeyError: pass # Extract mosaicity, if present try: mosaicity = d['mosaicity'] xl.set_mosaicity(mosaicity) except KeyError: pass return xl