Skip to content

Commit 1bdca46

Browse files
authored
Storing meta data in pmd structure (#496)
* storing meta data in pmd structure * Handle case where forcefield is missing non-bonded force section * add unit test * change pytest syntax to capture warning
1 parent 4a77c66 commit 1bdca46

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

foyer/forcefield.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
RBTorsionGenerator,
3030
_convertParameterToNumber,
3131
)
32+
from parmed.gromacs.gromacstop import _Defaults
3233
from pkg_resources import iter_entry_points, resource_filename
3334

3435
import foyer.element as custom_elem
@@ -782,7 +783,7 @@ def apply(
782783

783784
self._apply_typemap(structure, typemap)
784785

785-
return self.parametrize_system(
786+
structure = self.parametrize_system(
786787
structure=structure,
787788
references_file=references_file,
788789
assert_bond_params=assert_bond_params,
@@ -794,6 +795,31 @@ def apply(
794795
**kwargs,
795796
)
796797

798+
# Start storing scaling factors and combining rule to parmed structure
799+
# Utilizing parmed gromactop's _Default class
800+
801+
# Note: nb_func = 1 (LJ) or 2 (Buckingham), foyer forcefield only support 1 at the moment
802+
# Combining rule follow GROMACS scheme, where "lorentz" is 2 and "geometric" is 3
803+
combining_rules = {"lorentz": 2, "geometric": 3}
804+
gen_pairs = "yes" if structure.adjusts else "no"
805+
try:
806+
lj14scale = self.lj14scale
807+
coulomb14scale = self.coulomb14scale
808+
structure.defaults = _Defaults(
809+
nbfunc=1,
810+
comb_rule=combining_rules[self.combining_rule],
811+
gen_pairs=gen_pairs,
812+
fudgeLJ=lj14scale,
813+
fudgeQQ=coulomb14scale,
814+
)
815+
except AttributeError:
816+
warnings.warn(
817+
"Missing lj14scale or coulomb14scale, could not set structure metadata."
818+
)
819+
structure.defaults = None
820+
821+
return structure
822+
797823
def run_atomtyping(self, structure, use_residue_map=True, **kwargs):
798824
"""Atomtype the topology.
799825

foyer/tests/test_forcefield.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import parmed as pmd
88
import pytest
99
from lxml import etree as ET
10+
from parmed.gromacs.gromacstop import _Defaults
1011
from pkg_resources import resource_filename
1112

1213
from foyer import Forcefield, forcefields
@@ -94,6 +95,17 @@ def test_from_parmed(self, oplsaa):
9495

9596
assert ethane.box_vectors == mol2.box_vectors
9697

98+
def test_structure_meta(self, oplsaa):
99+
mol2 = pmd.load_file(get_fn("ethane.mol2"), structure=True)
100+
ethane = oplsaa.apply(mol2)
101+
102+
assert isinstance(ethane.defaults, _Defaults)
103+
assert ethane.defaults.nbfunc == 1
104+
assert ethane.defaults.comb_rule == 3
105+
assert ethane.defaults.fudgeLJ == oplsaa.lj14scale
106+
assert ethane.defaults.fudgeQQ == oplsaa.coulomb14scale
107+
assert ethane.defaults.gen_pairs == "yes"
108+
97109
@pytest.mark.skipif(not has_mbuild, reason="mbuild is not installed")
98110
def test_from_mbuild(self, oplsaa):
99111
import mbuild as mb
@@ -426,7 +438,10 @@ def test_allow_empty_def(self):
426438
ethane = mb.load(get_fn("ethane.mol2"))
427439
with pytest.warns(ValidationWarning):
428440
ff = Forcefield(forcefield_files=get_fn("empty_def.xml"))
429-
ff.apply(ethane)
441+
442+
with pytest.warns(UserWarning):
443+
typed = ff.apply(ethane)
444+
assert typed.defaults is None
430445

431446
@pytest.mark.skipif(not has_mbuild, reason="mbuild is not installed")
432447
def test_assert_bonds(self):

0 commit comments

Comments
 (0)