Source code for pybel_tools.filters.node_filters

# -*- coding: utf-8 -*-

"""
Node Filters
------------

A node filter is a function that takes two arguments: a :class:`pybel.BELGraph` and a node tuple. It returns a boolean
representing whether the node passed the given test.

This module contains a set of default functions for filtering lists of nodes and building node filtering functions.

A general use for a node filter function is to use the built-in :func:`filter` in code like
:code:`filter(your_node_filter, graph)`
"""

from collections import Iterable

from pybel.constants import FUNCTION, LABEL, NAMESPACE, PATHOLOGY
from pybel.struct.filters import build_node_data_search, build_node_key_search, data_missing_key_builder
from pybel.struct.filters.node_filters import count_passed_node_filter

__all__ = [
    'summarize_node_filter',
    'node_inclusion_filter_builder',
    'node_exclusion_filter_builder',
    'function_inclusion_filter_builder',
    'function_exclusion_filter_builder',
    'function_namespace_inclusion_builder',
    'namespace_inclusion_builder',
    'data_contains_key_builder',
    'data_missing_key_builder',
    'node_has_label',
    'node_missing_label',
    'include_pathology_filter',
    'exclude_pathology_filter',
    'build_node_data_search',
    'build_node_key_search',
]


[docs]def summarize_node_filter(graph, node_filters): """Prints a summary of the number of nodes passing a given set of filters :param pybel.BELGraph graph: A BEL graph :param node_filters: A node filter or list/tuple of node filters :type node_filters: types.FunctionType or iter[types.FunctionType] """ passed = count_passed_node_filter(graph, node_filters) print('{}/{} nodes passed'.format(passed, graph.number_of_nodes()))
# Example filters
[docs]def node_inclusion_filter_builder(nbunch): """Builds a filter that only passes on nodes in the given list :param iter[tuple] nbunch: An iterable of BEL nodes :return: A node filter (graph, node) -> bool :rtype: types.FunctionType """ node_set = set(nbunch) def inclusion_filter(graph, node): """Passes only for a node that is in the enclosed node list :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node is contained within the enclosed node list :rtype: bool """ return node in node_set return inclusion_filter
[docs]def node_exclusion_filter_builder(nodes): """Builds a filter that fails on nodes in the given list :param nodes: A list of nodes :type nodes: list :return: A node filter (graph, node) -> bool :rtype: types.FunctionType """ node_set = set(nodes) def exclusion_filter(graph, node): """Passes only for a node that isn't in the enclosed node list :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node isn't contained within the enclosed node list :rtype: bool """ return node not in node_set return exclusion_filter
def _single_function_inclusion_filter_builder(func): def function_inclusion_filter(graph, node): """Pass only for a node that has the enclosed function. :param BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node doesn't have the enclosed function :rtype: bool """ return node[FUNCTION] == func return function_inclusion_filter def _collection_function_inclusion_builder(funcs): funcs = set(funcs) def functions_inclusion_filter(graph, node): """Pass only for a node that is one of the enclosed functions. :param BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node doesn't have the enclosed functions :rtype: bool """ return node[FUNCTION] in funcs return functions_inclusion_filter
[docs]def function_inclusion_filter_builder(func): """Build a filter that only passes on nodes of the given function(s). :param func: A BEL Function or list/set/tuple of BEL functions :type func: str or iter[str] :return: A node predicate :rtype: (pybel.BELGraph, tuple) -> bool """ if isinstance(func, str): return _single_function_inclusion_filter_builder(func) elif isinstance(func, Iterable): return _collection_function_inclusion_builder(func) raise ValueError('Invalid type for argument: {}'.format(func))
[docs]def function_exclusion_filter_builder(func): """Build a filter that fails on nodes of the given function(s). :param func: A BEL Function or list/set/tuple of BEL functions :type func: str or list[str] or tuple[str] or set[str] :return: A node predicate :rtype: (pybel.BELGraph, tuple) -> bool """ if isinstance(func, str): def function_exclusion_filter(graph, node): """Pass only for a node that doesn't have the enclosed function. :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node doesn't have the enclosed function :rtype: bool """ return node[FUNCTION] != func return function_exclusion_filter elif isinstance(func, Iterable): functions = set(func) def functions_exclusion_filter(graph, node): """Pass only for a node that doesn't have the enclosed functions. :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node doesn't have the enclosed functions :rtype: bool """ return node[FUNCTION] not in functions return functions_exclusion_filter raise ValueError('Invalid type for argument: {}'.format(func))
[docs]def function_namespace_inclusion_builder(func, namespace): """Build a filter function for matching the given BEL function with the given namespace or namespaces. :param str func: A BEL function :param str or iter[str] namespace: The namespace to serach by :return: A node predicate :rtype: (pybel.BELGraph, tuple) -> bool """ if isinstance(namespace, str): def function_namespace_filter(graph, node): """Passes only for nodes that have the enclosed function and enclosed namespace :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :rtype: bool """ if func != node[FUNCTION]: return False return NAMESPACE in node and node[NAMESPACE] == namespace return function_namespace_filter elif isinstance(namespace, Iterable): namespaces = set(namespace) def function_namespaces_filter(graph, node): """Passes only for nodes that have the enclosed function and namespace in the enclose set :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :rtype: bool """ if func != node[FUNCTION]: return False return NAMESPACE in node and node[NAMESPACE] in namespaces return function_namespaces_filter raise ValueError('Invalid type for argument: {}'.format(namespace))
[docs]def namespace_inclusion_builder(namespace): """Build a predicate for namespace inclusion. :param str or iter[str] namespace: A namespace or iter of namespaces :return: A node predicate :rtype: (pybel.BELGraph, tuple) -> bool """ if isinstance(namespace, str): def namespace_filter(graph, node): """Passes only for a node that has the enclosed namespace :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :rtype: bool """ return NAMESPACE in node and node[NAMESPACE] == namespace return namespace_filter elif isinstance(namespace, Iterable): namespaces = set(namespace) def namespaces_filter(graph, node): """Pass only for a node that has a namespace in the enclosed set. :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :rtype: bool """ return NAMESPACE in node and node[NAMESPACE] in namespaces return namespaces_filter raise ValueError('Invalid type for argument: {}'.format(namespace))
[docs]def data_contains_key_builder(key): """Build a filter that passes only on nodes that have the given key in their data dictionary. :param str key: A key for the node's data dictionary :return: A node predicate :rtype: (pybel.BELGraph, tuple) -> bool """ def data_contains_key(graph, node): """Pass only for a node that contains the enclosed key in its data dictionary. :param pybel.BELGraph graph: A BEL Graph :param BaseEntity node:: A BEL node :return: If the node contains the enclosed key in its data dictionary :rtype: bool """ return key in node return data_contains_key
#: Passes for nodes that have been annotated with a label node_has_label = data_contains_key_builder(LABEL) #: Fails for nodes that have been annotated with a label node_missing_label = data_missing_key_builder(LABEL) # Default Filters #: A filter that passes for nodes that are :data:`pybel.constants.PATHOLOGY` include_pathology_filter = function_inclusion_filter_builder(PATHOLOGY) #: A filter that fails for nodes that are :data:`pybel.constants.PATHOLOGY` exclude_pathology_filter = function_exclusion_filter_builder(PATHOLOGY) # TODO node filter that is false for abundances with no in-edges