예제 #1
0
def test_cycle_graph(n: int, edge_sign: int):
    primes = cycle_graph(n=n, edge_sign=edge_sign)
    ig = primes2igraph(primes)
    cycle = networkx.cycle_graph(n=n, create_using=networkx.DiGraph)

    assert networkx.is_isomorphic(ig, cycle)
    assert_edge_signs_agree(ig, edge_sign, loop_sign=edge_sign)
예제 #2
0
def test_primes2igraph2():
    fname_in = get_tests_path_in(fname="interactiongraphs_irma.primes")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes=primes)

    nodes = sorted(igraph.nodes(data=True))
    expected_nodes = [("Ash1", {}), ("Cbf1", {}), ("Gal4", {}), ("Gal80", {}),
                      ("Swi5", {}), ("gal", {})]
    assert nodes == expected_nodes

    edges = sorted(igraph.edges(data=True))
    expected_edges = [("Ash1", "Cbf1", {
        "sign": {1}
    }), ("Cbf1", "Ash1", {
        "sign": {1}
    }), ("Gal4", "Swi5", {
        "sign": {-1}
    }), ("Gal80", "Gal4", {
        "sign": {1}
    }), ("Swi5", "Gal4", {
        "sign": {-1}
    }), ("gal", "Ash1", {
        "sign": {1}
    }), ("gal", "Gal80", {
        "sign": {-1}
    }), ("gal", "gal", {
        "sign": {1}
    })]
    assert edges == expected_edges
예제 #3
0
def test_path_graph(n: int, edge_sign: int, loop_sign: int):
    primes = path_graph(n=n, edge_sign=edge_sign, loop_sign=loop_sign)
    ig = primes2igraph(primes)
    path = networkx.path_graph(n=n, create_using=networkx.DiGraph)
    path.add_edge(0, 0)

    assert networkx.is_isomorphic(ig, path)
    assert_edge_signs_agree(ig, edge_sign, loop_sign)
예제 #4
0
def primes2bns(primes: dict, fname_bns: Optional[str] = None) -> str:
    """
    Saves Primes as a *bns* file for the computation of all attractors of the synchronous transition system.
    BNS_ is based on :ref:`Dubrova2011 <Dubrova2011>`.
    It is available at http://people.kth.se/~dubrova/bns.html.

    **arguments**:
       * *primes*: prime implicants
       * *fname_bns*: name of *bns* file or *None* to return file as string

    **example**::

          >>> primes2bns(primes, "mapk.bns")
    """

    names_sorted = sorted(primes)
    lines = ["# " + ", ".join(names_sorted), ""]
    lines += [f".v {len(names_sorted)}", ""]

    ig = primes2igraph(primes)
    for i, name in enumerate(names_sorted):
        i += 1
        lines += [f"# {name}"]
        regulators = sorted(ig.predecessors(name))
        number_regs = len(regulators)
        ids_regs = " ".join(
            [str(names_sorted.index(reg) + 1) for reg in regulators])
        lines += [f".n {i} {number_regs} {ids_regs}"]

        for v in [0, 1]:
            for prime in primes[name][v]:
                seq = []
                for reg in regulators:
                    if reg in prime:
                        if prime[reg] == 1:
                            seq.append("1")
                        else:
                            seq.append("0")
                    else:
                        seq.append("-")

                if regulators:
                    seq.append(" ")

                seq.append(str(v))

                lines += ["".join(seq)]

        lines += [""]

    text = "\n".join(lines)
    if fname_bns:
        with open(fname_bns, "w") as f:
            f.write(text)
        log.info(f"created {fname_bns}")

    return text
예제 #5
0
def test_find_minimal_autonomous_nodes():
    primes = get_primes("randomnet_n15k3")
    igraph = primes2igraph(primes)
    nodes = find_minimal_autonomous_nodes(igraph, core=set())
    expected = [{
        "Gene8", "Gene9", "Gene1", "Gene2", "Gene3", "Gene4", "Gene5", "Gene6",
        "Gene7", "Gene12", "Gene13", "Gene10", "Gene11", "Gene14"
    }]

    assert expected == nodes
예제 #6
0
def test_balanced_tree(height: int, branching_factor: int, edge_sign: int,
                       loop_sign: int):
    primes = balanced_tree(height, branching_factor, edge_sign, loop_sign)
    ig = primes2igraph(primes)
    path = networkx.balanced_tree(r=branching_factor,
                                  h=height,
                                  create_using=networkx.DiGraph)
    path.add_edge(0, 0)

    assert networkx.is_isomorphic(ig, path)
    assert_edge_signs_agree(ig, edge_sign, loop_sign)
예제 #7
0
def test_primes2igraph1():
    fname_in = get_tests_path_in(fname="interactiongraphs_irma.primes")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes=primes)

    nodes = sorted(igraph.nodes())
    expected_nodes = ["Ash1", "Cbf1", "Gal4", "Gal80", "Swi5", "gal"]
    assert nodes == expected_nodes

    edges = sorted(igraph.edges())
    expected_edges = [("Ash1", "Cbf1"), ("Cbf1", "Ash1"), ("Gal4", "Swi5"),
                      ("Gal80", "Gal4"), ("Swi5", "Gal4"), ("gal", "Ash1"),
                      ("gal", "Gal80"), ("gal", "gal")]
    assert edges == expected_edges
예제 #8
0
def test_primes2igraph4():
    primes = {
        "A": [[{}], []],
        "B": [[{
            "B": 0
        }], [{
            "B": 1
        }]],
        "C": [[{
            "C": 1
        }], [{
            "C": 0
        }]],
        "D": [[{
            "B": 0,
            "C": 0
        }, {
            "B": 1,
            "C": 1
        }], [{
            "B": 1,
            "C": 0
        }, {
            "B": 0,
            "C": 1
        }]]
    }
    igraph = primes2igraph(primes=primes)

    nodes = sorted(igraph.nodes(data=True))
    expected_nodes = [("A", {}), ("B", {}), ("C", {}), ("D", {})]
    assert nodes == expected_nodes

    edges = sorted(igraph.edges(data=True))
    expected_edges = [("B", "B", {
        "sign": {1}
    }), ("B", "D", {
        "sign": {1, -1}
    }), ("C", "C", {
        "sign": {-1}
    }), ("C", "D", {
        "sign": {1, -1}
    })]
    assert edges == expected_edges
예제 #9
0
def iterative_completeness_algorithm(
        primes: dict,
        update: str,
        compute_counterexample: bool,
        max_output: int = 1000) -> Union[Tuple[bool, Optional[dict]], bool]:
    """
    The iterative algorithm for deciding whether the minimal trap spaces are complete.
    The function is implemented by line-by-line following of the pseudo code algorithm given in
    "Approximating attractors of Boolean networks by iterative CTL model checking", Klarner and Siebert 2015.

    **arguments**:
        * *primes*: prime implicants
        * *update*: the update strategy, one of *"asynchronous"*, *"synchronous"*, *"mixed"*
        * *compute_counterexample*: whether to compute a counterexample

    **returns**:
        * *answer*: whether *subspaces* is complete in the STG defined by *primes* and *update*,
        * *counterexample*: a state that can not reach one of the minimal trap spaces of *primes* or *None* if no counterexample exists

    **example**::

        >>> answer, counterexample = completeness_with_counterexample(primes, "asynchronous")
        >>> answer
        False
        >>> state2str(counterexample)
        10010111101010100001100001011011111111
    """

    primes = percolate(primes=primes, copy=True)
    constants_global = find_constants(primes=primes)
    remove_all_constants(primes=primes)

    min_trap_spaces = compute_trap_spaces(primes=primes,
                                          type_="min",
                                          max_output=max_output)
    if min_trap_spaces == [{}]:
        if compute_counterexample:
            return True, None
        else:
            return True

    current_set = [({}, set([]))]
    while current_set:
        p, w = current_set.pop()
        primes_reduced = copy_primes(primes=primes)
        create_constants(primes=primes_reduced, constants=p)
        igraph = primes2igraph(primes=primes_reduced)

        cgraph = digraph2condensationgraph(digraph=igraph)
        cgraph_dash = cgraph.copy()

        for U in cgraph.nodes():
            if set(U).issubset(set(w)):
                cgraph_dash.remove_node(U)

        w_dash = w.copy()
        refinement = []
        top_layer = [
            U for U in cgraph_dash.nodes() if cgraph_dash.in_degree(U) == 0
        ]

        for U in top_layer:
            u_dash = find_ancestors(igraph, U)

            primes_restricted = copy_primes(primes_reduced)
            remove_all_variables_except(primes=primes_restricted, names=u_dash)

            q = compute_trap_spaces(primes=primes_restricted,
                                    type_="min",
                                    max_output=max_output)

            phi = exists_finally_one_of_subspaces(primes=primes_restricted,
                                                  subspaces=q)

            init = "INIT TRUE"
            spec = f"CTLSPEC {phi}"

            if compute_counterexample:
                answer, counterexample = model_checking(
                    primes=primes_restricted,
                    update=update,
                    initial_states=init,
                    specification=spec,
                    enable_counterexample=True)
                if not answer:
                    downstream = [x for x in igraph if x not in U]
                    arbitrary_state = random_state(downstream)
                    top_layer_state = counterexample[-1]
                    counterexample = merge_dicts([
                        constants_global, p, top_layer_state, arbitrary_state
                    ])

                    return False, counterexample
            else:
                answer = model_checking(primes=primes_restricted,
                                        update=update,
                                        initial_states=init,
                                        specification=spec)
                if not answer:
                    return False

            refinement += intersection([p], q)
            w_dash.update(u_dash)

        for q in intersection(refinement):
            q_tilde = find_constants(
                primes=percolate(primes=primes, add_constants=q, copy=True))

            if q_tilde not in min_trap_spaces:
                current_set.append((q_tilde, w_dash))

    if compute_counterexample:
        return True, None
    else:
        return True
예제 #10
0
def test_activities2animation():
    fname_in = get_tests_path_in(fname="irma.primes")
    fname_out1 = get_tests_path_out(fname="irma*.png")
    fname_out2 = get_tests_path_out(fname="irma.gif")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes)
    activities = [
        {
            "gal": 0,
            "Cbf1": 1,
            "Gal80": 1,
            "Ash1": 0,
            "Gal4": 0,
            "Swi5": 1
        },
        {
            "gal": 1,
            "Cbf1": 1,
            "Gal80": 1,
            "Ash1": 0,
            "Gal4": 0,
            "Swi5": 1
        },
        {
            "gal": 1,
            "Cbf1": 0,
            "Gal80": 1,
            "Ash1": 0,
            "Gal4": 0,
            "Swi5": 1
        },
        {
            "gal": 1,
            "Cbf1": 0,
            "Gal80": 0,
            "Ash1": 0,
            "Gal4": 0,
            "Swi5": 1
        },
        {
            "gal": 1,
            "Cbf1": 0,
            "Gal80": 0,
            "Ash1": 1,
            "Gal4": 0,
            "Swi5": 1
        },
        {
            "gal": 1,
            "Cbf1": 0,
            "Gal80": 0,
            "Ash1": 1,
            "Gal4": 1,
            "Swi5": 1
        },
        {
            "gal": 1,
            "Cbf1": 0,
            "Gal80": 0,
            "Ash1": 1,
            "Gal4": 1,
            "Swi5": 0
        },
    ]

    activities2animation(igraph=igraph,
                         activities=activities,
                         fname_tmp=fname_out1,
                         fname_gif=fname_out2)
예제 #11
0
def test_styles():
    fname_in = get_tests_path_in(fname="interactiongraphs_topology.primes")
    fname_out_dot = get_tests_path_out(
        fname="interactiongraphs_style_interactionsigns.dot")
    fname_out_pdf = get_tests_path_out(
        fname="interactiongraphs_style_interactionsigns.pdf")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes=primes)
    add_style_interactionsigns(igraph=igraph)
    igraph2dot(igraph=igraph, fname_dot=fname_out_dot)
    dot2image(fname_dot=fname_out_dot, fname_image=fname_out_pdf)
    igraph2image(igraph=igraph, fname_image=fname_out_pdf)

    fname_out_dot = get_tests_path_out(
        fname="interactiongraphs_style_activities.dot")
    fname_out_pdf = get_tests_path_out(
        fname="interactiongraphs_style_activities.pdf")

    add_style_interactionsigns(igraph=igraph)
    igraph2dot(igraph=igraph, fname_dot=fname_out_dot)
    dot2image(fname_dot=fname_out_dot, fname_image=fname_out_pdf)
    igraph2image(igraph=igraph, fname_image=fname_out_pdf)

    igraph = primes2igraph(primes=primes)
    activities = {"v1": 1, "v2": 0, "v3": 1, "v4": 1, "v5": 1, "v6": 0}
    add_style_activities(igraph=igraph, activities=activities)
    igraph2dot(igraph=igraph, fname_dot=fname_out_dot)
    dot2image(fname_dot=fname_out_dot, fname_image=fname_out_pdf)

    fname_in = get_tests_path_in(fname="interactiongraphs_topology.primes")
    fname_out_dot = get_tests_path_out(
        fname="interactiongraphs_style_sccs.dot")
    fname_out_pdf = get_tests_path_out(
        fname="interactiongraphs_style_sccs.pdf")
    primes = read_primes(fname_json=fname_in)

    igraph = primes2igraph(primes=primes)
    add_style_sccs(igraph=igraph)
    igraph2dot(igraph=igraph, fname_dot=fname_out_dot)
    dot2image(fname_dot=fname_out_dot, fname_image=fname_out_pdf)

    fname_in = get_tests_path_in(fname="interactiongraphs_topology.primes")
    fname_out_pdf = get_tests_path_out(fname="interactiongraphs_style_ioc.pdf")
    primes = read_primes(fname_json=fname_in)

    igraph = primes2igraph(primes=primes)
    add_style_inputs(igraph=igraph)
    add_style_constants(igraph=igraph)
    add_style_outputs(igraph=igraph)
    igraph2image(igraph=igraph, fname_image=fname_out_pdf)

    fname_in = get_tests_path_in(fname="interactiongraphs_topology.primes")
    fname_out_pdf = get_tests_path_out(
        fname="interactiongraphs_style_subgrapghs.pdf")
    fname_out_dot = get_tests_path_out(
        fname="interactiongraphs_style_subgrapghs.dot")
    primes = read_primes(fname_json=fname_in)

    igraph = primes2igraph(primes=primes)
    subgraphs = [(["v1", "v2"], {}), (["v3", "v4"], {"label": "jo"})]
    add_style_subgraphs(igraph=igraph, subgraphs=subgraphs)
    igraph2dot(igraph=igraph, fname_dot=fname_out_dot)
    dot2image(fname_dot=fname_out_dot, fname_image=fname_out_pdf)
예제 #12
0
def test_igraph2image():
    fname_in = get_tests_path_in(fname="interactiongraphs_irma.primes")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes=primes)
    fname_out = get_tests_path_out(fname="interactiongraphs_igraph2image.png")
    igraph2image(igraph=igraph, fname_image=fname_out)
예제 #13
0
def test_igraph2dot_string():
    fname_in = get_tests_path_in(fname="interactiongraphs_irma.primes")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes=primes)
    igraph2dot(igraph=igraph, fname_dot=None)
예제 #14
0
def test_igraph2dot():
    fname_in = get_tests_path_in(fname="interactiongraphs_irma.primes")
    fname_out = get_tests_path_out(fname="interactiongraphs_igraph2dot.dot")
    primes = read_primes(fname_json=fname_in)
    igraph = primes2igraph(primes=primes)
    igraph2dot(igraph=igraph, fname_dot=fname_out)
import pyboolnet.state_space
from pyboolnet.interaction_graphs import primes2igraph, igraph2image, local_igraph_of_state, add_style_interactionsigns
from pyboolnet.repository import get_primes
from pyboolnet.state_transition_graphs import create_stg_image

if __name__ == "__main__":
    primes = get_primes("remy_tumorigenesis")
    create_stg_image(primes, update="asynchronous", fname_image="igraph.pdf")
    create_stg_image(primes,
                     update="asynchronous",
                     fname_image="igraph2.pdf",
                     styles=["anonymous", "sccs"])

    # advances drawing

    igraph = primes2igraph(primes)

    for x in igraph.nodes:
        if "GF" in x:
            igraph.nodes[x]["shape"] = "square"
            igraph.nodes[x]["fillcolor"] = "lightblue"

    igraph2image(igraph, "igraph3.pdf")

    # local interaction graphs

    state = pyboolnet.state_space.random_state(primes)
    local_igraph = local_igraph_of_state(primes, state)
    add_style_interactionsigns(local_igraph)
    igraph2image(local_igraph, "local_igraph.pdf")
예제 #16
0
def compute_commitment_diagram(attractors: dict,
                               fname_image: Optional[str] = None,
                               fname_json=None,
                               edge_data=False) -> networkx.DiGraph:
    """
    Computes the commitment diagram for the AttrJson and STG defined in *attractors*, a json object computed by :ref:`AttrJson_compute_json`
    The nodes of the diagram represent states that can reach the exact same subset of *attractors*.
    Edges indicate the existence of a transition between two nodes in the respective commitment sets.
    Edges are labeled by the number of states of the source set that can reach the target set and,
    if *EdgeData* is true, additionally by the size of the border.

    **arguments**:
        * *attractors*: json attractor data, see :ref:`compute_attractors`
        * *fname_image*: generate image for diagram
        * *fname_json*: save diagram as json
        * *edge_data*: toggles computation of additional edge data

    **returns**::
        * *diagram*: the commitment diagram

    **example**::

        >>> attractors = compute_attractors(primes, update)
        >>> diagram = compute_phenotype_diagram(attractors)
    """

    primes = attractors["primes"]
    update = attractors["update"]

    subspaces = []
    for x in attractors["attractors"]:
        if x["min_trap_space"]["is_univocal"] and x["min_trap_space"][
                "is_faithful"]:
            subspaces.append(x["min_trap_space"]["dict"])
        else:
            subspaces.append(x["state"]["dict"])

    log.info("Commitment.compute_diagram(..)")

    size_total = size_state_space(primes)

    if len(subspaces) == 1:
        log.info(" single attractor, trivial case.")
        diagram = networkx.DiGraph()
        counter_mc = 0

        diagram.add_node("0")
        diagram.nodes["0"]["attractors"] = subspaces
        diagram.nodes["0"]["size"] = size_total
        diagram.nodes["0"]["formula"] = "TRUE"

    else:
        igraph = primes2igraph(primes)
        outdag = find_outdag(igraph)

        attractor_nodes = [x for A in subspaces for x in A]
        critical_nodes = find_ancestors(igraph, attractor_nodes)
        outdag = [x for x in outdag if x not in critical_nodes]

        igraph.remove_nodes_from(outdag)
        log.info(f"excluding the non-critical out-dag nodes {outdag}")

        components = networkx.connected_components(igraph.to_undirected())
        components = [list(x) for x in components]
        log.info(f"working on {len(components)} connected component(s)")

        counter_mc = 0
        diagrams = []
        for component in components:
            sub_primes = copy_primes(primes)
            remove_all_variables_except(sub_primes, component)
            attractors_projected = _project_attractors(subspaces, component)
            diagram, count = _compute_diagram_component(
                sub_primes, update, attractors_projected, edge_data)
            counter_mc += count
            diagrams.append(diagram)

        factor = 2**len(outdag)
        diagram = _cartesian_product_of_diagrams(diagrams, factor, edge_data)

        for x in attractors:
            diagram.graph[x] = copy_json_data(attractors[x])

        nodes_sum = 0
        for x in diagram.nodes():
            projection = diagram.nodes[x]["attractors"]
            diagram.nodes[x]["attractors"] = _lift_attractors(
                subspaces, projection)
            nodes_sum += diagram.nodes[x]["size"]

        if not nodes_sum == size_total:
            log.warning(
                "commitment diagram does not partition the state space, this may be due to rounding of large numbers."
            )

        sorted_ids = sorted(diagram, key=lambda x: diagram.nodes[x]["formula"])
        mapping = {x: str(sorted_ids.index(x)) for x in diagram}
        networkx.relabel_nodes(diagram, mapping, copy=False)

    log.info(f"total executions of NuSMV: {counter_mc}")

    if fname_image:
        commitment_diagram2image(diagram,
                                 fname_image=fname_image,
                                 style_inputs=True,
                                 style_edges=edge_data,
                                 style_ranks=True,
                                 first_index=1)

    if fname_json:
        save_commitment_diagram(diagram, fname_json)

    return diagram
예제 #17
0
def primes2bnet(primes: dict,
                fname_bnet: str = None,
                minimize: bool = False,
                header: bool = False) -> str:
    """
    Saves *primes* as a *bnet* file, including the header *"targets, factors"* for compatibility with :ref:`installation_boolnet`.
    Without minimization, the resuting formulas are disjunctions of all prime implicants and may therefore be very long.
    If *Minimize=True* then a Python version of the Quine-McCluskey algorithm,
    namely :ref:`Prekas2012 <Prekas2012>` which is implemented in :ref:`QuineMcCluskey.primes2mindnf <primes2mindnf>`,
    will be used to minimize the number of clauses for each update function.

    **arguments**:
        * *primes*: prime implicants
        * *fname_bnet*: name of *bnet* file or *None* for the string of the file contents
        * *minimize*: minimize the Boolean expressions
        * *header*: whether to include the "targets, factors" header

    **returns**:
        * *text_bnet*: str contents of bnet file

    **example**::

        >>> primes2bnet(primes, "mapk.bnet")
        >>> primes2bnet(primes, "mapk.bnet", True)
        >>> expr = primes2bnet(primes)
        >>> expr = primes2bnet(primes, True)
    """

    width = max([len(x) for x in primes]) + 3
    igraph = primes2igraph(primes)
    constants = sorted(find_constants(primes))
    inputs = sorted(find_inputs(primes))
    outdag = sorted(find_outdag(igraph))
    outdag = [x for x in outdag if x not in constants]
    body = sorted(x for x in primes
                  if all(x not in X for X in [constants, inputs, outdag]))
    blocks = [constants, inputs, body, outdag]
    blocks = [x for x in blocks if x]

    assert len(constants) + len(inputs) + len(body) + len(outdag) == len(
        primes)

    lines = []
    if header:
        lines += ["targets, factors"]

    if minimize:
        expressions = primes2mindnf(primes)
        for block in blocks:
            for name in block:
                lines += [f"{name + ',': <{width}} {expressions[name]}"]
            lines += [""]

    else:
        for block in blocks:
            for name in block:
                expression = get_dnf(one_implicants=primes[name][1])
                lines += [f"{name+',': <{width}} {expression}"]
            lines += [""]

    text = "\n".join(lines)

    if fname_bnet:
        with open(fname_bnet, "w") as fp:
            fp.writelines(text)
            log.info(f"created {fname_bnet}")

    return text