Skip to content

Descriptors Plugin

Package: caddforge-descriptors

Public source tag

This page describes caddforge-descriptors 0.11.0, tagged as v0.11.0. Published on PyPI; see the version matrix.

The descriptors plugin provides molecular descriptor, conformer, shape/pharmacophore similarity, and clustering workflows.

Requirements and example status

PheSA imports pyocl, supplied by pyocl-idor>=0.8.3. Its OpenChemLib runtime requires Java 21 or newer and a configured JAVA_HOME.

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.

ani-psa

Computes ANI-weighted 3D polar surface area values from one molecule or a batch.

CLI:

caddforge run descriptors ani-psa --config ani_psa.yaml

YAML:

smiles: "CC(=O)Oc1ccccc1C(=O)O"
num_confs: 100
top_n: 10
rmsd_cluster_thresh: 0.5
max_mmff_iters: 200
temperature: 298.15
model_name: ANI2x
device: cpu

Python:

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

spec = get_tool("descriptors", "ani-psa")
cfg = spec.config_cls(smiles="CCO", top_n=10, 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: results/results.json, results/results.csv, results/result_record.json.

phesa

Computes OpenChemLib PheSA shape/pharmacophore similarities between one reference molecule and one or more candidate molecules. The reference can be provided as SMILES, SDF, or an encoded PheSA descriptor file; candidates can be provided as SMILES strings or single-/multi-compound SDF files.

Reference mode

When reference_smiles is used, the reference descriptor is generated with DescriptorHandlerShape and the configured max_confs and pp_weight. When reference_sdf is used, the reference descriptor is generated with OpenChemLib's one-conformation handler. Candidate descriptors always use DescriptorHandlerShape with the configured max_confs and pp_weight.

Only SDF-reference mode restores aligned coordinates into the original SDF coordinate frame. SMILES and encoded-reference modes retain the generated PheSA alignment frame. Do not combine those coordinates with a receptor's coordinates without a validated transformation.

Choose exactly one of reference_smiles, reference_sdf, and reference_phesa_file:

# Template: supply one encoded descriptor generated by a compatible public runtime.
reference_phesa_file: data/reference_phesa.txt
candidate_smiles: ["CCCO", "CCCCO"]
max_confs: 200
pp_weight: 0.5

The whole UTF-8 file contains one encoded descriptor; surrounding whitespace is stripped before decoding. This mode reuses its stored reference representation. max_confs and pp_weight configure generated candidate descriptors. The aligned reference and candidate SDFs, including any merged candidate SDF, remain in the PheSA frame because an original SDF-coordinate transformation is unavailable.

CLI:

caddforge run descriptors phesa --config phesa.yaml

YAML:

reference_smiles: "CCO"
candidate_smiles:
  - "CCCO"
  - "CCCCO"
max_confs: 200
pp_weight: 0.5

SDF reference and candidate files:

reference_sdf: data/reference.sdf
candidate_sdf_files:
  - data/candidates.sdf
  - data/extra_candidate.sdf
max_confs: 200
pp_weight: 0.5
write_merged_aligned_candidates_sdf: true

Each valid molecule record in candidate_sdf_files is scored as one candidate. PHESA uses SDF record names as candidate_id values when present, falling back to the source file stem plus the record index.

Set write_merged_aligned_candidates_sdf: true to additionally write a merged SDF containing all successfully aligned candidate molecules. The default filename is results/aligned/aligned_candidates.sdf and can be changed with merged_aligned_candidates_sdf_name.

Python:

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

spec = get_tool("descriptors", "phesa")
cfg = spec.config_cls(
    reference_smiles="CCO",
    candidate_smiles=["CCCO", "CCCCO"],
    max_confs=200,
    pp_weight=0.5,
    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)

Pipeline stage:

stages:
  - id: phesa_similarity
    tool: descriptors/phesa
    config:
      reference_sdf: data/reference.sdf
      max_confs: 200
      pp_weight: 0.5
    inputs:
      candidates: upstream_stage.poses

Pipeline ports:

Direction Name Kind Config/result key
Input reference_sdf file reference_sdf
Input reference_phesa_file file reference_phesa_file
Input candidates molecule collection candidate_sdf_files
Output scores tabular scores scores_csv
Output aligned_reference file aligned_reference_sdf
Output aligned_candidates molecule collection aligned_manifest_csv, column aligned_candidate_sdf
Output merged_aligned_candidates molecule collection merged_aligned_candidates_sdf

Outputs to inspect: results/results.json, results/scores.csv, results/aligned/reference.sdf, results/aligned/candidates/, results/aligned/manifest.csv, optional results/aligned/aligned_candidates.sdf, results/result_record.json.

ani-conformers

Generates RDKit conformers, re-ranks representatives with ANI, and writes selected conformers to SDF.

CLI:

caddforge run descriptors ani-conformers --config ani_conformers.yaml

YAML:

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

Python:

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

spec = get_tool("descriptors", "ani-conformers")
cfg = spec.config_cls(smiles="CCO", top_n=10, num_confs=50, 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.paths["ranked_conformers_sdf"])

Outputs to inspect: results/results.json, results/ranked_conformers.sdf, results/result_record.json.

cluster-molecules

Clusters molecules from SMILES/SDF/CSV/TSV input using fingerprint or scaffold algorithms.

CLI:

caddforge run descriptors cluster-molecules --config cluster_molecules.yaml

YAML:

input_path: data/molecules.csv
smiles_column: smiles
id_column: compound_id
algorithm: kmedoids
fingerprint_radius: 2
fingerprint_bits: 2048
kmedoids_n_clusters: 100
kmedoids_mode: auto
kmedoids_max_exact_n: 5000
kmedoids_max_exact_pairs: 25000000

Python:

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

spec = get_tool("descriptors", "cluster-molecules")
cfg = spec.config_cls(
    input_path="data/molecules.csv",
    smiles_column="smiles",
    algorithm="kmedoids",
    kmedoids_n_clusters=100,
    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: results/assignments.csv, results/centroids.csv, results/summary.json, results/result_record.json.

Compressed inputs

File-based SMILES, SDF, CSV, and TSV inputs may use a trailing .gz. This includes nested cluster-molecule inputs. CADDForge expands wrappers in runtime scratch; plain inputs and native tool formats remain unchanged.