def test_replace_pattern_in_structure__replace_hydrogens_in_octane_with_fluorines_half_the_time(octane): search_pattern = Atoms(elements='H', positions=[(0, 0, 0)]) replace_pattern = Atoms(elements='F', positions=[(0, 0, 0)]) match_indices = find_pattern_in_structure(octane, search_pattern) final_structure = replace_pattern_in_structure(octane, search_pattern, replace_pattern, replace_fraction=0.5) assert Counter(final_structure.elements) == {"H":9, "F": 9, "C": 8} assert_structure_positions_are_unchanged(octane, final_structure)
def test_replace_pattern_in_structure__replacement_pattern_across_pbc_gets_coordinates_within_unit_cell(): structure = Atoms(elements='CNNF', positions=[(9.1, 0., 0), (0.1, 0., 0), (1.1, 0., 0.), (2.1, 0., 0.)], cell=10*np.identity(3)) search_pattern = Atoms(elements='CN', positions=[(0., 0., 0), (1.0, 0., 0.)]) replace_pattern = search_pattern final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern) assert Counter(final_structure.elements) == Counter(structure.elements) assert_structure_positions_are_unchanged(structure, final_structure)
def test_replace_pattern_in_structure__two_points_on_x_axis_positions_are_unchanged(): structure = Atoms(elements='CNNC', positions=[(0., 0., 0), (1.0, 0., 0.), (2.0, 0., 0.), (3.0, 0., 0.)], cell=100*np.identity(3)) search_pattern = Atoms(elements='NN', positions=[(0.0, 0., 0), (1.0, 0., 0.)]) replace_pattern = Atoms(elements='FF', positions=[(0., 0., 0), (1.0, 0., 0.)]) final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern) assert Counter(final_structure.elements) == {"C":2, "F": 2} assert_structure_positions_are_unchanged(structure, final_structure)
def test_replace_pattern_in_structure__replace_CH3_in_octane_with_CH3(octane): search_pattern = Atoms(elements='CHHH', positions=[(0, 0, 0), (-0.538, -0.635, 0.672), (-0.397, 0.993, 0.052), (-0.099, -0.371, -0.998)]) replace_pattern = Atoms(elements='CHHH', positions=search_pattern.positions) final_structure = replace_pattern_in_structure(octane, search_pattern, replace_pattern) assert Counter(final_structure.elements) == {"C": 8, "H": 18} # note the positions are not EXACTLY the same because the original structure has slightly # different coordinates for the two CH3 groups! assert_structure_positions_are_unchanged(octane, final_structure, max_delta=0.1)
def test_replace_pattern_in_structure__replace_no_bonds_linker_with_linker_with_bonds_angles_has_bonds_angles(uio66_linker_no_bonds, uio66_linker_some_bonds): structure = uio66_linker_no_bonds.copy() structure.cell = 100*np.identity(3) final_structure = replace_pattern_in_structure(structure, uio66_linker_no_bonds, uio66_linker_some_bonds, axis1a_idx=0, axis1b_idx=15) assert Counter(final_structure.elements) == {'C': 8, 'O': 4, 'H': 4} assert_structure_positions_are_unchanged(structure, final_structure, max_delta=0.1) assert_topo(final_structure.dihedrals, uio66_linker_some_bonds.dihedrals, final_structure.dihedral_types, uio66_linker_some_bonds.dihedral_types, final_structure.dihedral_type_coeffs, uio66_linker_some_bonds.dihedral_type_coeffs)
def test_replace_pattern_in_structure__special2_rotated_pattern_replaced_with_itself_does_not_change_positions(): search_pattern = Atoms(elements='CCH', positions=[(0., 0., 0.), (4., 0., 0.),(0., 1., 0.)]) replace_pattern = Atoms(elements='FFHe', positions=search_pattern.positions) structure = search_pattern.copy() structure.cell = 15 * np.identity(3) r = R.from_quat([ 0.02814096, 0.99766676, 0.03984918, -0.04776152]) structure.positions = r.apply(structure.positions) structure.positions = structure.positions % 15 final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern, axis1a_idx=0, axis1b_idx=1) assert_structure_positions_are_unchanged(structure, final_structure)
def test_replace_pattern_in_structure__special_rotated_pattern_replaced_with_itself_does_not_change_positions(): search_pattern = Atoms(elements='CCH', positions=[(0., 0., 0.), (4., 0., 0.),(0., 1., 0.)]) replace_pattern = Atoms(elements='FFHe', positions=search_pattern.positions) structure = search_pattern.copy() structure.cell = [15] * np.identity(3) r = R.from_quat([-0.4480244, -0.50992783, 0.03212454, -0.7336319 ]) structure.positions = r.apply(structure.positions) structure.positions = structure.positions % 15 final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern, axis1a_idx=0, axis1b_idx=1) assert_structure_positions_are_unchanged(structure, final_structure)
def test_replace_pattern_in_structure__pattern_and_reverse_pattern_on_x_axis_positions_are_unchanged(): structure = Atoms(elements='HHCCCHH', positions=[(-1., 1, 0), (-1., -1, 0), (0., 0., 0), (1., 0., 0.), (3., 0., 0.), (4., 1, 0), (4., -1, 0)], cell=7*np.identity(3)) structure.translate([2, 2, 0.1]) search_pattern = Atoms(elements='HHC', positions=[(0., 1, 0), (0., -1, 0), (1., 0., 0.)]) replace_pattern = Atoms(elements='HHC', positions=[(0., 1, 0), (0., -1, 0), (1., 0., 0.)]) final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern) assert Counter(final_structure.elements) == {"C":3, "H": 4} assert_structure_positions_are_unchanged(structure, final_structure)
def test_replace_pattern_in_structure__three_points_on_x_axis_positions_are_unchanged(): # this test exists to verify that for a search pattern with more than 2 atoms where all atoms lie on the same axis # there are no errors, since there is an extra unnecessary quaternion calcuation to orient the replacement pattern # into the final position structure = Atoms(elements='CNNNC', positions=[(0., 0., 0), (1., 0., 0.), (2., 0., 0.), (3., 0., 0.), (4., 0., 0.)], cell=100*np.identity(3)) search_pattern = Atoms(elements='NNN', positions=[(0., 0., 0), (1.0, 0., 0.), (2.0, 0., 0.)]) replace_pattern = Atoms(elements='FFF', positions=[(0., 0., 0), (1.0, 0., 0.), (2.0, 0., 0.)]) final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern) assert Counter(final_structure.elements) == {"C":2, "F": 3} assert_structure_positions_are_unchanged(structure, final_structure)
def test_atoms_replicate__triclinic_222_has_replicates_in_three_dims(): a = Atoms(elements="H", positions=[(1, 1, 1)], cell=np.array([[10, 0, 0], [10, 10, 0], [0, 0, 10]])) expected = Atoms(elements="HHHHHHHH", cell=np.array([[20, 0, 0], [20, 20, 0], [0, 0, 20]]), positions=[[1, 1, 1], [11, 1, 1], [11, 11, 1], [21, 11, 1], [1, 1, 11], [11, 1, 11], [11, 11, 11], [21, 11, 11]]) ra = a.replicate((2, 2, 2)) assert len(ra) == 8 assert_structure_positions_are_unchanged(ra, expected, verbose=True) assert np.array_equal(ra.cell, expected.cell)
def test_replace_pattern_in_structure__100_randomly_rotated_patterns_replaced_with_itself_does_not_change_positions(): search_pattern = Atoms(elements='CCH', positions=[(0., 0., 0.), (4., 0., 0.),(0., 1., 0.)]) replace_pattern = Atoms(elements='FFHe', positions=search_pattern.positions) structure = search_pattern.copy() structure.cell = 15 * np.identity(3) for _ in range(100): r = R.random(1) print("quat: ", r.as_quat()) structure.positions = r.apply(structure.positions) dp = np.random.random(3) * 15 print(dp) structure.translate(dp) structure.positions = structure.positions % 15 final_structure = replace_pattern_in_structure(structure, search_pattern, replace_pattern, axis1a_idx=0, axis1b_idx=1) assert_structure_positions_are_unchanged(structure, final_structure)
def test_replace_pattern_in_structure__in_hkust1_offset_replacing_benzene_with_benzene_does_not_change_positions(hkust1_cif, benzene): hkust1_cif.translate((-4,-4,-4)) hkust1_cif.positions = hkust1_cif.positions % np.diag(hkust1_cif.cell) final_structure = replace_pattern_in_structure(hkust1_cif, benzene, benzene, axis1a_idx=0, axis1b_idx=7) assert Counter(final_structure.elements) == Counter(hkust1_cif.elements) assert_structure_positions_are_unchanged(hkust1_cif, final_structure, max_delta=0.1)
def test_replace_pattern_in_structure__in_hkust1_replacing_benzene_with_benzene_does_not_change_positions(hkust1_cif, benzene): final_structure = replace_pattern_in_structure(hkust1_cif, benzene, benzene, axis1a_idx=0, axis1b_idx=7) assert Counter(final_structure.elements) == Counter(hkust1_cif.elements) assert_structure_positions_are_unchanged(hkust1_cif, final_structure, max_delta=0.1)
def test_replace_pattern_in_structure__replace_hydrogens_in_octane_with_hydrogens(octane): search_pattern = Atoms(elements='H', positions=[(0, 0, 0)]) replace_pattern = search_pattern final_structure = replace_pattern_in_structure(octane, search_pattern, replace_pattern) assert Counter(final_structure.elements) == {"H": 18, "C": 8} assert_structure_positions_are_unchanged(octane, final_structure)