Source code for vermouth.selectors

# Copyright 2018 University of Groningen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Provides helper function for selecting part of a system, e.g. all proteins, or
protein backbones.
"""

import numpy as np
from .molecule import attributes_match


# TODO: Make that list part of the force fields
PROTEIN_RESIDUES = set(('ALA', 'ARG', 'ASP', 'ASN', 'CYS',
                        'GLU', 'GLN', 'GLY', 'HIS', 'ILE',
                        'LEU', 'LYS', 'MET', 'PHE', 'PRO',
                        'SER', 'THR', 'TRP', 'TYR', 'VAL',
                        'HSE', 'HIE', 'HSD', 'HID', 'HSP',
                        'HIP', 'ASPP', 'GLUP', 'LSN', 'ASH',
                        'GLH', 'LYN'))


[docs] def is_protein(molecule): """ Return True if all the residues in the molecule are protein residues. The function tests if the residue name of all the atoms in the input molecule are in ``PROTEIN_RESIDUES``. Parameters ---------- molecule: Molecule The molecule to test. Returns ------- bool """ return all( molecule.nodes[n_idx].get('resname') in PROTEIN_RESIDUES for n_idx in molecule )
[docs] def select_all(_): """ Returns True for all particles. """ return True
# TODO: Have the backbone definition be force field specific.
[docs] def select_backbone(node): """ Returns True if `node` is in a protein backbone. """ return node.get('atomname') == 'BB'
[docs] def selector_has_position(atom): """ Return True if the atom have a position. An atom is considered as not having a position if: * the "position" key is not defined; * the value of "position" is ``None``; * the coordinates are not finite numbers. Parameters ---------- atom: dict Returns ------- bool """ position = atom.get('position') return position is not None and np.all(np.isfinite(position))
[docs] def proto_select_attribute_in(node, attribute, values): """ Return True if the given attribute of the node is in a list of values. To be used as a selector, the function must be wrapped in a way that it can be called without the need to explicitly specify the 'attribute' and 'values' arguments. This can be done using :func:`functools.partial`: >>> # select an atom if its name is in a given list >>> to_keep = ['BB', 'SC1'] >>> select_name_in = functools.partial( ... proto_select_attribute_in, ... attribute='atomname', ... values=to_keep ... ) >>> select_name_in(node) Parameters ---------- node: dict The atom/node to consider. attribute: str The key to look at in the node. values: list The values the node attribute can take for the node to be selected. Returns ------- bool """ return node.get(attribute) in values
[docs] def proto_multi_templates(node, templates, ignore_keys=()): """ Return `True` is the node matched one of the templates. Parameters ---------- node: dict The atom/node to consider. templates: collections.abc.Iterable[dict] A list of node templates to compare to the node. ignore_keys: collections.abc.Collection List of keys to ignore from the templates. Returns ------- bool See Also -------- vermouth.molecule.attributes_match """ return any( attributes_match(node, template, ignore_keys) for template in templates )
[docs] def filter_minimal(molecule, selector): """ Yield the atom keys that match the selector. The selector must be a function that accepts an atom as a argument. The atom is passed as a node attribute dictionary. The selector must return ``True`` for atoms to keep in the selection. The function can be used to build a subgraph that only contains the selection: .. code-block:: python selection = molecule.subgraph( filter_minimal(molecule, selector_function) ) Parameters ---------- molecule: Molecule selector: collections.abc.Callable Yields ------ collections.abc.Hashable: Keys of the atoms that match the selection. """ for name, atom in molecule.nodes.items(): if selector(atom): yield name