| | """ |
| | This module provides the following: read and write of p2g format |
| | used in metabolic pathway studies. |
| | |
| | See https://web.archive.org/web/20080626113807/http://www.cs.purdue.edu/homes/koyuturk/pathway/ for a description. |
| | |
| | The summary is included here: |
| | |
| | A file that describes a uniquely labeled graph (with extension ".gr") |
| | format looks like the following: |
| | |
| | |
| | name |
| | 3 4 |
| | a |
| | 1 2 |
| | b |
| | |
| | c |
| | 0 2 |
| | |
| | "name" is simply a description of what the graph corresponds to. The |
| | second line displays the number of nodes and number of edges, |
| | respectively. This sample graph contains three nodes labeled "a", "b", |
| | and "c". The rest of the graph contains two lines for each node. The |
| | first line for a node contains the node label. After the declaration |
| | of the node label, the out-edges of that node in the graph are |
| | provided. For instance, "a" is linked to nodes 1 and 2, which are |
| | labeled "b" and "c", while the node labeled "b" has no outgoing |
| | edges. Observe that node labeled "c" has an outgoing edge to |
| | itself. Indeed, self-loops are allowed. Node index starts from 0. |
| | |
| | """ |
| | import networkx as nx |
| | from networkx.utils import open_file |
| |
|
| |
|
| | @open_file(1, mode="w") |
| | def write_p2g(G, path, encoding="utf-8"): |
| | """Write NetworkX graph in p2g format. |
| | |
| | Notes |
| | ----- |
| | This format is meant to be used with directed graphs with |
| | possible self loops. |
| | """ |
| | path.write((f"{G.name}\n").encode(encoding)) |
| | path.write((f"{G.order()} {G.size()}\n").encode(encoding)) |
| | nodes = list(G) |
| | |
| | nodenumber = dict(zip(nodes, range(len(nodes)))) |
| | for n in nodes: |
| | path.write((f"{n}\n").encode(encoding)) |
| | for nbr in G.neighbors(n): |
| | path.write((f"{nodenumber[nbr]} ").encode(encoding)) |
| | path.write("\n".encode(encoding)) |
| |
|
| |
|
| | @open_file(0, mode="r") |
| | @nx._dispatchable(graphs=None, returns_graph=True) |
| | def read_p2g(path, encoding="utf-8"): |
| | """Read graph in p2g format from path. |
| | |
| | Returns |
| | ------- |
| | MultiDiGraph |
| | |
| | Notes |
| | ----- |
| | If you want a DiGraph (with no self loops allowed and no edge data) |
| | use D=nx.DiGraph(read_p2g(path)) |
| | """ |
| | lines = (line.decode(encoding) for line in path) |
| | G = parse_p2g(lines) |
| | return G |
| |
|
| |
|
| | @nx._dispatchable(graphs=None, returns_graph=True) |
| | def parse_p2g(lines): |
| | """Parse p2g format graph from string or iterable. |
| | |
| | Returns |
| | ------- |
| | MultiDiGraph |
| | """ |
| | description = next(lines).strip() |
| | |
| | G = nx.MultiDiGraph(name=description, selfloops=True) |
| | nnodes, nedges = map(int, next(lines).split()) |
| | nodelabel = {} |
| | nbrs = {} |
| | |
| | |
| | for i in range(nnodes): |
| | n = next(lines).strip() |
| | nodelabel[i] = n |
| | G.add_node(n) |
| | nbrs[n] = map(int, next(lines).split()) |
| | |
| | |
| | for n in G: |
| | for nbr in nbrs[n]: |
| | G.add_edge(n, nodelabel[nbr]) |
| | return G |
| |
|