CADDForge Descriptors Plugin
Install this plugin with python -m pip install caddforge-descriptors. 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-descriptors provides descriptor and clustering workflows as plugins for the CADDForge framework.
Implemented Tools
Tool: ani-psa
What it does
The ani-psa tool computes ANI-weighted 3D polar surface area values from one molecule or a batch of molecules. The workflow:
- accepts one SMILES, an inline SMILES list, or a SMILES file
- generates conformers with RDKit, optimizes them with MMFF, clusters them, and re-ranks them with TorchANI
- computes 3D PSA on the selected conformers and reports the Boltzmann-weighted average
- writes standardized CADDForge outputs plus per-molecule JSON/CSV summaries
External dependencies
No external command-line tools are required beyond the Python environment.
Runtime notes:
- TorchANI and PyTorch must be available in the environment.
- CUDA is optional; set
device: cudaordevice: cuda:0if you want GPU execution.
CLI usage
caddforge run descriptors ani-psa --config ani_psa.yaml
Python API usage
from cadd_descriptors import AniPsaConfig, AniPsaWorkflow
cfg = AniPsaConfig(
smiles="CC(=O)Oc1ccccc1C(=O)O",
top_n=25,
backend="local",
)
workflow = AniPsaWorkflow(cfg)
job = workflow.prepare_job()
result = workflow.run(job)
print(result.status.value, result.metrics)
Example config
smiles: "CCO"
num_confs: 100
top_n: 10
rmsd_cluster_thresh: 0.5
max_mmff_iters: 200
temperature: 298.15
model_name: ANI2x
device: cpu
Tool-specific config options
Only one input source must be set:
smilessmiles_listsmiles_file
Input options
smiles(str | None): Single SMILES string.smiles_list(list[str] | None): Inline batch of SMILES strings.smiles_file(Path | None): SMILES input file.smiles_column(str, defaultsmiles): Column to read from CSV/TSV input.
Conformer and ANI options
num_confs(int, default500): Number of conformers to generate.rmsd_cluster_thresh(float, default0.5): RMSD threshold for conformer clustering.max_mmff_iters(int, default200): MMFF optimization steps per conformer.top_n(int, default50): Number of ANI-ranked conformers kept for PSA averaging.temperature(float, default298.15): Boltzmann weighting temperature in Kelvin.model_name(str, defaultANI2x): TorchANI model name.device(str | None, defaultcpu): Torch device string.
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/results.json: per-molecule PSA summary payloadresults/results.csv: tabular per-molecule PSA summaryresults/result_record.json: standardized CADDForgeResultstdout.log: workflow log
Tool: phesa
What it does
The phesa tool computes OpenChemLib PheSA shape/pharmacophore similarities between one reference
molecule and one or more candidates. It supports:
- a reference molecule from SMILES, SDF, or an encoded PheSA text file
- candidate molecules from either SMILES strings or single-/multi-compound SDF files
- configurable maximum conformer count and pharmacophore point weight
- aligned SDF outputs for the reference and candidates
- pipeline outputs for scores and aligned candidate collections
External dependencies
PheSA imports pyocl, provided by the public pyocl-idor>=0.8.3 distribution.
The OpenChemLib runtime requires Java 21 or newer with JAVA_HOME configured.
CLI usage
caddforge run descriptors phesa --config phesa.yaml
Python API usage
from cadd_descriptors import PhesaConfig, PhesaWorkflow
cfg = PhesaConfig(
reference_smiles="CCO",
candidate_smiles=["CCCO", "CCCCO"],
max_confs=200,
pp_weight=0.5,
)
workflow = PhesaWorkflow(cfg)
job = workflow.prepare_job()
result = workflow.run(job)
print(result.status.value, result.metrics)
Example configs
reference_smiles: "CCO"
candidate_smiles:
- "CCCO"
- "CCCCO"
max_confs: 200
pp_weight: 0.5
reference_sdf: reference.sdf
candidate_sdf_files:
- candidates.sdf
- extra_candidate.sdf
max_confs: 200
pp_weight: 0.5
write_merged_aligned_candidates_sdf: true
reference_phesa_file: reference_phesa.txt
candidate_smiles:
- "CCCO"
- "CCCCO"
max_confs: 200
pp_weight: 0.5
Tool-specific config options
Exactly one reference source must be set:
reference_smilesreference_sdfreference_phesa_file
Exactly one candidate source must be set:
candidate_smilescandidate_sdf_files
candidate_sdf_files may contain single- or multi-compound SDF files. Each valid SDF molecule
record is scored as one candidate; record names are used as candidate IDs when present, otherwise
IDs fall back to the source file stem plus the record index.
PheSA options
max_confs(int, default200): Maximum number of conformers for generated PheSA descriptors.pp_weight(float, default0.5): Pharmacophore point weight.scores_csv_name(str, defaultscores.csv): Scores CSV filename underresults/.aligned_dir_name(str, defaultaligned): Aligned SDF output directory underresults/.write_merged_aligned_candidates_sdf(bool, defaultfalse): Write one SDF containing all successfully aligned candidate molecules.merged_aligned_candidates_sdf_name(str, defaultaligned_candidates.sdf): Filename for the merged aligned candidate SDF under the aligned output directory.
When reference_smiles is used, both the reference and candidates use OpenChemLib's generated-shape
handler with max_confs and pp_weight. When reference_sdf is used, the reference uses
OpenChemLib's one-conformation handler; candidates still use max_confs and pp_weight.
With reference_phesa_file, the entire UTF-8 text file must contain one encoded PheSA descriptor.
Surrounding whitespace is stripped before decoding with DescriptorHandlerShape.decode().
The decoded reference is used directly, without generating reference conformers. Candidates still
use max_confs and pp_weight. Empty, unreadable, or invalid descriptor files fail the run.
Reference coordinate frame: With reference_phesa_file, the aligned reference and candidate
SDFs, including the optional merged candidate SDF, remain in the PheSA alignment coordinate frame.
They are not restored to the coordinates of the original molecule used to create the encoded
descriptor. If downstream calculations need alignment in an input reference SDF's coordinate frame,
use reference_sdf; coordinate restoration applies only to that reference mode.
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/results.json: per-candidate PheSA similarity payloadresults/scores.csv: tabular candidate scoresresults/aligned/reference.sdf: aligned reference structureresults/aligned/candidates/*.sdf: aligned candidate structuresresults/aligned/aligned_candidates.sdf: optional merged aligned candidate SDFresults/aligned/manifest.csv: candidate scores and aligned SDF pathsresults/result_record.json: standardized CADDForgeResult
Pipeline artifacts
The plugin exposes:
- input
reference_sdfmapped to config fieldreference_sdf - input
reference_phesa_filemapped to config fieldreference_phesa_file - input
candidatesmapped to config fieldcandidate_sdf_files - output
scoresfromscores_csv - output
aligned_referencefromaligned_reference_sdf - output
aligned_candidatesfromaligned_manifest_csvusing columnaligned_candidate_sdf - optional output
merged_aligned_candidatesfrommerged_aligned_candidates_sdf
Tool: ani-conformers
What it does
The ani-conformers tool generates ANI re-ranked conformers and writes the selected conformers to SDF. It supports:
- one SMILES, an inline SMILES list, a SMILES file, or an input SDF file
- RDKit conformer generation and MMFF optimization
- ANI re-ranking of clustered conformer representatives
- batch processing with per-molecule summaries and a combined ranked-conformer SDF
External dependencies
No external command-line tools are required beyond the Python environment.
Runtime notes:
- TorchANI and PyTorch must be available in the environment.
- CUDA is optional.
CLI usage
caddforge run descriptors ani-conformers --config ani_conformers.yaml
Python API usage
from cadd_descriptors import AniConformersConfig, AniConformersWorkflow
cfg = AniConformersConfig(
smiles="CCO",
top_n=10,
num_confs=50,
backend="local",
)
workflow = AniConformersWorkflow(cfg)
job = workflow.prepare_job()
result = workflow.run(job)
print(result.status.value, result.paths["ranked_conformers_sdf"])
Example config
smiles: "CCO"
num_confs: 100
top_n: 10
rmsd_cluster_thresh: 0.5
max_mmff_iters: 200
model_name: ANI2x
device: cpu
output_sdf_name: ranked_conformers.sdf
Tool-specific config options
Only one input source must be set:
smilessmiles_listsmiles_filestructure_file
Input options
smiles(str | None): Single SMILES string.smiles_list(list[str] | None): Inline batch of SMILES strings.smiles_file(Path | None): SMILES input file.structure_file(Path | None): Input SDF file.smiles_column(str, defaultsmiles): Column to read from CSV/TSV SMILES input.
Conformer and ANI options
num_confs(int, default500): Number of conformers to generate.rmsd_cluster_thresh(float, default0.5): RMSD threshold for conformer clustering.max_mmff_iters(int, default200): MMFF optimization steps per conformer.top_n(int, default50): Number of ANI-ranked conformers to keep.model_name(str, defaultANI2x): TorchANI model name.device(str | None, defaultcpu): Torch device string.output_sdf_name(str, defaultranked_conformers.sdf): Output SDF filename underresults/.
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/results.json: per-molecule conformer summary payloadresults/<output_sdf_name>: ranked conformers SDFresults/result_record.json: standardized CADDForgeResultstdout.log: workflow log
Tool: cluster-molecules
What it does
The cluster-molecules tool clusters molecules from SMILES input using fingerprint-based and scaffold-based algorithms. It supports:
- SMILES input from
.smi,.smiles,.sdf,.csv, or.tsv - multiple clustering algorithms: Butina, agglomerative, DBSCAN, HDBSCAN, k-medoids, scaffold, and affinity propagation
- medoid/centroid reporting for each cluster
- automatic k-medoids planning that chooses exact in-memory, exact disk-backed, or approximate execution modes
External dependencies
No external command-line tools are required beyond the Python environment.
Runtime notes:
hdbscanis required only foralgorithm: hdbscan.- The approximate
kmedoidsfallback uses sparseMiniBatchKMeansand then snaps cluster centers back to actual medoids.
CLI usage
caddforge run descriptors cluster-molecules --config cluster.yaml
Python API usage
from cadd_descriptors import ClusterMoleculesConfig, ClusterMoleculesWorkflow
cfg = ClusterMoleculesConfig(
input_path="molecules.csv",
smiles_column="smiles",
algorithm="kmedoids",
kmedoids_n_clusters=100,
kmedoids_mode="auto",
backend="local",
)
workflow = ClusterMoleculesWorkflow(cfg)
job = workflow.prepare_job()
result = workflow.run(job)
print(result.status.value, result.metrics)
Example config
input_path: molecules.csv
smiles_column: smiles
algorithm: kmedoids # butina|agglomerative|dbscan|hdbscan|kmedoids|scaffold|affinity_propagation
fingerprint_radius: 2
fingerprint_bits: 2048
kmedoids_n_clusters: 100
kmedoids_mode: auto # auto|exact_ram|exact_disk|approximate
kmedoids_memory_budget_gb: null
kmedoids_disk_budget_gb: null
kmedoids_max_exact_n: 5000
kmedoids_max_exact_pairs: 25000000
kmedoids_max_exact_disk_n: 20000
kmedoids_max_exact_disk_pairs: 100000000
kmedoids_batch_size: 1024
kmedoids_max_iter: 20
kmedoids_minibatch_size: 4096
kmedoids_local_refine_limit: 128
kmedoids_temp_dir: null
Tool-specific config options
Input options
input_path(Path): Input file containing molecules.smiles_column(str, defaultsmiles): SMILES column for CSV/TSV input.id_column(str | None): Optional identifier column copied into outputs.
Fingerprint options
fingerprint_radius(int, default2): Morgan fingerprint radius.fingerprint_bits(int, default2048): Morgan fingerprint size.
Algorithm selection
algorithm(butina | agglomerative | dbscan | hdbscan | kmedoids | scaffold | affinity_propagation): Clustering algorithm.
Algorithm-specific options
butina_cutoff(float, default0.6): Butina Tanimoto similarity cutoff.agglomerative_n_clusters(int | None): Agglomerative cluster count.agglomerative_distance_threshold(float | None): Agglomerative distance threshold.dbscan_eps(float, default0.4): DBSCAN epsilon in distance space.dbscan_min_samples(int, default3): DBSCAN minimum samples.hdbscan_min_cluster_size(int, default5): HDBSCAN minimum cluster size.affinity_preference(float | None): Affinity propagation preference.scaffold_use_generic(bool, defaulttrue): Use generic Bemis-Murcko scaffolds.
K-medoids planning options
kmedoids_n_clusters(int, default5): Target number of medoid clusters.kmedoids_mode(auto | exact_ram | exact_disk | approximate, defaultauto): Force or auto-select the execution strategy.kmedoids_memory_budget_gb(float | None): Optional RAM budget for planning.kmedoids_disk_budget_gb(float | None): Optional temp-disk budget for planning.kmedoids_max_exact_n(int, default5000): Max size for exact in-memory planning.kmedoids_max_exact_pairs(int, default25000000): Max pair count for exact in-memory planning.kmedoids_max_exact_disk_n(int, default20000): Max size for exact disk-backed planning.kmedoids_max_exact_disk_pairs(int, default100000000): Max pair count for exact disk-backed planning.kmedoids_batch_size(int, default1024): Batch size for exact assignment/cost evaluation.kmedoids_max_iter(int, default20): PAM swap-iteration limit.kmedoids_minibatch_size(int, default4096): Mini-batch size for approximate mode.kmedoids_local_refine_limit(int, default128): Max cluster size for exact local medoid refinement in approximate mode.kmedoids_temp_dir(Path | None): Optional temp directory for disk-backed exact mode.
Outputs
For each run, artifacts are written under runs/<date>/<job-id>/:
results/assignments.csv: molecule-to-cluster assignmentsresults/centroids.csv: per-cluster medoid/centroid summaryresults/summary.json: clustering summaryresults/planning.json: k-medoids planning summary whenalgorithm: kmedoidsresults/result_record.json: standardized CADDForgeResultstdout.log: workflow log
Compressed inputs
File-based SMILES, SDF, CSV, and TSV inputs may be supplied with a trailing .gz. CADDForge
expands these wrappers in job-local runtime scratch before invoking the descriptor workflow. Plain
inputs and native tool formats retain their existing behavior.
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.
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 first,
and publish docking/descriptors before MD.
Metadata
Release files for caddforge-descriptors 0.11.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_descriptors-0.11.0.tar.gz | 39.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| caddforge_descriptors-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 78.6 kB
Release files / caddforge_descriptors-0.11.0.tar.gz
| Download URL | caddforge_descriptors-0.11.0.tar.gz |
|---|---|
| Size | 39.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
932b6e0ac44c1376569415ac65fc6d75ced6b3390542036c20a2141e1fde44d3
|
|
BLAKE2b-256 checksum How to use checksums |
3510583f75495e1aa32f4e46517bc332f5fc03be6f311dca12fef93aff29d703
|
| 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_descriptors-0.11.0-py3-none-any.whl
| Download URL | caddforge_descriptors-0.11.0-py3-none-any.whl |
|---|---|
| Size | 39.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e559ae928dcda2aa6a1b1f8f44fe7b8b439d4404cc2b07a62c96f09fd41ebb8
|
|
BLAKE2b-256 checksum How to use checksums |
bb14175e21a00da2fb0ba2cc4ea8369829536cac4e552168e490566424a3c490
|
| 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