Source code for deeprank2.molstruct.structure

from __future__ import annotations

from typing import TYPE_CHECKING

from typing_extensions import Self

if TYPE_CHECKING:
    from deeprank2.molstruct.atom import Atom
    from deeprank2.molstruct.residue import Residue
    from deeprank2.utils.pssmdata import PssmRow


[docs]class PDBStructure: """.""" def __init__(self, id_: str | None = None): """A proitein or protein complex structure. A `PDBStructure` can contain one or multiple `Chains`, i.e. separate molecular entities (individual proteins). One PDBStructure consists of a number of `Residue`s, each of which is of a particular `AminoAcid` type and in turn consists of a number of `Atom`s. Args: id_: An unique identifier for this structure, can be the pdb accession code. Defaults to None. """ self._id = id_ self._chains = {} def __eq__(self, other: Self) -> bool: if isinstance(other, PDBStructure): return self._id == other._id return NotImplemented def __hash__(self) -> hash: return hash(self._id) def __repr__(self) -> str: return self._id
[docs] def has_chain(self, chain_id: str) -> bool: return chain_id in self._chains
[docs] def get_chain(self, chain_id: str) -> Chain: return self._chains[chain_id]
[docs] def add_chain(self, chain: Chain) -> None: if chain.id in self._chains: msg = f"Duplicate chain: {chain.id}" raise ValueError(msg) self._chains[chain.id] = chain
@property def chains(self) -> list[Chain]: return list(self._chains.values())
[docs] def get_atoms(self) -> list[Atom]: """List all atoms in the structure.""" atoms = [] for chain in self._chains.values(): for residue in chain.residues: atoms.extend(residue.atoms) return atoms
@property def id(self) -> str: return self._id
[docs]class Chain: """One independent molecular entity of a `PDBStructure`. In other words: each `Chain` in a `PDBStructure` is a separate molecule. """ def __init__(self, model: PDBStructure, id_: str | None): """One chain of a PDBStructure. Args: model: The model that this chain is part of. id_: The pdb identifier of this chain. """ self._model = model self._id = id_ self._residues = {} self._pssm = None # pssm is per chain @property def model(self) -> PDBStructure: return self._model @property def pssm(self) -> PssmRow: return self._pssm @pssm.setter def pssm(self, pssm: PssmRow) -> None: self._pssm = pssm
[docs] def add_residue(self, residue: Residue) -> None: self._residues[(residue.number, residue.insertion_code)] = residue
[docs] def has_residue(self, residue_number: int, insertion_code: str | None = None) -> bool: return (residue_number, insertion_code) in self._residues
[docs] def get_residue(self, residue_number: int, insertion_code: str | None = None) -> Residue: return self._residues[(residue_number, insertion_code)]
@property def id(self) -> str: return self._id @property def residues(self) -> list[Residue]: return list(self._residues.values())
[docs] def get_atoms(self) -> list[Atom]: """Shortcut to list all atoms in this chain.""" atoms = [] for residue in self.residues: atoms.extend(residue.atoms) return atoms
def __eq__(self, other: Self) -> bool: if isinstance(other, Chain): return self._model == other._model and self._id == other._id return NotImplemented def __hash__(self) -> hash: return hash(self._id) def __repr__(self) -> str: return f"{self._model} {self._id}"