diff --git a/docs/_templates/autosummary/base.rst b/docs/_templates/autosummary/base.rst deleted file mode 100644 index cdb86a616..000000000 --- a/docs/_templates/autosummary/base.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. title:: {{ objname }} - -.. currentmodule:: {{ module }} - -.. auto{{ objtype }}:: {{ objname }} diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst deleted file mode 100644 index cdb86a616..000000000 --- a/docs/_templates/autosummary/class.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. title:: {{ objname }} - -.. currentmodule:: {{ module }} - -.. auto{{ objtype }}:: {{ objname }} diff --git a/docs/_templates/autosummary/top-level-module.rst b/docs/_templates/autosummary/top-level-module.rst new file mode 100644 index 000000000..f7f0202e5 --- /dev/null +++ b/docs/_templates/autosummary/top-level-module.rst @@ -0,0 +1,6 @@ +{% extends "autosummary/module.rst" %} +{% block title -%} + +{{ ("``" ~ fullname ~ "``") | underline('=')}} + +{%- endblock %} diff --git a/docs/conf.py b/docs/conf.py index 9deb7f180..f99a77398 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,7 @@ import nbsphinx import nbformat -sys.path.insert(0, os.path.abspath('../')) +sys.path.insert(0, os.path.abspath("../")) os.environ["SPHINX"] = "True" @@ -79,9 +79,10 @@ autodoc_default_options = { "members": True, "member-order": "bysource", - "inherited-members": "GufeTokenizable,BaseModel", + "inherited-members": "GufeTokenizable,BaseModel,SettingsBaseModel", "undoc-members": True, "special-members": "__call__", + "exclude-members": "get_defaults", } toc_object_entries_show_parents = "hide" @@ -107,8 +108,45 @@ "openmmtools", "mdtraj", "openmmforcefields", + "netCDF4", + "py3Dmol", ] +# API docs settings +autosummary_generate = True +# Document imported items iff they're in __all__ +autosummary_imported_members = False +autosummary_ignore_module_all = False +# Autosummary template configuration +autosummary_context = { + # Modules to exclude from API docs + "exclude_modules": [ + "openfe.tests", + ], + "show_inheritance": True, + "show_inherited_members": False, + "show_undoc_members": True, +} + +autodoc_preserve_defaults = True +autodoc_inherit_docstrings = True +autodoc_typehints_format = "short" +# Fold the __init__ or __new__ methods' signature into class documentation +autoclass_content = "both" +autodoc_class_signature = "mixed" +# Workaround for autodoc_typehints_format not working for attributes +# see https://github.com/sphinx-doc/sphinx/issues/10290#issuecomment-1079740009 +python_use_unqualified_type_names = True + + +autodoc_pydantic_model_show_json = False +autodoc_pydantic_model_show_field_summary = False +autodoc_pydantic_model_show_config_member = False +autodoc_pydantic_model_show_config_summary = False +autodoc_pydantic_model_show_validator_members = False +autodoc_pydantic_model_show_validator_summary = False +autodoc_pydantic_field_list_validators = False + # Extensions for the myst parser myst_enable_extensions = [ "dollarmath", @@ -137,6 +175,7 @@ } ], "accent_color": "DarkGoldenYellow", + "navigation_depth": 8, } html_logo = "_static/Squaredcircle.svg" diff --git a/docs/cookbook/index.rst b/docs/cookbook/index.rst index f7090b6f0..03ddbbdfa 100644 --- a/docs/cookbook/index.rst +++ b/docs/cookbook/index.rst @@ -21,6 +21,7 @@ The typical way to use the Python API is to load a number of molecules you want - .. container:: flowchart-sidebyside - - + .. rst-class:: flowchart-spacer - diff --git a/docs/cookbook/under_the_hood.rst b/docs/cookbook/under_the_hood.rst index ddd821adb..a602a60fe 100644 --- a/docs/cookbook/under_the_hood.rst +++ b/docs/cookbook/under_the_hood.rst @@ -104,7 +104,7 @@ If you want to implement your own atom mapper or free energy procedure, or you w - - .. rst-class:: arrow-down - - :any:`executors` + - :any:`openfe.orchestration` - :class:`ProtocolDAGResult` A completed transformation. diff --git a/docs/environment.yaml b/docs/environment.yaml index ef93acb7b..2063f8d24 100644 --- a/docs/environment.yaml +++ b/docs/environment.yaml @@ -16,6 +16,7 @@ dependencies: - gitpython - tqdm - libsass +- cinnabar - nbsphinx - nbsphinx-link - myst-parser diff --git a/docs/index.rst b/docs/index.rst index 1e465dbf6..d1d469d7b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -76,7 +76,7 @@ The **OpenFE** toolkit provides open-source frameworks for calculating alchemica .. grid-item-card:: Relative Free Energy Protocol :img-top: _static/Rocket.svg :text-align: center - :link: reference/api/openmm_rfe + :link: reference/api/generated/openfe.protocols.openmm_rfe :link-type: doc Documentation for OpenFE's OpenMM-based Hybrid Topology Relative Free diff --git a/docs/reference/api/alchemical_network_planning.rst b/docs/reference/api/alchemical_network_planning.rst deleted file mode 100644 index 8a288404c..000000000 --- a/docs/reference/api/alchemical_network_planning.rst +++ /dev/null @@ -1,41 +0,0 @@ -.. _Alchemical Network Planning: - -Simulation Campaign Planning -============================ - -While a :class:`LigandNetwork` describes a network of ligands and their atom -mappings, a :class:`AlchemicalNetwork` describes a single replicate of a -simulation campaign. It includes all the information needed to perform the -simulation, and so implicitly includes the :class:`LigandNetwork`. - -Alchemical Simulations -~~~~~~~~~~~~~~~~~~~~~~ - -Descriptions of anticipated alchemical simulation campaigns. - -.. module:: openfe - :noindex: - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - Transformation - AlchemicalNetwork - -Alchemical Network Planners ---------------------------- -Alchemical network planners are objects that pull all the ideas in OpenFE -into a quick setup for simulation. The goal is to create the -:class:`.AlchemicalNetwork` that represents an entire simulation campaign, -starting from a bare amount of user input. - -.. module:: openfe.setup - :noindex: - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - RBFEAlchemicalNetworkPlanner - RHFEAlchemicalNetworkPlanner diff --git a/docs/reference/api/data.rst b/docs/reference/api/data.rst deleted file mode 100644 index ef438b2b8..000000000 --- a/docs/reference/api/data.rst +++ /dev/null @@ -1,13 +0,0 @@ -Data Objects and Serialization -============================== - -.. module:: gufe.tokenization - -Almost every OpenFE data object inherits from :class:`GufeTokenizable`, which -enforces immutability and provides functions for data serialization. - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - GufeTokenizable diff --git a/docs/reference/api/defining_and_executing_simulations.rst b/docs/reference/api/defining_and_executing_simulations.rst deleted file mode 100644 index 7adaa16ce..000000000 --- a/docs/reference/api/defining_and_executing_simulations.rst +++ /dev/null @@ -1,47 +0,0 @@ -Defining and Executing Simulations -================================== - -.. _executors: - -Executing Simulations ---------------------- - -.. module:: openfe - :noindex: - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - execute_DAG - -General classes ---------------- - -.. module:: openfe - :noindex: - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - ProtocolDAG - ProtocolUnitResult - ProtocolUnitFailure - ProtocolDAGResult - -Specialised classes -------------------- - -These classes are abstract classes that are specialised (subclassed) for an individual Protocol. - -.. module:: openfe - :noindex: - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - Protocol - ProtocolUnit - ProtocolResult diff --git a/docs/reference/api/index.rst b/docs/reference/api/index.rst index 5d0df4f7e..3c2bda8cc 100644 --- a/docs/reference/api/index.rst +++ b/docs/reference/api/index.rst @@ -3,12 +3,24 @@ OpenFE API Reference ==================== -.. toctree:: - :maxdepth: 2 - - data - systems_and_components - ligand_network - alchemical_network_planning - defining_and_executing_simulations - openmm_rfe +``openfe`` +---------- + +.. automodule:: openfe + :no-members: + :noindex: + + .. rubric:: Modules + + .. autosummary:: + :nosignatures: + :toctree: generated/ + :recursive: + :template: autosummary/top-level-module.rst + + setup + orchestration + analysis + protocols + storage + utils diff --git a/docs/reference/api/ligand_network.rst b/docs/reference/api/ligand_network.rst deleted file mode 100644 index 40182bbb6..000000000 --- a/docs/reference/api/ligand_network.rst +++ /dev/null @@ -1,131 +0,0 @@ -Ligand Network Tools -==================== - -.. module:: openfe.setup - :noindex: - -Ligand Network --------------- - -A network of mutations between ligands. - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - LigandNetwork - - -.. _Ligand Network Planners: - -Network Planners -~~~~~~~~~~~~~~~~ - -.. module:: openfe.setup.ligand_network_planning - -Functions that build a :class:`.LigandNetwork` from a collection of :class:`SmallMoleculeComponents` by optimizing over a `scoring function `_. - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - generate_radial_network - generate_maximal_network - generate_minimal_spanning_network - -.. _Ligand Network Loaders: - -Network Loaders -~~~~~~~~~~~~~~~ - -Functions to load a :class:`.LigandNetwork` from equivalent classes in other packages, or to specify one by hand. - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - generate_network_from_names - generate_network_from_indices - load_orion_network - load_fepplus_network - -.. _Atom Mappers: - -Atom Mappings -------------- - -Tools for mapping atoms in one molecule to those in another. Used to generate efficient ligand networks. - -.. module:: openfe.setup.atom_mapping - -.. rubric:: Abstract Base Class - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - LigandAtomMapper - -.. rubric:: Implementations - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - LomapAtomMapper - PersesAtomMapper - -.. rubric:: Data Types - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - LigandAtomMapping - -.. _Atom Map Scorers: - -Atom Map Scorers ----------------- - -Scoring functions for a mapping between ligands. These are used as objective functions for :any:`Ligand Network Planners`. - -LOMAP Scorers -~~~~~~~~~~~~~ - -Scorers implemented by the `LOMAP `_ package. - -.. apparently we need the atom_mapping because internally autofunction is - trying ``import openfe.setup.lomap_scorers``, which doesn't work (whereas - ``from openfe.setup import lomap_scorers`` does) - -.. module:: openfe.setup.atom_mapping.lomap_scorers - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - default_lomap_score - ecr_score - mcsr_score - mncar_score - atomic_number_score - hybridization_score - sulfonamides_score - heterocycles_score - transmuting_methyl_into_ring_score - transmuting_ring_sizes_score - - -Perses Scorers -~~~~~~~~~~~~~~ - -Scorers implemented by the `Perses `_ package. - -.. module:: openfe.setup.atom_mapping.perses_scorers - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - default_perses_scorer diff --git a/docs/reference/api/openmm_rfe.rst b/docs/reference/api/openmm_rfe.rst deleted file mode 100644 index e8b222c08..000000000 --- a/docs/reference/api/openmm_rfe.rst +++ /dev/null @@ -1,136 +0,0 @@ -OpenMM Relative Free Energy Protocol -==================================== - -This section provides details about the OpenMM Relative Free Energy Protocol -implemented in OpenFE. - -Protocol API specification --------------------------- - -.. module:: openfe.protocols.openmm_rfe - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - RelativeHybridTopologyProtocol - RelativeHybridTopologyProtocolResult - -Protocol Settings ------------------ - - -Below are the settings which can be tweaked in the protocol. The default settings (accessed using :meth:`RelativeHybridTopologyProtocol.default_settings`) will automatically populate a settings which we have found to be useful for running relative binding free energies using explicit solvent. There will however be some cases (such as when doing gas phase calculations) where you will need to tweak some of the following settings. - -.. autopydantic_model:: RelativeHybridTopologyProtocolSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :exclude-members: get_defaults - :member-order: bysource - -.. module:: openfe.protocols.openmm_rfe.equil_rfe_settings - -.. autopydantic_model:: OpenMMSystemGeneratorFFSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: ThermoSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: AlchemicalSamplerSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: AlchemicalSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: OpenMMEngineSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: IntegratorSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: SimulationSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: SolvationSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource - -.. autopydantic_model:: SystemSettings - :model-show-json: False - :model-show-field-summary: False - :model-show-config-member: False - :model-show-config-summary: False - :model-show-validator-members: False - :model-show-validator-summary: False - :field-list-validators: False - :inherited-members: SettingsBaseModel - :member-order: bysource diff --git a/docs/reference/api/systems_and_components.rst b/docs/reference/api/systems_and_components.rst deleted file mode 100644 index 0732f4ce7..000000000 --- a/docs/reference/api/systems_and_components.rst +++ /dev/null @@ -1,29 +0,0 @@ -Chemical Systems and Components -=============================== - -We describe a chemical system as being made up of one or more "components," e.g., solvent, protein, or small molecule. The :class:`.ChemicalSystem` object joins components together into a simulation system. - -.. module:: openfe - :noindex: - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - Component - SmallMoleculeComponent - ProteinComponent - SolventComponent - ChemicalSystem - - -Chemical System Generators --------------------------- - -.. module:: openfe.setup.chemicalsystem_generator - -.. autosummary:: - :nosignatures: - :toctree: generated/ - - EasyChemicalSystemGenerator diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 8853d761f..a9b17a0c9 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -5,7 +5,11 @@ This contains details of the Python API as well as a reference to the command line interface. .. toctree:: - :maxdepth: 2 + :maxdepth: 3 api/index + +.. toctree:: + :maxdepth: 2 + cli/index diff --git a/openfe/__init__.py b/openfe/__init__.py index 0b11ed153..1292440c1 100644 --- a/openfe/__init__.py +++ b/openfe/__init__.py @@ -1,22 +1,16 @@ -from gufe import ( - ChemicalSystem, - Component, - ProteinComponent, - SmallMoleculeComponent, - SolventComponent, - Transformation, - AlchemicalNetwork, - LigandAtomMapping, -) -from gufe.protocols import ( +""" +Open source free energy calculation via molecular mechanics. +""" + +from .protocols import ( Protocol, ProtocolDAG, ProtocolUnit, ProtocolUnitResult, ProtocolUnitFailure, ProtocolDAGResult, ProtocolResult, - execute_DAG, ) +from .orchestration import execute_DAG from . import utils from . import setup @@ -28,6 +22,16 @@ ligand_network_planning, LigandNetwork, LigandAtomMapper, + LigandAtomMapping, + Transformation, + AlchemicalNetwork, +) +from .setup.system import ( + ChemicalSystem, + Component, + ProteinComponent, + SmallMoleculeComponent, + SolventComponent, ) from . import orchestration from . import analysis diff --git a/openfe/analysis/__init__.py b/openfe/analysis/__init__.py index 99fb0c159..032d435b0 100644 --- a/openfe/analysis/__init__.py +++ b/openfe/analysis/__init__.py @@ -1,3 +1,6 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Analyse the results and outputs of a free energy campaign. +""" from . import plotting diff --git a/openfe/analysis/plotting.py b/openfe/analysis/plotting.py index 282ef5439..9158a84ff 100644 --- a/openfe/analysis/plotting.py +++ b/openfe/analysis/plotting.py @@ -1,5 +1,9 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Best-practices graphs for visualising free energy results. +""" + import matplotlib.pyplot as plt from matplotlib.axes import Axes import numpy.typing as npt diff --git a/openfe/orchestration/__init__.py b/openfe/orchestration/__init__.py index e69de29bb..baee118f3 100644 --- a/openfe/orchestration/__init__.py +++ b/openfe/orchestration/__init__.py @@ -0,0 +1,8 @@ +""" +Tools to execute and orchestrate the execution of protocol DAGs. +""" +from gufe.protocols import execute_DAG + +__all__ = [ + "execute_DAG", +] diff --git a/openfe/protocols/__init__.py b/openfe/protocols/__init__.py index efae32ddb..d0c5c95d3 100644 --- a/openfe/protocols/__init__.py +++ b/openfe/protocols/__init__.py @@ -1,2 +1,47 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Descriptions and implementations of free energy calculation protocols. + +A :class:`.Protocol` describes a methodology for computing a free energy from a +pair of chemical systems. It produces a number of :class:`ProtocolDAG` objects, +which are directed acyclic graphs describing the dependencies between +individual units of work that can otherwise be run in parallel. Each unit of +work is described and implemented by a :class:`ProtocolUnit`. The results of a +``ProtocolUnit`` are described by a :class:`ProtocolUnitResult` when successful +or else a :class:`ProtocolUnitFailure`; these types are then collected into a +:class:`ProtocolDAGResult` to describe the result of a protocol DAG, and +multiple DAGs from different transformations in the same campaign can be +collected into a :class:`ProtocolResult`. + +``Protocol`` instances are configured by Pydantic models describing their +settings.. Base classes and a number of implemented building blocks for complex +configurations are found in the :class:`settings` module. + +Other submodules in this module represent individual implementations of +protocols. +""" + +from gufe.protocols import ( + Protocol, + ProtocolDAG, + ProtocolUnit, + ProtocolUnitResult, + ProtocolUnitFailure, + ProtocolDAGResult, + ProtocolResult, +) + +from . import openmm_rfe, openmm_utils, settings + +__all__ = [ + "settings", + "openmm_rfe", + "Protocol", + "ProtocolDAG", + "ProtocolUnit", + "ProtocolUnitResult", + "ProtocolUnitFailure", + "ProtocolDAGResult", + "ProtocolResult", +] diff --git a/openfe/protocols/openmm_rfe/__init__.py b/openfe/protocols/openmm_rfe/__init__.py index eb50c0712..4d802305d 100644 --- a/openfe/protocols/openmm_rfe/__init__.py +++ b/openfe/protocols/openmm_rfe/__init__.py @@ -1,5 +1,10 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Run relative free energy calculations on hybrid topologies with OpenMM. + + +""" from . import _rfe_utils @@ -13,3 +18,9 @@ RelativeHybridTopologyProtocolUnit, ) +__all__ = [ + "RelativeHybridTopologyProtocolSettings", + "RelativeHybridTopologyProtocol", + "RelativeHybridTopologyProtocolResult", + "RelativeHybridTopologyProtocolUnit", +] diff --git a/openfe/protocols/openmm_rfe/equil_rfe_methods.py b/openfe/protocols/openmm_rfe/equil_rfe_methods.py index 0f6aa98c6..41021248e 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_methods.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_methods.py @@ -309,6 +309,16 @@ def production_iterations(self) -> list[float]: class RelativeHybridTopologyProtocol(gufe.Protocol): + """ + Relative free energy calculations with a hybrid topology in OpenMM. + + See Also + -------- + openfe.protocols + openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocolSettings + openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocolResult + openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocolUnit + """ result_cls = RelativeHybridTopologyProtocolResult _settings: RelativeHybridTopologyProtocolSettings diff --git a/openfe/protocols/openmm_rfe/equil_rfe_settings.py b/openfe/protocols/openmm_rfe/equil_rfe_settings.py index 230d05ff6..32c9403a1 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_settings.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_settings.py @@ -80,6 +80,14 @@ class Config: class RelativeHybridTopologyProtocolSettings(Settings): + """ + Configuration object for ``RelativeHybridTopologyProtocol`` + + See Also + -------- + openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol + """ + class Config: arbitrary_types_allowed = True diff --git a/openfe/protocols/settings.py b/openfe/protocols/settings.py new file mode 100644 index 000000000..f6f1c9ed2 --- /dev/null +++ b/openfe/protocols/settings.py @@ -0,0 +1,47 @@ +""" +Settings models for Protocols. + +Protocols often permit extensive configuration that would be cumbersome to +configure in an ``__init__`` method and which may want to be independently +recorded and shared. Settings models are Pydantic models that support these use +cases. Each protocol should have an associated settings object; for a protocol +called ``FooProtocol``, the corresponding settings object is called +``FooProtocolSettings``. + +Settings are generally broken up into multiple levels to avoid overwhelming +users with information and to allow settings models to be shared across +multiple protocols. Top level protocol settings models should inherit +from :class:`.Settings`, whereas all other settings models should inherit from +:class:`.SettingsBaseModel`. + +""" + +from .openmm_utils.omm_settings import ( + Settings, + SettingsBaseModel, + SystemSettings, + SolvationSettings, + AlchemicalSamplerSettings, + OpenMMEngineSettings, + IntegratorSettings, + SimulationSettings, + ThermoSettings, + OpenMMSystemGeneratorFFSettings, +) + +from .openmm_rfe.equil_rfe_settings import AlchemicalSettings + +__all__ = [ + "Settings", + "SettingsBaseModel", + "SystemSettings", + "SolvationSettings", + "AlchemicalSamplerSettings", + "OpenMMEngineSettings", + "IntegratorSettings", + "SimulationSettings", + "ThermoSettings", + "OpenMMSystemGeneratorFFSettings", + "AlchemicalSettings", + +] diff --git a/openfe/setup/__init__.py b/openfe/setup/__init__.py index 024680822..cabf64222 100644 --- a/openfe/setup/__init__.py +++ b/openfe/setup/__init__.py @@ -1,13 +1,62 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Set up a free energy campaign by preparing an :class:`.AlchemicalNetwork`. +Setup consists of preparing an :class:`.AlchemicalNetwork`, which contains a +collection of :class:`.Transformation` objects. Each ``Transformation`` +describes an alchemic mutation from one chemical system to another, including +full descriptions of both chemical systems as well as the simulation protocol +used to compute the change. Descriptions of chemical systems and their +components are found in the :mod:`.system` module. -from .atom_mapping import (LigandAtomMapping, - LigandAtomMapper, - LomapAtomMapper, lomap_scorers, - PersesAtomMapper, perses_scorers) +An ``AlchemicalNetwork`` is usually prepared from a :class:`.LigandNetwork`, +which is an undirected graph of small molecules. Each edge represents a +yet-to-be-calculated mutation including an atom mapping, but without specifying +a simulation protocol or explicit chemical system. A ``LigandNetwork`` is +created by a planner function from the :mod:`.ligand_network_planning` module. +A planner may generate the network layout automatically, load it from another +tool, or require the user to specify it by hand. Most planners generate atom +mappings automatically by optimising over a scorer function +from :mod:`.lomap_scorers` or :mod:`.perses_scorers`; these and other atom +mapping utilities are found in the :mod:`.atom_mapping` module. -from gufe import LigandNetwork -from . import ligand_network_planning +An ``AlchemicalNetwork`` additionally needs +a :class:`Protocol` for each transformation, though +it usually uses the same protocol for all transformations. A protocol describes +and implements the process of computing the free energy from the two chemical +systems described by a transformation. -from .alchemical_network_planner import RHFEAlchemicalNetworkPlanner, RBFEAlchemicalNetworkPlanner \ No newline at end of file +""" + + +from .atom_mapping import ( + LigandAtomMapping, + LigandAtomMapper, + LomapAtomMapper, + lomap_scorers, + PersesAtomMapper, + perses_scorers, +) + +from gufe import ( + LigandNetwork, + Transformation, + AlchemicalNetwork, +) +from . import ligand_network_planning, atom_mapping, system + +from .alchemical_network_planner import ( + RHFEAlchemicalNetworkPlanner, + RBFEAlchemicalNetworkPlanner, +) + +__all__ = [ + "atom_mapping", + "system", + "ligand_network_planning", + "alchemical_network_planner", + "LigandNetwork", + "Transformation", + "AlchemicalNetwork", +] diff --git a/openfe/setup/alchemical_network_planner/__init__.py b/openfe/setup/alchemical_network_planner/__init__.py index 7a67e50a9..d56b7b440 100644 --- a/openfe/setup/alchemical_network_planner/__init__.py +++ b/openfe/setup/alchemical_network_planner/__init__.py @@ -1,5 +1,12 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Tools for planning alchemical networks. + +This module is being replaced by methods on :class:`LigandNetwork +` like :meth:`to_rbfe_alchemical_network() +`. +""" from .relative_alchemical_network_planner import ( RHFEAlchemicalNetworkPlanner, diff --git a/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py b/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py index 3b34aa511..7eaf693bb 100644 --- a/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py +++ b/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py @@ -39,6 +39,7 @@ PROTOCOL_GENERATOR = { RelativeHybridTopologyProtocol: EasyChemicalSystemGenerator, } +"""Mapping from a RFE protocol to the corresponding system generator""" class RelativeAlchemicalNetworkPlanner( diff --git a/openfe/setup/atom_mapping/__init__.py b/openfe/setup/atom_mapping/__init__.py index 0d19acf64..262c5dc58 100644 --- a/openfe/setup/atom_mapping/__init__.py +++ b/openfe/setup/atom_mapping/__init__.py @@ -1,3 +1,23 @@ +""" +Mappings from atoms in one molecule to those in another. + +:class:`LigandAtomMapper` defines the interface of atom mappers, and is +implemented by :class:`LomapAtomMapper` and :class:`PersesAtomMapper`. +:class:`LigandAtomMapping` is a simple container for an atom maping. It +describes which atoms in one molecule should be transformed into which atoms +in the other, and which atoms should be destroyed or created over the +transformation. + +The :mod:`.perses_scorers` and :mod:`.lomap_scorers` modules provide scoring +functions used for both atom mappings and transformations. A scorer takes +a :class:`..mapping.LigandAtomMapping` and possibly some other parameters and +returns a score between 0 and 1. Higher scores represent better mappings. These +scores are used by :class:`LigandNetwork` +planners to select the best mapping for a given transformation and also to +compare different transformations while optimising network topologies. + +""" + from gufe import LigandAtomMapping from .ligandatommapper import LigandAtomMapper @@ -6,3 +26,12 @@ from . import perses_scorers from . import lomap_scorers + +__all__ = [ + "LigandAtomMapping", + "LigandAtomMapper", + "LomapAtomMapper", + "PersesAtomMapper", + "perses_scorers", + "lomap_scorers", +] diff --git a/openfe/setup/atom_mapping/lomap_scorers.py b/openfe/setup/atom_mapping/lomap_scorers.py index bcf3e6516..d8dca0122 100644 --- a/openfe/setup/atom_mapping/lomap_scorers.py +++ b/openfe/setup/atom_mapping/lomap_scorers.py @@ -1,5 +1,9 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Functions from LOMAP for scoring atom mappings. +""" + from collections import defaultdict from lomap import dbmol as _dbmol from lomap import mcs as lomap_mcs @@ -20,7 +24,7 @@ # Br to element 35: {53: 0.85}, } - +"""Default ``difficulty`` argument for :func:`.atomic_number_score`.""" def ecr_score(mapping: LigandAtomMapping) -> float: """ diff --git a/openfe/setup/atom_mapping/perses_scorers.py b/openfe/setup/atom_mapping/perses_scorers.py index 341194dad..95fd11701 100644 --- a/openfe/setup/atom_mapping/perses_scorers.py +++ b/openfe/setup/atom_mapping/perses_scorers.py @@ -1,5 +1,8 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Functions from Perses for scoring atom mappings. +""" from typing import Callable diff --git a/openfe/setup/ligand_network.py b/openfe/setup/ligand_network.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 723c9edcf..bb228f099 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -1,5 +1,9 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Functions for planning a :class:`LigandNetwork` from small molecules. +""" + import math from pathlib import Path from typing import Iterable, Callable, Optional, Union diff --git a/openfe/setup/system.py b/openfe/setup/system.py new file mode 100644 index 000000000..d1b2775eb --- /dev/null +++ b/openfe/setup/system.py @@ -0,0 +1,33 @@ +""" +Chemical systems and their components. + +A :class:`ChemicalSystem` describes a simulation box and its contents. They are +the nodes of an ``AlchemicalNetwork``; two are included in each +``Transformation`` as end states. The abstract base class :class:`Component` +defines the interface for a components of a chemical system. A ``Component`` +need not refer to a single molecule; it may represent a protein of multiple +chains and their cofactors, or the entire solvent including ions. + +.. admonition:: Custom ``Components`` require support from the ``Protocol`` + + ``Component`` types are handled individually by each ``Protocol``; it is + not presently possible to define a custom ``Component`` and have it work + in an existing ``Protocol``. + +""" + +from gufe import ( + ChemicalSystem, + Component, + ProteinComponent, + SmallMoleculeComponent, + SolventComponent, +) + +__all__ = [ + "ChemicalSystem", + "Component", + "ProteinComponent", + "SmallMoleculeComponent", + "SolventComponent", +] diff --git a/openfe/storage/__init__.py b/openfe/storage/__init__.py index e69de29bb..ece33ae8e 100644 --- a/openfe/storage/__init__.py +++ b/openfe/storage/__init__.py @@ -0,0 +1,3 @@ +""" +Storage of results, data, and artifacts from simulations. +""" diff --git a/openfe/storage/resultclient.py b/openfe/storage/resultclient.py index 012c12f66..cf4cf0268 100644 --- a/openfe/storage/resultclient.py +++ b/openfe/storage/resultclient.py @@ -145,8 +145,8 @@ def _store_gufe_tokenizable(self, prefix, obj): def store_transformation(self, transformation): """Store a :class:`.Transformation`. - Parmeters - --------- + Parameters + ---------- transformation: :class:`.Transformation` the transformation to store """ diff --git a/openfe/utils/__init__.py b/openfe/utils/__init__.py index 0d276a97e..07f97e901 100644 --- a/openfe/utils/__init__.py +++ b/openfe/utils/__init__.py @@ -1,7 +1,22 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +""" +Utilities and tools for OpenFE. + +Of particular note is the :class:`.GufeTokenizable` class, which enforces +immutability and provides serialization tools for most OpenFE data types. +""" from . import custom_typing from .optional_imports import requires_package from .remove_oechem import without_oechem_backend from .system_probe import log_system_probe +from gufe.tokenization import GufeTokenizable + +__all__ = [ + "GufeTokenizable", + "custom_typing", + "requires_package", + "without_oechem_backend", + "log_system_probe", +]