y_petri 2.1.26 → 2.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/y_petri/core/timed/gillespie.rb +25 -14
- data/lib/y_petri/core/timed.rb +2 -2
- data/lib/y_petri/simulation/marking_vector/access.rb +1 -2
- data/lib/y_petri/simulation/place_representation.rb +3 -0
- data/lib/y_petri/version.rb +1 -1
- data/test/examples/gillespie.rb +25 -0
- data/test/simulation_test.rb +1 -0
- data/test/ttp_pathway.rb +233 -0
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a29f67d51f216827623f8644ed4d62b5b9571413
|
4
|
+
data.tar.gz: f7f37ade4f8d98a67325bde2fd05da466d27a1d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51718ecc0d946472ac976594d6a6be4ff530b53b07d9eb060be4371b07434a6a32263e8ef262ac00b8ffc13bc1b5f8e2241220b1bd1d96ab2236bcaf3ad6bda2
|
7
|
+
data.tar.gz: 67437f897b783d283e19542186b22670b3dc43ea1bed8510b9114b8b2e470dcc4562d876e8d3a89918da799430102c3bd2e0ab3fa3a1668a4073696a8d2f29cb
|
@@ -21,16 +21,16 @@ module YPetri::Core::Timed::Gillespie
|
|
21
21
|
def step! Δt=simulation.step
|
22
22
|
@gillespie_time = curr_time = simulation.time
|
23
23
|
target_time = curr_time + Δt
|
24
|
-
propensities = propensity_vector_TS
|
25
|
-
puts "Propensity vector TS is:"
|
26
|
-
Kernel::p propensities
|
24
|
+
propensities = propensity_vector_TS.column_to_a
|
27
25
|
update_next_gillespie_time( propensities )
|
28
26
|
until ( @next_gillespie_time > target_time )
|
29
27
|
gillespie_step! propensities
|
30
|
-
|
31
|
-
propensities = propensity_vector_TS
|
28
|
+
simulation.recorder.alert
|
29
|
+
propensities = propensity_vector_TS.column_to_a
|
32
30
|
update_next_gillespie_time( propensities )
|
33
31
|
end
|
32
|
+
simulation.increment_time! Δt
|
33
|
+
print '.'
|
34
34
|
end
|
35
35
|
|
36
36
|
# Name of this method.
|
@@ -61,22 +61,33 @@ module YPetri::Core::Timed::Gillespie
|
|
61
61
|
Distribution::Exponential.p_value( rng.rand, sum )
|
62
62
|
end
|
63
63
|
|
64
|
+
# Given a discrete probability distributions, this function makes a random
|
65
|
+
# choice of a category.
|
66
|
+
#
|
67
|
+
def choose_from_discrete_distribution( distribution )
|
68
|
+
sum = rng.rand * distribution.reduce( :+ )
|
69
|
+
distribution.index do |p|
|
70
|
+
sum -= p
|
71
|
+
sum <= 0
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
64
75
|
# Chooses the transition to fire.
|
65
76
|
#
|
66
77
|
def choose_TS_transition( propensities )
|
67
|
-
|
68
|
-
transitions[ propensities.index do |propensity|
|
69
|
-
n -= propensity
|
70
|
-
n <= 0
|
71
|
-
end ]
|
78
|
+
transitions.fetch choose_from_discrete_distribution( propensities )
|
72
79
|
end
|
73
80
|
|
74
|
-
# Fires a transition
|
81
|
+
# Fires a transitions. More precisely, performs a single transition event with
|
82
|
+
# certain stoichiometry, adding / subtracting the number of quanta to / from
|
83
|
+
# the codomain places as indicated by the stoichiometry.
|
75
84
|
#
|
76
85
|
def fire!( transition )
|
77
|
-
|
78
|
-
|
79
|
-
|
86
|
+
cd, sto = transition.codomain, transition.stoichiometry
|
87
|
+
mv = simulation.m_vector
|
88
|
+
cd.zip( sto ).each { |pl, coeff|
|
89
|
+
mv.set( pl, mv.fetch( pl ) + pl.quantum * coeff )
|
80
90
|
}
|
91
|
+
@gillespie_time = @next_gillespie_time
|
81
92
|
end
|
82
93
|
end # YPetri::Core::Timed::Euler
|
data/lib/y_petri/core/timed.rb
CHANGED
@@ -18,8 +18,8 @@ class YPetri::Core::Timed < YPetri::Core
|
|
18
18
|
#
|
19
19
|
def step! Δt=simulation.step
|
20
20
|
increment_marking_vector Δ( Δt )
|
21
|
-
increment_time! Δt
|
22
|
-
|
21
|
+
simulation.increment_time! Δt
|
22
|
+
simulation.recorder.alert
|
23
23
|
end
|
24
24
|
|
25
25
|
# Gradient for free places.
|
@@ -8,8 +8,7 @@ class YPetri::Simulation::MarkingVector
|
|
8
8
|
#
|
9
9
|
def m_vector ids=nil
|
10
10
|
if ids.nil? then
|
11
|
-
|
12
|
-
@m_vector or fail TypeError, msg
|
11
|
+
@m_vector or fail TypeError, "Marking vector not established yet!"
|
13
12
|
else
|
14
13
|
m_vector.select( ids )
|
15
14
|
end
|
@@ -4,6 +4,8 @@
|
|
4
4
|
#
|
5
5
|
class YPetri::Simulation
|
6
6
|
class PlaceRepresentation < ElementRepresentation
|
7
|
+
attr_reader :quantum
|
8
|
+
|
7
9
|
# Index
|
8
10
|
def m_vector_index
|
9
11
|
places.index( self )
|
@@ -13,6 +15,7 @@ class YPetri::Simulation
|
|
13
15
|
#
|
14
16
|
def initialize net_place
|
15
17
|
super
|
18
|
+
@quantum = source.quantum
|
16
19
|
end
|
17
20
|
|
18
21
|
# Setter of clamp.
|
data/lib/y_petri/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
# ==============================================================================
|
5
|
+
#
|
6
|
+
# encoding: utf-8
|
7
|
+
|
8
|
+
require 'y_petri'
|
9
|
+
require 'sy' # This pathway model uses 'sy' metrology domain model.
|
10
|
+
require 'mathn' # Standard library 'mathn' is required.
|
11
|
+
include YPetri # pull in the DSL
|
12
|
+
|
13
|
+
A = Place m!: 10
|
14
|
+
B = Place m!: 10
|
15
|
+
A2B = Transition s: { A: -1, B: 1 }, rate: 0.1
|
16
|
+
B2A = Transition s: { A: 1, B: -1 }, rate: 0.05
|
17
|
+
|
18
|
+
set_step 1 # in seconds
|
19
|
+
set_target_time 100
|
20
|
+
set_sampling 1
|
21
|
+
set_simulation_method :gillespie
|
22
|
+
sim = new_simulation guarded: false
|
23
|
+
run!
|
24
|
+
|
25
|
+
plot_state
|
data/test/simulation_test.rb
CHANGED
@@ -56,6 +56,7 @@ describe YPetri::Simulation do
|
|
56
56
|
@s.net.places.names.must_equal [:A, :B]
|
57
57
|
@s.pn.must_equal [:A, :B]
|
58
58
|
@s.send( :places ).free.size.must_equal 1
|
59
|
+
@s.send( :places ).first.quantum.must_equal 1
|
59
60
|
@s.send( :free_places ).names.must_equal [:A]
|
60
61
|
@s.send( :places ).clamped.size.must_equal 1
|
61
62
|
@s.send( :clamped_places ).names.must_equal [:B]
|
data/test/ttp_pathway.rb
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
# ==============================================================================
|
5
|
+
#
|
6
|
+
# Thymidine triphosphate pathway model.
|
7
|
+
#
|
8
|
+
# Author: Boris Stitnicky
|
9
|
+
# Affiliation:
|
10
|
+
# ... etc etc same shit as in SBML
|
11
|
+
#
|
12
|
+
# ==============================================================================
|
13
|
+
|
14
|
+
# === Load the required libraries.
|
15
|
+
require 'y_nelson' # This pathway model uses FPN domain model.
|
16
|
+
require 'sy' # This pathway model uses 'sy' metrology domain model.
|
17
|
+
require 'mathn' # Standard library 'mathn' is required.
|
18
|
+
include YNelson # pull in the DSL
|
19
|
+
|
20
|
+
require "./ttp_pathway/version" # version number
|
21
|
+
require './ttp_pathway/michaelis_menten' # basic function definitions
|
22
|
+
require './ttp_pathway/general_assumptions' # general model assumptions
|
23
|
+
|
24
|
+
# === Load the chosen cell cycle model.
|
25
|
+
require "./ttp_pathway/simple_cell_cycle"
|
26
|
+
|
27
|
+
# === Load the original version of the dTTP pathway based on the literature.
|
28
|
+
require "./ttp_pathway/literature_model"
|
29
|
+
|
30
|
+
# === Simulate it.
|
31
|
+
set_step 1 # in seconds
|
32
|
+
set_target_time 24.h.in :s
|
33
|
+
set_sampling 5.min.in :s
|
34
|
+
set_simulation_method :pseudo_euler
|
35
|
+
sim = new_simulation guarded: false
|
36
|
+
sim.guarded?
|
37
|
+
sim.run! upto: 10
|
38
|
+
sim.run! upto: 20
|
39
|
+
sim.run! upto: 30
|
40
|
+
sim.run! upto: 40
|
41
|
+
# FIXME: Here it breaks if step is set to
|
42
|
+
# set_step 5 # seconds
|
43
|
+
# it seems that the problem is actually caused by one of the closures
|
44
|
+
# returning an incompatible result (imaginary number in this particular case),
|
45
|
+
# which causes the whole marking vector become imaginary numbers and fail upon
|
46
|
+
# comparison (#>) subsequently.
|
47
|
+
#
|
48
|
+
# The challenge here is to make it easy to debug the models. In execution, I am
|
49
|
+
# against artificial constraints on place marking, and not just because it slows
|
50
|
+
# things down, but mainly because such thing is not a part of the Petri net
|
51
|
+
# business model as I understand it. But at debug time, I am for "type" checking
|
52
|
+
# that identify the source of problem values. And that should be implemented in
|
53
|
+
# simulation, in those several #create_*_closures at the end of the class. There
|
54
|
+
# should be versions of these closures that check the values of the transition
|
55
|
+
# functions as they are produced and pinpoint where the problem is coming from.
|
56
|
+
#
|
57
|
+
# Obviously, YNelson at its current shape has no problems simulating well-written
|
58
|
+
# nets with good simulation settings
|
59
|
+
#
|
60
|
+
# I am not going to program this right now. I'll just look at the simulation
|
61
|
+
# class, and that will be it for this week. Next programming session: Monday.
|
62
|
+
sim.run! upto: 50
|
63
|
+
sim.run! upto: 60
|
64
|
+
sim.run! upto: 70
|
65
|
+
sim.run! upto: 80
|
66
|
+
sim.run! upto: 90
|
67
|
+
sim.run! upto: 100
|
68
|
+
sim.run! upto: 1000
|
69
|
+
sim.run! upto: 10000
|
70
|
+
sim.run!
|
71
|
+
|
72
|
+
sim = new_timed_simulation( guarded: true )
|
73
|
+
sim.run! upto: 1000
|
74
|
+
sim.run! upto: 1000
|
75
|
+
|
76
|
+
# It turns out that simply, the step was too big
|
77
|
+
|
78
|
+
# === Load the acceptance tests for the dTTP pathway behavior.
|
79
|
+
require_relative "ttp_pathway/acceptance_tests"
|
80
|
+
|
81
|
+
# === Run those tests.
|
82
|
+
test simulation
|
83
|
+
|
84
|
+
# === Load the pathway updates according to human judgment.
|
85
|
+
require_relative "ttp_pathway/model_correction"
|
86
|
+
|
87
|
+
# === Rerun the simulation.
|
88
|
+
run!
|
89
|
+
|
90
|
+
# === Run those tests.
|
91
|
+
test simulation
|
92
|
+
|
93
|
+
# Now, having at our disposal a satisfactory dTTP pathway, we can simulate
|
94
|
+
# its behavior throughout the cell cycle.
|
95
|
+
|
96
|
+
# === Rerun the simulation.
|
97
|
+
run!
|
98
|
+
|
99
|
+
# === Visualization suggestions
|
100
|
+
plot :all, except: Timer # marking of all the FPN places except Timer
|
101
|
+
|
102
|
+
plot [ S_phase, A_phase, Cdc20A ] # cell-cycle places marking
|
103
|
+
plot [ S_phase, A_phase, Cdc20A, TK1, TK1di, TK1tetra, TK1di_P, TMPK ] # TTP pathway concentrations
|
104
|
+
plot [ S_phase, TK1, TK1di, TK1tetra, TK1di_P ] # TTP pathway enzyme concentrations
|
105
|
+
plot [ S_phase, Thymidine, TMP, TDP, TTP, T23P ] # TTP patwhay concentrations simplified
|
106
|
+
plot :flux, except: Clock # all flux except time flow
|
107
|
+
plot :flux, except: [ Clock, T23P_flux_clamp, TMP_flux_clamp,
|
108
|
+
Thymidine_flux_clamp ] # all except flux clamps
|
109
|
+
plot :state, except: [ Timer, AMP, ADP, ATP, UTP, UDP, UMP, GMP, DeoxyATP,
|
110
|
+
DeoxyADP, DeoxyAMP, DeoxyCytidine, DeoxyCMP, DeoxyCDP,
|
111
|
+
DeoxyCTP, DeoxyGTP, DeoxyGMP, DeoxyUridine, DeoxyUMP,
|
112
|
+
DeoxyUDP, DeoxyUTP, DeoxyT23P ] # cell cycle marking
|
113
|
+
|
114
|
+
# Now let's look into the graph visualization.
|
115
|
+
|
116
|
+
# Define function to display it with kioclient
|
117
|
+
#
|
118
|
+
def showit( fɴ )
|
119
|
+
system "sleep 0.2; kioclient exec 'file:%s'" %
|
120
|
+
File.expand_path( '.', fɴ )
|
121
|
+
end
|
122
|
+
|
123
|
+
# Define enzyme places
|
124
|
+
enzyme_places = {
|
125
|
+
TK1: "TK1",
|
126
|
+
TK1di: "TK1 dimer",
|
127
|
+
TK1di_P: "TK1 phosphorylated dimer",
|
128
|
+
TK1tetra: "TK1 tetramer",
|
129
|
+
TMPK: "TMPK"
|
130
|
+
}
|
131
|
+
|
132
|
+
# Define small molecule places
|
133
|
+
small_molecule_places = {
|
134
|
+
Thymidine: "Thymidine",
|
135
|
+
TMP: "Thymidine monophosphate",
|
136
|
+
T23P: "Thymidine diphosphate / triphosphate pool",
|
137
|
+
TDP: "Thymidine diphosphate",
|
138
|
+
TTP: "Thymidine triphosphate"
|
139
|
+
}
|
140
|
+
|
141
|
+
# Define graphviz places
|
142
|
+
def graphviz places
|
143
|
+
require 'graphviz'
|
144
|
+
γ = GraphViz.new :G, type: :digraph # Create a new graph
|
145
|
+
|
146
|
+
# # set global node options
|
147
|
+
# γ.node[:color] = "#ddaa66"
|
148
|
+
# γ.node[:style] = "filled"
|
149
|
+
# γ.node[:shape] = "box"
|
150
|
+
# γ.node[:penwidth] = "1"
|
151
|
+
# γ.node[:fontname] = "Trebuchet MS"
|
152
|
+
# γ.node[:fontsize] = "8"
|
153
|
+
# γ.node[:fillcolor] = "#ffeecc"
|
154
|
+
# γ.node[:fontcolor] = "#775500"
|
155
|
+
# γ.node[:margin] = "0.0"
|
156
|
+
|
157
|
+
# # set global edge options
|
158
|
+
# γ.edge[:color] = "#999999"
|
159
|
+
# γ.edge[:weight] = "1"
|
160
|
+
# γ.edge[:fontsize] = "6"
|
161
|
+
# γ.edge[:fontcolor] = "#444444"
|
162
|
+
# γ.edge[:fontname] = "Verdana"
|
163
|
+
# γ.edge[:dir] = "forward"
|
164
|
+
# γ.edge[:arrowsize] = "0.5"
|
165
|
+
|
166
|
+
nodes = Hash[ places.map { |pɴ, label| # make nodes
|
167
|
+
[ pɴ, γ.add_nodes( label ) ]
|
168
|
+
} ]
|
169
|
+
|
170
|
+
places.each { |pɴ, label| # add edges
|
171
|
+
p = place pɴ
|
172
|
+
p.upstream_places.each { |up|
|
173
|
+
node = nodes[ pɴ ]
|
174
|
+
next unless places.map { |ɴ, _| ɴ }.include? up.name
|
175
|
+
next if up == p
|
176
|
+
upstream_node = nodes[ up.name ]
|
177
|
+
upstream_node << node
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
γ.output png: "enzymes.png" # Generate output image
|
182
|
+
showit "enzymes.png"
|
183
|
+
end
|
184
|
+
|
185
|
+
[ enzyme_places, small_molecule_places ].each { |ꜧ|
|
186
|
+
ꜧ.define_singleton_method :+ do |o| merge o end }
|
187
|
+
|
188
|
+
graphviz enzyme_places
|
189
|
+
graphviz small_molecule_places
|
190
|
+
graphviz enzyme_places + small_molecule_places # combining pathways
|
191
|
+
|
192
|
+
net.visualize
|
193
|
+
|
194
|
+
|
195
|
+
# ==============================================================================
|
196
|
+
#
|
197
|
+
# 1. Please note that the script contained in this file does not constitute
|
198
|
+
# programming in the sense of software development. It is simply scripted
|
199
|
+
# user interaction with YPetri FPN simulator. This user interaction takes
|
200
|
+
# place inside the interactive Ruby session (irb), or it can be saved and
|
201
|
+
# run all at once as a script. The user has at her disposal the devices and
|
202
|
+
# language constructs of full-fledged Ruby. The user is not sandboxed (the
|
203
|
+
# problem of many GUI-based "applications"). In other words, the simulation
|
204
|
+
# software does not wrap its host language. Rather, it extends Ruby, giving
|
205
|
+
# its interactive session new, pathway-specific abilities. No constraints
|
206
|
+
# are placed on how complicated or intelligent the user's use of the software
|
207
|
+
# can be.
|
208
|
+
#
|
209
|
+
# 2. However, on this dTTP pathway model, it can be already noted, that there
|
210
|
+
# would be certain actions, that the user will have to repeat in most of
|
211
|
+
# her biological models usin YPetri. For example, Michaelis & Menten function
|
212
|
+
# definitions are to be expected in many pathway models. More seriously, the
|
213
|
+
# Petri net models of enzymes and signal proteins suffer exponential explosion
|
214
|
+
# with number of eligible reactants, competitive inhibitors, and other
|
215
|
+
# interacting molecules. In typical smaller pathway models, this explosion is
|
216
|
+
# not deadly, because only few of these interacting molecules are considered.
|
217
|
+
# But the amount of scripting the user is required to do would still be
|
218
|
+
# reduced many times, if such enzymes and signal proteins can be expressed
|
219
|
+
# declaratively, rather than by manual enumeration of their Petri net
|
220
|
+
# transitions. All of this provides motivation towards developing even more
|
221
|
+
# concise way of pathway encoding than that provided by plain FPN.
|
222
|
+
#
|
223
|
+
# 3. In the planned more concise pathway encoding (that would subsume the
|
224
|
+
# functionality of the current standards such as SBML), there is one more
|
225
|
+
# major concern – storing relations. I feel tempted to use Ted Nelson's zz
|
226
|
+
# structure as an alternative to usual SQL and non-SQL relational databases.
|
227
|
+
# The usability of zz structures in bioinformatics has already been noted.
|
228
|
+
# However, I am aware of the advantage held by the existing database merely
|
229
|
+
# by the virtue of its maturity. To account for the possibility, that my zz
|
230
|
+
# domain model would become a bottleneck, I will leave the back door open on
|
231
|
+
# the possibility of using existing database software later on.
|
232
|
+
#
|
233
|
+
# ==============================================================================
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: y_petri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.30
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
@@ -178,12 +178,14 @@ files:
|
|
178
178
|
- test/examples/demonstrator_3.rb
|
179
179
|
- test/examples/demonstrator_4.rb
|
180
180
|
- test/examples/example_2.rb
|
181
|
+
- test/examples/gillespie.rb
|
181
182
|
- test/examples/manual_examples.rb
|
182
183
|
- test/net_test.rb
|
183
184
|
- test/place_test.rb
|
184
185
|
- test/sim_test
|
185
186
|
- test/simulation_test.rb
|
186
187
|
- test/transition_test.rb
|
188
|
+
- test/ttp_pathway.rb
|
187
189
|
- test/world_mock.rb
|
188
190
|
- test/world_test.rb
|
189
191
|
- test/y_petri_test.rb
|
@@ -224,12 +226,14 @@ test_files:
|
|
224
226
|
- test/examples/demonstrator_3.rb
|
225
227
|
- test/examples/demonstrator_4.rb
|
226
228
|
- test/examples/example_2.rb
|
229
|
+
- test/examples/gillespie.rb
|
227
230
|
- test/examples/manual_examples.rb
|
228
231
|
- test/net_test.rb
|
229
232
|
- test/place_test.rb
|
230
233
|
- test/sim_test
|
231
234
|
- test/simulation_test.rb
|
232
235
|
- test/transition_test.rb
|
236
|
+
- test/ttp_pathway.rb
|
233
237
|
- test/world_mock.rb
|
234
238
|
- test/world_test.rb
|
235
239
|
- test/y_petri_test.rb
|