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

Typing abstraction #9

Merged
merged 44 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
8332c40
Add Potential class
mattwthompson May 12, 2020
f691154
Update Potential class
mattwthompson May 13, 2020
b6bfc77
Make barebones system class
mattwthompson May 15, 2020
414453e
Merge branch 'master' into potential-1
mattwthompson May 18, 2020
c88302a
Merge branch 'master' into potential-1
mattwthompson May 18, 2020
f70fb5e
Update conda env
mattwthompson May 18, 2020
9cee3db
Update test structure
mattwthompson May 21, 2020
e9acbb6
Make separate classes for parametrized and un-parametrized potentials
mattwthompson May 21, 2020
09554cd
Store expressions as strings
mattwthompson May 21, 2020
b875977
Validate parameters with sympy and update tests
mattwthompson May 21, 2020
9c8ae08
Let independent_variables be a string
mattwthompson May 21, 2020
2531561
Copy evaluator simtk->pint function from evaluator
mattwthompson May 21, 2020
c92003e
Merge branch 'potential-1' into system-1
mattwthompson May 22, 2020
157b366
Add some templates for a class API
mattwthompson May 27, 2020
4cf3013
Merge remote-tracking branch 'origin/potential-1' into system-1
mattwthompson May 27, 2020
480e3d5
Add some basic classes
mattwthompson May 27, 2020
e575f28
Add a prototype with example
mattwthompson May 29, 2020
4b3fcee
Merge branch 'master' into system-1
mattwthompson May 29, 2020
30667ea
More clearly distinguish between toolkit and system objects and add t…
mattwthompson May 29, 2020
1ed5b1e
Add toolkit dependency
mattwthompson May 29, 2020
a12b9ff
Test constructing directly from toolkit objects
mattwthompson May 29, 2020
69c9260
Don't assume toolkit >0.7.0
mattwthompson Jun 1, 2020
d45af88
Directly use toolit atom
mattwthompson Jun 1, 2020
cd7f2f2
Add SMIRKS attribute
mattwthompson Jun 2, 2020
78710aa
Move System ForceField to PotentialCollection
mattwthompson Jun 2, 2020
b31fce0
Merge branch 'master' into potential-1
mattwthompson Jun 2, 2020
4af5cda
Switch to directly using toolkit topology
mattwthompson Jun 4, 2020
f38542d
Update gitignore
mattwthompson Jun 4, 2020
9a9148d
Rebrand System.forcefield to System.potential_collection
mattwthompson Jun 4, 2020
1732ce4
Start typing module
mattwthompson Jun 4, 2020
3ebf3bf
Remove un-used NumPy dependency
mattwthompson Jun 4, 2020
a33279c
Remove classes that mimic toolkit objects
mattwthompson Jun 4, 2020
e1dfa4a
Move SMIRNOFF-specific things into its own submodule, subclassing thi…
mattwthompson Jun 4, 2020
c8ae196
Astract ForceField into ParameterCollection
mattwthompson Jun 5, 2020
fce9b9a
Lint, fix imports
mattwthompson Jun 5, 2020
d027ed8
Rename and move around functions, fix tests
mattwthompson Jun 5, 2020
ed5d91f
Add SMIRNOFF example
mattwthompson Jun 5, 2020
3befc4b
Use the right notebook
mattwthompson Jun 5, 2020
58b6f2d
Merge branch 'potential-1' into typing-abstraction
mattwthompson Jun 5, 2020
90f2717
Add bond parameter parsing and update examples
mattwthompson Jun 5, 2020
1387fa4
Merge branch 'master' into typing-abstraction
mattwthompson Jun 5, 2020
b64c696
Initialize dicts to empty dicts, not None
mattwthompson Jun 5, 2020
e96a2c9
Assorted fixes
mattwthompson Jun 5, 2020
555ef46
Add ethanol example showing off loading Parsely and inspecting bond p…
mattwthompson Jun 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rebrand System.forcefield to System.potential_collection
  • Loading branch information
mattwthompson committed Jun 4, 2020
commit 9a9148d78f12de3ee233db550bc04f5386bbc9ca
98 changes: 66 additions & 32 deletions system/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,81 @@
from pydantic import BaseModel, validator
import pint

from openforcefield.typing.engines.smirnoff import ForceField as ToolkitForceField
from openforcefield.typing.engines.smirnoff import ForceField
from openforcefield.topology import Topology as ToolkitTopology
from openforcefield.topology.molecule import Atom as ToolkitAtom

from .potential import ParametrizedAnalyticalPotential as Potential
from .typing.smirnoff import build_slots_parameter_map
from .utils import simtk_to_pint


u = pint.UnitRegistry()


class PotentialHandler(BaseModel):

name: str
potentials: Dict[str, Potential] = None

def __getitem__(self, potential_smirks):
return self.potentials[potential_smirks]

def handler_conversion(forcefield, potential_collection, handler_name):
"""Temporary stand-in for .to_potential calls in toolkit ParameterHandler objects."""
if handler_name != 'vdW':
raise NotImplementedError

for param in forcefield.get_parameter_handler(handler_name).parameters:
if param.sigma is None:
sigma = 2. * param.rmin_half / (2.**(1. / 6.))
else:
sigma = param.sigma
sigma = simtk_to_pint(sigma)
epsilon = simtk_to_pint(param.epsilon)

potential = Potential(
name=param.id,
smirks=param.smirks,
expression='4*epsilon*((sigma/r)**12-(sigma/r)**6)',
independent_variables={'r'},
parameters={'sigma': sigma, 'epsilon': epsilon},
)

try:
potential_collection.handlers['vdW'][param.smirks] = potential
except (AttributeError, TypeError):
potential_collection.handlers = {
'vdW': PotentialHandler(
name='vdW',
potentials={
param.smirks: potential,
}
)

}

return potential_collection


class PotentialCollection(BaseModel):

parameters: Dict[str, Potential]
handlers: Dict[str, PotentialHandler] = None

@classmethod
def from_toolkit_forcefield(cls, toolkit_forcefield):

for param in toolkit_forcefield.get_parameter_handler('vdW').parameters:
if param.sigma is None:
sigma = 2. * param.rmin_half / (2.**(1. / 6.))
else:
sigma = param.sigma
sigma = simtk_to_pint(sigma)
epsilon = simtk_to_pint(param.epsilon)

potential = Potential(
name=param.id,
expression='4*epsilon*((sigma/r)**12-(sigma/r)**6)',
independent_variables={'r'},
parameters={'sigma': sigma, 'epsilon': epsilon},
)
toolkit_handlers = toolkit_forcefield._parameter_handlers.keys()
supported_handlers = ['vdW']

try:
forcefield.parameters[param.id] = potential
except UnboundLocalError:
forcefield = cls(parameters={param.id: potential})
for handler in toolkit_handlers:
if handler not in supported_handlers:
continue
handler_conversion(toolkit_forcefield, cls, handler)
return cls

return forcefield
def __getitem__(self, handler_name):
return self.handlers[handler_name]


class Atom(ToolkitAtom):
Expand Down Expand Up @@ -93,13 +129,14 @@ class System(BaseModel):
"""The OpenFF System object."""

topology: Union[Topology, ToolkitTopology]
forcefield: Union[PotentialCollection, ToolkitForceField]
potential_collection: Union[PotentialCollection, ForceField]
positions: Iterable = None
box: Iterable = None
slots_map: Dict = None

@validator("forcefield")
@validator("potential_collection")
def validate_forcefield(cls, val):
if isinstance(val, ToolkitForceField):
if isinstance(val, ForceField):
return PotentialCollection.from_toolkit_forcefield(val)
elif isinstance(val, PotentialCollection):
return val
Expand All @@ -123,14 +160,11 @@ class Config:
arbitrary_types_allowed = True

def run_typing(self, toolkit_forcefield, toolkit_topology):
# Only doing on vdW for now
matches = toolkit_forcefield.get_parameter_handler('vdW').find_matches(toolkit_topology)

typing_map = {}

for atom_key, atom_match in matches.items():
typing_map[atom_key[0]] = atom_match.parameter_type.id
self.topology.atoms[atom_key[0]].parameter_id = atom_match.parameter_type.id
"""Just store the slots map"""
self.slots_map = build_slots_parameter_map(
forcefield=toolkit_forcefield,
topology=toolkit_topology
)

def to_file(self):
raise NotImplementedError()
Expand Down
27 changes: 22 additions & 5 deletions system/tests/test_system.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
import pytest
import pint

from system import System, PotentialCollection, Topology
from system import System, PotentialHandler, PotentialCollection, Topology, handler_conversion
from system.tests.base_test import BaseTest


class TestForceField(BaseTest):
def test_forcefield_from_toolkit(self, argon_ff):
u = pint.UnitRegistry()

class TestPotentialHandler(BaseTest):
def test_handler_conversion(self, argon_ff):
collection = handler_conversion(
forcefield=argon_ff,
potential_collection=PotentialCollection(
parameters={
'vdW': PotentialHandler(name='vdW'),
}
),
handler_name='vdW',
)

assert collection['vdW']['[#18:1]'].parameters['sigma'] == 0.3 * u.nm

class TestPotentialCollection(BaseTest):
def test_potential_collection_from_toolkit(self, argon_ff):
ff = PotentialCollection.from_toolkit_forcefield(argon_ff)
assert ff is not None

Expand All @@ -21,14 +38,14 @@ def test_constructor(self, argon_ff, argon_top):
"""Test the basic constructor"""
System(
topology=argon_top,
forcefield=argon_ff,
potential_collection=argon_ff,
)

def test_run_typing(self, argon_ff, argon_top):
"""Test that run_typing properly stores the parameter id"""
test_system = System(
topology=argon_top,
forcefield=argon_ff,
potential_collection=argon_ff,
)

test_system.run_typing(
Expand Down