class ViewerToolBase(ipy.Box):
    """
    The base for most viewer-based widgets - it consists of a viewer in the top-left,
    UI controls on the right, and some additional widgets underneath the viewer
    """
    VIEWERTYPE = viewers.GeometryViewer
    VIEWERWIDTH = '600px'

    selected_atom_indices = utils.Alias('viewer.selected_atom_indices')
    selected_atoms = utils.Alias('viewer.selected_atoms')

    def __init__(self, mol):
        self.mol = mol

        self.toolpane = VBox()
        self.viewer = self.VIEWERTYPE(mol, width=self.VIEWERWIDTH)

        self.subtools = ipy.Box()
        self.viewer_pane = VBox([self.viewer, self.subtools])
        self.main_pane = HBox([self.viewer_pane, self.toolpane])

        super().__init__([self.main_pane])

    def __getattr__(self, item):
        if hasattr(self.viewer, item):
            return getattr(self.viewer, item)
        else:
            raise AttributeError(item)
class _DatabaseEntry(object):
    """ Maps into a field stored in the database
    """
    def __init__(self, hostdb, keyname):
        self.hostdb = hostdb
        self.keyname = keyname
        self.index = self.hostdb['__FIELDS__']['RESFIELDS'].index(keyname)

    def __repr__(self):
        return '<Chemical component dictionary: "%s" entries>' % self.keyname

    def __getitem__(self, item):
        return self.hostdb[item][self.index]

    __contains__ = utils.Alias('hostdb.__contains__')

    def keys(self):
        for key in self.hostdb.keys():
            if key == '__FIELDS__':
                continue
            yield key

    def items(self):
        for key in self:
            yield key, self[key]

    __iter__ = keys
Exemplo n.º 3
0
class AtomPropertyMixin(object):
    """ Functions accessing computed atomic properties.

    Note:
        This is a mixin class designed only to be mixed into the :class:`Atom` class. Routines
        are separated are here for code organization only - they could be included in the main
        Atom class without changing any functionality
    """
    distance = utils.Alias('_container.distance')
    atoms_within = utils.Alias('_container.atoms_within')
    residues_within = utils.Alias('_container.residues_within')

    @utils.args_from(AtomContainer.calc_distance_array)
    def calc_distances(self, *args, **kwargs):
        array = self._container.calc_distance_array(*args, **kwargs)
        return array[0]

    @property
    def _container(self):
        """ AtomContainer: a container with just this atom in it.

        This is a convenience method for accessing to all of the :class:`AtomContainer`'s
        useful methods for dealing with geometry
        """
        return AtomList([self])

    @property
    def ff(self):
        """ moldesign.utils.DotDict: This atom's force field parameters, if available (``None``
        otherwise)
        """
        try:
            ff = self.molecule.energy_model.mdtforcefield
        except AttributeError:
            return None
        if ff is None: return None

        return utils.DotDict(partialcharge=ff.partial_charges[self],
                             lj=ff.lennard_jones[self])

    @property
    def basis_functions(self):
        """ List[mdt.orbitals.AtomicBasisFunction]: This atom's basis functions, if available
        (``None`` otherwise)
        """
        if self.molecule is None:
            return None
        try:
            wfn = self.molecule.wfn
        except mdt.exceptions.NotCalculatedError:
            return None

        return wfn.aobasis.on_atom.get(self, [])

    @property
    def properties(self):
        """ moldesign.utils.DotDict: Returns any calculated properties for this atom
        """
        props = utils.DotDict()
        for name, p in self.molecule.properties.iteritems():
            if hasattr(p, 'type') and p.type == 'atomic':
                props[name] = p[self]
        return props
class ChildList(AtomContainer):
    """ A list of biochemical objects that can be accessed by name or by index.
    """
    __len__ = utils.Alias('_childinorder.__len__')
    __iter__ = utils.Alias('_childinorder.__iter__')
    index = utils.Alias('_childinorder.index')

    def __str__(self):
        return str(self._childinorder._items)

    def __repr__(self):
        try:
            return '<Children of %s: %s>' % (self.parent, self)
        except (KeyError, AttributeError):
            return '<ChildList @ %x (exception in self.__repr__)>' % id(self)

    def __init__(self, parent):
        super(ChildList, self).__init__()
        self.parent = parent
        self._childbyname = {}
        self._childinorder = utils.SortedCollection(key=_sortkey)

    def __dir__(self):
        return self.__dict__.keys() + self.__class__.__dict__.keys(
        ) + self._childbyname.keys()

    def __getitem__(self, item):
        if isinstance(item, basestring):
            return self._childbyname[item]
        else:
            return self._childinorder[item]

    def __setitem__(self, key, val):
        if key in self._childbyname:
            raise KeyError('%s already exists in %s' % (key, self.parent))
        self._childbyname[key] = val
        self._childinorder.insert_right(val)

    def __contains__(self, item):
        if isinstance(item, basestring) or item is None:
            return (item in self._childbyname)
        else:
            return (item in self._childinorder)

    def __getattr__(self, item):
        if item == '_childbyname':
            return self.__getattribute__('_childbyname')

        try:
            return self._childbyname[item]
        except KeyError:
            raise AttributeError(
                'ChildList object in %s has no attribute %s.' %
                (self.parent.__repr__(), item))

    def iteratoms(self):
        """Iterate over all atoms

        Yields:
            Atom: all atoms in this entity and/or its children
        """
        for child in self:
            if isinstance(child, mdt.Atom):
                yield child
            else:
                for atom in child.iteratoms():
                    yield atom

    @property
    def atoms(self):
        """ AtomList: a sorted list of all atoms in this entity and/or its children
        """
        return AtomList(self.iteratoms())

    def rebuild(self):
        self._childbyname = {obj.name: obj for obj in self._childinorder}
class BioContainer(AtomContainer):
    """
    Generalized storage mechanism for hierarchical representation of biomolecules,
    e.g. by residue, chain, etc. Permits other groupings, provided that everything is
    tree-like.

    All children of a given entity must have unique names. An individual child can be retrieved with
    ``biocontainer.childname`` or ``biocontainer['childname']`` or ``biocontainer[index]``

    Yields:
        BioContainer or mdt.Atom: this entity's children, in order
    """

    __getitem__ = utils.Alias('children.__getitem__')
    __len__ = utils.Alias('children.__len__')
    __iter__ = utils.Alias('children.__iter__')
    __contains__ = utils.Alias('children.__contains__')
    atoms = utils.Alias('children.atoms')
    iteratoms = utils.Alias('children.iteratoms')
    rebuild = utils.Alias('children.rebuild')

    def __init__(self,
                 name=None,
                 molecule=None,
                 index=None,
                 pdbname=None,
                 pdbindex=None,
                 **kwargs):
        """  Initialization:

        Args:
            name (str): Name of this biocontainer
            parent (mdt.Molecule): molecule this biocontainer belongs to
            index (int): index of this biocontainer in the parent molecule
            pdbname (str): PDB-format name of this biocontainer
            pdbindex (str): Index of this biocontainer in PDB format
        """
        super(BioContainer, self).__init__()
        self.children = ChildList(self)
        self.molecule = molecule
        self.name = name
        self.index = index

        self.pdbname = pdbname
        self.pdbindex = pdbindex

        for name, val in kwargs.iteritems():
            setattr(self, name, val)

    def add(self, item, key=None):
        """ Add a child to this entity.

        Raises:
            KeyError: if an object with this key already exists

        Args:
            item (BioContainer or mdt.Atom): the child object to add
            key (str): Key to retrieve this item (default: ``item.name`` )
        """
        if key is None:
            key = item.name
        self.children[key] = item

    __setitem__ = add

    def __dir__(self):
        return (self.__dict__.keys() + self.__class__.__dict__.keys() +
                [x.name for x in self.children])

    def __hash__(self):
        """ Explicitly hash by object id
        """
        return id(self)

    def __eq__(self, other):
        return self is other

    def __repr__(self):
        try:
            if self.molecule is not None:
                return '<%s in %s>' % (self, self.molecule)
            else:
                return '<%s (no molecule)>' % self
        except (KeyError, AttributeError):
            return '<%s at %s (exception in __repr__)>' % (
                self.__class__.__name__, id(self))

    def __str__(self):
        return '%s %s (index=%s)' % (self.__class__.__name__, self.name,
                                     str(self.index))

    def __call__(self, **kwargs):
        """
        Allow for some simple queries, i.e. mol.chain['A'].residue(pdbname='ALA')
        """
        retlist = []
        for child in self:
            for key, val in kwargs.iteritems():
                if hasattr(child, key) and getattr(child, key) == val:
                    retlist.append(child)
        return retlist