Skip to content

Denticity → topology → skeleton → ligand

Many “ligand chemical space” summaries stop at donor counts and donor atom types. For coordination chemistry, this misses a big part of what controls complex geometry and properties: how donor atoms are connected, i.e. the skeleton — and its reduced topology.

cTopo provides a hierarchy that gradually increases chemical detail:

Hierarchy pipeline

Default levels

The default tree builder groups a dataset by the following levels (from coarse to fine):

  1. denticity
    Number of donor atoms.

  2. topology
    A reduced representation of the skeleton that preserves connectivity/branching but removes “path length” where it is reducible.

  3. skeleton
    The donor atoms plus the atoms that connect donors.

  4. skeleton + bonds
    Same skeleton graph, but now bond orders/aromaticity are kept.

  5. skeleton + donors + bonds
    Like above, but donor atom identity/typing is included in the grouping key.

  6. ligand
    The full molecule.

This is meant to answer questions like:

  • Do I have 50 variants of the same scaffold/topology, or genuinely different cages?
  • Which topologies are missing / rare?
  • Where is diversity coming from: substituents or the cage itself?

Build a tree and export to HTML

from pathlib import Path
from ctopo import ligand_from_smiles
from ctopo.trees import build_ligand_tree, tree_to_html

ligands = [
    ligand_from_smiles("[NH2:1]CC[NH2:2]"),
    ligand_from_smiles("[NH2:1]CC[NH:2]CC[NH2:3]"),
]

tree = build_ligand_tree(ligands)
html = tree_to_html(tree)

Path("ligand_tree.html").write_text(html, encoding="utf-8")

Tree HTML mock

Custom grouping levels

If you want a different hierarchy (e.g. include formal charge, donor element set, or “skeleton-only fingerprints”), treat the default as a template:

  • a level is just a function that maps a ligand to a grouping key (often a SMILES string of a derived representation),
  • plus an optional “preview” (SVG) for display in the HTML tree.

The simplest workflow is:

1) start with the default levels,
2) add one new level at a time,
3) verify that you’re not accidentally “forgetting” information as you go down the tree.