def exercise_similarity(): 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_1.set_mosaicity(0.5) model_2 = 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.set_mosaicity(0.5) assert model_1.is_similar_to(model_2) model_1.set_mosaicity(-1) model_2.set_mosaicity(-0.5) assert model_1.is_similar_to(model_2) # test ignores negative mosaicity model_1.set_mosaicity(0.5) model_2.set_mosaicity(0.63) # outside tolerance assert not model_1.is_similar_to(model_2) model_2.set_mosaicity(0.62) #just inside tolerance # orientation tests R = matrix.sqr(model_2.get_U()) dr1 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0101, deg=True) dr2 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0099, deg=True) model_2.set_U(dr1 * R) assert not model_1.is_similar_to(model_2) # outside tolerance model_2.set_U(dr2 * R) assert model_1.is_similar_to(model_2) # inside tolerance # unit_cell.is_similar_to is tested elsewhere return
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())
class Simulation(object): def __init__(self, override_fdp=None): # Set up detector distance = 100 pixel_size = 0.1 image_size = (1000, 1000) beam_centre_mm = ( pixel_size * image_size[0] / 2, pixel_size * image_size[1] / 2, ) self.detector = DetectorFactory().simple( "CCD", distance, beam_centre_mm, "+x", "-y", (pixel_size, pixel_size), image_size, ) # Set up beam self.beam = BeamFactory().simple(wavelength=1) # Set up scan sequence_width = 90.0 osc_start = 0.0 image_width = 0.2 oscillation = (osc_start, image_width) nframes = int(math.ceil(sequence_width / image_width)) image_range = (1, nframes) exposure_times = 0.0 epochs = [0] * nframes self.scan = ScanFactory().make_scan( image_range, exposure_times, oscillation, epochs, deg=True ) # Set up goniometer self.goniometer = GoniometerFactory.known_axis(self.detector[0].get_fast_axis()) # Set up simulated structure factors self.sfall = self.fcalc_from_pdb( resolution=1.6, algorithm="direct", override_fdp=override_fdp ) # Set up crystal self.crystal = Crystal( real_space_a=(50, 0, 0), real_space_b=(0, 60, 0), real_space_c=(0, 0, 70), space_group_symbol="P1", ) axis = matrix.col( elems=(-0.14480368275412925, -0.6202131724405818, -0.7709523423610766) ) self.crystal.set_U( axis.axis_and_angle_as_r3_rotation_matrix(angle=0.625126343998969) ) def fcalc_from_pdb(self, resolution, algorithm=None, override_fdp=None): pdb_inp = pdb.input(source_info=None, lines=_pdb_lines) xray_structure = pdb_inp.xray_structure_simple() wavelength = self.beam.get_wavelength() # # take a detour to calculate anomalous contribution of every atom scatterers = xray_structure.scatterers() for sc in scatterers: expected_henke = henke.table(sc.element_symbol()).at_angstrom(wavelength) sc.fp = expected_henke.fp() sc.fdp = override_fdp if override_fdp is not None else expected_henke.fdp() # how do we do bulk solvent? primitive_xray_structure = xray_structure.primitive_setting() P1_primitive_xray_structure = primitive_xray_structure.expand_to_p1() fcalc = P1_primitive_xray_structure.structure_factors( d_min=resolution, anomalous_flag=True, algorithm=algorithm ).f_calc() return fcalc.amplitudes() def set_varying_beam(self, along="fast", npixels_drift=5): assert along in ["fast", "slow", "both"] num_scan_points = self.scan.get_num_images() + 1 s0 = matrix.col(self.beam.get_s0()) beam_centre_px = self.detector[0].get_beam_centre_px(s0) if along == "fast": start_beam_centre = ( beam_centre_px[0] - npixels_drift / 2, beam_centre_px[1], ) end_beam_centre = (beam_centre_px[0] + npixels_drift / 2, beam_centre_px[1]) elif along == "slow": start_beam_centre = ( beam_centre_px[0], beam_centre_px[1] - npixels_drift / 2, ) end_beam_centre = (beam_centre_px[0], beam_centre_px[1] + npixels_drift / 2) elif along == "both": offset = math.sqrt(2.0) * npixels_drift / 4.0 start_beam_centre = (beam_centre_px[0] - offset, beam_centre_px[1] - offset) end_beam_centre = (beam_centre_px[0] + offset, beam_centre_px[1] + offset) start_lab = matrix.col(self.detector[0].get_pixel_lab_coord(start_beam_centre)) end_lab = matrix.col(self.detector[0].get_pixel_lab_coord(end_beam_centre)) axis = start_lab.cross(end_lab).normalize() full_angle = start_lab.angle(end_lab) angle_step = full_angle / self.scan.get_num_images() angles = [e * angle_step for e in range(num_scan_points)] start_s0 = start_lab.normalize() * s0.length() s0_list = [start_s0.rotate_around_origin(axis=axis, angle=e) for e in angles] self.beam.set_s0_at_scan_points(s0_list)