DSGRN Tutorial¶
Warning
This section needs to be rewritten for the python interface and currently only applies to DSGRN 1.0 and below. The command line interface described below has been deprecated. For examples using the python interface to DSGRN, see the DSGRN Getting Started notebook.
To begin with, we tell DSGRN what network we are interested in. Let’s study the network 2D_Example_C.txt
:
X : (X)(~Y)
Y : (~X)(Y)
To do this we type:
dsgrn network ./networks/2D_Example_C.txt
This produces a file called dsgrn.session
in the current working directory. You can delete it when you are done. It just remembers which network we want to study. If you change directories and call dsgrn
again, it won’t find the session file and will have forgotten about the network.
Anyhow, we can visualize the network using DSGRN by asking it for a graphviz representation of the network. To do this, we type:
dsgrn network draw > network.gv
Here we used the shell redirection operator >
to pipe the output to the file network.gv
. We can open this up with Graphviz and we get the following image:
Next, we ask about parameters. Let’s find out how many parameters there are.
dsgrn parameter
There are 1600 parameters.
Looks good. Later we should add a feature that tells us how many there are for each cohort of output orderings. In this case it happens to be 4 cohorts of 400, since there are 2 output orders for both \(X\) and \(Y\).
Let’s pick a parameter out of a hat: 126. Let’s ask DSGRN about parameter 126. First, we will ask it to give us a JSON-string representing the parameter:
dsgrn parameter json 126
[["X",[2,2,"C0"],[0,1]],["Y",[2,2,"C0"],[0,1]]]
This is telling us that for this parameter, node \(X\) has the logic [2,2,"C0"]
associated with it (2 inputs, 2 outputs, and hex code C0
) and the output ordering [0,1]
. The outputs have a natural ordering inherited from the sequence in which they appear in the network file; the [0,1]
indicates an identity permutation of this natural ordering. Thus the outputs are ordered X
then Y
. Had it been [1,0]
this would mean the other way around! In general, the \(k\) th out-ordered edge is the p[k]
th node, where p
is the permutation array.
We can ask about which parameter inequalities this logic/order corresponds to:
dsgrn parameter inequalities 126
["{
L(X,X) L(Y,X) < THETA(X,X),
U(X,X) L(Y,X) < THETA(X,X),
L(X,X) U(Y,X) < THETA(X,X),
THETA(X,Y) < U(X,X) U(Y,X)
},{
THETA(X,X) < THETA(X,Y)
}",
"{
L(X,Y) L(Y,Y) < THETA(Y,X),
U(X,Y) L(Y,Y) < THETA(Y,X),
L(X,Y) U(Y,Y) < THETA(Y,X),
THETA(Y,Y) < U(X,Y) U(Y,Y)
},{
THETA(Y,X) < THETA(Y,Y)
}"]
Neat. Let’s try to turn around and find out the index (i.e. 126) from the JSON-string it hands us:
dsgrn parameter index '[["X",[2,2,"C0"],[0,1]],["Y",[2,2,"C0"],[0,1]]]'
126
And now a consistency check:
dsgrn parameter inequalities '[["X",[2,2,"C0"],[0,1]],["Y",[2,2,"C0"],[0,1]]]'
["{
L(X,X) L(Y,X) < THETA(X,X),
U(X,X) L(Y,X) < THETA(X,X),
L(X,X) U(Y,X) < THETA(X,X),
THETA(X,Y) < U(X,X) U(Y,X)
},{
THETA(X,X) < THETA(X,Y)
}",
"{
L(X,Y) L(Y,Y) < THETA(Y,X),
U(X,Y) L(Y,Y) < THETA(Y,X),
L(X,Y) U(Y,Y) < THETA(Y,X),
THETA(Y,Y) < U(X,Y) U(Y,Y)
},{
THETA(Y,X) < THETA(Y,Y)
}"]
They are the same. Hooray!
Now let’s start doing dynamics. We can ask it to create a domain graph:
dsgrn domaingraph json '[["X",[2,2,"C0"],[0,1]],["Y",[2,2,"C0"],[0,1]]]'
[[0],[2],[2],[0],[1,3],[2,4],[6],[6],[5,7]]
Here we had asked for json output, so what we have is a nested json array giving an adjacency list representation of the domain graph. This is not visually appealing, so let’s ask for a graphviz representation instead:
dsgrn domaingraph graphviz '[["X",[2,2,"C0"],[0,1]],["Y",[2,2,"C0"],[0,1]]]' > dg.gv
Here we used >
to pipe the output to the file dg.gv. We can open this up with Graphviz and we get the following image:
We might improve this by setting the positions using the actual positions of domain in space (though it isn’t clear the best way to do this for higher than 2 dimensions).
And we could also pass the parameter by it’s index:
dsgrn domaingraph json 126
[[0],[2],[2],[0],[1,3],[2,4],[6],[6],[5,7]]
dsgrn domaingraph graphviz 126
Very similarly, we can also get wall graphs:
dsgrn wallgraph json 126
[[12,1],[13],[12],[2],[1],[3,4],[13],[2,14],[14],[3,4,8],[8],[5,6],[],[],[]]
dsgrn wallgraph graphviz 126 > wg.gv
Again, this might be improved by setting the position of the nodes using where the walls are in space rather than letting Graphviz choose.
Time for Morse theory. Here we ask for a Morse decomposition, which is essentially a Morse Graph which is annotated with the list of domains (the software is set up to calculate the Morse decomposition using the domain graph representation):
dsgrn morsedecomposition json 126
[[],[],[]]
Hmm, this isn’t great, since it lacks the phase space annotatation. That will be fixed! Meanwhile the graphviz output does have the appropriate annotations:
dsgrn morsedecomposition graphviz 126 > md.gv
Here we see the vertices are annotated with all the domains in the strongly connected component of the domain graph. Which in this case is just singletons sets. How boring! Maybe I should have picked a more interesting example.
Next up: Morse graphs. Same drill: we can give it the parameter either by index or by json string, and we can request either json output or graphviz output:
dsgrn morsegraph json 126
{"poset":[[],[],[]],"annotations":[["FP"],["FP"],["FP OFF"]]}
dsgrn morsegraph json '[["X",[2,2,"C0"],[0,1]],["Y",[2,2,"C0"],[0,1]]]'
{"poset":[[],[],[]],"annotations":[["FP"],["FP"],["FP OFF"]]}
dsgrn morsegraph graphviz 126
To wrap up, here is a summary of DSGRN’s current syntax. Any path from the green diamond to the red octagon is a valid DSGRN command: