CADDForge Docking Plugin
Install this plugin with python -m pip install caddforge-docking. It depends directly
on caddforge-core>=0.21.0; Python imports and CLI commands still use caddforge.
For the complete public toolbox, including user-facing extras, install
python -m pip install caddforge. When migrating an existing environment, uninstall
the former caddforge core distribution before installing renamed core and updated plugins.
caddforge-docking provides docking workflows as plugins for the CADDForge framework.
Optional GUI dependencies
The core docking workflows can be installed without GUI dependencies.
If you want to use the Docking GUI extension, install the optional GUI extra:
pip install "caddforge-docking[gui]"
GUI tip for large shared inputs:
- In file inputs, choose
Use server pathwhen the backend host can access the same filesystem path directly (for example shared/mnt/...data or Slurm env packs). This skips upload/copy and avoids long submit times for large files.
Implemented Tools
Tool: unidock
What it does
The unidock tool runs GPU-accelerated molecular docking with Uni-Dock through the standard CADDForge workflow/job interface. It supports:
- receptor input as
.pdbqt, or.pdbwith automatic receptor preparation - docking one ligand, an index of ligands, or SDF input
- iterative batch processing for multi-structure SDF input (
batch_size) - automatic pocket center detection from a reference ligand (
.pdb,.pdbqt,.sdf) - standardized CADDForge outputs (
results.json,best_scores.csv,result_record.json)
External dependencies
These tools are required and are not installed automatically by this Python package:
unidock(Uni-Dock CLI): https://github.com/dptech-corp/Uni-Dock
Notes:
- If receptor input is
.pdb, the workflow also callsunidocktools proteinprepto create.pdbqt.
CLI usage
caddforge run docking unidock --config unidock.yaml
Python API usage
from caddforge.core.execution import load_result_for_job, submit_workflow
from caddforge.plugins import get_tool
spec = get_tool("docking", "unidock")
cfg = spec.config_cls(
receptor_path="protein.pdbqt",
ligand_index_path="ligands.index",
center_x=-19.18838,
center_y=1.76425,
center_z=9.23822,
size_x=20.0,
size_y=20.0,
size_z=20.0,
search_mode="balance",
backend="local", # or "slurm"
)
workflow = spec.workflow_cls(cfg)
job = submit_workflow(workflow, cfg, backend_name=cfg.backend)
result = load_result_for_job(job)
if result is not None:
print(result.status.value, result.metrics)
Example config
receptor_path: protein.pdbqt
ligand_index_path: ligands.index
center_x: -19.18838
center_y: 1.76425
center_z: 9.23822
size_x: 20
size_y: 20
size_z: 20
search_mode: fast
Tool-specific config options
Only one ligand source must be set: ligand_path or ligand_index_path or ligand_multisdf_path.
Required / primary inputs
receptor_path(Path): Receptor file (.pdbor.pdbqt).ligand_path(Path | None): Single ligand input (.pdbqtor.sdf).ligand_index_path(Path | None): Path to ligand index file (text file with one absolute or relative ligand file path per line; supported ligand files are.pdbqtor single-structure.sdf).ligand_multisdf_path(Path | None): Multi-structure SDF ligand input (recommended for batch processing).
Ligand index file example (ligands.index):
/data/ligands/ligand_0001.sdf
/data/ligands/ligand_0002.sdf
/data/ligands/ligand_0003.sdf
Optional receptor / pocket inputs
flex_path(Path | None): Optional flexible sidechain file (.pdbor.pdbqt).reference_ligand_path(Path | None): Optional ligand to infer docking center from center of geometry (.pdb,.pdbqt,.sdf).center_x(float | None): Box center X.center_y(float | None): Box center Y.center_z(float | None): Box center Z.size_x(float, default20.0): Box size X.size_y(float, default20.0): Box size Y.size_z(float, default20.0): Box size Z.
Notes:
- If
center_x/y/zare not all provided,reference_ligand_pathis required. proteinprep_center_x/y/zandproteinprep_size_x/y/zexist in the current config model for compatibility, but are not used with the current minimalunidocktools proteinprep -r ... -o ...interface.- Ligand input intent:
- Use
ligand_pathfor a single ligand file (.pdbqtor.sdf). - Use
ligand_multisdf_pathfor multi-structure SDF files. - Use
ligand_index_pathwhen you already have ligands split into one-file-per-ligand and want explicit file-level control.
- Use
Batch handling options
batch_size(int | None): When set withligand_multisdf_path, process multi-structure SDF in iterative batches.run_ligandprep(bool, defaultfalse): If enabled, rununidocktools ligandprepbefore docking and use prepared ligands as UniDock input.ligandprep_batch_size(int, default10000): Batch size passed tounidocktools ligandprep -bswhen ligand preparation is enabled.ligandprep_timeout_seconds(int, default3600): Maximum allowed runtime for oneunidocktools ligandprepcall; timed-out prep is terminated and the job fails fast.max_pending_postprocess_batches(int, default2): Upper bound of completed batches waiting for async post-processing; controls overlap vs temporary disk usage.
Batch behavior:
- Split each batch into single-structure SDF files.
- Create an index for that batch only.
- Run UniDock for that batch.
- Remove temporary files for that batch (unless
keep_temporary_files: true).
Ligand preparation behavior (run_ligandprep: true):
- CADDForge runs
unidocktools ligandprepautomatically and docks prepared SDF outputs. - If the installed
unidocktoolsversion does not supportligandprep, the job fails fast with a clear error. - If one
ligandprepcall exceedsligandprep_timeout_seconds, CADDForge terminates it and fails fast (prevents indefinite hangs).
UniDock runtime/scoring options
scoring("ad4" | "vina" | "vinardo", default"vina"): Scoring function.search_mode("fast" | "balance" | "detail", default"balance"): UniDock search mode.cpu(int, default0): CPU count passed to UniDock.seed(int, default0): Random seed.exhaustiveness(int, default384): Search exhaustiveness.max_evals(int, default0): Max evaluations.num_modes(int, default9): Max number of output modes.min_rmsd(float, default1.0): Minimum RMSD between output poses.energy_range(float, default3.0): Maximum energy range from best mode.spacing(float, default0.375): Grid spacing.verbosity(int, default1): UniDock verbosity (0/1/2).max_step(int, default0): Max steps per MC run.refine_step(int, default3): Refinement steps.max_gpu_memory(int, default0): GPU memory limit (0 = auto/all available).
Output / execution extras
output_dir_name(str, default"docked_out"): Pose output directory name underresults/.prepared_receptor_filename(str, default"protein_prepared.pdbqt"): Filename for generated prepared receptor.keep_temporary_files(bool, defaultfalse): Keep temporary split/index files.extra_unidock_args(list[str], default[]): Extra raw CLI args appended tounidock(for non-core options only; core options like--max_gpu_memory,--search_mode, etc. should be set via dedicated config fields).
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/<output_dir_name>/: UniDock pose files (<ligand>_out.sdf, etc.)results/results.json: summary payload with per-ligand best scoreresults/best_scores.csv: per-ligand best score tableresults/result_record.json: standardized CADDForgeResultstdout.log/stderr.log: command logs
Tool: idockya
What it does
The idockya tool runs docking with OpenChemLib iDockYa through pyocl, supplied
by pyocl-idor>=0.8.3. Java 21 or newer is required; set JAVA_HOME to that runtime.
It supports:
- receptor and native ligand input from standard structure files
- ligand input as one file (
ligand_path) or many files (ligand_paths) - multi-structure SDF processing from
ligand_path(record-by-record streaming) - optional parallel ligand docking with per-worker
DockingEnginereuse - standardized CADDForge outputs (
results.json,best_scores.csv,result_record.json)
Supported input formats:
.sdf,.mol,.mol2,.pdb,.pdbqt,.smi,.smiles
Notes:
- For receptor/native ligand SDF input, the first SDF record is used.
- For ligand SDF input (
ligand_path), all records are docked.
CLI usage
caddforge run docking idockya --config idockya.yaml
Python API usage
from caddforge.core.execution import load_result_for_job, submit_workflow
from caddforge.plugins import get_tool
spec = get_tool("docking", "idockya")
cfg = spec.config_cls(
receptor_path="receptor.sdf",
native_ligand_path="native_ligand.sdf",
ligand_path="ligands.sdf", # can be multi-structure SDF
output_format="sdf",
num_workers=0, # auto (uses SLURM_CPUS_PER_TASK if set)
backend="local", # or "slurm"
)
workflow = spec.workflow_cls(cfg)
job = submit_workflow(workflow, cfg, backend_name=cfg.backend)
result = load_result_for_job(job)
if result is not None:
print(result.status.value, result.metrics)
Example config
receptor_path: receptor.sdf
native_ligand_path: native_ligand.sdf
ligand_path: ligands.sdf
output_format: sdf
output_dir_name: docked_out
num_workers: 0
max_inflight_tasks: 0
Tool-specific config options
Required / primary inputs
receptor_path(Path): Receptor structure input.native_ligand_path(Path): Native/reference ligand structure input.ligand_path(Path | None): Single ligand file path (can be multi-record SDF).ligand_paths(list[Path]): Multiple ligand file paths.
Only one ligand source must be set:
ligand_pathorligand_paths
Output / execution options
output_dir_name(str, defaultdocked_out): Pose output directory underresults/.output_format("sdf" | "pdb" | "mol2", defaultsdf): Primary pose output format.grid_dimension(float | None): Optional iDockYa grid dimension override.
Parallelism options
num_workers(int, default0): Worker processes for ligand docking.0=> auto-detect (SLURM_CPUS_PER_TASKif available, else local CPU count).max_inflight_tasks(int, default0): Max queued/running ligand tasks not yet collected.0=>4 * num_workers.
Performance behavior:
- In parallel mode, each worker initializes one
DockingEngineand reuses it. - Ligand input is streamed; no full multi-structure SDF is loaded into RAM.
- Scores are written incrementally to CSV to keep memory usage bounded.
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/<output_dir_name>/: per-ligand docked poses (primarypose_fileusesoutput_format; SDF is also produced internally for compatibility)results/results.json: summary payload (ligands_total,best_score_overall,best_scores_csv, andligands_preview)results/best_scores.csv: per-ligand score tableresults/result_record.json: standardized CADDForgeResultstdout.log/stderr.log: run logs
Tool: gnina
What it does
The gnina tool runs docking with the gnina executable through the standard CADDForge workflow/job interface. It supports:
- receptor input as
.pdbqtor.pdb - ligand input as one file or a list of files
- SDF input with automatic per-record staging so each ligand gets a dedicated output pose file
- manual docking boxes or gnina autoboxing
- flexible docking through
--flex,--flexres, or--flexdist - standardized CADDForge outputs (
results.json,best_scores.csv,result_record.json)
External dependencies
These tools are required and are not installed automatically by this Python package:
gninaexecutable: https://github.com/gnina/gnina
CLI usage
caddforge run docking gnina --config gnina.yaml
Python API usage
from caddforge.core.execution import load_result_for_job, submit_workflow
from caddforge.plugins import get_tool
spec = get_tool("docking", "gnina")
cfg = spec.config_cls(
receptor_path="protein.pdb",
ligand_path="ligands.sdf",
autobox_ligand_path="reference_ligand.sdf",
flexres=["A:194", "A:244", "A:252"],
no_gpu=True,
backend="local", # or "slurm"
)
workflow = spec.workflow_cls(cfg)
job = submit_workflow(workflow, cfg, backend_name=cfg.backend)
result = load_result_for_job(job)
if result is not None:
print(result.status.value, result.metrics)
Example config
receptor_path: protein.pdb
ligand_path: ligands.sdf
autobox_ligand_path: reference_ligand.sdf
flexres:
- A:194
- A:244
- A:252
scoring: dkoes_fast
cnn_scoring: rescore
no_gpu: true
Tool-specific config options
Required / primary inputs
receptor_path(Path): Rigid receptor input (.pdbqtor.pdb). Flexible complex generation requires.pdbso receptor hydrogen/protonation states can be preserved from the input.ligand_path(Path | None): One ligand file..sdfinputs may contain multiple records.ligand_paths(list[Path]): Alternative toligand_pathfor docking multiple ligand files.
Only one ligand source must be set:
ligand_pathorligand_paths
Supported ligand/autobox formats:
.sdf,.mol2,.pdbqt,.pdb
Search space options
Choose exactly one search-space mode:
Manual box:
center_x,center_y,center_zsize_x,size_y,size_z
Autobox:
autobox_ligand_pathautobox_add(float | None)autobox_extend(int | None)
Flexible docking options
flex_path(Path | None): Prebuilt flexible side-chain PDBQT passed via--flex.flexres(list[str]): Flexible residues, rendered as comma-separatedchain:resid.flexdist_ligand_path(Path | None) andflexdist(float | None): Define flexible residues by distance from a ligand.flex_limit(int | None): Hard limit for flexible residues.flex_max(int | None): Keep at most the closestflex_maxflexible residues.
Notes:
flex_pathandflexresare mutually exclusive.- If flexibility is enabled and
write_flex_receptor_output: true, the workflow writes per-ligand flexible receptor outputs underresults/flex_receptor_out/. - If flexibility,
write_flex_receptor_output, andwrite_flexible_complexesare enabled, the workflow also writes one full protein-ligand complex PDB, one protein-only PDB, and one ligand-only SDF per generated pose. Protein and ligand hydrogen presence is copied from the input receptor and ligand records; missing input hydrogens are not invented. Ligand bond orders and formal charges are copied from the input ligand; PDB complexes emit ligand bond orders asCONECTrecords, whose interpretation depends on the downstream PDB reader.
Common gnina runtime/scoring options
scoring(dkoes_fast,ad4_scoring,dkoes_scoring,dkoes_scoring_old,vina,vinardo): if omitted, CADDForge does not pass--scoringand gnina uses its own default.cnn_scoring(none,rescore,refinement,metrorescore,metrorefine,all): if omitted, CADDForge does not pass--cnn_scoringand gnina uses its own default.cnn(str | None): Built-in CNN model name.cnn_model(Path | None): External Torch model file.score_only,local_only,minimize,randomize_only(bool)exhaustiveness(int | None): if omitted, CADDForge does not pass--exhaustiveness.num_modes(int | None): if omitted, CADDForge does not pass--num_modes.min_rmsd_filter(float | None): if omitted, CADDForge does not pass--min_rmsd_filter.cpu(int | None): Explicit CPU count. If omitted, gnina auto-detects.seed(int | None)add_hydrogens(on | off | None): if omitted, CADDForge does not pass--addH.device(int | None)no_gpu(bool | None): if true, CADDForge passes--no_gpu; if omitted, the flag is not passed.pose_sort_order(CNNscore | CNNaffinity | Energy | None)
Output / execution extras
gnina_executable(str, defaultgnina): Executable name or full path.output_dir_name(str, defaultdocked_out)flex_output_dir_name(str, defaultflex_receptor_out)flexible_complex_output_dir_name(str, defaultflexible_complexes)flexible_complex_ligand_resname(str, defaultLIG)gnina_log_dir_name(str, defaultgnina_logs)output_format(sdf | pdbqt, defaultsdf)write_flex_receptor_output(bool, defaulttrue)write_flexible_complexes(bool, defaulttrue): Requires flexible docking,write_flex_receptor_output: true,output_format: sdf, and a PDB receptor. Set tofalseto keep only gnina's raw pose and flex output files.keep_temporary_files(bool, defaultfalse): On Slurm, temporary staged ligand files are created in$SLURM_TMPDIR; if this istrue, they are copied back torun_dir/staged_inputsbefore cleanup.log_sync_interval_seconds(int, default30): Interval for resiliently copying live stdout, stderr, and the active per-ligand gnina log from Slurm scratch to the job directory.result_sync_interval_seconds(int, default5): Retry interval for asynchronously copying completed ligand artifacts from Slurm scratch to the job directory.extra_gnina_args(list[str], default[]): Additional raw gnina CLI args for less-common options not modeled directly.
On Slurm, gnina runs inside $SLURM_TMPDIR/caddforge_gnina_<job-id>. Static inputs are staged once, completed ligand artifacts are copied back asynchronously, and transient copy failures remain queued while docking continues. After the last ligand, pending files receive one final copy attempt; the job fails rather than publishing an incomplete completed result if files still cannot be persisted.
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/<output_dir_name>/: Per-ligand docked posesresults/<flex_output_dir_name>/: Flexible receptor outputs when enabledresults/<flexible_complex_output_dir_name>/: Per-pose complex PDBs, protein-only PDBs, and ligand-only SDFs when flexible complex generation is enabledresults/flexible_complexes_manifest.csv: Flexible complex artifact provenance and hydrogen countsresults/<gnina_log_dir_name>/: Per-ligand gnina log filesresults/results.json: Summary payload with ligand counts and best scoreresults/best_scores.csv: Per-ligand best score tableresults/result_record.json: Standardized CADDForgeResultstdout.log/stderr.log: Workflow command logs
Pipeline output aliases:
scores:best_scores.csvposes: docked pose output directoryflexible_complexes_manifest: flexible artifact manifest CSV, when generatedflexible_complexes: per-pose complex PDB path collection, when generatedflexible_proteins: per-pose protein-only PDB path collection, when generatedflexible_ligand_poses: per-pose ligand-only SDF path collection, when generated
Compressed inputs
Declared receptor, ligand, and reference inputs may use a trailing .gz, for example
ligands.sdf.gz; CADDForge supplies the docking tool with a plain file in runtime scratch. UniDock
ligand indexes may also reference .sdf.gz entries.
Continuous integration and releases
.github/workflows/release.yml builds a wheel and source archive, validates
metadata, and tests the installed wheel on Linux with Python 3.10 and 3.12.
The lightweight test selection is recorded in scripts/ci_tests.json;
external scientific engines are validated separately. CI installs the same
wheel with its [gui] extra so GUI regression tests use the declared GUI
dependencies, including caddforge-gui.
Pushing a matching v* release tag publishes the tested artifacts to PyPI.
Branch pushes, pull requests and manual runs never publish. Configure a
PyPI Trusted Publisher for the idorsia repository, release.yml workflow
and pypi environment before pushing release tags. Runtime CADDForge
dependencies must already be available publicly; publish core and GUI before
FEP/docking, and publish docking/descriptors before MD.
Metadata
Release files for caddforge-docking 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| caddforge_docking-0.7.0.tar.gz | 101.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| caddforge_docking-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 198.8 kB
Release files / caddforge_docking-0.7.0.tar.gz
| Download URL | caddforge_docking-0.7.0.tar.gz |
|---|---|
| Size | 101.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
810dce9a767b7c9b9c7766f12ee0e7e48347a9be26160b0eff0ba9abdb493954
|
|
BLAKE2b-256 checksum How to use checksums |
39d9c6e8106765728ecbd094d600be5e6d9f858198e91ead495b680f79867c82
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / caddforge_docking-0.7.0-py3-none-any.whl
| Download URL | caddforge_docking-0.7.0-py3-none-any.whl |
|---|---|
| Size | 97.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
beb5bedad97da7e3a003d5e7b918ed2b99964e6f41a0028f6aa047dc4cc2b712
|
|
BLAKE2b-256 checksum How to use checksums |
f50fba6dd84ebd9b458cd15f7acc1820b9c7c5f2cec87201a9e6fe23a40e56c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log