Project

y_petri

0.01
No commit activity in last 3 years
No release in over 3 years
YPetri is a DSL (domain-specific language) for modelling of dynamical systems. It is biologically inspired, but concerns of biology and chemistry have been purposely separated away from it. YPetri caters solely to the two main concerns of modelling, model specification and simulation, and it excels in the first one. Dynamical systems are described under a Petri net paradigm. YPetri implements a universal Petri net abstraction that integrates discrete/continous, timed/timeless and stoichiometric/nonstoichiometric dichotomies of the extended Petri nets, and allows efficient specification of any kind of dynamical system. Like Petri nets themselves, YPetri was inspired by problems from the domain of chemistry (biochemical pathway modelling), but is not specific to it. Other gems, YChem and YCell are planned to cater to the concerns specific to chemistry and cell biochemistry. A lower-level extension of YPetri is currently under development under the name YNelson. Its usage is practically identical to YPetri, so any YPetri user can now consider using YNelson instead. YNelson covers additional concerns: it allows relations among nodes and parameters to be specified under a zz structure paradigm (developed by Ted Nelson) and it is also aimed towards providing a higher level of abstraction in Petri net specification by providing commands that create more than one Petri net node per command. YPetri documentation is avalable online, but due to formatting issues, you may prefer to generate the documentation on your own by running rdoc in the gem directory. As for the user manuals, there are currently 3 documents applicable for both YPetri and YNelson, whose master copies are stored in the YNelson source directory: 1. Introduction to YNelson and YPetri (hands-on tutorial), 2. Object model of YNelson and YPetri, 3. Introduction to Ruby for YNelson users. These manuals are written to allow beginners, including those unfamiliar with Ruby, to start working with YPetri and/or YNelson. For an example of how YPetri can be used to model complex dynamical systems, see the eukaryotic cell cycle model which I released as "cell_cycle" gem.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.6
>= 0

Runtime

 Project Readme

YPetri

YPetri is a domain model and a simulator of dynamical systems. It was inspired by the problems from the field of modelling of biochemical pathways, but on purpose, YPetri is not specific to biochemistry. As a matter of separation of concerns, YPetri caters solely to the two main concerns of modelling, model specification and simulation, excelling in the first one. YPetri implements a novel universal Petri net type, that integrating discrete/continous, deterministic/stochastic, timed/timeless and stoichiometric/nonstoichiometric dichotomies commonly seen in extended Petri nets. YPetri allows specification of any kind of dynamical system whatsoever.

Usage

YPetri provides a domain specific language (DSL) that can be loaded by:

  require 'y_petri'
  include YPetri

(As a matter of terminology, DSLs used in modelling are sometimes termed domain specific modelling languages (DSMLs). This term is popular especially in engineering.) Petri net places can now be created:

  A = Place()
  B = Place()
  places.names # you can shorten this to #pn
  #=> [:A, :B]
  # Setting their marking:
  A.marking = 2
  B.marking = 5

And transitions:

  A2B = Transition stoichiometry: { A: -1, B: 1 }
  #=> #<Transition: A2B (tS) >
  A2B.stoichiometry
  #=> [-1, 1]
  A2B.s
  #=> {:A=>-1, :B=>1}
  A2B.arcs.names
  #=> [:A, :B]
  A2B.timeless?
  #=> true
  A2B.enabled?
  #=> true

Explanation of the keywords: arcs, enabled are standard Petri net terms, stoichiometry means arcs with the amount of tokens to add / take from the connected places when the transition fires, timeless means that firing of the transition is not defined in time.

We can now play the token game:

  places.map &:marking
  #=> [2, 5]
  A2B.fire!
  places.map &:marking
  #=> [1, 6]
  A2B.fire!
  places.map &:marking
  #=> [0, 7]

Advanced usage

A Petri net is mostly used as a wiring diagram of some real-world system. Such Petri net can then be used to generate its simulation -- represented by YPetri::Simulation class. A Petri net consisting of only timed transitions can be used to generate (implicitly or explicitly) a system of ordinary differential equations (ODE). A simulation generated from such Petri net can then be used to solve (eg.) the initial value problem by numeric methods:

  # Start a fresh irb session!
  require 'y_petri'
  include YPetri
  A = Place default_marking: 0.5
  B = Place default_marking: 0.5
  A_pump = Transition s: { A: -1 }, rate: proc { 0.005 }
  B_decay = Transition s: { B: -1 }, rate: 0.05
  net
  #=> #<Net: name: Top, 2pp, 2tt >
  run!

Simulation can now be accessed through simulation DSL method:

  simulation
  #=> #<Simulation: time: 60, pp: 2, tt: 2, oid: -XXXXXXXXX>
  simulation.settings
  #=> {:method=>:pseudo_euler, :guarded=>false, :step=>0.1, :sampling=>5, :time=>0..60}
  print_recording

If you have gnuplot gem installed properly, you can view plots:

  plot_state
  plot_flux

Gillespie method

To try out another simulation method, Gillespie algorithm, open a fresh session and type:

require 'y_petri'
require 'sy'
require 'mathn'
include YPetri

A = Place m!: 10
B = Place m!: 10
AB = Place m!: 0
AB_association = Transition s: { A: -1, B: -1, AB: 1 }, rate: 0.1
AB_dissociation = Transition s: { AB: -1, A: 1, B: 1 }, rate: 0.1
A2B = Transition s: { A: -1, B: 1 }, rate: 0.05
B2A = Transition s: { A: 1, B: -1 }, rate: 0.07

set_step 1
set_target_time 50
set_sampling 1
set_simulation_method :gillespie

run!

print_recording

Again, you can visualize the results using gnuplot gem:

  plot_state

So much for the demo for now! Thanks for trying YPetri!

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request core_ext/array/