y_petri 2.3.3 → 2.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ACKNOWLEDGMENT.txt +6 -0
- data/README.md +3 -7
- data/lib/y_petri/net/data_set.rb +24 -20
- data/lib/y_petri/net/state/features/record.rb +1 -1
- data/lib/y_petri/net/state/features.rb +13 -1
- data/lib/y_petri/net/state.rb +7 -5
- data/lib/y_petri/net/visualization.rb +6 -6
- data/lib/y_petri/net.rb +1 -11
- data/lib/y_petri/place/guarded.rb +5 -5
- data/lib/y_petri/simulation/dependency.rb +12 -10
- data/lib/y_petri/simulation/matrix.rb +9 -7
- data/lib/y_petri/simulation/node_representation.rb +7 -2
- data/lib/y_petri/simulation/nodes.rb +8 -8
- data/lib/y_petri/simulation/places/access.rb +3 -1
- data/lib/y_petri/simulation/places.rb +0 -1
- data/lib/y_petri/transition/construction_convenience.rb +1 -1
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri.rb +16 -17
- data/test/acceptance/simulation_test.rb +40 -33
- data/test/y_petri_test.rb +0 -1
- data/y_petri.gemspec +2 -2
- metadata +38 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab4404308e31c4a9a63ab12ddb9bf0e38a398fdb
|
4
|
+
data.tar.gz: cd8d2cc2f6c21c1081d3d6364ccfadf307edaee0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9da0176d66c7792f3fc0539577be721ab130507a486b7392ccaed64ccfef0e5ce5a330c6127a9c69a007104c35cda9d876bcf57999cf79d6b9dfe1156ad9c507
|
7
|
+
data.tar.gz: f4fa59e863486eea853560ecd71c76dbf31ab5381e0f670ad93bc2a32018d0f45b3b34364f88ae2fc674a1942b94884f86ba0856b1c9498e956ccedcbbbbe8cb
|
data/ACKNOWLEDGMENT.txt
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
This document serves to acknowledge the support of Bioinformatics Program,
|
2
|
+
Taiwan International Graduate Program, Institute of Computer Science,
|
3
|
+
Academia Sinica (128, Academia Road, Sec. 2. Namkang, Taipei, 115), and
|
4
|
+
of Bioinformatics Institute, National Yang-Ming University, Taipei,
|
5
|
+
Taiwan. Without their support, creation of this package would not be
|
6
|
+
possible.
|
data/README.md
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
# YPetri
|
2
2
|
|
3
|
-
`YPetri` is a domain model and a simulator of
|
4
|
-
_Petri_ _nets_ unifying discrete/continous, deterministic/stochastic,
|
5
|
-
timed/timeless and stoichiometric/nonstoichiometric dichotomies, thus enabling
|
6
|
-
modelling and simulation of dynamic systems of any kind whatsoever.
|
3
|
+
`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.
|
7
4
|
|
8
5
|
## Usage
|
9
6
|
|
10
|
-
`YPetri` provides a _domain_ _specific_
|
11
|
-
be loaded by:
|
7
|
+
`YPetri` provides a _domain_ _specific_ _language_ (DSL) that can be loaded by:
|
12
8
|
```ruby
|
13
9
|
require 'y_petri'
|
14
10
|
include YPetri
|
15
11
|
```
|
16
|
-
|
12
|
+
(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:
|
17
13
|
```ruby
|
18
14
|
A = Place()
|
19
15
|
B = Place()
|
data/lib/y_petri/net/data_set.rb
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# +DataSet+ is a collection of labeled state records. It is
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
3
|
+
# +YPetri::Net::DataSet+ is a collection of labeled state records. It is
|
4
|
+
# a subclass of +Hash+. +DataSet+ keys are known as _events_, and values
|
5
|
+
# are data points. Each of these data points is an array that can be used
|
6
|
+
# to reconstruct a record, (an object of
|
7
|
+
# +YPetri::Net::State::Features::Record+ class). Each record records
|
8
|
+
# a specific feature set (of +YPetri::Net::State::Features+ class). +DataSet+
|
9
|
+
# class is intended to be parametrized with such specific feature set, which
|
10
|
+
# indicates the meaning of its data points.
|
11
|
+
#
|
12
|
+
# Apart from methods inherited from +Hash+, +DataSet+ can load a record at
|
13
|
+
# a given event (+#record+ method), reconstruct a simulation at a given event
|
10
14
|
# (+#reconstruct+ method), return columns corresponding to features (+#series+
|
11
15
|
# method) and perform feature selection (+#marking+, +#firing+, +#flux+,
|
12
|
-
# +#gradient+, +#delta+, +#assignment+, and +#reduced_features+ for mixed
|
13
|
-
# sets). Apart from standard inspection methods, +DataSet+ has methods
|
14
|
-
# and +#plot+ for visual presentation. Also, +DataSet+ has methods
|
15
|
-
# geared towards records of timed simulations, whose events are points
|
16
|
-
# Method +#interpolate+ uses linear interpolation to find the
|
17
|
-
# of the system at some exact time using linear interpolation
|
18
|
-
# earlier and later data points (which can be accessed
|
19
|
-
# and +#ceiling+ methods). Interpolation is
|
20
|
-
#
|
16
|
+
# +#gradient+, +#delta+, +#assignment+, and +#reduced_features+ for mixed
|
17
|
+
# feature sets). Apart from standard inspection methods, +DataSet+ has methods
|
18
|
+
# +#print+ and +#plot+ for visual presentation. Also, +DataSet+ has methods
|
19
|
+
# specially geared towards records of timed simulations, whose events are points
|
20
|
+
# in time. Method +#interpolate+ uses linear interpolation to find the
|
21
|
+
# approximate state of the system at some exact time using linear interpolation
|
22
|
+
# between the nearest earlier and later data points (which can be accessed
|
23
|
+
# respectively by +#floor+ and +#ceiling+ methods). Interpolation is available
|
24
|
+
# to the user, and is also used by +DataSet#resample+ method for resampling
|
25
|
+
# the dataset.
|
21
26
|
#
|
22
27
|
# Finally, it is possible that especially professional statisticians have
|
23
28
|
# written, or are planning to write, a +DataSet+ class better than this one.
|
24
29
|
# If I discover a good +DataSet+ class in the future, I would like to inherit
|
25
|
-
# from it or otherwise integrate with it for the purposes of
|
26
|
-
# +YPetri::Net::DataSet+.
|
30
|
+
# from it or otherwise integrate with it for the purposes of +DataSet+.
|
27
31
|
#
|
28
32
|
class YPetri::Net::DataSet < Hash
|
29
33
|
class << self
|
@@ -50,7 +54,7 @@ class YPetri::Net::DataSet < Hash
|
|
50
54
|
:net,
|
51
55
|
to: "self.class"
|
52
56
|
|
53
|
-
attr_reader :type,
|
57
|
+
attr_reader :type, # TODO: More like event_type, idea not matured yet.
|
54
58
|
:settings
|
55
59
|
|
56
60
|
# Type of the dataset.
|
@@ -307,6 +311,7 @@ class YPetri::Net::DataSet < Hash
|
|
307
311
|
Delta( net.places, transitions: transitions, **named_args )
|
308
312
|
end
|
309
313
|
|
314
|
+
#
|
310
315
|
def delta_timed *ordered_args, **named_args
|
311
316
|
delta *ordered_args, transitions: net.T_transitions, **named_args
|
312
317
|
end
|
@@ -350,7 +355,6 @@ class YPetri::Net::DataSet < Hash
|
|
350
355
|
# this dataset are meant to be plotted.
|
351
356
|
#
|
352
357
|
def plot( nodes=nil, except: [], **named_args )
|
353
|
-
puts "Hello from plot!"
|
354
358
|
nn = named_args
|
355
359
|
time = nn.may_have :time, syn!: :time_range
|
356
360
|
events = events()
|
@@ -1,6 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# A set of state features
|
3
|
+
# A feature set. In other words, a set of state features, such as marking,
|
4
|
+
# flux etc.
|
5
|
+
#
|
6
|
+
# marking:: Applicable to all places, all places have marking.
|
7
|
+
# firing:: Applicable to all stoichiometric transitions, but delta time has
|
8
|
+
# to be known for timed transitions.
|
9
|
+
# flux:: Applicable to timed stochiometric transitions only.
|
10
|
+
# delta:: Expresses change to a chosen set of places caused by firing of a
|
11
|
+
# chosen set of transitions. Requires delta time to be provided if
|
12
|
+
# there are timed transitions in the set.
|
13
|
+
# gradient:: Expresses gradient of change of a chosen set of places caused by
|
14
|
+
# firing of a chosen set of transitions. Only applicable to timed
|
15
|
+
# transitions.
|
4
16
|
#
|
5
17
|
class YPetri::Net::State::Features < Array
|
6
18
|
require_relative 'features/record'
|
data/lib/y_petri/net/state.rb
CHANGED
@@ -20,7 +20,7 @@ class YPetri::Net::State < Array
|
|
20
20
|
end
|
21
21
|
|
22
22
|
# Returns the feature identified by the argument.
|
23
|
-
#
|
23
|
+
#
|
24
24
|
def Feature arg=nil, **named_args
|
25
25
|
case arg
|
26
26
|
when Feature() then arg
|
@@ -62,9 +62,11 @@ class YPetri::Net::State < Array
|
|
62
62
|
|
63
63
|
delegate :net,
|
64
64
|
:Feature, # Note that as syntactic salt, specific methods
|
65
|
-
:Features, # #
|
66
|
-
:features, #
|
65
|
+
:Features, # #firing, #gradient, #flux etc. are not
|
66
|
+
:features, # delegated to self.class.
|
67
67
|
to: "self.class"
|
68
|
+
# FIXME: #features method above actually doesn't work in practice, self.class
|
69
|
+
# doesn't have it.
|
68
70
|
|
69
71
|
# Given a set of clamped places, this method outputs a +Record+ instance
|
70
72
|
# containing the marking of the free places (complementary to the supplied
|
@@ -77,8 +79,8 @@ class YPetri::Net::State < Array
|
|
77
79
|
else
|
78
80
|
places - places( clamped_places )
|
79
81
|
end
|
80
|
-
features( marking: free_places ).Record.load markings( free_places )
|
81
|
-
end
|
82
|
+
features( marking: free_places ).Record.load markings( free_places )
|
83
|
+
end # FIXME: I find it not working atm.
|
82
84
|
|
83
85
|
# Marking of a single given place in this state.
|
84
86
|
#
|
@@ -18,12 +18,12 @@ module YPetri::Net::Visualization
|
|
18
18
|
transition_nodes = transitions.map.with_object Hash.new do |tr, ꜧ|
|
19
19
|
ꜧ[tr] = γ.add_nodes tr.name.to_s,
|
20
20
|
shape: 'box',
|
21
|
-
fillcolor: if tr.assignment? then 'yellow'
|
22
|
-
|
23
|
-
|
24
|
-
color: if tr.assignment? then 'goldenrod'
|
25
|
-
|
26
|
-
|
21
|
+
fillcolor: ( if tr.assignment? then 'yellow'
|
22
|
+
elsif tr.type == :TS then 'lightcyan'
|
23
|
+
else 'ghostwhite' end ),
|
24
|
+
color: ( if tr.assignment? then 'goldenrod'
|
25
|
+
elsif tr.type == :TS then 'cyan'
|
26
|
+
else 'grey' end ),
|
27
27
|
style: 'filled'
|
28
28
|
end
|
29
29
|
# Add Petri net arcs.
|
data/lib/y_petri/net.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# coding: utf-8
|
2
2
|
|
3
3
|
require_relative 'net/node_access'
|
4
4
|
require_relative 'net/visualization'
|
@@ -13,16 +13,6 @@ require_relative 'net/state'
|
|
13
13
|
# neighbors of nodes (places or transitions).
|
14
14
|
#
|
15
15
|
class YPetri::Net
|
16
|
-
# ===========================================================================
|
17
|
-
# !!! TODO !!!
|
18
|
-
#
|
19
|
-
# Refactoring plans for Net class
|
20
|
-
#
|
21
|
-
# Make it a subclass of Module class, so places and transitions can simply
|
22
|
-
# be defined as its constants.
|
23
|
-
#
|
24
|
-
# ===========================================================================
|
25
|
-
|
26
16
|
★ NameMagic # ★ means include
|
27
17
|
★ NodeAccess
|
28
18
|
★ Visualization
|
@@ -5,21 +5,21 @@
|
|
5
5
|
module YPetri::Place::Guarded
|
6
6
|
# Expects a guard assertion in natural language, and a guard block. Guard
|
7
7
|
# block is a unary block that validates marking. A validation fails when:
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# 1. The block returns _false_.
|
10
10
|
# 2. The block raises +YPetri::GuardError+.
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# In all other cases, including when the block returns _nil_ (beware!),
|
13
13
|
# the marking is considered valid! Inside the block, +#fail+ keyword is
|
14
14
|
# redefined so that it can (and must) be called without arguments, and it
|
15
15
|
# raises an appropriately worded +GuardError+. (Other exceptions can still
|
16
16
|
# be raised using +#raise+ keyword.) Practical example:
|
17
|
-
#
|
17
|
+
#
|
18
18
|
# guard "should be a number" do |m| fail unless m.is_a? Numeric end
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# Then <code>guard! :foobar</code> raises +GuardError+ with a message "Marking
|
21
21
|
# foobar:Symbol should be a number!"
|
22
|
-
#
|
22
|
+
#
|
23
23
|
# Finally, this method is overloaded in such way, that if no block is
|
24
24
|
# given to it, it acts as an alias of +#common_guard_closure+ method.
|
25
25
|
#
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
#
|
4
|
-
# YPetri::Simulation. Expects the includer to provide
|
5
|
-
# method returning
|
6
|
-
#
|
3
|
+
# Mixin providing collections of places / transitions to classes parametrized
|
4
|
+
# by an instance of YPetri::Simulation. Expects the includer classes to provide
|
5
|
+
# +#simulation+ method returning the +Simulation+ instance with which they are
|
6
|
+
# parametrized.
|
7
|
+
#
|
7
8
|
class YPetri::Simulation
|
8
9
|
module Dependency
|
9
10
|
delegate :Place,
|
@@ -25,17 +26,18 @@ class YPetri::Simulation
|
|
25
26
|
:m_vector,
|
26
27
|
:recorder,
|
27
28
|
to: :simulation
|
28
|
-
|
29
|
-
# Delegates to the protected (and private) methods
|
29
|
+
|
30
|
+
# Delegates supplied method symbols to the protected (and private) methods
|
31
|
+
# of the simulation.
|
30
32
|
#
|
31
|
-
def self.delegate_to_simulation! *
|
32
|
-
|
33
|
+
def self.delegate_to_simulation! *method_symbols
|
34
|
+
method_symbols.each do |symbol|
|
33
35
|
module_exec do
|
34
|
-
define_method
|
36
|
+
define_method symbol do |*aa, &b| simulation.send symbol, *aa, &b end
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
38
|
-
|
40
|
+
|
39
41
|
# Necessary to overcoming the protected character of the listed methods.
|
40
42
|
#
|
41
43
|
[ :node,
|
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'matrix'
|
4
4
|
|
5
|
-
# Patches
|
6
|
-
# access.
|
7
|
-
#
|
5
|
+
# Patches built-in Matrix class with methods that generate code for direct
|
6
|
+
# vector access. This is used in simulation. It is imaginable and desirable
|
7
|
+
# that this way of simulation be refactored, and also, a faster way of
|
8
|
+
# simulation provided using NMatrix class.
|
9
|
+
#
|
8
10
|
class Matrix
|
9
11
|
class << self
|
10
12
|
# Builds a code string for accessing the vector values at given indices.
|
@@ -13,7 +15,7 @@ class Matrix
|
|
13
15
|
indices: (fail ArgumentError, "No indices!")
|
14
16
|
indices.map { |i| "#{vector}[#{i}, 0]" }.join( ", " )
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
# Builds a code string for assigning to a vector at given indices.
|
18
20
|
#
|
19
21
|
def column_vector_assignment_code vector: (fail ArgumentError, "No vector!"),
|
@@ -24,7 +26,7 @@ class Matrix
|
|
24
26
|
end
|
25
27
|
code_lines.compact.join( "\n" ) << "\n"
|
26
28
|
end
|
27
|
-
|
29
|
+
|
28
30
|
# Builds a code string for incrementing a vector at given indices. Source is
|
29
31
|
# a vector.
|
30
32
|
#
|
@@ -37,7 +39,7 @@ class Matrix
|
|
37
39
|
end
|
38
40
|
code_lines.compact.join( "\n" ) << "\n"
|
39
41
|
end
|
40
|
-
|
42
|
+
|
41
43
|
# Builds a code string for incrementing a vector at given indices. Source is
|
42
44
|
# an array.
|
43
45
|
#
|
@@ -51,7 +53,7 @@ class Matrix
|
|
51
53
|
code_lines.compact.join( "\n" ) << "\n"
|
52
54
|
end
|
53
55
|
end
|
54
|
-
|
56
|
+
|
55
57
|
# Builds a closure for incrementing a column at given indices.
|
56
58
|
#
|
57
59
|
def increment_at_indices_closure indices: (fail ArgumentError, "No indices!")
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# Representation of a YPetri
|
3
|
+
# Representation of a +YPetri+ node inside a +YPetri::Simulation+ instance.
|
4
|
+
# An instance of +YPetri::Simulation+ does is constructed based on an instance
|
5
|
+
# of +YPetri::Net+, but not directly work with Petri net nodes (that is, it
|
6
|
+
# does not work with instances of +YPetri::Place+ or +YPetri::Transition+).
|
7
|
+
# Instead, it creates its own internal representations of the nodes of the
|
8
|
+
# Petri net it is constructed from -- instances of NodeRepresentation.
|
4
9
|
#
|
5
10
|
class YPetri::Simulation::NodeRepresentation
|
6
11
|
★ NameMagic
|
@@ -10,7 +15,7 @@ class YPetri::Simulation::NodeRepresentation
|
|
10
15
|
|
11
16
|
delegate :simulation, to: "self.class"
|
12
17
|
|
13
|
-
# Expect a single YPetri place as an argument.
|
18
|
+
# Expect a single YPetri node (place or transition) as an argument.
|
14
19
|
#
|
15
20
|
def initialize net_node_id
|
16
21
|
@source = net.node( net_node_id )
|
@@ -1,27 +1,27 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
class YPetri::Simulation
|
4
|
-
# An array of simulation
|
4
|
+
# An array of simulation-owned places and/or transitions.
|
5
5
|
#
|
6
6
|
class Nodes < Array
|
7
7
|
★ Dependency
|
8
|
-
|
8
|
+
|
9
9
|
class << self
|
10
10
|
# New collection constructor
|
11
|
-
#
|
11
|
+
#
|
12
12
|
def load collection
|
13
13
|
new.tap { |inst| inst.load collection }
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
delegate :simulation, to: "self.class"
|
18
|
-
|
18
|
+
|
19
19
|
# Loads nodes to this collection.
|
20
|
-
#
|
20
|
+
#
|
21
21
|
def load nodes
|
22
22
|
nodes.each{ |node| push node }
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Creates a subset of this collection (of the same class).
|
26
26
|
#
|
27
27
|
def subset nodes=nil, &block
|
@@ -37,7 +37,7 @@ class YPetri::Simulation
|
|
37
37
|
self.class.load( nn )
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
# Returns an array of the node sources (nodes in the underlying net).
|
42
42
|
#
|
43
43
|
def sources
|
@@ -89,7 +89,9 @@ class YPetri::Simulation::Places
|
|
89
89
|
# that even without an argument, it does not fail, but returns the @Places
|
90
90
|
# parametrized subclass itself.
|
91
91
|
#
|
92
|
-
def Places( array )
|
92
|
+
def Places( array ) # TODO: Understand why this method does not behave
|
93
|
+
# as protected in real Simulation instances, while
|
94
|
+
# places method just above does.
|
93
95
|
# Kernel.p array
|
94
96
|
Places().load array.map &method( :place )
|
95
97
|
end
|
@@ -168,7 +168,7 @@ module YPetri::Transition::ConstructionConvenience
|
|
168
168
|
def __upstream_for_A__( **nn )
|
169
169
|
dom = domain
|
170
170
|
funct = true
|
171
|
-
λ = nn[:assignment].aT_is_a Proc, "supplied
|
171
|
+
λ = nn[:assignment].aT_is_a Proc, "supplied assignment argument"
|
172
172
|
if dom == :missing then
|
173
173
|
dom = λ.arity == 0 ? [] : codomain
|
174
174
|
else
|
data/lib/y_petri/version.rb
CHANGED
data/lib/y_petri.rb
CHANGED
@@ -35,27 +35,26 @@ require_relative 'y_petri/core'
|
|
35
35
|
require_relative 'y_petri/agent'
|
36
36
|
require_relative 'y_petri/dsl'
|
37
37
|
|
38
|
-
# YPetri
|
38
|
+
# YPetri is a domain model and a domain-specific language (DSL) for modelling of
|
39
|
+
# dynamical systems. YPetri module contains a collection of assets for Petri
|
40
|
+
# net-based model specification and its simulation.
|
39
41
|
#
|
40
|
-
# A PN
|
41
|
-
#
|
42
|
-
#
|
42
|
+
# A Petri net (PN) is a bipartite graph with two kinds of nodes: places and
|
43
|
+
# transitions. Places are visualised as circles, transitions as rectangles. Arcs
|
44
|
+
# connecting places and transitions are visualised as lines, but these are not
|
45
|
+
# considered first class citizens in YPetri abstraction.
|
43
46
|
#
|
44
47
|
# During PN execution (simulation), transitions act upon places and change their
|
45
|
-
# marking by adding / removing tokens as dictated by
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
48
|
+
# marking by adding / removing tokens as dictated by the prescription of their
|
49
|
+
# operation. This can be done by attaching a function to the transition. Such
|
50
|
+
# transitions are called functional transitions in YPetri. Borrowing more from
|
51
|
+
# the functional terminology, YPetri defines keywords domain an codomain for
|
52
|
+
# a PN transition in a way similar to the domain and codomain of a function.
|
49
53
|
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
# there is a fluid transition between Fixnum and Bignum, YPetri attempts for
|
55
|
-
# similarly fluid transition between Integer (ie. discrete) and floating point
|
56
|
-
# (ie. continuous) representation of token amounts and reaction speeds. Whole
|
57
|
-
# discrete / continuous issue thus becomes the business of the simulator, not
|
58
|
-
# the model.
|
54
|
+
# YPetri unifies discrete and stochastic modelling of timed transitions at the
|
55
|
+
# level of model specification in line with the present day unifying Petri net
|
56
|
+
# frameworks. YPetri also integrates other dichotomies: timed / timeless and
|
57
|
+
# stoichiometric / nonstoichiometric.
|
59
58
|
#
|
60
59
|
module YPetri
|
61
60
|
class << self
|
@@ -4,7 +4,7 @@
|
|
4
4
|
require 'minitest/autorun'
|
5
5
|
require_relative '../../lib/y_petri' # tested component itself
|
6
6
|
# require 'y_petri'
|
7
|
-
|
7
|
+
require 'sy'
|
8
8
|
|
9
9
|
describe "Simplified dTTP pathway used for demo with Dr. Chang" do
|
10
10
|
before do
|
@@ -42,74 +42,80 @@ describe "Simplified dTTP pathway used for demo with Dr. Chang" do
|
|
42
42
|
@m.clamp Deoxycytidine: 0.5, DeoxyCTP: 1.0, DeoxyGMP: 1.0
|
43
43
|
@m.clamp Thymidine: 0.5
|
44
44
|
@m.clamp UMP_UDP_pool: 2737.0
|
45
|
+
|
45
46
|
# Functions
|
46
47
|
Vmax_per_minute_per_enzyme_molecule =
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
-> specific_activity_µmol_per_min_per_mg, mol_mass_in_kDa {
|
49
|
+
specific_activity_µmol_per_min_per_mg * mol_mass_in_kDa
|
50
|
+
}
|
51
|
+
|
51
52
|
Vmax_per_minute =
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
-> specific_activity, kDa, enzyme_molecules_per_cell {
|
54
|
+
Vmax_per_minute_per_enzyme_molecule.( specific_activity, kDa ) *
|
55
|
+
enzyme_molecules_per_cell
|
56
|
+
}
|
57
|
+
|
55
58
|
Vmax_per_second =
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
-> specific_activity, kDa, enzyme_molecules_per_cell {
|
60
|
+
Vmax_per_minute.( specific_activity, kDa, enzyme_molecules_per_cell ) / 60
|
61
|
+
}
|
62
|
+
|
60
63
|
Km_reduced =
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
-> km, ki_hash=Hash.new {
|
65
|
+
ki_hash.map { |conc, ci_Ki| conc / ci_Ki }.reduce( 1, :+ ) * km
|
66
|
+
}
|
67
|
+
|
65
68
|
Occupancy =
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
-> conc, reactant_Km, compet_inh_w_Ki_hash=Hash.new {
|
70
|
+
conc / ( conc + Km_reduced.( reactant_Km, compet_inh_w_Ki_hash ) )
|
71
|
+
}
|
72
|
+
|
70
73
|
MM_with_inh_micromolars_per_second =
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
Vmax_per_second.( enzyme_specific_activity,
|
78
|
-
enzyme_mass_in_kDa,
|
79
|
-
enzyme_molecules_per_cell ) *
|
80
|
-
Occupancy.( reactant_concentration,
|
74
|
+
-> reactant_conc, enz_spec_activity, enz_mass_in_kDa,
|
75
|
+
enz_molecules_per_cell, reactant_Km, compet_inh_w_Ki_hash=Hash.new {
|
76
|
+
Vmax_per_second.( enz_spec_activity,
|
77
|
+
enz_mass_in_kDa,
|
78
|
+
enz_molecules_per_cell ) *
|
79
|
+
Occupancy.( reactant_conc,
|
81
80
|
reactant_Km,
|
82
|
-
|
81
|
+
compet_inh_w_Ki_hash )
|
82
|
+
}
|
83
|
+
|
83
84
|
MMi = MM_with_inh_micromolars_per_second
|
84
85
|
TK1_Thymidine_Km = 5.0
|
85
86
|
TYMS_DeoxyUMP_Km = 2.0
|
86
87
|
RNR_UDP_Km = 1.0
|
87
|
-
DNA_creation_speed = 3_000_000_000 / ( 12 * 3600 )
|
88
|
+
DNA_creation_speed = 3_000_000_000 / ( 12 * 3600 ) / Pieces_per_micromolar
|
88
89
|
TMPK_DeoxyTMP_Km = 12.0
|
89
90
|
|
90
91
|
# transitions
|
91
92
|
@m.Transition name: :TK1_Thymidine_DeoxyTMP,
|
92
|
-
domain: [ Thymidine, TK1, DeoxyTDP_DeoxyTTP_pool,
|
93
|
+
domain: [ Thymidine, TK1, DeoxyTDP_DeoxyTTP_pool,
|
94
|
+
DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
|
93
95
|
stoichiometry: { Thymidine: -1, DeoxyTMP: 1 },
|
94
96
|
rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
|
95
97
|
ci1 = pool1 * master3 / ( master2 + master3 )
|
96
98
|
MMi.( rc, TK1_a, TK1_kDa, e, TK1_Thymidine_Km,
|
97
99
|
ci1 => 13.5, ci2 => 0.8, ci3 => 40.0 ) }
|
100
|
+
|
98
101
|
@m.Transition name: :TYMS_DeoxyUMP_DeoxyTMP,
|
99
102
|
domain: [ DeoxyUMP_DeoxyUDP_pool, TYMS, AMP, ADP, ATP ],
|
100
103
|
stoichiometry: { DeoxyUMP_DeoxyUDP_pool: -1, DeoxyTMP: 1 },
|
101
104
|
rate: proc { |pool, e, master1, master2, master3|
|
102
105
|
rc = pool * master2 / ( master1 + master2 )
|
103
106
|
MMi.( rc, TYMS_a, TYMS_kDa, e, TYMS_DeoxyUMP_Km ) }
|
107
|
+
|
104
108
|
@m.Transition name: :RNR_UDP_DeoxyUDP,
|
105
109
|
domain: [ UMP_UDP_pool, RNR, DeoxyUMP_DeoxyUDP_pool, AMP, ADP, ATP ],
|
106
110
|
stoichiometry: { UMP_UDP_pool: -1, DeoxyUMP_DeoxyUDP_pool: 1 },
|
107
111
|
rate: proc { |pool, e, master1, master2, master3|
|
108
112
|
rc = pool * master2 / ( master1 + master2 )
|
109
113
|
MMi.( rc, RNR_a, RNR_kDa, e, RNR_UDP_Km ) }
|
114
|
+
|
110
115
|
@m.Transition name: :DNA_polymerase_consumption_of_DeoxyTTP,
|
111
116
|
stoichiometry: { DeoxyTDP_DeoxyTTP_pool: -1 },
|
112
117
|
rate: proc { DNA_creation_speed / 4 }
|
118
|
+
|
113
119
|
@m.Transition name: :TMPK_DeoxyTMP_DeoxyTDP,
|
114
120
|
domain: [ DeoxyTMP, TMPK, ADP,
|
115
121
|
DeoxyTDP_DeoxyTTP_pool,
|
@@ -121,6 +127,7 @@ describe "Simplified dTTP pathway used for demo with Dr. Chang" do
|
|
121
127
|
ci3 = pool * master3 / ( master2 + master3 )
|
122
128
|
MMi.( rc, TMPK_a, TMPK_kDa, e, TMPK_DeoxyTMP_Km,
|
123
129
|
ci1 => 250.0, ci2 => 30.0, ci3 => 750, ci4 => 117 ) }
|
130
|
+
|
124
131
|
end
|
125
132
|
|
126
133
|
it "should work" do
|
data/test/y_petri_test.rb
CHANGED
data/y_petri.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = YPetri::VERSION
|
9
9
|
spec.authors = ["boris"]
|
10
10
|
spec.email = ["\"boris@iis.sinica.edu.tw\""]
|
11
|
-
spec.summary = %q{Systems modelling and simulation gem, and a domain model of a
|
12
|
-
spec.description = %q{YPetri is a gem for modelling
|
11
|
+
spec.summary = %q{Systems modelling and simulation gem, and a domain model of a specific type of universal Petri net (YPetri net), which can be used to model any kind of dynamical system whatsoever.}
|
12
|
+
spec.description = %q{YPetri is a gem for modelling of dynamical systems. It 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, deterministic/stochastic, 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 it is not specific it. Other gems, YChem and YCell are planned to cater to the concerns specific to chemistry and cell biochemistry. As a part of this effort, an extended version of YPetri is under development. Its name is YNelson, its usage is practically identical to YPetri, but it covers more concerns than just Petri net specification and simulation. Namely, YNelson allows relations among Petri net nodes and parameters to be captured under a zz structure paradigm (which was developed by Ted Nelson) and it also provides higher level of abstraction in Petri net specification by providing commands that create more than one Petri net node per command.}
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "GPLv3"
|
15
15
|
|
metadata
CHANGED
@@ -1,113 +1,123 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: y_petri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.6'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: y_support
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: gnuplot
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: ruby-graphviz
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: distribution
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description: YPetri is a gem for modelling
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
97
|
+
description: YPetri is a gem for modelling of dynamical systems. It caters solely
|
98
|
+
to the two main concerns of modelling, model specification and simulation, and it
|
99
|
+
excels in the first one. Dynamical systems are described under a Petri net paradigm.
|
100
|
+
YPetri implements a universal Petri net abstraction that integrates discrete/continous,
|
101
|
+
deterministic/stochastic, timed/timeless and stoichiometric/nonstoichiometric dichotomies
|
102
|
+
of the extended Petri nets, and allows efficient specification of any kind of dynamical
|
103
|
+
system. Like Petri nets themselves, YPetri was inspired by problems from the domain
|
104
|
+
of chemistry (biochemical pathway modelling), but it is not specific it. Other gems,
|
105
|
+
YChem and YCell are planned to cater to the concerns specific to chemistry and cell
|
106
|
+
biochemistry. As a part of this effort, an extended version of YPetri is under development.
|
107
|
+
Its name is YNelson, its usage is practically identical to YPetri, but it covers
|
108
|
+
more concerns than just Petri net specification and simulation. Namely, YNelson
|
109
|
+
allows relations among Petri net nodes and parameters to be captured under a zz
|
110
|
+
structure paradigm (which was developed by Ted Nelson) and it also provides higher
|
111
|
+
level of abstraction in Petri net specification by providing commands that create
|
112
|
+
more than one Petri net node per command.
|
104
113
|
email:
|
105
114
|
- '"boris@iis.sinica.edu.tw"'
|
106
115
|
executables: []
|
107
116
|
extensions: []
|
108
117
|
extra_rdoc_files: []
|
109
118
|
files:
|
110
|
-
- .gitignore
|
119
|
+
- ".gitignore"
|
120
|
+
- ACKNOWLEDGMENT.txt
|
111
121
|
- Gemfile
|
112
122
|
- LICENSE.txt
|
113
123
|
- README.md
|
@@ -249,22 +259,22 @@ require_paths:
|
|
249
259
|
- lib
|
250
260
|
required_ruby_version: !ruby/object:Gem::Requirement
|
251
261
|
requirements:
|
252
|
-
- -
|
262
|
+
- - ">="
|
253
263
|
- !ruby/object:Gem::Version
|
254
264
|
version: '2.0'
|
255
265
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
266
|
requirements:
|
257
|
-
- -
|
267
|
+
- - ">="
|
258
268
|
- !ruby/object:Gem::Version
|
259
269
|
version: '0'
|
260
270
|
requirements: []
|
261
271
|
rubyforge_project:
|
262
|
-
rubygems_version: 2.
|
272
|
+
rubygems_version: 2.2.2
|
263
273
|
signing_key:
|
264
274
|
specification_version: 4
|
265
|
-
summary: Systems modelling and simulation gem, and a domain model of a
|
266
|
-
of Petri
|
267
|
-
|
275
|
+
summary: Systems modelling and simulation gem, and a domain model of a specific type
|
276
|
+
of universal Petri net (YPetri net), which can be used to model any kind of dynamical
|
277
|
+
system whatsoever.
|
268
278
|
test_files:
|
269
279
|
- test/acceptance/basic_usage_test.rb
|
270
280
|
- test/acceptance/simulation_test.rb
|