Skip to content

Commit

Permalink
Yuuuge refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
samirelanduk committed Jun 6, 2018
1 parent dbb0951 commit 7d32a27
Show file tree
Hide file tree
Showing 53 changed files with 3,429 additions and 5,313 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016 Sam Ireland
Copyright (c) 2018 Sam Ireland

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
5 changes: 2 additions & 3 deletions atomium/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from .files import xyz_data_from_file, xyz_from_file
from .files import pdb_data_from_file, fetch_data
from .files import pdb_from_file, fetch
from .models import *
from .files import *

__author__ = "Sam Ireland"
__version__ = "0.10.0"
36 changes: 1 addition & 35 deletions atomium/files/pdb.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Contains the Pdb class and functions for opening them."""

import datetime
from ..structures.models import Model
from ..models.molecules import Model

class Pdb:
"""A Pdb is used to represent a fully processed PDB file."""
Expand Down Expand Up @@ -46,53 +46,41 @@ def model(self):
def code(self):
"""The Pdb's 4-letter code.
:raises TypeError: if a non-str code is set.
:raises ValueError: if the PDB code given is invalid.
:rtype: ``str``"""

return self._code


@code.setter
def code(self, code):
if not isinstance(code, str):
raise TypeError("PDB code {} is not str".format(code))
if len(code) != 4:
raise ValueError("PDB code {} is not valid".format(code))
self._code = code


@property
def deposition_date(self):
"""The Pdb's desposition date.
:raises TypeError: if a non-date is given.
:rtype: ``datetime.date``"""

return self._deposition_date


@deposition_date.setter
def deposition_date(self, deposition_date):
if not isinstance(deposition_date, datetime.date):
raise TypeError("{} is not a Date".format(deposition_date))
self._deposition_date = deposition_date


@property
def title(self):
"""The Pdb's title.
:raises TypeError: if a non-str title is given.
:rtype: ``str``"""

return self._title


@title.setter
def title(self, title):
if not isinstance(title, str):
raise TypeError("PDB title {} is not str".format(title))
self._title = title


Expand All @@ -101,16 +89,13 @@ def title(self, title):
def resolution(self):
"""The Pdb's resolution.
:raises TypeError: if a non-numeric resolution is given.
:rtype: ``float``"""

return self._resolution


@resolution.setter
def resolution(self, resolution):
if not isinstance(resolution, (int, float)):
raise TypeError("Resolution {} isn't numeric".format(resolution))
self._resolution = resolution


Expand All @@ -119,88 +104,69 @@ def resolution(self, resolution):
def rfactor(self):
"""The Pdb's R-factor.
:raises TypeError: if a non-numeric rfactor is given.
:rtype: ``float``"""

return self._rfactor


@rfactor.setter
def rfactor(self, rfactor):
if not isinstance(rfactor, (int, float)):
raise TypeError("R-factor {} isn't numeric".format(rfactor))
self._rfactor = rfactor


@property
def organism(self):
"""The Pdb's source organism.
:raises TypeError: if a non-str organism is given.
:rtype: ``str``"""

return self._organism


@organism.setter
def organism(self, organism):
if not isinstance(organism, str):
raise TypeError("PDB organism {} is not str".format(organism))
self._organism = organism


@property
def expression_system(self):
"""The Pdb's expression organism.
:raises TypeError: if a non-str organism is given.
:rtype: ``str``"""

return self._expression_system


@expression_system.setter
def expression_system(self, expression_system):
if not isinstance(expression_system, str):
raise TypeError(
"PDB expression organism {} is not str".format(expression_system)
)
self._expression_system = expression_system


@property
def technique(self):
"""The Pdb's experimental technique.
:raises TypeError: if a non-str technique is given.
:rtype: ``str``"""

return self._technique


@technique.setter
def technique(self, technique):
if not isinstance(technique, str):
raise TypeError("Technique {} is not str".format(technique))
self._technique = technique


@property
def classification(self):
"""The Pdb's classification.
:raises TypeError: if a non-str classification is given.
:rtype: ``str``"""

return self._classification


@classification.setter
def classification(self, classification):
if not isinstance(classification, str):
raise TypeError(
"Classification {} is not str".format(classification)
)
self._classification = classification


Expand Down
41 changes: 21 additions & 20 deletions atomium/files/pdb2pdbdict.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
dictionaries."""

from .pdbstring2pdbdict import atoms_to_chains, atoms_to_residues
from ..structures.molecules import CODES
from ..models.data import CODES

def pdb_to_pdb_dict(pdb):
"""Converts a :py:class:`.Pdb` to a data ``dict``
"""Converts a :py:class:`.Pdb` to a data ``dict``.
:param Pdb pdb: The Pdb to save..
:param Pdb pdb: The Pdb to save.
:rtype: ``dict``"""

pdb_dicts = [structure_to_pdb_dict(model) for model in pdb._models]
Expand All @@ -29,21 +29,20 @@ def pdb_to_pdb_dict(pdb):


def structure_to_pdb_dict(structure):
"""Converts an :py:class:`.AtomicStructure` to a model ``dict``
"""Converts an :py:class:`.AtomStructure` to a model ``dict``.
:param AtomicStructure structure: the structure to convert.
:param AtomStructure structure: the structure to convert.
:rtype: ``dict``"""

atoms, heteroatoms = [], []
structure_atoms = sorted(
structure.atoms(), key=lambda a: a.id
)
for atom in structure_atoms:
list_ = heteroatoms if atom.chain is None else atoms
list_ = heteroatoms if atom.residue is None else atoms
list_.append(atom_to_atom_dict(atom))
chains = atoms_to_chains(atoms)
molecules = atoms_to_residues(heteroatoms)
model = {"chains": chains, "molecules": molecules}
chains = atoms_to_chains(atoms, heteroatoms)
model = {"chains": chains}
connections = structure_to_connections(structure)
return {
"models": [model], "connections": connections,
Expand All @@ -54,7 +53,7 @@ def structure_to_pdb_dict(structure):


def atom_to_atom_dict(atom):
"""Converts an :py:class:`.Atom` to an atom ``dict``
"""Converts an :py:class:`.Atom` to an atom ``dict``.
:param Atom atom: the atom to convert.
:rtype: ``dict``"""
Expand All @@ -66,10 +65,10 @@ def atom_to_atom_dict(atom):
chain_id = atom.chain.id if atom.chain is not None else ""
residue_id = int("".join([c for c in id_ if c.isdigit()]))
insert_code = id_[-1] if id_ and id_[-1].isalpha() else ""
elif atom.molecule:
id_ = atom.molecule.id
residue_name = atom.molecule.name
chain_id = id_[0] if id_ and id_[0].isalpha() else None
elif atom.ligand:
id_ = atom.ligand.id
residue_name = atom.ligand.name
chain_id = atom.chain.id if atom.chain is not None else ""
residue_id = int("".join([c for c in id_ if c.isdigit()]))
return {
"atom_id": atom.id, "atom_name": atom.name, "alt_loc": None,
Expand All @@ -83,18 +82,18 @@ def atom_to_atom_dict(atom):


def structure_to_connections(structure):
"""Gets a connections ``list`` from an :py:class:`.AtomicStructure`. Only
"""Gets a connections ``list`` from an :py:class:`.AtomStructure`. Only
atoms that are not part of residues will have their bonds used.
:param AtomicStructure structure: The structure to use.
:param AtomStructure structure: The structure to use.
:rtype: ``list``"""

connections = []
for atom in structure.atoms():
if not atom.residue:
connections.append({
"atom": atom.id,
"bond_to": sorted([a.id for a in atom.bonded_atoms()])
"bond_to": sorted([a.id for a in atom.bonded_atoms])
})
return sorted(connections, key=lambda k: k["atom"])

Expand All @@ -104,10 +103,12 @@ def sequences_from_model(model):
:param Model model: the model to parse.
:rtype: ``dict``"""

sequences = {}
lookup = {v: k for k, v in CODES.items()}
lookup = {v: k for k, v in CODES.items() if k not in ["HIP", "HIE"]}
for chain in model.chains():
if chain.rep_sequence:
sequences[chain.id] = [lookup.get(c, "???") for c in chain.rep_sequence]
sequences[chain.id] = [
lookup.get(c, "???") for c in chain.rep_sequence
]
return sequences
43 changes: 21 additions & 22 deletions atomium/files/pdbdict2pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
objects."""

from .pdb import Pdb
from ..structures import Model, Chain, Residue, Molecule, Atom
from ..structures.molecules import CODES
from ..structures.reference import bonds
from ..models import Model, Chain, Residue, Ligand, Atom
from ..models.data import CODES, BONDS

def pdb_dict_to_pdb(pdb_dict):
"""Converts a data ``dict`` to a :py:class:`.Pdb`
"""Converts a data ``dict`` to a :py:class:`.Pdb`.
:param dict pdb_dict: The data dictionary to load.
:rtype: :py:class:`.Pdb`"""
Expand All @@ -30,7 +29,7 @@ def pdb_dict_to_pdb(pdb_dict):


def model_dict_to_model(model_dict, connections, sequences):
"""Converts a model ``dict`` to a :py:class:`.Model`
"""Converts a model ``dict`` to a :py:class:`.Model`.
:param dict model_dict: The model dictionary to load.
:param dict connections: The connections dictionary to use.
Expand All @@ -40,54 +39,54 @@ def model_dict_to_model(model_dict, connections, sequences):
model = Model()
for chain in model_dict["chains"]:
model.add(chain_dict_to_chain(chain, sequences))
for molecule in model_dict["molecules"]:
model.add(residue_dict_to_residue(molecule, molecule=True))
bond_atoms(model, connections)
return model


def chain_dict_to_chain(chain_dict, sequences):
"""Converts a chain ``dict`` to a :py:class:`.Chain`
"""Converts a chain ``dict`` to a :py:class:`.Chain`.
:param dict chain_dict: The chain dictionary to load.
:param dict sequences: The sequences dictionary to use.
:rtype: :py:class:`.Chain`"""

residues = [residue_dict_to_residue(res) for res in chain_dict["residues"]]
ligands = [residue_dict_to_residue(lig, ligand=True)
for lig in chain_dict["ligands"]]
hets = residues + ligands
for index, residue in enumerate(residues[:-1]):
residue.next = residues[index + 1]
rep = "".join(CODES.get(res, "X") for res in sequences.get(chain_dict["chain_id"], []))
return Chain(*residues, id=chain_dict["chain_id"], rep=rep)
rep = "".join(CODES.get(res, "X")
for res in sequences.get(chain_dict["chain_id"], []))
return Chain(*hets, id=chain_dict["chain_id"], rep=rep)


def residue_dict_to_residue(residue_dict, molecule=False):
def residue_dict_to_residue(residue_dict, ligand=False):
"""Converts a residue ``dict`` to a :py:class:`.Residue` or
:py:class:`.Molecule`.
:py:class:`.Ligand`.
:param dict residue_dict: The residue dictionary to load.
:param bool molecule: if ``True``, a :py:class:`.Molecule` will be returned\
:param bool ligand: if ``True``, a :py:class:`.Ligand` will be returned\
instead of a :py:class:`.Residue`.
:rtype: :py:class:`.Residue` or :py:class:`.Molecule`"""
:rtype: :py:class:`.Residue` or :py:class:`.Ligand`"""

alt_loc = None
if any([atom["occupancy"] < 1 for atom in residue_dict["atoms"]]):
if any([atom["alt_loc"] for atom in residue_dict["atoms"]]):
alt_loc = sorted([
atom["alt_loc"] for atom in residue_dict["atoms"] if atom["alt_loc"]
])[0]
alt_loc = sorted([atom["alt_loc"]
for atom in residue_dict["atoms"] if atom["alt_loc"]])[0]
atoms = [
atom_dict_to_atom(atom) for atom in residue_dict["atoms"]
if atom["occupancy"] ==1 or atom["alt_loc"] is None
or atom["alt_loc"] == alt_loc
]
MolClass = Molecule if molecule else Residue
residue = MolClass(*atoms, name=residue_dict["name"])
residue._id = residue_dict["id"]
MolClass = Ligand if ligand else Residue
residue = MolClass(*atoms, name=residue_dict["name"], id=residue_dict["id"])
return residue


def atom_dict_to_atom(atom_dict):
"""Converts an atom ``dict`` to a :py:class:`.Atom`
"""Converts an atom ``dict`` to a :py:class:`.Atom`.
:param dict atom_dict: The atom dictionary to load.
:rtype: :py:class:`.Atom`"""
Expand All @@ -105,7 +104,7 @@ def bond_atoms(model, connections):
:param Model model: The ``Model`` to be connected up."""

make_intra_residue_bonds(model.residues(), bonds)
make_intra_residue_bonds(model.residues(), BONDS)
make_inter_residue_bonds(model.residues())
make_connections_bonds(model, connections)

Expand Down
Loading

0 comments on commit 7d32a27

Please sign in to comment.