deeporigin.drug_discovery.Pose / PoseSet¶
Bases: Entity
A 3D ligand conformation backed by an SDF in the platform pose result table.
A :class:Pose holds the platform pose result id (:attr:id) and the
parent ligand id (:attr:ligand_id). These are distinct from
:class:~deeporigin.drug_discovery.structures.ligand.Ligand identity.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str | None
|
Platform pose result id (inherited from :class: |
ligand_id |
str | None
|
Parent ligand id in the ligands table (set by :meth: |
smiles |
str | None
|
Canonical or input SMILES when known without loading the SDF. |
name |
str | None
|
Optional pose or ligand name. |
protein_id |
str | None
|
Optional protein the pose is associated with. |
compute_job_id |
str | None
|
Optional compute job that produced this pose. |
pose_score |
float | None
|
Docking pose score when present. |
binding_energy |
float | None
|
Docking binding energy when present. |
best_pose |
bool | None
|
Whether this row is the best pose for its ligand in a run. |
origin |
PoseOrigin | str | None
|
Platform pose provenance ( |
component_id |
str | None
|
Protein Prep Selection component id for cocrystal poses. |
props |
dict[str, Any]
|
Additional metadata from the platform row. |
Attributes¶
local_path
class-attribute
instance-attribute
¶
local_path: str | None = field(default=None, kw_only=True)
project_id
class-attribute
instance-attribute
¶
project_id: str | None = field(default=None, kw_only=True)
remote_path
class-attribute
instance-attribute
¶
remote_path: str | None = field(default=None, kw_only=True)
tags
class-attribute
instance-attribute
¶
tags: dict[str, Any] | None = field(
default=None, kw_only=True
)
Methods:¶
download
¶
download(
*,
lazy: bool = True,
client: DeepOriginClient | None = None,
sanitize: bool = True,
remove_hydrogens: bool = False
) -> str
Download the pose SDF and reload :attr:mol from disk when needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lazy
|
bool
|
Reuse cached local files when True. |
True
|
client
|
DeepOriginClient | None
|
Optional platform client. |
None
|
sanitize
|
bool
|
Passed to :meth: |
True
|
remove_hydrogens
|
bool
|
Passed to :meth: |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Local file path. |
ensure_remote_path
¶
ensure_remote_path(
*, client: DeepOriginClient, label: str
) -> None
Ensure :attr:remote_path is set after a lazy :meth:sync may have no-oped.
If the entity already has a platform id but remote_path was never
populated (e.g. rehydrated metadata only), sync(lazy=True) returns
early. This performs a full sync when needed, then raises if the path is
still missing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
DeepOriginClient
|
Authenticated client for sync/upload. |
required |
label
|
str
|
Human-readable name for error messages (e.g. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
from_id
classmethod
¶
from_id(
id: str, *, client: Optional[DeepOriginClient] = None
) -> Self
Load a single pose from a result-explorer record id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id
|
str
|
Platform pose result id. |
required |
client
|
Optional[DeepOriginClient]
|
Optional platform client. |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
The matching :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no pose record exists for |
from_json
classmethod
¶
from_json(
data: list[dict[str, Any]],
*,
client: Optional[DeepOriginClient] = None,
sanitize: bool = True,
remove_hydrogens: bool = False
) -> list[Self]
Build :class:Pose objects from pose metadata dicts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
list[dict[str, Any]]
|
Pose rows (for example result-explorer |
required |
client
|
Optional[DeepOriginClient]
|
Platform client; must have |
None
|
sanitize
|
bool
|
Passed to :meth: |
True
|
remove_hydrogens
|
bool
|
Passed to :meth: |
False
|
Returns:
| Type | Description |
|---|---|
list[Self]
|
One pose per dict, in input order. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a row is invalid or lacks required fields. |
from_sdf
classmethod
¶
from_sdf(
path: str | Path,
*,
ligand: Ligand | None = None,
protein_id: str | None = None,
origin: PoseOrigin | str = "registered",
client: Optional[DeepOriginClient] = None,
sanitize: bool = True,
remove_hydrogens: bool = False
) -> Self
Register an external SDF as a platform pose and return a :class:Pose.
Syncs the parent :class:Ligand (unless ligand is supplied), uploads
the SDF, and invokes the ImportTool pose-registration path.
Requires client.project_id. When the parent ligand has
:attr:~deeporigin.drug_discovery.structures.ligand.Ligand.project_id
set, it must match the client. The execution is created with
visibility="hidden".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Local SDF file path. |
required |
ligand
|
Ligand | None
|
Optional explicit parent ligand (skips auto-sync by SMILES). |
None
|
protein_id
|
str | None
|
Associated protein id (required). |
None
|
origin
|
PoseOrigin | str
|
Provenance string stored on the pose row. |
'registered'
|
client
|
Optional[DeepOriginClient]
|
Optional platform client. |
None
|
sanitize
|
bool
|
Passed to :meth: |
True
|
remove_hydrogens
|
bool
|
Passed to :meth: |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Registered |
Self
|
class: |
Blocks until the platform has stored the pose.
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If no project id can be resolved, the registration run fails (the message carries the run's reason), or the platform did not store the pose. |
TimeoutError
|
If the pose is not stored within an hour. |
resolved_project_id
¶
resolved_project_id(
client: DeepOriginClient | None = None,
) -> str | None
Data platform project id for API calls.
Returns :attr:project_id when set; otherwise client.project_id when
client is given; otherwise None. Does not read the filesystem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
DeepOriginClient | None
|
Optional platform client (e.g. the one passed to
:meth: |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Project id string, or None if neither the entity nor the client |
str | None
|
provides one. |
sync
¶
sync(
*,
lazy: bool = False,
client: Optional[DeepOriginClient] = None,
remote_path: Optional[str] = None
) -> None
Register this pose via import-dataset process_sdf (single-record SDF).
Requires :attr:protein_id, project_id, and a local or exportable structure.
Blocks until the platform has stored the pose, then sets :attr:id to the
platform pose result row id (and may set :attr:ligand_id when the tool
mints a new ligand). Raises as :meth:PoseSet.sync does.
to_file
¶
to_file(file_path: str | Path | None = None) -> str
Write this pose to an SDF file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path | None
|
Destination path. When omitted, writes a temp file. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Path to the written SDF file. |
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If no local structure is available. |
to_ligand
¶
to_ligand() -> Ligand
Convert this pose to a legacy pose-hydrated :class:Ligand.
Prefer using :class:Pose directly; this exists for backward compatibility
with code paths that still expect :class:Ligand pose rows (for example
molstar overlays).
upload
¶
upload(
*,
client: DeepOriginClient | None = None,
remote_path: str | None = None
) -> None
Upload the entity to the remote server.
Serializes via :meth:to_file with :attr:remote_path temporarily
cleared so subclasses that guard exports when only remote metadata is
present (e.g. :meth:Ligand.to_sdf) still write from in-memory state
on repeat uploads.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
DeepOriginClient | None
|
DeepOriginClient instance. If None, uses DeepOriginClient(). |
None
|
remote_path
|
str | None
|
Custom remote path to upload to. When provided, sets
:attr: |
None
|
Collection of :class:Pose objects.
Attributes¶
Methods:¶
compute_rmsd
¶
compute_rmsd() -> ndarray
Compute pairwise pose RMSD between all poses in this set.
RMSD is symmetry-corrected and computed in place: coordinates are not
aligned or centered. Each pose must have a local 3D structure; call
:meth:download first when poses are remote-only.
Returns:
| Type | Description |
|---|---|
ndarray
|
An |
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If any pose lacks a hydrated RDKit molecule. |
download
¶
download(
*,
client: Optional[DeepOriginClient] = None,
lazy: bool = True,
max_workers: int = 20,
skip_errors: bool = False,
sanitize: bool = True,
remove_hydrogens: bool = False
) -> None
Download platform SDF files for poses that lack a local path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Optional[DeepOriginClient]
|
Optional platform client. |
None
|
lazy
|
bool
|
Reuse cached local files when True. |
True
|
max_workers
|
int
|
Maximum concurrent downloads. |
20
|
skip_errors
|
bool
|
When False, raise on the first download failure. |
False
|
sanitize
|
bool
|
Passed to SDF rehydration after download. |
True
|
remove_hydrogens
|
bool
|
Passed to SDF rehydration after download. |
False
|
filter_top_poses
¶
filter_top_poses(*, by_pose_score: bool = True) -> Self
Keep the best pose for each unique SMILES.
Groups by :attr:Pose.smiles and retains:
- maximum :attr:Pose.pose_score when by_pose_score is True, or
- minimum :attr:Pose.binding_energy otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
by_pose_score
|
bool
|
Select by pose score (True) or binding energy (False). |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
A new :class: |
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If a multi-pose group lacks the required score. |
from_json
classmethod
¶
from_json(
data: list[dict[str, Any]],
*,
client: Optional[DeepOriginClient] = None,
sanitize: bool = True,
remove_hydrogens: bool = False
) -> Self
Build a :class:PoseSet from pose metadata dicts.
from_result
classmethod
¶
from_result(
*,
protein_id: str | None = None,
execution_id: str | None = None,
ligand_id: str | list[str] | None = None,
best_pose: bool | None = None,
scored_only: bool = False,
client: Optional[DeepOriginClient] = None
) -> Self
Load poses from the data platform result explorer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
protein_id
|
str | None
|
Optional protein filter. |
None
|
execution_id
|
str | None
|
Optional compute job / execution id filter. |
None
|
ligand_id
|
str | list[str] | None
|
Optional ligand id filter (single id or list). |
None
|
best_pose
|
bool | None
|
When set, restrict to rows whose |
None
|
scored_only
|
bool
|
When |
False
|
client
|
Optional[DeepOriginClient]
|
Optional platform client. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Matching |
Self
|
class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no pose rows match the filters. |
from_sdf
classmethod
¶
from_sdf(
file_path: str | Path,
*,
protein_id: str | None = None,
origin: PoseOrigin | str | None = None,
sanitize: bool = True,
remove_hydrogens: bool = False
) -> Self
Load a multi-record SDF into local :class:Pose objects.
Typical for docking output files with one conformer per record. This does
not register poses on the platform; call :meth:sync when ids are needed.
Docking scores in the SDF (for example POSE SCORE, Binding Energy)
are mapped to :attr:~Pose.pose_score and :attr:~Pose.binding_energy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path
|
Path to a multi-molecule SDF file. |
required |
protein_id
|
str | None
|
Optional protein id applied to every pose (overrides SDF fields when set). |
None
|
origin
|
PoseOrigin | str | None
|
Optional provenance string for every pose. |
None
|
sanitize
|
bool
|
Passed to :meth: |
True
|
remove_hydrogens
|
bool
|
Passed to :meth: |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Self
|
class: |
set_protein
¶
set_protein(protein: Protein) -> Self
Set :attr:~Pose.protein_id from a synced :class:~deeporigin.drug_discovery.structures.protein.Protein.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
protein
|
Protein
|
Protein with :attr: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
This |
Self
|
class: |
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If the protein has no platform id. |
set_protein_id
¶
set_protein_id(protein_id: str) -> Self
Set :attr:~Pose.protein_id on every pose in this set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
protein_id
|
str
|
Platform protein row id. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
This |
Self
|
class: |
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If |
sync
¶
sync(
*,
lazy: bool = False,
client: Optional[DeepOriginClient] = None,
remote_path: Optional[str] = None,
show_progress: bool | None = None
) -> None
Sync all poses in one import-dataset process_sdf execution.
Each pose must have :attr:~Pose.protein_id set. Ligands are created or
reused in the tool; pose rows are minted with register_poses: true.
Blocks until the platform has stored every pose, then reads the stored
pose rows once and sets :attr:~Pose.id on each pose.
In Jupyter, a step checklist is shown by default (upload → import-dataset
→ ingestion → ID resolution). Pass show_progress=False to disable.
Raises:
| Type | Description |
|---|---|
DeepOriginException
|
If a pose has no |
TimeoutError
|
If the platform has not finished storing the poses within an hour. |
to_dataframe
¶
to_dataframe() -> DataFrame
Convert poses to a pandas DataFrame (via legacy ligand view).
to_ligand_set
¶
to_ligand_set() -> LigandSet
Convert to a legacy :class:LigandSet of pose-hydrated ligands.
to_sdf
¶
to_sdf(output_path: str | Path | None = None) -> str
Write all poses with local structures to a multi-record SDF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_path
|
str | Path | None
|
Destination path. When omitted, writes a temp file. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Path to the written SDF. |
Overview¶
A Pose is a 3D ligand conformation stored in the platform pose result table
(result_type=pose). It has its own platform pose id (Pose.id) and a
parent ligand id (Pose.ligand_id) in the ligands table.
Pose origin known values include cocrystal, docked, registered, and
manual. Older indexed rows may still store crystal_extract; the client
reads that as cocrystal. Unknown origin strings are preserved for forward
compatibility.
Use :class:Pose / :class:PoseSet when you need pose-scoped identity.
:meth:~deeporigin.drug_discovery.Docking.get_results and
:meth:~deeporigin.drug_discovery.Docking.get_poses return :class:PoseSet.
You can also load poses with :meth:PoseSet.from_result or
:meth:~deeporigin.drug_discovery.Ligand.get_poses.
Register an external SDF¶
from deeporigin.drug_discovery import Pose
pose = Pose.from_sdf("cocrystal.sdf", protein_id=protein.id)
print(pose.id, pose.ligand_id)
To register several poses in one call, load them into a :class:PoseSet and
call :meth:PoseSet.sync. Every pose needs a protein_id, and all poses in one
call must share the same protein, project and origin.
The example loads one :class:Pose per record of a multi-record SDF; none has
an id until sync() returns. A PoseSet built from :class:Pose objects you
already have (PoseSet(poses=[...])) syncs the same way.
from deeporigin.drug_discovery import PoseSet
pose_set = PoseSet.from_sdf("poses.sdf", protein_id=protein.id)
pose_set.sync()
print([pose.id for pose in pose_set])
Pose.from_sdf, Pose.sync and PoseSet.sync block until the platform has
stored every pose, then set id on each pose. They raise:
DeepOriginExceptionif the registration run failed. The message includes the reason the platform gave.DeepOriginExceptionif the platform stored fewer poses than were sent. The message names each missing record by its position in the batch (starting at 0) and its name. The platform can reject a single record without failing the whole run, so check this error even when the run succeeded.TimeoutErrorif the poses are not stored within an hour.
List poses for a ligand¶
ligand.sync()
poses = ligand.get_poses()
for pose in poses:
print(pose.id, pose.pose_score)
Load poses from a docking run¶
from deeporigin.drug_discovery import PoseSet
pose_set = PoseSet.from_result(execution_id=docking.id)
Computing pairwise pose RMSD¶
Use :meth:PoseSet.compute_rmsd for an n x n matrix of pose-to-pose RMSD
values (Å). The calculation is symmetry-corrected (equivalent symmetric
atom mappings are minimized) and in place: coordinates are not aligned or
centered, so RMSD reflects actual positional deviation in the stored poses.
Each pose must have a local 3D structure loaded. For remote-only poses, call
:meth:PoseSet.download before :meth:PoseSet.compute_rmsd.
from deeporigin.drug_discovery import PoseSet
pose_set = PoseSet.from_sdf("docking_results.sdf")
rmsd_matrix = pose_set.compute_rmsd()
Returns New Data
compute_rmsd() returns a NumPy array and does not mutate the
:class:PoseSet or its poses.