# This program implements a simple 2-node boolean network, computes all possible state transitions (4 of them), and # plots the resulting STG. # The Boolean update equations for the 2 nodes (gene_0 and gene_1) are: # gene_0 = NOT gene_1 # gene_1 = gene_0 AND gene_1 # The program then stores the states and the corresponding transitions as nodes and edges in a 'networkx' graph object. # This graph is nothing but the 'state transition graph' (STG) of the Boolean network that is then plotted. # IMPORTANT NOTE: The STG is a visualization of the state transitions that shows which states drain into which # attractors. For a large state space (such as the one for the 10-node BN in the second problem), it may be difficult # to read off the attractors. Hence, you should write your own logic to identify the attractors in the STG, which would # basically be a list of states in a particular order. import networkx as nx import matplotlib.pyplot as plt G = nx.DiGraph() # this only creates the 'graph' object, and does not plot it # Below is the set of all possible states of 2-gene boolen network # For your 10-gene network, you have to create this list of all possible states programmatically. DO NOT hard-code them. possible_states = [(False, False), (False, True), (True, False), (True, True)] # when represented in Boolean numerals they read as: [(0, 0), (0, 1), (1, 0), (1, 1)] # corresponding values in Decimals are: [0, 1, 2, 3] ## One way to automatically generate the set of all possible states in as follows: # possible_states = [(x, y) for x in [False, True] for y in [False, True]] ## Alternatively, you may also use the packages 'itertools': http://docs.python.org/2/library/itertools.html#itertools.product for (i, j) in possible_states: genes = [i, j] updated_genes = [False, False] # initially set to some value, which will then get updated in the loop below # Below, I have created my own simple boolean expressions. You have to use the expressions given in the paper # Gene0 = NOT Gene1 # Gene1 = Gene0 AND Gene1 # state of the network = [value of Gene 0, value of Gene 1] updated_genes[0] = not genes[1] # Boolean expression for updating gene 1 updated_genes[1] = genes[0] and genes[1] # Boolean expression for updating gene 2 # Now, you know that the current state contained in 'genes' goes to the state contained in 'updated_genes' in one update step. # You want to record this transition from the current state to the next state in your STG graph. # Both the current state and the next state are nodes in your graph. A node in a graph needs a 'label' to be referred to. # So, calculate the decimal number equivalent of the current and next state that are in boolean form and use them as the node labels. # For your 10-gene network, compute the decimal value of each state using a loop. DO NOT hard code. current_state = int(genes[0]) * pow(2,0) + int(genes[1]) * pow(2,1) # label for the node representing the current state next_state = int(updated_genes[0]) * pow(2,0) + int(updated_genes[1]) * pow(2,1) # label for the next state node G.add_node(current_state) G.add_node(next_state) G.add_edge(current_state, next_state) print (G.nodes(), G.edges()) plt.figure(figsize=(8,8)) nx.draw_circular(G,node_size=500,with_labels=True) # creates a circular graph plt.axis('equal') plt.show() # you may use other graph plotting options shown in DrawGraph.py