Skip to content

Commit

Permalink
Added rewiring testing
Browse files Browse the repository at this point in the history
References #27
  • Loading branch information
cthoyt committed Mar 15, 2017
1 parent 2ab1046 commit 80cda99
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 1 deletion.
58 changes: 58 additions & 0 deletions src/pybel_tools/selection/rewiring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-

"""
This module has functions that help produce random permutations over networks.
Random permutations are useful in statistical testing over aggregate statistics.
"""

import random

from ..utils import is_edge_consistent


def all_edges_consistent(graph):
"""Returns if all edges are consistent in a graph. Wraps :func:`pybel_tools.utils.is_edge_consistent`
:param graph: A BEL graph
:type graph: pybel.BELGraph
:return: Are all edges consistent
:rtype: bool
"""
return all(is_edge_consistent(graph, u, v) for u, v in graph.edges_iter())


def rewire_targets(graph, p):
"""Rewires a graph's edges' target nodes
- For BEL graphs, assumes edge consistency (all edges between two given nodes are have the same relation)
- Doesn't make self-edges
:param graph: A BEL graph
:type graph: pybel.BELGraph
:param p: The probability of rewiring
:return: A rewired BEL graph
"""

if not all_edges_consistent(graph):
raise ValueError('{} is not consistent'.format(graph))

bg = graph.copy()
nodes = bg.nodes()

for u, v in bg.edges():
if random.random() < p:
continue

w = random.choice(nodes)

while w == u or bg.has_edge(u, w):
w = random.choice(nodes)

bg.add_edge(w, v)
bg.remove_edge(u, v)

return bg
40 changes: 39 additions & 1 deletion src/pybel_tools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pandas import DataFrame

from pybel.constants import ANNOTATIONS, CITATION_TYPE, CITATION_NAME, CITATION_REFERENCE, CITATION_DATE, \
CITATION_AUTHORS, CITATION_COMMENTS
CITATION_AUTHORS, CITATION_COMMENTS, RELATION


def graph_edge_data_iter(graph):
Expand Down Expand Up @@ -183,3 +183,41 @@ def citation_to_tuple(citation):
citation.get(CITATION_AUTHORS),
citation.get(CITATION_COMMENTS)
])


def is_edge_consistent(graph, u, v):
"""Checks if all edges between two nodes have the same relation
:param graph: A BEL Graph
:type graph: pybel.BELGraph
:param u: The source BEL node
:type u: tuple
:param v: The target BEL node
:type v: tuple
:return: If all edges from the source to target node have the same relation
:rtype: bool
"""
if not graph.has_edge(u, v):
raise ValueError('{} does not contain an edge ({}, {})'.format(graph, u, v))

return 0 == len(set(d[RELATION] for d in graph.edge[u][v].values()))


def safe_add_edge(graph, u, v, k, d):
"""Adds an edge while preserving negative keys, and paying no respect to positive ones
:param graph: A BEL Graph
:type graph: pybel.BELGraph
:param u: The source BEL node
:type u: tuple
:param v: The target BEL node
:type v: tuple
:param k: The edge key. If less than zero, corresponds to an unqualified edge, else is disregarded
:type k: int
:param d: The edge data dictionary
:type d: dict
"""
if k < 0:
graph.add_edge(u, v, key=k, attr_dict=d)
else:
graph.add_edge(u, v, attr_dict=d)

0 comments on commit 80cda99

Please sign in to comment.