Skip to content
Open
Show file tree
Hide file tree
Changes from all 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