Updated forcefield parameters are being ignored when creating an `Interchange` due to caching
Description
In openff-interchange 0.4.1+, parameters are cached when creating a new Interchange. When the ForceField is updated with new parameters, these are ignored when creating another Interchange and the cached parameters are used instead. This is causing issues with Forcebalance, which creates many Interchange objects with slightly modified parameters.
It would be helpful if there was a way to turn off parameter caching in openff-interchange so that these issues could be avoided.
Reproduction
Running any forcebalance torsion-drive calculation with a SMIRNOFF forcefield fails because identical potential energies are being calculated for all modified forcefields. A minimal example is:
from forcebalance import smirnoffio
from openff.toolkit import ForceField, Molecule
from openff.interchange import Interchange
ff = ForceField('openff_unconstrained-2.2.1.offxml')
mol = Molecule.from_smiles('CC')
interchange = Interchange.from_smirnoff(ff, mol.to_topology())
print(interchange["ProperTorsions"].potentials)
smirnoffio.assign_openff_parameter(ff, 0.25, "ProperTorsions/Proper/k1/[#1:1]-[#6X4:2]-[#6X4:3]-[#1:4]")
interchange = Interchange.from_smirnoff(ff, mol.to_topology())
print(interchange["ProperTorsions"].potentials)
Output
With interchange v0.4.2, k is not updated:
{PotentialKey associated with handler 'ProperTorsions' with id '[#1:1]-[#6X4:2]-[#6X4:3]-[#1:4]', mult 0: Potential(parameters={'k': <Quantity(0.239039384, 'kilocalorie / mole')>, 'periodicity': <Quantity(3, 'dimensionless')>, 'phase': <Quantity(0.0, 'degree')>, 'idivf': <Quantity(1.0, 'dimensionless')>}, map_key=None)}
{PotentialKey associated with handler 'ProperTorsions' with id '[#1:1]-[#6X4:2]-[#6X4:3]-[#1:4]', mult 0: Potential(parameters={'k': <Quantity(0.239039384, 'kilocalorie / mole')>, 'periodicity': <Quantity(3, 'dimensionless')>, 'phase': <Quantity(0.0, 'degree')>, 'idivf': <Quantity(1.0, 'dimensionless')>}, map_key=None)}
With interchange v0.4.0, k is updated correctly:
{PotentialKey associated with handler 'ProperTorsions' with id '[#1:1]-[#6X4:2]-[#6X4:3]-[#1:4]', mult 0: Potential(parameters={'k': <Quantity(0.239039384, 'kilocalorie / mole')>, 'periodicity': <Quantity(3, 'dimensionless')>, 'phase': <Quantity(0.0, 'degree')>, 'idivf': <Quantity(1.0, 'dimensionless')>}, map_key=None)}
{PotentialKey associated with handler 'ProperTorsions' with id '[#1:1]-[#6X4:2]-[#6X4:3]-[#1:4]', mult 0: Potential(parameters={'k': <Quantity(0.25, 'kilocalorie / mole')>, 'periodicity': <Quantity(3, 'dimensionless')>, 'phase': <Quantity(0.0, 'degree')>, 'idivf': <Quantity(1.0, 'dimensionless')>}, map_key=None)}
Software versions
- Which operating system and version are you using?
Ubuntu 22.04.5 LTS
- How did you install Interchange?
conda install -c conda-forge openff-interchange=0.4.2
- What is the output of running
conda list?
Note, we have also patched forcebalance due to the interchange handlers deprecation
# packages in environment at /data/thomasp/miniconda3/envs/fb_196_np2:
#
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-forge
_openmp_mutex 4.5 2_gnu conda-forge
ambertools 23.6 cuda_None_nompi_py311h4a53416_105 conda-forge
amberutils 21.0 pypi_0 pypi
annotated-types 0.7.0 pyhd8ed1ab_1 conda-forge
anyio 4.9.0 pyh29332c3_0 conda-forge
argon2-cffi 23.1.0 pyhd8ed1ab_1 conda-forge
argon2-cffi-bindings 21.2.0 py311h9ecbd09_5 conda-forge
arpack 3.9.1 nompi_hf03ea27_102 conda-forge
arrow 1.3.0 pyhd8ed1ab_1 conda-forge
asttokens 3.0.0 pyhd8ed1ab_1 conda-forge
async-lru 2.0.5 pyh29332c3_0 conda-forge
attrs 25.3.0 pyh71513ae_0 conda-forge
babel 2.17.0 pyhd8ed1ab_0 conda-forge
beautifulsoup4 4.13.4 pyha770c72_0 conda-forge
binutils_impl_linux-64 2.43 h4bf12b8_4 conda-forge
bleach 6.2.0 pyh29332c3_4 conda-forge
bleach-with-css 6.2.0 h82add2a_4 conda-forge
blosc 1.21.6 he440d0b_1 conda-forge
brotli 1.1.0 hb9d3cd8_2 conda-forge
brotli-bin 1.1.0 hb9d3cd8_2 conda-forge
brotli-python 1.1.0 py311hfdbb021_2 conda-forge
bson 0.5.10 pyhd8ed1ab_0 conda-forge
bzip2 1.0.8 h4bc722e_7 conda-forge
c-ares 1.34.5 hb9d3cd8_0 conda-forge
c-blosc2 2.17.1 h3122c55_0 conda-forge
ca-certificates 2025.4.26 hbd8a1cb_0 conda-forge
cached-property 1.5.2 hd8ed1ab_1 conda-forge
cached_property 1.5.2 pyha770c72_1 conda-forge
cachetools 6.0.0 pyhd8ed1ab_0 conda-forge
cairo 1.18.4 h3394656_0 conda-forge
certifi 2025.4.26 pyhd8ed1ab_0 conda-forge
cffi 1.17.1 py311hf29c0ef_0 conda-forge
chardet 5.2.0 pyhd8ed1ab_3 conda-forge
charset-normalizer 3.4.2 pyhd8ed1ab_0 conda-forge
colorama 0.4.6 pyhd8ed1ab_1 conda-forge
comm 0.2.2 pyhd8ed1ab_1 conda-forge
conda-gcc-specs 15.1.0 hc55bae6_2 conda-forge
contourpy 1.3.2 py311hd18a35c_0 conda-forge
cudatoolkit 11.8.0 h4ba93d1_13 conda-forge
cycler 0.12.1 pyhd8ed1ab_1 conda-forge
debugpy 1.8.14 py311hfdbb021_0 conda-forge
decorator 5.2.1 pyhd8ed1ab_0 conda-forge
defusedxml 0.7.1 pyhd8ed1ab_0 conda-forge
edgembar 0.2 pypi_0 pypi
exceptiongroup 1.3.0 pyhd8ed1ab_0 conda-forge
executing 2.2.0 pyhd8ed1ab_0 conda-forge
fftw 3.3.10 nompi_hf1063bd_110 conda-forge
flexcache 0.3 pyhd8ed1ab_1 conda-forge
flexparser 0.4 pyhd8ed1ab_1 conda-forge
font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge
font-ttf-inconsolata 3.000 h77eed37_0 conda-forge
font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge
font-ttf-ubuntu 0.83 h77eed37_3 conda-forge
fontconfig 2.15.0 h7e30c49_1 conda-forge
fonts-conda-ecosystem 1 0 conda-forge
fonts-conda-forge 1 0 conda-forge
fonttools 4.58.1 py311h2dc5d0c_0 conda-forge
forcebalance 1.9.6 py311h2b7392c_2 conda-forge
fqdn 1.5.1 pyhd8ed1ab_1 conda-forge
freetype 2.13.3 ha770c72_1 conda-forge
freetype-py 2.3.0 pyhd8ed1ab_0 conda-forge
future 1.0.0 pyhd8ed1ab_2 conda-forge
gcc 15.1.0 h33e79ad_2 conda-forge
gcc_impl_linux-64 15.1.0 h4393ad2_2 conda-forge
greenlet 3.2.2 py311hfdbb021_0 conda-forge
h11 0.16.0 pyhd8ed1ab_0 conda-forge
h2 4.2.0 pyhd8ed1ab_0 conda-forge
hdf4 4.2.15 h2a13503_7 conda-forge
hdf5 1.14.6 nompi_h2d575fe_101 conda-forge
hpack 4.1.0 pyhd8ed1ab_0 conda-forge
httpcore 1.0.9 pyh29332c3_0 conda-forge
httpx 0.28.1 pyhd8ed1ab_0 conda-forge
hyperframe 6.1.0 pyhd8ed1ab_0 conda-forge
icu 75.1 he02047a_0 conda-forge
idna 3.10 pyhd8ed1ab_1 conda-forge
importlib-metadata 8.7.0 pyhe01879c_1 conda-forge
importlib_resources 6.5.2 pyhd8ed1ab_0 conda-forge
ipykernel 6.29.5 pyh3099207_0 conda-forge
ipython 9.2.0 pyhfb0248b_0 conda-forge
ipython_pygments_lexers 1.1.1 pyhd8ed1ab_0 conda-forge
ipywidgets 8.1.7 pyhd8ed1ab_0 conda-forge
isoduration 20.11.0 pyhd8ed1ab_1 conda-forge
jedi 0.19.2 pyhd8ed1ab_1 conda-forge
jinja2 3.1.6 pyhd8ed1ab_0 conda-forge
joblib 1.5.1 pyhd8ed1ab_0 conda-forge
json5 0.12.0 pyhd8ed1ab_0 conda-forge
jsonpointer 3.0.0 py311h38be061_1 conda-forge
jsonschema 4.24.0 pyhd8ed1ab_0 conda-forge
jsonschema-specifications 2025.4.1 pyh29332c3_0 conda-forge
jsonschema-with-format-nongpl 4.24.0 hd8ed1ab_0 conda-forge
jupyter-lsp 2.2.5 pyhd8ed1ab_1 conda-forge
jupyter_client 8.6.3 pyhd8ed1ab_1 conda-forge
jupyter_core 5.8.1 pyh31011fe_0 conda-forge
jupyter_events 0.12.0 pyh29332c3_0 conda-forge
jupyter_server 2.16.0 pyhe01879c_0 conda-forge
jupyter_server_terminals 0.5.3 pyhd8ed1ab_1 conda-forge
jupyterlab 4.4.3 pyhd8ed1ab_0 conda-forge
jupyterlab_pygments 0.3.0 pyhd8ed1ab_2 conda-forge
jupyterlab_server 2.27.3 pyhd8ed1ab_1 conda-forge
jupyterlab_widgets 3.0.15 pyhd8ed1ab_0 conda-forge
kernel-headers_linux-64 3.10.0 he073ed8_18 conda-forge
keyutils 1.6.1 h166bdaf_0 conda-forge
kiwisolver 1.4.7 py311hd18a35c_0 conda-forge
krb5 1.21.3 h659f571_0 conda-forge
lcms2 2.17 h717163a_0 conda-forge
ld_impl_linux-64 2.43 h712a8e2_4 conda-forge
lerc 4.0.0 h0aef613_1 conda-forge
libaec 1.1.3 h59595ed_0 conda-forge
libblas 3.9.0 31_h59b9bed_openblas conda-forge
libboost 1.84.0 h6c02f8c_7 conda-forge
libboost-python 1.84.0 py311h5b7b71f_7 conda-forge
libbrotlicommon 1.1.0 hb9d3cd8_2 conda-forge
libbrotlidec 1.1.0 hb9d3cd8_2 conda-forge
libbrotlienc 1.1.0 hb9d3cd8_2 conda-forge
libcblas 3.9.0 31_he106b2a_openblas conda-forge
libcurl 8.14.0 h332b0f4_0 conda-forge
libdeflate 1.24 h86f0d12_0 conda-forge
libedit 3.1.20250104 pl5321h7949ede_0 conda-forge
libev 4.33 hd590300_2 conda-forge
libexpat 2.7.0 h5888daf_0 conda-forge
libffi 3.4.6 h2dba641_1 conda-forge
libfreetype 2.13.3 ha770c72_1 conda-forge
libfreetype6 2.13.3 h48d6fc4_1 conda-forge
libgcc 15.1.0 h767d61c_2 conda-forge
libgcc-devel_linux-64 15.1.0 h4c094af_102 conda-forge
libgcc-ng 15.1.0 h69a702a_2 conda-forge
libgfortran 15.1.0 h69a702a_2 conda-forge
libgfortran-ng 15.1.0 h69a702a_2 conda-forge
libgfortran5 15.1.0 hcea5267_2 conda-forge
libglib 2.84.2 h3618099_0 conda-forge
libgomp 15.1.0 h767d61c_2 conda-forge
libiconv 1.18 h4ce23a2_1 conda-forge
libjpeg-turbo 3.1.0 hb9d3cd8_0 conda-forge
liblapack 3.9.0 31_h7ac8fdf_openblas conda-forge
liblzma 5.8.1 hb9d3cd8_1 conda-forge
libnetcdf 4.9.2 nompi_h0134ee8_117 conda-forge
libnghttp2 1.64.0 h161d5f1_0 conda-forge
libnsl 2.0.1 hd590300_0 conda-forge
libopenblas 0.3.29 pthreads_h94d23a6_0 conda-forge
libpng 1.6.47 h943b412_0 conda-forge
libpq 16.9 h87c4ccc_0 conda-forge
librdkit 2024.03.5 h79cfef2_3 conda-forge
libsanitizer 15.1.0 h97b714f_2 conda-forge
libsodium 1.0.20 h4ab18f5_0 conda-forge
libsqlite 3.49.2 hee588c1_0 conda-forge
libssh2 1.11.1 hcf80075_0 conda-forge
libstdcxx 15.1.0 h8f9b012_2 conda-forge
libstdcxx-ng 15.1.0 h4852527_2 conda-forge
libtiff 4.7.0 hf01ce69_5 conda-forge
libuuid 2.38.1 h0b41bf4_0 conda-forge
libwebp-base 1.5.0 h851e524_0 conda-forge
libxcb 1.17.0 h8a09558_0 conda-forge
libxcrypt 4.4.36 hd590300_1 conda-forge
libxml2 2.13.8 h4bc477f_0 conda-forge
libxslt 1.1.39 h76b75d6_0 conda-forge
libzip 1.11.2 h6991a6a_0 conda-forge
libzlib 1.3.1 hb9d3cd8_2 conda-forge
lxml 5.4.0 py311hbd2c71b_0 conda-forge
lz4-c 1.10.0 h5888daf_1 conda-forge
markupsafe 3.0.2 py311h2dc5d0c_1 conda-forge
matplotlib-base 3.10.3 py311h2b939e6_0 conda-forge
matplotlib-inline 0.1.7 pyhd8ed1ab_1 conda-forge
mda-xdrlib 0.2.0 pyhd8ed1ab_1 conda-forge
mdtraj 1.10.3 py311h2ed89a0_0 conda-forge
mistune 3.1.3 pyh29332c3_0 conda-forge
mmpbsa-py 16.0 pypi_0 pypi
munkres 1.1.4 pyh9f0ad1d_0 conda-forge
nbclient 0.10.2 pyhd8ed1ab_0 conda-forge
nbconvert-core 7.16.6 pyh29332c3_0 conda-forge
nbformat 5.10.4 pyhd8ed1ab_1 conda-forge
ncurses 6.5 h2d0b736_3 conda-forge
nest-asyncio 1.6.0 pyhd8ed1ab_1 conda-forge
netcdf-fortran 4.6.2 nompi_hee1cade_100 conda-forge
networkx 3.4.2 pyh267e887_2 conda-forge
nomkl 1.0 h5ca1d4c_0 conda-forge
notebook 7.4.3 pyhd8ed1ab_0 conda-forge
notebook-shim 0.2.4 pyhd8ed1ab_1 conda-forge
numexpr 2.10.2 py311h38b10cd_100 conda-forge
numpy 1.26.4 py311h64a7726_0 conda-forge
ocl-icd 2.3.3 hb9d3cd8_0 conda-forge
ocl-icd-system 1.0.0 1 conda-forge
opencl-headers 2024.10.24 h5888daf_0 conda-forge
openff-amber-ff-ports 0.0.4 pyhca7485f_0 conda-forge
openff-forcefields 2024.09.0 pyhff2d567_0 conda-forge
openff-interchange 0.4.2 pyhd8ed1ab_2 conda-forge
openff-interchange-base 0.4.2 pyhd8ed1ab_2 conda-forge
openff-toolkit 0.16.9 pyhd8ed1ab_0 conda-forge
openff-toolkit-base 0.16.9 pyhd8ed1ab_0 conda-forge
openff-units 0.2.2 pyhd8ed1ab_1 conda-forge
openff-utilities 0.1.15 pyhd8ed1ab_0 conda-forge
openjpeg 2.5.3 h5fbd93e_0 conda-forge
openmm 8.2.0 py311he5bdeac_2 conda-forge
openssl 3.5.0 h7b32b05_1 conda-forge
overrides 7.7.0 pyhd8ed1ab_1 conda-forge
packaging 25.0 pyh29332c3_1 conda-forge
packmol-memgen 2024.2.9 pypi_0 pypi
pandas 2.2.3 py311h7db5c69_3 conda-forge
pandocfilters 1.5.0 pyhd8ed1ab_0 conda-forge
panedr 0.8.0 pyhd8ed1ab_1 conda-forge
parmed 4.3.0 py311h8cc7b42_1 conda-forge
parso 0.8.4 pyhd8ed1ab_1 conda-forge
pcre2 10.45 hc749103_0 conda-forge
pdb4amber 22.0 pypi_0 pypi
perl 5.32.1 7_hd590300_perl5 conda-forge
pexpect 4.9.0 pyhd8ed1ab_1 conda-forge
pickleshare 0.7.5 pyhd8ed1ab_1004 conda-forge
pillow 11.2.1 py311h1322bbf_0 conda-forge
pint 0.23 pyhd8ed1ab_1 conda-forge
pip 25.1.1 pyh8b19718_0 conda-forge
pixman 0.46.0 h29eaf8c_0 conda-forge
pkgutil-resolve-name 1.3.10 pyhd8ed1ab_2 conda-forge
platformdirs 4.3.8 pyhe01879c_0 conda-forge
prometheus_client 0.22.0 pyhd8ed1ab_0 conda-forge
prompt-toolkit 3.0.51 pyha770c72_0 conda-forge
psutil 7.0.0 py311h9ecbd09_0 conda-forge
pthread-stubs 0.4 hb9d3cd8_1002 conda-forge
ptyprocess 0.7.0 pyhd8ed1ab_1 conda-forge
pure_eval 0.2.3 pyhd8ed1ab_1 conda-forge
py-cpuinfo 9.0.0 pyhd8ed1ab_1 conda-forge
pycairo 1.28.0 py311hd785cd9_0 conda-forge
pycparser 2.22 pyh29332c3_1 conda-forge
pydantic 2.11.4 pyh3cfb1c2_0 conda-forge
pydantic-core 2.33.2 py311hdae7d1d_0 conda-forge
pyedr 0.8.0 pyhd8ed1ab_1 conda-forge
pygments 2.19.1 pyhd8ed1ab_0 conda-forge
pymbar 3.1.1 py311h7c22f60_3 conda-forge
pymsmt 22.0 pypi_0 pypi
pyparsing 3.2.3 pyhd8ed1ab_1 conda-forge
pysocks 1.7.1 pyha55dd90_7 conda-forge
pytables 3.10.2 py311h9c973dd_4 conda-forge
python 3.11.12 h9e4cc4f_0_cpython conda-forge
python-constraint 1.4.0 pyhff2d567_1 conda-forge
python-dateutil 2.9.0.post0 pyhff2d567_1 conda-forge
python-fastjsonschema 2.21.1 pyhd8ed1ab_0 conda-forge
python-json-logger 2.0.7 pyhd8ed1ab_0 conda-forge
python-tzdata 2025.2 pyhd8ed1ab_0 conda-forge
python_abi 3.11 7_cp311 conda-forge
pytraj 2.0.6 pypi_0 pypi
pytz 2025.2 pyhd8ed1ab_0 conda-forge
pyyaml 6.0.2 py311h2dc5d0c_2 conda-forge
pyzmq 26.4.0 py311h7deb3e3_0 conda-forge
qhull 2020.2 h434a139_5 conda-forge
rdkit 2024.03.5 py311h845bd92_3 conda-forge
readline 8.2 h8c095d6_2 conda-forge
referencing 0.36.2 pyh29332c3_0 conda-forge
reportlab 4.4.1 py311h9ecbd09_0 conda-forge
requests 2.32.3 pyhd8ed1ab_1 conda-forge
rfc3339-validator 0.1.4 pyhd8ed1ab_1 conda-forge
rfc3986-validator 0.1.1 pyh9f0ad1d_0 conda-forge
rlpycairo 0.2.0 pyhd8ed1ab_0 conda-forge
rpds-py 0.25.1 py311hdae7d1d_0 conda-forge
sander 22.0 pypi_0 pypi
scipy 1.15.2 py311h8f841c2_0 conda-forge
send2trash 1.8.3 pyh0d859eb_1 conda-forge
setuptools 80.8.0 pyhff2d567_0 conda-forge
six 1.17.0 pyhd8ed1ab_0 conda-forge
smirnoff99frosst 1.1.0 pyh44b312d_0 conda-forge
snappy 1.2.1 h8bd8927_1 conda-forge
sniffio 1.3.1 pyhd8ed1ab_1 conda-forge
soupsieve 2.7 pyhd8ed1ab_0 conda-forge
sqlalchemy 2.0.41 py311h9ecbd09_0 conda-forge
stack_data 0.6.3 pyhd8ed1ab_1 conda-forge
sysroot_linux-64 2.17 h0157908_18 conda-forge
terminado 0.18.1 pyh0d859eb_0 conda-forge
tinycss2 1.4.0 pyhd8ed1ab_0 conda-forge
tk 8.6.13 noxft_hd72426e_102 conda-forge
tomli 2.2.1 pyhd8ed1ab_1 conda-forge
tornado 6.5.1 py311h9ecbd09_0 conda-forge
tqdm 4.67.1 pyhd8ed1ab_1 conda-forge
traitlets 5.14.3 pyhd8ed1ab_1 conda-forge
types-python-dateutil 2.9.0.20250516 pyhd8ed1ab_0 conda-forge
typing-extensions 4.13.2 h0e9735f_0 conda-forge
typing-inspection 0.4.1 pyhd8ed1ab_0 conda-forge
typing_extensions 4.13.2 pyh29332c3_0 conda-forge
typing_utils 0.1.0 pyhd8ed1ab_1 conda-forge
tzdata 2025b h78e105d_0 conda-forge
unicodedata2 16.0.0 py311h9ecbd09_0 conda-forge
uri-template 1.3.0 pyhd8ed1ab_1 conda-forge
urllib3 2.4.0 pyhd8ed1ab_0 conda-forge
wcwidth 0.2.13 pyhd8ed1ab_1 conda-forge
webcolors 24.11.1 pyhd8ed1ab_0 conda-forge
webencodings 0.5.1 pyhd8ed1ab_3 conda-forge
websocket-client 1.8.0 pyhd8ed1ab_1 conda-forge
wheel 0.45.1 pyhd8ed1ab_1 conda-forge
widgetsnbextension 4.0.14 pyhd8ed1ab_0 conda-forge
xmltodict 0.14.2 pyhd8ed1ab_1 conda-forge
xorg-libice 1.1.2 hb9d3cd8_0 conda-forge
xorg-libsm 1.2.6 he73a12e_0 conda-forge
xorg-libx11 1.8.12 h4f16b4b_0 conda-forge
xorg-libxau 1.0.12 hb9d3cd8_0 conda-forge
xorg-libxdmcp 1.1.5 hb9d3cd8_0 conda-forge
xorg-libxext 1.3.6 hb9d3cd8_0 conda-forge
xorg-libxrender 0.9.12 hb9d3cd8_0 conda-forge
xorg-libxt 1.3.1 hb9d3cd8_0 conda-forge
yaml 0.2.5 h7f98852_2 conda-forge
zeromq 4.3.5 h3b0a872_7 conda-forge
zipp 3.22.0 pyhd8ed1ab_0 conda-forge
zlib 1.3.1 hb9d3cd8_2 conda-forge
zlib-ng 2.2.4 h7955e40_0 conda-forge
zstandard 0.23.0 py311h9ecbd09_2 conda-forge
zstd 1.5.7 hb8e6e7a_2 conda-forge
Thanks for the detailed reproduction! This was introduced in https://github.com/openforcefield/openff-interchange/pull/1122. I hoped that hashing the input objects would prevent collisions, but unfortunately some hashes of toolkit objects are meaningless (https://github.com/openforcefield/openff-toolkit/issues/2065). Using lru_cache.cache_clear is the most obvious way around this:
from openff.toolkit import ForceField, Molecule, Quantity
from openff.interchange import Interchange
from openff.interchange.components.toolkit import _cache_torsion_parameter_lookup
def _print(handler):
print(hash(handler), id(handler))
def reset_cache():
_cache_torsion_parameter_lookup.cache_clear()
sage = ForceField("openff_unconstrained-2.2.1.offxml")
topology = Molecule.from_smiles("CC").to_topology()
interchange = Interchange.from_smirnoff(sage, topology)
print([*interchange["ProperTorsions"].potentials.values()][0].parameters["k"])
# 0.2390393844711
for reset in [False, True]:
if reset:
reset_cache()
# should be k = 1.0 on False iteration, k = 2.0 on True iteration
sage["ProperTorsions"]["[#1:1]-[#6X4:2]-[#6X4:3]-[#1:4]"].k1 = Quantity(float(1 + reset), "kilocalorie / mole")
interchange = Interchange.from_smirnoff(sage, topology)
print([*interchange["ProperTorsions"].potentials.values()][0].parameters["k"])
# 0.2390393844711 kilocalorie / mole on False iteration (bad)
# 2.0 kilocalorie / mole on False iteration (good)
I think the best long-term solution is to fix the hashing of parameter handlers. I'd recommend to the ForceBalance developers that a suitable short-term fix is to reach into the cache and turn it off at particular points, like above. But the solution you all have put together looks pretty good as well and might be more robust and without performance issues for small molecules.