openff-toolkit
openff-toolkit copied to clipboard
Exception adding molecule to topology
Describe the bug I've run into a strange case where I can create a Molecule without problem, but I get an exception when I try to add it to a Topology.
To Reproduce
mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C(C#N)\\N=C/C(C)=C\\N/C(C#N)=C(C#N)/N=C\\1')
top = Topology()
top.add_molecule(mol)
Output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/topology/topology.py", line 3006, in add_molecule
mol_smiles = molecule.to_smiles()
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/topology/molecule.py", line 2730, in to_smiles
smiles = to_smiles_method(self, isomeric, explicit_hydrogens, mapped)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 667, in to_smiles
rdmol = self.to_rdkit(molecule)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 1774, in to_rdkit
cls._assign_rdmol_bonds_stereo(molecule, rdmol)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 2386, in _assign_rdmol_bonds_stereo
assert stereo_rdbond.GetStereo() == desired_rdk_stereo_code
AssertionError
Computing environment (please complete the following information):
- Operating system
Ubuntu 18.04
- Output of running
conda list
# packages in environment at /home/peastman/miniconda3/envs/openmm:
#
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-forge
_openmp_mutex 4.5 1_llvm conda-forge
alsa-lib 1.2.3 h516909a_0 conda-forge
amberlite 16.0 pypi_0 pypi
ambertools 20.9 pypi_0 pypi
argon2-cffi 20.1.0 py38h497a2fe_2 conda-forge
arpack 3.7.0 hc6cf775_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.4 pyhd8ed1ab_0 conda-forge
blas 1.0 mkl conda-forge
bleach 3.3.0 pyh44b312d_0 conda-forge
blosc 1.21.0 h9c3ff4c_0 conda-forge
bokeh 2.3.3 py38h578d9bd_0 conda-forge
boost 1.72.0 py38h1e42940_1 conda-forge
boost-cpp 1.72.0 h312852a_5 conda-forge
brotlipy 0.7.0 py38h497a2fe_1001 conda-forge
bzip2 1.0.8 h7f98852_4 conda-forge
c-ares 1.17.1 h7f98852_1 conda-forge
ca-certificates 2021.7.5 h06a4308_1
cached-property 1.5.2 hd8ed1ab_1 conda-forge
cached_property 1.5.2 pyha770c72_1 conda-forge
cairo 1.16.0 h6cf1ce9_1008 conda-forge
certifi 2021.5.30 py38h578d9bd_0 conda-forge
cffi 1.14.5 py38ha65f79e_0 conda-forge
cftime 1.4.1 py38h5c078b8_0 conda-forge
chardet 4.0.0 py38h578d9bd_1 conda-forge
click 8.0.1 py38h578d9bd_0 conda-forge
cloudpickle 2.0.0 pyhd8ed1ab_0 conda-forge
cmake 3.20.5 h8897547_0 conda-forge
cryptography 3.4.7 py38ha5dfef3_0 conda-forge
cudatoolkit 10.2.89 h8f6ccaa_9 conda-forge
cudnn 7.6.5.32 h01f27c4_1 conda-forge
curl 7.77.0 hea6ffbf_0 conda-forge
cycler 0.10.0 py_2 conda-forge
cython 0.29.21 py38h348cfbe_1 conda-forge
cytoolz 0.11.0 py38h497a2fe_3 conda-forge
dask 2021.9.0 pyhd8ed1ab_0 conda-forge
dask-core 2021.9.0 pyhd8ed1ab_0 conda-forge
dbus 1.13.18 hb2f20db_0
decorator 4.4.2 py_0 conda-forge
defusedxml 0.7.1 pyhd8ed1ab_0 conda-forge
distributed 2021.9.0 py38h578d9bd_0 conda-forge
entrypoints 0.3 py38h32f6830_1002 conda-forge
expat 2.4.1 h9c3ff4c_0 conda-forge
fftw 3.3.9 h27cfd23_1
fontconfig 2.13.1 hba837de_1005 conda-forge
freetype 2.10.4 h0708190_1 conda-forge
fsspec 2021.8.1 pyhd8ed1ab_0 conda-forge
future 0.18.2 py38h578d9bd_3 conda-forge
gettext 0.19.8.1 h0b5b191_1005 conda-forge
glib 2.68.1 h9c3ff4c_0 conda-forge
glib-tools 2.68.1 h9c3ff4c_0 conda-forge
greenlet 1.0.0 py38h709712a_0 conda-forge
gromacs 2021.1 nompi_hcc3dda7_101 bioconda
gst-plugins-base 1.18.4 hf529b03_2 conda-forge
gstreamer 1.18.4 h76c114f_2 conda-forge
h5py 3.2.1 nompi_py38h9915d05_100 conda-forge
hdf4 4.2.13 h10796ff_1005 conda-forge
hdf5 1.10.6 nompi_h7c3c948_1111 conda-forge
heapdict 1.0.1 py_0 conda-forge
icu 68.1 h58526e2_0 conda-forge
idna 2.10 pyh9f0ad1d_0 conda-forge
importlib-metadata 4.0.1 py38h578d9bd_0 conda-forge
importlib_metadata 4.0.1 hd8ed1ab_0 conda-forge
iniconfig 1.1.1 pyh9f0ad1d_0 conda-forge
intel-openmp 2021.3.0 h06a4308_3350
ipykernel 5.5.3 py38hd0cf306_0 conda-forge
ipython 7.22.0 py38hd0cf306_0 conda-forge
ipython_genutils 0.2.0 py_1 conda-forge
ipywidgets 7.6.3 pyhd3deb0d_0 conda-forge
jbig 2.1 h7f98852_2003 conda-forge
jedi 0.18.0 py38h578d9bd_2 conda-forge
jinja2 2.11.3 pyh44b312d_0 conda-forge
jpeg 9d h36c2ea0_0 conda-forge
jsonschema 3.2.0 py38h32f6830_1 conda-forge
jupyter 1.0.0 py38h578d9bd_6 conda-forge
jupyter_client 6.1.12 pyhd8ed1ab_0 conda-forge
jupyter_console 6.4.0 pyhd8ed1ab_0 conda-forge
jupyter_core 4.7.1 py38h578d9bd_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 py38h1fd1430_1 conda-forge
krb5 1.19.1 hcc1bbae_0 conda-forge
lark-parser 0.11.2 pyh44b312d_0 conda-forge
lcms2 2.12 hddcbb42_0 conda-forge
ld_impl_linux-64 2.35.1 hea4e1c9_2 conda-forge
lerc 2.2.1 h9c3ff4c_0 conda-forge
libblas 3.9.0 8_mkl conda-forge
libcblas 3.9.0 8_mkl conda-forge
libclang 11.1.0 default_ha53f305_0 conda-forge
libcurl 7.77.0 h2574ce0_0 conda-forge
libdeflate 1.7 h7f98852_5 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.3 h58526e2_2 conda-forge
libgcc-ng 11.1.0 hc902ee8_8 conda-forge
libgfortran-ng 7.5.0 h14aa051_19 conda-forge
libgfortran4 7.5.0 h14aa051_19 conda-forge
libglib 2.68.1 h3e27bee_0 conda-forge
libgomp 11.1.0 hc902ee8_8 conda-forge
libhwloc 2.4.1 h6746aa3_0 conda-forge
libiconv 1.16 h516909a_0 conda-forge
liblapack 3.9.0 8_mkl conda-forge
libllvm10 10.0.1 he513fc3_3 conda-forge
libllvm11 11.1.0 hf817b99_2 conda-forge
libnetcdf 4.7.4 nompi_h56d31a8_107 conda-forge
libnghttp2 1.43.0 h812cca2_0 conda-forge
libogg 1.3.4 h7f98852_1 conda-forge
libopus 1.3.1 h7f98852_1 conda-forge
libpng 1.6.37 h21135ba_2 conda-forge
libpq 13.3 hd57d9b9_0 conda-forge
libprotobuf 3.16.0 h780b84a_0 conda-forge
libsodium 1.0.18 h516909a_1 conda-forge
libssh2 1.9.0 ha56f1ee_6 conda-forge
libstdcxx-ng 11.2.0 he4da1e4_9 conda-forge
libtiff 4.3.0 hf544144_1 conda-forge
libuuid 2.32.1 h7f98852_1000 conda-forge
libuv 1.41.0 h7f98852_0 conda-forge
libvorbis 1.3.7 he1b5a44_0 conda-forge
libwebp-base 1.2.0 h7f98852_2 conda-forge
libxcb 1.13 h7f98852_1003 conda-forge
libxkbcommon 1.0.3 he3ba5ed_0 conda-forge
libxml2 2.9.10 h72842e0_4 conda-forge
llvm-openmp 11.1.0 h4bd325d_1 conda-forge
llvmlite 0.36.0 py38h4630a5e_0 conda-forge
locket 0.2.1 py38h06a4308_1
lz4-c 1.9.3 h9c3ff4c_0 conda-forge
lzo 2.10 h516909a_1000 conda-forge
magma 2.5.4 h5da55e3_2 conda-forge
markupsafe 1.1.1 py38h497a2fe_3 conda-forge
matplotlib-base 3.4.1 py38hcc49a3a_0 conda-forge
mdtraj 1.9.5 py38hbcc7ddf_1 conda-forge
mistune 0.8.4 py38h497a2fe_1003 conda-forge
mkl 2020.4 h726a3e6_304 conda-forge
mkl-service 2.3.0 py38h1e0a361_2 conda-forge
mmpbsa-py 16.0 pypi_0 pypi
mock 4.0.3 py38h578d9bd_1 conda-forge
more-itertools 8.9.0 pyhd8ed1ab_0 conda-forge
mpiplus v0.0.1 py38h32f6830_1002 conda-forge
msgpack-python 1.0.2 py38h1fd1430_1 conda-forge
mysql-common 8.0.25 ha770c72_2 conda-forge
mysql-libs 8.0.25 hfa10184_2 conda-forge
nbclient 0.5.3 pyhd8ed1ab_0 conda-forge
nbconvert 6.0.7 py38h578d9bd_3 conda-forge
nbformat 5.1.3 pyhd8ed1ab_0 conda-forge
nccl 2.10.3.1 h1a5f58c_0 conda-forge
ncurses 6.2 h58526e2_4 conda-forge
nest-asyncio 1.5.1 pyhd8ed1ab_0 conda-forge
netcdf-fortran 4.5.3 nompi_hfef6a68_101 conda-forge
netcdf4 1.5.6 nompi_py38hf887595_102 conda-forge
networkx 2.5.1 pyhd8ed1ab_0 conda-forge
ninja 1.10.2 h4bd325d_0 conda-forge
nose 1.3.7 pyhd3eb1b0_1006
notebook 6.3.0 py38h578d9bd_0 conda-forge
nspr 4.30 h9c3ff4c_0 conda-forge
nss 3.64 hb5efdd6_0 conda-forge
numba 0.53.1 py38h8b71fd7_1 conda-forge
numexpr 2.7.3 py38h51da96c_0 conda-forge
numpy 1.20.2 py38h9894fe3_0 conda-forge
ocl-icd 2.3.0 h7f98852_0 conda-forge
ocl-icd-system 1.0.0 1 conda-forge
olefile 0.46 pyh9f0ad1d_1 conda-forge
openbabel 3.1.1 py38hf4b5c11_1 conda-forge
openff-forcefields 2.0.0 pyh6c4a22f_0 conda-forge
openff-toolkit 0.10.0+18.gf5b5558f dev_0 <develop>
openjpeg 2.4.0 hf7af979_0 conda-forge
openmm 7.6.0 pypi_0 pypi
openmmml 1.0 dev_0 <develop>
openmmtools 0.20.3+3.g5b46695 dev_0 <develop>
openmmtorch 1.0 pypi_0 pypi
openssl 1.1.1l h7f98852_0 conda-forge
packaging 20.9 pyh44b312d_0 conda-forge
packmol-memgen 1.1.0rc0 pypi_0 pypi
pandas 1.2.4 py38h1abd341_0 conda-forge
pandoc 2.12 h7f98852_0 conda-forge
pandocfilters 1.4.3 py38h06a4308_1
parmed at20RC5+54.g5702a232fe.dirty pypi_0 pypi
parso 0.8.2 pyhd8ed1ab_0 conda-forge
partd 1.2.0 pyhd8ed1ab_0 conda-forge
pcre 8.44 he1b5a44_0 conda-forge
pdb4amber 1.7.dev0 pypi_0 pypi
pdbfixer 1.8 dev_0 <develop>
perl 5.32.0 h36c2ea0_0 conda-forge
pexpect 4.8.0 py38h32f6830_1 conda-forge
pickleshare 0.7.5 py38h32f6830_1002 conda-forge
pillow 8.1.2 py38ha0e1e83_1 conda-forge
pip 21.0.1 pyhd8ed1ab_0 conda-forge
pixman 0.40.0 h36c2ea0_0 conda-forge
pluggy 0.13.1 py38h578d9bd_4 conda-forge
prometheus_client 0.10.1 pyhd8ed1ab_0 conda-forge
prompt-toolkit 3.0.18 pyha770c72_0 conda-forge
prompt_toolkit 3.0.18 hd8ed1ab_0 conda-forge
psutil 5.8.0 py38h497a2fe_1 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 py38hf61ee4a_1 conda-forge
pycparser 2.20 pyh9f0ad1d_2 conda-forge
pygments 2.8.1 pyhd8ed1ab_0 conda-forge
pymbar 3.0.5 py38h5c078b8_2 conda-forge
pyopenssl 20.0.1 pyhd8ed1ab_0 conda-forge
pyparsing 2.4.7 pyh9f0ad1d_0 conda-forge
pyqt 5.12.3 py38h578d9bd_7 conda-forge
pyqt-impl 5.12.3 py38h7400c14_7 conda-forge
pyqt5-sip 4.19.18 py38h709712a_7 conda-forge
pyqtchart 5.12 py38h7400c14_7 conda-forge
pyqtwebengine 5.12.1 py38h7400c14_7 conda-forge
pyrsistent 0.17.3 py38h497a2fe_2 conda-forge
pysocks 1.7.1 py38h578d9bd_3 conda-forge
pytables 3.6.1 py38hc386592_3 conda-forge
pytest 6.2.5 py38h578d9bd_0 conda-forge
python 3.8.5 h7579374_1
python-dateutil 2.8.1 py_0 conda-forge
python_abi 3.8 1_cp38 conda-forge
pytorch 1.7.1 cuda102py38h9f8c3ab_1 conda-forge
pytorch-gpu 1.7.1 cuda102py38hf05f184_1 conda-forge
pytraj 2.0.5 pypi_0 pypi
pytz 2021.1 pyhd8ed1ab_0 conda-forge
pyyaml 5.4.1 py38h497a2fe_0 conda-forge
pyzmq 22.0.3 py38h2035c66_1 conda-forge
qt 5.12.9 hda022c4_4 conda-forge
qtconsole 5.0.3 pyhd8ed1ab_0 conda-forge
qtpy 1.9.0 py_0 conda-forge
rdkit 2020.09.3 py38h3f7302f_0 conda-forge
readline 8.1 h46c0cb4_0 conda-forge
reportlab 3.5.67 py38hadf75a6_0 conda-forge
requests 2.25.1 pyhd3deb0d_0 conda-forge
rhash 1.4.1 h7f98852_0 conda-forge
sander 16.0 pypi_0 pypi
scipy 1.6.2 py38h91f5cce_0
send2trash 1.5.0 py_0 conda-forge
setuptools 49.6.0 py38h578d9bd_3 conda-forge
six 1.15.0 pyh9f0ad1d_0 conda-forge
sleef 3.5.1 h28343ad_2 conda-forge
smirnoff99frosst 1.1.0 pyh44b312d_0 conda-forge
snappy 1.1.8 he1b5a44_3 conda-forge
sortedcontainers 2.4.0 pyhd8ed1ab_0 conda-forge
sqlalchemy 1.4.10 py38h497a2fe_0 conda-forge
sqlite 3.35.4 h74cdb3f_0 conda-forge
tblib 1.7.0 pyhd8ed1ab_0 conda-forge
terminado 0.9.4 py38h578d9bd_0 conda-forge
testpath 0.4.4 py_0 conda-forge
tk 8.6.10 h21135ba_1 conda-forge
toml 0.10.2 pyhd8ed1ab_0 conda-forge
toolz 0.11.1 py_0 conda-forge
torchani 2.2 pyh9f0ad1d_0 conda-forge
tornado 6.1 py38h497a2fe_1 conda-forge
traitlets 5.0.5 py_0 conda-forge
typing_extensions 3.7.4.3 py_0 conda-forge
urllib3 1.26.4 pyhd8ed1ab_0 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 py38h578d9bd_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 h7f98852_0 conda-forge
xorg-libsm 1.2.3 hd9c2040_1000 conda-forge
xorg-libx11 1.7.0 h7f98852_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 h7f98852_1 conda-forge
xorg-libxrender 0.9.10 h7f98852_1003 conda-forge
xorg-libxt 1.2.1 h7f98852_2 conda-forge
xorg-renderproto 0.11.1 h7f98852_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.4 h9c3ff4c_0 conda-forge
zict 2.0.0 py_0 conda-forge
zipp 3.4.1 pyhd8ed1ab_0 conda-forge
zlib 1.2.11 h516909a_1010 conda-forge
zstd 1.5.0 ha95c52a_0 conda-forge
Thanks for the report! I can reproduce this and I agree it's a bug. I can't offer a solution or quick workaround at the moment (barring an OpenEye license).
This root of this is that the molecule doesn't survive our round-trips with RDKit:
>>> from openff.toolkit.topology import Molecule, Topology
>>> mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C(C#N)\\N=C/C(C)=C\\N/C(C#N)=C(C#N)/N=C\\1')
>>> mol.to_rdkit()
[11:52:10] Conflicting single bond directions around double bond at index 6.
[11:52:10] BondStereo set to STEREONONE and single bond directions set to NONE.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mwt/miniconda3/envs/openff-system/lib/python3.9/site-packages/openff/toolkit/utils/base_wrapper.py", line 51, in wrapped_function
value = func(*args, **kwargs)
File "/Users/mwt/miniconda3/envs/openff-system/lib/python3.9/site-packages/openff/toolkit/topology/molecule.py", line 5157, in to_rdkit
return toolkit.to_rdkit(self, aromaticity_model=aromaticity_model)
File "/Users/mwt/miniconda3/envs/openff-system/lib/python3.9/site-packages/openff/toolkit/utils/rdkit_wrapper.py", line 1793, in to_rdkit
cls._assign_rdmol_bonds_stereo(molecule, rdmol)
File "/Users/mwt/miniconda3/envs/openff-system/lib/python3.9/site-packages/openff/toolkit/utils/rdkit_wrapper.py", line 2405, in _assign_rdmol_bonds_stereo
assert stereo_rdbond.GetStereo() == desired_rdk_stereo_code
AssertionError
As a separate issue, there are probably other ways to do this "is the molecule already in my set of reference molecules?" check here. This will magically dissipate when the TopologyMolecule paradigm is deprecated. Changing that logic in the mean time would side-step this issue, except it could push failures to a different stage in a pipeline.
FWIW these behaviors are specific to the RDKit interface; none pop up using OpenEye toolkits. (Not suggesting this as a solution, only as information for diagnosing the issue.)
Summary
After some digging, I don't have an answer here. I think the following may be good next directions to pursue:
- Something about the parity of the number of bond stereomarks (
/and\) in the circular structure may make it impossible to represent the desired stereoisomer - Something about OpenFF's internal use of CIP stereo (#139) may be getting mangled during sanitization in to/from rdkit conversions.
- Disagreement between aromaticity models/whether an aromatic bond has stereo is losing info/getting things confused
- (unlikely) RDKit has a heuristic that thinks this structure/stereoisomer is totally unreasonable
Detailed notes
Yeah, super odd that this works using the OpenEyeToolkitWrapper, but not the RDKitToolkitWrapper. For reference, the specific molecule in question, loaded using the OpenEyeToolkitWrapper, visualizes like this:
mol.visualize(backend='openeye')
mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C(C#N)\\N=C/C(C)=C\\N/C(C#N)=C(C#N)/N=C\\1')

Except that 2D structure is wrong. On one side of the macrocycle, the pair of nitrile groups should be trans- to each other according to the input SMILES, and on the other side they should be cis- to each other. However, in the depiction above, BOTH pairs of nitrile substituents are cis- to each other.
If I have OE generate conformers and look in 3D, the correct stereochemistry is obeyed, but the molecule seems very strained (it is folded like a hot dog, which seems to be at odds with its aromaticness).
mol.generate_conformers()
mol.visualize(backend='nglview')
If I chop off all the nitriles, I still get success from OpenEye:
mol = Molecule.from_smiles('CC1=C/N/C=C\\N=C/C(C)=C\\N/C=C/N=C\\1')

and now I also get success from RDKit, though either the drawing code isn't giving me a nice structure or the bond stereo is off:
And I can actually keep two on the nitriles in the structure and be fine, they just can't be next to each other:
mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C\\N=C/C(C)=C\\N/C=C(C#N)/N=C\\1') # works in both, nitriles far from each other
OE:

RDK:

If I put them next to each other, only the OE wrapper works:
mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C(C#N)\\N=C/C(C)=C\\N/C=C/N=C\\1') # nitriles adjacent, breaks rdkitwrapper

For what it's worth, here is the molecule in question: https://pubchem.ncbi.nlm.nih.gov/substance/135240687
Here's another one I found that produces an exception, but this time when I try to canonicalize the atom order.
>>> mol = Molecule.from_smiles('COc1ccc(/N=C(NO)/C(C)=N/N=C/c2ccc(OC)cc2OC)cc1')
>>> mol.canonical_order_atoms()
[08:11:31] Conflicting single bond directions around double bond at index 0.
[08:11:31] BondStereo set to STEREONONE and single bond directions set to NONE.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/topology/molecule.py", line 2603, in __repr__
self.name, self.to_smiles()
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/topology/molecule.py", line 2730, in to_smiles
smiles = to_smiles_method(self, isomeric, explicit_hydrogens, mapped)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 667, in to_smiles
rdmol = self.to_rdkit(molecule)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 1774, in to_rdkit
cls._assign_rdmol_bonds_stereo(molecule, rdmol)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 2382, in _assign_rdmol_bonds_stereo
cls._flip_rdbond_direction(flipped_rdbond, paired_bonds)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 2307, in _flip_rdbond_direction
_flip(rdbond, paired_rdbonds, flipped=set(), ignored=None)
File "/home/peastman/workspace/openff-toolkit/openff/toolkit/utils/rdkit_wrapper.py", line 2281, in _flip
assert b.GetBondDir() in supported_directions
AssertionError
I can no longer reproduce the original behavior
>>> from openff.toolkit import Molecule, Topology, __version__
>>> __version__
'0.12.0'
>>> mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C(C#N)\\N=C/C(C)=C\\N/C(C#N)=C(C#N)/N=C\\1')
>>> top = Topology()
>>> top.add_molecule(mol)
1
>>> from openff.toolkit.utils.toolkits import GLOBAL_TOOLKIT_REGISTRY, OpenEyeToolkitWrapper
>>> GLOBAL_TOOLKIT_REGISTRY.deregister_toolkit(OpenEyeToolkitWrapper)
>>> mol = Molecule.from_smiles('CC1=C/N/C(C#N)=C(C#N)\\N=C/C(C)=C\\N/C(C#N)=C(C#N)/N=C\\1')
>>> top = Topology()
>>> top.add_molecule(mol)
1
>>> GLOBAL_TOOLKIT_REGISTRY.registered_toolkit_versions
{'The RDKit': '2022.09.1', 'AmberTools': '22.0', 'Built-in Toolkit': None}
nor the snippet in the comment just prior to this one:
>>> from openff.toolkit import Molecule, Topology, __version__
>>> __version__
'0.12.0'
>>> mol = Molecule.from_smiles('COc1ccc(/N=C(NO)/C(C)=N/N=C/c2ccc(OC)cc2OC)cc1')
>>>
>>> mol.canonical_order_atoms()
Molecule with name '' and SMILES '[H]c1c(c(c(c(c1/C(=N/N=C(/C(=N/c2c(c(c(c(c2[H])[H])OC([H])([H])[H])[H])[H])/N([H])O[H])\C([H])([H])[H])/[H])OC([H])([H])[H])[H])OC([H])([H])[H])[H]'
>>> from openff.toolkit.utils.toolkits import GLOBAL_TOOLKIT_REGISTRY, OpenEyeToolkitWrapper
>>> GLOBAL_TOOLKIT_REGISTRY.deregister_toolkit(OpenEyeToolkitWrapper)
>>> mol = Molecule.from_smiles('COc1ccc(/N=C(NO)/C(C)=N/N=C/c2ccc(OC)cc2OC)cc1')
>>> mol.canonical_order_atoms()
Molecule with name '' and SMILES '[H][O][N]([H])[C](=[N]\[c]1[c]([H])[c]([H])[c]([O][C]([H])([H])[H])[c]([H])[c]1[H])/[C](=[N]/[N]=[C](\[H])[c]1[c]([H])[c]([H])[c]([O][C]([H])([H])[H])[c]([H])[c]1[O][C]([H])([H])[H])[C]([H])([H])[H]'
>>> >>> GLOBAL_TOOLKIT_REGISTRY.registered_toolkit_versions
{'The RDKit': '2022.09.1', 'AmberTools': '22.0', 'Built-in Toolkit': None}
I'm not sure what exactly fixed this - maybe #1190?