Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0187a5c
Create freesolv and mnsol subsets
Mar 26, 2026
c7ebfac
Update subset
Mar 26, 2026
2681287
Update preparation details
Mar 26, 2026
518b9ea
Add subset detection
Mar 26, 2026
df92c60
Merge branch 'main' into add_solvation_subsets
Mar 26, 2026
aa2af3c
Add use of subsets into plan_asfe
Mar 26, 2026
37de099
Update exp*freesolv*.json with 3D based inchikeys
Mar 27, 2026
85b7bf8
Update contributing expectations
Mar 27, 2026
78bd782
Apply suggestions from code review
jaclark5 Mar 27, 2026
8d35454
Update path in defeine*subsets.py
Mar 27, 2026
36b4f98
Update subsets
Mar 31, 2026
7340aa2
Update subsets using UMAP swapping
Apr 2, 2026
dca6c9f
Update preparation details solvation
Apr 8, 2026
2a9ed59
Update subsets
Apr 8, 2026
4fb1306
Update _example_plan_asfe.py with subset
Apr 8, 2026
c12a05e
Update toolkit registry for _example_plan_asfe.py
Apr 14, 2026
305090c
Canonicalize MNSol smiles and names
Apr 22, 2026
ec48589
Update generate mnsol to exclude undefined stereochemistry and update…
Apr 22, 2026
5423852
Update run instructions
Apr 22, 2026
8d60d2b
reformat mnsol preparation details
Apr 22, 2026
3da82de
Update explanations
Apr 22, 2026
a847c5a
Update gitignore
May 20, 2026
cf307bc
Update subset sampling
May 21, 2026
a639204
Update docs to correctly reflect missing ChemEnv
Jun 3, 2026
8b7b228
Merge branch 'main' into add_solvation_subsets
hannahbaumann Jun 11, 2026
ec15ab5
Update subsets to remove duplicate exp data
Jun 16, 2026
69cb77d
Fix SMILES
Jun 16, 2026
14c15c0
Merge branch 'main' into add_solvation_subsets
jaclark5 Jun 16, 2026
d543238
Update SDF files
Jun 17, 2026
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
8 changes: 7 additions & 1 deletion openfe_benchmarks/data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ When adding new benchmark systems:
4. Generate ligand network mapping files, `*network*.json` (JSON format)
5. (If necessary) Add new charge types to `PARTIAL_CHARGE_TYPES` in `data/__init__.py`
6. Generate `ligands_<charge_type>.sdf` files with ``openfe_benchmarks/data/data_generation/charge_molecules.py``
6. (If present) Generate `cofactors_<charge_type>.sdf` files with ``openfe_benchmarks/data/data_generation/charge_molecules.py``
6. (If present) Generate `cofactors_<charge_type>.sdf` files with ``openfe_benchmarks/data/data_generation/charge_molecules.py``
7. Add `experimental_*.json` as appropriate for the calculation type. Each transformation should have:
- a name corresponding to the alchemical network edge
- dg (and uncertainty is available) with "magnitude, "unit", "pint_unit_registry", ":is_custom:".
- reference: DOI or the like
- solute_*/solvent_* where * is name, smiles, inchikey, and inchi. Note that inchi* much be generated from the 3D coordinates in the ligands.sdf. See scripts in the data_generation directory for examples (For SFE data only).
- canonical_smiles and inchikey. Note that inchi* much be generated from the 3D coordinates in the ligands.sdf. See scripts in the data_generation directory for examples (For BFE data only).
20 changes: 17 additions & 3 deletions openfe_benchmarks/data/_benchmark_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ class BenchmarkData:
reference_data : dict[str, Path] | None
Dictionary of available reference data files where the key is the filename 'experimental*data.json',
and the value is a Path to a reference data file.
subset_data : dict[str, Path] | None
Dictionary of available subset files where the key is the filename stem 'subset*.json',
and the value is a Path to a subset JSON file defining a named subset of ligands.
details : str
Information available in the preparation_details.md file
"""
Expand All @@ -225,6 +228,7 @@ class BenchmarkData:
cofactors: dict[str, Path] | None
ligand_networks: dict[str, Path] | None
reference_data: dict[str, Path] | None
subset_data: dict[str, Path] | None
details: str

def __repr__(self):
Expand All @@ -234,8 +238,9 @@ def __repr__(self):
f"protein={self.protein.name if self.protein else 'None'}, "
f"ligands={list(self.ligands.keys())}, "
f"cofactors={list(self.cofactors.keys()) if self.cofactors is not None else 'None'}, "
f"ligand_network={list(self.ligand_networks.keys()) if self.ligand_networks is not None else 'None'}"
f"reference_data={list(self.reference_data.keys()) if self.reference_data is not None else 'None'})"
f"ligand_network={list(self.ligand_networks.keys()) if self.ligand_networks is not None else 'None'}, "
f"reference_data={list(self.reference_data.keys()) if self.reference_data is not None else 'None'}, "
f"subset_data={list(self.subset_data.keys()) if self.subset_data is not None else 'None'})"
)


Expand Down Expand Up @@ -269,6 +274,7 @@ def _validate_and_load_data_system(
cofactors = {}
ligand_networks = {}
reference_data = {}
subset_data = {}
details = None

# Track all files for validation
Expand Down Expand Up @@ -354,6 +360,13 @@ def _validate_and_load_data_system(
logger.debug(f"Found reference data: {filename}")
continue

# check for subset data file (subset*.json)
if filename.startswith("subset") and filename.endswith(".json"):
subset_data[file_path.stem] = file_path
categorized_files.add(file_path)
logger.debug(f"Found subset: {filename}")
continue

# Check for uncategorized files
uncategorized = set(all_files) - categorized_files
for file_path in uncategorized:
Expand Down Expand Up @@ -381,7 +394,7 @@ def _validate_and_load_data_system(
raise ValueError(
f"Uncategorized JSON file '{filename}' found in system '{system_name}' "
f"in benchmark set '{benchmark_set}'. Expected format: "
f"'*network*.json' for ligand networks."
f"'*network*.json' for ligand networks, 'experimental*data.json', or 'subset*.json'."
)

raise ValueError(
Expand Down Expand Up @@ -425,6 +438,7 @@ def _validate_and_load_data_system(
cofactors=cofactors or None,
ligand_networks=ligand_networks or None,
reference_data=reference_data or None,
subset_data=subset_data or None,
details=details,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
Done by Joshua Horton on 2026-02-12
Done by Joshua Horton on 2026-02-12 (subset regenerated 2026-04-02)

All ligands extracted from the FreeSolv database version https://github.com/MobleyLab/FreeSolv/releases/tag/v0.52



## Notes
## Partial Charges

The reference data was generated using the [generate_freesolv_exp_data.py](../../../data_generation/generate_freesolv_exp_data.py) script using the [conda-lock_linux-64.yml](../../../data_generation/conda-lock_linux-64.yml) environment.
Charges were generated using the [charge_freesolv.py](../../../data_generation/charge_freesolv.py) script using the [conda-lock_linux-64.yml](../../../data_generation/conda-lock_linux-64.yml) environment.
Some ligands could not be charged with all methods, the following lists the ligands that could not be charged with each method:

- am1bccelf10_oe:
- mobley_7176248
Charging failures:
- `am1bccelf10_oe`: mobley_7176248
- `am1bcc_at`: mobley_9741965

## Subsets

Regenerate all subsets: run `python define_freesolv_mnsol_openff_subsets.py` in `data_generation/`.

### subset_openff_filtered.json
588 neutral solutes retained from the full FreeSolv v0.52 database, all measured in water. Excluded 54 entries: 47 with elements outside the OpenFF chemical space, 5 with disqualifying SMIRKS patterns, and 2 with undefined stereochemistry. Each entry is a unique solute with a single experimental aqueous hydration free energy measurement.

- am1bcc_at:
- mobley_9741965
### subset_openff_small.json
188 unique solutes drawn from `subset_openff_filtered`. Selection seeded the 188 solutes present in both the FreeSolv and MNSol filtered pools (by OpenFF SMILES isomorphism).
Loading
Loading