| """ |
| This module provides the following: read and write of p2g format |
| used in metabolic pathway studies. |
| |
| See 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. |
| |
| """ |
| # Copyright (C) 2008-2012 by |
| # Aric Hagberg <hagberg@lanl.gov> |
| # Dan Schult <dschult@colgate.edu> |
| # Pieter Swart <swart@lanl.gov> |
| # All rights reserved. |
| # BSD license. |
| import networkx |
| from networkx.utils import is_string_like,open_file |
| __author__ = '\n'.join(['Willem Ligtenberg (w.p.a.ligtenberg@tue.nl)', |
| 'Aric Hagberg (aric.hagberg@gmail.com)']) |
| |
| @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(("%s\n"%G.name).encode(encoding)) |
| path.write(("%s %s\n"%(G.order(),G.size())).encode(encoding)) |
| nodes = G.nodes() |
| # make dictionary mapping nodes to integers |
| nodenumber=dict(zip(nodes,range(len(nodes)))) |
| for n in nodes: |
| path.write(("%s\n"%n).encode(encoding)) |
| for nbr in G.neighbors(n): |
| path.write(("%s "%nodenumber[nbr]).encode(encoding)) |
| path.write("\n".encode(encoding)) |
| |
| @open_file(0,mode='r') |
| 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=networkx.DiGraph(read_p2g(path)) |
| """ |
| lines = (line.decode(encoding) for line in path) |
| G=parse_p2g(lines) |
| return G |
| |
| def parse_p2g(lines): |
| """Parse p2g format graph from string or iterable. |
| |
| Returns |
| ------- |
| MultiDiGraph |
| """ |
| description = next(lines).strip() |
| # are multiedges (parallel edges) allowed? |
| G=networkx.MultiDiGraph(name=description,selfloops=True) |
| nnodes,nedges=map(int,next(lines).split()) |
| nodelabel={} |
| nbrs={} |
| # loop over the nodes keeping track of node labels and out neighbors |
| # defer adding edges until all node labels are known |
| for i in range(nnodes): |
| n=next(lines).strip() |
| nodelabel[i]=n |
| G.add_node(n) |
| nbrs[n]=map(int,next(lines).split()) |
| # now we know all of the node labels so we can add the edges |
| # with the correct labels |
| for n in G: |
| for nbr in nbrs[n]: |
| G.add_edge(n,nodelabel[nbr]) |
| return G |