Exemplo n.º 1
0
def test_stereochem():
    parser = SmilesParser()
    parser.parse_smiles('N[C@](Br)(O)C')
    parser_coords = [atom.coord for atom in parser.atoms][:5]
    desired_coords = [[1.26597, 0.60740, -0.09729],
                      [-0.26307, 0.59858, -0.07141],
                      [-0.91282, 2.25811, 0.01409],
                      [-0.72365, -0.12709, 1.01313],
                      [-0.64392, 0.13084, -1.00380]]
    assert calc_rmsd(parser_coords, desired_coords) < 0.5

    parser = SmilesParser()
    parser.parse_smiles('N[C@@H](Br)(O)')
    parser_coords = [atom.coord
                     for atom in parser.atoms][:4] + [parser.atoms[6].coord]
    desired_coords = [[1.26597, 0.60740, -0.09729],
                      [-0.26307, 0.59858, -0.07141],
                      [-0.72365, -0.12709, 1.01313],
                      [-0.91282, 2.25811, 0.01409],
                      [-0.64392, 0.13084, -1.00380]]
    assert calc_rmsd(parser_coords, desired_coords) < 0.5

    parser = SmilesParser()
    parser.parse_smiles('F/C=C/F')
    parser_coords = [atom.coord for atom in parser.atoms]
    desired_coords = [[-4.14679, 1.36072, 0.92663],
                      [-3.58807, 1.44785, -0.00000],
                      [-2.26409, 1.31952, 0.00000],
                      [-1.70538, 1.40665, -0.92663],
                      [-4.11965, 1.64066, -0.92663],
                      [-1.73251, 1.12671, 0.92663]]
    assert calc_rmsd(parser_coords, desired_coords) < 0.5
Exemplo n.º 2
0
def test_calc_rmsd():

    atoms = [
        Atom('C', 0.0009, 0.0041, -0.0202),
        Atom('H', -0.6577, -0.8481, -0.3214),
        Atom('H', -0.4585, 0.9752, -0.3061),
        Atom('H', 0.0853, -0.0253, 1.0804),
        Atom('H', 1.0300, -0.1058, -0.4327)
    ]

    atoms_rot = [
        Atom('C', -0.0009, -0.0041, -0.0202),
        Atom('H', 0.6577, 0.8481, -0.3214),
        Atom('H', 0.4585, -0.9752, -0.3061),
        Atom('H', -0.0853, 0.0253, 1.0804),
        Atom('H', -1.0300, 0.1058, -0.4327)
    ]

    coords1 = np.array([atom.coord for atom in atoms])
    coords2 = np.array([atom.coord for atom in atoms_rot])

    # Rotated coordinates should have almost 0 RMSD between them
    assert geom.calc_rmsd(coords1, coords2) < 1E-5

    # Coordinates need to have the same shape to calculate the RMSD
    with pytest.raises(AssertionError):
        _ = geom.calc_rmsd(coords1, coords2[1:])

    assert geom.calc_heavy_atom_rmsd(atoms, atoms_rot) < 1E-5

    # Permuting two hydrogens should generate a larger RMSD
    atoms_rot[2], atoms_rot[3] = atoms_rot[3], atoms_rot[2]
    rmsd = geom.calc_rmsd(coords1=np.array([atom.coord for atom in atoms]),
                          coords2=np.array([atom.coord for atom in atoms_rot]))

    assert rmsd > 0.1

    # While the heavy atom RMSD should remain unchanged
    assert geom.calc_heavy_atom_rmsd(atoms, atoms_rot) < 1E-6
Exemplo n.º 3
0
def test_chiral_rotation(tmpdir):
    os.chdir(tmpdir)

    chiral_ethane = Molecule(name='chiral_ethane',
                             charge=0,
                             mult=1,
                             atoms=[
                                 Atom('C', -0.26307, 0.59858, -0.07141),
                                 Atom('C', 1.26597, 0.60740, -0.09729),
                                 Atom('Cl', -0.91282, 2.25811, 0.01409),
                                 Atom('F', -0.72365, -0.12709, 1.01313),
                                 Atom('H', -0.64392, 0.13084, -1.00380),
                                 Atom('Cl', 1.93888, 1.31880, 1.39553),
                                 Atom('H', 1.61975, 1.19877, -0.96823),
                                 Atom('Br', 1.94229, -1.20011, -0.28203)
                             ])

    chiral_ethane.graph.nodes[0]['stereo'] = True
    chiral_ethane.graph.nodes[1]['stereo'] = True

    atoms = conf_gen.get_simanl_atoms(chiral_ethane)
    regen = Molecule(name='regenerated_ethane', charge=0, mult=1, atoms=atoms)

    regen_coords = regen.get_coordinates()
    coords = chiral_ethane.get_coordinates()

    # Atom indexes of the C(C)(Cl)(F)(H) chiral centre
    ccclfh = [0, 1, 2, 3, 4]

    # Atom indexes of the C(C)(Cl)(Br)(H) chiral centre
    ccclbrh = [1, 0, 5, 7, 6]

    for centre_idxs in [ccclfh, ccclbrh]:
        # Ensure the fragmented centres map almost identically
        # if calc_rmsd(template_coords=coords[centre_idxs], coords_to_
        # fit=regen_coords[centre_idxs]) > 0.5:
        #     chiral_ethane.print_xyz_file(filename=os.path.join(here,
        # 'chiral_ethane.xyz'))
        #     regen.print_xyz_file(filename=os.path.join(here, 'regen.xyz'))

        # RMSD on the 5 atoms should be < 0.5 Å
        assert calc_rmsd(coords1=coords[centre_idxs],
                         coords2=regen_coords[centre_idxs]) < 0.5

    os.chdir(here)
Exemplo n.º 4
0
def get_and_copy_unique_confs(xyz_filenames, only_heavy_atoms, threshold_rmsd):
    """For each xyz file generate a species and copy it to a folder if it is
    unique based on an RMSD threshold"""

    molecules = [
        Species(name=fn.rstrip('.xyz'),
                atoms=xyz_file_to_atoms(fn),
                charge=0,
                mult=1) for fn in xyz_filenames
    ]

    if only_heavy_atoms:
        molecules = get_molecules_no_hydrogens(molecules)

    unique_mol_ids = []

    for i in range(len(molecules)):
        mol = molecules[i]

        is_unique = True

        for j in unique_mol_ids:
            rmsd = calc_rmsd(coords1=mol.get_coordinates(),
                             coords2=molecules[j].get_coordinates())

            if rmsd < threshold_rmsd:
                is_unique = False
                break

        if is_unique:
            unique_mol_ids.append(i)

    print('Number of unique molecules = ', len(unique_mol_ids))

    # Copy all the unique .xyz files to a new folder
    if not os.path.exists(folder_name):
        os.mkdir(folder_name)

    for i in unique_mol_ids:
        xyz_filename = xyz_filenames[i]
        copyfile(xyz_filename, os.path.join(folder_name, xyz_filename))

    return None