Source code for ding0.tools.debug

"""This file is part of DING0, the DIstribution Network GeneratOr.
DING0 is a tool to generate synthetic medium and low voltage power
distribution grids based on open data.

It is developed in the project open_eGo: https://openegoproject.wordpress.com

DING0 lives at github: https://github.com/openego/ding0/
The documentation is available on RTD: http://ding0.readthedocs.io"""

__copyright__  = "Reiner Lemoine Institut gGmbH"
__license__    = "GNU Affero General Public License Version 3 (AGPL-3.0)"
__url__        = "https://github.com/openego/ding0/blob/master/LICENSE"
__author__     = "nesnoj, gplssm"

import os

import ding0
import os.path as path
import networkx as nx
import traceback

from functools import wraps
import logging

logger = logging.getLogger(__name__)

[docs]def log_errors(f): """ Decorator object that logs every exception into the defined logger object. """ @wraps(f) def exception_wrapper(*args, **kwargs): if os.environ.get("DING0_DEBUG") == "true": return f(*args, **kwargs) else: try: return f(*args, **kwargs) except Exception as e: args[0].network.message.append(str(traceback.format_exc())) logger.warning(f"Can't plot: {kwargs['filename']}") logger.exception(traceback.format_exc()) return exception_wrapper
[docs]def compare_graphs(graph1, mode, graph2=None): """ Compares graph with saved one which is loaded via networkx' gpickle Parameters ---------- graph1 : networkx.graph First Ding0 MV graph for comparison graph2 : networkx.graph Second Ding0 MV graph for comparison. If a second graph is not provided it will be laoded from disk with hard-coded file name. mode: 'write' or 'compare' Returns: """ # get path package_path = ding0.__path__[0] file = path.join(package_path, 'output', 'debug', 'graph1.gpickle') if mode == 'write': try: nx.write_gpickle(graph1, file) print('=====> DEBUG: Graph written to', file) except: raise FileNotFoundError('Could not write to file', file) elif mode == 'compare': if graph2 is None: try: graph2 = nx.read_gpickle(file) print('=====> DEBUG: Graph read from', file) except: raise FileNotFoundError('File not found:', file) # get data nodes1 = sorted(graph1.nodes(), key=lambda _: repr(_)) nodes2 = sorted(graph2.nodes(), key=lambda _: repr(_)) edges1 = sorted(graph1.edges(), key=lambda _: repr(_)) edges2 = sorted(graph2.edges(), key=lambda _: repr(_)) graphs_are_isomorphic = True # check nodes if len(nodes1) > len(nodes2): print('Node count in graph 1 > node count in graph 2') print('Difference:', [node for node in nodes1 if repr(node) not in repr(nodes2)]) graphs_are_isomorphic = False elif len(nodes2) > len(nodes1): print('Node count in graph 2 > node count in graph 1') print('Difference:', [node for node in nodes2 if repr(node) not in repr(nodes1)]) graphs_are_isomorphic = False # check edges if len(edges1) > len(edges2): print('Edge count in graph 1 > edge count in graph 2') print('Difference:', [edge for edge in edges1 if (repr(edge) not in repr(edges2)) and (repr(tuple(reversed(edge))) not in repr(edges2))]) graphs_are_isomorphic = False elif len(edges2) > len(edges1): print('Edge count in graph 2 > edge count in graph 1') print('Difference:', [edge for edge in edges2 if (repr(edge) not in repr(edges1)) and (repr(tuple(reversed(edge))) not in repr(edges1))]) graphs_are_isomorphic = False elif (len(edges1) == len(edges1)) and (len([edge for edge in edges1 if (repr(edge) not in repr(edges2)) and (repr(tuple(reversed(edge))) not in repr(edges2))]) > 0): print('Edge count in graph 1 = edge count in graph 2') print('Difference:', [edge for edge in edges2 if (repr(edge) not in repr(edges1)) and (repr(tuple(reversed(edge))) not in repr(edges1))]) graphs_are_isomorphic = False if graphs_are_isomorphic: print('=====> DEBUG: Graphs are isomorphic') else: print('=====> DEBUG: Graphs are NOT isomorphic') else: raise ValueError('Invalid value for mode, use mode=\'write\' or \'compare\'') exit(0)