Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion devtools/conda-envs/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ channels:
- conda-forge
dependencies:
- gufe
- openfe<1.9
- openfe<1.9 # From alchemiscale stack dependence?
- pytest
- pre-commit
- pontibus==0.4.0
- pint
# - cinnabar >= 0.6.1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ summary: |
# REQUIRED: list of submission tags
tags: [rbfe, ff14SB, phosaa10, tip3p_HFE_multivalent, tip3p_standard, openff-2.3.0, bace, cdk2, jacs_set, jnk1, mcl1, p38, ptp1b, thrombin, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, openfe, alchemicalarchive]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
- name: Josh Horton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ summary: |
# REQUIRED: list of submission tags
tags: [rbfe, ff14SB, phosaa10, tip3p_HFE_multivalent, tip3p_standard, charge_annihilation_set, egfr, irak4_s2, irak4_s3, jacs_set, p38, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, charge_change, benchmark, openfe, openmm-840]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
- name: Josh Horton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ summary: |
resources/submissions/2026_03_17_openff-2.3.0_jacs_tyk2/alchemiscale_submission.ipynb

# REQUIRED: list of submission tags
tags: [rbfe, ff14SB, phosaa10, tip3p_HFE_multivalent, tip3p_standard, openff-2.3.0, jacs_set, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]
tags: [rbfe, alchemicalarchive, ff14SB, phosaa10, tip3p_HFE_multivalent, tip3p_standard, openff-2.3.0, jacs_set, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# REQUIRED: unique, kebab-case identifier for this submission
submission_id: 2026-08-06-openff-2.3.0-solvation_set_freesolv

# REQUIRED: short descriptive title
title: OpenFE ASFE - solvation_set - freesolv - 2026-08-06-openff-2.3.0-solvation_set_freesolv

# REQUIRED: short descriptive summary (1-2 sentences)
summary: |
This submission describes the ASFE benchmark covering the solvation_set benchmark set (freesolv)
prepared with openff-2.3.0/tip3p for solvents and nagl_openff-gnn-am1bcc-1.0.0.pt for solutes and
cofactors. The archive contains 603 edges across 603 unique solutes and 1 unique solvents. Results
are derived from archived Alchemiscale workflow data. This is the full freesolv set that is
parametrizable by OpenFF-2.3.0, submitted before the development of OpenFF subsets.

# REQUIRED: list of submission tags
tags: [alchemicalarchive, asfe, freesolv, nagl_openff-gnn-am1bcc-1.0.0.pt, openff-2.3.0, pontibus, solvation_set, tip3p]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: asfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
- name: Jennifer A Clark

# REQUIRED: publication/submission date (ISO 8601)
date: 2026-08-06
openfe_version: "1.8.0"
openmm_version: "8.2.0"
openff_toolkit_version: "0.18"

forcefield: ["openff-2.3.0", "tip3p"]

partial_charges: "nagl_openff-gnn-am1bcc-1.0.0.pt"

## BenchmarkData Provenance (from openfe-benchmarks planning script) with associated network key
benchmark_data:
source_repository: https://github.com/OpenFreeEnergy/openfe-benchmarks
"solvation_set":
"freesolv": AlchemicalNetwork-55961080ba1805b112aff83fca84b15f


# REQUIRED: results file
results: computational_results.json.bz2

# REQUIRED: long-term archive pointer (at least doi or url)
archive:
doi: 10.5281/zenodo.21810272
archive_provider: zenodo

# REQUIRED: license for the submission
license: CC-BY-4.0

# RECOMMENDED / OPTIONAL metadata for protocol settings
protocol_settings:
- protocol: "ASFEProtocol"
protocol_library: "pontibus"
timestep: "4.0 fs"
temperature: "298.15 K"
pressure: "1 bar"
forcefields: ["openff-2.3.0", "tip3p"]
small_molecule_forcefield: ""
partial_charges: "nagl_openff-gnn-am1bcc-1.0.0.pt"
equilibration_time:
production_time:
vacuum_equilibration_time: "500.00000000000006 ps"
vacuum_production_time: "2.0 ns"
solvent_equilibration_time: "1.0 ns"
solvent_production_time: "10.0 ns"
lambda_functions: ""
lambda_windows: ""
lambda_schedule: ""
notes: "Applies to all edges"

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ summary: |
resources/submissions/2026_07_15_openff-3.0.0-alpha1b_opc3/alchemiscale_submission.ipynb

# REQUIRED: list of submission tags
tags: [rbfe, opc3.offxml, openff-3.0.0-alpha1b, bace, cdk2, jacs_set, jnk1, mcl1, p38, ptp1b, thrombin, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]
tags: [rbfe, "alchemicalarchive", opc3.offxml, openff-3.0.0-alpha1b, bace, cdk2, jacs_set, jnk1, mcl1, p38, ptp1b, thrombin, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ summary: |
# REQUIRED: list of submission tags
tags: [rbfe, opc3.offxml, openff-3.0.0-alpha0, bace, cdk2, jacs_set, jnk1, mcl1, p38, ptp1b, thrombin, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
- name: Jennifer A. Clark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ summary: |
# REQUIRED: list of submission tags
tags: [rbfe, openff-3.0.0-alpha1b, tip3p.offxml, bace, cdk2, jacs_set, jnk1, mcl1, p38, ptp1b, thrombin, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
- name: Jennifer A. Clark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ summary: |
# REQUIRED: list of submission tags
tags: [rbfe, ff14SB, lipid17_merged, phosaa10, tip3p_HFE_multivalent, tip3p_standard, openff-3.0.0-alpha1b, jacs_set, thrombin, tyk2, nagl_openff-gnn-am1bcc-1.0.0.pt, benchmark, openfe]

# REQUIRED: calculation type (asfe, rbfe, etc.)
calculation_type: rbfe

# REQUIRED: list of contributing authors (name, affiliation; ORCID optional)
authors:
- name: Jennifer A. Clark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,12 @@
[
"jacs_set",
"bace",
"AlchemicalNetwork-58ef1baba714145eaddb8f81abf609ce-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_bace",
"AlchemicalNetwork-your-key",
],
[
"jacs_set",
"cdk2",
"AlchemicalNetwork-8b3e6b25fe046924998a1f520c798b19-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_cdk2",
],
[
"jacs_set",
"jnk1",
"AlchemicalNetwork-6cea205bc124349b8add8824e2060147-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_jnk1",
],
[
"jacs_set",
"mcl1",
"AlchemicalNetwork-ee5422ba932ced782b51da9bb9eb24ff-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_mcl1",
],
[
"jacs_set",
"p38",
"AlchemicalNetwork-c613a533bdaa47f92e9a1cf4d58fe6dd-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_p38",
],
[
"jacs_set",
"ptp1b",
"AlchemicalNetwork-3885e858e4b36849e110edbebe348ae2-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_ptp1b",
],
[
"jacs_set",
"thrombin",
"AlchemicalNetwork-7fcf1d4cb0a6af702747de83fc23af69-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_thrombin",
],
[
"jacs_set",
"tyk2",
"AlchemicalNetwork-51caad3a5d3daea240406eb23fa6dad6-openff-openff_3_0_0_alpha1b_opc3-rbfe_pontibus_jacs_set_tyk2",
"AlchemicalNetwork-your-key",
],
)
OUTPUT_DIR = "output"
Expand All @@ -71,7 +41,7 @@
"For scripts to generate this network: "
"github.com/openforcefield/alchemical-benchmark-resources/submissions/2026_07_15_openff-3.0.0-alpha1b_opc3/alchemiscale_submission.ipynb"
)
TAGS = "rbfe,benchmark,openfe"
TAGS = ""
SMALL_MOL_FF = "openff-3.0.0-alpha1b"
WATER_MODEL = "opc3.offxml"
OPENFE_VER = "1.8.0"
Expand Down
62 changes: 62 additions & 0 deletions openfe_benchmarks/scripts/_no_test_example_plot_asfe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Plot ASFEs, only for cinnabar >= 0.6.1, which is not compatible with current env"""

import pathlib
import json
import bz2

from gufe.tokenization import JSON_HANDLER
from cinnabar import plotting

from openfe_benchmarks.scripts._results_utils import build_femap_from_absolute_results

RESULTS_FILE = "../results/2026-08-06-openff-2.3.0-solvation_set_freesolv/computational_results.json.bz2"
OUTPUT_DIR = "outputs"


def _load_results(results_file: str) -> dict:
results_path = pathlib.Path(results_file)

if not results_path.exists():
raise FileNotFoundError(f"Could not find results file: {results_path}")

open_func = bz2.open if "bz2" in results_file else open

with open_func(results_path, "rt") as handle:
return json.load(handle, cls=JSON_HANDLER.decoder)


def main():
"""
An example script which can load the calculated DG values from ASFE calculations and plot vs experimental solvation data.

This script creates plots comparing the computed absolute solvation free energies (DG)
to experimental values for each benchmark system.
"""

# load the results file, whether compressed or not
results = _load_results(RESULTS_FILE)
if "dg" not in results:
raise ValueError(
f"Results file {RESULTS_FILE} does not contain 'dg' values, cannot plot"
)

# build FEMaps and load with experimental data
femaps_by_system = build_femap_from_absolute_results(results=results["dg"])

output_dir = pathlib.Path(OUTPUT_DIR)
output_dir.mkdir(parents=True, exist_ok=True)

# for each system plot the ASFE results compared to experimental data
for (system_group, system_name), femap in femaps_by_system.items():
plotting.plot_DGs(
femap,
source="Computational",
title=f"{system_group}-{system_name}",
figsize=5,
scatter_kwargs={"s": 20, "marker": "o"},
filename=(output_dir / f"{system_group}_{system_name}_DG.png").as_posix(),
)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
1. Pull alchemical network from Alchemiscale
2. Generate computational results
3. Generate submission metadata

Also works for ASFEs
"""

import logging
Expand Down Expand Up @@ -32,7 +34,7 @@
" and provide an indication of the variability in results. For scripts to generate this network: "
"github.com/openforcefield/alchemical-benchmark-resources/submissions/2026_03_17_openff-2.3.0_jacs_tyk2/alchemiscale_submission.ipynb"
)
TAGS = "rbfe,benchmark,openfe"
TAGS = ""
OPENFE_VER = "1.8.0"
OPENMM_VER = "8.2.0"
OFFTOOL_VER = "0.18"
Expand Down
87 changes: 87 additions & 0 deletions openfe_benchmarks/scripts/_results_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,90 @@ def build_femap_from_relative_results(

femaps_by_system_key[system_key] = femap
return femaps_by_system_key


def build_femap_from_absolute_results(
results: list[dict],
) -> dict[tuple[str, str], FEMap]:
"""
Build FEMaps for each of the unique combinations of system_group and system_name in the absolute solvation results
and add experimental solvation free energy data.

Parameters
----------
results: list[dict]
A list of absolute solvation free energy estimates which should include at least the following entries:
- solute: str
- system_group: str
- system_name: str
- dg: Quantity
- dg_uncertainty: Quantity

Returns
-------
dict[tuple[str, str], FEMap]
A dictionary mapping each unique combination of system_group and system_name to an FEMap with calculated
and experimental solvation free energy data.
"""
# get the unique combinations of system_group and system_name
results_by_system_key = defaultdict(list)
for result in results:
key = (result["system_group"], result["system_name"])
results_by_system_key[key].append(result)

femaps_by_system_key = {}
for system_key, system_results in results_by_system_key.items():
system_group, system_name = system_key
benchmark_data = get_benchmark_data_system(system_group, system_name)

# Check if all solutes have valid dg_uncertainty (not NaN)
solutes_no_uncertainty = [
result["solute"]
for result in system_results
if np.isnan(
result["dg_uncertainty"].magnitude
if "dg" in result
else result["estimate_error"].magnitude
)
]
if solutes_no_uncertainty:
raise ValueError(
f"Not all solutes have dg_uncertainty for {system_group} {system_name}: {solutes_no_uncertainty}"
)
Comment on lines +149 to +152

femap = FEMap()
for result in system_results:
value_key = "dg" if "dg" in result else "estimate"
err_key = "dg_uncertainty" if value_key == "dg" else "estimate_error"
label = f"{result['solute']},{result['solvent']}"
femap.add_absolute_calculation(
label=label,
value=result[value_key],
uncertainty=result[err_key],
source="Computational",
)

# add experimental solvation data for each of the solutes in the results
experimental_file = benchmark_data.reference_data[
"experimental_solvation_free_energy_data"
]
experimental_data = json.load(open(experimental_file), cls=JSON_HANDLER.decoder)
n_experimental_points = 0
for result in system_results:
label = f"{result['solute']},{result['solvent']}"
exp_data = experimental_data.get(label, None)
if exp_data is not None:
femap.add_experimental_measurement(
label=label,
value=exp_data["dg"],
uncertainty=exp_data.get(
"uncertainty", 0 * unit.kilocalories_per_mole
),
)
n_experimental_points += 1
if n_experimental_points == 0:
raise ValueError("No experimental data points were found")

femaps_by_system_key[system_key] = femap

return femaps_by_system_key
Loading
Loading