# Path: src/common.py
# def removekey(d, key):
# def colinear(p0, p1, p2):
# def manhattan_dist(A,B):
# def euclidean_dist(A,B):
# def Charge(X_charge = 0, Z_charge = 0):
# def Sign(count, num_sides):
#     def __init__(self, depth, dimension = 2):
#     def Syndrome(self, type, charge_type):
#     def PhysicalErrors(self):
#     def distance(self, type, node1, node2):
#     def Assessment(self):
# class Code:


from decoders import *
from matplotlib import path
from math import floor
from src import common
import sys
import networkx as nx
import numpy as np
def Partition(UnclusteredGraph, code, type, scale):
    # Make edges on Unclustered graph
    # between all nodes separated by distance 'scale'
    # on Dual Lattice
    for node1 in UnclusteredGraph.nodes():
        for node2 in UnclusteredGraph.nodes():
            if node1 != node2:
                d = code.distance(type, node1, node2)
                if d <= scale:
                    UnclusteredGraph.add_edge(*(node1, node2), weight=d)
    Clusters = []
    # Networkx connected components analysis
    subgraphs = nx.connected_component_subgraphs(UnclusteredGraph)
    for i, sg in enumerate(subgraphs):
        Clusters.append(sg.nodes(data=True))
            

    return Clusters


# Choose fixed node for cluster fusion
def CentralNode(UnclusteredGraph, cluster):
    # Initialize Center
    for node in cluster:
        if 'external' not in node[1]:
            center = node
            degree = UnclusteredGraph.degree(center[0])
            break

    for node in cluster:

# Path: src/common.py
# def removekey(d, key):
# def colinear(p0, p1, p2):
# def manhattan_dist(A,B):
# def euclidean_dist(A,B):
# def Charge(X_charge = 0, Z_charge = 0):
# def Sign(count, num_sides):
#     def __init__(self, depth, dimension = 2):
#     def Syndrome(self, type, charge_type):
#     def PhysicalErrors(self):
#     def distance(self, type, node1, node2):
#     def Assessment(self):
# class Code:


# Path: src/decoders/rg.py
from decoders import *
from matplotlib import path
from math import floor
from src import common
import sys
import networkx as nx
import numpy as np

def Partition(UnclusteredGraph, code, type, scale):
    # Make edges on Unclustered graph
    # between all nodes separated by distance 'scale'
    # on Dual Lattice
    for node1 in UnclusteredGraph.nodes():
        for node2 in UnclusteredGraph.nodes():
            if node1 != node2:
                d = code.distance(type, node1, node2)
                if d <= scale:
                    UnclusteredGraph.add_edge(*(node1, node2), weight=d)
    Clusters = []
    # Networkx connected components analysis
    subgraphs = nx.connected_component_subgraphs(UnclusteredGraph)
    for i, sg in enumerate(subgraphs):
        Clusters.append(sg.nodes(data=True))
            

    return Clusters


# Choose fixed node for cluster fusion
def CentralNode(UnclusteredGraph, cluster):
    # Initialize Center
    for node in cluster:
        if 'external' not in node[1]:
            center = node
            degree = UnclusteredGraph.degree(center[0])
            break

    for node in cluster:

        if UnclusteredGraph.degree(node[0]) > degree and 'external' not in node[1]: