Mercurial > repos > shellac > guppy_basecaller
diff env/lib/python3.7/site-packages/networkx/readwrite/sparse6.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/networkx/readwrite/sparse6.py Thu May 14 16:47:39 2020 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -# Original author: D. Eppstein, UC Irvine, August 12, 2003. -# The original code at http://www.ics.uci.edu/~eppstein/PADS/ is public domain. -# Copyright (C) 2004-2019 by -# Aric Hagberg <hagberg@lanl.gov> -# Dan Schult <dschult@colgate.edu> -# Pieter Swart <swart@lanl.gov> -# Tomas Gavenciak <gavento@ucw.cz> -# All rights reserved. -# BSD license. -# -# Authors: Tomas Gavenciak <gavento@ucw.cz> -# Aric Hagberg <aric.hagberg@lanl.gov> -"""Functions for reading and writing graphs in the *sparse6* format. - -The *sparse6* file format is a space-efficient format for large sparse -graphs. For small graphs or large dense graphs, use the *graph6* file -format. - -For more information, see the `sparse6`_ homepage. - -.. _sparse6: http://users.cecs.anu.edu.au/~bdm/data/formats.html - -""" -from itertools import chain -import math -import sys - -import networkx as nx -from networkx.exception import NetworkXError -from networkx.utils import open_file, not_implemented_for -from networkx.readwrite.graph6 import data_to_n, n_to_data - -__all__ = ['from_sparse6_bytes', 'read_sparse6', 'to_sparse6_bytes', - 'write_sparse6'] - - -def _generate_sparse6_bytes(G, nodes, header): - """Yield bytes in the sparse6 encoding of a graph. - - `G` is an undirected simple graph. `nodes` is the list of nodes for - which the node-induced subgraph will be encoded; if `nodes` is the - list of all nodes in the graph, the entire graph will be - encoded. `header` is a Boolean that specifies whether to generate - the header ``b'>>sparse6<<'`` before the remaining data. - - This function generates `bytes` objects in the following order: - - 1. the header (if requested), - 2. the encoding of the number of nodes, - 3. each character, one-at-a-time, in the encoding of the requested - node-induced subgraph, - 4. a newline character. - - This function raises :exc:`ValueError` if the graph is too large for - the graph6 format (that is, greater than ``2 ** 36`` nodes). - - """ - n = len(G) - if n >= 2 ** 36: - raise ValueError('sparse6 is only defined if number of nodes is less ' - 'than 2 ** 36') - if header: - yield b'>>sparse6<<' - yield b':' - for d in n_to_data(n): - yield str.encode(chr(d + 63)) - - k = 1 - while 1 << k < n: - k += 1 - - def enc(x): - """Big endian k-bit encoding of x""" - return [1 if (x & 1 << (k - 1 - i)) else 0 for i in range(k)] - - edges = sorted((max(u, v), min(u, v)) for u, v in G.edges()) - bits = [] - curv = 0 - for (v, u) in edges: - if v == curv: # current vertex edge - bits.append(0) - bits.extend(enc(u)) - elif v == curv + 1: # next vertex edge - curv += 1 - bits.append(1) - bits.extend(enc(u)) - else: # skip to vertex v and then add edge to u - curv = v - bits.append(1) - bits.extend(enc(v)) - bits.append(0) - bits.extend(enc(u)) - if k < 6 and n == (1 << k) and ((-len(bits)) % 6) >= k and curv < (n - 1): - # Padding special case: small k, n=2^k, - # more than k bits of padding needed, - # current vertex is not (n-1) -- - # appending 1111... would add a loop on (n-1) - bits.append(0) - bits.extend([1] * ((-len(bits)) % 6)) - else: - bits.extend([1] * ((-len(bits)) % 6)) - - data = [(bits[i + 0] << 5) + (bits[i + 1] << 4) + (bits[i + 2] << 3) + (bits[i + 3] << 2) + - (bits[i + 4] << 1) + (bits[i + 5] << 0) for i in range(0, len(bits), 6)] - - for d in data: - yield str.encode(chr(d + 63)) - yield b'\n' - - -def from_sparse6_bytes(string): - """Read an undirected graph in sparse6 format from string. - - Parameters - ---------- - string : string - Data in sparse6 format - - Returns - ------- - G : Graph - - Raises - ------ - NetworkXError - If the string is unable to be parsed in sparse6 format - - Examples - -------- - >>> G = nx.from_sparse6_bytes(b':A_') - >>> sorted(G.edges()) - [(0, 1), (0, 1), (0, 1)] - - See Also - -------- - read_sparse6, write_sparse6 - - References - ---------- - .. [1] Sparse6 specification - <http://users.cecs.anu.edu.au/~bdm/data/formats.html> - - """ - if string.startswith(b'>>sparse6<<'): - string = string[11:] - if not string.startswith(b':'): - raise NetworkXError('Expected leading colon in sparse6') - - if sys.version_info < (3, ): - chars = [ord(c) - 63 for c in string[1:]] - else: - chars = [c - 63 for c in string[1:]] - n, data = data_to_n(chars) - k = 1 - while 1 << k < n: - k += 1 - - def parseData(): - """Returns stream of pairs b[i], x[i] for sparse6 format.""" - chunks = iter(data) - d = None # partial data word - dLen = 0 # how many unparsed bits are left in d - - while 1: - if dLen < 1: - try: - d = next(chunks) - except StopIteration: - return - dLen = 6 - dLen -= 1 - b = (d >> dLen) & 1 # grab top remaining bit - - x = d & ((1 << dLen) - 1) # partially built up value of x - xLen = dLen # how many bits included so far in x - while xLen < k: # now grab full chunks until we have enough - try: - d = next(chunks) - except StopIteration: - return - dLen = 6 - x = (x << 6) + d - xLen += 6 - x = (x >> (xLen - k)) # shift back the extra bits - dLen = xLen - k - yield b, x - - v = 0 - - G = nx.MultiGraph() - G.add_nodes_from(range(n)) - - multigraph = False - for b, x in parseData(): - if b == 1: - v += 1 - # padding with ones can cause overlarge number here - if x >= n or v >= n: - break - elif x > v: - v = x - else: - if G.has_edge(x, v): - multigraph = True - G.add_edge(x, v) - if not multigraph: - G = nx.Graph(G) - return G - - -def to_sparse6_bytes(G, nodes=None, header=True): - """Convert an undirected graph to bytes in sparse6 format. - - Parameters - ---------- - G : Graph (undirected) - - nodes: list or iterable - Nodes are labeled 0...n-1 in the order provided. If None the ordering - given by ``G.nodes()`` is used. - - header: bool - If True add '>>sparse6<<' bytes to head of data. - - Raises - ------ - NetworkXNotImplemented - If the graph is directed. - - ValueError - If the graph has at least ``2 ** 36`` nodes; the sparse6 format - is only defined for graphs of order less than ``2 ** 36``. - - Examples - -------- - >>> nx.to_sparse6_bytes(nx.path_graph(2)) # doctest: +SKIP - b'>>sparse6<<:An\\n' - - See Also - -------- - to_sparse6_bytes, read_sparse6, write_sparse6_bytes - - Notes - ----- - The returned bytes end with a newline character. - - The format does not support edge or node labels. - - References - ---------- - .. [1] Graph6 specification - <http://users.cecs.anu.edu.au/~bdm/data/formats.html> - - """ - if nodes is not None: - G = G.subgraph(nodes) - G = nx.convert_node_labels_to_integers(G, ordering='sorted') - return b''.join(_generate_sparse6_bytes(G, nodes, header)) - - -@open_file(0, mode='rb') -def read_sparse6(path): - """Read an undirected graph in sparse6 format from path. - - Parameters - ---------- - path : file or string - File or filename to write. - - Returns - ------- - G : Graph/Multigraph or list of Graphs/MultiGraphs - If the file contains multiple lines then a list of graphs is returned - - Raises - ------ - NetworkXError - If the string is unable to be parsed in sparse6 format - - Examples - -------- - You can read a sparse6 file by giving the path to the file:: - - >>> import tempfile - >>> with tempfile.NamedTemporaryFile() as f: - ... _ = f.write(b'>>sparse6<<:An\\n') - ... _ = f.seek(0) - ... G = nx.read_sparse6(f.name) - >>> list(G.edges()) - [(0, 1)] - - You can also read a sparse6 file by giving an open file-like object:: - - >>> import tempfile - >>> with tempfile.NamedTemporaryFile() as f: - ... _ = f.write(b'>>sparse6<<:An\\n') - ... _ = f.seek(0) - ... G = nx.read_sparse6(f) - >>> list(G.edges()) - [(0, 1)] - - See Also - -------- - read_sparse6, from_sparse6_bytes - - References - ---------- - .. [1] Sparse6 specification - <http://users.cecs.anu.edu.au/~bdm/data/formats.html> - - """ - glist = [] - for line in path: - line = line.strip() - if not len(line): - continue - glist.append(from_sparse6_bytes(line)) - if len(glist) == 1: - return glist[0] - else: - return glist - - -@not_implemented_for('directed') -@open_file(1, mode='wb') -def write_sparse6(G, path, nodes=None, header=True): - """Write graph G to given path in sparse6 format. - - Parameters - ---------- - G : Graph (undirected) - - path : file or string - File or filename to write - - nodes: list or iterable - Nodes are labeled 0...n-1 in the order provided. If None the ordering - given by G.nodes() is used. - - header: bool - If True add '>>sparse6<<' string to head of data - - Raises - ------ - NetworkXError - If the graph is directed - - Examples - -------- - You can write a sparse6 file by giving the path to the file:: - - >>> import tempfile - >>> with tempfile.NamedTemporaryFile() as f: - ... nx.write_sparse6(nx.path_graph(2), f.name) - ... print(f.read()) # doctest: +SKIP - b'>>sparse6<<:An\\n' - - You can also write a sparse6 file by giving an open file-like object:: - - >>> with tempfile.NamedTemporaryFile() as f: - ... nx.write_sparse6(nx.path_graph(2), f) - ... _ = f.seek(0) - ... print(f.read()) # doctest: +SKIP - b'>>sparse6<<:An\\n' - - See Also - -------- - read_sparse6, from_sparse6_bytes - - Notes - ----- - The format does not support edge or node labels. - - References - ---------- - .. [1] Sparse6 specification - <http://users.cecs.anu.edu.au/~bdm/data/formats.html> - - """ - if nodes is not None: - G = G.subgraph(nodes) - G = nx.convert_node_labels_to_integers(G, ordering='sorted') - for b in _generate_sparse6_bytes(G, nodes, header): - path.write(b)
