Example #1
0
 def test_multigraph(self):
     G = nx.MultiGraph()
     G.add_edge(1, 2, key="first")
     G.add_edge(1, 2, key="second", color="blue")
     H = adjacency_graph(adjacency_data(G))
     nx.is_isomorphic(G, H)
     assert H[1][2]["second"]["color"] == "blue"
Example #2
0
    def with_empty_graph(cls, structure, name="bonds",
                        edge_weight_name=None,
                         edge_weight_units=None):
        """
        Constructor for StructureGraph, returns a StructureGraph
        object with an empty graph (no edges, only nodes defined
        that correspond to Sites in Structure).

        :param structure (Structure):
        :param name (str): name of graph, e.g. "bonds"
        :param edge_weight_name (str): name of edge weights,
        e.g. "bond_length" or "exchange_constant"
        :param edge_weight_units (str): name of edge weight units
        e.g. "Å" or "eV"
        :return (StructureGraph):
        """

        if edge_weight_name and (edge_weight_units is None):
            raise ValueError("Please specify units associated "
                             "with your edge weights. Can be "
                             "empty string if arbitrary or "
                             "dimensionless.")

        # construct graph with one node per site
        # graph attributes don't change behavior of graph,
        # they're just for book-keeping
        graph = nx.MultiDiGraph(edge_weight_name=edge_weight_name,
                                edge_weight_units=edge_weight_units,
                                name=name)
        graph.add_nodes_from(range(len(structure)))

        graph_data = json_graph.adjacency_data(graph)

        return cls(structure, graph_data=graph_data)
Example #3
0
def to_json(net, gformat):
    if "list" in gformat:
        jsn = jsg.node_link_data(net)
    else:
        jsn = jsg.adjacency_data(net)
    jsn = json.dumps(jsn, indent=2, sort_keys=True)
    return jsn
 def test_multigraph(self):
     G = nx.MultiGraph()
     G.add_edge(1, 2, key='first')
     G.add_edge(1, 2, key='second', color='blue')
     H = adjacency_graph(adjacency_data(G))
     nx.is_isomorphic(G, H)
     assert H[1][2]['second']['color'] == 'blue'
Example #5
0
    def with_empty_graph(cls, structure, name="bonds",
                        edge_weight_name=None,
                         edge_weight_units=None):
        """
        Constructor for StructureGraph, returns a StructureGraph
        object with an empty graph (no edges, only nodes defined
        that correspond to Sites in Structure).

        :param structure (Structure):
        :param name (str): name of graph, e.g. "bonds"
        :param edge_weight_name (str): name of edge weights,
        e.g. "bond_length" or "exchange_constant"
        :param edge_weight_units (str): name of edge weight units
        e.g. "Å" or "eV"
        :return (StructureGraph):
        """

        if edge_weight_name and (edge_weight_units is None):
            raise ValueError("Please specify units associated "
                             "with your edge weights. Can be "
                             "empty string if arbitrary or "
                             "dimensionless.")

        # construct graph with one node per site
        # graph attributes don't change behavior of graph,
        # they're just for book-keeping
        graph = nx.MultiDiGraph(edge_weight_name=edge_weight_name,
                                edge_weight_units=edge_weight_units,
                                name=name)
        graph.add_nodes_from(range(len(structure)))

        graph_data = json_graph.adjacency_data(graph)

        return cls(structure, graph_data=graph_data)
Example #6
0
def create_relations_graph():
    client = MongoClient('localhost', 27017)
    db = client["cinema-of-israel-db"]["movies"]

    movies_list = db.find({})
    all_casts = []
    for rec in movies_list:
        all_casts.append(get_movie_cast(rec))

    #every movie represents by clique sub graph
    all_subgraph = [nx.complete_graph(x[1]) for x in all_casts]

    #set edges attribute to movie's name for each sub graph
    for x in range(0, len(all_casts)):
        nx.set_edge_attributes(all_subgraph[x], all_casts[x][0], "שם הסרט")

    #union graph includes all movies
    israel_cinema_relations = nx.compose_all(all_subgraph)

    #save graph in json format
    data = json_graph.adjacency_data(israel_cinema_relations)
    with open('json_graph.json', 'w') as outfile:
        json.dump(data, outfile)

    return
Example #7
0
def gsource_gdata(config, graphSource, graphData):
    """Create a graph from the config file GRAPH_SOURCE and GRAPH_DATA sections"""
    # make sure the config file has graph information in it
    graph_source_field = "gSource"
    save_graph_field = "save_json"
    required_graph_data_fields = ['id', 'pop', 'area', 'cd']

    if not config.has_section(graphData):
        raise configparser.NoSectionError(graphData)
    if not config.has_section(graphSource):
        raise configparser.NoSectionError(graphSource)

    configGraphData = config[graphData]
    configGraphSource = config[graphSource]

    missing = [
        x for x in required_graph_data_fields if x not in configGraphData
    ]

    if missing:
        missing_str = " ".join(missing)
        raise configparser.NoOptionError(missing_str, graphData)

    if graph_source_field not in configGraphSource:
        raise configparser.NoOptionError(graph_source_field, graphSource)

    ID = configGraphData['id']
    POP = configGraphData['pop']
    AREA = configGraphData['area']
    CD = configGraphData['cd']
    # create graph from data and load required data

    path = configGraphSource[graph_source_field]
    save_graph = False
    load_graph = False

    if save_graph_field in configGraphSource:
        save_graph = True
        if os.path.isfile(configGraphSource[save_graph_field]):
            print("trying to load graph from", path)
            path = configGraphSource[save_graph_field]
            save_graph = False
            load_graph = True

    type = "json" if load_graph else "fiona"
    graph = mgs.construct_graph(path,
                                ID,
                                pop_col=POP,
                                area_col=AREA,
                                district_col=CD,
                                cols_to_add=[POP, AREA, CD],
                                data_source_type=type)

    if save_graph:
        print("saving graph to", configGraphSource[save_graph_field])
        with open(configGraphSource[save_graph_field], "w") as f:
            json.dump(json_graph.adjacency_data(graph), f)

    return graph, POP, AREA, CD
Example #8
0
def write_json(G, i):
    data = json_graph.adjacency_data(G)
    s = json.dumps(data)
    f = open(outFileName.format("-{0}".format(i), "json"), "w")
    f.write(s)
    f.close()
    if not outputOnlyReducedGraphs:
        export_as_coord_list(G, "nodes-{0}.json".format(i))
Example #9
0
def graph2json(graph,filename):

    # convert to json
    jdata = json_graph.adjacency_data(graph)

    # write to file
    f = open(filename+'.json','w')
    json.dump(jdata,f)
    f.close()
Example #10
0
    def test_graph_attributes(self):
        G = nx.path_graph(4)
        G.add_node(1, color="red")
        G.add_edge(1, 2, width=7)
        G.graph["foo"] = "bar"
        G.graph[1] = "one"

        H = adjacency_graph(adjacency_data(G))
        assert H.graph["foo"] == "bar"
        assert H.nodes[1]["color"] == "red"
        assert H[1][2]["width"] == 7

        d = json.dumps(adjacency_data(G))
        H = adjacency_graph(json.loads(d))
        assert H.graph["foo"] == "bar"
        assert H.graph[1] == "one"
        assert H.nodes[1]["color"] == "red"
        assert H[1][2]["width"] == 7
    def test_graph_attributes(self):
        G = nx.path_graph(4)
        G.add_node(1, color='red')
        G.add_edge(1, 2, width=7)
        G.graph['foo'] = 'bar'
        G.graph[1] = 'one'

        H = adjacency_graph(adjacency_data(G))
        assert H.graph['foo'] == 'bar'
        assert H.nodes[1]['color'] == 'red'
        assert H[1][2]['width'] == 7

        d = json.dumps(adjacency_data(G))
        H = adjacency_graph(json.loads(d))
        assert H.graph['foo'] == 'bar'
        assert H.graph[1] == 'one'
        assert H.nodes[1]['color'] == 'red'
        assert H[1][2]['width'] == 7
Example #12
0
    def serialize(self):
        data = json_graph.adjacency_data(self._graph)

        data["adjacency"] = [
            sorted(outbounds, key=lambda x: x["id"])
            for outbounds in data["adjacency"]
        ]

        return data
Example #13
0
def saveGraph(G, file_name):
    data = json_graph.adjacency_data(G)
    
    try:
        with open(file_name, 'w') as outfile:
            json.dump(json.dumps(data), outfile)
        return(True)
    except IOError:
        return(False)
Example #14
0
    def serialize(self):
        data = json_graph.adjacency_data(self._graph)

        data['adjacency'] = [
            sorted(outbounds, key=lambda x: x['id'])
            for outbounds in data['adjacency']
        ]

        return data
Example #15
0
def json_networkx(obj):
    logger.debug("nx graph")
    json_string = json_graph.adjacency_data(obj,
                                            attrs={
                                                'id': 'json_id',
                                                'key': 'json_key'
                                            })
    d = with_signature(obj, json_string, obj_module="networkx")
    return d
Example #16
0
def create_subgraph(poi_input_path: str, graph_input_path: str, subgraph_output_path: str):
    """
    Read csv in poi_input_path containing point of interests (POIs) {name, lat, lon, id}
    Read json file in graph_input_path containing the complete graph (where the POIs are some of the nodes)
    Create subgraph for given POIs and save it as JSON in subgraph_output_path

    Args:
        poi_input_path (str): path of the csv containing POI having rows {name, lat, lon, id}
        graph_input_path (str): path to networkx json_graph.adjacency_data
        subgraph_output_path (str): path to write networkx subgraph as json_graph.adjacency_data
    """
    # read input
    node_ids = []
    print(f'reading POI file {poi_input_path}')
    with open(poi_input_path) as f:
        reader = csv.reader(f)
        for row in reader:
            assert len(row) >= 5
            node_id = row[4]
            node_ids.append(int(node_id))
    
    node_ids = list(set(node_ids))
    node_ids.sort()

    data = {}
    print(f'reading graph file {graph_input_path}') 
    with open(graph_input_path) as f:
        data = json.load(f)
    
    # create subgraph
    print(f'creating subgraph')
    G = json_graph.adjacency_graph(data)    
    len_node_ids = len(node_ids)
    # H = nx.to_undirected(G)    
    # num_combinations = math.factorial(len_node_ids) / (2*math.factorial((len_node_ids-2)))
    # print(f'* getting the shortest paths of {num_combinations} combinations')
    # futures = []
    # with concurrent.futures.ThreadPoolExecutor(max_workers=mp.cpu_count()) as executor:
    #     for nodes in combinations(node_ids, r=2):
    #         futures.append(executor.submit(nx.shortest_path, H, *nodes))
    num_permutations = math.factorial(len_node_ids) / math.factorial((len_node_ids-2))
    print(f'* getting the shortest paths of {num_permutations} permutations')
    futures = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=mp.cpu_count()) as executor:
        for nodes in permutations(node_ids, r=2):
            futures.append(executor.submit(nx.shortest_path, G, *nodes))
    min_nodes = set()
    for future in futures:
        nodes = future.result()
        min_nodes.update(nodes)
    print('* create subgraph from the longest induced path')
    I = nx.subgraph(G, min_nodes)
    subgraph_data = json_graph.adjacency_data(I)
    with open(subgraph_output_path, 'w+') as f:
        json.dump(subgraph_data, f)
    print(f'subgraph saved in {subgraph_output_path}')
def save_json_file(graph):
    data = json_graph.adjacency_data(graph)
    data['graph'] = []
    bad_node = []
    for node in data['nodes']:
        # node['pos'] = list(node['pos'])
        if 'pos' in node:
            del node['pos']
        if 'rotation' in node:
            # node['rotation'] = list(node['rotation'])
            del node['rotation']

        # I guess here the frozenset and pos is the information for face, should we keep this information?
        for i in range(len(node)):
            if isinstance(list(node.values())[i], set):
                key = list(node.keys())[i]
                del node[key]
                if len(node) == 0:
                    bad_node.append(node)
            elif type(list(node.values())[i]) is frozenset:
                key = list(node.keys())[i]
                del node[key]
                if len(node) == 0:
                    bad_node.append(node)

    for i in bad_node:
        data['nodes'].remove(i)

    bad_node = []
    break_bool = False
    for adj_node in data['adjacency']:
        bad_key = []
        for node in adj_node:
            for i in range(len(node)):
                if isinstance(list(node.values())[i], set):
                    bad_key.append(node)
                elif type(list(node.values())[i]) is frozenset:
                    bad_key.append(node)
        for i in bad_key:
            adj_node.remove(i)
        for node in adj_node:
            for i in range(len(node)):
                if i == 0 and list(node.keys())[0] == 'id':
                    bad_node.append(adj_node)
                    break_bool = True
                    break
            if break_bool:
                break_bool = False
                break
    for i in bad_node:
        data['adjacency'].remove(i)

    remove_geometries(data)
    with open("some.json", "w") as f:
        json.dump(data, f)
Example #18
0
def _serialize_graph(graph):
    graph = json_graph.adjacency_data(graph)
    graph["nodes"] = [{
        "id":
        n["id"] if not isinstance(n["id"], Step) else repr(n["id"])
    } for n in graph["nodes"]]
    graph["adjacency"] = [[{
        "id":
        a["id"] if not isinstance(a["id"], Step) else repr(a["id"])
    } for a in adj] for adj in graph["adjacency"]]

    return graph
Example #19
0
def find_crowds(weak_comps):
    """
    break up big connected components using crowd detection algorithm, add
    details to crowds
    """
    crowds = []
    for crowd,weak_comp in enumerate(weak_comps):
        g = json_graph.adjacency_graph(weak_comp)
        dendo = community.generate_dendogram(nx.Graph(g))

        if len(dendo)>=2:
            partition = community.partition_at_level(dendo, 1 )
            crowd_ids = collections.defaultdict(list)
            for uid,subcrowd in partition.iteritems():
                crowd_ids[subcrowd].append(uid)
            for subcrowd,uids in sorted(crowd_ids.iteritems()):
                subg = nx.DiGraph(nx.subgraph(g,uids))
                if len(subg)>2:
                    crowds.append(subg)
        else:
            crowds.append(g)

    def _blur(angle):
        return random.triangular(angle-.02,angle+.02)

    big_spots = collections.defaultdict(list)
    lil_spots = collections.defaultdict(list)
    for index,g in enumerate(crowds):
        # location is location of user with greatest degree
        uid,degree = max(g.degree_iter(),key=operator.itemgetter(1))
        lng,lat = g.node[uid]['loc']
        big_spots[int(lng/2),int(lat/2)].append(g)
        lil_spots[int(lng*5),int(lat*5)].append(g)
        g.graph['loc'] = lng,lat
        g.graph['id'] = index

    # add noise to each location based on how popular that area is.
    for lng_lat,graphs in lil_spots.iteritems():
        graphs.sort(key=len,reverse=True)
        for index,g in enumerate(graphs):
            lng,lat = g.graph['loc']
            ang = random.random()*2*np.pi
            dist = .001 * math.sqrt(index)
            g.graph['loc'] = lng+1.2*dist*math.cos(ang), lat+dist*math.sin(ang)

    # pick crowds to show on map based on size
    for lng_lat,graphs in big_spots.iteritems():
        graphs.sort(key=len,reverse=True)
        for index,g in enumerate(graphs):
            g.graph['zoom'] = int(math.floor(1+math.log(index,3))) if index else 0

    return (json_graph.adjacency_data(g) for g in crowds)
Example #20
0
    def as_dict(self):
        """
        As in :Class: `pymatgen.core.Structure` except
        with using `to_dict_of_dicts` from NetworkX
        to store graph information.
        """

        d = {"@module": self.__class__.__module__,
             "@class": self.__class__.__name__,
             "structure": self.structure.as_dict(),
             "graphs": json_graph.adjacency_data(self.graph)}

        return d
Example #21
0
    def as_dict(self):
        """
        As in :Class: `pymatgen.core.Structure` except
        with using `to_dict_of_dicts` from NetworkX
        to store graph information.
        """

        d = {"@module": self.__class__.__module__,
             "@class": self.__class__.__name__,
             "structure": self.structure.as_dict(),
             "graphs": json_graph.adjacency_data(self.graph)}

        return d
Example #22
0
def to_json(glist, fname):
    """ Accepts a list of networkx graphs and dumps them to file for later
    reading """

    count = 1
    master = {}
    for plan in glist:
        data = json_graph.adjacency_data(plan)
        master["graph-{}".format(count)] = data
        count += 1

    with open("{}".format(fname), "w") as f:
        json.dump(master, f, indent=2)
Example #23
0
def grids(horizontal_file, vertical_file):
    """Generates two 10x10 grids with vertically striped districts.

    One grid (the A/B grid) has a 40%/60% binary partisan split along
    a horizontal line, perpendicular to the districts. Another grid
    (the A'/B' grid) has a 40%/60% binary partisan split along a vertical
    line, parallel to the districts.

    :param horizontal_file: The JSON file to dump the grid with horizontal
    partisan split to.
    :param vertical_file: The JSON file to dump the grid with horizontal
    partisan split to.
    """
    graph = nx.grid_graph(dim=[N, N])
    for node in graph.nodes:
        graph.nodes[node]['population'] = 1
        graph.nodes[node]['district'] = (node[0] // 6) + 1
        graph.nodes[node]['x'] = node[0] + 1
        graph.nodes[node]['y'] = node[1] + 1

    horizontal_graph = graph.copy()
    vertical_graph = graph.copy()
    for node in graph.nodes:
        a_share = int(node[1] < SPLIT)
        horizontal_graph.nodes[node]['a_share'] = a_share
        horizontal_graph.nodes[node]['b_share'] = 1 - a_share
    for node in vertical_graph.nodes:
        a_share = int(node[0] < SPLIT)
        vertical_graph.nodes[node]['a_share'] = a_share
        vertical_graph.nodes[node]['b_share'] = 1 - a_share

    mapping = {(x, y): (x * N) + y for x, y in horizontal_graph.nodes}
    horizontal_graph = nx.relabel_nodes(horizontal_graph, mapping)
    vertical_graph = nx.relabel_nodes(vertical_graph, mapping)
    with open(horizontal_file, 'w') as adj_file:
        json.dump(json_graph.adjacency_data(horizontal_graph), adj_file)
    with open(vertical_file, 'w') as adj_file:
        json.dump(json_graph.adjacency_data(vertical_graph), adj_file)
 def __del__(self):
     new = []
     for doc in Block.ADJ_GRAPHS.values():
         if 'new' in doc:
             del doc['new']
             data = json_graph.adjacency_data(doc['graph'])
             doc['graph'] = bson.Binary(bz2.compress(pickletools.optimize(
                 pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL))))
             new.append(doc)
     if doc:
         mdb = pymongo.MongoClient('mongodb://127.0.0.1:27017')
         mdb.config['graph'].insert_many(new)
         mdb.close()
         Log.info('New scene graphs uploaded')
     Block.ADJ_GRAPHS = {}
Example #25
0
def gml2json(infile):

    graph = nx.read_gml(infile)
    
    # delete all nodes
    for n,d in graph.nodes(data=True):
        del d['id']

    # convert to json
    jdata = json_graph.adjacency_data(graph)

    # write to file
    f = open(infile.replace('gml','json'),'w')
    json.dump(jdata,f)
    f.close()
    print("[i] Conversion successful...")
Example #26
0
def save_following_network_graph(user_list, file_name):
    graph = nx.DiGraph()

    for user in user_list:
        print user
        user_followings = get_user_following(user)

        graph_edges = [(user, u) for u in user_followings]
        graph.add_edges_from(graph_edges)

        print 'added {1} edges for user @{0}'.format(user, len(graph_edges))

    graph_data = json_graph.adjacency_data(graph)

    with open(file_name, 'w') as f:
        json.dump(graph_data, f, indent=4)
Example #27
0
    def __init__(self,
                 graph: Graph,
                 initial_state: Partition,
                 total_steps: int,
                 pop_col: str,
                 pop_tol: float,
                 compressed: bool = True,
                 reversible: bool = True,
                 seed: int = None):
        """
        :param graph: the GerryChain graph to compile to a Julia graph.
        :param initial_state: The state to start from.
        :param total_steps: The total steps to take in the chain.
        :param pop_col: The column of the graph with population data.
        :param pop_tol: The population tolerance to use.
        :param compressed: If `True`, plans are represented in `RecomStep`
            format. Otherwise, behavior mimics GerryChain.
        :param reversible: Determines if the reversible version of the chain
            should be used.
        :param seed: The random seed to use for plan generation.
        """
        for node, assignment in initial_state.assignment.items():
            graph.nodes[node]['__district'] = assignment
        graph_data = json_graph.adjacency_data(graph)
        self.graph = Flips.IndexedGraph(graph_data, pop_col)
        # TODO: verify initial state is valid w.r.t. population constraints
        #       (+ more?)
        self.plan = Flips.Plan(self.graph, '__district')
        total_pop = sum(graph.nodes[node][pop_col] for node in graph.nodes)
        districts = list(initial_state.assignment.values())
        n_districts = max(districts) - min(districts) + 1
        district_pop = total_pop / n_districts
        self.min_pop = int(ceil((1 - pop_tol) * district_pop))
        self.max_pop = int(floor((1 + pop_tol) * district_pop))
        self.reversible = reversible
        self.compressed = compressed

        self._curr_parent = initial_state
        self.total_steps = total_steps
        self._curr_step = 0
        self._buf = deque()  # https://stackoverflow.com/a/4426727/8610749
        self.data = None
        if seed is None:
            self._twister = Random.MersenneTwister()
        else:
            self._twister = Random.MersenneTwister(seed)
Example #28
0
    def to_json(self, json_file, *, include_geometries_as_geojson=False):
        """Save a graph to a JSON file in the NetworkX json_graph format.
        :param json_file: Path to target JSON file.
        :param bool include_geometry_as_geojson: (optional) Whether to include any
            :mod:`shapely` geometry objects encountered in the graph's node attributes
            as GeoJSON. The default (``False``) behavior is to remove all geometry
            objects because they are not serializable. Including the GeoJSON will result
            in a much larger JSON file.
        """
        data = json_graph.adjacency_data(self)

        if include_geometries_as_geojson:
            convert_geometries_to_geojson(data)
        else:
            remove_geometries(data)

        with open(json_file, "w") as f:
            json.dump(data, f)
Example #29
0
    def add_flow(self, name, input_flow):
        new_flow = [[y[0:2] for y in x] for x in input_flow]
        for flow in input_flow:
            for app in flow:
                if not self.graph.has_node(app[0:2]):
                    raise Exception('Please define application {0} first.'.format(app))
                elif self.graph.node[app[0:2]]['full_name'] != app:
                    raise Exception('Names of app abbreviations {0} and '
                                    '{1} don\'t match.'.format(self.graph.node[app[0:2]]['full_name'], app))
        flow = nx.DiGraph()
        for path in new_flow:
            flow.add_path(path, weight=1)

        # copy node attributes
        for node in flow.nodes():
            flow.node[node] = self.graph.node[node]

        self.flows[name] = flow
        print "graph {0} created: {1}".format(name, json_graph.adjacency_data(flow))
        self.save_flows()
        self.save_graph(name, flow)
        self.merge_graphs(flow)
Example #30
0
def simulate(p=0, alpha=25e-6, resolution=40000, fname='results/data.json'):
    """ Simulate Bornholdt/Sneppen model
    """
    if os.path.exists(fname):
        print(f'File {fname} exists, skipping')
        return

    N = 128
    tmax = resolution * 2  #80000

    freq = int(tmax / resolution)  #1/N**2
    print(f'Simulating with p={p}, alpha={alpha} ({fname})')
    print(
        f'Saving data every {freq*N**2} time steps, resulting in {int(tmax/(freq*N**2))} ({int(tmax/freq)}) data points'
    )

    node_list = [(i // N, i % N) for i in range(N**2)]
    graph = generate_graph(N, p)

    graph_mat = nx.to_numpy_matrix(graph, nodelist=node_list)
    graph_repr = convert_matrix(graph_mat)

    sim = Simulator(N, p, alpha, tmax, freq, fname, graph_repr)

    start = time.time()
    snapshot_num = sim.run()
    end = time.time()
    assert snapshot_num == int(tmax / freq), snapshot_num

    print(f' > Runtime: {end-start:.0f}s')

    # save graph
    with open(fname) as fd:
        data = json.load(fd)
    data['graph'] = json_graph.adjacency_data(graph)
    with open(fname, 'w') as fd:
        json.dump(data, fd)
Example #31
0
def weak_comps(edges,user_locs):
    """convert near_edges into networkx format, keep weakly-connected users"""
    g = nx.DiGraph()
    for edge in edges:
        ne = NearEdge(*edge)
        conv = (ne.day,ne.at,ne.rt)
        if g.has_edge(ne.frm,ne.to):
            g[ne.frm][ne.to]['conv'].append(conv)
        else:
            g.add_edge(ne.frm, ne.to, dist=ne.dist, conv=[conv])
    # remove edges that are only retweets
    for frm,to,data in g.edges(data=True):
        if not any(at for day,at,rt in data['conv']):
            g.remove_edge(frm,to)
    # remove nodes with a degree greater than 50
    popular = [uid for uid,degree in g.degree_iter() if degree>50]
    g.remove_nodes_from(popular)
    # add locations
    for node in g.nodes_iter():
        g.node[node]['loc'] = user_locs[node]
    # yield weakly connected crowds
    for subg in nx.weakly_connected_component_subgraphs(g):
        if len(subg)>2:
            yield json_graph.adjacency_data(subg)
Example #32
0
    def network_x_block_together(self,
                                 population,
                                 location=None,
                                 additional=None):
        """
        :param location: The location parameters which the blocks are checked for (scene_type for example).
        :param population: These are the parameters which the blocks are checked for.
        :param additional: Additional attributes for the blocks calculation:
        1. calculate_all_scenes: whether to check all the relevant scenes for a block or stop once a block was found.
                If True, the function will search for blocks in all scenes (which will affect the performance!!).
                If False, the function will stop running once a scene was found with the relevant block.
        2. horizontal_bucket_size: Used to calculate the number of products in order to determine whether a block
                is vertical or horizontal. Usually 1ft - the length of the bay
        3. outliers_threshold: The threshold for removing the outliers for the horizontal/vertical calculation.
        4. include_stacking: Whether the products can be stacked on the shelf or not
        5. minimum_facing_for_block: Minimum number of facings that needs to be in a block to consider it as one.
        6. adjacency_overlap_ratio: Minimal threshold the overlap between the products must exceeds to be considered
                as adjacent.
        7. allowed_products_filters: These are the parameters which are allowed to corrupt the block without failing it.
        8. minimum_block_ratio: The minimum (block number of facings / total number of relevant facings) ratio
                                    in order for KPI to pass (if ratio=1, then only one block is allowed).
        9. check_vertical_horizontal: True if the orientation (vertical or horizontal) of the block should be checked for.
        10. allowed_edge_type: This determines what allowed products will actually be allowed. That is, allowed products
                in scene can be filtered based on their connections (or lack of) to relevant group products. Format is a
                Mix and Match list of -> [unconnected, connected, encapsulated].
                        unconnected-> allowed nodes with no connections to relevant products.
                        connected -> allowed nodes that connect to both relevant group and irrelevant group nodes
                        encapsulated -> allowed nodes that only connect to relevant group products
        :return: df with the following fields;
                block (Graph), scene_fk, orientation (string - vertical or horizontal), facing_percentage.

        """

        block_parameters = {
            AdditionalAttr.MINIMUM_BLOCK_RATIO: Default.minimum_block_ratio,
            AdditionalAttr.CHECK_VERTICAL_HORIZONTAL:
            Default.check_vertical_horizontal,
            AdditionalAttr.ALLOWED_PRODUCTS_FILTERS: None,
            AdditionalAttr.ADJACENCY_OVERLAP_RATIO:
            Default.adjacency_overlap_ratio,
            AdditionalAttr.MINIMUM_FACING_FOR_BLOCK:
            Default.minimum_facing_for_block,
            AdditionalAttr.INCLUDE_STACKING: Default.include_stacking,
            AdditionalAttr.IGNORE_EMPTY: Default.ignore_empty,
            AdditionalAttr.OUTLIERS_THRESHOLD: Default.outliers_threshold,
            AdditionalAttr.CALCULATE_ALL_SCENES: Default.calculate_all_scenes,
            AdditionalAttr.ALLOWED_EDGE_TYPE: Default.allowed_edge_type,
            AdditionalAttr.FILTER_OPERATOR: Default.filter_operator
        }

        if additional is not None:
            block_parameters.update(additional)

        self.outliers_threshold = block_parameters[
            AdditionalAttr.OUTLIERS_THRESHOLD]
        self.check_vertical_horizontal = block_parameters[
            AdditionalAttr.CHECK_VERTICAL_HORIZONTAL]
        # self.include_stacking = block_parameters[AdditionalAttr.INCLUDE_STACKING]
        self.include_stacking = True
        self.ignore_empty = block_parameters[AdditionalAttr.IGNORE_EMPTY]
        self.allowed_edge_type = block_parameters[
            AdditionalAttr.ALLOWED_EDGE_TYPE]
        operator = block_parameters[AdditionalAttr.FILTER_OPERATOR]

        # Constructing the result_df that will be returned if calculate_all_scenes = True
        results_df = pd.DataFrame(columns=[
            ColumnNames.CLUSTER, ColumnNames.SCENE_FK, ColumnNames.ORIENTATION,
            ColumnNames.FACING_PERCENTAGE, ColumnNames.IS_BLOCK
        ])

        # Separate the filters on products from the filters on scene and get the relevant scenes
        if location is not None:
            conditions = {'location': location}
            relevant_scenes = self.input_parser.filter_df(
                conditions, self.scif).scene_id.unique()
        else:
            relevant_scenes = self.scif.scene_id.unique()
        if not relevant_scenes.any():
            Log.info('No scenes with the requested location filter.')
            return results_df

        # Identify relevant block values
        block_value = [
            '_'.join(str(x) for x in elem)
            for elem in list(itertools.product(*population.values()))
        ]

        # Creating unified filters from the block filters and the allowed filters
        allowed_product_filter = []
        if block_parameters[AdditionalAttr.ALLOWED_PRODUCTS_FILTERS]:
            allowed_product_filter = block_parameters[
                AdditionalAttr.ALLOWED_PRODUCTS_FILTERS].keys()

        # For each relevant scene check if a block is exist
        for scene in relevant_scenes:
            try:
                # filter masking and matches data by the scene
                scene_mask = self.masking_data[self.masking_data['scene_fk'] ==
                                               scene].drop('scene_fk', axis=1)
                scene_matches = self.matches_df[self.matches_df['scene_fk'] ==
                                                scene]
                relevant_matches_for_block = self.filter_graph_data(
                    scene_matches,
                    population,
                    operator=operator,
                    is_blocks_graph=False)
                scene_matches = scene_matches.drop(
                    'pk', axis=1).rename(columns={'scene_match_fk': 'pk'})
                if relevant_matches_for_block.empty:
                    continue

                import time
                times = []
                start = time.time()

                graph = AdjacencyGraphBuilder.initiate_graph_by_dataframe(
                    scene_matches,
                    scene_mask,
                    additional_attributes=['rect_x', 'rect_y'] +
                    allowed_product_filter + list(scene_matches.columns))
                start = time.time() - start
                times.append(['build graph', start])
                print('{} to build graph'.format(start))
                start = time.time()

                graph = AdjacencyGraphBuilder.condense_graph_by_level(
                    CalcConst.PRODUCT_FK, graph)
                start = time.time() - start
                times.append(['simplify graph', start])
                print('{} to build simplify'.format(start))
                start = time.time()

                import pymongo
                from networkx.readwrite import json_graph
                import json
                import cPickle as pickle
                import pickletools
                import bz2
                import bson
                mdb = pymongo.MongoClient('mongodb://127.0.0.1:27017')
                col = mdb.config['graph']

                start = time.time() - start
                times.append(['mongo connect', start])
                print('{} to connect to mongo'.format(start))
                start = time.time()

                data = json_graph.adjacency_data(graph)
                start = time.time() - start
                times.append(['extract graph data', start])
                print('{} extract graph data'.format(start))
                start = time.time()

                print('~~~~~~~~~~~~')
                g = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
                start = time.time() - start
                print('{} pickle'.format(start))
                start = time.time()
                g = pickletools.optimize(g)
                start = time.time() - start
                print('{} optimize'.format(start))
                start = time.time()
                g = bz2.compress(g)
                start = time.time() - start
                print('{} compress'.format(start))
                start = time.time()
                g = bson.Binary(g)
                start = time.time() - start
                print('{} bsonify'.format(start))
                start = time.time()
                print('~~~~~~~~~~~~')

                # bson.Binary(bz2.compress(pickletools.optimize(pickle.dumps(data))))
                pkl = {
                    'project': self.data_provider.project_name,
                    'scene': scene,
                    'session': self.data_provider.session_uid,
                    'graph': g
                }
                start = time.time() - start
                times.append(['pickle graph', start])
                print('{} to pickle graph'.format(start))
                start = time.time()

                col.insert_one(pkl)
                start = time.time() - start
                times.append(['insert to mongo', start])
                print('{} to insert into mongo'.format(start))
                start = time.time()

                doc = col.find({
                    'project': self.data_provider.project_name,
                    'scene': scene
                })[0]
                start = time.time() - start
                times.append(['load from mongo', start])
                print('{} to load graph from mongo'.format(start))
                start = time.time()

                upkl = pickle.loads(bz2.decompress(doc['graph']))
                start = time.time() - start
                times.append(['unpickle graph', start])
                print('{} to unpickle'.format(start))
                start = time.time()

                if not self.include_stacking:
                    scene_matches = self._get_no_stack_data(scene_matches)

                # check if the adj_g already exists for this scene, if not create it and save it
                if scene not in self.adj_graphs_by_scene:
                    # Create the adjacency graph on the data we filtered above
                    graph = AdjacencyGraphBuilder.initiate_graph_by_dataframe(
                        scene_matches,
                        scene_mask,
                        additional_attributes=['rect_x', 'rect_y'] +
                        allowed_product_filter + list(scene_matches.columns))
                    self.adj_graphs_by_scene[scene] = graph
                adj_g = self.adj_graphs_by_scene[scene].copy()

                # Update the block_key node attribute based on the population fields
                for i, n in adj_g.nodes(data=True):
                    n[Block.BLOCK_KEY].stored_values = set(
                        ['_'.join([str(*n[x]) for x in population.keys()])])

                if allowed_product_filter:
                    adj_g = self._set_allowed_nodes(
                        adj_g, block_parameters[
                            AdditionalAttr.ALLOWED_PRODUCTS_FILTERS],
                        block_value)

                # TODO: filter nodes to subgraph
                # Filter only relevant nodes for block out of the graph
                filtered_nodes = list(
                    n for n, d in adj_g.nodes(data=True)
                    if list(d[Block.BLOCK_KEY])[0] in block_value +
                    self.allowed_edge_type)

                # Create a sub graph based on the adj_g containing only the filtered nodes
                adj_g = adj_g.subgraph(filtered_nodes)

                # Creating the condensed graph based on the adjacency graph created above
                if len(population.keys()
                       ) == 1 and population.keys()[0] != CalcConst.PRODUCT_FK:
                    # adj_g = AdjacencyGraphBuilder.build_adjacency_graph_by_level(Block.BLOCK_KEY, adj_g)
                    adj_g = AdjacencyGraphBuilder.condense_graph_by_level(
                        Block.BLOCK_KEY, adj_g)

                # Transferring the graph to be undirected
                condensed_graph_sku = adj_g.to_undirected()

                # Calculating all the components in the graph
                components = list(
                    nx.connected_component_subgraphs(condensed_graph_sku))

                # Constructing the block_res df that will contain each block's data
                blocks_res = pd.DataFrame(
                    columns=['component', 'sum_of_facings', 'num_of_shelves'])

                # For each component in the graph calculate the blocks data
                for component in components:
                    component_data = self.calculate_block_data(
                        component, relevant_matches_for_block)

                    blocks_res = blocks_res.append(component_data)

                total_facings = blocks_res['sum_of_facings'].sum()

                # For each block check if its valid or not
                for row in blocks_res.itertuples():

                    if not row.sum_of_facings:
                        continue

                    orientation = None

                    # Calculate facing percentage
                    facing_percentage = np.divide(float(row.sum_of_facings),
                                                  float(total_facings))
                    if (facing_percentage >= block_parameters[AdditionalAttr.MINIMUM_BLOCK_RATIO]) and \
                            (row.sum_of_facings >= block_parameters[AdditionalAttr.MINIMUM_FACING_FOR_BLOCK]):

                        # If needed, calculate the block's orientation
                        if block_parameters[
                                AdditionalAttr.CHECK_VERTICAL_HORIZONTAL]:
                            orientation = self.handle_horizontal_and_vertical(
                                row.component, row.num_of_shelves)

                        results_df = results_df.append(
                            pd.DataFrame(columns=[
                                ColumnNames.CLUSTER, ColumnNames.SCENE_FK,
                                ColumnNames.ORIENTATION,
                                ColumnNames.FACING_PERCENTAGE,
                                ColumnNames.IS_BLOCK
                            ],
                                         data=[[
                                             row.component, scene, orientation,
                                             facing_percentage, True
                                         ]]))
                        if not block_parameters[
                                AdditionalAttr.CALCULATE_ALL_SCENES]:
                            return results_df
                    else:
                        results_df = results_df.append(
                            pd.DataFrame(columns=[
                                ColumnNames.CLUSTER, ColumnNames.SCENE_FK,
                                ColumnNames.ORIENTATION,
                                ColumnNames.FACING_PERCENTAGE,
                                ColumnNames.IS_BLOCK
                            ],
                                         data=[[
                                             row.component, scene, orientation,
                                             facing_percentage, False
                                         ]]))

            except AttributeError as err:
                Log.error('{}'.format(err))
                continue
            except Exception as err:
                Log.error('{}'.format(err))
                return results_df
        return results_df
Example #33
0
    def __mul__(self, scaling_matrix):
        """
        Replicates the graph, creating a supercell,
        intelligently joining together
        edges that lie on periodic boundaries.
        In principle, any operations on the expanded
        graph could also be done on the original
        graph, but a larger graph can be easier to
        visualize and reason about.
        :param scaling_matrix: same as Structure.__mul__
        :return:
        """

        # Developer note: a different approach was also trialed, using
        # a simple Graph (instead of MultiDiGraph), with node indices
        # representing both site index and periodic image. Here, the
        # number of nodes != number of sites in the Structure. This
        # approach has many benefits, but made it more difficult to
        # keep the graph in sync with its corresponding Structure.

        # Broadly, it would be easier to multiply the Structure
        # *before* generating the StructureGraph, but this isn't
        # possible when generating the graph using critic2 from
        # charge density.

        # Multiplication works by looking for the expected position
        # of an image node, and seeing if that node exists in the
        # supercell. If it does, the edge is updated. This is more
        # computationally expensive than just keeping track of the
        # which new lattice images present, but should hopefully be
        # easier to extend to a general 3x3 scaling matrix.

        # code adapted from Structure.__mul__
        scale_matrix = np.array(scaling_matrix, np.int16)
        if scale_matrix.shape != (3, 3):
            scale_matrix = np.array(scale_matrix * np.eye(3), np.int16)
        else:
            # TODO: test __mul__ with full 3x3 scaling matrices
            raise NotImplementedError('Not tested with 3x3 scaling matrices yet.')
        new_lattice = Lattice(np.dot(scale_matrix, self.structure.lattice.matrix))

        f_lat = lattice_points_in_supercell(scale_matrix)
        c_lat = new_lattice.get_cartesian_coords(f_lat)

        new_sites = []
        new_graphs = []

        for v in c_lat:

            # create a map of nodes from original graph to its image
            mapping = {n: n + len(new_sites) for n in range(len(self.structure))}

            for idx, site in enumerate(self.structure):

                s = PeriodicSite(site.species_and_occu, site.coords + v,
                                 new_lattice, properties=site.properties,
                                 coords_are_cartesian=True, to_unit_cell=False)

                new_sites.append(s)

            new_graphs.append(nx.relabel_nodes(self.graph, mapping, copy=True))

        new_structure = Structure.from_sites(new_sites)

        # merge all graphs into one big graph
        new_g = nx.MultiDiGraph()
        for new_graph in new_graphs:
            new_g = nx.union(new_g, new_graph)

        edges_to_remove = []  # tuple of (u, v, k)
        edges_to_add = []  # tuple of (u, v, attr_dict)

        # list of new edges inside supercell
        # for duplicate checking
        edges_inside_supercell = [{u, v} for u, v, d in new_g.edges(data=True)
                                  if d['to_jimage'] == (0, 0, 0)]
        new_periodic_images = []

        orig_lattice = self.structure.lattice

        # use k-d tree to match given position to an
        # existing Site in Structure
        kd_tree = KDTree(new_structure.cart_coords)

        # tolerance in Å for sites to be considered equal
        # this could probably be a lot smaller
        tol = 0.05

        for u, v, k, d in new_g.edges(keys=True, data=True):

            to_jimage = d['to_jimage']  # for node v

            # reduce unnecessary checking
            if to_jimage != (0, 0, 0):

                # get index in original site
                n_u = u % len(self.structure)
                n_v = v % len(self.structure)

                # get fractional co-ordinates of where atoms defined
                # by edge are expected to be, relative to original
                # lattice (keeping original lattice has
                # significant benefits)
                v_image_frac = np.add(self.structure[n_v].frac_coords, to_jimage)
                u_frac = self.structure[n_u].frac_coords

                # using the position of node u as a reference,
                # get relative Cartesian co-ordinates of where
                # atoms defined by edge are expected to be
                v_image_cart = orig_lattice.get_cartesian_coords(v_image_frac)
                u_cart = orig_lattice.get_cartesian_coords(u_frac)
                v_rel = np.subtract(v_image_cart, u_cart)

                # now retrieve position of node v in
                # new supercell, and get absolute Cartesian
                # co-ordinates of where atoms defined by edge
                # are expected to be
                v_expec = new_structure[u].coords + v_rel

                # now search in new structure for these atoms
                # query returns (distance, index)
                v_present = kd_tree.query(v_expec)
                v_present = v_present[1] if v_present[0] <= tol else None

                # check if image sites now present in supercell
                # and if so, delete old edge that went through
                # periodic boundary
                if v_present is not None:

                    new_u = u
                    new_v = v_present
                    new_d = d.copy()

                    # node now inside supercell
                    new_d['to_jimage'] = (0, 0, 0)

                    edges_to_remove.append((u, v, k))

                    # make sure we don't try to add duplicate edges
                    # will remove two edges for everyone one we add
                    if {new_u, new_v} not in edges_inside_supercell:

                        # normalize direction
                        if new_v < new_u:
                            new_u, new_v = new_v, new_u

                        edges_inside_supercell.append({new_u, new_v})
                        edges_to_add.append((new_u, new_v, new_d))

                else:

                    # want to find new_v such that we have
                    # full periodic boundary conditions
                    # so that nodes on one side of supercell
                    # are connected to nodes on opposite side

                    v_expec_frac = new_structure.lattice.get_fractional_coords(v_expec)

                    # find new to_jimage
                    # use np.around to fix issues with finite precision leading to incorrect image
                    v_expec_image = np.around(v_expec_frac, decimals=3)
                    v_expec_image = v_expec_image - v_expec_image%1

                    v_expec_frac = np.subtract(v_expec_frac, v_expec_image)
                    v_expec = new_structure.lattice.get_cartesian_coords(v_expec_frac)
                    v_present = kd_tree.query(v_expec)
                    v_present = v_present[1] if v_present[0] <= tol else None

                    if v_present is not None:

                        new_u = u
                        new_v = v_present
                        new_d = d.copy()
                        new_to_jimage = tuple(map(int, v_expec_image))

                        # normalize direction
                        if new_v < new_u:
                            new_u, new_v = new_v, new_u
                            new_to_jimage = tuple(np.multiply(-1, d['to_jimage']).astype(int))

                        new_d['to_jimage'] = new_to_jimage

                        edges_to_remove.append((u, v, k))

                        if (new_u, new_v, new_to_jimage) not in new_periodic_images:
                            edges_to_add.append((new_u, new_v, new_d))
                            new_periodic_images.append((new_u, new_v, new_to_jimage))

        logger.debug("Removing {} edges, adding {} new edges.".format(len(edges_to_remove),
                                                                      len(edges_to_add)))

        # add/delete marked edges
        for edges_to_remove in edges_to_remove:
            new_g.remove_edge(*edges_to_remove)
        for (u, v, d) in edges_to_add:
            new_g.add_edge(u, v, **d)

        # return new instance of StructureGraph with supercell
        d = {"@module": self.__class__.__module__,
             "@class": self.__class__.__name__,
             "structure": new_structure.as_dict(),
             "graphs": json_graph.adjacency_data(new_g)}

        sg = StructureGraph.from_dict(d)

        return sg
Example #34
0
 def serialize(self):
     return json_graph.adjacency_data(self._graph)
Example #35
0
def get_prereq_graph(course_id, format=None):
    """
    Generate a graph of prerequisites within a course. If format is not
    requested, simply return a NetworkX graph object.

    couse_id: the ID of the requested course
    format:   what format to return in (optional)
                  node: json formatted as node-link style
                  adjacency: json formatted as adjacency style
                  tree: json formatted as tree style
    """

    from trajectory.models import Department, Course
    from trajectory.models.meta import session
    from trajectory.utils.common import row2dict

    from networkx.readwrite import json_graph
    import networkx as nx
    import json

    if format not in [None, "node", "adjacency", "tree"]:
        raise RuntimeError("Unknown requested data format %s" % format)

    # Initialize a new NetworkX graph.
    G = nx.DiGraph()

    # Attempt to look up the requested course.
    course = session.query(Course).get(course_id)
    if course is None:
        return None

    # Recursively add course ids in a subtree to the graph.
    def add_tree(G, tree, parent=None):
        cid = tree[0]   # unpack information
        prereqs = tree[1]  # unpack information
        course = session.query(Course).get(cid)

        # Insert all known data, including department abbreviation.
        node_data = row2dict(course)
        node_data['dept'] = course.department.abbreviation

        # Identify the primary course in the graph (the requested).
        if str(cid) == str(course_id):
            node_data['prime'] = True
        else:
            node_data['prime'] = False

        # If the course has already been added, generate a unique ID for it
        # based on its parent, and add it anyway. But don't recurse into
        # its list of prereqs.
        seen = False
        if cid in G.nodes():
            cid = str(parent) + "-" + str(cid)
            seen = True

        # Add course and an edge from its parent, if relevant.
        G.add_node(cid, node_data)
        if parent is not None:
            G.add_edge(parent, cid)

        # Recurse through the prerequisite tree and add in subtrees.
        if not seen:
            for prereq in prereqs:
                add_tree(G, prereq, cid)

    # Navigate the prerequisite tree and add the course ids as nodes, and
    # prerequisite relationships as unweighted edges.
    prereq_tree = get_prereq_tree(course_id)
    add_tree(G, prereq_tree)

    if G is None:
        return G

    # Calculate and apply a basic layout.
    pos = nx.spring_layout(G)
    for node in G.nodes():
        G.node[node]["viz"] = {
            'position': {
                'x': pos[node][0],
                'y': pos[node][1]
            }
        }

    # Apply any requested data output formatting.
    if format == "node":
        return json.dumps(json_graph.node_link_data(G))
    elif format == "adjacency":
        return json.dumps(json_graph.adjacency_data(G))
    elif format == "tree":
        return json.dumps(json_graph.tree_data(G, int(course_id)))
    else:
        return G
import json
import glob

# Blockgroups 20
bg_dgs = glob.glob("bg20_dgs/*")

for dg in bg_dgs:
    st_name = dg.split("/")[-1].split(".")[0]

    with open(dg) as fin:
        data = json.load(fin)

    graph = json_graph.adjacency_graph(data)
    mapping = {n: graph.nodes()[n]["GEOID20"] for n in graph.nodes()}
    nx.relabel.relabel_nodes(graph, mapping=mapping, copy=False)
    data_out = json_graph.adjacency_data(graph)
    node_data = [{"id": n["id"]} for n in data_out["nodes"]]
    data_out["nodes"] = node_data
    with open("graphs/{}_blockgroups20.json".format(st_name), "w") as fout:
        json.dump(data_out, fout)

# VTDs 20
vtd_dgs = glob.glob("vtd_dg/*")

for dg in vtd_dgs:
    st_name = dg.split("/")[-1].split(".")[0]

    with open(dg) as fin:
        data = json.load(fin)

    graph = json_graph.adjacency_graph(data)
Example #37
0
if __name__ == '__main__':
    graph = nx.read_edgelist('input/example_graph.edgelist', nodetype=int, data=(('weight', float),))
    assert isinstance(graph, nx.Graph)
    print 'edges:', graph.edges()

    # raw
    nx.write_adjlist(graph, 'output_raw/example_graph.adjlist')
    nx.write_multiline_adjlist(graph, 'output_raw/example_graph.multiline_adjlist')
    nx.write_edgelist(graph, 'output_raw/example_graph.edgelist')

    # better serialization
    nx.write_gpickle(graph, 'output_serialization/example_graph.pickle')
    nx.write_yaml(graph, 'output_serialization/example_graph.yaml')
    nx.write_graph6(graph, 'output_serialization/example_graph.graph6')

    # xml
    nx.write_gexf(graph, 'output_xml/example_graph.gexf')
    nx.write_graphml(graph, 'output_xml/example_graph.graphml')

    # json
    with open('output_json/node_link.json', 'w') as outfile:
        json.dump(json_graph.node_link_data(graph), outfile, indent=2)

    with open('output_json/adjacency.json', 'w') as outfile:
        json.dump(json_graph.adjacency_data(graph), outfile, indent=2)

    # other
    nx.write_gml(graph, 'output_other/example_graph.gml')
    nx.write_pajek(graph, 'output_other/example_graph.pajek')
def json_graph_list_dump(graph_list,file):
    with open_filename(file,'w') as f:
        json.dump([json_graph.adjacency_data(graph) for graph in graph_list],f)
    pass
Example #39
0
    def __mul__(self, scaling_matrix):
        """
        Replicates the graph, creating a supercell,
        intelligently joining together
        edges that lie on periodic boundaries.
        In principle, any operations on the expanded
        graph could also be done on the original
        graph, but a larger graph can be easier to
        visualize and reason about.
        :param scaling_matrix: same as Structure.__mul__
        :return:
        """

        # Developer note: a different approach was also trialed, using
        # a simple Graph (instead of MultiDiGraph), with node indices
        # representing both site index and periodic image. Here, the
        # number of nodes != number of sites in the Structure. This
        # approach has many benefits, but made it more difficult to
        # keep the graph in sync with its corresponding Structure.

        # Broadly, it would be easier to multiply the Structure
        # *before* generating the StructureGraph, but this isn't
        # possible when generating the graph using critic2 from
        # charge density.

        # Multiplication works by looking for the expected position
        # of an image node, and seeing if that node exists in the
        # supercell. If it does, the edge is updated. This is more
        # computationally expensive than just keeping track of the
        # which new lattice images present, but should hopefully be
        # easier to extend to a general 3x3 scaling matrix.

        # code adapted from Structure.__mul__
        scale_matrix = np.array(scaling_matrix, np.int16)
        if scale_matrix.shape != (3, 3):
            scale_matrix = np.array(scale_matrix * np.eye(3), np.int16)
        else:
            # TODO: test __mul__ with full 3x3 scaling matrices
            raise NotImplementedError('Not tested with 3x3 scaling matrices yet.')
        new_lattice = Lattice(np.dot(scale_matrix, self.structure.lattice.matrix))

        f_lat = lattice_points_in_supercell(scale_matrix)
        c_lat = new_lattice.get_cartesian_coords(f_lat)

        new_sites = []
        new_graphs = []

        for v in c_lat:

            # create a map of nodes from original graph to its image
            mapping = {n: n + len(new_sites) for n in range(len(self.structure))}

            for idx, site in enumerate(self.structure):

                s = PeriodicSite(site.species_and_occu, site.coords + v,
                                 new_lattice, properties=site.properties,
                                 coords_are_cartesian=True, to_unit_cell=False)

                new_sites.append(s)

            new_graphs.append(nx.relabel_nodes(self.graph, mapping, copy=True))

        new_structure = Structure.from_sites(new_sites)

        # merge all graphs into one big graph
        new_g = nx.MultiDiGraph()
        for new_graph in new_graphs:
            new_g = nx.union(new_g, new_graph)

        edges_to_remove = []  # tuple of (u, v, k)
        edges_to_add = []  # tuple of (u, v, attr_dict)

        # list of new edges inside supercell
        # for duplicate checking
        edges_inside_supercell = [{u, v} for u, v, d in new_g.edges(data=True)
                                  if d['to_jimage'] == (0, 0, 0)]
        new_periodic_images = []

        orig_lattice = self.structure.lattice

        # use k-d tree to match given position to an
        # existing Site in Structure
        kd_tree = KDTree(new_structure.cart_coords)

        # tolerance in Å for sites to be considered equal
        # this could probably be a lot smaller
        tol = 0.05

        for u, v, k, d in new_g.edges(keys=True, data=True):

            to_jimage = d['to_jimage']  # for node v

            # reduce unnecessary checking
            if to_jimage != (0, 0, 0):

                # get index in original site
                n_u = u % len(self.structure)
                n_v = v % len(self.structure)

                # get fractional co-ordinates of where atoms defined
                # by edge are expected to be, relative to original
                # lattice (keeping original lattice has
                # significant benefits)
                v_image_frac = np.add(self.structure[n_v].frac_coords, to_jimage)
                u_frac = self.structure[n_u].frac_coords

                # using the position of node u as a reference,
                # get relative Cartesian co-ordinates of where
                # atoms defined by edge are expected to be
                v_image_cart = orig_lattice.get_cartesian_coords(v_image_frac)
                u_cart = orig_lattice.get_cartesian_coords(u_frac)
                v_rel = np.subtract(v_image_cart, u_cart)

                # now retrieve position of node v in
                # new supercell, and get absolute Cartesian
                # co-ordinates of where atoms defined by edge
                # are expected to be
                v_expec = new_structure[u].coords + v_rel

                # now search in new structure for these atoms
                # query returns (distance, index)
                v_present = kd_tree.query(v_expec)
                v_present = v_present[1] if v_present[0] <= tol else None

                # check if image sites now present in supercell
                # and if so, delete old edge that went through
                # periodic boundary
                if v_present is not None:

                    new_u = u
                    new_v = v_present
                    new_d = d.copy()

                    # node now inside supercell
                    new_d['to_jimage'] = (0, 0, 0)

                    edges_to_remove.append((u, v, k))

                    # make sure we don't try to add duplicate edges
                    # will remove two edges for everyone one we add
                    if {new_u, new_v} not in edges_inside_supercell:

                        # normalize direction
                        if new_v < new_u:
                            new_u, new_v = new_v, new_u

                        edges_inside_supercell.append({new_u, new_v})
                        edges_to_add.append((new_u, new_v, new_d))

                else:

                    # want to find new_v such that we have
                    # full periodic boundary conditions
                    # so that nodes on one side of supercell
                    # are connected to nodes on opposite side

                    v_expec_frac = new_structure.lattice.get_fractional_coords(v_expec)

                    # find new to_jimage
                    # use np.around to fix issues with finite precision leading to incorrect image
                    v_expec_image = np.around(v_expec_frac, decimals=3)
                    v_expec_image = v_expec_image - v_expec_image%1

                    v_expec_frac = np.subtract(v_expec_frac, v_expec_image)
                    v_expec = new_structure.lattice.get_cartesian_coords(v_expec_frac)
                    v_present = kd_tree.query(v_expec)
                    v_present = v_present[1] if v_present[0] <= tol else None

                    if v_present is not None:

                        new_u = u
                        new_v = v_present
                        new_d = d.copy()
                        new_to_jimage = tuple(map(int, v_expec_image))

                        # normalize direction
                        if new_v < new_u:
                            new_u, new_v = new_v, new_u
                            new_to_jimage = tuple(np.multiply(-1, d['to_jimage']).astype(int))

                        new_d['to_jimage'] = new_to_jimage

                        edges_to_remove.append((u, v, k))

                        if (new_u, new_v, new_to_jimage) not in new_periodic_images:
                            edges_to_add.append((new_u, new_v, new_d))
                            new_periodic_images.append((new_u, new_v, new_to_jimage))

        logger.debug("Removing {} edges, adding {} new edges.".format(len(edges_to_remove),
                                                                      len(edges_to_add)))

        # add/delete marked edges
        for edges_to_remove in edges_to_remove:
            new_g.remove_edge(*edges_to_remove)
        for (u, v, d) in edges_to_add:
            new_g.add_edge(u, v, **d)

        # return new instance of StructureGraph with supercell
        d = {"@module": self.__class__.__module__,
             "@class": self.__class__.__name__,
             "structure": new_structure.as_dict(),
             "graphs": json_graph.adjacency_data(new_g)}

        sg = StructureGraph.from_dict(d)

        return sg
Example #40
0
 def to_json(self):
   return json_graph.adjacency_data(self.network)
Example #41
0
 def to_json(self):
     return json_graph.adjacency_data(self.network)
Example #42
0
 def saveGraph(self):
     data = json_graph.adjacency_data(self.G)
     with open('graph.json', 'w') as outfile:
         json.dump(data, outfile, cls=SetEncoder)
Example #43
0
def communities(args, neighbor_weight=None):
    graphname = args.graphname or 'network'
    edge_weights = args.weight
    vertex_weights = str('FamilyFrequency')
    normalize = args.normalize
    edgefilter = args.edgefilter
    threshold = args.threshold or 1
    neighbor_weight = neighbor_weight or 5

    _graph = args.api.load_graph(graphname, threshold, edgefilter)
    args.log.info('loaded graph')
    for n, d in tqdm(_graph.nodes(data=True), desc='vertex-weights', leave=False):
        d[vertex_weights] = int(d[vertex_weights])

    if normalize:
        for edgeA, edgeB, data in tqdm(_graph.edges(data=True), desc='normalizing', leave=False):
            data[str('weight')] = data[edge_weights] ** 2 / (
                _graph.node[edgeA][vertex_weights] +
                _graph.node[edgeB][vertex_weights] -
                data[edge_weights])
        vertex_weights = None
        edge_weights = 'weight'
        args.log.info('computed weights')

    graph = networkx2igraph(_graph)
    args.log.info('starting infomap')
    args.log.info('converted graph...')

    comps = graph.community_infomap(
        edge_weights=str(edge_weights), vertex_weights=vertex_weights)

    args.log.info('finished infomap')
    D, Com = {}, defaultdict(list)
    for i, comp in enumerate(sorted(comps.subgraphs(), key=lambda x: len(x.vs), reverse=True)):
        for vertex in [v['name'] for v in comp.vs]:
            D[graph.vs[vertex]['ConcepticonId']] = str(i + 1)
            Com[i + 1].append(graph.vs[vertex]['ConcepticonId'])

    for node, data in _graph.nodes(data=True):
        data['infomap'] = D[node]
        data['ClusterName'] = ''
        data['CentralConcept'] = ''

    # get the articulation points etc. immediately
    for idx, nodes in sorted(Com.items()):
        sg = _graph.subgraph(nodes)
        if len(sg) > 1:
            d_ = sorted(sg.degree(), key=lambda x: x[1], reverse=True)
            d = [_graph.node[a]['Gloss'] for a, b in d_][0]
            cluster_name = 'infomap_{0}_{1}'.format(idx, d)
        else:
            d = _graph.node[nodes[0]]['Gloss']
            cluster_name = 'infomap_{0}_{1}'.format(idx, _graph.node[nodes[0]]['Gloss'])
        args.log.debug(cluster_name, d)
        for node in nodes:
            _graph.node[node]['ClusterName'] = cluster_name
            _graph.node[node]['CentralConcept'] = d

    args.log.info('computed cluster names')

    cluster_dir = args.api.existing_dir('app', 'cluster', clean=True)
    cluster_names = {}
    removed = []
    for idx, nodes in tqdm(sorted(Com.items()), desc='export to app', leave=False):
        sg = _graph.subgraph(nodes)
        for node, data in sg.nodes(data=True):
            data['OutEdge'] = []
            neighbors = [
                n for n in _graph if
                n in _graph[node] and
                _graph[node][n]['FamilyWeight'] >= neighbor_weight and
                n not in sg]
            if neighbors:
                sg.node[node]['OutEdge'] = []
                for n in neighbors:
                    sg.node[node]['OutEdge'].append([
                        _graph.node[n]['ClusterName'],
                        _graph.node[n]['CentralConcept'],
                        _graph.node[n]['Gloss'],
                        _graph[node][n]['WordWeight'],
                        n
                    ])
        if len(sg) > 1:
            jsonlib.dump(
                json_graph.adjacency_data(sg),
                cluster_dir / (_graph.node[nodes[0]]['ClusterName'] + '.json'),
                sort_keys=True)
            for node in nodes:
                cluster_names[_graph.node[node]['Gloss']] = _graph.node[node]['ClusterName']
        else:
            removed += [list(nodes)[0]]
    _graph.remove_nodes_from(removed)
    for node, data in _graph.nodes(data=True):
        if 'OutEdge' in data:
            data['OutEdge'] = '//'.join(['/'.join([str(y) for y in x]) for x in data['OutEdge']])
    removed = []
    for nA, nB, data in tqdm(_graph.edges(data=True), desc='remove edges', leave=False):
        if _graph.node[nA]['infomap'] != _graph.node[nB]['infomap'] and data['FamilyWeight'] < 5:
            removed += [(nA, nB)]
    _graph.remove_edges_from(removed)

    args.api.save_graph(_graph, 'infomap', threshold, edgefilter)
    args.api.write_js_var('INFO', cluster_names, 'app', 'source', 'infomap-names.js')
Example #44
0
def adjacency_data_json():
    H = generate_complete_graph()
    return json.dumps(json_graph.adjacency_data(H))
Example #45
0
                sys.stdout.flush()
            count += 1
            trace = get_trace(f)
            if not trace: break
            last_trace = trace
            add_hops_to_graph(G, trace)
    
    print "\nSetting source"
    global source
    source = last_trace['source']
    print_stats(G)
    return G

G = getGraph()

print "Pruning"
min_weight = 5000 # If you want to prune to a very high number (basically no pruning), set this to 1 instead.
while G.number_of_nodes() > N:
    min_weight += 1
    prune(G, min_weight, source)

print "Pruned the graph!"
print_stats(G)

import geodb
geo_data = {n: geodb.get_geo(n) for n in G.nodes()}

data = {'graph': json_graph.adjacency_data(G), 'geo': geo_data}
with open("data/backbone.json", "w") as f:
    json.dump(data, f)
 def to_jsongraph(graph):
     return json.dumps(json_graph.adjacency_data(graph))
Example #47
0
def tree_ready_json(asn):
    H = flare_tree_as_json_for_asn(asn)
    return json.dumps(json_graph.adjacency_data(H))
Example #48
0
def subgraph(args, neighbor_weight=None):
    args.api._log = args.log
    graphname = args.graphname or 'network'
    threshold = args.threshold or 1
    edgefilter = args.edgefilter
    neighbor_weight = neighbor_weight or 5

    _graph = args.api.load_graph(graphname, threshold, edgefilter)
    for node, data in _graph.nodes(data=True):
        generations = [{node}]
        while generations[-1] and len(set.union(*generations)) < 30 and len(generations) < 3:
            nextgen = set.union(*[set(_graph[n].keys()) for n in generations[-1]])
            if len(nextgen) > 50:
                break  # pragma: no cover
            else:
                generations.append(set.union(*[set(_graph[n].keys()) for n in generations[-1]]))
        data['subgraph'] = list(set.union(*generations))

    args.api.save_graph(_graph, 'subgraph', threshold, edgefilter)

    outdir = args.api.existing_dir('app', 'subgraph', clean=True)
    cluster_names = {}
    nodes2cluster = {}
    nidx = 1
    for node, data in tqdm(
            sorted(_graph.nodes(data=True), key=lambda x: len(x[1]['subgraph']), reverse=True),
            leave=False):
        nodes = tuple(sorted(data['subgraph']))
        sg = _graph.subgraph(data['subgraph'])
        if nodes not in nodes2cluster:
            d_ = sorted(sg.degree(), key=lambda x: x[1], reverse=True)
            d = [_graph.node[a]['Gloss'] for a, b in d_][0]
            nodes2cluster[nodes] = 'subgraph_{0}_{1}'.format(nidx, d)
            nidx += 1
        cluster_name = nodes2cluster[nodes]
        data['ClusterName'] = cluster_name
        for n, d in sg.nodes(data=True):
            d['OutEdge'] = []
            neighbors = [
                n_ for n_ in _graph if
                n_ in _graph[node] and
                _graph[node][n_]['FamilyWeight'] >= neighbor_weight and
                n_ not in sg]
            if neighbors:
                sg.node[node]['OutEdge'] = []
                for n_ in neighbors:
                    sg.node[node]['OutEdge'].append([
                        'subgraph_' + n_ + '_' + _graph.node[n]['Gloss'],
                        _graph.node[n_]['Gloss'],
                        _graph.node[n_]['Gloss'],
                        _graph[node][n_]['FamilyWeight'],
                        n_
                    ])
                    sg.node[node]['OutEdge'].append([
                        _graph.node[n]['ClusterName'],
                        _graph.node[n]['CentralConcept'],
                        _graph.node[n]['Gloss'],
                        _graph[node][n]['WordWeight'],
                        n
                    ])
        if len(sg) > 1:
            jsonlib.dump(
                json_graph.adjacency_data(sg), outdir / (cluster_name + '.json'), sort_keys=True)
            cluster_names[data['Gloss']] = cluster_name

    for node, data in _graph.nodes(data=True):
        if 'OutEdge' in data:
            data['OutEdge'] = '//'.join([str(x) for x in data['OutEdge']])
    args.api.write_js_var('SUBG', cluster_names, 'app', 'source', 'subgraph-names.js')
Example #49
0
def get_structure_components(bonded_structure, inc_orientation=False,
                             inc_site_ids=False, inc_molecule_graph=False):
    """
    Gets information on the components in a bonded structure.

    Correctly determines the dimensionality of all structures, regardless of
    structure type or improper connections due to periodic boundary conditions.

    Requires a StructureGraph object as input. This can be generated using one
    of the NearNeighbor classes. For example, using the CrystalNN class::

        bonded_structure = CrystalNN().get_bonded_structure(structure)

    Based on the modified breadth-first-search algorithm described in:

    P. Larsem, M. Pandey, M. Strange, K. W. Jacobsen, 2018, arXiv:1808.02114

    Args:
        bonded_structure (StructureGraph): A structure with bonds, represented
            as a pymatgen structure graph. For example, generated using the
            CrystalNN.get_bonded_structure() method.
        inc_orientation (bool, optional): Whether to include the orientation
            of the structure component. For surfaces, the miller index is given,
            for one-dimensional structures, the direction of the chain is given.
        inc_site_ids (bool, optional): Whether to include the site indices
            of the sites in the structure component.
        inc_molecule_graph (bool, optional): Whether to include MoleculeGraph
            objects for zero-dimensional components.

    Returns:
        (list of dict): Information on the components in a structure as a list
        of dictionaries with the keys:

        - "structure_graph": A pymatgen StructureGraph object for the
            component.
        - "dimensionality": The dimensionality of the structure component as an
            int.
        - "orientation": If inc_orientation is `True`, the orientation of the
            component as a tuple. E.g. (1, 1, 1)
        - "site_ids": If inc_site_ids is `True`, the site indices of the
            sites in the component as a tuple.
        - "molecule_graph": If inc_molecule_graph is `True`, the site a
            MoleculeGraph object for zero-dimensional components.
    """
    import networkx as nx  # optional dependency therefore not top level import

    comp_graphs = (bonded_structure.graph.subgraph(c) for c in
                   nx.weakly_connected_components(bonded_structure.graph))

    components = []
    for graph in comp_graphs:
        dimensionality, vertices = calculate_dimensionality_of_site(
            bonded_structure, list(graph.nodes())[0], inc_vertices=True)

        component = {'dimensionality': dimensionality}

        if inc_orientation:
            if dimensionality in [1, 2]:
                vertices = np.array(vertices)

                g = vertices.sum(axis=0) / vertices.shape[0]

                # run singular value decomposition
                _, _, vh = np.linalg.svd(vertices - g)

                # get direction (first column is best fit line,
                # 3rd column is unitary norm)
                index = 2 if dimensionality == 2 else 0
                orientation = get_integer_index(vh[index, :])
            else:
                orientation = None

            component['orientation'] = orientation

        if inc_site_ids:
            component['site_ids'] = tuple(graph.nodes())

        if inc_molecule_graph and dimensionality == 0:
            component['molecule_graph'] = zero_d_graph_to_molecule_graph(
                bonded_structure, graph)

        component_structure = Structure.from_sites(
            [bonded_structure.structure[n] for n in sorted(graph.nodes())])

        sorted_graph = nx.convert_node_labels_to_integers(
            graph, ordering="sorted")
        component_graph = StructureGraph(
            component_structure,
            graph_data=json_graph.adjacency_data(sorted_graph))
        component['structure_graph'] = component_graph

        components.append(component)
    return components
def json_graph_list_dumps(graph_list):
    return json.dumps([json_graph.adjacency_data(graph) for graph in graph_list])
Example #51
0
def save_graphs(graphs):
	for g,d in graphs.items():
		f = open(g, 'w')
		data = json_graph.adjacency_data(d)
		s = json.dump(data, f)
		f.close()