diff --git a/docs/conf.py b/docs/conf.py index 2eb98da39..181dbe4a3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,8 +19,8 @@ # -- Project information ----------------------------------------------------- project = "gmso" -copyright = "2020, mosdef-hub, Vanderbilt University" -author = "Matt Thompson, Alex Yang, Ray Matsumoto, Parashara Shamaprasad, Umesh Timalsina, Co Quach, Ryan S. DeFever, Justin Gilmer" +copyright = "2024, mosdef-hub, Vanderbilt University" +author = "Matt Thompson, Alex Yang, Ray Matsumoto, Parashara Shamaprasad, Umesh Timalsina, Co D. Quach, Ryan S. DeFever, Justin Gilmer" # The full version, including alpha/beta/rc tags version = "0.12.0" @@ -49,7 +49,7 @@ napoleon_use_param = False napoleon_use_ivar = True -intersphinx_mapping = {"python": ("https://docs.python.org/3.7", None)} +intersphinx_mapping = {"python": ("https://docs.python.org/3.11", None)} # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -69,9 +69,9 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +# html_static_path = ["_static"] -_python_doc_base = "http://docs.python.org/3.7" +_python_doc_base = "http://docs.python.org/3.11" source_suffix = ".rst" diff --git a/docs/contributing.rst b/docs/contributing.rst index 9e08eb83b..752543946 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -18,7 +18,7 @@ Version control --------------- We currently use the "standard" Pull Request model. Contributions should be implemented on feature branches of forks. -Please try to keep the `master` branch of your fork up-to-date with the `master` branch of the main repository. +Please try to keep the `main` branch of your fork up-to-date with the `main` branch of the main repository. Propose a single set of related changes **************************************** diff --git a/docs/data_structures.rst b/docs/data_structures.rst index 5bda2cd53..7d4f14e56 100644 --- a/docs/data_structures.rst +++ b/docs/data_structures.rst @@ -8,17 +8,11 @@ Core Classes :nosignatures: gmso.Topology - gmso.SubTopology gmso.Atom gmso.Bond gmso.Angle gmso.Dihedral gmso.Improper - gmso.AtomType - gmso.BondType - gmso.AngleType - gmso.DihedralType - gmso.ImproperType Topology @@ -26,74 +20,87 @@ Topology .. autoclass:: gmso.Topology :members: add_site, add_connection, update_topology -SubTopology -*********** - .. autoclass:: gmso.SubTopology - :members: - Atom **** .. autoclass:: gmso.Atom :members: + :exclude-members: model_config, model_fields Bond **** .. autoclass:: gmso.Bond :members: + :exclude-members: model_config, model_fields Angle ***** .. autoclass:: gmso.Angle :members: + :exclude-members: model_config, model_fields Dihedral ******** .. autoclass:: gmso.Dihedral :members: + :exclude-members: model_config, model_fields Improper ******** .. autoclass:: gmso.Improper :members: + :exclude-members: model_config, model_fields Potential Classes ================= +.. autosummary:: + :nosignatures: + + gmso.AtomType + gmso.BondType + gmso.AngleType + gmso.DihedralType + gmso.ImproperType + gmso.PairPotentialType AtomType ******** .. autoclass:: gmso.AtomType :members: + :exclude-members: model_config, model_fields BondType ******** .. autoclass:: gmso.BondType :members: + :exclude-members: model_config, model_fields AngleType ********** .. autoclass:: gmso.AngleType :members: + :exclude-members: model_config, model_fields DihedralType ************ .. autoclass:: gmso.DihedralType :members: + :exclude-members: model_config, model_fields ImproperType ************ .. autoclass:: gmso.ImproperType :members: + :exclude-members: model_config, model_fields PairPotentialType -************ +***************** .. autoclass:: gmso.PairPotentialType :members: + :exclude-members: model_config, model_fields ForceField ========== .. autoclass:: gmso.ForceField :members: - - -======= + :exclude-members: model_config, model_fields diff --git a/docs/docker.rst b/docs/docker.rst index 32befb854..cdf2ff738 100644 --- a/docs/docker.rst +++ b/docs/docker.rst @@ -35,13 +35,11 @@ Alternatively, you can also start a Bourne shell to use python from the containe container's lifecycle. If the container is removed, any changes or code additions will not persist. See the section below for persistent data. -.. Note:: - -Note +.. note:: -The -it flags connect your keyboard to the terminal running in the container. -You may run the prior command without those flags, but be aware that the container will not respond to any keyboard input. -In that case, you would need to use the docker ``ps`` and ``docker kill`` commands to shut down the container. + The -it flags connect your keyboard to the terminal running in the container. + You may run the prior command without those flags, but be aware that the container will not respond to any keyboard input. + In that case, you would need to use the docker ``ps`` and ``docker kill`` commands to shut down the container. Persisting User Volumes diff --git a/docs/docs-env.yml b/docs/docs-env.yml index 9e70700d1..bf55b12f6 100644 --- a/docs/docs-env.yml +++ b/docs/docs-env.yml @@ -1,17 +1,24 @@ name: gmso-docs channels: - conda-forge + - symengine dependencies: - - python>=3.8 + - python=3.11 + - numpy + - sympy + - symengine + - python-symengine + - unyt >= 2.4 + - boltons + - lxml + - pydantic >= 2 + - networkx + - ele >= 0.2.0 + - mbuild + - foyer + - forcefield-utilities + - pip - pip: - - numpy - - sympy - - unyt >= 2.4 - - boltons - - lxml - - pydantic < 1.9.0 - - networkx - - ele >= 0.2.0 - numpydoc - sphinx - sphinx_rtd_theme diff --git a/docs/index.rst b/docs/index.rst index c45c0d8b4..02d16ea7a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,18 +5,22 @@ GMSO: Flexible storage of chemical topology for molecular simulation ==================================================================== -`GMSO`is a flexible storage of chemical topology for molecular simulation. -With a few lines of `GMSO` code, together with [`mBuild`](https://mbuild.mosdef.org) and [`foyer`](https://foyer.mosdef.org), users can rapidly prototype arbitrary parameterized chemical systems and generate data files for a wide variety of simulation engines. + +.. image:: https://img.shields.io/badge/license-MIT-blue.svg + :target: http://opensource.org/licenses/MIT + +`GMSO` is a flexible storage of chemical topology for molecular simulation. +With a few lines of `GMSO` code, together with `mBuild `_ and `foyer `_, users can rapidly prototype arbitrary parameterized chemical systems and generate data files for a wide variety of simulation engines. GMSO is a part of the MoSDeF ecosystem ----------------------------------------- `GMSO` is designed to be a general and flexible representation of chemical topolgies for molecular simulation. With an emphasis on assuming as little as possible about the chemical system, model, or engine, `GMSO` can enable support for a variety of systems. -`GMSO` is a part of the [MoSDeF (Molecular Simulation and Design Framework)](https://mosdef.org) ecosystem, and is intended to be the backend replacement for the [`foyer` package](https://foyer.mosdef.org). +`GMSO` is a part of the `MoSDeF (Molecular Simulation and Design Framework) `_ ecosystem, and is intended to be a generalized alternative for the `foyer package `_. Libraries in the MoSDeF ecosystem are designed to provide utilities neccessary to streamline a researcher's simulation workflow. When setting up simulation studies, -we also recommend users to follow the [TRUE](https://www.tandfonline.com/doi/full/10.1080/00268976.2020.1742938) +we also recommend users to follow the `TRUE `_ (Transparent, Reproducible, Usable-by-others, and Extensible) standard, which is a set of common practices meant to improve the reproducibility of computational simulation research. @@ -27,52 +31,47 @@ Goals and Features `GMSO`'s goal is to provide a flexible backend framework to store topological information of a chemical system in a reproducible fashion. **Topology** in this case is defined as the information needed to initialize a molecular simulation. Depending on the type of simulation performed, this ranges from: + * particle positions * particle connectivity * box information * forcefield data - - functional forms defined as [`sympy` expressions](https://www.sympy.org) - - parameters with defined units - - partial charges - - tabulated data - - etc. + + * functional forms defined as `sympy `_ expressions + * parameters with defined units + * partial charges + * tabulated data + * etc. + * Other optional data - - particle mass - - elemental data - - etc. + + * particle mass + * elemental data + * etc. With these driving goals for `GMSO`, the following features are enabled: -1. __Supporting a variety of models__ in the molecular simulation/computational - chemistry community_: - No assumptions are made about an interaction site - representing an atom or bead, instead these can be atomistic, - united-atom/coarse-grained, polarizable, and other models! - -1. __Greater flexibility for exotic potentials__: The [`AtomType`](./gmso/core/atom_type.py) (and [analogue - classes for intramolecular interactions](./gmso/core)) uses [`sympy`](https://www.sympy.org) to store any - potential that can be represented by a mathematical expression. - -1. __Adaptable for new engines__: by not being designed for - compatibility with any particular molecular simulation engine or ecosystem, - it becomes more tractable for developers in the community to add glue for - engines that are not currently supported. - -1. __Compatibility with existing community tools__: No single molecular simulation - tool will ever be a silver bullet, so ``GMSO`` includes functions to convert - between various file formats and libraries. These can be used in their own right to convert between objects in-memory - and also to support conversion to file formats not natively supported at - any given time. Currently supported conversions include: - * [`ParmEd`](./gmso/external/convert_parmed.py) - * [`OpenMM`](./gmso/external/convert_openmm.py) - * [`mBuild`](./gmso/external/convert_mbuild.py) - * more in the future! - -1. __Native support for reading and writing many common file formats__: We natively have support for: - * [`XYZ`](./gmso/formats/xyz.py) - * [`GRO`](./gmso/formats/gro.py) - * [`TOP`](gmso/formats/top.py) - * [`LAMMPSDATA`](gmso/formats/lammpsdata.py) - * indirect support, through other libraries, for many more! + + #. **Supporting a variety of models**: in the molecular simulation/computational chemistry community: No assumptions are made about an interaction site representing an atom or bead, instead these can be atomistic, united-atom/coarse-grained, polarizable, and other models! + + #. **Greater flexibility for exotic potentials**: The `AtomType` (and analogue classes for intramolecular interactions) uses `sympy `_ to store any potential that can be represented by a mathematical expression. + + #. **Adaptable for new engines**: by not being designed for compatibility with any particular molecular simulation engine or ecosystem, it becomes more tractable for developers in the community to add glue for engines that are not currently supported. + + #. **Compatibility with existing community tools**: No single molecular simulation tool will ever be a silver bullet, so ``GMSO`` includes functions to convert between various file formats and libraries. These can be used in their own right to convert between objects in-memory and also to support conversion to file formats not natively supported at any given time. Currently supported conversions include: + + * `ParmEd` + * `OpenMM` + * `mBuild` + * more in the future! + + #. **Native support for reading and writing many common file formats**: + + * `XYZ` + * `GRO` + * `TOP` + * `LAMMPSDATA` + * `GSD` + * indirect support, through other libraries, for many more! .. toctree:: diff --git a/docs/installation.rst b/docs/installation.rst index 5c98e684d..6f1c1194d 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -50,8 +50,8 @@ Once all dependencies have been installed and the ``conda`` environment has been Supported Python Versions ------------------------- -Python 3.8-3.11 is the recommend version for users. It is the only version on which -development and testing consistently takes place. Older (3.6-3.7) and newer (3.12+) +Python 3.9-3.11 is the recommend version for users. It is the only version on which +development and testing consistently takes place. Older (3.6-3.9) and newer (3.12+) versions of Python 3 are likely to work but no guarantee is made and, in addition, some dependencies may not be available for other versions. No effort is made to support Python 2 because it is considered obsolete as of early 2020. diff --git a/gmso/abc/auto_doc.py b/gmso/abc/auto_doc.py deleted file mode 100644 index 33832ae5c..000000000 --- a/gmso/abc/auto_doc.py +++ /dev/null @@ -1,308 +0,0 @@ -"""Documentation support for pydantic objects.""" - -import inspect -import re -from copy import deepcopy -from typing import Any, Dict, List, Optional, Tuple, Type, Union - -from pydantic import BaseModel - -BASE_DOC_ATTR = "__base_doc__" -FIELDS_IN_DOCSTRING = "__alias_to_fields__" -DOCS_GENERATED = "__docs_generated__" -FIELDS_KEY = "__fields__" - -__all__ = ["AutoDocGenerator", "apply_docs"] - - -def _infer_type(type_: Type) -> str: - """Infer types based on typing or builtin.""" - # FIXME: Inferred types clunky pydantic.main.ModelMetaclass - if type(type_) is type: - return type_.__name__ - else: - return repr(type_).replace("typing.", "") - - -def _find_extended_summary(doc_lines: List) -> str: - """Find extended summary from the docstring if it exists.""" - if len(doc_lines) == 2: - return doc_lines[1] - - first_section_index = None - for i, line in enumerate(doc_lines): - if re.match(r"-+", line): - first_section_index = i - 1 - break - - if first_section_index: - return "\n".join(doc_lines[1:first_section_index]) - else: - return "" - - -def _find_section_at(doc_lines: List, name: str) -> str: - """Find sections based on name.""" - try: - sec_index_start = doc_lines.index(name) - sec_index_end = -1 - for j in range(sec_index_start + 2, len(doc_lines)): - if re.match(r"-+", doc_lines[j]): - sec_index_end = j - 1 - break - - if sec_index_end != -1: - return "\n".join(doc_lines[sec_index_start:sec_index_end]) - else: - return "\n".join(doc_lines[sec_index_start:]) - - except ValueError: - return "" - - -def _base_doc_to_sections(base_doc: str) -> dict: - """Convert base doc to the sections expected in numpydoc style.""" - lines = list(filter(lambda x: x.strip() != "", base_doc.split("\n"))) - doc_lines = [line.strip() for line in lines] - leading_spaces = [(len(line) - len(line.lstrip()) - 4) for line in lines] - # Hack but works - doc_lines = [ - f"\t{doc_lines[j]}" if leading_spaces[j] > 0 else doc_lines[j] - for j in range(len(doc_lines)) - ] - - sections = { - "Parameters": "", - "Attributes": "", - "Notes": "", - "Examples": "", - "See Also": "", - "References": "", - "Warnings": "", - } - - summary = "" - if len(doc_lines) > 0: - summary = doc_lines[0] - - extended_summary = _find_extended_summary(doc_lines) - - for section in sections: - sections[section] = _find_section_at(doc_lines, section) - - sections.update({"Summary": summary, "Extended Summary": extended_summary}) - return sections - - -def _inject_parameters_from_fields( - fields: Dict[str, Any], - by_alias: bool = True, - name_map: Optional[Tuple[str, str]] = None, - inject_init: bool = True, - extra_params: Optional[List] = None, -) -> Union[Tuple[str, str], str]: - """Inject the parameters name from the fields.""" - parameters = ["Parameters", "----------"] - init_signature = None - if inject_init: - init_signature = [ - "__init__(", - ] - - for key, value in fields.items(): - default = value.default - if default == "": - default = "''" - - if by_alias: - name = value.alias - else: - name = key - - parameters.append( - f"{name} : " f"{_infer_type(value.type_)}" f", default={default}" - ) - if init_signature: - init_signature.append(f"{name}={repr(default)}, ") - - if value.field_info.description: - parameters.append(f"\t{value.field_info.description}") - - if extra_params: - parameters.extend(extra_params) - - if len(parameters) > 2: - parameters = "\n".join(parameters) - else: - parameters = "" - - if init_signature: - init_signature[-1] = init_signature[-1].replace(",", "") - init_signature.append(")") - init_signature = "".join(init_signature) - - # TODO: Will this always be lower? Could use `re` - if name_map: - parameters = parameters.replace( - name_map[1].lower(), name_map[0].lower() - ) - if init_signature: - return parameters, init_signature - - return parameters - - -def _find_extra_params(cls, fields, init_params): - """Find extra parameters not in the fields.""" - extra_params = [] - aliases_set = set(field.alias for field in fields.values()) - for param in init_params: - if param not in aliases_set and param != "self": - if hasattr(cls, param) and isinstance( - getattr(cls, param), property - ): - prop = getattr(cls, param) - [doc_main, doc_desc] = prop.__doc__.split("\n") - doc_main = ( - param - + ": " - + doc_main - + ", default=" - + str(init_params[param].default) - ) - extra_params.append(doc_main) - extra_params.append(doc_desc) - return extra_params - - -class AutoDocGenerator: - """Generate __doc__ attribute for pydantic base model classes and descendants. - - Parameters - ---------- - target: pydantic.BaseModel or its children - The basemodel class to generate __doc__ attribute for - map_names: bool, default=True - If true, change field descriptions by replacing superclass name by subclass - """ - - def __init__(self, target: Type[BaseModel], map_names=True) -> None: - self.should_apply = True - if target is BaseModel or issubclass(target, BaseModel): - if hasattr(target, BASE_DOC_ATTR): - if getattr(target, DOCS_GENERATED): - self.should_apply = False - else: - raise AttributeError( - f"No matching attribute {BASE_DOC_ATTR} found in {target.__name__}" - ) - - else: - raise TypeError( - "Cannot generate documentation for non-basemodel descendants" - ) - self.base_doc = getattr(target, BASE_DOC_ATTR) - self.target = target - setattr(self.target, DOCS_GENERATED, True) - self.name_map = self._name_map(map_names=map_names) - self.should_inject_init = self._should_inject_init() - - def _should_inject_init(self) -> bool: - """Inject __init__ docs if super and self are the same.""" - immediate_super_class = self.target.mro()[1] - self_init = self.target.__init__ - super_init = immediate_super_class.__init__ - return id(self_init) == id(super_init) - - def _name_map(self, map_names: bool = True) -> Union[Tuple[str, str], None]: - """Return mapping between super and this object.""" - super_classes = self.target.mro() - if map_names and len(super_classes) > 2: - return (self.target.__name__, super_classes[1].__name__) - else: - return None - - def __get__(self, *args: Any, **kwargs: Any) -> str: - """Return the __doc__ attribute.""" - fields = deepcopy(getattr(self.target, FIELDS_KEY)) - extra_params = None - - if not self.should_inject_init: - init_params = inspect.signature(self.target.__init__).parameters - to_pop = [] - for key, value in fields.items(): - if key not in init_params and value.alias not in init_params: - to_pop.append(key) - for field_key in to_pop: - fields.pop(field_key) - - extra_params = _find_extra_params(self.target, fields, init_params) - - return self.get_docstring( - fields, - self.base_doc, - self.name_map, - self.should_inject_init, - extra_params=extra_params, - ) - - def __del__(self) -> None: - """Define behavior when the instance is about to be destroyed.""" - self.target.__doc__ = self.base_doc - setattr(self.target, DOCS_GENERATED, False) - self.should_apply = True - - @staticmethod - def get_docstring( - fields: Dict[str, Any], - base_doc: str, - name_map: Tuple[str, str], - inject_init_signature: bool = True, - extra_params: Optional[List] = None, - ) -> str: - """Get the docstring names based on fields.""" - sections = _base_doc_to_sections(base_doc) - params_or_params_init = _inject_parameters_from_fields( - fields, - by_alias=True, - name_map=name_map, - inject_init=inject_init_signature, - extra_params=extra_params, - ) - docstring = [] - - if inject_init_signature: - sections["Parameters"] = params_or_params_init[0] - docstring.append(params_or_params_init[1]) - else: - sections["Parameters"] = params_or_params_init - - docstring.append(sections.pop("Summary")) - extended_summary = sections.pop("Extended Summary") - - if extended_summary: - docstring.append(extended_summary) - - for section in sections: - sec_str = sections.get(section) - if sec_str: - docstring.append(sec_str) - - return "\n\n".join(docstring) - - -def apply_docs( - target_class: Type[BaseModel], map_names: bool = True, silent: bool = True -) -> None: - """Apply __doc__ attribute to the BaseModel and its descendants.""" - if hasattr(target_class, DOCS_GENERATED) and getattr( - target_class, DOCS_GENERATED - ): - return - try: - target_class.__doc__ = AutoDocGenerator( - target_class, map_names=map_names - ) - except (TypeError, ValueError, AttributeError) as e: - if not silent: - raise e diff --git a/gmso/abc/gmso_base.py b/gmso/abc/gmso_base.py index 5c219c1fc..036408432 100644 --- a/gmso/abc/gmso_base.py +++ b/gmso/abc/gmso_base.py @@ -7,7 +7,6 @@ from pydantic import BaseModel, ConfigDict, validators -from gmso.abc.auto_doc import apply_docs from gmso.abc.serialization_utils import dict_to_unyt dict_validator = validators.getattr_migration("dict_validator") @@ -16,12 +15,6 @@ class GMSOBase(BaseModel, ABC): """A BaseClass to all abstract classes in GMSO.""" - __base_doc__: ClassVar[str] = ( - """A base class to all abstract base classes in gmso.""" - ) - - __docs_generated__: ClassVar[bool] = False - model_config = ConfigDict( arbitrary_types_allowed=True, validate_assignment=True, @@ -49,22 +42,6 @@ def __setattr__(self, name: Any, value: Any) -> None: super().__setattr__(name, value) - @classmethod - def __init_subclass__(cls, **kwargs): - """Initialize the subclass of the object.""" - super().__init_subclass__() - setattr(cls, "__docs_generated__", False) - for super_class in cls.mro()[1:]: - if ( - hasattr(super_class, "Config") - and hasattr(super_class.Config, "alias_to_fields") - and hasattr(cls.Config, "alias_to_fields") - ): - cls.Config.alias_to_fields.update( - super_class.Config.alias_to_fields - ) - apply_docs(cls, map_names=True, silent=False) - @classmethod def model_validate(cls: Type["Model"], obj: Any) -> "Model": dict_to_unyt(obj) diff --git a/gmso/core/angle.py b/gmso/core/angle.py index f4b24c117..8708d8ffc 100644 --- a/gmso/core/angle.py +++ b/gmso/core/angle.py @@ -10,7 +10,7 @@ class Angle(Connection): - __base_doc__ = """A 3-partner connection between Atoms. + """A 3-partner connection between Atoms. This is a subclass of the gmso.Connection superclass. This class has strictly 3 members in its connection members. @@ -19,9 +19,11 @@ class Angle(Connection): Notes ----- Inherits some methods from Connection: - __eq__, __repr__, _validate methods - Additional _validate methods are presented + __eq__, __repr__, _validate methods + + Additional _validate methods are presented. """ + __members_creator__: ClassVar[Callable] = Atom.model_validate connection_members_: Tuple[Atom, Atom, Atom] = Field( diff --git a/gmso/core/angle_type.py b/gmso/core/angle_type.py index 1e62a0a27..366bcb929 100644 --- a/gmso/core/angle_type.py +++ b/gmso/core/angle_type.py @@ -8,7 +8,7 @@ class AngleType(ParametricPotential): - __base_doc__ = """A descripton of the interaction between 3 bonded partners. + """A descripton of the interaction between 3 bonded partners. This is a subclass of the gmso.core.Potential superclass. diff --git a/gmso/core/atom.py b/gmso/core/atom.py index 90606ac94..f4a460add 100644 --- a/gmso/core/atom.py +++ b/gmso/core/atom.py @@ -15,7 +15,7 @@ class Atom(Site): - __base_doc__ = """An atom represents a single element association in a topology. + """An atom represents a single element association in a topology. Atoms are the representation of an element within `gmso` that describes any general atom in a molecular simulation. Atoms also contain information that are unique to @@ -26,8 +26,9 @@ class Atom(Site): ----- Atoms have all the attributes inherited from the base Site class, The order of precedence when attaining properties `charge` and `mass` is: - 1. atom.charge > atom.atom_type.charge - 2. atom.mass > atom.atom_type.mass + + 1. atom.charge > atom.atom_type.charge + 2. atom.mass > atom.atom_type.mass Examples -------- @@ -40,6 +41,7 @@ class Atom(Site): An Abstract Base class for implementing site objects in GMSO. The class Atom bases from the gmso.abc.abstract site class """ + charge_: Optional[Union[u.unyt_quantity, float]] = Field( None, description="Charge of the atom", alias="charge" ) diff --git a/gmso/core/atom_type.py b/gmso/core/atom_type.py index 34a513a9a..9f95878cb 100644 --- a/gmso/core/atom_type.py +++ b/gmso/core/atom_type.py @@ -19,7 +19,7 @@ class AtomType(ParametricPotential): - __base_doc__ = """A description of non-bonded interactions between sites. + """A description of non-bonded interactions between sites. This is a subclass of the gmso.core.Potential superclass. diff --git a/gmso/core/bond.py b/gmso/core/bond.py index 80d691c84..23f250700 100644 --- a/gmso/core/bond.py +++ b/gmso/core/bond.py @@ -10,7 +10,7 @@ class Bond(Connection): - __base_doc__ = """A 2-partner connection between sites. + """A 2-partner connection between sites. This is a subclass of the gmso.abc.Connection superclass. This class has strictly 2 members in its connection_members. @@ -19,9 +19,11 @@ class Bond(Connection): Notes ----- Inherits some methods from Connection: - __eq__, __repr__, _validate methods. + __eq__, __repr__, _validate methods. + Additional _validate methods are presented. """ + __members_creator__: ClassVar[Callable] = Atom.model_validate connection_members_: Tuple[Atom, Atom] = Field( diff --git a/gmso/core/bond_type.py b/gmso/core/bond_type.py index 2a891c97c..6e08356ed 100644 --- a/gmso/core/bond_type.py +++ b/gmso/core/bond_type.py @@ -10,7 +10,7 @@ class BondType(ParametricPotential): - __base_doc__ = """A descripton of the interaction between 2 bonded partners. + """A descripton of the interaction between 2 bonded partners. This is a subclass of the gmso.core.Potential superclass. diff --git a/gmso/core/dihedral.py b/gmso/core/dihedral.py index 219720259..acf5b7f1d 100644 --- a/gmso/core/dihedral.py +++ b/gmso/core/dihedral.py @@ -8,23 +8,24 @@ class Dihedral(Connection): - __base_doc__ = """A 4-partner connection between sites. + """A 4-partner connection between sites. This is a subclass of the gmso.Connection superclass. This class has strictly 4 members in its connection_members. The connection_type in this class corresponds to gmso.DihedralType. The connectivity of a dihedral is: - m1–m2–m3–m4 + m1–m2–m3–m4 where m1, m2, m3, and m4 are connection members 1-4, respectively. Notes ----- Inherits some methods from Connection: - __eq__, __repr__, _validate methods + __eq__, __repr__, _validate methods - Additional _validate methods are presented + Additional _validate methods are presented. """ + __members_creator__: ClassVar[Callable] = Atom.model_validate connection_members_: Tuple[Atom, Atom, Atom, Atom] = Field( diff --git a/gmso/core/dihedral_type.py b/gmso/core/dihedral_type.py index 32cebba3c..97d63f303 100644 --- a/gmso/core/dihedral_type.py +++ b/gmso/core/dihedral_type.py @@ -8,7 +8,7 @@ class DihedralType(ParametricPotential): - __base_doc__ = """A descripton of the interaction between 4 bonded partners. + """A descripton of the interaction between 4 bonded partners. This is a subclass of the gmso.core.Potential superclass. diff --git a/gmso/core/element.py b/gmso/core/element.py index dbd2cef30..27ddc6d9d 100644 --- a/gmso/core/element.py +++ b/gmso/core/element.py @@ -27,12 +27,13 @@ class Element(GMSOBase): - __base_doc__ = """Chemical element object + """Chemical element object Template to create a chemical element. Properties of the element instance are immutable. All known elements are pre-built and stored internally. """ + name: str = Field(..., description="Name of the element.") symbol: str = Field(..., description="Chemical symbol of the element.") diff --git a/gmso/core/improper.py b/gmso/core/improper.py index bb25a1778..dda5d0ccc 100644 --- a/gmso/core/improper.py +++ b/gmso/core/improper.py @@ -10,28 +10,25 @@ class Improper(Connection): - __base_doc__ = """sA 4-partner connection between sites. + """A 4-partner connection between sites. This is a subclass of the gmso.Connection superclass. This class has strictly 4 members in its connection_members. The connection_type in this class corresponds to gmso.ImproperType The connectivity of an improper is: - - m2 - | - m1 - / \ - m3 m4 + m2 + m3 - m1 - m4 where m1, m2, m3, and m4 are connection members 1-4, respectively. Notes ----- Inherits some methods from Connection: - __eq__, __repr__, _validate methods + __eq__, __repr__, _validate methods - Additional _validate methods are presented + Additional _validate methods are presented. """ + __members_creator__: ClassVar[Callable] = Atom.model_validate connection_members_: Tuple[Atom, Atom, Atom, Atom] = Field( diff --git a/gmso/core/improper_type.py b/gmso/core/improper_type.py index 68bb2a698..e336c91ba 100644 --- a/gmso/core/improper_type.py +++ b/gmso/core/improper_type.py @@ -10,7 +10,7 @@ class ImproperType(ParametricPotential): - __base_doc__ = """A description of the interaction between 4 bonded partners. + """A description of the interaction between 4 bonded partners. This is a subclass of the gmso.core.Potential superclass. @@ -19,22 +19,16 @@ class ImproperType(ParametricPotential): as a `sympy` expression and the parameters, with units, are stored explicitly. The AtomTypes that are used to define the improper type are stored as `member_types`. - The connectivity of an improper is: - - m2 - | - m1 - / \ - m3 m4 + m2 + m3 - m1 - m4 where m1, m2, m3, and m4 are connection members 1-4, respectively. Notes ---- Inherits many functions from gmso.ParametricPotential: - __eq__, _validate functions - + __eq__, _validate functions """ member_types_: Optional[Tuple[str, str, str, str]] = Field( diff --git a/gmso/core/pairpotential_type.py b/gmso/core/pairpotential_type.py index 8791dbb2a..a3298f580 100644 --- a/gmso/core/pairpotential_type.py +++ b/gmso/core/pairpotential_type.py @@ -8,7 +8,7 @@ class PairPotentialType(ParametricPotential): - __base_doc__ = """A description of custom pairwise potential between 2 AtomTypes that does not follow combination rule. + """A description of custom pairwise potential between 2 AtomTypes that does not follow combination rule. This is a subclass of the gmso.core.ParametricPotential superclass. diff --git a/gmso/core/parametric_potential.py b/gmso/core/parametric_potential.py index 58ac1efaa..cb25b31fc 100644 --- a/gmso/core/parametric_potential.py +++ b/gmso/core/parametric_potential.py @@ -11,7 +11,7 @@ class ParametricPotential(AbstractPotential): - __base_doc__ = """A parametric potential class. + """A parametric potential class. Potential stores a general interaction between components of a chemical topology that can be specified by a mathematical expression. The functional diff --git a/gmso/external/convert_mbuild.py b/gmso/external/convert_mbuild.py index 1832c8bbf..d46f56863 100644 --- a/gmso/external/convert_mbuild.py +++ b/gmso/external/convert_mbuild.py @@ -39,18 +39,20 @@ def from_mbuild( * All positional and box dimension values in compound are in nanometers. - * The hierarchical structure of the Compound will be flattened and translated to labels - in GMSO Sites. The directly supported labels include `Site.group`, + * The hierarchical structure of the Compound will be flattened and translated to labels\ + in GMSO Sites. The directly supported labels include `Site.group`,\ `Site.molecule_name`, and `Site.residue_name`. - * `group` is determined as te second-highest level Compound and is automatically generated; - * `molecule` is determined by traversing through - hierarchy of the mb.Compound, starting from the particle level, until the lowest - independent mb.Compound is reached (determined as an mb.Compound that does not have + + * `group` is determined as te second-highest level Compound and is automatically generated;\ + * `molecule` is determined by traversing through\ + hierarchy of the mb.Compound, starting from the particle level, until the lowest\ + independent mb.Compound is reached (determined as an mb.Compound that does not have\ any bond outside its boundary); - * `residue` is the `mb.Compound` level right above particle level. ` - * `molecule` and `residue` take the format of (name, index), where the latter can be used - to distinguish between molecule/residue of the same name. These two labels are only generated + * `residue` is the `mb.Compound` level right above particle level. + * `molecule` and `residue` take the format of (name, index), where the latter can be used\ + to distinguish between molecule/residue of the same name. These two labels are only generated\ if parse_label=True. + * Only `Bonds` are added for each bond in the `Compound`. If `Angles`\ and `Dihedrals` are desired in the resulting `Topology`, they must be\ added separately from this function. @@ -60,15 +62,14 @@ def from_mbuild( compound : mbuild.Compound mbuild.Compound instance that need to be converted box : mbuild.Box, optional, default=None - Box information to be loaded to a gmso.Topologyl + Box information to be loaded to a gmso.Topology search_method : function, optional, default=element_by_symbol - Searching method used to assign element from periodic table to - particle site. + Searching method used to assign element from periodic table to particle site. The information specified in the `search_method` argument is extracted from each `Particle`'s `name` attribute. Valid functions are element_by_symbol, element_by_name, element_by_atomic_number, and element_by_mass, which can be imported - from `gmso.core.element' + from `gmso.core.element` parse_label : bool, optional, default=True Option to parse hierarchy info of the compound into system of top label, including, group, molecule and residue labels.