Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
4 changes: 2 additions & 2 deletions gmso/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,5 @@ def print_level(self, level: str):


# Example usage in __init__.py
gmso_logger = GMSOLogger()
gmso_logger.library_logger.setLevel(logging.INFO)
# gmso_logger = GMSOLogger()
# gmso_logger.library_logger.setLevel(logging.WARNING)
18 changes: 18 additions & 0 deletions gmso/abc/abstract_connection.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import itertools
from typing import Optional, Sequence

from pydantic import ConfigDict, Field, model_validator
Expand Down Expand Up @@ -111,3 +112,20 @@

def __str__(self):
return f"<{self.__class__.__name__} {self.name}, id: {id(self)}> "

def get_connection_identifiers(self):
from gmso.core.bond import Bond

Check notice

Code scanning / CodeQL

Cyclic import Note

Import of module
gmso.core.bond
begins an import cycle.

borderDict = {1: "-", 2: "=", 3: "#", 0: "~", None: "~", 1.5: ":"}
site_identifiers = [
(site.atom_type.atomclass, site.atom_type.name)
for site in self.connection_members
]
if isinstance(self, Bond):
bond_identifiers = [borderDict[self.bond_order]]
else:
bond_identifiers = [borderDict[b.bond_order] for b in self.bonds]
choices = [(aclass, atype, "*") for aclass, atype in site_identifiers]
choices += [(val, "~") for val in bond_identifiers]
all_combinations = itertools.product(*choices)
return all_combinations
45 changes: 44 additions & 1 deletion gmso/core/angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

from typing import Callable, ClassVar, Optional, Tuple

from pydantic import ConfigDict, Field
from pydantic import ConfigDict, Field, model_validator

from gmso.abc.abstract_connection import Connection
from gmso.core.angle_type import AngleType
from gmso.core.atom import Atom
from gmso.core.bond import Bond


class Angle(Connection):
Expand All @@ -26,12 +27,24 @@ class Angle(Connection):

__members_creator__: ClassVar[Callable] = Atom.model_validate

connectivity: ClassVar[Tuple[Tuple[int]]] = ((0, 1), (1, 2))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a description here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do we need an alias?


connection_members_: Tuple[Atom, Atom, Atom] = Field(
...,
description="The 3 atoms involved in the angle.",
alias="connection_members",
)

bonds_: Tuple[Bond, Bond] = Field(
default=None,
description="""
List of connection bonds.
Ordered to align with connection_members, such that self.bonds_[0] is
the bond between (self.connection_members[0], self.connection_members[1]).
""",
alias="bonds",
)

angle_type_: Optional[AngleType] = Field(
default=None,
description="AngleType of this angle.",
Expand All @@ -48,6 +61,7 @@ class Angle(Connection):
""",
alias="restraint",
)

model_config = ConfigDict(
alias_to_fields=dict(
**Connection.model_config["alias_to_fields"],
Expand All @@ -73,6 +87,24 @@ def restraint(self):
"""Return the restraint of this angle."""
return self.__dict__.get("restraint_")

@property
def bonds(self):
"""Return the bond_order symbol of this bond."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the doc string to say that it returns a tuple of gmso.core.Bond instances that make up this angle.

return self.__dict__.get("bonds_")

@bonds.setter
def bonds(self, bonds):
"""Return the bonds that makeup this Improper.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these doc strings aren't correct for this setter method?


Connectivity is ((0,1), (0,2), (0,3))
"""
self._bonds = bonds

@property
def bonds_orders(self):
"""Return the bond_order strings of this angle."""
return "".join([str(b.bond_order) for b in self.bonds])

def equivalent_members(self):
"""Return a set of the equivalent connection member tuples.

Expand All @@ -99,3 +131,14 @@ def __setattr__(self, key, value):
super(Angle, self).__setattr__("angle_type", value)
else:
super(Angle, self).__setattr__(key, value)

@model_validator(mode="before")
@classmethod
def set_dependent_value_default(cls, data):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a concise doc string for this method would be helpful.

if "bonds" not in data and "connection_members" in data:
atoms = data["connection_members"]
data["bonds"] = (
Bond(connection_members=(atoms[0], atoms[1])),
Bond(connection_members=(atoms[1], atoms[2])),
)
return data
15 changes: 15 additions & 0 deletions gmso/core/bond.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably have a bond_order setter in Bond

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Bond(Connection):

__members_creator__: ClassVar[Callable] = Atom.model_validate

connectivity: ClassVar[Tuple[Tuple[int]]] = ((0, 1),)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in angle.py. Do we need a description and alias here?


connection_members_: Tuple[Atom, Atom] = Field(
...,
description="The 2 atoms involved in the bond.",
Expand All @@ -46,12 +48,20 @@ class Bond(Connection):
""",
alias="restraint",
)

bond_order_: Optional[float] = Field(
default=None,
description="Bond order of this bond.",
alias="bond_order",
)

model_config = ConfigDict(
alias_to_fields=dict(
**Connection.model_config["alias_to_fields"],
**{
"bond_type": "bond_type_",
"restraint": "restraint_",
"bond_order": "bond_order_",
},
)
)
Expand All @@ -71,6 +81,11 @@ def restraint(self):
"""Return the restraint of this bond."""
return self.__dict__.get("restraint_")

@property
def bond_order(self):
"""Return the bond_order of this bond."""
return self.__dict__.get("bond_order_")

def equivalent_members(self):
"""Get a set of the equivalent connection member tuples.

Expand Down
49 changes: 48 additions & 1 deletion gmso/core/dihedral.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from typing import Callable, ClassVar, Optional, Tuple

from pydantic import ConfigDict, Field
from pydantic import ConfigDict, Field, model_validator

from gmso.abc.abstract_connection import Connection
from gmso.core.atom import Atom
from gmso.core.bond import Bond
from gmso.core.dihedral_type import DihedralType


Expand All @@ -28,12 +29,24 @@ class Dihedral(Connection):

__members_creator__: ClassVar[Callable] = Atom.model_validate

connectivity: ClassVar[Tuple[Tuple[int]]] = ((0, 1), (1, 2), (2, 3))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, does this need a description and alias?


connection_members_: Tuple[Atom, Atom, Atom, Atom] = Field(
...,
description="The 4 atoms involved in the dihedral.",
alias="connection_members",
)

bonds_: Tuple[Bond, Bond, Bond] = Field(
default=None,
description="""
List of connection bonds.
Ordered to align with connection_members, such that self.bonds_[0] is
the bond between (self.connection_members[0], self.connection_members[1]).
""",
alias="bonds",
)

dihedral_type_: Optional[DihedralType] = Field(
default=None,
description="DihedralType of this dihedral.",
Expand All @@ -50,6 +63,7 @@ class Dihedral(Connection):
""",
alias="restraint",
)

model_config = ConfigDict(
alias_to_fields=dict(
**Connection.model_config["alias_to_fields"],
Expand All @@ -74,6 +88,27 @@ def restraint(self):
"""Return the restraint of this dihedral."""
return self.__dict__.get("restraint_")

@property
def bonds(self):
"""Return the bonds that makeup this dihedral.

Connectivity is ((0,1), (1,2), (2,3))
"""
return self.__dict__.get("bonds_")

@bonds.setter
def bonds(self, bonds):
"""Return the bonds that makeup this Improper.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update doc strings here.


Connectivity is ((0,1), (0,2), (0,3))
"""
self._bonds = bonds

@property
def bonds_orders(self):
"""Return the bond_order strings of this dihedral."""
return "".join([b.bond_order for b in self.bonds])

def equivalent_members(self):
"""Get a set of the equivalent connection member tuples

Expand All @@ -99,3 +134,15 @@ def __setattr__(self, key, value):
super(Dihedral, self).__setattr__("dihedral_type_", value)
else:
super(Dihedral, self).__setattr__(key, value)

@model_validator(mode="before")
@classmethod
def set_dependent_value_default(cls, data):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a concise doc string for this method would be helpful.

if "bonds" not in data and "connection_members" in data:
atoms = data["connection_members"]
data["bonds"] = (
Bond(connection_members=(atoms[0], atoms[1])),
Bond(connection_members=(atoms[1], atoms[2])),
Bond(connection_members=(atoms[2], atoms[3])),
)
return data
Loading
Loading