Enumerator¶
Generate analogue libraries
from a parent Ligand on the Deep Origin platform.
To run it you need:
- a parent
Ligand(built from a SMILES string) - a
job_typethat picks the enumeration mode (see the table below) - the inputs that mode requires (e.g. atom indices for matched-molecular-pair (MMP ) modes)
Create an Enumerator, call run(), and get a pandas.DataFrame of results
back. run() blocks until the job finishes, so you must be logged in
(deeporigin login) before calling it.
Modes¶
The tool exposes four job_type values:
job_type |
What it does | Key inputs | Output |
|---|---|---|---|
SCAFFOLD |
MMP: grow a fragment at one attachment atom | replace_ix (one atom index) |
products CSV |
ANALOGUE |
MMP: swap a connected fragment | replace_ix (one or more indices) |
products CSV |
AVAILABLE_REACTIONS |
Discover named-reaction sites on the parent | none | reaction-site table |
REACTION |
Enumerate products against the Enamine fragment library | reaction_sites |
products CSV |
SCAFFOLD and ANALOGUE are the two MMP flavors, both
backed by CReM . AVAILABLE_REACTIONS is a
discovery step (it writes no CSV); its
output feeds REACTION.
The two workflows below are independent — pick MMP or reaction enumeration:
flowchart TD
L["Parent Ligand (from SMILES)"] --> Q{"Choose job_type"}
Q -->|"SCAFFOLD (replace_ix = 1 atom)"| S["Grow a fragment at<br/>one attachment atom"]
Q -->|"ANALOGUE (replace_ix = 1+ atoms)"| A["Swap a connected fragment"]
Q -->|"reaction workflow"| AR["AVAILABLE_REACTIONS<br/>(discover reaction sites)"]
S --> P["products DataFrame"]
A --> P
AR --> RS["reaction-site table"]
RS -->|"pick rows, pass as reaction_sites"| R["REACTION<br/>(enumerate vs Enamine library)"]
R --> P
MMP enumeration (SCAFFOLD / ANALOGUE)¶
MMP modes take explicit RDKit atom indices (replace_ix) marking the enumeration
site. SCAFFOLD grows a new fragment at a single attachment atom; ANALOGUE
replaces a connected fragment defined by one or more atom indices.
from deeporigin.drug_discovery import Enumerator, Ligand
parent = Ligand.from_smiles("Brc1ccccc1")
# Grow a fragment at atom 0
scaffold = Enumerator(ligand=parent, job_type="SCAFFOLD", replace_ix=0)
df = scaffold.run()
df.head()
Tune the CReM search with radius (1-5) and max_fragment_size (1-15):
analogue = Enumerator(
ligand=parent,
job_type="ANALOGUE",
replace_ix=[0, 1],
radius=2,
max_fragment_size=8,
)
df = analogue.run()
The returned DataFrame is the descriptor-enriched results.csv: enumeration
metadata columns plus RDKit descriptors (molecular_weight, hbond_donor_count,
hbond_acceptor_count, logp, tpsa, rotatable_bond_count). After a run,
enumerator.cap_hit indicates whether the platform enumeration cap was reached.
Reaction enumeration (AVAILABLE_REACTIONS then REACTION)¶
Choosing valid reaction sites by hand is error-prone, so run AVAILABLE_REACTIONS
first to discover them. Each row gives a reaction_id, reaction_name,
reactant_role, and the atom_indices of the matched site.
sites = Enumerator(ligand=parent, job_type="AVAILABLE_REACTIONS").run()
sites
Pick the rows you want and pass them verbatim as reaction_sites to a REACTION
run:
df = Enumerator(
ligand=parent,
job_type="REACTION",
reaction_sites=[
{"reaction_id": "suzuki", "reactant_role": "core_halide", "atom_indices": [0, 1]},
],
).run()
df.head()
REACTION accepts up to 16 sites. Each site must match a hit returned by
AVAILABLE_REACTIONS on the same parent, otherwise the tool rejects the request.
Existing executions¶
Reconstruct an Enumerator from an existing tools execution ID (for example to
re-fetch results in a later session):
enum = Enumerator.from_id("<executionId>")
df = enum.get_results()
To re-fetch results from the most recently created Enumerator run without its
ID, use from_last_run():
enum = Enumerator.from_last_run()
df = enum.get_results()
If you already have the execution payload from client.executions.get, use
Enumerator.from_dto(dto) instead.
See the API reference for the full signature.