molforge.freeenergy¶
freeenergy ¶
Binding free energy: result types, ranking, and engine base.
An endpoint binding free energy method estimates the free energy of association ΔG_bind for a receptor–ligand complex from an ensemble of structures (typically an MD trajectory), without the alchemical machinery of FEP/TI. The workhorse is MM/GBSA (and its Poisson– Boltzmann sibling MM/PBSA): molecular-mechanics interaction energy plus an implicit-solvent correction, averaged over frames.
molforge treats these as post-processors over a
:class:molforge.md.Trajectory: the MD layer produces the ensemble,
this layer consumes it and returns a :class:FreeEnergyResult. Concrete
engines that invoke MMPBSA.py / gmx_MMPBSA live under
:mod:molforge.wrappers.freeenergy; this module holds the shared types
and the :class:MMGBSAEngine base they implement.
A word on what these numbers are worth. Endpoint methods are notoriously
poor at absolute affinities — the implicit-solvent term is
systematically biased and the configurational entropy is usually dropped
— but the rank order across a congeneric series is often useful. The
types here lean into that: every result carries an uncertainty, entropy
is explicitly None when it wasn't computed (rather than silently
zero), and :class:FreeEnergyRanking exposes pairwise ΔΔG with
propagated error rather than a bare ordering, so ties within the error
bars stay visible.
FreeEnergyComponents
dataclass
¶
FreeEnergyComponents(
vdw: float,
electrostatic: float,
polar_solvation: float,
nonpolar_solvation: float,
entropy: float | None = None,
)
Per-term decomposition of a binding free energy, in kcal/mol.
The four energetic terms are the standard MM/PB(GB)SA breakdown; each
is a difference (complex − receptor − ligand). entropy is the
configurational entropy contribution −TΔS, carried separately because
it comes from a distinct calculation (normal-mode or quasi-harmonic)
that single-trajectory runs usually skip.
Attributes:
| Name | Type | Description |
|---|---|---|
vdw |
float
|
Van der Waals interaction energy. |
electrostatic |
float
|
Electrostatic (Coulomb) interaction energy. |
polar_solvation |
float
|
Polar solvation free energy (GB or PB term). |
nonpolar_solvation |
float
|
Nonpolar / cavity + dispersion solvation term. |
entropy |
float | None
|
The −TΔS contribution, or |
enthalpy
property
¶
Interaction enthalpy: the sum of the four energetic terms.
This is the ΔH part of ΔG = ΔH − TΔS. When entropy is
None, this equals the reported binding free energy (endpoint
runs without an entropy calculation report ΔH as ΔG).
FreeEnergyResult
dataclass
¶
FreeEnergyResult(
delta_g: float,
uncertainty: float,
method: str,
components: FreeEnergyComponents | None = None,
convergence: NDArray[float64] | None = None,
provenance: Provenance | None = None,
metadata: dict[str, object] = dict(),
decomposition: Decomposition | None = None,
)
A binding free energy estimate with its uncertainty.
Attributes:
| Name | Type | Description |
|---|---|---|
delta_g |
float
|
Binding free energy ΔG_bind in kcal/mol. Lower (more negative) means tighter binding. |
uncertainty |
float
|
Standard error of |
method |
str
|
Method label, e.g. |
components |
FreeEnergyComponents | None
|
Per-term :class: |
convergence |
NDArray[float64] | None
|
Optional |
provenance |
Provenance | None
|
Optional :class: |
metadata |
dict[str, object]
|
Engine-specific extras (per-term std devs, frame count, solvent model, walltime, ...). |
decomposition |
Decomposition | None
|
Optional per-residue :class: |
DeltaDeltaG
dataclass
¶
A relative binding free energy between two ligands, with error.
Attributes:
| Name | Type | Description |
|---|---|---|
reference |
str
|
Label of the reference ligand. |
other |
str
|
Label of the other ligand. |
value |
float
|
ΔΔG = ΔG(other) − ΔG(reference) in kcal/mol. Negative
means |
uncertainty |
float
|
Propagated standard error,
|
tighter |
str
|
Label of the tighter-binding ligand (the lower ΔG). On
an exact tie this is |
FreeEnergyRanking ¶
An affinity ranking over labelled :class:FreeEnergyResult\ s.
Ranking — "which of these ligands binds tightest?" — is the tractable
job for endpoint methods, so this is the headline output over a
congeneric series. Results are ordered by delta_g ascending
(tightest first). Comparisons are exposed as :class:DeltaDeltaG
with propagated uncertainty rather than a bare rank, so a pair that
is tied within error stays visibly tied. Deliberately absent: any
significance verdict — the right test depends on assumptions
(frame correlation, Gaussianity) molforge should not bake in.
Build a ranking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
results
|
Mapping[str, FreeEnergyResult]
|
Mapping from ligand label to its
:class: |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
ranked
property
¶
(label, result) pairs, tightest binder first.
delta_delta_g ¶
Relative binding free energy of other vs reference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reference
|
str
|
Label of the reference ligand. |
required |
other
|
str
|
Label of the ligand compared against the reference. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
DeltaDeltaG
|
class: |
DeltaDeltaG
|
uncertainty. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If either label is not in the ranking. |
ResidueContribution
dataclass
¶
ResidueContribution(
residue: str,
total: float,
uncertainty: float,
internal: float,
vdw: float,
electrostatic: float,
polar_solvation: float,
nonpolar_solvation: float,
)
One residue's contribution to the binding free energy.
From a per-residue MM/PB(GB)SA decomposition (the DELTA section):
total is the residue's net contribution to ΔG_bind, split into the
same energy terms as the overall estimate. A large negative total
marks a binding hotspot; a positive one, a residue that opposes
binding.
Attributes:
| Name | Type | Description |
|---|---|---|
residue |
str
|
Residue label, e.g. |
total |
float
|
Net contribution to ΔG_bind in kcal/mol (the sum of the component terms below). |
uncertainty |
float
|
Standard error of |
internal |
float
|
Internal term (bond/angle/dihedral; plus 1-4 for
|
vdw |
float
|
van der Waals contribution. |
electrostatic |
float
|
Electrostatic contribution. |
polar_solvation |
float
|
Polar solvation contribution. |
nonpolar_solvation |
float
|
Non-polar solvation contribution. |
Decomposition ¶
A per-residue decomposition of a binding free energy.
A mapping from residue label to its :class:ResidueContribution,
preserving the order the residues were reported, with
:meth:hotspots to surface the residues that drive (or oppose)
binding. This is the endpoint-method answer to "where does the
affinity come from?" once :class:FreeEnergyRanking has answered
"which ligand?".
Build a decomposition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contributions
|
Sequence[ResidueContribution]
|
Per-residue contributions, in report order. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If two contributions share a residue label. |
hotspots ¶
Residues ranked by contribution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int | None
|
Return at most this many; |
None
|
favorable
|
bool
|
If true (default), most binding-favorable first
(most negative |
True
|
Returns:
| Type | Description |
|---|---|
list[ResidueContribution]
|
The ranked contributions. |
MMGBSAEngine ¶
Bases: ABC
Abstract base for endpoint binding-free-energy engines.
Concrete engines (under :mod:molforge.wrappers.freeenergy) invoke an
external tool — MMPBSA.py or gmx_MMPBSA — building its input
from a trajectory, running it, and parsing the results into a
:class:FreeEnergyResult. They handle their own topology/endpoint
marshalling rather than exposing it to callers.
Despite the name, these engines do both MM/GBSA and MM/PBSA; the
solvent model is a parameter (solvent_model) that defaults to
generalized Born ("gb", i.e. MM/GBSA). Poisson–Boltzmann
("pb", MM/PBSA) is the slower, off-default alternative.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Human-readable engine name (set by subclasses). |
run
abstractmethod
¶
run(
trajectory: Trajectory,
*,
receptor: object,
ligand: object,
solvent_model: str = "gb",
**kwargs: object,
) -> FreeEnergyResult
Estimate ΔG_bind from a trajectory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trajectory
|
Trajectory
|
The ensemble to average over; its topology defines the complex. |
required |
receptor
|
object
|
Selection identifying the receptor atoms within the complex (resolved against the topology, consistent with molforge's selection machinery). |
required |
ligand
|
object
|
Selection identifying the ligand atoms. |
required |
solvent_model
|
str
|
|
'gb'
|
**kwargs
|
object
|
Engine-specific options. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
FreeEnergyResult
|
class: |
FreeEnergyResult
|
the tool reports them — a component breakdown. |
MMGBSAEngineNotInstalledError ¶
Bases: ImportError
Raised when an endpoint-free-energy engine's tool isn't installed.
The message points at the relevant install instructions (Amber's
MMPBSA.py or gmx_MMPBSA) so users can fix it without grepping
the docs.