Skip to content

Commit

Permalink
some work on API docs
Browse files Browse the repository at this point in the history
  • Loading branch information
richardjgowers committed Jan 26, 2024
1 parent 201c17c commit c140fea
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 29 deletions.
7 changes: 6 additions & 1 deletion cinnabar/arsenic.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# this will combine a single command that will run all analysis and save everything
"""
cinnabar.arsenic
================
Containing the command line interface usage of cinnabar.
"""
import argparse

from . import FEMap, plotting
Expand Down
37 changes: 24 additions & 13 deletions cinnabar/femap.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""
FEMap
=====
The workhorse of cinnabar, a :class:`FEMap` contains many measurements of free energy differences,
both relative and absolute,
which form an interconnected "network" of values.
"""
import pathlib
from typing import Union
import copy
Expand Down Expand Up @@ -76,26 +84,28 @@ class FEMap:
Examples
--------
To read from a csv file specifically formatted for this, you can use:
>>> fe = FEMap.from_csv('../data/example.csv')
To construct manually:
To construct a FEMap by hand:
>>> # Load/create experimental results
>>> from openff.units import unit
>>> kJpm = unit.kilojoule_per_mole
>>> g = ReferenceState()
>>> experimental_result1 = Measurement(labelA=g, labelB="CAT-13a", DG=-8.83 * kJpm, uncertainty=0.10 * kJpm)
>>> experimental_result2 = Measurement(labelA=g, labelB="CAT-17g", DG=-9.73 * kJpm, uncertainty=0.10 * kJpm)
>>> experimental_result1 = Measurement(labelA=g, labelB="CAT-13a", DG=-8.83 * kJpm, uncertainty=0.10 * kJpm,
... computational=False)
>>> experimental_result2 = Measurement(labelA=g, labelB="CAT-17g", DG=-9.73 * kJpm, uncertainty=0.10 * kJpm,
... computational=False)
>>> # Load/create calculated results
>>> calculated_result = Measurement(labelA="CAT-13a", labelB="CAT-17g", DG=0.36 * kJpm,
... uncertainty=0.11 * kJpm)
... uncertainty=0.11 * kJpm, computational=True)
>>> # Incrementally created FEMap
>>> fe = FEMap()
>>> fe.add_measurement(experimental_result1)
>>> fe.add_measurement(experimental_result2)
>>> fe.add_measurement(calculated_result)
To read from a legacy csv file specifically formatted for this, you can use:
>>> fe = FEMap.from_csv('../data/example.csv')
"""
# internal representation:
# graph with measurements as edges
Expand Down Expand Up @@ -144,12 +154,13 @@ def to_networkx(self) -> nx.MultiDiGraph:
The FEMap is represented as a multi-edged directional graph
Edges have the following attributes:
- DG: the free energy difference of going from the first edge label to
* DG: the free energy difference of going from the first edge label to
the second edge label
- uncertainty: uncertainty of the DG value
- temperature: the temperature at which DG was measured
- computational: boolean label of the original source of the data
- source: a string describing the source of data.
* uncertainty: uncertainty of the DG value
* temperature: the temperature at which DG was measured
* computational: boolean label of the original source of the data
* source: a string describing the source of data.
Note
----
Expand Down
63 changes: 51 additions & 12 deletions cinnabar/measurements.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""
Measurements
============
Contains the :class:`Measurement` class which is used to define a single free energy difference,
as well as the :class:`ReferenceState` class which denotes the end point for absolute measurements.
"""
from openff.models.models import DefaultModel
from openff.models.types import FloatQuantity
from openff.units import unit
Expand All @@ -8,17 +16,10 @@
class ReferenceState:
"""A label indicating a reference point to which absolute measurements are relative
E.g. an absolute measurement for "LigandA" is defined as::
>>> m = Measurement(labelA=ReferenceState(), labelB='LigandA',
... DG=2.4 * unit.kilocalorie_per_mol,
... uncertainty=0.2 * unit.kilocalorie_per_mol,
... source='gromacs')
A ``ReferenceState`` optionally has a label, which is used to differentiate
it to other absolute measurements that might be relative to a different
reference point. E.g. MLE measurements are against an arbitrary reference
state that must be linked to the reference point of experiments.
reference point. E.g. MLE estimations are against an arbitrary reference
state that can be linked to the reference point of experiments.
"""
label: str

Expand All @@ -33,6 +34,7 @@ def __init__(self, label: str = ""):
self.label = label

def is_true_ground(self) -> bool:
"""If this ReferenceState is the zero point of all other measurements"""
return not self.label

def __repr__(self):
Expand All @@ -49,17 +51,52 @@ def __hash__(self):


class Measurement(DefaultModel):
"""The free energy difference of moving from A to B"""
"""The free energy difference of moving from A to B
All quantities are accompanied by units, to prevent mix-ups associated with
kcal and kJ. This is done via the `openff.units` package::
>>> m = Measurement(labelA='LigandA', labelB='LigandB',
... DG=2.4 * unit.kilocalorie_per_mol,
... uncertainty=0.2 * unit.kilocalorie_per_mol,
... computational=True,
... source='gromacs')
Alternatively strings are automatically coerced into quantities, making this
equivalent to above::
>>> m = Measurement(labelA='LigandA', labelB='LigandB',
... DG='2.4 kcal/mol',
... uncertainty='0.2 kcal/mol',
... computational=True,
... source='gromacs')
Where a measurement is "absolute" then a `ReferenceState` can be used as the
label at one end of the measurement. I.e. it is relative to a reference
ground state. E.g. an absolute measurement for "LigandA" is defined as::
>>> m = Measurement(labelA=ReferenceState(), labelB='LigandA',
... DG=-11.2 * unit.kilocalorie_per_mol,
... uncertainty=0.3 * unit.kilocalorie_per_mol,
... computational=False)
"""
class Config:
frozen = True

labelA: Hashable
"""Label of state A, e.g. a ligand name or any hashable Python object"""
labelB: Hashable
"""Label of state B"""
DG: FloatQuantity['kilocalorie_per_mole']
"""The free energy difference of moving from A to B"""
uncertainty: FloatQuantity['kilocalorie_per_mole']
"""The uncertainty of the DG measurement"""
temperature: FloatQuantity['kelvin'] = 298.15 * unit.kelvin
"""Temperature that the measurement was taken as"""
computational: bool
"""If this measurement is computationally based (or experimental)"""
source: str = ""
"""An arbitrary label to group measurements from a common source"""

@classmethod
def from_experiment(cls,
Expand All @@ -70,7 +107,9 @@ def from_experiment(cls,
source: str = '',
temperature: unit.Quantity = 298.15 * unit.kelvin,
):
"""Create Measurement from experimental data
"""Shortcut to create a Measurement from experimental data
Can perform conversion from Ki values to kcal/mol values.
Parameters
----------
Expand All @@ -84,7 +123,7 @@ def from_experiment(cls,
default is zero if no uncertainty is provided (0 * unit.nanomolar)
source: str, optional
source of experimental measurement
temperature: unit.Quantity
temperature: unit.Quantity, optional
temperature in K at which the experimental measurement was carried out.
By default: 298 K (298.15 * unit.kelvin)
"""
Expand Down
7 changes: 5 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ API Documentation
=================

.. autosummary::
:toctree: autosummary
:toctree: generated

cinnabar.plotting
cinnabar.arsenic
cinnabar.femap
cinnabar.measurements
cinnabar.plotlying
cinnabar.plotting
cinnabar.stats
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
"cinnabar Documentation",
author,
"cinnabar",
"Report results for free energy simualtions",
"Report results for free energy simulations",
"Miscellaneous",
),
]
Expand Down

0 comments on commit c140fea

Please sign in to comment.