Skip to content

FEP Plugin

Package: caddforge-fep

Public source tag

This page describes caddforge-fep 0.7.0, tagged as v0.7.0. Published on PyPI; see the version matrix.

The FEP plugin provides OpenFE-based absolute and relative free-energy workflows.

Install optional GUI support with:

python -m pip install "caddforge-fep[gui]"

Requirements and example status

The example library provides downloadable configuration templates for every workflow on this page, plus a shared Python runner. File paths refer to inputs you must prepare; these are not bundled research datasets. Schema validation does not establish scientific validity or engine availability. See the version matrix for release tags and publication status.

openfe-abfe

Prepares and optionally runs OpenFE absolute binding free energy calculations.

The default is one independent protocol repeat per leg using CUDA. Protocol repeats are distinct from the lambda replicas within each leg.

Settings group NVT equilibration Equilibration Production Lambda replicas Analysis interval
Complex pre-equilibration 0.10 ns 0.2 ns 0.5 ns — —
Complex alchemical simulation — 0.2 ns 2.0 ns 68 10 ps
Solvent pre-equilibration 0.05 ns 0.1 ns 0.5 ns — —
Solvent alchemical simulation — 0.1 ns 1 ns 60 10 ps

The complex and solvent lambda schedules contain 68 and 60 entries respectively; solvent restraints remain zero throughout. The full schedules are shown below and included in the downloadable configuration.

Defaults apply consistently through the CLI, Python API, and GUI. Omitted, empty, or partial settings_overrides dictionaries retain unspecified defaults; explicit entries replace individual values. An explicit settings_overrides.protocol_repeats entry takes precedence over top-level protocol_repeats. Explicit top-level protocol_repeats: null keeps OpenFE's repeat default. When changing lambda schedules, update all three arrays and n_replicas together for the affected leg.

CLI:

caddforge run fep openfe-abfe --config abfe.yaml

YAML:

ligand_sdf: data/ligand_neutral.sdf
protein_pdb: data/protein_fixed.pdb
ligand_index: 0
fix_protein_pdb: false
partial_charge_method: am1bcc
off_toolkit_backend: ambertools
host_min_distance_nm: 0.5
host_max_distance_nm: 1.5
protocol_repeats: 1
settings_overrides:
  complex_simulation_settings.real_time_analysis_interval: 10 picosecond
  complex_equil_simulation_settings.equilibration_length: 0.2 nanosecond
  complex_equil_simulation_settings.production_length: 0.5 nanosecond
  complex_equil_simulation_settings.equilibration_length_nvt: 0.10 nanosecond
  complex_simulation_settings.equilibration_length: 0.2 nanosecond
  complex_simulation_settings.production_length: 2.0 nanosecond
  complex_simulation_settings.n_replicas: 68
  solvent_equil_simulation_settings.equilibration_length: 0.1 nanosecond
  solvent_equil_simulation_settings.production_length: 0.5 nanosecond
  solvent_equil_simulation_settings.equilibration_length_nvt: 0.05 nanosecond
  solvent_simulation_settings.equilibration_length: 0.1 nanosecond
  solvent_simulation_settings.production_length: 1 nanosecond
  solvent_simulation_settings.real_time_analysis_interval: 10 picosecond
  solvent_simulation_settings.n_replicas: 60
  engine_settings.compute_platform: CUDA
  complex_lambda_settings.lambda_elec:
    [0, 0.05, 0.1, 0.14, 0.19, 0.24, 0.29, 0.33, 0.38, 0.43, 0.48, 0.52, 0.57, 0.62, 0.67, 0.71,
      0.76, 0.81, 0.86, 0.9, 0.95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  complex_lambda_settings.lambda_vdw:
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.06, 0.12, 0.18, 0.24,
      0.28, 0.32, 0.36, 0.4, 0.44, 0.48, 0.52, 0.56, 0.6, 0.62, 0.64, 0.66, 0.68, 0.69, 0.7, 0.71,
      0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8, 0.81, 0.82, 0.83, 0.83, 0.84, 0.85,
      0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.94, 0.96, 0.98, 1]
  complex_lambda_settings.lambda_restraints:
    [0, 0, 0, 0.01, 0.01, 0.02, 0.03, 0.04, 0.06, 0.07, 0.09, 0.11, 0.13, 0.16, 0.18, 0.21, 0.24,
      0.27, 0.3, 0.33, 0.37, 0.4, 0.44, 0.49, 0.53, 0.57, 0.62, 0.67, 0.72, 0.77, 0.83, 0.88,
      0.94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
      1, 1, 1, 1, 1, 1, 1]
  solvent_lambda_settings.lambda_elec:
    [0, 0.01, 0.02, 0.03, 0.04, 0.07, 0.09, 0.11, 0.13, 0.15, 0.17, 0.22, 0.26, 0.3, 0.35, 0.39,
      0.43, 0.48, 0.52, 0.57, 0.61, 0.65, 0.7, 0.74, 0.78, 0.83, 0.87, 0.91, 0.96, 1, 1, 1, 1,
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  solvent_lambda_settings.lambda_vdw:
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0.1, 0.18, 0.26, 0.32, 0.38, 0.42, 0.46, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71,
      0.74, 0.76, 0.78, 0.8, 0.81, 0.83, 0.84, 0.86, 0.88, 0.9, 0.92, 0.94, 0.96, 0.98, 1]
  solvent_lambda_settings.lambda_restraints:
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
run_quickrun: true
quickrun_extra_args: []

Python:

from caddforge.core.execution import load_result_for_job, submit_workflow
from caddforge.plugins import get_tool

spec = get_tool("fep", "openfe-abfe")
cfg = spec.config_cls(
    ligand_sdf="data/ligand_neutral.sdf",
    protein_pdb="data/protein_fixed.pdb",
    ligand_index=0,
    run_quickrun=True,
    backend="local",
)
workflow = spec.workflow_cls(cfg)
job = submit_workflow(
    workflow, cfg, backend_name=cfg.backend,
    input_ports=tuple(getattr(spec.plugin, "input_ports", ())),
)
result = load_result_for_job(job)
if result is not None:
    print(result.metrics)

Outputs to inspect: abfe_json/, results/openfe_results.json, results/openfe_stdout.log, results/result_record.json.

openfe-rbfe-septop

Plans, prepares, and optionally runs OpenFE SepTop RBFE campaigns.

CLI:

caddforge run fep openfe-rbfe-septop --config rbfe_septop.yaml

YAML:

operation_mode: run
ligand_sdf: data/ligands.sdf
ligand_sdfs: []
protein_pdb: data/protein.pdb
complexes: []
project_compound_ids:
  - proj_anchor_01
  - proj_anchor_02
export_network_bundle: true
reuse_completed_edges: true
partial_charge_method: am1bcc
off_toolkit_backend: ambertools
protocol_repeats: 3
settings_overrides:
  engine_settings.compute_platform: CUDA
compatibility_threshold: 0.45
project_assignment_threshold: 0.35
local_cluster_threshold: 0.55
max_clash_score: 0.35
diagnostic_cycle_edges_per_component: 1
run_quickrun: true
quickrun_extra_args: []

Python:

from caddforge.core.execution import load_result_for_job, submit_workflow
from caddforge.plugins import get_tool

spec = get_tool("fep", "openfe-rbfe-septop")
cfg = spec.config_cls(
    ligand_sdf="data/ligands.sdf",
    protein_pdb="data/protein.pdb",
    project_compound_ids=["proj_anchor_01", "proj_anchor_02"],
    operation_mode="run",
    protocol_repeats=3,
    backend="local",
)
workflow = spec.workflow_cls(cfg)
job = submit_workflow(
    workflow, cfg, backend_name=cfg.backend,
    input_ports=tuple(getattr(spec.plugin, "input_ports", ())),
)
result = load_result_for_job(job)
if result is not None:
    print(result.metrics)

Outputs to inspect: network/ligand_network.json, results/ligand_network_bundle.zip, results/transformations_manifest.json, results/edge_records/, results/result_record.json.

Compressed inputs

ABFE and RBFE ligand, protein, network, manifest, and bundle inputs accept transparent gzip where declared by the workflow, including paths nested in RBFE complex collections. Existing-network JSON and transformation manifests are read natively when required to preserve relative reference resolution; other wrappers are staged as plain runtime inputs.