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

charge_from_molecules silently ignores isomorphic molecules in list, only using the first entry #1058

Open
IAlibay opened this issue Sep 20, 2024 · 2 comments · May be fixed by #1070
Open

Comments

@IAlibay
Copy link

IAlibay commented Sep 20, 2024

Description

Passing two isomorphic Molecules with different partial charges to from_smirnoff's charge_from_molecules flag will lead to partial charges only being assigned from the first Molecule.

Reproduction

from openff.toolkit import Molecule, Topology, ForceField
from openff.interchange.components._packmol import solvate_topology_nonwater
from openff.interchange import Interchange
import pytest

solvent = Molecule.from_smiles('c1ccccc1')
solvent.assign_partial_charges(partial_charge_method='gasteiger')
print("solvent charges: ", solvent.partial_charges)

ligand = Molecule.from_smiles('c1ccccc1')
ligand.generate_conformers()
ligand.assign_partial_charges(partial_charge_method='am1bcc')
print("ligand charges: ", ligand.partial_charges)

print("molecules are isomorphic: ", ligand.is_isomorphic_with(solvent))

off_top = Topology.from_molecules(ligand)
solvated_off_top = solvate_topology_nonwater(topology=off_top, solvent=solvent)

ff = ForceField('openff-2.2.0.offxml', 'opc.offxml')
inter = Interchange.from_smirnoff(topology=solvated_off_top, force_field=ff, charge_from_molecules=[ligand, solvent])

for _, c in inter.collections["Electrostatics"].charges.items():
    assert abs(c.m) == pytest.approx(0.13)
    
inter = Interchange.from_smirnoff(topology=solvated_off_top, force_field=ff, charge_from_molecules=[solvent, ligand])

for _, c in inter.collections["Electrostatics"].charges.items():
    assert abs(c.m) == pytest.approx(0.06226857)

Output

solvent charges:  [-0.062268570782092456 -0.062268570782092456 -0.062268570782092456 -0.062268570782092456 -0.062268570782092456 -0.062268570782092456 0.062268570782092456 0.062268570782092456 0.062268570782092456 0.062268570782092456 0.062268570782092456 0.062268570782092456] elementary_charge
ligand charges:  [-0.13 -0.13 -0.13 -0.13 -0.13 -0.13 0.13 0.13 0.13 0.13 0.13 0.13] elementary_charge
molecules are isomorphic:  True

Software versions

Interchange v0.3.29

@mattwthompson
Copy link
Member

That doesn't seem good!

SMIRNOFF doesn't help in this case:

In our reference implementation of SMIRNOFF in the OpenFF Toolkit, we also provide a method for specifying user-defined partial charges during system creation. This functionality is accessed by using the charge_from_molecules optional argument during system creation, such as in ForceField.create_openmm_system(topology, charge_from_molecules=molecule_list). When this optional keyword is provided, all matching molecules will have their charges set by the entries in molecule_list. This method is provided solely for convenience in developing and exploring alternative charging schemes; actual force field releases for distribution will use one of the other mechanisms specified above.

so I'm going to decide we're on our own in deciding how this behavior should work.

Simple ideas first - forbid isomorphic molecules from appearing in this list multiple times? This would be straightforward to implement, just de-duplicating everything into a set using a key that would collide isomorphic molecules.

@IAlibay
Copy link
Author

IAlibay commented Sep 23, 2024

forbid isomorphic molecules from appearing in this list multiple times?

Raising an error and saying "nope don't do this" sounds like the right solution to me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants