Skip to content

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:Entity, keyword-only). Set by :meth:sync or when loading via :meth:from_id / :meth:from_json.

ligand_id str | None

Parent ligand id in the ligands table (set by :meth:sync or when loading platform metadata / exported SDF fields).

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 (cocrystal, docked, registered, manual). Legacy rows may store crystal_extract; the client presents that as cocrystal.

component_id str | None

Protein Prep Selection component id for cocrystal poses.

props dict[str, Any]

Additional metadata from the platform row.

Attributes

best_pose class-attribute instance-attribute

best_pose: bool | None = None

binding_energy class-attribute instance-attribute

binding_energy: float | None = None

component_id class-attribute instance-attribute

component_id: str | None = None

compute_job_id class-attribute instance-attribute

compute_job_id: str | None = None

id class-attribute instance-attribute

id: str | None = field(default=None, kw_only=True)

ligand_id class-attribute instance-attribute

ligand_id: str | None = None

local_path class-attribute instance-attribute

local_path: str | None = field(default=None, kw_only=True)

mol property

mol: Mol | None

Return the RDKit molecule, loading from disk when needed.

name class-attribute instance-attribute

name: str | None = None

origin class-attribute instance-attribute

origin: PoseOrigin | str | None = None

pose_score class-attribute instance-attribute

pose_score: float | None = None

project_id class-attribute instance-attribute

project_id: str | None = field(default=None, kw_only=True)

props class-attribute instance-attribute

props: dict[str, Any] = field(default_factory=dict)

protein_id class-attribute instance-attribute

protein_id: str | None = None

remote_path class-attribute instance-attribute

remote_path: str | None = field(default=None, kw_only=True)

smiles class-attribute instance-attribute

smiles: str | None = None

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:Ligand.from_sdf when rehydrating.

True
remove_hydrogens bool

Passed to :meth:Ligand.from_sdf when rehydrating.

False

Returns:

Type Description
str

Local file path.

draw

draw()

Draw this pose's 3D structure using RDKit (same as :meth:Ligand.draw).

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. "Protein").

required

Raises:

Type Description
ValueError

If remote_path cannot be determined after sync.

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:Pose.

Raises:

Type Description
ValueError

If no pose record exists for id.

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 data payloads).

required
client Optional[DeepOriginClient]

Platform client; must have project_id set for registration.

None
sanitize bool

Passed to :meth:Ligand.from_sdf for local SDF paths.

True
remove_hydrogens bool

Passed to :meth:Ligand.from_sdf for local paths.

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:Ligand.from_sdf.

True
remove_hydrogens bool

Passed to :meth:Ligand.from_sdf.

False

Returns:

Name Type Description
Registered Self

class:Pose with platform id populated.

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:sync).

None

Returns:

Type Description
str | None

Project id string, or None if neither the entity nor the client

str | None

provides one.

show

show()

Visualize this pose in a notebook (Mol* viewer via :meth:Ligand.show).

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_hash

to_hash() -> str

Return a stable hash string for remote path generation.

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:remote_path before uploading. If :attr:remote_path is still unset, it is set to the default hash-based path.

None

Collection of :class:Pose objects.

Attributes

poses class-attribute instance-attribute

poses: list[Pose] = field(default_factory=list)

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 n x n NumPy array of pairwise RMSD values in Å.

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:PoseSet with one pose per SMILES group.

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 best_pose matches.

None
scored_only bool

When True, skip reference/metadata rows that lack docking scores (same filter as legacy docking loaders).

False
client Optional[DeepOriginClient]

Optional platform client.

None

Returns:

Name Type Description
Matching Self

class:PoseSet.

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:LigandSet.from_sdf.

True
remove_hydrogens bool

Passed to :meth:LigandSet.from_sdf.

False

Returns:

Name Type Description
A Self

class:PoseSet with one pose per successfully parsed SDF record.

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:~deeporigin.drug_discovery.structures.entity.Entity.id set (call :meth:~deeporigin.drug_discovery.structures.protein.Protein.sync first).

required

Returns:

Name Type Description
This Self

class:PoseSet (for chaining).

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:PoseSet (for chaining).

Raises:

Type Description
DeepOriginException

If protein_id is empty.

show_df

show_df()

Show poses in a dataframe with 2D visualizations.

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 protein_id, the import run did not succeed (the message carries the run's reason), or the platform stored fewer poses than were sent (the message names the missing records).

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:

  • DeepOriginException if the registration run failed. The message includes the reason the platform gave.
  • DeepOriginException if 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.
  • TimeoutError if 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.