Source code for prody.atomic.fields

# -*- coding: utf-8 -*-
"""This module defines atomic data fields.  You can read this page in
interactive sessions using ``help(fields)``.

Data parsed from PDB and other supported files for these fields are stored in
:class:`.AtomGroup` instances.  Available data fields are listed in the table
below.  :class:`Atomic` classes, such as :class:`.Selection`, offer ``get`` and
``set`` for handling parsed data:

"""

from numpy import array

from prody.utilities import wrapText, DTYPE

from .flags import FIELDS as FLAG_FIELDS

__all__ = ['Field']

READONLY = set()


[docs]class Field(object): """Atomic data field.""" __slots__ = ['name', 'dtype', 'doc', 'doc_pl', 'meth', 'meth_pl', 'ndim', 'none', 'selstr', 'synonym', 'readonly', 'call', 'private', 'depr', 'depr_pl', 'desc', 'flags'] def __init__(self, name, dtype, **kwargs): #: data field name used in atom selections self.name = name #: data type (primitive Python types) self.dtype = dtype #: internal variable name used as key for :class:`.AtomGroup` ``_data`` self.doc = kwargs.get('doc', name) #: plural form for documentation self.doc_pl = kwargs.get('doc_pl', self.doc + 's') #: description of data field, used in documentation self.desc = kwargs.get('desc') #: expected dimension of the data array self.ndim = kwargs.get('ndim', 1) #: atomic get/set method name self.meth = kwargs.get('meth', name.capitalize()) #: get/set method name in plural form self.meth_pl = kwargs.get('meth_pl', self.meth + 's') #: :class:`.AtomGroup` attributes to be set None, when ``setMethod`` #: is called self.none = kwargs.get('none') #: list of selection string examples self.selstr = kwargs.get('selstr') #: deprecated method name self.depr = kwargs.get('depr') #: deprecated method name in plural form self.depr_pl = None if self.depr is not None: self.depr_pl = kwargs.get('depr_pl', self.depr + 's') #: synonym used in atom selections self.synonym = kwargs.get('synonym') #: read-only attribute without a set method self.readonly = kwargs.get('readonly', False) #: list of :class:`.AtomGroup` methods to call when ``getMethod`` is #: called self.call = kwargs.get('call', None) #: define only _getMethod for :class:`.AtomGroup` to be used by #: :class:`.Select` class self.private = kwargs.get('private', False) #: **True** when there are flags associated with the data field self.flags = kwargs.get('flags', False) if self.readonly: READONLY.add(self.name)
[docs] def getDocstr(self, meth, plural=True, selex=True): """Returns documentation string for the field.""" assert meth in ('set', 'get', '_get'), "meth must be 'set' or 'get'" assert isinstance(plural, bool), 'plural must be a boolean' assert isinstance(selex, bool), 'selex must be a boolean' if meth == 'get': if plural: docstr = 'Return a copy of {0}.'.format(self.doc_pl) else: docstr = 'Return {0} of the atom.'.format(self.doc) elif meth == 'set': if plural: docstr = 'Set {0}.'.format(self.doc_pl) else: docstr = 'Set {0} of the atom.'.format(self.doc) else: selex = False if plural: docstr = 'Return {0} array.'.format(self.doc_pl) if self.desc: docstr += ' ' + self.desc selstr = self.selstr if selex and selstr: if plural: doc = self.doc_pl else: doc = self.doc if '(' in doc: doc = doc[:doc.index('(')] selex = "``, ``".join([repr(s) for s in selstr]) selex = (" {0} can be used in atom selections, e.g. " "``{1}``.").format(doc.capitalize(), selex) if self.synonym is not None: selex = selex + (' Note that *{0}* is a synonym for ' '*{1}*.').format(self.synonym, self.name) return wrapText(docstr + selex) else: return wrapText(docstr)
HVNONE = ['_hv', 'segindex', 'chindex', 'resindex'] ATOMIC_FIELDS = { 'name': Field('name', DTYPE + '6', selstr=('name CA CB',)), 'altloc': Field('altloc', DTYPE + '1', doc='alternate location indicator', selstr=('altloc A B', 'altloc _'),), 'anisou': Field('anisou', float, doc='anisotropic temperature factor', ndim=2), 'chain': Field('chain', DTYPE + '2', doc='chain identifier', meth='Chid', none=HVNONE, synonym='chid', selstr=('chain A', 'chid A B C', 'chain _')), 'element': Field('element', DTYPE + '2', doc='element symbol', selstr=('element C O N',)), 'occupancy': Field('occupancy', float, doc='occupancy value', meth_pl='Occupancies', selstr=('occupancy 1', 'occupancy > 0')), 'resname': Field('resname', DTYPE + '6', doc='residue name', selstr=('resname ALA GLY',)), 'resnum': Field('resnum', int, doc='residue number', none=HVNONE, selstr=('resnum 1 2 3', 'resnum 120A 120B', 'resnum 10 to 20', 'resnum 10:20:2', 'resnum < 10'), synonym='resid'), 'secondary': Field('secondary', DTYPE + '1', doc='secondary structure assignment', meth='Secstr', synonym='secstr', selstr=('secondary H E', 'secstr H E'), ), 'secid': Field('secid', DTYPE + '3', doc='secondary structure identifier', meth='Secid', selstr=('secid A B', 'secid 1 2') ), 'secclass': Field('secclass', int, doc='secondary structure class', meth='Secclass', meth_pl='Secclasses', selstr=('secclass 2', 'secclass -1') ), 'secindex': Field('secindex', int, doc='secondary structure index', meth='Secindex', meth_pl='Secindices', selstr=('secindex 2') ), 'segment': Field('segment', DTYPE + '6', doc='segment name', meth='Segname', selstr=('segment PROT', 'segname PROT'), synonym='segname', none=HVNONE), 'siguij': Field('siguij', float, doc='standard deviations for ' 'anisotropic temperature factor', meth='Anistd', ndim=2), 'serial': Field('serial', int, doc='serial number (from file)', doc_pl='serial numbers (from file)', none=['_sn2i'], selstr=('serial 1 2 3', 'serial 1 to 10', 'serial 1:10:2', 'serial < 10')), 'beta': Field('beta', float, doc='β-value (temperature factor)', doc_pl='β-values (or temperature factors)', selstr=('beta 555.55', 'beta 0 to 500', 'beta 0:500', 'beta < 500')), 'icode': Field('icode', DTYPE + '1', doc='insertion code', none=HVNONE, selstr=('icode A', 'icode _')), 'type': Field('type', DTYPE + '6', selstr=('type CT1 CT2 CT3',)), 'charge': Field('charge', float, doc='partial charge', selstr=('charge 1', 'abs(charge) == 1', 'charge < 0')), 'mass': Field('mass', float, doc_pl='masses', meth_pl='Masses', selstr=('12 <= mass <= 13.5',)), 'radius': Field('radius', float, doc='radius', doc_pl='radii', meth_pl='Radii', selstr=('radii < 1.5', 'radii ** 2 < 2.3')), 'resindex': Field('resindex', int, doc='residue index', doc_pl='residue indices', meth_pl='Resindices', selstr=('resindex 0',), readonly=True, call=['getHierView'], desc='Residue indices are assigned to subsets of atoms ' 'with distinct sequences of residue number, ' 'insertion code, chain identifier, and segment ' 'name. Residue indices start from zero, are ' 'incremented by one, and are assigned in the ' 'order of appearance in :class:`.AtomGroup` ' 'instance.'), 'chindex': Field('chindex', int, doc='chain index', doc_pl='chain indices', meth_pl='Chindices', selstr=('chindex 0',), readonly=True, call=['getHierView'], desc='Chain indices are assigned to subsets of atoms ' 'with distinct pairs of chain identifier and ' ' segment name. Chain indices start from zero, ' 'are incremented by one, and are assigned in the ' 'order of appearance in :class:`.AtomGroup` ' 'instance.'), 'segindex': Field('segindex', int, doc='segment index', doc_pl='segment indices', meth_pl='Segindices', selstr=['segindex 0'], readonly=True, call=['getHierView'], desc='Segment indices are assigned to subsets of atoms ' 'with distinct segment names. Segment indices ' 'start from zero, are incremented by one, and are ' 'assigned in the order of appearance in ' ':class:`.AtomGroup` instance.'), 'fragindex': Field('fragindex', int, doc='fragment index', doc_pl='fragment indices', meth_pl='Fragindices', selstr=['fragindex 0', 'fragment 1'], readonly=True, call=['_fragment'], synonym='fragment', desc='Fragment indices are assigned to connected ' 'subsets of atoms. Bonds needs to be set using ' ':meth:`.AtomGroup.setBonds` or :meth:`.AtomGroup.inferBonds`. ' 'Fragment indices start from zero, are incremented by ' 'one, and are assigned in the order of appearance ' 'in :class:`.AtomGroup` instance.'), 'numbonds': Field('numbonds', int, meth_pl='Numbonds', doc='number of bonds', selstr=['numbonds 0', 'numbonds 1'], readonly=True, private=True), } __doc__ += """ Many of these data fields can be used to make :ref:`selections`. Following table lists definitions of fields and selection examples. Note that fields noted as *read only* do not have a ``set`` method. .. glossary:: """ keys = list(ATOMIC_FIELDS.keys()) keys.sort() for key in keys: field = ATOMIC_FIELDS[key] __doc__ += '\n\n ' + key + '\n' if field.synonym: __doc__ += ' ' + field.synonym + '\n' __doc__ += wrapText(field.doc + (' *(read only)*' if field.readonly else ''), indent=6) if field.selstr: sel = "\n ``'" + "'``,\n ``'".join(field.selstr) + "'``" __doc__ += '\n\n *E.g.:* ' + sel for key in FLAG_FIELDS.keys(): ATOMIC_FIELDS[key].flags = True def wrapGetMethod(fn): def getMethod(self): return fn(self) return getMethod def wrapSetMethod(fn): def setMethod(self, data): return fn(self, data) return setMethod