示例#1
0
def test_rmsd():
    # pick one molecule from docked poses
    mols = list(
        oddt.toolkit.readfile(
            'sdf',
            os.path.join(test_data_dir, 'data/dude/xiap/actives_docked.sdf')))
    mols = list(filter(lambda x: x.title == '312335', mols))

    res = {
        'method=None': [
            4.7536, 2.5015, 2.7942, 1.1282, 0.7444, 1.6257, 4.7625, 2.7168,
            2.5504, 1.9304, 2.6201, 3.1742, 3.2254, 4.7785, 4.8035, 7.8963,
            2.2385, 4.8625, 3.2037
        ],
        'method=hungarian': [
            0.9013, 1.0730, 1.0531, 1.0286, 0.7353, 1.4094, 0.5391, 1.3297,
            1.0881, 1.7796, 2.6064, 3.1577, 3.2135, 0.8126, 1.2909, 2.5217,
            2.0836, 1.8325, 3.1874
        ],
        'method=min_symmetry': [
            0.9013, 1.0732, 1.0797, 1.0492, 0.7444, 1.6257, 0.5391, 1.5884,
            1.0935, 1.9304, 2.6201, 3.1742, 3.2254, 1.1513, 1.5206, 2.5361,
            2.2385, 1.971, 3.2037
        ],
    }

    kwargs_grid = [{
        'method': None
    }, {
        'method': 'hungarian'
    }, {
        'method': 'min_symmetry'
    }]
    for kwargs in kwargs_grid:
        res_key = '_'.join('%s=%s' % (k, v) for k, v in sorted(kwargs.items()))
        assert_array_almost_equal(
            [rmsd(mols[0], mol, **kwargs) for mol in mols[1:]],
            res[res_key],
            decimal=4)

    # test shuffled rmsd
    for _ in range(5):
        for kwargs in kwargs_grid:
            # dont use method=None in shuffled tests
            if kwargs['method'] is None:
                continue
            res_key = '_'.join('%s=%s' % (k, v)
                               for k, v in sorted(kwargs.items()))
            assert_array_almost_equal([
                rmsd(mols[0], shuffle_mol(mol), **kwargs) for mol in mols[1:]
            ],
                                      res[res_key],
                                      decimal=4)
示例#2
0
def test_rmsd_errors():
    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()
    mol.addh()
    mol2 = next(oddt.toolkit.readfile('sdf', os.path.join(test_data_dir, 'data/dude/xiap/actives_docked.sdf')))

    for method in [None, 'hungarian', 'min_symmetry']:
        with pytest.raises(ValueError, match='Unequal number of atoms'):
            rmsd(mol, mol2, method=method)

        for _ in range(5):
            with pytest.raises(ValueError, match='Unequal number of atoms'):
                rmsd(shuffle_mol(mol), shuffle_mol(mol2), method=method)
示例#3
0
def test_rmsd_errors():
    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()
    mol.addh()
    mol2 = next(
        oddt.toolkit.readfile(
            'sdf',
            os.path.join(test_data_dir, 'data/dude/xiap/actives_docked.sdf')))

    for method in [None, 'hungarian', 'min_symmetry']:
        with pytest.raises(ValueError, match='Unequal number of atoms'):
            rmsd(mol, mol2, method=method)

        for _ in range(5):
            with pytest.raises(ValueError, match='Unequal number of atoms'):
                rmsd(shuffle_mol(mol), shuffle_mol(mol2), method=method)
示例#4
0
def test_diverse_conformers():
    # FIXME: make toolkit a module so we can import from it
    diverse_conformers_generator = oddt.toolkit.diverse_conformers_generator

    mol = oddt.toolkit.readstring(
        "smi",
        "CN1CCN(S(=O)(C2=CC=C(OCC)C(C3=NC4=C(N(C)N=C4CCC)C(N3)=O)=C2)=O)CC1")
    mol.make3D()

    if oddt.toolkit.backend == 'ob' and oddt.toolkit.__version__ < '2.4.0':
        assert_raises(NotImplementedError, diverse_conformers_generator, mol)
        return None  # skip test for older OB

    res = []
    for conf in diverse_conformers_generator(mol, seed=123456):
        res.append(rmsd(mol, conf))

    assert_equal(len(res), 10)
    if oddt.toolkit.backend == 'ob':
        assert_array_almost_equal(res, [
            0., 3.043712, 3.897143, 3.289482, 3.066374, 2.909683, 2.913927,
            3.488244, 3.70603, 3.597467
        ])
    # else:
    #     if oddt.toolkit.__version__ > '2016.03.9':
    #         assert_array_almost_equal(res, [1.237538, 2.346984, 0.900624,
    #                                         3.469511, 1.886213, 2.128909,
    #                                         2.852608, 1.312513, 1.291595,
    #                                         1.326843])
    #     else:
    #         assert_array_almost_equal(res, [3.08995, 2.846358, 3.021795,
    #                                         1.720319, 2.741972, 2.965332,
    #                                         2.925344, 2.930157, 2.934049,
    #                                         3.009545])

    # check all implemented methods
    if oddt.toolkit.backend == 'ob':
        methods = ['ga', 'confab']
    else:
        methods = ['dg', 'etkdg', 'kdg', 'etdg']
    for method in methods:
        assert_equal(
            len(
                diverse_conformers_generator(mol,
                                             seed=123456,
                                             n_conf=5,
                                             method=method)), 5)
        assert_equal(
            len(
                diverse_conformers_generator(mol,
                                             seed=123456,
                                             n_conf=10,
                                             method=method)), 10)
        assert_equal(
            len(
                diverse_conformers_generator(mol,
                                             seed=123456,
                                             n_conf=20,
                                             method=method)), 20)
示例#5
0
def test_spatial():
    """Test spatial misc computations"""
    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()
    mol2 = mol.clone
    # Test rotation
    assert_almost_equal(mol2.coords, rotate(mol2.coords, np.pi, np.pi, np.pi))

    # Rotate perpendicular to ring
    mol2.coords = rotate(mol2.coords, 0, 0, np.pi)

    # RMSD
    assert_almost_equal(rmsd(mol, mol2, method=None), 2.77, decimal=1)
    # Hungarian must be close to zero (RDKit is 0.3)
    assert_almost_equal(rmsd(mol, mol2, method='hungarian'), 0, decimal=0)
    # Minimized by symetry must close to zero
    assert_almost_equal(rmsd(mol, mol2, method='min_symmetry'), 0, decimal=0)
示例#6
0
def test_spatial():
    """Test spatial misc computations"""
    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()
    mol2 = mol.clone
    # Test rotation
    assert_almost_equal(mol2.coords, rotate(mol2.coords, np.pi, np.pi, np.pi))

    # Rotate perpendicular to ring
    mol2.coords = rotate(mol2.coords, 0, 0, np.pi)

    # RMSD
    assert_almost_equal(rmsd(mol, mol2, method=None), 2.77, decimal=1)
    # Hungarian must be close to zero (RDKit is 0.3)
    assert_almost_equal(rmsd(mol, mol2, method='hungarian'), 0, decimal=0)
    # Minimized by symetry must close to zero
    assert_almost_equal(rmsd(mol, mol2, method='min_symmetry'), 0, decimal=0)
示例#7
0
def test_diverse_conformers():
    # FIXME: make toolkit a module so we can import from it
    diverse_conformers_generator = oddt.toolkit.diverse_conformers_generator

    mol = oddt.toolkit.readstring(
        'smi',
        'CN1CCN(S(=O)(C2=CC=C(OCC)C(C3=NC4=C(N(C)N=C4CCC)C(N3)=O)=C2)=O)CC1')
    mol.make3D()

    res = []
    for conf in diverse_conformers_generator(mol, seed=123456):
        res.append(rmsd(mol, conf))

    assert len(res) == 10
    if oddt.toolkit.backend == 'ob':
        if oddt.toolkit.__version__ < '0.3':
            assert_array_almost_equal(res, [
                0., 3.043712, 3.897143, 3.289482, 3.066374, 2.909683, 2.913927,
                3.488244, 3.70603, 3.597467
            ])
        else:
            assert_array_almost_equal(res, [
                0.0, 1.372770, 2.489789, 2.759941, 2.968366, 3.228773,
                3.392191, 3.921166, 3.185065, 3.283915
            ])
    # else:
    #     if oddt.toolkit.__version__ > '2016.03.9':
    #         assert_array_almost_equal(res, [1.237538, 2.346984, 0.900624,
    #                                         3.469511, 1.886213, 2.128909,
    #                                         2.852608, 1.312513, 1.291595,
    #                                         1.326843])
    #     else:
    #         assert_array_almost_equal(res, [3.08995, 2.846358, 3.021795,
    #                                         1.720319, 2.741972, 2.965332,
    #                                         2.925344, 2.930157, 2.934049,
    #                                         3.009545])

    # check all implemented methods
    if oddt.toolkit.backend == 'ob':
        methods = ['ga', 'confab']
    else:
        methods = ['dg', 'etkdg', 'kdg', 'etdg']
    for method in methods:
        assert len(
            diverse_conformers_generator(mol,
                                         seed=123456,
                                         n_conf=5,
                                         method=method)) == 5
        assert len(
            diverse_conformers_generator(mol,
                                         seed=123456,
                                         n_conf=10,
                                         method=method)) == 10
        assert len(
            diverse_conformers_generator(mol,
                                         seed=123456,
                                         n_conf=20,
                                         method=method)) == 20
示例#8
0
def test_rmsd():
    # pick one molecule from docked poses
    mols = list(oddt.toolkit.readfile('sdf', os.path.join(test_data_dir, 'data/dude/xiap/actives_docked.sdf')))
    mols = list(filter(lambda x: x.title == '312335', mols))

    res = {
        'method=None':
            [4.7536, 2.5015, 2.7942, 1.1282, 0.7444, 1.6257, 4.7625,
             2.7168, 2.5504, 1.9304, 2.6201, 3.1742, 3.2254, 4.7785,
             4.8035, 7.8963, 2.2385, 4.8625, 3.2037],
        'method=hungarian':
            [0.9013, 1.0730, 1.0531, 1.0286, 0.7353, 1.4094, 0.5391,
             1.3297, 1.0881, 1.7796, 2.6064, 3.1577, 3.2135, 0.8126,
             1.2909, 2.5217, 2.0836, 1.8325, 3.1874],
        'method=min_symmetry':
            [0.9013, 1.0732, 1.0797, 1.0492, 0.7444, 1.6257, 0.5391,
             1.5884, 1.0935, 1.9304, 2.6201, 3.1742, 3.2254, 1.1513,
             1.5206, 2.5361, 2.2385, 1.971, 3.2037],
        }

    kwargs_grid = [{'method': None},
                   {'method': 'hungarian'},
                   {'method': 'min_symmetry'}]
    for kwargs in kwargs_grid:
        res_key = '_'.join('%s=%s' % (k, v)
                           for k, v in sorted(kwargs.items()))
        assert_array_almost_equal([rmsd(mols[0], mol, **kwargs)
                                  for mol in mols[1:]],
                                  res[res_key], decimal=4)

    # test shuffled rmsd
    for _ in range(5):
        for kwargs in kwargs_grid:
            # dont use method=None in shuffled tests
            if kwargs['method'] is None:
                continue
            res_key = '_'.join('%s=%s' % (k, v)
                               for k, v in sorted(kwargs.items()))
            assert_array_almost_equal([rmsd(mols[0],
                                            shuffle_mol(mol),
                                            **kwargs)
                                       for mol in mols[1:]],
                                      res[res_key], decimal=4)
示例#9
0
def test_diverse_conformers():
    # FIXME: make toolkit a module so we can import from it
    diverse_conformers_generator = oddt.toolkit.diverse_conformers_generator

    mol = oddt.toolkit.readstring(
        'smi',
        'CN1CCN(S(=O)(C2=CC=C(OCC)C(C3=NC4=C(N(C)N=C4CCC)C(N3)=O)=C2)=O)CC1'
    )
    mol.make3D()

    if oddt.toolkit.backend == 'ob' and oddt.toolkit.__version__ < '2.4.0':
        with pytest.raises(NotImplementedError):
            diverse_conformers_generator(mol)
        return None  # skip test for older OB

    res = []
    for conf in diverse_conformers_generator(mol, seed=123456):
        res.append(rmsd(mol, conf))

    assert len(res) == 10
    if oddt.toolkit.backend == 'ob':
        assert_array_almost_equal(res, [0., 3.043712, 3.897143, 3.289482,
                                        3.066374, 2.909683, 2.913927,
                                        3.488244, 3.70603, 3.597467])
    # else:
    #     if oddt.toolkit.__version__ > '2016.03.9':
    #         assert_array_almost_equal(res, [1.237538, 2.346984, 0.900624,
    #                                         3.469511, 1.886213, 2.128909,
    #                                         2.852608, 1.312513, 1.291595,
    #                                         1.326843])
    #     else:
    #         assert_array_almost_equal(res, [3.08995, 2.846358, 3.021795,
    #                                         1.720319, 2.741972, 2.965332,
    #                                         2.925344, 2.930157, 2.934049,
    #                                         3.009545])

    # check all implemented methods
    if oddt.toolkit.backend == 'ob':
        methods = ['ga', 'confab']
    else:
        methods = ['dg', 'etkdg', 'kdg', 'etdg']
    for method in methods:
        assert len(diverse_conformers_generator(mol,
                                                seed=123456,
                                                n_conf=5,
                                                method=method)) == 5
        assert len(diverse_conformers_generator(mol,
                                                seed=123456,
                                                n_conf=10,
                                                method=method)) == 10
        assert len(diverse_conformers_generator(mol,
                                                seed=123456,
                                                n_conf=20,
                                                method=method)) == 20
示例#10
0
def test_spatial():
    """Test spatial misc computations"""
    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()
    mol2 = mol.clone
    # Test rotation
    assert_almost_equal(mol2.coords, rotate(mol2.coords, np.pi, np.pi, np.pi))

    # Rotate perpendicular to ring
    mol2.coords = rotate(mol2.coords, 0, 0, np.pi)

    # RMSD
    assert_almost_equal(rmsd(mol, mol2, method=None), 2.77, decimal=1)
    # Hungarian must be close to zero (RDKit is 0.3)
    assert_almost_equal(rmsd(mol, mol2, method='hungarian'), 0, decimal=0)

    # pick one molecule from docked poses
    mols = list(
        oddt.toolkit.readfile(
            'sdf',
            os.path.join(test_data_dir, 'data/dude/xiap/actives_docked.sdf')))
    mols = list(filter(lambda x: x.title == '312335', mols))

    assert_array_almost_equal([rmsd(mols[0], mol) for mol in mols[1:]], [
        4.753552, 2.501487, 2.7941732, 1.1281863, 0.74440968, 1.6256877,
        4.762476, 2.7167852, 2.5504358, 1.9303833, 2.6200771, 3.1741529,
        3.225431, 4.7784939, 4.8035369, 7.8962774, 2.2385094, 4.8625236,
        3.2036853
    ])

    assert_array_almost_equal(
        [rmsd(mols[0], mol, method='hungarian') for mol in mols[1:]], [
            0.90126, 1.073049, 1.053131, 1.028578, 0.735297, 1.409403,
            0.539091, 1.329666, 1.088053, 1.779618, 2.606429, 3.157684,
            3.213502, 0.812635, 1.290902, 2.521703, 2.083612, 1.832457,
            3.187363
        ])
示例#11
0
def test_vs_docking():
    """VS docking (Vina) tests"""
    vs = virtualscreening(n_cpu=1)
    vs.load_ligands('sdf', xiap_crystal_ligand)

    # bad docking engine
    with pytest.raises(ValueError):
        vs.dock('srina', 'prot.pdb')

    vs.dock(engine='autodock_vina',
            protein=xiap_protein,
            auto_ligand=xiap_crystal_ligand,
            exhaustiveness=1,
            energy_range=6,
            num_modes=7,
            size=(20, 20, 20),
            seed=0)
    mols = list(vs.fetch())
    assert len(mols) == 7
    mol_data = mols[0].data
    assert 'vina_affinity' in mol_data
    assert 'vina_rmsd_lb' in mol_data
    assert 'vina_rmsd_ub' in mol_data
    if oddt.toolkit.backend == 'ob':
        vina_scores = [-5.3, -4.0, -3.8, -3.7, -3.4, -3.4, -3.0]
    else:
        vina_scores = [-6.3, -6.0, -5.8, -5.8, -3.9, -3.0, -1.1]
    assert_array_equal([float(m.data['vina_affinity']) for m in mols],
                       vina_scores)

    # verify the SMILES of molecules
    ref_mol = next(oddt.toolkit.readfile('sdf', xiap_crystal_ligand))

    if oddt.toolkit.backend == 'ob':
        # OB 2.3.2 will fail the following, since Hs are removed, etc.
        # OB 2.4 recognizes the smiles chirality wrong
        pass
    else:
        vina_rmsd = [
            8.153314, 5.32554, 8.514586, 8.510169, 9.060128, 8.995098, 8.626776
        ]
        assert_array_equal([mol.smiles for mol in mols],
                           [ref_mol.smiles] * len(mols))

        assert_array_almost_equal(
            [rmsd(ref_mol, mol, method='min_symmetry') for mol in mols],
            vina_rmsd)
示例#12
0
def test_vs_docking():
    """VS docking (Vina) tests"""
    vs = virtualscreening(n_cpu=1)
    vs.load_ligands('sdf', xiap_crystal_ligand)

    # bad docking engine
    with pytest.raises(ValueError):
        vs.dock('srina', 'prot.pdb')

    vs.dock(engine='autodock_vina',
            protein=xiap_protein,
            auto_ligand=xiap_crystal_ligand,
            exhaustiveness=1,
            energy_range=6,
            num_modes=7,
            size=(20, 20, 20),
            seed=0)
    mols = list(vs.fetch())
    assert len(mols) == 7
    mol_data = mols[0].data
    assert 'vina_affinity' in mol_data
    assert 'vina_rmsd_lb' in mol_data
    assert 'vina_rmsd_ub' in mol_data
    if oddt.toolkit.backend == 'ob':
        vina_scores = [-5.3, -4.0, -3.8, -3.7, -3.4, -3.4, -3.0]
    else:
        vina_scores = [-6.3, -6.0, -5.8, -5.8, -3.9, -3.0, -1.1]
    assert_array_equal([float(m.data['vina_affinity']) for m in mols], vina_scores)

    # verify the SMILES of molecules
    ref_mol = next(oddt.toolkit.readfile('sdf', xiap_crystal_ligand))

    if oddt.toolkit.backend == 'ob':
        # OB 2.3.2 will fail the following, since Hs are removed, etc.
        # OB 2.4 recognizes the smiles chirality wrong
        pass
    else:
        vina_rmsd = [8.153314, 5.32554, 8.514586, 8.510169, 9.060128, 8.995098,
                     8.626776]
        assert_array_equal([mol.smiles for mol in mols],
                           [ref_mol.smiles] * len(mols))

        assert_array_almost_equal([rmsd(ref_mol, mol, method='min_symmetry')
                                   for mol in mols], vina_rmsd)
示例#13
0
def test_spatial():
    """Test spatial computations"""

    # Angles
    assert_array_almost_equal(angle(np.array((1, 0, 0)),
                                    np.array((0, 0, 0)),
                                    np.array((0, 1, 0))), 90)

    assert_array_almost_equal(angle(np.array((1, 0, 0)),
                                    np.array((0, 0, 0)),
                                    np.array((1, 1, 0))), 45)

    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()

    # Check benzene ring angle
    assert_array_almost_equal(angle(mol.coords[0],
                                    mol.coords[1],
                                    mol.coords[2]), 120, decimal=1)

    # Dihedrals
    assert_array_almost_equal(dihedral(np.array((1, 0, 0)),
                                       np.array((0, 0, 0)),
                                       np.array((0, 1, 0)),
                                       np.array((1, 1, 0))), 0)

    assert_array_almost_equal(dihedral(np.array((1, 0, 0)),
                                       np.array((0, 0, 0)),
                                       np.array((0, 1, 0)),
                                       np.array((1, 1, 1))), -45)

    # Check benzene ring dihedral
    assert_array_almost_equal(dihedral(mol.coords[0],
                                       mol.coords[1],
                                       mol.coords[2],
                                       mol.coords[3]), 0, decimal=1)

    mol = oddt.toolkit.readstring('smi', 'c1ccccc1')
    mol.make3D()
    mol2 = mol.clone

    # Test rotation
    assert_almost_equal(mol2.coords, rotate(mol2.coords, np.pi, np.pi, np.pi))

    # Rotate perpendicular to ring
    mol2.coords = rotate(mol2.coords, 0, 0, np.pi)

    # RMSD
    assert_almost_equal(rmsd(mol, mol2, method=None), 2.77, decimal=1)
    # Hungarian must be close to zero (RDKit is 0.3)
    assert_almost_equal(rmsd(mol, mol2, method='hungarian'), 0, decimal=0)

    # pick one molecule from docked poses
    mols = list(oddt.toolkit.readfile('sdf', os.path.join(test_data_dir, 'data/dude/xiap/actives_docked.sdf')))
    mols = list(filter(lambda x: x.title == '312335', mols))

    assert_array_almost_equal([rmsd(mols[0], mol) for mol in mols[1:]],
                              [4.753552, 2.501487, 2.7941732, 1.1281863, 0.74440968,
                               1.6256877, 4.762476, 2.7167852, 2.5504358, 1.9303833,
                               2.6200771, 3.1741529, 3.225431, 4.7784939, 4.8035369,
                               7.8962774, 2.2385094, 4.8625236, 3.2036853])

    assert_array_almost_equal([rmsd(mols[0], mol, method='hungarian') for mol in mols[1:]],
                              [2.5984519, 1.7295024, 1.1268076, 1.0285776, 0.73529714,
                               1.4094033, 2.5195069, 1.7449125, 1.5116163, 1.7796179,
                               2.6064286, 3.1576841, 3.2135022, 3.1675091, 2.7001681,
                               5.1263351, 2.0836117, 3.542397, 3.1873631])
示例#14
0
    def dock(self, ligands, protein=None):
        """Automated docking procedure.

        Parameters
        ----------
        ligands: iterable of oddt.toolkit.Molecule objects
            Ligands to dock

        protein: oddt.toolkit.Molecule object or None
            Protein object to be used. If None, then the default one
            is used, else the protein is new default.

        Returns
        -------
        ligands : array of oddt.toolkit.Molecule objects
            Array of ligands (scores are stored in mol.data method)
        """
        if protein:
            self.set_protein(protein)
        if not self.protein_file:
            raise IOError("No receptor.")
        if is_molecule(ligands):
            ligands = [ligands]
        ligand_dir = mkdtemp(dir=self.tmp_dir, prefix='ligands_')
        output_array = []
        for n, ligand in enumerate(ligands):
            check_molecule(ligand, force_coords=True)
            ligand_file = write_vina_pdbqt(ligand, ligand_dir, name_id=n)
            ligand_outfile = ligand_file[:-6] + '_out.pdbqt'
            try:
                scores = parse_vina_docking_output(
                    subprocess.check_output([
                        self.executable, '--receptor', self.protein_file,
                        '--ligand', ligand_file, '--out', ligand_outfile
                    ] + self.params + ['--cpu', str(self.n_cpu)],
                                            stderr=subprocess.STDOUT))
            except subprocess.CalledProcessError as e:
                sys.stderr.write(e.output.decode('ascii'))
                if self.skip_bad_mols:
                    continue  # TODO: print some warning message
                else:
                    raise Exception('Autodock Vina failed. Command: "%s"' %
                                    ' '.join(e.cmd))

            # docked conformations may have wrong connectivity - use source ligand
            if is_openbabel_molecule(ligand):
                if oddt.toolkits.ob.__version__ >= '2.4.0':
                    # find the order of PDBQT atoms assigned by OpenBabel
                    with open(ligand_file) as f:
                        write_order = [
                            int(line[7:12].strip()) for line in f
                            if line[:4] == 'ATOM'
                        ]
                    new_order = sorted(range(len(write_order)),
                                       key=write_order.__getitem__)
                    new_order = [i + 1
                                 for i in new_order]  # OBMol has 1 based idx

                    assert len(new_order) == len(ligand.atoms)
                else:
                    # Openbabel 2.3.2 does not support perserving atom order.
                    # We read back the PDBQT ligand to get "correct" bonding.
                    ligand = next(oddt.toolkit.readfile('pdbqt', ligand_file))
                    if 'REMARK' in ligand.data:
                        del ligand.data['REMARK']

            docked_ligands = oddt.toolkit.readfile('pdbqt', ligand_outfile)
            for docked_ligand, score in zip(docked_ligands, scores):
                # Renumber atoms to match the input ligand
                if (is_openbabel_molecule(docked_ligand)
                        and oddt.toolkits.ob.__version__ >= '2.4.0'):
                    docked_ligand.OBMol.RenumberAtoms(new_order)
                # HACK: copy docked coordinates onto source ligand
                # We assume that the order of atoms match between ligands
                clone = ligand.clone
                clone.clone_coords(docked_ligand)
                clone.data.update(score)

                # Calculate RMSD to the input pose
                try:
                    clone.data['vina_rmsd_input'] = rmsd(ligand, clone)
                    clone.data['vina_rmsd_input_min'] = rmsd(
                        ligand, clone, method='min_symmetry')
                except Exception:
                    pass
                output_array.append(clone)
        rmtree(ligand_dir)
        return output_array
示例#15
0
    def dock(self, ligands, protein=None):
        """Automated docking procedure.

        Parameters
        ----------
        ligands: iterable of oddt.toolkit.Molecule objects
            Ligands to dock

        protein: oddt.toolkit.Molecule object or None
            Protein object to be used. If None, then the default one
            is used, else the protein is new default.

        Returns
        -------
        ligands : array of oddt.toolkit.Molecule objects
            Array of ligands (scores are stored in mol.data method)
        """
        if protein:
            self.set_protein(protein)
        if not self.protein_file:
            raise IOError("No receptor.")
        if is_molecule(ligands):
            ligands = [ligands]
        ligand_dir = mkdtemp(dir=self.tmp_dir, prefix='ligands_')
        output_array = []
        for n, ligand in enumerate(ligands):
            check_molecule(ligand, force_coords=True)
            ligand_file = write_vina_pdbqt(ligand, ligand_dir, name_id=n)
            ligand_outfile = ligand_file[:-6] + '_out.pdbqt'
            try:
                scores = parse_vina_docking_output(
                    subprocess.check_output([self.executable, '--receptor',
                                             self.protein_file,
                                             '--ligand', ligand_file,
                                             '--out', ligand_outfile] +
                                            self.params +
                                            ['--cpu', str(self.n_cpu)],
                                            stderr=subprocess.STDOUT))
            except subprocess.CalledProcessError as e:
                sys.stderr.write(e.output.decode('ascii'))
                if self.skip_bad_mols:
                    continue  # TODO: print some warning message
                else:
                    raise Exception('Autodock Vina failed. Command: "%s"' %
                                    ' '.join(e.cmd))

            # docked conformations may have wrong connectivity - use source ligand
            if is_openbabel_molecule(ligand):
                if oddt.toolkits.ob.__version__ >= '2.4.0':
                    # find the order of PDBQT atoms assigned by OpenBabel
                    with open(ligand_file) as f:
                        write_order = [int(line[7:12].strip())
                                       for line in f
                                       if line[:4] == 'ATOM']
                    new_order = sorted(range(len(write_order)),
                                       key=write_order.__getitem__)
                    new_order = [i + 1 for i in new_order]  # OBMol has 1 based idx

                    assert len(new_order) == len(ligand.atoms)
                else:
                    # Openbabel 2.3.2 does not support perserving atom order.
                    # We read back the PDBQT ligand to get "correct" bonding.
                    ligand = next(oddt.toolkit.readfile('pdbqt', ligand_file))
                    if 'REMARK' in ligand.data:
                        del ligand.data['REMARK']

            docked_ligands = oddt.toolkit.readfile('pdbqt', ligand_outfile)
            for docked_ligand, score in zip(docked_ligands, scores):
                # Renumber atoms to match the input ligand
                if (is_openbabel_molecule(docked_ligand) and
                        oddt.toolkits.ob.__version__ >= '2.4.0'):
                    docked_ligand.OBMol.RenumberAtoms(new_order)
                # HACK: copy docked coordinates onto source ligand
                # We assume that the order of atoms match between ligands
                clone = ligand.clone
                clone.clone_coords(docked_ligand)
                clone.data.update(score)

                # Calculate RMSD to the input pose
                clone.data['vina_rmsd_input'] = rmsd(ligand, clone)
                clone.data['vina_rmsd_input_min'] = rmsd(ligand, clone,
                                                         method='min_symmetry')
                output_array.append(clone)
        rmtree(ligand_dir)
        return output_array