diff --git a/docs/guide/introduction.rst b/docs/guide/introduction.rst index ba8a0a19a..6edc96c85 100644 --- a/docs/guide/introduction.rst +++ b/docs/guide/introduction.rst @@ -13,16 +13,16 @@ Workflow overview The overall workflow of OpenFE involves three stages: -1. **Setup**: Defining the simulation campaign you are going to run. -2. **Execution**: Running and performing initial analysis of your +1. :ref:`Simulation setup `: Defining the simulation campaign you are going to run. +2. :ref:`Execution `: Running and performing initial analysis of your simulation campaign. -3. **Gather results**: Assembling the results from the simulation +3. :ref:`Gather results `: Assembling the results from the simulation campaign for further analysis. -In many use cases, these stages may be done on different machines -- for +In many use cases, these stages may be done on different machines. For example, you are likely to make use of HPC or cloud computing resources to -run the simulation campaign. Because of this, each stage has a certain type -of output, which is the input to the next stage. +run the simulation campaign. Because of this, each stage has a defined output which +is then the input for the next stage: .. TODO make figure .. .. figure:: ??? @@ -30,25 +30,25 @@ of output, which is the input to the next stage. The main stages of a free energy calculation in OpenFE, and the intermediates between them. -The output of **setup** is an :class:`.AlchemicalNetwork`. This contains all -the information about what is being simulated (e.g., what ligands, host proteins, solvation details etc) and the +The output of the :ref:`simulation setup ` stage is an :class:`.AlchemicalNetwork`. This contains all +the information about what is being simulated (e.g., what ligands, host proteins, solvation details, etc.) and the information about how to perform the simulation (the Protocol). -The output of the **execution** stage is the basic results from each edge. +The output of the :ref:`execution ` stage is the basic results from each edge. This can depend of the specific analysis intended, but will either involve a :class:`.ProtocolResult` representing the calculated :math:`\Delta G` for each edge or the :class:`.ProtocolDAGResult` linked to the data needed to calculate that :math:`\Delta G`. -The **gather results** stage takes these results and produces something -useful to the user. For example, the CLI's ``gather`` command will create a +The :ref:`gather results ` stage aggregates the individual results for further analysis. For example, the CLI's ``gather`` command will create a table of the :math:`\Delta G` for each leg. +.. TODO: Should the CLI workflow be moved to under "CLI Interface"? CLI Workflow ------------ -We have separate CLI commands for each stage of setup, running, and +We have separate CLI commands for each stage of setup, execution, and gathering results. With the CLI, the Python objects of :class:`.AlchemicalNetwork` and :class:`.ProtocolResult` are stored to disk in an intermediate representation between the commands. @@ -61,7 +61,7 @@ in an intermediate representation between the commands. planner to generate the network, before saving each transformation as a JSON file. -The commands used to generate an :class:`AlchemicalNetwork` using the CLI are: +The commands used to generate an :class:`.AlchemicalNetwork` using the CLI are: * :ref:`cli_plan-rbfe-network` * :ref:`cli_plan-rhfe-network` @@ -72,7 +72,7 @@ For example, you can create a relative binding free energy (RBFE) network using $ openfe plan-rbfe-network -p protein.pdb -M dir_with_sdfs/ -These will save the alchemical network represented as a JSON file for each +This will save the alchemical network represented as a JSON file for each edge of the :class:`.AlchemicalNetwork` (i.e., each leg of the alchemical cycle). To run a given transformation, use the :ref:`cli_quickrun`; for example: @@ -88,8 +88,8 @@ from the network planning command with something like this: .. TODO Link to example here. I think this is waiting on the CLI example being merged into example notebooks? -Finally, to gather the results of that, assuming all results (and only -results) are in the `results/` direcory, use the :ref:`cli_gather`: +Finally, assuming all results (and only results) are in the `results/` directory, +use the :ref:`cli_gather` to generate a summary table: .. code:: bash diff --git a/docs/guide/results/index.rst b/docs/guide/results/index.rst index e539879e2..931027218 100644 --- a/docs/guide/results/index.rst +++ b/docs/guide/results/index.rst @@ -1,7 +1,7 @@ .. _userguide_results: -Working with Results -===================== +Results Gathering +================= With simulations completed, the results of individual simulations can be inspected, diff --git a/docs/guide/setup/alchemical_network_creation.rst b/docs/guide/setup/alchemical_network_creation.rst deleted file mode 100644 index 7bd386802..000000000 --- a/docs/guide/setup/alchemical_network_creation.rst +++ /dev/null @@ -1,61 +0,0 @@ -.. _alchemical_network_creation: - -Alchemical Networks: Creation -============================= - -In :ref:`the previous section ` we detail the -theory of :class:`.AlchemicalNetwork` objects and what they contain. Here -we explain how you can go about creating a :class:`.AlchemicalNetwork` -by combining its various components. - -Python API ----------- - -You can manually create a :class:`.AlchemicalNetwork` by creating a list -of :class:`.Transformation` objects. -The :ref:`cookbook on creating alchemical networks ` -demonstrates how to do this. - -Alchemical Network Planners ---------------------------- - -OpenFE provides convenience classes for creating :class:`.AlchemicalNetwork`. -These currently include; - -* :class:`.RBFEAlchemicalNetworkPlanner`: creating relative binding free energy networks using the :class:`.RelativeHybridTopologyProtocol` -* :class:`.RHFEAlchemicalNetworkPlanner`: creating relative hydration free energy networks using the :class:`.RelativeHybridTopologyProtocol` - -The :ref:`Relative Alchemical Network Planners cookbook ` -demonstrates how to use these. - - -.. note:: - The Network Planners are provided for user convenience. Whilst they cover - majority of use cases, they may not currently offer the complete range - of options available through the Python API. - - -Command-line interface ----------------------- - -The Alchemical Network Planners can be used directly through the -:ref:`command line interface `. - -For example, you can create a relative binding free energy (RBFE) network -using: - -.. code:: bash - - $ openfe plan-rbfe-network -p protein.pdb -M dir_with_sdfs/ - -Similarly you can create a relative hydration free energy (RHFE) network -using: - -.. code:: bash - - $ openfe plan-rhfe network -M dir_with_sdfs/ - -Please see the :ref:`RBFE CLI tutorial ` -for an example on how to use the CLI to run an RBFE campaign. - -.. todo: link to appropriate CLI page in the userguide? diff --git a/docs/guide/setup/alchemical_network_model.rst b/docs/guide/setup/alchemical_network_model.rst index bb6033a59..179f28c96 100644 --- a/docs/guide/setup/alchemical_network_model.rst +++ b/docs/guide/setup/alchemical_network_model.rst @@ -3,20 +3,21 @@ Alchemical Networks: Planning a Simulation Campaign =================================================== -The goal of the setup stage is to create an :class:`.AlchemicalNetwork`, -which contains all the information needed for a campaign of simulations. -This section will describe the composition of the achemical network, -including the OpenFE objects that define chemistry, as well as -alchemical transformations. +The ultimate goal of the setup stage is to create an :class:`.AlchemicalNetwork`, +which contains all the information needed for a campaign of simulations, including the +``openfe`` objects that define the chemical systems and alchemical transformations. .. TODO provide a written or image based comparison between alchemical and thermodynamic cycles -Like any network, the :class:`.AlchemicalNetwork` can be described in terms -of nodes and edges between nodes. The nodes are :class:`.ChemicalSystem`\ s, +Like any network, an :class:`.AlchemicalNetwork` can be described in terms +of nodes and edges between nodes. The nodes are :class:`.ChemicalSystem`\s, which describe the specific molecules involved. The edges are :class:`.Transformation` objects, which carry all the information about how the simulation is to be performed. + +.. figure:: img/AlchemicalNetwork.png + In practice, nodes must be associated with a transformation in order to be relevant in an alchemical network; that is, there are no disconnected nodes. This means that the alchemical network can be fully described by just the @@ -32,14 +33,48 @@ containing the information for each :class:`.ChemicalSystem`, the relevant, atom mapping information for alchemical transformations. The latter is often done through a :class:`.LigandNetwork`. +.. _alchemical_network_creation: -.. figure:: img/AlchemicalNetwork.png +3 Ways to Create an Alchemical Network +-------------------------------------- + +1. Python API +^^^^^^^^^^^^^ + +You can manually create a :class:`.AlchemicalNetwork` by creating a list +of :class:`.Transformation` objects. For examples using the Python API, +see :ref:`cookbook on creating alchemical networks `. + +2. Python ``NetworkPlanner`` Convenience Classes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +OpenFE also provides the convenience classes :class:`.RBFEAlchemicalNetworkPlanner` and :class:`.RHFEAlchemicalNetworkPlanner`, +which use the :class:`.RelativeHybridTopologyProtocol` for creating :class:`.AlchemicalNetwork`\s. +For example usage of these convenience classes, see :ref:`Relative Alchemical Network Planners cookbook `. + +.. note:: + The Network Planners are provided for user convenience. While they cover + majority of use cases, they may not currently offer the complete range + of options available through the Python API. + +3. Command Line ``NetworkPlanner`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Alchemical Network Planners can also be called directly from the +:ref:`command line interface `. + +For example, you can create a Relative Hydration Free Energy (RHFE) network +using: + +.. code:: bash + + $ openfe plan-rhfe-network -M dir_with_sdfs/ + +or a Relative Binding Free Energy (RBFE) network using: +.. code:: bash -.. TODO where to find details on settings + $ openfe plan-rbfe-network -p protein.pdb -M dir_with_sdfs/ -See Also --------- -* :ref:`Alchemical Network API reference ` -* :ref:`Chemical Systems UserGuide entry ` +For more CLI details, see :ref:`RBFE CLI tutorial ` and the :ref:`userguide_cli_interface`. diff --git a/docs/guide/setup/chemical_systems_and_thermodynamic_cycles.rst b/docs/guide/setup/chemical_systems_and_thermodynamic_cycles.rst index 133ebcbfd..c4983dc01 100644 --- a/docs/guide/setup/chemical_systems_and_thermodynamic_cycles.rst +++ b/docs/guide/setup/chemical_systems_and_thermodynamic_cycles.rst @@ -1,54 +1,61 @@ .. _userguide_chemicalsystems_and_components: -ChemicalSystems, Components and Thermodynamic Cycles -==================================================== +Chemical Systems, Components and Thermodynamic Cycles +===================================================== + +.. _userguide_chemical_systems: Chemical Systems ---------------- -In order to define the input systems to a Protocol, -which correspond as the end states of an alchemical transformation, -we need an object model to represent their chemical composition. -In ``openfe`` a :class:`.ChemicalSystem` is used to capture this information, -and represents the chemical models that are present in each end state. +A :class:`.ChemicalSystem` represents the end state of an alchemical transformation, +which can then be input to a :class:`.Protocol`. -A :class:`.ChemicalSystem` **does** include information, where present, on: +A :class:`.ChemicalSystem` **does** contain the following information (when present): * exact atomic information (including protonation state) of protein, ligands, co-factors, and any crystallographic waters * atomic positions of all explicitly defined components such as ligands or proteins * the abstract definition of the solvation environment, if present -It **does not** include any information on: +A :class:`.ChemicalSystem` does **NOT** include the following: * forcefield applied to any component, including details on water model or virtual particles -* thermodynamic conditions, i.e. temperature and pressure +* thermodynamic conditions (e.g. temperature or pressure) + +.. _userguide_components: Components ---------- -A :class:`.ChemicalSystem` is composed of many :class:`.Component` objects, -each representing a single ''piece'' of the overall system. +A :class:`.ChemicalSystem` is composed of many 'component' objects, which together define overall system. + Examples of components include: -* :class:`.ProteinComponent` to represent an entire biological assembly, typically the contents of a PDB file -* :class:`.SmallMoleculeComponent` to represent ligands and cofactors -* :class:`.SolventComponent` to represent the solvent conditions +* :class:`.ProteinComponent`: an entire biological assembly, typically the contents of a PDB file. +* :class:`.SmallMoleculeComponent`: typically ligands and cofactors +* :class:`.SolventComponent`: solvent conditions Splitting the total system into components serves three purposes: -* alchemical transformations can be easily understood by comparing the differences in Components -* components can be reused to compose different systems -* ``Protocol`` \s can treat different components differently, for example applying different force fields +1. alchemical transformations can be easily understood by comparing the differences in components. +2. components can be reused to compose different systems. +3. :class:`.Protocol`\s can have component-specific behavior. E.g. different force fields for each component. Thermodynamic Cycles -------------------- -With a language to express chemical systems piecewise, we can now also construct thermodynamic cycles based on these. +We can now describe a thermodynamic cycle as a set of :class:`.ChemicalSystem`\s. The exact end states to construct are detailed in the :ref:`pages for each specific Protocol `. -For example to construct the classic relative binding free energy cycle, we will need four components, two ligands, -a protein, and a solvent. These four ingredients can then be combined into the four points on the thermodynamic cycle -that we wish to sample: + +As an example, we can construct the classic relative binding free energy cycle by defining four components: two ligands, +a protein, and a solvent: + +.. figure:: ../protocols/img/rbfe_thermocycle.png + :scale: 40% + :alt: RBFE thermodynamic cycle + + Illustration of the relative binding free energy thermodynamic cycles and the chemical systems at each end state. :: @@ -71,12 +78,6 @@ that we wish to sample: # ligand_A + solvent ligand_B_solvent = openfe.ChemicalSystem(components={'ligand': ligand_B, 'solvent': solvent}) -.. figure:: ../protocols/img/rbfe_thermocycle.png - :scale: 50% - :alt: RBFE thermodynamic cycle - - Illustration of the relative binding free energy thermodynamic cycles and the chemical systems at each end state. - See Also -------- diff --git a/docs/guide/setup/creating_atom_mappings_and_scores.rst b/docs/guide/setup/creating_atom_mappings_and_scores.rst index f2bca4630..2e0503649 100644 --- a/docs/guide/setup/creating_atom_mappings_and_scores.rst +++ b/docs/guide/setup/creating_atom_mappings_and_scores.rst @@ -4,24 +4,19 @@ Creating Atom Mappings ====================== -Once your :ref:`data has been loaded` -we can now proceed to defining how Components in these Systems correspond. -``Mapping`` objects are used to defined how ``Component`` objects from different :class:`.ChemicalSystem` objects are related. -This guide will show how this concept applies to the case of a pair of ligands we wish to transform between. +``Atom Mapping`` objects are used to define the relationship between +:ref:`components ` from different :class:`.ChemicalSystem`\s. +This guide will show how ``Atom Mappings`` can describe the transformation between a pair of ligands. Generating Mappings ------------------- -Mappings between small molecules are generated by a :class:`.LigandAtomMapper`, -which are reusable classes. -These take pairs of :class:`openfe.SmallMoleculeComponent` objects and suggests zero -(in the case that no mapping can be found) or more mappings. +The :class:`.LigandAtomMapper` takes pairs of :class:`openfe.SmallMoleculeComponent`\s and returns zero +(in the case that no mapping can be found) or more possible mappings. Built in to the ``openfe`` package are bindings to the `Lomap `_ package, -including the :class:`openfe.setup.LomapAtomMapper` -which uses an MCS approach based on the RDKit. -This takes various parameters which control how it produces mappings, -these are viewable through ``help(LomapAtomMapper)``. +including the :class:`.openfe.setup.LomapAtomMapper`, which uses an MCS approach based on RDKit. +.. TODO: insert example output This is how we can create a mapping between two ligands: @@ -34,22 +29,21 @@ This is how we can create a mapping between two ligands: m1 = SmallMoleculeComponent(...) m2 = SmallMoleculeComponent(...) - # first create the object which is a mapping producer + # first create an atom mapper mapper = setup.LomapAtomMapper(threed=True) - # this gives an iterable of possible mappings, zero or more! + # this returns an iterable of possible mappings mapping_gen = mapper.suggest_mappings(m1, m2) - # all possible mappings can be extracted into a list + # extract all possible mappings into a list mappings = list(mapping_gen) # Lomap always produces a single Mapping, so extract it from the list mapping = mappings[0] -The first and second ligand molecules put into the ``suggest_mappings`` method -are then henceforth referred to as ``componentA`` and ``componentB``. -The correspondence of atoms in these two components is then given via the ``.componentA_to_componentB`` attribute, -which returns a dictionary of integers. -Keys in this dictionary refer to the indices of atoms in the "A" molecule, -while the corresponding values refer to indices of atoms in the "B" molecule. +The two molecules passed into the ``suggest_mappings()`` method are then referred to +as ``componentA`` and ``componentB`` (in the above example, ``m1`` is ``componentA`` and ``m2`` is ``componentB``). + +The atom mapping can be accessed through the ``componentA_to_componentB`` attribute, which returns a dictionary +where keys refer to the indices of atoms in the "A" component, and values refer to indices of atoms in the "B" component. If a given index does not appear, then it is unmapped. @@ -64,8 +58,7 @@ In an interactive notebook we can view a 2D representation of the mapping. In this view, atoms that are deleted are coloured red, while atoms that undergo an elemental transformation are coloured blue. Similarly, bonds that are deleted are coloured red, -while bonds that change, either bond order or are between different elements, -are coloured blue. +while bonds that change (either bond order change or element change), are coloured blue. .. image:: img/2d_mapping.png @@ -74,11 +67,9 @@ are coloured blue. :alt: Sample output of 2d mapping visualisation -These 2D mappings can be saved to file using the :func:`LigandAtomMapping.draw_to_file` function. +These 2D mappings can be saved to file using the :func:`LigandAtomMapping.draw_to_file()` method. -With the ``py3dmol`` package installed, -we can also view the mapping in 3D allowing us to manually inspect the spatial overlap -of the mapping. +With the ``py3dmol`` package, we can inspect the spatial overlap of the mapping in 3D. In a notebook, this produces an interactive rotatable view of the mapping. The left and rightmost views show the "A" and "B" molecules with coloured spheres on each showing the correspondence between atoms. @@ -104,22 +95,22 @@ This returns a numpy array. mapping.get_distances() +.. _Scoring Atom Mappings: Scoring Mappings ---------------- -With many possible mappings, -and many ligand pairs we could form mappings between, -we use **scorers** to rate if a mapping is a good idea. -These take a ``LigandAtomMapping`` object and return a value from 0.0 (indicating a terrible mapping) -to 1.0 (indicating a great mapping), and so can be used as objective functions for optimizing ligand networks. +Mapping **scorers**, or "scoring functions", evaluate the quality of an atom mapping and +can be used as objective functions for optimizing ligand networks. +**Scorers** take a :class:`.LigandAtomMapping` object and return a value from 0.0 (indicating a terrible mapping) +to 1.0 (indicating a great mapping). + +Because **scorers** are normalized, it is possible to use multiple **scorers** together. +For example, the built-in Lomap scorer :func:`default_lomap_score` combines several criteria +(such as the number of heavy atoms, if certain chemical changes are present, +and if ring sizes are being mutated), into a single value. +It is possible to combine scoring functions in this way because each scoring function returns a normalized value. -Again, the scoring functions from Lomap are included in the ``openfe`` package. -The :func:`default_lomap_score` function combines many different criteria together -such as the number of heavy atoms, -if certain chemical changes are present, -and if ring sizes are being mutated, -into a single value. .. code:: @@ -128,8 +119,3 @@ into a single value. mapping = next(mapper.suggest_mappings(m1, m2)) score = lomap_scorers.default_lomap_scorer(mapping) - - -As each scoring function returns a normalised value, -it is possible to chain together various scoring functions, -which is how this ``default_lomap_score`` function is constructed! diff --git a/docs/guide/setup/creating_ligand_networks.rst b/docs/guide/setup/creating_ligand_networks.rst index 25d7379e2..f83e55f2e 100644 --- a/docs/guide/setup/creating_ligand_networks.rst +++ b/docs/guide/setup/creating_ligand_networks.rst @@ -2,32 +2,32 @@ Defining the Ligand Network =========================== -A :class:`.LigandNetwork` is a set of small molecules connected by mappings of two small molecules. -One example for such a network could be a set of drug candidates, that should be ranked using alchemical transformations. -The :class:`.LigandNetwork` is a tool that is used to orchestrate the free energy calculations to efficiently -compute a ligand ranking. -It is of course possible to calculate all possible :class:`.Transformation` defined by all possible :class:`.AtomMappings` -connecting all :class:`.SmallMoleculeComponent` with a ''maximal network'' (using :func:`.generate_maximal_network`), -but it is much more efficient to use a network with less transformations like a ''radial network'' (also known as a star map, using :func:`.generate_radial_network`) -or a ''minimimal spanning network'' (using :func:`.generate_minimal_spanning_network`). +A :class:`.LigandNetwork` is a set of connected small molecule ``component``\s, such as a set of drug candidates, +that can be used to orchestrate free energy calculations and efficiently compute a ligand ranking. -Any :class:`.LigandNetwork`` generation can be generally conceptualized into three steps: +It is of course possible to calculate all possible :class:`.Transformation`\s, defined as all possible :class:`.AtomMappings` +connecting all :class:`.SmallMoleculeComponent` in a "maximal network" (using :func:`.generate_maximal_network`), +but it is much more efficient to use a network with fewer transformations like a "radial network" (also known as a star map, using :func:`.generate_radial_network`) +or a "minimimal spanning network" (using :func:`.generate_minimal_spanning_network`). -* Generate the :ref:`Atom Mappings` of all pairwise combinations of ligands -* :ref:`Score all resulting Atom Mappings` -* Build a :class:`.LigandNetwork` with all possible mappings directed by their scores. +:class:`.LigandNetwork` generation can typically be described as three steps: + + 1. Generate the :ref:`Atom Mappings` of all pairwise combinations of ligands. + 2. :ref:`Score ` all generated Atom Mappings. + 3. Build a ``LigandNetwork`` of all possible mappings and their scores. .. image:: img/ligand_network.png - :width: 90% + :width: 50% :align: center - :alt: Concept of a simple MST ligand network + :alt: Diagram of a simple MST ligand network Generating Ligand Networks -------------------------- -The ''LigandNetwork'' can be generated with OpenFE employing a :class:`.LigandAtomMapper` and a atom mapping scorer, -like the :func:`.default_lomap_score` together with a ``LigandNetworkPlanner``, like e.g. the :func:`.generate_radial_network`. +The :class:`.LigandNetwork` can be generated with OpenFE employing a :class:`.LigandAtomMapper` and an atom mapping scorer, +like the :func:`.default_lomap_score` together with a ``LigandNetworkPlanner``, such as :func:`.generate_radial_network`. + In the following code, we will show how a ``LigandNetwork`` can be planned: .. code:: diff --git a/docs/guide/setup/defining_protocols.rst b/docs/guide/setup/defining_protocols.rst index 6acd6e6d8..e1d4a39b4 100644 --- a/docs/guide/setup/defining_protocols.rst +++ b/docs/guide/setup/defining_protocols.rst @@ -1,70 +1,67 @@ .. _defining-protocols: -Creating and using Protocols +Protocols in OpenFE ============================ -With a thermodynamic cycle of interest identified and represented using `ChemicalSystem` objects, -the next step is to choose a method for estimating the free energy differences. -This is done using a :class:`.Protocol`, -a computational method for estimating the free energy difference between two chemical systems. +A :class:`.Protocol` is a computational method for estimating the free energy difference between two chemical systems. Just as there are multiple possible methods for estimating free energy differences, -there are multiple available Protocols to choose from. -For example, included in the ``openfe`` package are the -:class:`.RelativeHybridTopologyProtocol`, -:class:`.AbsoluteSolvationProtocol`, -and :class:`.PlainMDProtocol`; -for a full list see :ref:`userguide_protocols`. -This selection is being built upon, -both by the openfe development team as well as with external academic groups. - -What all these Protocols share is a common interface for how they are created and executed, -therefore it is relatively simple to -try out a new method, +there are multiple available ``Protocol``\s to choose from. + +For example, included in the ``openfe`` package are the following: + * :class:`.RelativeHybridTopologyProtocol` + * :class:`.AbsoluteSolvationProtocol` + * :class:`.PlainMDProtocol` + +More protocols are in development, and a full list of available protocols +can be found at :ref:`userguide_protocols`. + +Because :class:`.Protocol`\s share a common interface for how they are created and executed, +it is relatively straightforward to try out a new method, or benchmark several to choose the best for a particular project. -Settings and creating Protocols -------------------------------- +Defining Settings and Creating Protocols +---------------------------------------- + +A ``Settings`` object contains all the parameters needed by a ``Protocol``. +Each ``Protocol`` has a ``.default_settings()`` method, which will provide a sensible default +starting point and relevant documentation. + +.. TODO: print what a settings object looks like, or how you might define custom settings -A ``Protocol`` has a variety of options which control the details of how it behaves, -these are referred to as ``Settings``. -While methods which share common foundations and approaches will share many of these options in common, -ultimately the best resource for understanding these will be the documentation for each particular ``Protocol``. -Each Protocol will define a ``.default_settings()`` method, -which will return a sensible default starting point. For example, to create an instance of the OpenMM RFE Protocol with default settings:: from openfe.protocols import openmm_rfe settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() - prot = openmm_rfe.RelativeHybridTopologyProtocol(settings) + protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings) -A key point of ``Protocol`` objects is that they cannot be modified once created, -this is important for later tracking the provenance of data, -therefore the ``Settings`` objects must be customised before the ``Protocol`` object is created. -For example to customise the production run length of the RFE Protocol:: +``Protocol`` objects **cannot be modified once created**. This is crucial for data provenance. +Therefore, the ``Settings`` objects must be customised *before* the ``Protocol`` object is created. +For example, to customise the production run length of the RFE Protocol:: from openfe.protocols import openmm_rfe settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.simulation_settings.production_length = '10 ns' - prot = openmm_rfe.RelativeHybridTopologyProtocol(settings) + protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings) + -Using Protocols ---------------- +Creating Transformations from Protocols +----------------------------------------- -Up until this point, the ``Protocol`` has not involved any of the specific chemistry that is of interest. -This means that a single defined ``Protocol`` can be applied to multiple pairs of ``ChemicalSystem`` objects -to measure each difference. -The :class:`.Transformation` object is a handy container for connecting two ``ChemicalSystem`` objects -and the ``Protocol`` together. -Often a :class:`.LigandAtomMapping` object is also required to define the correspondence of atoms, -for further details refer to the :ref:`userguide_mappings` section. +With only ``settings`` defined, a ``Protocol`` contains no chemistry-specific information. +This means that a single ``Protocol`` object can be applied to multiple pairs of ``ChemicalSystem`` objects +to measure each free energy difference. -The ``Transformation`` object is then capable of creating computational work via the :func:`.Transformation.create()` method. +The :class:`.Transformation` class connects two ``ChemicalSystem`` objects with a ``Protocol``, and +often a :ref:`AtomMapping ` (depending on the system). + +A ``Transformation`` object is then capable of creating computational work via the :func:`.Transformation.create()` method. For further details on this, refer to the :ref:`userguide_execution` section. -Finaly, a ``Protocol`` is responsible for using the data generated in this process to perform further analysis, + +Finally, a ``Protocol`` is responsible for using the data generated in this process to perform further analysis, such as generating an estimate of the free energy difference. For further details on this refer to the :ref:`userguide_results` section, or the details of each method in :ref:`userguide_protocols`. diff --git a/docs/guide/setup/index.rst b/docs/guide/setup/index.rst index e2a60cfb9..636bb800a 100644 --- a/docs/guide/setup/index.rst +++ b/docs/guide/setup/index.rst @@ -1,40 +1,42 @@ +.. _userguide_setup: + Simulation Setup ================ -This section provides details on how to set up free energy calculation or MD simulations. +This section provides details on how to set up a free energy calculation or MD simulations. All protocols in OpenFE follow the same general structure: -* Reading in input structures and Creating ``ChemicalSystem`` \s -* Defining the Protocol with specific ProtocolSettings -* Creating ``LigandAtomMapping`` \s for relative free energy calculations Protocols +* Reading in input structures and creating :class:`.ChemicalSystem` \s +* Defining the :class:`.Protocol` with specific `ProtocolSettings`. +* Creating :class:`.LigandAtomMapping` \s for relative free energy calculation `Protocols`. .. image:: img/setup_1x.png - :width: 60% + :width: 70% :align: center :alt: Concept of a ChemicalSystems and Transformations -The image below demonstrates how, for relative free energy calculations, you plan a network of ligand transformations starting from input SDF / MOL2 / PDB files: +The image below demonstrates how, for relative free energy calculations, you plan a +network of ligand transformations starting from input SDF / MOL2 / PDB files: .. image:: img/setup_2x.png - :width: 60% + :width: 70% :align: center :alt: Concept of a LigandNetwork and AlchemicalNetwork -The procedure for setting up a simulation depends somewhat on the on the -type of free energy calculation you are running. See more detailed -instructions can be found under: +The procedure for setting up a simulation depends on the +type of free energy calculation you are running. More detailed +instructions can be found in the following sections: .. toctree:: + :maxdepth: 1 chemical_systems_and_thermodynamic_cycles creating_atom_mappings_and_scores defining_protocols creating_ligand_networks alchemical_network_model - alchemical_network_creation -If you intend to set up your alchemical network using the Python interface, -but to run it using the CLI, you will want to export the network in the same -format used by the CLI. See :ref:`dumping transformations ` -for more details. +To set up your alchemical network using the Python interface, but run it using the CLI, +you will need to export the network in the same format used by the CLI. +See :ref:`dumping transformations ` for more details. diff --git a/docs/guide/troubleshooting.rst b/docs/guide/troubleshooting.rst index 52d756f64..d408ef807 100644 --- a/docs/guide/troubleshooting.rst +++ b/docs/guide/troubleshooting.rst @@ -2,20 +2,24 @@ Troubleshooting Simulations =========================== -There are many different failure modes for simulations. -In this guide, we will cover some tips and strategies for troubleshooting simulation failures. +This guide covers tips and strategies for troubleshooting simulation failures. Log Debug information --------------------- .. note:: - When using a scheduler (e.g. SLURM) be sure to specify output files for standard out and standard error. - For example when using SLURM both ``--output=`` and ``--error=`` must be set to view errors. + When using a scheduler (e.g. SLURM), be sure to specify output files for standard out and standard error. + For example, when using SLURM both ``--output=`` and ``--error=`` must be set to view errors. One of the first troubleshooting steps is to increase the verbosity of the logging. ``openfe`` uses Python's native logging library which can be `configured `_ either using a Python API or a configuration file. -When using ``openfe quickrun`` using the configuration file is more convenient. + +.. warning:: + + **We do not recommend setting the log level to debug for production runs,** as the logging may slow down the simulation and add a lot of noise to the output. + +When using ``openfe quickrun``, the configuration file is more convenient. Below is an example logging configuration file that can be used to set the log level to ``DEBUG``: .. code-block:: ini @@ -51,9 +55,6 @@ Save this configuration file as ``debug_logging.conf`` and then run ``openfe qui $ openfe --log debug_logging.conf quickrun -d results/ -o results/result_lig_ejm_31_solvent_lig_ejm_42_solvent.json transformations/easy_rbfe_lig_ejm_31_solvent_lig_ejm_42_solvent.json -.. note:: - - The ``--log debug_logging.conf`` argument goes between ``openfe`` and ``quickrun``. +Note that the ``--log debug_logging.conf`` argument goes between ``openfe`` and ``quickrun`` on the command line. This will cause every package to log at the debug level, which may be quite verbose and noisy but should aid in identify what is going on right before the exception is thrown. -We do not recommend setting the log level to debug for production runs as the logging may slow down the simulation and add a lot of noise to the output.