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
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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
                        '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:[dict] A list of node templates to compare to the node. ignore_keys: 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: Yields ------ Keys of the atoms that match the selection. """ for name, atom in molecule.nodes.items(): if selector(atom): yield name