File: model.py

package info (click to toggle)
python-modelcif 1.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 688 kB
  • sloc: python: 6,746; makefile: 14; sh: 6
file content (135 lines) | stat: -rw-r--r-- 5,141 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import ihm.representation
from ihm.model import Atom, ModelGroup  # noqa: F401
import modelcif.data
from ihm.util import _check_residue_range


# Provide ma-specific docs for Atom
Atom.__doc__ = """Coordinates of part of the model represented by an atom.

See :meth:`Model.get_atoms` for more details.

:param asym_unit: The asymmetric unit that this atom represents
:type asym_unit: :class:`modelcif.AsymUnit`
:param int seq_id: The residue index represented by this atom
       (can be None for HETATM sites)
:param str atom_id: The name of the atom in the residue
:param str type_symbol: Element name
:param float x: x coordinate of the atom
:param float y: y coordinate of the atom
:param float z: z coordinate of the atom
:param bool het: True for HETATM sites, False (default) for ATOM
:param float biso: Temperature factor or equivalent (if applicable)
:param float occupancy: Fraction of the atom type present
       (if applicable)
"""

# Provide ma-specific docs for ModelGroup
ModelGroup.__doc__ = """A set of related models. See :class:`Model`.
It is implemented as a simple list of the models.

These objects are typically stored directly in the system; see
:attr:`modelcif.System.model_groups`.

:param elements: Initial set of models in the group.
:param str name: Descriptive name for the group.
"""


class Model(modelcif.data.Data):
    """Base class for coordinates of a single structure.
       Use a subclass such as :class:`HomologyModel` or
       :class:`AbInitioModel`, or represent a custom model type by
       creating a new subclass and providing a docstring to describe it, e.g.::

           class CustomModel(Model):
               "custom model type"

       :param assembly: The :class:`modelcif.AsymUnit` objects that make up
              this model.
       :type assembly: :class:`modelcif.Assembly`
       :param str name: Short name for this model.
    """
    data_content_type = 'model coordinates'
    model_type = "Other"

    def __init__(self, assembly, name=None):
        modelcif.data.Data.__init__(self, name)
        self.assembly = assembly
        # Assume everything is atomic for ModelCIF models
        self.representation = ihm.representation.Representation(
            [ihm.representation.AtomicSegment(seg, rigid=False)
             for seg in assembly])
        self._atoms = []

        #: List of residue ranges that were explicitly not modeled. See
        #: :class:`NotModeledResidueRange`.
        self.not_modeled_residue_ranges = []

        #: Quality scores for the model or part of it (a simple list of
        #: metric objects; see :mod:`modelcif.qa_metric`)
        self.qa_metrics = []

    def _get_other_details(self):
        if (type(self) is not Model
                and self.model_type == Model.model_type):
            return self.__doc__.split('\n')[0]

    other_details = property(
        _get_other_details,
        doc="More information about a custom model type. "
            "By default it is the first line of the docstring.")

    def get_atoms(self):
        """Yield :class:`Atom` objects that represent this model.

           The default implementation simply iterates over an internal
           list of atoms, but this is not very memory-efficient, particularly
           if the atoms are already stored somewhere else, e.g. in the
           software's own data structures. It is recommended to subclass
           and provide a more efficient implementation. For example,
           `the modbase_pdb_to_cif script <https://github.com/salilab/modbase_utils/blob/main/modbase_pdb_to_cif.py>`_
           uses a custom ``MyModel`` subclass that creates Atom objects on
           the fly from PDB ATOM or HETATM lines.
        """  # noqa: E501
        for a in self._atoms:
            yield a

    def add_atom(self, atom):
        self._atoms.append(atom)


class HomologyModel(Model):
    """Coordinates of a single structure generated using homology
       or comparative modeling.

       See :class:`Model` for a description of the parameters.
    """
    model_type = "Homology model"
    other_details = None


class AbInitioModel(Model):
    """Coordinates of a single structure generated using ab initio modeling.

       See :class:`Model` for a description of the parameters.
    """
    model_type = "Ab initio model"
    other_details = None


class NotModeledResidueRange:
    """A range of residues that were explicitly not modeled.
       See :attr:`Model.not_modeled_residue_ranges`.
       These ranges are not explicitly stored in the mmCIF file,
       but they will be excluded from the ``pdbx_poly_seq_scheme`` table.

       :param asym_unit: The asymmetric unit to which the residues belong.
       :type asym_unit: :class:`~modelcif.AsymUnit`
       :param int seq_id_begin: Starting residue in the range.
       :param int seq_id_end: Ending residue in the range.
    """
    def __init__(self, asym_unit, seq_id_begin, seq_id_end):
        self.asym_unit = asym_unit
        self.seq_id_begin, self.seq_id_end = seq_id_begin, seq_id_end
        _check_residue_range((seq_id_begin, seq_id_end), asym_unit.entity)