Skip to content

deeporigin.drug_discovery.pocket_finder

PocketFinder -- find binding pockets via synchronous or asynchronous execution.

Sync usage (blocking, returns pockets directly)::

pf = PocketFinder(protein)
pf.run(quote=True)   # populates pf.estimate; pf.status == "Quoted"
pockets = pf.run()   # blocking; calls get_results(); populates pf.cost

Async usage (persisted execution, watch in notebook)::

pf = PocketFinder(protein)
pf.start()            # submits async; sets pf.id and pf.status
await pf.watch()      # live Jupyter updates (or pf.sync() in a loop)
pockets = pf.get_results()

Define-by-selection (one pocket from residue/ligand/cofactor selectors)::

pf = PocketFinder(
    protein,
    mode="define-by-selection",
    selections=[{"kind": "ligand", "author": {"chain_id": "A", "resname": "LIG"}}],
    pocket_radius=10.0,
    align_to_pocket=True,
)
pockets = pf.run()

From-crystal-ligand (one pocket from a crystal ligand, either still embedded in a holo structure, or already extracted into a separate Ligand)::

# ligand still embedded in the protein file; identify it by its bare
# residue/ligand code
pf = PocketFinder(protein, mode="from-crystal-ligand", ligand_id="635")
pockets = pf.run()

# ligand already extracted (also strips it from the protein structure)
crystal_ligand = protein.extract_ligand()
pf = PocketFinder(
    protein,
    mode="from-crystal-ligand",
    crystal_ligand=crystal_ligand,
)
pockets = pf.run()

Attributes

BoxGeometry module-attribute

BoxGeometry = Literal['ligand-extents', 'fixed-radius']

PocketFinderMode module-attribute

PocketFinderMode = Literal[
    "auto-find",
    "define-by-selection",
    "from-crystal-ligand",
]

PocketSelectionKind module-attribute

PocketSelectionKind = Literal[
    "residue", "ligand", "cofactor"
]

Classes

PocketFinder

Bases: Execution, SyncExecutableMixin, AsyncExecutableMixin, NotebookWatchMixin

Find binding pockets in a protein structure.

Supports mode="auto-find" (classifier; default), mode="define-by-selection" (one pocket from structured selections), and mode="from-crystal-ligand" (one pocket from a crystal ligand, either resolved in-place within the supplied protein via ligand_id, or supplied separately via crystal_ligand).

The execution request body includes sync (true = blocking, false = immediate DTO). :meth:run sets "sync": true and blocks until the run finishes. :meth:start sets "sync": false in inputs (non-blocking); start returns immediately with an execution DTO that you can poll with :meth:sync, wait on with :meth:wait, or watch in Jupyter with :meth:watch. Track async jobs with :meth:sync, :meth:from_id, and :meth:list.

Attributes:

Name Type Description
protein Protein

The protein to analyse.

mode PocketFinderMode

auto-find, define-by-selection, or from-crystal-ligand.

pocket_count int

Maximum pockets (auto-find).

pocket_min_size int

Minimum pocket volume in cubic Angstroms (auto-find).

selections list[PocketSelection] | None

Selectors for define-by-selection (tool wire dicts).

pocket_radius float

Half-edge of the docking cube in angstroms (define-by-selection, or from-crystal-ligand with box_geometry="fixed-radius").

align_to_pocket bool

PCA-orient box.rotation_deg from selection atoms.

crystal_ligand Ligand | None

Extracted Ligand to build the pocket from (from-crystal-ligand).

ligand_id str | None

Bare ligand/residue code resolved in-place within protein (from-crystal-ligand).

box_geometry str | None

"ligand-extents" or "fixed-radius" (from-crystal-ligand).

box_padding float | None

Padding in angstroms added to ligand PCA extents when box_geometry is "ligand-extents" (from-crystal-ligand).

Attributes

USER_LOG_COLUMNS class-attribute
USER_LOG_COLUMNS: list[str] = [
    "log_level",
    "tool_key",
    "timestamp",
    "message",
]
align_to_pocket property
align_to_pocket: bool

Whether to PCA-orient the box from selection atoms.

app instance-attribute
app: str | None = None
approve_amount instance-attribute
approve_amount: int | None = None
box_geometry property
box_geometry: str | None

Box geometry for from-crystal-ligand, or None to use the platform default.

box_padding property
box_padding: float | None

Padding in angstroms added to ligand PCA extents (from-crystal-ligand).

client instance-attribute
client: DeepOriginClient = client
completed_at instance-attribute
completed_at: str | None = None
cost property
cost: float | None

Actual cost in dollars, set after execution completes.

This property cannot be set manually.

created_at instance-attribute
created_at: str | None = None
created_by instance-attribute
created_by: str | None = None
crystal_ligand property
crystal_ligand: Ligand | None

Extracted crystal ligand (from-crystal-ligand), or None.

dto property
dto: dict[str, Any] | None

Last tools execution DTO from the platform, if any.

estimate property
estimate: float | None

Cost estimate in dollars, populated when the platform returns a quotation.

Set after run(quote=True), start(quote=True), or any call with approve_amount=-1. None until a quotation result is received. This property cannot be set manually.

id property
id: str | None

Platform execution ID when set (read-only).

ligand_id property
ligand_id: str | None

Bare ligand/residue code to locate in-place (from-crystal-ligand), or None.

mode property

Pocket finder mode: auto-find or define-by-selection.

name property writable
name: str | None

Optional user-defined label for this execution.

May be set or changed only while id is unset. After an execution ID exists, name is read-only.

pocket_count property
pocket_count: int

Maximum number of pockets to detect (auto-find).

pocket_min_size property
pocket_min_size: int

Minimum pocket volume in cubic Angstroms (auto-find).

pocket_radius property
pocket_radius: float

Half-edge of the docking cube in angstroms (define-by-selection).

progress instance-attribute
progress: dict | None = None
protein property
protein: Protein

The protein to analyse.

runtime property
runtime: float | None

Seconds from DTO startedAt to completedAt or current UTC time.

Uses :attr:dto (same shape as client.executions.get). When completedAt is present, it is the end time; otherwise the end time is datetime.now(timezone.utc). Returns None if there is no DTO or startedAt is missing or empty.

selections property
selections: list[PocketSelection] | None

Selectors for define-by-selection mode, or None for auto-find.

session instance-attribute
session: str | None = None
started_at instance-attribute
started_at: str | None = None
status instance-attribute
status: PlatformStatus | None = None
tool_key class-attribute instance-attribute
tool_key: str = TOOL_KEYS_AND_VERSIONS["pocket_finder"][
    "tool_key"
]
tool_version instance-attribute
tool_version = tool_version

Methods:

cancel
cancel() -> None

Cancel a running or queued execution.

Raises:

Type Description
ValueError

If the job has no execution ID.

ValueError

If the job is not in a cancellable state.

confirm
confirm() -> None

Confirm a quoted tools execution on the platform.

Requires :attr:id and status equal to "Quoted". Uses :meth:~deeporigin.platform.executions.Executions.confirm with :data:~deeporigin.utils.constants.TOOL_EXECUTION_POST_TIMEOUT_SECONDS (10 minutes) and retry=False, then applies the returned DTO via :meth:update_from_dto so status, :attr:cost, and :attr:dto reflect the platform response. For direct (blocking) tools the response is typically terminal (Completed); for async tools it may be Created or Running — call :meth:sync until the job finishes.

Raises:

Type Description
ValueError

If there is no platform execution id or status is not "Quoted".

duplicate
duplicate(
    *, client: DeepOriginClient | None = None
) -> Self

Create a fresh copy with the same configuration but no execution state.

Useful after from_id() to re-run the same calculation. The returned instance has no id, status, estimate, or cost — it is ready for run() / start().

Parameters:

Name Type Description Default
client DeepOriginClient | None

Optional API client for the new instance. Falls back to the current instance's client.

None

Returns:

Type Description
Self

A new instance sharing the same domain-specific configuration.

from_dto classmethod
from_dto(
    dto: dict[str, Any],
    *,
    client: DeepOriginClient | None = None
) -> Self

Construct a PocketFinder from a tools execution DTO.

Rehydrates protein and mode-specific inputs from userInputs (falling back to inputs for older payloads). When protein.id is present, the protein is loaded with Protein.from_id(..., download=False) and remote_path_override from the stored input. When only file_path is present (e.g. an unregistered Prepared Protein), builds an in-memory Protein with that remote path.

Parameters:

Name Type Description Default
dto dict[str, Any]

Execution payload (same shape as client.executions.get).

required
client DeepOriginClient | None

Optional API client. Uses the default if not provided.

None

Returns:

Type Description
Self

A PocketFinder with id, pricing fields, and domain inputs set.

Raises:

Type Description
ValueError

If neither protein.id nor protein.file_path is present in stored inputs, or selection inputs are invalid.

from_id classmethod
from_id(
    id: str, *, client: DeepOriginClient | None = None
) -> Self

Construct an instance from an existing platform execution ID.

Fetches the execution DTO via client.executions.get and delegates to :meth:from_dto. Concrete subclasses override :meth:from_dto to attach domain state from userInputs.

Parameters:

Name Type Description Default
id str

Platform execution ID.

required
client DeepOriginClient | None

Optional API client. Uses the default if not provided.

None

Returns:

Type Description
Self

A partially-hydrated instance with common fields populated.

Raises:

Type Description
NotImplementedError

If cls has no tool_key (bare :class:Execution).

from_last_run classmethod
from_last_run(
    *, client: DeepOriginClient | None = None
) -> Self

Construct an instance from the most recently created execution of this tool.

Scoped to the client's project, like :meth:list. Calls client.executions.list with tool_key, order set to :data:~deeporigin.utils.constants.EXECUTION_LIST_ORDER_CREATED_DESC, the client's project_id, and page_size=1, then delegates to :meth:from_dto. Concrete subclasses inherit this method; domain state is restored via their from_dto overrides.

Parameters:

Name Type Description Default
client DeepOriginClient | None

Optional API client. Uses the default if not provided.

None

Returns:

Type Description
Self

A partially-hydrated instance for the newest execution by

Self

createdAt.

Raises:

Type Description
NotImplementedError

If cls has no tool_key (bare :class:Execution).

ValueError

If no executions exist for this tool type.

get_results
get_results(
    dto: dict[str, Any] | None = None,
) -> list[Pocket]

Load pockets for this execution from the data platform or jobOutputs.

Tries :meth:~deeporigin.drug_discovery.structures.pocket.Pocket.from_result first. On failure, parses jobOutputs.pockets from dto, or from client.executions.get when dto is omitted (for example after :meth:~deeporigin.drug_discovery.execution.Execution.from_id).

Parameters:

Name Type Description Default
dto dict[str, Any] | None

Optional execution payload (executions.create / executions.get). Passing it avoids an extra GET when the data platform path fails but the sync response included jobOutputs.

None

Returns:

Type Description
list[Pocket]

List of Pocket objects for this execution. Each pocket has

list[Pocket]

attr:Pocket.protein set to this finder's protein.

Raises:

Type Description
ValueError

If :attr:id is unset.

DeepOriginException

If no pockets could be loaded from the data platform or jobOutputs.

get_user_logs
get_user_logs(
    *,
    limit: int | None = None,
    offset: int | None = None,
    select: list[str] | None = None,
    with_total_count: bool = False
) -> DataFrame | None

Search data-platform user_logs rows for this execution.

Uses :meth:deeporigin.platform.user_logs.UserLogs.search with this execution's id (tools executionId), stored as execution_id on user_logs rows — the same string passed to :meth:get_results as compute_job_id.

When no execution id is assigned yet, returns None without calling the API.

Parameters:

Name Type Description Default
limit int | None

Max rows to return (forwarded to UserLogs.search).

None
offset int | None

Skip offset (forwarded).

None
select list[str] | None

Columns to select (forwarded).

None
with_total_count bool

Request total count from the server (forwarded).

False

Returns:

Type Description
DataFrame | None

A DataFrame with columns log_level, tool_key, timestamp,

DataFrame | None

and message. tool_key omits the deeporigin. prefix;

DataFrame | None

timestamp is a compact humanized relative time. Returns None

DataFrame | None

if this instance has no execution id yet or the client has no

DataFrame | None

user_logs API.

list classmethod
list(
    *,
    client: DeepOriginClient | None = None,
    status: list[str] | None = None
) -> list[Self]

List executions of this tool, newest first, scoped to the client's project.

Parameters:

Name Type Description Default
client DeepOriginClient | None

Optional API client. Uses the default if not provided.

None
status list[str] | None

Optional list of statuses to keep.

None

Returns:

Type Description
list[Self]

Instances of this class, newest first.

Raises:

Type Description
NotImplementedError

If cls has no tool_key (bare :class:Execution).

run
run(
    *,
    quote: bool = False,
    approve_amount: int | None = None
) -> list[Pocket] | None

Execute pocket finding synchronously (blocking).

Submits one synchronous tools execution (sync=True) and returns the detected pockets via :meth:get_results. The server blocks until the run completes; use :meth:start for async, persisted execution.

Pass quote=True (or approve_amount=-1) to request a cost estimate only. In that case the platform returns a Quoted DTO, the instance is updated with estimate and status="Quoted", and None is returned.

Parameters:

Name Type Description Default
quote bool

Shorthand for approve_amount=-1.

False
approve_amount int | None

Spend cap forwarded to the platform as approveAmount.

None

Returns:

Type Description
list[Pocket] | None

List of Pocket objects, or None when the platform responds

list[Pocket] | None

with Quoted status.

Raises:

Type Description
DeepOriginException

If no pockets could be loaded from the data platform or jobOutputs.

show
show() -> None

Display the current execution in Jupyter using the execution card HTML view.

If no platform execution ID exists yet, shows the same card with a short notice instead of raising (see :meth:~deeporigin.platform.execution_display.ExecutionDisplay.from_pending).

start
start(
    *,
    quote: bool = False,
    approve_amount: int | None = None,
    **kwargs
) -> None

Submit a persisted async execution to the platform.

Only valid when status is None (no execution exists yet). All other statuses raise immediately to prevent re-submission.

Pass quote=True or approve_amount=-1 to request a cost estimate without running. If the platform returns a Quoted DTO the instance is left in that state — call :meth:~deeporigin.drug_discovery.execution.Execution.confirm explicitly to proceed.

Parameters:

Name Type Description Default
quote bool

Shorthand for approve_amount=-1. Takes precedence when both quote and approve_amount are provided.

False
approve_amount int | None

Spend cap passed to the platform as approveAmount. -1 (or any negative value) forces a quote-only create. None omits the field (platform may auto-confirm).

None
**kwargs

Forwarded verbatim to _start_impl.

{}

Raises:

Type Description
ValueError

If the current status is not None.

stop_watching
stop_watching() -> None

Cancel an in-flight watch loop if one is running.

Safe to call when no watch is active. Does not cancel the caller's current task when invoked from inside the watch loop.

sync
sync() -> None

Fetch the latest tools execution from the platform and refresh fields.

Calls client.executions.get for :attr:id and applies the response with :meth:update_from_dto. Use when the job may have changed outside this process (for example after submission from the web UI), to poll lifecycle state, or to refresh an instance built from an older DTO. Available on sync-only and async execution types alike.

Rejected executions are refreshed without raising for their status, so history inspection and notebook displays remain available. HTTP failures while fetching the execution still raise.

If executions.get returns a falsy value, this instance is left unchanged.

Raises:

Type Description
ValueError

If this instance has no execution id yet.

NotImplementedError

If type(self).tool_key is empty (bare :class:Execution).

ValueError

If the returned DTO tool.key does not match this class (see :meth:update_from_dto).

update_from_dto
update_from_dto(dto: dict[str, Any]) -> None

Apply tools execution fields from dto onto this instance.

Updates id, pricing, lifecycle fields, and _dto the same way as :meth:from_dto for a newly created instance. Use after a live executions.create / sync() response to refresh state without constructing a new object (domain inputs on self are unchanged).

Parameters:

Name Type Description Default
dto dict[str, Any]

Execution payload (same shape as client.executions.get).

required

Raises:

Type Description
NotImplementedError

If type(self) has no tool_key (bare :class:Execution).

ValueError

If the DTO tool.key does not match tool_key.

wait
wait(
    *,
    poll_interval: float = 5.0,
    timeout: float | None = None
) -> dict[str, Any] | None

Block until this execution reaches a terminal state.

Parameters:

Name Type Description Default
poll_interval float

Seconds to sleep between polling cycles.

5.0
timeout float | None

Maximum total seconds to wait. If None, waits indefinitely.

None

Returns:

Type Description
dict[str, Any] | None

The latest execution DTO, or None if the platform returned no DTO.

Raises:

Type Description
ValueError

If this instance has no execution id yet.

TimeoutError

If timeout elapses before the execution terminates.

watch async
watch(
    *, interval: float = 5.0, blocking: bool = False
) -> Task | None

Start live notebook updates; optionally block until the job finishes.

By default, awaiting this coroutine finishes in one event-loop turn, so the cell returns while the display keeps updating in the background. Use this when you need to run other cells while the job runs::

task = await abfe.watch()

Set blocking=True or export JOB_WATCH_BLOCK=1 (truthy values: 1, true, yes, on) to run the poll loop inline so the cell does not return until a terminal state — useful for nbconvert --execute and doc CI (see :data:~deeporigin.utils.constants.JOB_WATCH_BLOCK_ENV)::

await abfe.watch(blocking=True)
# or: export JOB_WATCH_BLOCK=1

Parameters:

Name Type Description Default
interval float

Seconds between polls.

5.0
blocking bool

When True, await the watch loop instead of returning a background task. Also blocks when JOB_WATCH_BLOCK is truthy.

False

Returns:

Type Description
Task | None

The background task when not blocking; None when blocking.

Task | None

Cancel a background watch with :meth:stop_watching or task.cancel().

PocketSelection

Bases: TypedDict

One residue, ligand, or cofactor selector for define-by-selection mode.

Attributes

author instance-attribute
kind instance-attribute

PocketSelectionAuthor

Bases: TypedDict

PDB/mmCIF author identity for a selected component (tool wire shape).

Attributes

chain_id instance-attribute
chain_id: str
icode instance-attribute
icode: NotRequired[str]
resname instance-attribute
resname: NotRequired[str]
resseq instance-attribute
resseq: NotRequired[int]

Functions: