StoJ is a polyadic, asynchronous stochastic pi calculus with input
join and no summation. It is intended for experimentation with
different styles of modelling molecular processes, just like the stochastic
pi calculus of Priami, Regev, Shapiro and Silverman.
article discusses some of the issues in stochastic-pi based
biological modelling and hints at some of the rationale for Stoj. You
can find a short tutorial on Stoj syntax and can experiment with our
current implementation using a web interface.
Rates are associated with a join, not with a channel. We implemented
reaction” method, as it seemed simplest. Despite its inefficiency
it’s performing reasonably well, although we suspect we have Moore’s
“law” to thank for that more than anything else.
Here’s an example model in StoJ. I duplicated the rates and the
overall design of the model from the Clock.zip code archive
at the BioSPI
website. This model is discussed in Aviv Regev’s paper “Representation
and simulation of molecular pathways in the stochastic pi-calculus.”
The implementation of the model below gives the same output graphs as
Regev’s model gives, which is a nice confirmation of the model and of
the StoJ system itself.
// Circadian clock model // Based on Regev et al new DNA_a, DNA_r, !MRNA_a, !MRNA_r, !protein_a, !protein_r, DNA_a_promoted, DNA_r_promoted, !complex_ar . ( // Start state. DNA_a<> | DNA_r<> // Basal rate transcription. | rec L. DNA_a() -> (DNA_a<> | MRNA_a<> | L) | rec L. DNA_r() ->[0.001] (DNA_r<> | MRNA_r<> | L) // MRNA degradation. | rec L. MRNA_a() ->[1.0] (L) | rec L. MRNA_r() ->[0.02] (L) // Translation. | rec L. MRNA_a() ->[1.0] (MRNA_a<> | protein_a<> | L) | rec L. MRNA_r() ->[0.1] (MRNA_r<> | protein_r<> | L) // Protein degradation. | rec L. protein_a() ->[0.1] (L) | rec L. protein_r() ->[0.01] (L) // A/R Complex formation. | rec L. protein_a() & protein_r() ->[100.0] (complex_ar<> | L) // A/R Complex degradation. | rec L. complex_ar() ->[0.1] (protein_r<> | L) | rec L. complex_ar() ->[0.01] (protein_a<> | L) // Activator binding/unbinding to A promoter, and enhanced transcription | rec L. protein_a() & DNA_a() -> (DNA_a_promoted<> | L) | rec L. DNA_a_promoted() -> (protein_a<> | DNA_a<> | L) | rec L. DNA_a_promoted() -> (DNA_a_promoted<> | MRNA_a<> | L) // Activator binding/unbinding to R promoter, and enhanced transcription | rec L. protein_a() & DNA_r() -> (DNA_r_promoted<> | L) | rec L. DNA_r_promoted() -> (protein_a<> | DNA_r<> | L) | rec L. DNA_r_promoted() -> (DNA_r_promoted<> | MRNA_r<> | L) )
Here are a couple of graphs produced by the simulator from the program
above—first a graph of reagent concentrations varying with
time, and then a graph of Repressor (R) molecule concentration against
Activator (A) molecule concentration, showing the bistable nature of
the whole system. If you take a look at the graphs in Regev’s paper,
you’ll see that the spikes in reagent concentration occur in the same
places with the same frequency in our model as in Regev’s.
We also implemented a simple Java applet/application that uses a
(human-assisted) mass-spring layout to draw a graph of the (statically
apparent) dataflow in the StoJ program it takes as input. It still
needs a bit of refining—the graphs/programs tend to be quite
densely connected in places, and not only is mass-spring layout poor
at densely-connected graphs, especially with cycles, but it doesn’t
identify any potential clustering in the graph either. Clustering
(subgraphs) might turn out to be important for visualising dataflow in
Here’s a simple chemical equilibrium model in StoJ:
// A simple H + Cl <--> HCl model, // similar to that in Andrew Phillips' slides // with numbers taken from his slides. // See http://www.doc.ic.ac.uk/~anp/spim/Slides.pdf // page 16. new !h, !cl, !hcl . ( rec ASSOC. h() & cl() -> (hcl<> | ASSOC) | rec DISSOC. hcl() -> (h<> | cl<> | DISSOC) | h<> * 100 | cl<> * 100 )
And here’s the display generated by the Java program visualisation
application. To see it in motion, and experiment with dragging the
nodes around using the mouse, visit the web interface
page, and click the “Visualise program” button.
As you can imagine, for larger models the display gets cluttered quite
quickly. A note on implementation though – we found Java2D to be
surprisingly pleasant to work with. The built-in support for
double-buffering of JComponents along with the various
classes of Shape helped us quickly develop the application.
This page is based on an earlier
article I wrote when ran the first few experiments with the