コード例 #1
0
ファイル: ProgramAnalysisGraph.py プロジェクト: hlim1/delphi
    def from_agraph(cls, A: AGraph, lambdas):
        """ Construct a ProgramAnalysisGraph from an AGraph """
        self = cls(nx.DiGraph())

        for n in A.nodes():
            if n.attr["node_type"] in ("LoopVariableNode", "FuncVariableNode"):
                self.add_variable_node(n)

        for n in A.nodes():
            if n.attr["node_type"] == "ActionNode":
                self.add_action_node(A, lambdas, n)

        for n in self.nodes(data=True):
            n_preds = len(n[1]["pred_fns"])
            if n_preds == 0:
                del n[1]["pred_fns"]
            elif n_preds == 1:
                n[1]["update_fn"], = n[1].pop("pred_fns")
            else:
                n[1]["choice_fns"] = n[1].pop("pred_fns")

                def update_fn(n, **kwargs):
                    cond_fn = n[1]["condition_fn"]
                    sig = signature(cond_fn)
                    ind = 0 if cond_fn(**kwargs) else 1
                    return n[1]["choice_fns"][ind](**kwargs)

                n[1]["update_fn"] = partial(update_fn, n)

        isolated_nodes = [
            n
            for n in self.nodes()
            if len(list(self.predecessors(n)))
            == len(list(self.successors(n)))
            == 0
        ]

        for n in isolated_nodes:
            self.remove_node(n)

        # Create lists of all input function and all input variables
        self.input_variables = list()
        self.input_functions = list()
        for n in self.nodes():
            if self.nodes[n].get("init_fn") is not None:
                self.input_functions.append(n)

            if (
                self.nodes[n]["node_type"]
                in ("LoopVariableNode", "FuncVariableNode")
                and len(list(self.predecessors(n))) == 0
            ):
                self.input_variables.append(n)

        return self
コード例 #2
0
def process_nodes(g: pgv.AGraph) -> Node:
    nodes = {str(gvnode): from_label(gvnode) for gvnode in g.nodes()}
    root_node = None
    for gvn, ndata in nodes.items():
        if 'this/RootNode' in ndata[1]:
            root_node = gvn
            break
    else:
        print("Error: cannot find root node\n")
        sys.exit(-1)

    def walk(rn: pgv.Node) -> Node:
        args_dict = {}
        for n in g.successors(rn):
            e = pgv.Edge(g, rn, n)
            m = re.match('^args\\s+\\[(\\d+)\\]$', e.attr['label'])
            assert m
            arg_idx = int(m.group(1))
            assert arg_idx not in args_dict
            args_dict[arg_idx] = walk(n)

        args = [args_dict[idx] for idx in range(len(args_dict))]

        return Node(*nodes[rn], args=args)

    return walk(root_node)
コード例 #3
0
ファイル: graph.py プロジェクト: fran-penedo/param-synth-web
def build_graph(ts):
    g = AGraph(directed=True)
    g.add_edges_from(ts.ts.todok().keys())
    g.graph_attr['overlap'] = 'scalexy'
    for n, s in zip(g.nodes(), ts._pwa.states):
        n.attr['label'] = s
    return g
コード例 #4
0
def gen_op_insts(rf_allocs: List[RFallocation], dfg: AGraph, fu: AGraph,
                 input_map: Dict[str, int]) -> List[ATAI]:
    assembly = []
    instructions: List[Instruction] = []

    for instruction in fu.nodes():
        instructions.append(parse_instruction(instruction))

    for instruction in instructions:
        n = dfg.get_node(instruction.name)
        nodes = dfg.predecessors(n)

        input_type0 = inst_input_type(rf_allocs, fu, nodes[0])
        if len(nodes) > 1:
            input_type1 = inst_input_type(rf_allocs, fu, nodes[1])
        else:
            input_type1 = input_type0

        # This should never occur but we check for it anyways
        if input_type0 == OpInput and input_type1 == OpInput:
            if nodes[0] != nodes[1]:
                raise DoubleUnidenticalOPInputException

        # TODO: find scheduling for fetch ops might need to be swapped to fit?
        if input_type0 == RFInput:
            # If the data is in the RF we need to generate fetch instructions
            assembly.append(
                generate_fetch(rf_allocs, instruction, nodes[0],
                               ATAFetch.REG.REG0))
            input0 = RFInput()
        elif input_type0 == OpInput:
            input0 = OpInput()
        else:
            n = input_map[nodes[0].get_name()]
            if n is None:
                raise FUinputException(
                    'Cannot find FU from which predecessing node originates in map'
                )

            input0 = FUinput(n)

        if input_type1 == RFInput:
            assembly.append(
                generate_fetch(rf_allocs, instruction, nodes[1],
                               ATAFetch.REG.REG1))
            input1 = RFInput()
        elif input_type1 == OpInput:
            input1 = OpInput()
        else:
            n = input_map[nodes[1].get_name()]
            if n is None:
                raise FUinputException(
                    'Cannot find FU from which predecessing node originates in map'
                )

            input1 = FUinput(n)

        assembly.append(ATAOp(input0, input1, instruction.cycle))

    return assembly
コード例 #5
0
def process_nodes(g: pgv.AGraph) -> Tuple[Node, bool]:

    nodes = {str(gvnode): from_label(gvnode) for gvnode in g.nodes()}
    root_node = None
    for gvn, ndata in nodes.items():
        if 'this/RootNode' in ndata[1]:
            root_node = gvn
            break
    else:
        print("Error: cannot find root node\n")
        sys.exit(-1)

    def walk(rn: pgv.Node) -> Tuple[Node, bool]:
        args_dict = {}
        correctness_holds = True

        for n in g.successors(rn):
            e = pgv.Edge(g, rn, n)
            m = re.match('^args\\s+\\[(\\d+)\\]$', e.attr['label'])
            assert m
            arg_idx = int(m.group(1))
            assert arg_idx not in args_dict
            args_dict[arg_idx], have_correctness = walk(n)
            if not have_correctness:
                correctness_holds = False

        args = [args_dict[idx] for idx in range(len(args_dict))]

        new_node = Node(*nodes[rn], args=args)
        if correctness_holds:
            correctness_holds = 'this/CorrectnessHolds' in new_node.sets

        return new_node, correctness_holds

    return walk(root_node)
コード例 #6
0
ファイル: tb_gen.py プロジェクト: FelixBrakel/uGenie-codegen
def gen_add_input2(
        dfg: AGraph, fu: AGraph,
        input_map: Dict[str, int]) -> Tuple[List[Input], List[Output]]:
    outputs: List[Output] = []
    inputs: List[Input] = []
    nodes: List[Instruction] = []
    for node in fu.nodes():
        nodes.append(parse_instruction(node))

    nodes.sort()
    prev_o = 0
    for node in nodes:
        preds = dfg.predecessors(node.name)
        parent0 = parse_instruction(preds[0])
        parent1 = parse_instruction(preds[1])

        if parent0.name in input_map:
            label = dfg.get_node(parent0.name).attr['label']
            if 'mul' in label:
                latency = 2
            else:
                latency = 1

            i0 = prev_o + 1
            inputs.append(
                Input(i0, input_map[parent0.name], parent0.cycle + latency))
        else:
            for output in outputs:
                if output.cycle == parent0.cycle + 1:
                    i0 = output.val
                    break

        if parent1.name in input_map:
            label = dfg.get_node(parent1.name).attr['label']
            if 'mul' in label:
                latency = 2
            else:
                latency = 1

            i1 = prev_o + 1
            inputs.append(
                Input(i1, input_map[parent1.name], parent1.cycle + latency))
        else:
            for output in outputs:
                if output.cycle == parent1.cycle + 1:
                    i1 = output.val
                    break

        expected = i0 + i1
        prev_o = expected
        outputs.append(Output(expected, node.cycle + 1))

    inputs.sort()
    return inputs, outputs
コード例 #7
0
    def from_agraph(cls, A: AGraph, lambdas):
        """ Construct a ProgramAnalysisGraph from an AGraph """
        G = nx.DiGraph()

        for n in A.nodes():
            if n.attr["node_type"] == "LoopVariableNode":
                add_variable_node(G, n)

        for n in A.nodes():
            if n.attr["node_type"] == "ActionNode":
                add_action_node(A, G, lambdas, n)

        for n in G.nodes(data=True):
            n_preds = len(n[1]["pred_fns"])
            if n_preds == 0:
                del n[1]["pred_fns"]
            elif n_preds == 1:
                n[1]["update_fn"], = n[1].pop("pred_fns")
            else:
                n[1]["choice_fns"] = n[1].pop("pred_fns")

                def update_fn(n, **kwargs):
                    cond_fn = n[1]["condition_fn"]
                    sig = signature(cond_fn)
                    ind = 0 if cond_fn(**kwargs) else 1
                    return n[1]["choice_fns"][ind](**kwargs)

                n[1]["update_fn"] = partial(update_fn, n)

        isolated_nodes = [
            n for n in G.nodes()
            if len(list(G.predecessors(n))) == len(list(G.successors(n))) == 0
        ]

        for n in isolated_nodes:
            G.remove_node(n)

        return cls(G)
コード例 #8
0
ファイル: visualization.py プロジェクト: hlim1/delphi
def _(
    G: ProgramAnalysisGraph,
    show_values=True,
    save=False,
    filename="program_analysis_graph.pdf",
    **kwargs,
):
    """ Visualizes ProgramAnalysisGraph in Jupyter notebook cell.

    Args:
        args
        kwargs

    Returns:
        AGraph
    """

    A = AGraph(directed=True)
    A.graph_attr.update({"dpi": 227, "fontsize": 20, "fontname": "Menlo"})
    A.node_attr.update({
        "shape": "rectangle",
        "color": "#650021",
        "style": "rounded",
        "fontname": "Gill Sans",
    })

    color_str = "#650021"

    for n in G.nodes():
        A.add_node(n, label=n)

    for e in G.edges(data=True):
        A.add_edge(e[0], e[1], color=color_str, arrowsize=0.5)

    if show_values:
        for n in A.nodes():
            value = str(G.nodes[n]["value"])
            n.attr["label"] = n.attr["label"] + f": {value:.4}"

    if save:
        A.draw(filename, prog=kwargs.get("layout", "dot"))

    return Image(A.draw(format="png", prog=kwargs.get("layout", "dot")),
                 retina=True)
    def draw_relations(self, relations, fname):
        def get_node_name(n):
            return n.__name__

        g= AGraph(directed=True)
        for n in relations:
            n_name= get_node_name(n)
            g.add_node(n_name)

        for relation in chain(*relations.values()):
            n1_name= get_node_name(relation.object1)
            n2_name= get_node_name(relation.object2)
            g.add_edge(n1_name, n2_name)

            e= g.get_edge(n1_name, n2_name)
            relation.set_edge_attributes(e)

        for n in g.nodes():
            n.attr['shape']= 'box'

        g.draw(fname, prog='dot', args='-Grankdir=TB')
コード例 #10
0
 def get_graphviz(self, triple_hook=graphviz_triple_hook,
                  node_hook=graphviz_node_hook,
                  theme_options=VIS_THEME_OPTIONS, **hook_options):
     """
     Create a pygraphviz graph from the tree
     @param triple_hook: a function that returns an attribute dict (or None)
                         given a triple and the kargs
     @param node_hook: a function that returns a label given a node
                        and the kargs
     @param theme_options: a dict-of-dicts containing global
                           graph/node/edge attributes
     @param hook_options: additional arguments to pass to the hook functions
     """
     def _id(node):
         return node.uri.split("/")[-1]
     g = AGraph(directed=True, strict=False)
     triples = list(self.get_triples())
     # create nodes
     nodeset = set(chain.from_iterable((t.subject, t.object)
                                       for t in triples))
     for n in sorted(nodeset, key=lambda n:n.id):
         g.add_node(_id(n), **node_hook(n, **hook_options))
     connected = set()
     # create edges
     for triple in sorted(triples, key=lambda t:t.predicate):
         kargs = triple_hook(triple, **hook_options)
         if kargs:
             if kargs.get('reverse'):
                 g.add_edge(_id(triple.object), _id(triple.subject), **kargs)
             else:
                 g.add_edge(_id(triple.subject), _id(triple.object), **kargs)
             connected |= {_id(triple.subject), _id(triple.object)}
     connected = chain.from_iterable(g.edges())
     for isolate in set(g.nodes()) - set(connected):
         g.remove_node(isolate)
     # some theme options
     for obj, attrs in theme_options.iteritems():
         for k, v in attrs.iteritems():
             getattr(g, "%s_attr" % obj)[k] = v
     return g
コード例 #11
0
ファイル: igraphtools.py プロジェクト: horvatha/cxnet
def igraph_from_dot(file):
    """numbered_graph(file) -> graph

  Input:
    file: the name of the dot-file 

  Output:
    graph: igraph.Graph object. Verticies has the attribute
         "name".
    """
    print("Step 1/3: Reading from dot.")
    a=AGraph(file)
    vertices = a.nodes()
    edges = a.edges()
    numbered_edges = []
    print("Step 2/3: To numbered graph. Be patient...")
    for x, y in edges:
        xx = vertices.index(x)
        yy = vertices.index(y)
        numbered_edges.append((xx,yy))
    print("Step 3/3: To igraph.")
    g=igraph.Graph(len(vertices), numbered_edges)
    g.vs["name"]=vertices
    return g
コード例 #12
0
    def visualize(self, show_values=False):
        """ Exports AnalysisGraph to pygraphviz AGraph

        Args:
            args
            kwargs

        Returns:
            AGraph
        """

        A = AGraph(directed=True)
        A.graph_attr.update({"dpi": 227, "fontsize": 20, "fontname": "Menlo"})
        A.node_attr.update({
            "shape": "rectangle",
            "color": "#650021",
            "style": "rounded",
            "fontname": "Gill Sans",
        })

        color_str = "#650021"

        for n in self.nodes():
            A.add_node(n, label=n)

        for e in self.edges(data=True):
            A.add_edge(e[0], e[1], color=color_str, arrowsize=0.5)

        if show_values:
            for n in A.nodes():
                value = str(self.nodes[n]["value"])
                n.attr["label"] = n.attr["label"] + f": {value:.4}"

        # Drawing indicator variables

        return Image(A.draw(format="png", prog="dot"), retina=True)
コード例 #13
0
ファイル: draw_graph.py プロジェクト: pythseq/gene_graph_lib
def get_graphviz_layout(input_subgraph,
                        ref_chain=[],
                        aim_chain=[],
                        freq_min=1,
                        draw_all=False):
    print('SD')
    ps = AGraph(directed=True)
    ps.graph_attr['rankdir'] = 'LR'
    ps.graph_attr['mode'] = 'hier'

    nodes = delete_nodes(ref_chain, input_subgraph[1], freq_min)

    print('Number of nodes: ', end='')
    if draw_all == False:
        print(len(nodes))

    elif draw_all == True:
        print(len(input_subgraph[1]))
    cluster_main = ps.add_subgraph()
    cluster_main.graph_attr['rank'] = '0'

    for i in range(len(ref_chain)):
        shape = 'circle'
        if ref_chain[i] in aim_chain:
            cluster_main.add_node(ref_chain[i], shape=shape, color='red')

        else:

            cluster_main.add_node(ref_chain[i], shape=shape, color='pink')

    for i in input_subgraph[0]:
        if i in aim_chain or i in ref_chain:
            continue

        if i in nodes:
            ps.add_node(str(i))
            continue

        else:
            if draw_all == True:
                ps.add_node(str(i), color='grey')
                continue

    for i in input_subgraph[1]:
        color = 'black'
        try:
            if ref_chain.index(i[1]) - ref_chain.index(i[0]) == 1:
                color = 'red'
                ps.add_edge(str(i[0]),
                            str(i[1]),
                            color=color,
                            penwidth=str(math.sqrt(i[2])))
                continue

        except ValueError:
            pass

        if i[2] < freq_min:

            if draw_all == True:
                ps.add_edge(str(i[0]),
                            str(i[1]),
                            color='grey',
                            penwidth=str(math.sqrt(i[2])),
                            constraint='false')

            continue

        elif i[0] in nodes and i[1] in nodes:
            ps.add_edge(str(i[0]),
                        str(i[1]),
                        color=color,
                        penwidth=str(math.sqrt(i[2])))

        elif draw_all == True:

            ps.add_edge(str(i[0]),
                        str(i[1]),
                        color='grey',
                        penwidth=str(math.sqrt(i[2])),
                        constraint='false')

    ps.layout(prog='dot')

    positions = {n: n.attr['pos'] for n in ps.nodes()}
    edge_points = {edge: edge.attr['pos'] for edge in ps.edges()}
    return positions, edge_points
コード例 #14
0
ファイル: main.py プロジェクト: anhptvolga/graphview
class UiGraphio(QMainWindow):
    """
        Main window for application
    """
    def __init__(self):
        """
        Constructor
        """
        QMainWindow.__init__(self)
        self.ui = graphio.Ui_MainWindow()
        self.ui.setupUi(self)

        self.scene_graph = QGraphicsScene()
        self.ui.graphicsView.setScene(self.scene_graph)
        self.ui.graphicsView.update()

        self.graph = AGraph(strict=True, directed=True)
        self.graph.layout(prog='dot')

    #####################################################
    # View update
    #####################################################
    def update_adj_matrix(self):
        count = self.graph.number_of_nodes()
        self.ui.tw_adjmatrix.setRowCount(count)
        self.ui.tw_adjmatrix.setColumnCount(count)

        self.ui.tw_adjmatrix.setHorizontalHeaderLabels(self.graph.nodes())
        self.ui.tw_adjmatrix.setVerticalHeaderLabels(self.graph.nodes())

        for (i, u) in enumerate(self.graph.nodes()):
            for (j, v) in enumerate(self.graph.nodes_iter()):
                if self.graph.has_edge(u, v):
                    self.ui.tw_adjmatrix.setItem(
                        i, j,
                        QTableWidgetItem(
                            self.graph.get_edge(u, v).attr['label']))
                else:
                    self.ui.tw_adjmatrix.setItem(i, j,
                                                 QTableWidgetItem(str(0)))

    def update_matrix_incidence(self):
        nodes = self.graph.nodes()
        edges = self.graph.edges()
        self.ui.tw_incmatrix.setRowCount(len(nodes))
        self.ui.tw_incmatrix.setColumnCount(len(edges))
        self.ui.tw_incmatrix.setHorizontalHeaderLabels(
            [str(node) for node in self.graph.edges()])
        self.ui.tw_incmatrix.setVerticalHeaderLabels(self.graph.nodes())
        for (i, u) in enumerate(nodes):
            for (j, edg) in enumerate(edges):
                value = 0
                if (u == edg[0]): value = 1
                elif (u == edg[1]): value = -1
                self.ui.tw_incmatrix.setItem(i, j,
                                             QTableWidgetItem(str(value)))

    def update_list_edges(self):
        edges = self.graph.edges()
        self.ui.tw_edges.setRowCount(len(edges))
        for (i, edge) in enumerate(edges):
            self.ui.tw_edges.setItem(i, 0, QTableWidgetItem(edge[0]))
            self.ui.tw_edges.setItem(i, 1, QTableWidgetItem(edge[1]))

    def update_adj_list(self):
        nodes = self.graph.nodes()
        self.ui.tw_adjlist.setRowCount(self.graph.number_of_nodes())
        self.ui.tw_adjlist.setVerticalHeaderLabels(nodes)
        for (i, node) in enumerate(nodes):
            value = ''
            for adj in self.graph.out_edges(node):
                value += adj[1] + ', '
            self.ui.tw_adjlist.setItem(i, 0, QTableWidgetItem(value[:-2]))

    #####################################################
    # Reset editors
    #####################################################
    def add_cb_item(self, label):
        n = self.ui.cb_nodes.count()
        i = 0
        while i < n:
            itext = self.ui.cb_nodes.itemText(i)
            if label == itext:
                return
            elif label < itext:
                break
            i += 1
        # insert item to lists
        self.ui.cb_nodes.insertItem(i, label)
        self.ui.cb_starting_node.insertItem(i, label)
        self.ui.cb_ending_node.insertItem(i, label)

    @pyqtSlot(bool, name='on_bt_add_node_clicked')
    @pyqtSlot(bool, name='on_bt_del_node_clicked')
    @pyqtSlot(bool, name='on_bt_add_edge_clicked')
    @pyqtSlot(bool, name='on_bt_del_edge_clicked')
    def reset_editors(self):
        self.ui.cb_nodes.clearEditText()
        self.ui.cb_starting_node.clearEditText()
        self.ui.cb_ending_node.clearEditText()
        self.ui.sb_weight_edge.setMinimum()

    def redraw(self):
        self.graph.draw('graph', 'png', 'dot')
        self.scene_graph.clear()
        self.scene_graph.addItem(QGraphicsPixmapItem(QPixmap('graph')))
        self.ui.graphicsView.update()

    #####################################################
    # Buttons actions
    #####################################################
    @pyqtSlot()
    def on_bt_add_node_clicked(self):
        """ Slot when click on Add node button """
        label = self.ui.cb_nodes.currentText()
        if not self.graph.has_node(label):
            self.add_cb_item(label)
            self.graph.add_node(label)
            self.redraw()

    @pyqtSlot()
    def on_bt_del_node_clicked(self):
        """ Slot when click on Delete node button """
        index = self.ui.cb_nodes.currentIndex()
        label = self.ui.cb_nodes.currentText()
        if index > -1 and self.graph.has_node(label):
            self.graph.remove_node(label)
            self.redraw()
            self.ui.cb_nodes.removeItem(index)
            self.ui.cb_starting_node.removeItem(index)
            self.ui.cb_ending_node.removeItem(index)

    @pyqtSlot()
    def on_bt_add_edge_clicked(self):
        """ Slot when click on Add branch button """
        start = self.ui.cb_starting_node.currentText()
        end = self.ui.cb_ending_node.currentText()
        weight = self.ui.sb_weight_edge.value()
        if start and end:
            self.add_cb_item(start)
            self.add_cb_item(end)
            self.graph.add_edge(start, end, label=weight)
            self.redraw()

    @pyqtSlot()
    def on_bt_del_edge_clicked(self):
        """ Slot when click on Delete branch button """
        start = self.ui.cb_starting_node.currentText()
        end = self.ui.cb_ending_node.currentText()
        weight = self.ui.sb_weight_edge.value()
        if start and end and self.graph.has_edge(start, end):
            self.graph.remove_edge(start, end)
            self.redraw()

    @pyqtSlot(int)
    @pyqtSlot(bool, name='on_bt_add_node_clicked')
    @pyqtSlot(bool, name='on_bt_del_node_clicked')
    @pyqtSlot(bool, name='on_bt_add_edge_clicked')
    @pyqtSlot(bool, name='on_bt_del_edge_clicked')
    def on_toolbox_view_currentChanged(self, index):
        index = self.ui.toolbox_view.currentIndex()
        if index == 0:
            self.update_adj_matrix()
        elif index == 1:
            self.update_matrix_incidence()
        elif index == 2:
            self.update_list_edges()
        elif index == 3:
            self.update_adj_list()
コード例 #15
0
ファイル: dot_layout.py プロジェクト: odedp/ivy
def dot_layout(cy_elements, edge_labels=False, subgraph_boxes=False, node_gt=None):
    """
    Get a CyElements object and augment it (in-place) with positions,
    widths, heights, and spline data from a dot based layout.

    edge_labels is true if labels should appear on edges
    subgraph_boxes is true if boxes should be drawn around subgraphs

    Returns the object.
    """
    elements = cy_elements.elements

    #    g = AGraph(directed=True, strict=False)
    g = AGraph(directed=True, strict=False, forcelabels=True)

    # make transitive relations appear top to bottom

    elements = list(elements)
    nodes_by_id = dict((e["data"]["id"], e) for e in elements if e["group"] == "nodes")
    order = [
        (nodes_by_id[e["data"]["source"]], nodes_by_id[e["data"]["target"]])
        for e in elements
        if e["group"] == "edges" and "transitive" in e["data"] and e["data"]["transitive"]
    ]
    elements = topological_sort(elements, order, lambda e: e["data"]["id"])

    # get the node id's and stable sort them by cluster
    # the idea here is to convert the graph into a dag by sorting
    # the nodes, then reversing the back edges. In particular, we try to make
    # all the edges between two clusters go in the same direction so clustering
    # doesn't result in horizontal edges, which dot renders badly.

    sorted_nodes = [e["data"]["id"] for e in elements if e["group"] == "nodes"]
    sorted_nodes = sorted(enumerate(sorted_nodes), key=lambda x: (nodes_by_id[x[1]]["data"]["cluster"], x[0]))
    sorted_nodes = [y for idx, y in sorted_nodes]
    node_key = dict((id, idx) for idx, id in enumerate(sorted_nodes))

    if node_gt is None:
        node_gt = lambda X, y: False
    else:
        node_gt = lambda x, y: node_key[x] > node_key[y]

    # add nodes to the graph
    for e in elements:
        if e["group"] == "nodes" and e["classes"] != "non_existing":
            g.add_node(e["data"]["id"], label=e["data"]["label"].replace("\n", "\\n"))

    # TODO: remove this, it's specific to leader_demo
    weight = {"reach": 10, "le": 10, "id": 1}
    constraint = {"pending": False}

    # add edges to the graph
    for e in elements:
        if e["group"] == "edges":
            #            kwargs = {'weight': weight.get(e["data"]["obj"], 0)},
            kwargs = {"label": e["data"]["label"]} if edge_labels else {}
            if node_gt(e["data"]["source"], e["data"]["target"]):
                g.add_edge(
                    e["data"]["target"],
                    e["data"]["source"],
                    e["data"]["id"],
                    dir="back",
                    **kwargs
                    # constraint=constraint.get(e["data"]["obj"], True),
                )
            else:
                g.add_edge(
                    e["data"]["source"],
                    e["data"]["target"],
                    e["data"]["id"],
                    **kwargs
                    # constraint=constraint.get(e["data"]["obj"], True),
                )

    # add clusters
    clusters = defaultdict(list)
    for e in elements:
        if e["group"] == "nodes" and e["data"]["cluster"] is not None and e["classes"] != "non_existing":
            clusters[e["data"]["cluster"]].append(e["data"]["id"])
    for i, k in enumerate(sorted(clusters.keys())):
        g.add_subgraph(name="cluster_{}".format(i), nbunch=clusters[k], rank="min")

    # now get positions, heights, widths, and bsplines
    g.layout(prog="dot")

    # get the y origin. we want the top left of the graph to be a
    # fixed coordinate (hopefully (0,0)) so the graph doesn't jump when
    # its height changes. Unfortunately, pygraphviz has a bug a gives
    # the wrong bbox, so we compute the max y coord.

    #    bbox = pygraphviz.graphviz.agget(g.handle,'bb')

    global y_origin
    y_origin = 0.0
    for n in g.nodes():
        top = float(n.attr["pos"].split(",")[1]) + float(n.attr["height"]) / 2
        if top > y_origin:
            y_origin = top
    if subgraph_boxes:
        for sg in g.subgraphs():
            top = float(sg.graph_attr["bb"].split(",")[3])
            if top > y_origin:
                y_origin = top

    for e in elements:
        if e["group"] == "nodes" and e["classes"] != "non_existing":
            attr = g.get_node(e["data"]["id"]).attr
            e["position"] = _to_position(attr["pos"])
            e["data"]["width"] = 72 * float(attr["width"])
            e["data"]["height"] = 72 * float(attr["height"])

        elif e["group"] == "edges":
            if node_gt(e["data"]["source"], e["data"]["target"]):
                attr = g.get_edge(e["data"]["target"], e["data"]["source"], e["data"]["id"]).attr
                pos = attr["pos"]
                pe = pos.split()
                ppe = pe[1:]
                ppe.reverse()
                pos = " ".join([pe[0].replace("s", "e")] + ppe)
            else:
                attr = g.get_edge(e["data"]["source"], e["data"]["target"], e["data"]["id"]).attr
                pos = attr["pos"]
            e["data"].update(_to_edge_position(pos))
            if edge_labels and e["data"]["label"] != "":
                e["data"]["lp"] = _to_position(attr["lp"])
    #    g.draw('g.png')

    if subgraph_boxes:
        for sg in g.subgraphs():
            box = cy_elements.add_shape(sg.name, classes="subgraphs")
            coords = _to_coord_list(sg.graph_attr["bb"])
            box["data"]["coords"] = coords

    return cy_elements
コード例 #16
0
ファイル: tb_gen.py プロジェクト: FelixBrakel/uGenie-codegen
def gen_mul_inputs(
        dfg: AGraph, fu: AGraph,
        input_map: Dict[str, int]) -> Tuple[List[Input], List[Output]]:
    outputs: List[Output] = []
    inputs: List[Input] = []
    nodes: List[Instruction] = []

    for node in fu.nodes():
        nodes.append(parse_instruction(node))

    nodes.sort()
    prime_idx = 0
    for node in nodes:
        preds = dfg.predecessors(node.name)
        parent0 = parse_instruction(preds[0])
        parent1 = parse_instruction(preds[1])

        label0 = dfg.get_node(parent0.name).attr['label']
        label1 = dfg.get_node(parent1.name).attr['label']

        i0, edge_case0, prime_idx = gen_mul_input(node, parent0, input_map,
                                                  inputs, outputs, prime_idx,
                                                  label0)
        i1, edge_case1, prime_idx = gen_mul_input(node, parent1, input_map,
                                                  inputs, outputs, prime_idx,
                                                  label1)

        if edge_case0 or edge_case1:
            expected = None
        else:
            expected = i0 * i1

        # if parent0.name in input_map:
        #     label = dfg.get_node(parent0.name).attr['label']
        #     if 'mul' in label:
        #         latency = 2
        #     else:
        #         latency = 1
        #
        #     i0 = PRIMES[prime_idx]
        #     prime_idx += 1
        #     inputs.append(Input(i0, input_map[parent0.name], parent0.cycle + latency))
        # else:
        #     for output in outputs:
        #         if output.cycle == parent0.cycle + 2:
        #             i0 = output.val
        #             break
        #
        # if parent1.name in input_map:
        #     label = dfg.get_node(parent1.name).attr['label']
        #     if 'mul' in label:
        #         latency = 2
        #     else:
        #         latency = 1
        #
        #     i1 = PRIMES[prime_idx]
        #     prime_idx += 1
        #     inputs.append(Input(i1, input_map[parent1.name], parent1.cycle + latency))
        # else:
        #     for output in outputs:
        #         if output.cycle == parent1.cycle + 2:
        #             i1 = output.val
        #             break

        # expected = i0 * i1
        outputs.append(Output(expected, node.cycle + 1))

    inputs.sort()
    return inputs, outputs
コード例 #17
0
ファイル: export.py プロジェクト: cthoyt/delphi
def to_agraph(G, *args, **kwargs) -> AGraph:
    """ Exports AnalysisGraph to pygraphviz AGraph

    Args:
        G
        args
        kwargs

    Returns:
        AGraph
    """

    A = AGraph(directed=True)

    A.graph_attr.update(
        {
            "dpi": 227,
            "fontsize": 20,
            "rankdir": kwargs.get("rankdir", "TB"),
            "fontname": font,
            "overlap": "scale",
            "splines": True,
        }
    )

    A.node_attr.update(
        {
            "shape": "rectangle",
            "color": "#650021",
            "style": "rounded",
            "fontname": font,
        }
    )

    nodes_with_indicators = [
        n for n in G.nodes(data=True) if n[1].get("indicators") is not None
    ]

    n_max = max(
        [
            sum([len(s.evidence) for s in e[2]["InfluenceStatements"]])
            for e in G.edges(data=True)
        ]
    )

    color_str = "#650021"
    for n in G.nodes(data=True):
        if kwargs.get("values"):
            node_label = n[0].capitalize().replace("_", " ") + " ("+str(np.mean(n[1]["rv"].dataset))+")"
        else:
            node_label = n[0].capitalize().replace("_", " ")
        A.add_node(n[0], label=node_label)

    for e in G.edges(data=True):
        reinforcement = np.mean(
            [
                stmt.subj_delta["polarity"] * stmt.obj_delta["polarity"]
                for stmt in e[2]["InfluenceStatements"]
            ]
        )
        opacity = (
            sum([len(s.evidence) for s in e[2]["InfluenceStatements"]]) / n_max
        )
        h = (opacity * 255).hex()
        cmap = cm.Greens if reinforcement > 0 else cm.Reds
        c_str = matplotlib.colors.rgb2hex(cmap(abs(reinforcement)))# + h[4:6]
        A.add_edge(e[0], e[1], color=c_str, arrowsize=0.5)

    # Drawing indicator variables


    if kwargs.get("indicators"):
        for n in nodes_with_indicators:
            for indicator_name, ind in n[1]["indicators"].items():
                node_label = _insert_line_breaks(ind.name.replace("_", " "))
                if kwargs.get("indicator_values"):
                    if ind.unit is not None:
                        units = f" {ind.unit}"
                    else:
                        units = ""

                    if ind.mean is not None:
                        ind_value = "{:.2f}".format(ind.mean) + f"{units}"
                        node_label = f"{node_label}\n[{ind_value}]"

                A.add_node(
                    node_label, style="rounded, filled", fillcolor="lightblue"
                )
                A.add_edge(n[0], node_label, color="royalblue4")

    if kwargs.get("nodes_to_highlight") is not None:
        nodes = kwargs.pop("nodes_to_highlight")
        if isinstance(nodes, list):
            for n in nodes:
                if n in A.nodes():
                    A.add_node(n, fontcolor="royalblue")
        elif isinstance(nodes, str):
            if n in A.nodes():
                A.add_node(nodes, fontcolor="royalblue")

    if kwargs.get("graph_label") is not None:
        A.graph_attr["label"] = kwargs["graph_label"]

    return A
コード例 #18
0
def to_agraph(G, *args, **kwargs) -> AGraph:
    """ Exports AnalysisGraph to pygraphviz AGraph

    Args:
        G
        args
        kwargs

    Returns:
        AGraph
    """

    A = AGraph(directed=True)

    A.graph_attr.update(
        {
            "dpi": 227,
            "fontsize": 20,
            "rankdir": kwargs.get("rankdir", "TB"),
            "fontname": font,
        }
    )

    A.node_attr.update(
        {
            "shape": "rectangle",
            "color": "#650021",
            "style": "rounded",
            "fontname": font,
        }
    )

    nodes_with_indicators = [
        n for n in G.nodes(data=True) if n[1].get("indicators") is not None
    ]

    n_max = max(
        [
            sum([len(s.evidence) for s in e[2]["InfluenceStatements"]])
            for e in G.edges(data=True)
        ]
    )

    color_str = "#650021"
    for n in G.nodes():
        A.add_node(n, label=n.capitalize().replace("_", " "))

    for e in G.edges(data=True):
        opacity = (
            sum([len(s.evidence) for s in e[2]["InfluenceStatements"]]) / n_max
        )
        h = (opacity * 255).hex()
        c_str = color_str + h[4:6]
        A.add_edge(e[0], e[1], color=c_str, arrowsize=0.5)

    # Drawing indicator variables

    if kwargs.get("indicators"):
        for n in nodes_with_indicators:
            for ind in n[1]["indicators"]:
                node_label = _insert_line_breaks(ind.name)
                if kwargs.get("indicator_values"):
                    if ind.unit is not None:
                        units = f" {ind.unit}"
                    else:
                        units = ""

                    ind_value = "{:.2f}".format(ind.mean) + f"{units}"
                    node_label = f"{node_label}\n[{ind_value}]"

                A.add_node(
                    node_label, style="rounded, filled", fillcolor="lightblue"
                )
                A.add_edge(n[0], node_label, color="royalblue4")

    if kwargs.get("nodes_to_highlight") is not None:
        nodes = kwargs.pop("nodes_to_highlight")
        if isinstance(nodes, list):
            for n in nodes:
                if n in A.nodes():
                    A.add_node(n, fontcolor="royalblue")
        elif isinstance(nodes, str):
            if n in A.nodes():
                A.add_node(nodes, fontcolor="royalblue")

    if kwargs.get("graph_label") is not None:
        A.graph_attr["label"] = kwargs["graph_label"]

    return A
コード例 #19
0
    def from_agraph(cls, A: AGraph, lambdas):
        G = nx.DiGraph()
        variable_nodes = [
            n for n in A.nodes() if n.attr["node_type"] != "ActionNode"
        ]

        for n in variable_nodes:
            name = n.attr["cag_label"]
            G.add_node(name, value=None, pred_fns=[], agraph_name=n)
            if n.attr["is_index"] == "True":
                G.nodes[name]["init_fn"] = lambda: 1
                G.nodes[name]["update_fn"] = (lambda **kwargs: int(
                    kwargs.pop(list(kwargs.keys())[0])) + 1)
                G.add_edge(name, name)

        function_nodes = [n for n in A.nodes() if n not in variable_nodes]

        for f in function_nodes:
            output, = A.successors(f)
            oname = output.attr["cag_label"]

            # Check if it is an initialization function
            if len(A.predecessors(f)) == 0:
                G.nodes[oname]["init_fn"] = getattr(lambdas,
                                                    f.attr["lambda_fn"])
            # Otherwise append the predecessor function list
            elif f.attr["label"] == "__decision__":
                preds = A.predecessors(f)
                if_var, = [
                    n for n in preds if list(A.predecessors(n))
                    [0].attr["label"] == "__condition__"
                ]
                condition_fn, = A.predecessors(if_var)
                cut = condition_fn.rfind("__")
                condition_fn = condition_fn[:cut]
                condition_lambda = condition_fn.replace("condition", "lambda")
                G.nodes[oname]["condition_fn"] = getattr(
                    lambdas, condition_lambda)
            else:
                G.nodes[oname]["pred_fns"].append(
                    getattr(lambdas, f.attr["lambda_fn"]))

            # If the type of the function is assign, then add an edge in the CAG
            if f.attr["label"] == "__assign__":
                for i in A.predecessors(f):
                    iname = i.attr["cag_label"]
                    G.add_edge(iname, oname)

        for n in G.nodes(data=True):
            n_preds = len(n[1]["pred_fns"])
            if n_preds == 0:
                del n[1]["pred_fns"]
            elif n_preds == 1:
                n[1]["update_fn"], = n[1].pop("pred_fns")
            else:
                n[1]["choice_fns"] = n[1].pop("pred_fns")

                def update_fn(n, **kwargs):
                    cond_fn = n[1]["condition_fn"]
                    sig = signature(cond_fn)
                    if cond_fn(**kwargs):
                        return n[1]["choice_fns"][0](**kwargs)
                    else:
                        return n[1]["choice_fns"][1](**kwargs)

                n[1]["update_fn"] = partial(update_fn, n)

        isolated_nodes = [
            n for n in G.nodes()
            if len(list(G.predecessors(n))) == len(list(G.successors(n))) == 0
        ]
        for n in isolated_nodes:
            G.remove_node(n)
        return cls(G)
コード例 #20
0
def dot_layout(cy_elements,
               edge_labels=False,
               subgraph_boxes=False,
               node_gt=None):
    """
    Get a CyElements object and augment it (in-place) with positions,
    widths, heights, and spline data from a dot based layout.

    edge_labels is true if labels should appear on edges
    subgraph_boxes is true if boxes should be drawn around subgraphs

    Returns the object.
    """
    elements = cy_elements.elements

    #    g = AGraph(directed=True, strict=False)
    g = AGraph(directed=True, strict=False, forcelabels=True)

    # make transitive relations appear top to bottom

    elements = list(elements)
    nodes_by_id = dict(
        (e["data"]["id"], e) for e in elements if e["group"] == "nodes")
    order = [(nodes_by_id[e["data"]["source"]],
              nodes_by_id[e["data"]["target"]]) for e in elements
             if e["group"] == "edges" and "transitive" in e["data"]
             and e["data"]["transitive"]]
    elements = topological_sort(elements, order, lambda e: e["data"]["id"])

    # get the node id's and stable sort them by cluster
    # the idea here is to convert the graph into a dag by sorting
    # the nodes, then reversing the back edges. In particular, we try to make
    # all the edges between two clusters go in the same direction so clustering
    # doesn't result in horizontal edges, which dot renders badly.

    sorted_nodes = [e["data"]["id"] for e in elements if e["group"] == "nodes"]
    sorted_nodes = sorted(enumerate(sorted_nodes),
                          key=lambda x:
                          (nodes_by_id[x[1]]["data"]["cluster"], x[0]))
    sorted_nodes = [y for idx, y in sorted_nodes]
    node_key = dict((id, idx) for idx, id in enumerate(sorted_nodes))

    if node_gt is None:
        node_gt = lambda X, y: False
    else:
        node_gt = lambda x, y: node_key[x] > node_key[y]

    # add nodes to the graph
    for e in elements:
        if e["group"] == "nodes" and e["classes"] != 'non_existing':
            g.add_node(e["data"]["id"],
                       label=e["data"]["label"].replace('\n', '\\n'))

    # TODO: remove this, it's specific to leader_demo
    weight = {
        'reach': 10,
        'le': 10,
        'id': 1,
    }
    constraint = {
        'pending': False,
    }

    # add edges to the graph
    for e in elements:
        if e["group"] == "edges":
            #            kwargs = {'weight': weight.get(e["data"]["obj"], 0)},
            kwargs = {'label': e["data"]["label"]} if edge_labels else {}
            if node_gt(e["data"]["source"], e["data"]["target"]):
                g.add_edge(e["data"]["target"],
                           e["data"]["source"],
                           e["data"]["id"],
                           dir='back',
                           **kwargs
                           #constraint=constraint.get(e["data"]["obj"], True),
                           )
            else:
                g.add_edge(e["data"]["source"], e["data"]["target"],
                           e["data"]["id"], **kwargs
                           #constraint=constraint.get(e["data"]["obj"], True),
                           )

    # add clusters
    clusters = defaultdict(list)
    for e in elements:
        if e["group"] == "nodes" and e["data"][
                "cluster"] is not None and e["classes"] != 'non_existing':
            clusters[e["data"]["cluster"]].append(e["data"]["id"])
    for i, k in enumerate(sorted(clusters.keys())):
        g.add_subgraph(
            name='cluster_{}'.format(i),
            nbunch=clusters[k],
            rank='min',
        )

    # now get positions, heights, widths, and bsplines
    g.layout(prog='dot')

    # get the y origin. we want the top left of the graph to be a
    # fixed coordinate (hopefully (0,0)) so the graph doesn't jump when
    # its height changes. Unfortunately, pygraphviz has a bug a gives
    # the wrong bbox, so we compute the max y coord.

    #    bbox = pygraphviz.graphviz.agget(g.handle,'bb')

    global y_origin
    y_origin = 0.0
    for n in g.nodes():
        top = float(n.attr['pos'].split(',')[1]) + float(n.attr['height']) / 2
        if top > y_origin:
            y_origin = top
    if subgraph_boxes:
        for sg in g.subgraphs():
            top = float(sg.graph_attr['bb'].split(',')[3])
            if top > y_origin:
                y_origin = top

    for e in elements:
        if e["group"] == "nodes" and e["classes"] != 'non_existing':
            attr = g.get_node(e["data"]["id"]).attr
            e["position"] = _to_position(attr['pos'])
            e["data"]["width"] = 72 * float(attr['width'])
            e["data"]["height"] = 72 * float(attr['height'])

        elif e["group"] == "edges":
            if node_gt(e["data"]["source"], e["data"]["target"]):
                attr = g.get_edge(e["data"]["target"], e["data"]["source"],
                                  e["data"]["id"]).attr
                pos = attr['pos']
                pe = pos.split()
                ppe = pe[1:]
                ppe.reverse()
                pos = ' '.join([pe[0].replace('s', 'e')] + ppe)
            else:
                attr = g.get_edge(e["data"]["source"], e["data"]["target"],
                                  e["data"]["id"]).attr
                pos = attr['pos']
            e["data"].update(_to_edge_position(pos))
            if edge_labels and e["data"]["label"] != '':
                e["data"]["lp"] = _to_position(attr['lp'])
#    g.draw('g.png')

    if subgraph_boxes:
        for sg in g.subgraphs():
            box = cy_elements.add_shape(sg.name, classes='subgraphs')
            coords = _to_coord_list(sg.graph_attr['bb'])
            box["data"]["coords"] = coords

    return cy_elements
コード例 #21
0
ファイル: graph.py プロジェクト: wangdi2014/bioconvert
def create_graph(filename,
                 layout="dot",
                 use_singularity=False,
                 color_for_disabled_converter='red'):
    """

    :param filename: should end in .png or .svg or .dot

    If extension is .dot, only the dot file is created.
    This is useful if you have issues installing graphviz.
    If so, under Linux you could use our singularity container
    see github.com/cokelaer/graphviz4all

    """
    from bioconvert.core.registry import Registry
    rr = Registry()

    try:
        if filename.endswith(".dot") or use_singularity is True:
            raise Exception()
        from pygraphviz import AGraph
        dg = AGraph(directed=True)

        url = "https://bioconvert.readthedocs.io/en/master/formats.html#{}"

        for a, b, s in rr.get_all_conversions():
            if len(a) == 1 and len(b) == 1:

                dg.add_node(a[0],
                            shape="rectangle",
                            style="filled",
                            url=url.format(a[0].upper()))
                dg.add_node(b[0],
                            shape="rectangle",
                            style="filled",
                            url=url.format(b[0].upper()))
                dg.add_edge(
                    a[0],
                    b[0],
                    color='black' if s else color_for_disabled_converter)
            else:
                and_node = "_".join(a) + "_and_" + "_".join(b)

                dg.add_node(and_node,
                            label="",
                            fillcolor="black",
                            width=.1,
                            height=.1,
                            styled="filled",
                            fixedsize=True,
                            shape="circle")

                for this in a:
                    dg.add_edge(
                        this,
                        and_node,
                        color="black" if s else color_for_disabled_converter)

                for this in b:
                    dg.add_edge(
                        and_node,
                        this,
                        color="black" if s else color_for_disabled_converter)

        for name in dg.nodes():
            if dg.degree(name) < 5:
                dg.get_node(name).attr["fillcolor"] = "white"
            elif dg.degree(name) < 10:
                # yellow
                dg.get_node(name).attr["fillcolor"] = "yellow"
            elif dg.degree(name) < 20:
                # orange
                dg.get_node(name).attr["fillcolor"] = "orange"
            else:
                # red
                dg.get_node(name).attr["fillcolor"] = "red"

        dg.layout(layout)
        dg.draw(filename)
        dg.write("conversion.dot")
        print(list(dg.get_node("FASTQ").attr.values()))

    except Exception as e:
        _log.error(e)
        dot = """
strict digraph{
    node [label="\\N"];

    """
        nodes = set([
            item for items in rr.get_all_conversions() for item in items[0:1]
        ])

        for node in nodes:
            dot += "\"{}\";\n".format(node)
        for a, b, s in rr.get_all_conversions():
            dot += "\"{}\" -> \"{}\";\n".format(a, b)
        dot += "}\n"

        from easydev import TempFile
        from bioconvert import shell
        dotfile = TempFile(suffix=".dot")
        with open(dotfile.name, "w") as fout:
            fout.write(dot)

        dotpath = ""
        if use_singularity:
            from bioconvert.core.downloader import download_singularity_image
            singfile = download_singularity_image(
                "graphviz.simg", "shub://cokelaer/graphviz4all:v1",
                "4288088d91c848e5e3a327282a1ab3d1")

            dotpath = "singularity run {} ".format(singfile)
            on_rtd = environ.get('READTHEDOCS', None) == 'True'
            if on_rtd:
                dotpath = ""

        ext = filename.rsplit(".", 1)[1]
        cmd = "{}dot -T{} {} -o {}".format(dotpath, ext, dotfile.name,
                                           filename)
        print(dotfile.name)
        try:
            shell(cmd)
        except:
            import os
            os.system(cmd)