Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RDKitToolkitWrapper conformer generation fails on some large molecules #822

Closed
mieczyslaw opened this issue Jan 25, 2021 · 9 comments · Fixed by #1346
Closed

RDKitToolkitWrapper conformer generation fails on some large molecules #822

mieczyslaw opened this issue Jan 25, 2021 · 9 comments · Fixed by #1346

Comments

@mieczyslaw
Copy link

mieczyslaw commented Jan 25, 2021

Describe the bug
When I try to parametrize attached structure (using two versions of code as in OpenFF manual/github examples), openforcefield.utils.toolkits.ChargeMethodUnavailableError is generated.

The structure's topology is a bit off as it comes from warheads/linker assembly. The structure contains the correct CONECT
records (repaired in Maestro) and SMILES is also generated by Maestro. The scripts work fine for some other molecules.

To Reproduce
Try the following codes:
script1.py

from openforcefield.topology import Molecule, Topology
from openforcefield.typing.engines.smirnoff import ForceField
from simtk.openmm.app import PDBFile

force_field = ForceField('openff_unconstrained-1.0.0.offxml')
pdb = PDBFile("structure.pdb")
ligand = Molecule.from_smiles("c1cc(Cl)ccc1C2=N[C@@H](c(nnc3C)n3c(c24)sc(C)c4C)CC(=O)NCCOCCOCCOCCOCCOCCOCCOCCOCCOCCNC(=O)COc5cccc(c56)C(=O)N(C6=O)[C@@H](C7=O)CCC(=O)N7")
off_top = Topology.from_openmm(openmm_topology=pdb.topology, unique_molecules=[ligand])
omm_sys = force_field.create_openmm_system(off_top)

script2.py

from openforcefield.utils.toolkits import RDKitToolkitWrapper
from openforcefield.topology import Molecule, Topology
from openforcefield.typing.engines.smirnoff import ForceField
from rdkit import Chem

force_field = ForceField('openff_unconstrained-1.0.0.offxml')
toolkit_wrapper = RDKitToolkitWrapper()
rdmol = Chem.MolFromPDBFile("structure.pdb", removeHs=False)
molecule = toolkit_wrapper.from_rdkit(rdmol)
topology = molecule.to_topology()
system = force_field.create_openmm_system(topology)

The structure in PDB (as TXT as GitHub doesn't like PDB extension):
structure.pdb.txt

Output

/lib/python3.7/site-packages/openforcefield/typing/engines/smirnoff/parameters.py:4176: Warning: No registered toolkits can provide the capability "assign_partial_charges" for args "()" and kwargs "{'molecule': Molecule with name '' and SMILES '[H][c]1[c]([H])[c]([O][C]([H])([H])[C](=[O])[N]([H])[C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[N]([H])[C](=[O])[C]([H])([H])[C@@]2([H])[N]=[C]([c]3[c]([H])[c]([H])[c]([Cl])[c]([H])[c]3[H])[C]3=[C]([S][C]([C]([H])([H])[H])=[C]3[C]([H])([H])[H])[N]3[C]([C]([H])([H])[H])=[N][N]=[C]32)[c]2[c]([c]1[H])[C](=[O])[N]([C@@]1([H])[C](=[O])[N]([H])[C](=[O])[C]([H])([H])[C]1([H])[H])[C]2=[O]', 'partial_charge_method': 'am1bcc', 'use_conformers': None, 'strict_n_conformers': False, '_cls': <class 'openforcefield.topology.molecule.FrozenMolecule'>}"
Available toolkits are: [ToolkitWrapper around The RDKit version 2020.09.3, ToolkitWrapper around AmberTools version 19.0, ToolkitWrapper around Built-in Toolkit version None]
 ToolkitWrapper around The RDKit version 2020.09.3 <class 'openforcefield.utils.toolkits.ChargeMethodUnavailableError'> : partial_charge_method 'am1bcc' is not available from RDKitToolkitWrapper. Available charge methods are ['mmff94']
 ToolkitWrapper around AmberTools version 19.0 <class 'TypeError'> : 'NoneType' object is not iterable
 ToolkitWrapper around Built-in Toolkit version None <class 'openforcefield.utils.toolkits.ChargeMethodUnavailableError'> : Partial charge method "am1bcc"" is not supported by the Built-in toolkit. Available charge methods are ['zeros', 'formal_charge']

  warnings.warn(str(e), Warning)
Traceback (most recent call last):
  File "script1.py", line 10, in <module>
    omm_sys = force_field.create_openmm_system(off_top)
  File "/lib/python3.7/site-packages/openforcefield/typing/engines/smirnoff/forcefield.py", line 1329, in create_openmm_system
    parameter_handler.postprocess_system(system, topology, **kwargs)
  File "/lib/python3.7/site-packages/openforcefield/typing/engines/smirnoff/parameters.py", line 3978, in postprocess_system
    raise UnassignedMoleculeChargeException(msg)
openforcefield.typing.engines.smirnoff.parameters.UnassignedMoleculeChargeException: The following molecules did not have charges assigned by any ParameterHandler in the ForceField:
[H][c]1[c]([H])[c]([O][C]([H])([H])[C](=[O])[N]([H])[C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[N]([H])[C](=[O])[C]([H])([H])[C@@]2([H])[N]=[C]([c]3[c]([H])[c]([H])[c]([Cl])[c]([H])[c]3[H])[C]3=[C]([S][C]([C]([H])([H])[H])=[C]3[C]([H])([H])[H])[N]3[C]([C]([H])([H])[H])=[N][N]=[C]32)[c]2[c]([c]1[H])[C](=[O])[N]([C@@]1([H])[C](=[O])[N]([H])[C](=[O])[C]([H])([H])[C]1([H])[H])[C]2=[O]

Computing environment (please complete the following information):

  • Operating system: Linux RedHat
  • Output of running conda list
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       1_gnu    conda-forge
acpype                    2020.10.24.12.16            py_0    conda-forge
amberlite                 16.0                     pypi_0    pypi
ambertools                20.9                     pypi_0    pypi
apbs                      1.5                  h14c3975_3    schrodinger
argh                      0.26.2          pyh9f0ad1d_1002    conda-forge
argon2-cffi               20.1.0           py37h4abf009_2    conda-forge
arpack                    3.7.0                h236a147_2    conda-forge
astunparse                1.6.2                      py_0    conda-forge
async_generator           1.10                       py_0    conda-forge
attrs                     20.3.0             pyhd3deb0d_0    conda-forge
backcall                  0.2.0              pyh9f0ad1d_0    conda-forge
backports                 1.0                        py_2    conda-forge
backports.functools_lru_cache 1.6.1                      py_0    conda-forge
biopython                 1.78             py37h4abf009_1    conda-forge
biosimspace               2020.1.0        py37h14c3975_95    michellab/label/dev
bleach                    3.2.1              pyh9f0ad1d_0    conda-forge
blosc                     1.21.0               h9c3ff4c_0    conda-forge
boost                     1.72.0           py37h48f8a5e_1    conda-forge
boost-cpp                 1.72.0               h9359b55_3    conda-forge
brotlipy                  0.7.0           py37hb5d75c8_1001    conda-forge
bson                      0.5.9                      py_0    conda-forge
bzip2                     1.0.8                h7f98852_4    conda-forge
c-ares                    1.17.1               h36c2ea0_0    conda-forge
ca-certificates           2021.1.19            h06a4308_0  
cached-property           1.5.1                      py_0    conda-forge
cairo                     1.16.0            h9f066cc_1006    conda-forge
certifi                   2020.12.5        py37h06a4308_0  
cffi                      1.14.4           py37h11fe52a_0    conda-forge
cftime                    1.3.0            py37ha21ca33_0    conda-forge
chardet                   4.0.0            py37h89c1867_1    conda-forge
configargparse            1.2.3              pyh9f0ad1d_0    conda-forge
cryptography              3.3.1            py37h7f0c10b_1    conda-forge
curl                      7.71.1               he644dc0_8    conda-forge
cycler                    0.10.0                     py_2    conda-forge
cython                    0.29.21          py37hcd2ae1e_2    conda-forge
dbus                      1.13.6               hfdff14a_1    conda-forge
decorator                 4.4.2                      py_0    conda-forge
defusedxml                0.6.0                      py_0    conda-forge
entrypoints               0.3             pyhd8ed1ab_1003    conda-forge
expat                     2.2.9                he1b5a44_2    conda-forge
fftw                      3.3.8           nompi_h8cb7ab2_1114    conda-forge
fftw3f                    3.3.4                         2    omnia
fontconfig                2.13.1            h7e3eb15_1002    conda-forge
freemol                   1.158                      py_2    schrodinger
freetype                  2.10.4               h7ca028e_0    conda-forge
gettext                   0.19.8.1          hf34092f_1004    conda-forge
git                       2.30.0          pl5320h014a29a_0    conda-forge
git-lfs                   2.13.1               ha770c72_0    conda-forge
glew                      2.0.0                         0    schrodinger
glib                      2.66.3               h58526e2_0    conda-forge
griddataformats           0.5.0                      py_0    conda-forge
gsd                       2.4.0            py37ha21ca33_0    conda-forge
gsl                       2.6                  he838d99_1    conda-forge
gst-plugins-base          1.14.5               h0935bb2_2    conda-forge
gstreamer                 1.14.5               h36ae1b5_2    conda-forge
h5py                      3.1.0           nompi_py37h1e651dc_100    conda-forge
hdf4                      4.2.13            h10796ff_1004    conda-forge
hdf5                      1.10.6          nompi_h6a2412b_1114    conda-forge
icu                       67.1                 he1b5a44_0    conda-forge
idna                      2.10               pyh9f0ad1d_0    conda-forge
importlib-metadata        3.4.0            py37h89c1867_0    conda-forge
importlib_metadata        3.4.0                hd8ed1ab_0    conda-forge
iniconfig                 1.1.1              pyh9f0ad1d_0    conda-forge
ipykernel                 5.4.2            py37h888b3d9_0    conda-forge
ipython                   7.19.0           py37h888b3d9_0    conda-forge
ipython_genutils          0.2.0                      py_1    conda-forge
ipywidgets                7.6.3              pyhd3deb0d_0    conda-forge
jedi                      0.18.0           py37h89c1867_2    conda-forge
jinja2                    2.11.2             pyh9f0ad1d_0    conda-forge
joblib                    1.0.0              pyhd8ed1ab_0    conda-forge
jpeg                      9d                   h36c2ea0_0    conda-forge
jsonschema                3.2.0                      py_2    conda-forge
jupyter_client            6.1.11             pyhd8ed1ab_1    conda-forge
jupyter_core              4.7.0            py37h89c1867_0    conda-forge
jupyterlab_pygments       0.1.2              pyh9f0ad1d_0    conda-forge
jupyterlab_widgets        1.0.0              pyhd8ed1ab_1    conda-forge
kiwisolver                1.3.1            py37h2527ec5_1    conda-forge
krb5                      1.17.2               h926e7f8_0    conda-forge
lcms2                     2.11                 hcbb858e_1    conda-forge
ld_impl_linux-64          2.35.1               hea4e1c9_1    conda-forge
libblas                   3.9.0                7_openblas    conda-forge
libcblas                  3.9.0                7_openblas    conda-forge
libclang                  10.0.1          default_hde54327_1    conda-forge
libcurl                   7.71.1               hcdd3856_8    conda-forge
libedit                   3.1.20191231         he28a2e2_2    conda-forge
libev                     4.33                 h516909a_1    conda-forge
libevent                  2.1.10               hcdb4288_3    conda-forge
libffi                    3.2.1             he1b5a44_1007    conda-forge
libgcc                    7.2.0                h69d50b8_2    conda-forge
libgcc-ng                 9.3.0               h5dbcf3e_17    conda-forge
libgfortran-ng            9.3.0               he4bcb1c_17    conda-forge
libgfortran5              9.3.0               he4bcb1c_17    conda-forge
libglib                   2.66.3               hbe7bbb4_0    conda-forge
libglu                    9.0.0             he1b5a44_1001    conda-forge
libgomp                   9.3.0               h5dbcf3e_17    conda-forge
libholoplaycore           0.1.0_rc4                     1    schrodinger
libiconv                  1.16                 h516909a_0    conda-forge
liblapack                 3.9.0                7_openblas    conda-forge
libllvm10                 10.0.1               he513fc3_3    conda-forge
libnetcdf                 4.7.4           nompi_h56d31a8_107    conda-forge
libnghttp2                1.41.0               h8cfc5f6_2    conda-forge
libopenblas               0.3.12          pthreads_h4812303_1    conda-forge
libpng                    1.6.37               h21135ba_2    conda-forge
libpq                     12.3                 h255efa7_3    conda-forge
libsodium                 1.0.18               h36c2ea0_1    conda-forge
libssh2                   1.9.0                hab1572f_5    conda-forge
libstdcxx-ng              9.3.0               h2ae2ef3_17    conda-forge
libtiff                   4.2.0                hdc55705_0    conda-forge
libuuid                   2.32.1            h7f98852_1000    conda-forge
libwebp-base              1.1.0                h36c2ea0_3    conda-forge
libxcb                    1.13              h7f98852_1003    conda-forge
libxkbcommon              0.10.0               he1b5a44_0    conda-forge
libxml2                   2.9.10               h68273f3_2    conda-forge
lz4-c                     1.9.3                h9c3ff4c_0    conda-forge
lzo                       2.10              h516909a_1000    conda-forge
mako                      1.1.3              pyh9f0ad1d_0    conda-forge
markdown                  3.3.3              pyh9f0ad1d_0    conda-forge
markupsafe                1.1.1            py37h5e8e339_3    conda-forge
matplotlib-base           3.3.3            py37h4f6019d_0    conda-forge
mdanalysis                1.0.0            py37h745909e_1    conda-forge
mdtraj                    1.9.5            py37h113d463_0    conda-forge
mengine                   1                    h14c3975_1    schrodinger
mistune                   0.8.4           py37h5e8e339_1003    conda-forge
mmpbsa-py                 16.0                     pypi_0    pypi
mmtf-python               1.1.2                      py_0    conda-forge
mock                      4.0.3            py37h89c1867_1    conda-forge
more-itertools            8.6.0              pyhd8ed1ab_0    conda-forge
mpeg_encode               1                    h14c3975_1    schrodinger
msgpack-python            1.0.2            py37h2527ec5_1    conda-forge
mtz2ccp4_px               1.0                           1    schrodinger
mysql-common              8.0.21                        2    conda-forge
mysql-libs                8.0.21               hf3661c5_2    conda-forge
nbclient                  0.5.1                      py_0    conda-forge
nbconvert                 6.0.7            py37h89c1867_3    conda-forge
nbformat                  5.0.8                      py_0    conda-forge
ncurses                   6.2                  h58526e2_4    conda-forge
nest-asyncio              1.4.3              pyhd8ed1ab_0    conda-forge
netcdf-fortran            4.5.3           nompi_h1a0d97b_101    conda-forge
netcdf4                   1.5.3           nompi_py37hdc49583_105    conda-forge
networkx                  2.5                        py_0    conda-forge
nglview                   2.7.7              pyh5ca1d4c_1    conda-forge
notebook                  6.1.6            py37h89c1867_0    conda-forge
nspr                      4.29                 h9c3ff4c_1    conda-forge
nss                       3.60                 hb5efdd6_0    conda-forge
numexpr                   2.7.2            py37hdc94413_0    conda-forge
numpy                     1.19.5           py37haa41c4c_1    conda-forge
olefile                   0.46               pyh9f0ad1d_1    conda-forge
openbabel                 3.1.1            py37h200e996_1    conda-forge
openblas                  0.3.12          pthreads_h04b7a96_1    conda-forge
openforcefield            0.8.3              pyh39e3cac_0    omnia
openforcefields           1.3.0                      py_0    omnia
openmm                    7.4.2           py37_cuda101_rc_1    omnia
openssl                   1.1.1i               h27cfd23_0  
packaging                 20.8               pyhd3deb0d_0    conda-forge
packmol-memgen            1.1.0rc0                 pypi_0    pypi
pandas                    1.2.0            py37hdc94413_0    conda-forge
pandoc                    2.11.3.2             h7f98852_0    conda-forge
pandocfilters             1.4.2                      py_1    conda-forge
parmed                    at20RC5+54.g5702a232fe.dirty          pypi_0    pypi
parso                     0.8.1              pyhd8ed1ab_0    conda-forge
patsy                     0.5.1                      py_0    conda-forge
pcre                      8.44                 he1b5a44_0    conda-forge
pdb2pqr                   2.1.2+pymol                py_0    schrodinger
pdb4amber                 1.7.dev0                 pypi_0    pypi
pdoc3                     0.8.1                      py_0    conda-forge
perl                      5.32.0               h36c2ea0_0    conda-forge
pexpect                   4.8.0              pyh9f0ad1d_2    conda-forge
pickleshare               0.7.5                   py_1003    conda-forge
pillow                    8.1.0            py37he6b4880_1    conda-forge
pip                       20.3.3             pyhd8ed1ab_0    conda-forge
pixman                    0.40.0               h36c2ea0_0    conda-forge
pluggy                    0.13.1           py37h89c1867_4    conda-forge
pmw                       2.0.1+3                    py_3    schrodinger
prometheus_client         0.9.0              pyhd3deb0d_0    conda-forge
prompt-toolkit            3.0.10             pyha770c72_0    conda-forge
pthread-stubs             0.4               h36c2ea0_1001    conda-forge
ptyprocess                0.7.0              pyhd3deb0d_0    conda-forge
py                        1.10.0             pyhd3deb0d_0    conda-forge
pycairo                   1.20.0           py37h01af8b0_1    conda-forge
pycparser                 2.20               pyh9f0ad1d_2    conda-forge
pygments                  2.7.3              pyhd8ed1ab_0    conda-forge
pygtail                   0.11.1                     py_0    conda-forge
pymbar                    3.0.5            py37ha21ca33_1    conda-forge
pymol                     2.4.1            py37h913975d_0    schrodinger
pyopenssl                 20.0.1             pyhd8ed1ab_0    conda-forge
pyparsing                 2.4.7              pyh9f0ad1d_0    conda-forge
pypdb                     2.0                pyhd8ed1ab_0    conda-forge
pyqt                      5.12.3           py37h8685d9f_3    conda-forge
pyqt5-sip                 4.19.18                  pypi_0    pypi
pyqtchart                 5.12                     pypi_0    pypi
pyqtwebengine             5.12.1                   pypi_0    pypi
pyrsistent                0.17.3           py37h5e8e339_2    conda-forge
pysocks                   1.7.1            py37h89c1867_3    conda-forge
pytables                  3.6.1            py37h0c4f3e0_3    conda-forge
pytest                    6.2.1            py37h89c1867_1    conda-forge
python                    3.7.8           h8bdb77d_2_cpython    conda-forge
python-dateutil           2.8.1                      py_0    conda-forge
python_abi                3.7                     1_cp37m    conda-forge
pytraj                    2.0.5                    pypi_0    pypi
pytz                      2020.5             pyhd8ed1ab_0    conda-forge
pyyaml                    5.3.1            py37h5e8e339_2    conda-forge
pyzmq                     20.0.0           py37h499b945_1    conda-forge
qt                        5.12.5               h7400415_4    conda-forge
rdkit                     2020.09.3        py37h400b6df_0    conda-forge
readline                  8.0                  he28a2e2_2    conda-forge
reportlab                 3.5.59           py37h69800bb_0    conda-forge
requests                  2.25.1             pyhd3deb0d_0    conda-forge
rigimol                   1.3                           2    schrodinger
sander                    16.0                     pypi_0    pypi
scikit-learn              0.24.0           py37h69acf81_0    conda-forge
scipy                     1.6.0            py37h14a347d_0    conda-forge
seaborn                   0.11.1               ha770c72_0    conda-forge
seaborn-base              0.11.1             pyhd8ed1ab_0    conda-forge
send2trash                1.5.0                      py_0    conda-forge
setuptools                49.6.0           py37h89c1867_3    conda-forge
sire                      2020.1.0        py37hf484d3e_72    michellab/label/dev
six                       1.15.0             pyh9f0ad1d_0    conda-forge
smirnoff99frosst          1.1.0                      py_2    omnia
snappy                    1.1.8                he1b5a44_3    conda-forge
sqlalchemy                1.3.22           py37h5e8e339_1    conda-forge
sqlite                    3.34.0               h74cdb3f_0    conda-forge
statsmodels               0.12.1           py37h902c9e0_2    conda-forge
tbb                       2019.9               hc9558a2_1    conda-forge
tbb-devel                 2019.9               hc9558a2_1    conda-forge
terminado                 0.9.2            py37h89c1867_0    conda-forge
testpath                  0.4.4                      py_0    conda-forge
threadpoolctl             2.1.0              pyh5ca1d4c_0    conda-forge
tk                        8.6.10               h21135ba_1    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
tornado                   6.1              py37h5e8e339_1    conda-forge
tqdm                      4.55.1             pyhd3eb1b0_0  
traitlets                 5.0.5                      py_0    conda-forge
typing_extensions         3.7.4.3                    py_0    conda-forge
urllib3                   1.26.2             pyhd8ed1ab_0    conda-forge
watchdog                  1.0.2            py37h89c1867_1    conda-forge
wcwidth                   0.2.5              pyh9f0ad1d_2    conda-forge
webencodings              0.5.1                      py_1    conda-forge
wheel                     0.36.2             pyhd3deb0d_0    conda-forge
widgetsnbextension        3.5.1            py37h89c1867_4    conda-forge
xmltodict                 0.12.0                     py_0    conda-forge
xorg-kbproto              1.0.7             h7f98852_1002    conda-forge
xorg-libice               1.0.10               h516909a_0    conda-forge
xorg-libsm                1.2.3             h84519dc_1000    conda-forge
xorg-libx11               1.6.12               h516909a_0    conda-forge
xorg-libxau               1.0.9                h7f98852_0    conda-forge
xorg-libxdmcp             1.1.3                h7f98852_0    conda-forge
xorg-libxext              1.3.4                h516909a_0    conda-forge
xorg-libxrender           0.9.10            h516909a_1002    conda-forge
xorg-libxt                1.2.0                h516909a_0    conda-forge
xorg-renderproto          0.11.1            h14c3975_1002    conda-forge
xorg-xextproto            7.3.0             h7f98852_1002    conda-forge
xorg-xproto               7.0.31            h7f98852_1007    conda-forge
xz                        5.2.5                h516909a_1    conda-forge
yaml                      0.2.5                h516909a_0    conda-forge
zeromq                    4.3.3                h58526e2_3    conda-forge
zipp                      3.4.0                      py_0    conda-forge
zlib                      1.2.11            h516909a_1010    conda-forge
zstd                      1.4.8                ha95c52a_1    conda-forge

Additional context
The goal after the system generation step is to use parmed (as in docs) to save prmtop file.

@mattwthompson
Copy link
Member

Apologies for a not-very-useful error message. I can reproduce this; the failures can come from failing conformer generation, which happens before trying to assign charges.

In:

# Modified script1.py
...
pdb = PDBFile("structure.pdb")
ligand = Molecule.from_smiles("c1cc(Cl)ccc1C2=N[C@@H](c(nnc3C)n3c(c24)sc(C)c4C)CC(=O)NCCOCCOCCOCCOCCOCCOCCOCCOCCOCCNC(=O)COc5cccc(c56)C(=O)N(C6=O)[C@@H](C7=O)CCC(=O)N7")
ligand.generate_conformers(n_conformers=1)

Out:

----> 1 ligand.generate_conformers(n_conformers=1)

~/scratch/openff-toolkit/openff/toolkit/topology/molecule.py in generate_conformers(self, toolkit_registry, n_conformers, rms_cutoff, clear_existing)
   2776                 n_conformers=n_conformers,
   2777                 rms_cutoff=rms_cutoff,
-> 2778                 clear_existing=clear_existing,
   2779             )
   2780         elif isinstance(toolkit_registry, ToolkitWrapper):

~/scratch/openff-toolkit/openff/toolkit/utils/toolkits.py in call(self, method_name, raise_exception_types, *args, **kwargs)
   5284                     for exception_type in raise_exception_types:
   5285                         if isinstance(e, exception_type):
-> 5286                             raise e
   5287                     errors.append((toolkit, e))
   5288

~/scratch/openff-toolkit/openff/toolkit/utils/toolkits.py in call(self, method_name, raise_exception_types, *args, **kwargs)
   5280                 method = getattr(toolkit, method_name)
   5281                 try:
-> 5282                     return method(*args, **kwargs)
   5283                 except Exception as e:
   5284                     for exception_type in raise_exception_types:

~/scratch/openff-toolkit/openff/toolkit/utils/toolkits.py in generate_conformers(self, molecule, n_conformers, rms_cutoff, clear_existing, _cls)
   3363             molecule._conformers = list()
   3364
-> 3365         for conformer in molecule2._conformers:
   3366             molecule._add_conformer(conformer)
   3367

TypeError: 'NoneType' object is not iterable

The root of the confusing error is that molecule2 doesn't have any conformers; the RDKit conformer generation itself is failing

Chem.AllChem.EmbedMultipleConfs(rdmol, numConfs=1, pruneRmsThresh=1, randomSeed=1)
rdmol.GetNumConformers()  # returns 0

This may be a bug or shortcoming of RDKit, I'm not sure. I'm not so familiar with conformer generation so I can't help much more than that. Aside from being huge, the ligand doesn't seem to have an invalid topology.

If you have access to the OpenEye toolkits, it doesn't seem to have an issue with this molecule (molecule.generate_conformers(n_conformers=1, toolkit_registry=ToolkitRegistry(toolkit_precedence=[OpenEyeToolkitWrapper])) generates a conformer)

However - your molecule already has a "conformer" on it, since the PDB file has reasonable-looking positions, which can be used in the AM1-BCC call, bypassing the above issue.

# modified script2.py
rdmol = Chem.MolFromPDBFile("structure.pdb", removeHs=False)
molecule = Molecule.from_rdkit(rdmol)
molecule.assign_partial_charges(partial_charge_method="formal_charge", use_conformers=molecule.conformers)  # Dummy placeholder values only!
topology = molecule.to_topology()
system = force_field.create_openmm_system(topology=topology, charge_from_molecules=[molecule])

Since the ligand is so big, AM1 takes a long time (I killed it after several minutes on my poor dual-core machine). If there's another way to get partial charges and stick them into i.e. an SDF file, that would also work. The partial charges there are all zeros; just dummy values to demonstrate that actual values can be dropped in.

@mieczyslaw
Copy link
Author

mieczyslaw commented Jan 25, 2021

Thanks @mattwthompson ! As I wrote, the scripts work for many other molecules created in the similar way so I am confused what's special about this one? Why RDKit conformer generation is called at all? I would understand that someone provides SMILES only so a conformer needs to be generated, but both examples in OpenFF docs are based on PDB+SMILES (when off topology) or PDB only (when processed by RDKit).

Could you also explain why calling explicitly molecule.assign_partial_charges helps? Isn't it called anyway (and crashing)?

@j-wags
Copy link
Member

j-wags commented Jan 25, 2021

Hi @mieczyslaw,

Why RDKit conformer generation is called at all?

We do this to improve the reproducibility of the charges that get assigned.

One of OpenFF's core philosphies is that straightforward usage of our tools should yield reproducible, publication-ready outputs. Something we've seen a lot is papers saying "We charged the ligand using AM1-BCC", which doesn't actually tell the full story, since AM1 is conformer-dependent. So, our AM1BCC charging will always try to generate its own conformer using a backend toolkit, so that the same chemical graph/connection table will get the same partial charges.

We recognize that it's a bit counterintuitive, and that the exact output is still dependent on factors like low-level system factors and specific RDKit/AmberTools versions. But it should avoid situations where, for example, someone seeds simulations from different conformers of the same molecule, and each simulation ends up with different physical parameters.

@mieczyslaw
Copy link
Author

Thanks @j-wags.

It seems I found a solution you may want to use in case the exception is generated (or at least to show the user a hint) - I regenerated SMILES with RDKit using the code:

mol = Chem.rdmolfiles.MolFromSmiles(input_smiles)
output_smiles = Chem.rdmolfiles.MolToSmiles(mol)

So I got:

**BEFORE**: c1cc(Cl)ccc1C2=N[C@@H](c(nnc3C)n3c(c24)sc(C)c4C)CC(=O)NCCOCCOCCOCCOCCOCCOCCOCCOCCOCCNC(=O)COc5cccc(c56)C(=O)N(C6=O)[C@@H](C7=O)CCC(=O)N7

**AFTER:** Cc1sc2c(c1C)C(c1ccc(Cl)cc1)=N[C@H](CC(=O)NCCOCCOCCOCCOCCOCCOCCOCCOCCOCCNC(=O)COc1cccc3c1C(=O)N([C@@H]1CCC(=O)NC1=O)C3=O)c1nnc(C)n1-2

Then with script1.py where both PDB and SMILES is provided, it runs without this exception!

@mieczyslaw
Copy link
Author

Update: this must be related to the size of the molecule. I have another example:

structure2.pdb.txt

**MAESTRO SMILES:** c1cccc(c12)sc(n2)NC(=O)c3cccc(c34)CCN(C4)c(n5)sc(c5C(=O)O)CCCOc(cc6)ccc6C#CCOCCOCCOCCOCCOCCOCCC(=O)N[C@@H](C(C)(C)C)C(=O)N7C[C@H](O)C[C@H]7C(=O)NCc8ccc(cc8)-c(c9C)scn9

**RDKIT SMILES:** Cc1ncsc1-c1ccc(CNC(=O)[C@@H]2C[C@@H](O)CN2C(=O)[C@@H](NC(=O)CCOCCOCCOCCOCCOCCOCC#Cc2ccc(OCCCc3sc(N4CCc5cccc(C(=O)Nc6nc7ccccc7s6)c5C4)nc3C(=O)O)cc2)C(C)(C)C)cc1

This time even processing SMILES via RDKit doesn't help.

@mieczyslaw
Copy link
Author

@mattwthompson your modified script with calling assign_partial_charges doesn't work on my system, it crashes (at least on structure2.pdb.txt) with:

lib/python3.7/site-packages/openforcefield/utils/toolkits.py:394: IncorrectNumConformersWarning: Molecule 'Molecule with name '' and SMILES '[H][O][C](=[O])[C]1=[C]([C]([H])([H])[C]([H])([H])[C]([H])([H])[O][c]2[c]([H])[c]([H])[c]([C]#[C][C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[O][C]([H])([H])[C]([H])([H])[C](=[O])[N]([H])[C@]([H])([C](=[O])[N]3[C]([H])([H])[C@@]([H])([O][H])[C]([H])([H])[C@@]3([H])[C](=[O])[N]([H])[C]([H])([H])[c]3[c]([H])[c]([H])[c]([C]4=[C]([C]([H])([H])[H])[N]=[C]([H])[S]4)[c]([H])[c]3[H])[C]([C]([H])([H])[H])([C]([H])([H])[H])[C]([H])([H])[H])[c]([H])[c]2[H])[S][C]([N]2[C]([H])([H])[c]3[c]([C](=[O])[N]([H])[C]4=[N][c]5[c]([H])[c]([H])[c]([H])[c]([H])[c]5[S]4)[c]([H])[c]([H])[c]([H])[c]3[C]([H])([H])[C]2([H])[H])=[N]1'' has 1 conformers, but charge method 'formal_charge' expects exactly 0.
  warnings.warn(wrong_confs_msg, IncorrectNumConformersWarning)

@mieczyslaw
Copy link
Author

I reported in RDKit issues tracker: rdkit/rdkit#3764

@mieczyslaw
Copy link
Author

As suggested by Greg/RDKit, the solution is to add useRandomCoords=True:

AllChem.EmbedMultipleConfs(rdmol, numConfs=1, useRandomCoords=True)

Also, when only single conformer is needed, there is another function:

AllChem.EmbedMolecule(rdmol, useRandomCoords=True)

It seems to properly generate conformer as I tested with Chem.MolToMolBlock(rdmol) and opened in PyMol.

I believe that the current code can be kept, but if no conformers are generated, it can try again with useRandomCoords=True?

@j-wags
Copy link
Member

j-wags commented Apr 5, 2022

Hi @mieczyslaw - Thanks for doing so much legwork on this. I'm really sorry this fell off our radar. I hope we can be better organized in the future.

I just saw openmm/openmm#3550 which has the same root cause, and it kicked my memory to come looking for this.

I believe that the current code can be kept, but if no conformers are generated, it can try again with useRandomCoords=True?

Yeah, I think this is the right solution. I'm attaching this to a release milestone so it doesn't get lost again. Again, I really apologize that we lost track of this, and I'm very grateful for your help here.

@j-wags j-wags added this to the 0.11.1 milestone Apr 5, 2022
@mattwthompson mattwthompson changed the title openforcefield.utils.toolkits.ChargeMethodUnavailableError RDKitToolkitWrapper conformer generation fails on some large molecules Jul 7, 2022
mattwthompson added a commit that referenced this issue Jul 7, 2022
mattwthompson added a commit that referenced this issue Jul 29, 2022
…ls (#1346)

* Add test reproducing #822

* Fall back to `useRandomCoords=True` if first conformer generation fails

* Update openff/toolkit/tests/test_toolkits.py

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Update release history

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants