y_petri 2.0.7 → 2.0.14.p1

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.
data/test/y_petri_test.rb CHANGED
@@ -7,1114 +7,23 @@ require_relative '../lib/y_petri' # tested component itself
7
7
  # require 'y_petri'
8
8
  # require 'sy'
9
9
 
10
- include Pyper if require 'pyper'
11
-
12
- # **************************************************************************
13
- # Test of Net class.
14
- # **************************************************************************
15
- #
16
- describe ::YPetri::Net do
17
- before do
18
- # skip "to speed up testing"
19
- @tç = tç = Class.new ::YPetri::Transition
20
- @pç = pç = Class.new ::YPetri::Place
21
- @nç = nç = Class.new ::YPetri::Net
22
- [ tç, pç, nç ].each { |ç|
23
- ç.namespace!.class_exec {
24
- define_method :Place do pç end
25
- define_method :Transition do tç end
26
- define_method :Net do nç end
27
- private :Place, :Transition, :Net
28
- }
29
- }
30
- @p1 = pç.new ɴ: "A", quantum: 0.1, marking: 1.1
31
- @p2 = pç.new ɴ: "B", quantum: 0.1, marking: 2.2
32
- @p3 = pç.new ɴ: "C", quantum: 0.1, marking: 3.3
33
- @net = nç.new
34
- [@p1, @p2, @p3].each { |p| @net.include_place! p }
35
- @p_not_included = pç.new ɴ: "X", marking: 0
36
- end
37
-
38
- describe "net of 3 places and no transitions" do
39
- before do
40
- @p1.m = 1.1
41
- @p2.m = 2.2
42
- @p3.m = 3.3
43
- end
44
-
45
- it "should expose its elements" do
46
- assert_equal [@p1, @p2, @p3], @net.places
47
- assert_equal [:A, :B, :C], @net.pp
48
- assert_equal [], @net.transitions
49
- end
50
-
51
- it "should expose transition groups" do
52
- assert_equal [], @net.transitions_with_rate
53
- assert_equal [], @net.rateless_transitions
54
- assert_equal [], @net.transitions_without_rate
55
- assert_equal [], @net.stoichiometric_transitions
56
- assert_equal [], @net.nonstoichiometric_transitions
57
- end
58
-
59
- it "should tell its qualities" do
60
- assert_equal true, @net.functional?
61
- assert_equal true, @net.timed?
62
- assert @net.include?( @p1 ) && !@net.include?( YPetri::Place.new )
63
- end
64
-
65
- it "should have 'standard equipment' methods" do
66
- assert @net == @net.dup
67
- assert @net.inspect.start_with? "#<Net:"
68
- assert @net.include?( @p1 )
69
- assert ! @net.include?( @p_not_included )
70
- begin
71
- @net.exclude_place! @p_not_included
72
- @net.include_transition! YPetri::Transition.new( s: { @p_not_included => -1 } )
73
- flunk "Attempt to include illegal transition fails to raise"
74
- rescue; end
75
- end
76
-
77
- describe "plus 1 stoichio. transition with rate" do
78
- before do
79
- @t1 = @tç.new!( ɴ: "T1",
80
- s: { @p1 => 1, @p2 => -1, @p3 => -1 },
81
- rate: 0.01 )
82
- @net.include_transition! @t1
83
- end
84
-
85
- it "should expose its elements" do
86
- assert_equal [@t1], @net.transitions
87
- assert_equal [:T1], @net.tt
88
- end
89
-
90
- it "should expose transition groups" do
91
- assert_equal true, @t1.has_rate?
92
- assert_equal [@t1], @net.transitions_with_rate
93
- assert_equal [], @net.rateless_transitions
94
- assert_equal [@t1], @net.stoichiometric_transitions
95
- assert_equal [], @net.nonstoichiometric_transitions
96
- end
97
-
98
- it "should tell its qualities" do
99
- assert_equal true, @net.functional?
100
- assert_equal true, @net.timed?
101
- assert @net.include?( @t1 )
102
- end
103
-
104
- it "should have #place & #transition for safe access to the said elements" do
105
- @net.send( :place, @p1 ).must_equal @p1
106
- @net.send( :transition, @t1 ).must_equal @t1
107
- end
108
-
109
- it "has #new_simulation & #new_timed_simulation constructors" do
110
- @net.must_respond_to :new_simulation
111
- @net.must_respond_to :new_timed_simulation
112
- end
113
-
114
- it "should have other methods" do
115
- assert_equal [1.1, 2.2, 3.3], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
116
- assert_equal 2.2 * 3.3 * 0.01, @t1.rate_closure.call( @p2.marking, @p3.marking )
117
- assert_equal [ @p2, @p3 ], @t1.domain
118
- @t1.fire! 1
119
- assert_equal [1.1726, 2.1274, 3.2274], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
120
- end
121
-
122
- describe "plus 1 more nameless timeless functionless transition" do
123
- before do
124
- @t2 = @tç.new s: { @p2 => -1, @p3 => 1 }
125
- @net.include_transition! @t2
126
- end
127
-
128
- it "should expose its elements" do
129
- assert_equal [@t1, @t2], @net.transitions
130
- assert_equal [:T1, nil], @net.tt
131
- @net.tap{ |n| n.exclude_transition! @t1 }.exclude_transition! @t2
132
- @net.tap{ |n| n.exclude_place! @p3 }.pp.must_equal [:A, :B]
133
- end
134
-
135
- it "should expose transition groups" do
136
- assert_equal [], @net.timeless_nonstoichiometric_transitions
137
- assert_equal [], @net.timeless_nonstoichiometric_tt
138
- assert_equal [@t2], @net.timeless_stoichiometric_transitions
139
- assert_equal [nil], @net.timeless_stoichiometric_tt
140
- assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
141
- assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
142
- assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
143
- assert_equal [], @net.timed_rateless_nonstoichiometric_tt
144
- assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
145
- assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
146
- assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
147
- assert_equal [], @net.timed_rateless_nonstoichiometric_tt
148
- assert_equal [], @net.nonstoichiometric_transitions_with_rate
149
- assert_equal [], @net.nonstoichiometric_tt_with_rate
150
- assert_equal [@t1], @net.stoichiometric_transitions_with_rate
151
- assert_equal [:T1], @net.stoichiometric_tt_with_rate
152
- assert_equal [], @net.assignment_transitions
153
- assert_equal [], @net.assignment_tt
154
- assert_equal [@t1, @t2], @net.stoichiometric_transitions
155
- assert_equal [:T1, nil], @net.stoichiometric_tt
156
- assert_equal [], @net.nonstoichiometric_transitions
157
- assert_equal [], @net.nonstoichiometric_tt
158
- assert_equal [@t1], @net.timed_transitions
159
- assert_equal [:T1], @net.timed_tt
160
- assert_equal [@t2], @net.timeless_transitions
161
- assert_equal [nil], @net.timeless_tt
162
- assert_equal [@t1], @net.transitions_with_rate
163
- assert_equal [:T1], @net.tt_with_rate
164
- assert_equal [@t2], @net.rateless_transitions
165
- assert_equal [nil], @net.rateless_tt
166
- end
167
-
168
- it "should tell its qualities" do
169
- assert_equal false, @net.functional?
170
- assert_equal false, @net.timed?
171
- @net.exclude_transition! @t2
172
- assert_equal true, @net.functional?
173
- assert_equal true, @net.timed?
174
- end
175
- end
176
- end
177
- end
178
- end
179
-
180
-
181
- # **************************************************************************
182
- # Test of Simulation class.
183
- # **************************************************************************
184
- #
185
- describe ::YPetri::Simulation do
186
- before do
187
- # skip "to make the testing faster"
188
- @pç = pç = Class.new( ::YPetri::Place )
189
- @tç = tç = Class.new( ::YPetri::Transition )
190
- @nç = nç = Class.new( ::YPetri::Net )
191
- [ @pç, @tç, @nç ].each { |klass|
192
- klass.namespace!.class_exec {
193
- private
194
- define_method :Place do pç end
195
- define_method :Transition do tç end
196
- define_method :Net do nç end
197
- }
198
- }
199
- @p1 = @pç.new name: "P1", default_marking: 1
200
- @p2 = @pç.new name: "P2", default_marking: 2
201
- @p3 = @pç.new name: "P3", default_marking: 3
202
- @p4 = @pç.new name: "P4", default_marking: 4
203
- @p5 = @pç.new name: "P5", default_marking: 5
204
- @t1 = @tç.new name: "T1",
205
- s: { @p1 => -1, @p2 => -1, @p4 => 1 },
206
- rate: 0.1
207
- @t2 = @tç.new name: "T2",
208
- s: { @p1 => -1, @p3 => 1 },
209
- rate: -> a { a * 0.5 }
210
- @t3 = @tç.new name: "T3",
211
- s: { @p1 => -1, @p2 => -1, @p4 => 1 },
212
- domain: @p3,
213
- rate: -> a { a * 0.5 }
214
- @net = @nç.new << @p1 << @p2 << @p3 << @p4 << @p5
215
- @net.include_transition! @t1
216
- @net.include_transition! @t2
217
- @net << @t3
218
- @s = YPetri::Simulation.new net: @net,
219
- marking_clamps: { @p1 => 2.0, @p5 => 2.0 },
220
- initial_marking: { @p2 => @p2.default_marking,
221
- @p3 => @p3.default_marking,
222
- @p4 => @p4.default_marking }
223
- end
224
-
225
- it "exposes the net" do
226
- @s.net.must_equal @net
227
- @s.net.places.size.must_equal 5
228
- @s.net.transitions.size.must_equal 3
229
- assert @net.include? @t1
230
- assert @s.net.include? @t1
231
- assert @net.include? @t2
232
- assert @s.net.include? @t2
233
- assert @net.include? @t3
234
- assert @s.net.include? @t3
235
- @s.net.transitions.size.must_equal 3
236
- end
237
-
238
- it "exposes Petri net places" do
239
- @s.places.must_equal [ @p1, @p2, @p3, @p4, @p5 ]
240
- @s.pp.must_equal [ :P1, :P2, :P3, :P4, :P5 ]
241
- @s.places( :pp ).must_equal( { @p1 => :P1, @p2 => :P2, @p3 => :P3,
242
- @p4 => :P4, @p5 => :P5 } )
243
- @s.pp( :pp ).must_equal( { P1: :P1, P2: :P2, P3: :P3, P4: :P4, P5: :P5 } )
244
- end
245
-
246
- it "exposes Petri net transitions" do
247
- @s.transitions.must_equal [ @t1, @t2, @t3 ]
248
- @s.tt.must_equal [ :T1, :T2, :T3 ]
249
- @s.transitions( :tt ).must_equal( { @t1 => :T1, @t2 => :T2, @t3 => :T3 } )
250
- @s.tt( :tt ).must_equal( { T1: :T1, T2: :T2, T3: :T3 } )
251
- end
252
-
253
- it "exposes place clamps" do
254
- @s.clamped_places( :place_clamps ).must_equal( { @p1 => 2, @p5 => 2 } )
255
- @s.clamped_pp( :place_clamps ).must_equal( { P1: 2, P5: 2 } )
256
- end
257
-
258
- it "presents free places" do
259
- @s.free_places.must_equal [ @p2, @p3, @p4 ]
260
- @s.free_pp.must_equal [ :P2, :P3, :P4 ]
261
- @s.free_places( :free_pp )
262
- .must_equal( { @p2 => :P2, @p3 => :P3, @p4 => :P4 } )
263
- @s.free_pp( :free_pp )
264
- .must_equal( { P2: :P2, P3: :P3, P4: :P4 } )
265
- end
266
-
267
- it "presents clamped places" do
268
- @s.clamped_places.must_equal [ @p1, @p5 ]
269
- @s.clamped_pp.must_equal [ :P1, :P5 ]
270
- @s.clamped_places( :clamped_pp ).must_equal( { @p1 => :P1, @p5 => :P5 } )
271
- @s.clamped_pp( :clamped_pp ).must_equal( { P1: :P1, P5: :P5 } )
272
- end
273
-
274
- it "exposes initial marking" do
275
- @s.free_places( :im ).must_equal( { @p2 => 2, @p3 => 3, @p4 => 4 } )
276
- @s.free_pp( :im ).must_equal( { P2: 2, P3: 3, P4: 4 } )
277
- @s.im.must_equal [ 2, 3, 4 ]
278
- @s.im_vector.must_equal Matrix[[2], [3], [4]]
279
- @s.im_vector.must_equal @s.iᴍ
280
- end
281
-
282
- it "exposes marking (simulation state)" do
283
- @s.m.must_equal [2, 3, 4] # (we're after reset)
284
- @s.free_places( :m ).must_equal( { @p2 => 2, @p3 => 3, @p4 => 4 } )
285
- @s.free_pp( :m ).must_equal( { P2: 2, P3: 3, P4: 4 } )
286
- @s.ᴍ.must_equal Matrix[[2], [3], [4]]
287
- end
288
-
289
- it "separately exposes marking of clamped places" do
290
- @s.m_clamped.must_equal [ 2, 2 ]
291
- @s.clamped_places( :m_clamped ).must_equal( { @p1 => 2, @p5 => 2 } )
292
- @s.clamped_pp( :m_clamped ).must_equal( { P1: 2, P5: 2 } )
293
- @s.ᴍ_clamped.must_equal Matrix[[2], [2]]
294
- end
295
-
296
- it "exposes marking of all places (with capitalized M)" do
297
- @s.marking.must_equal [ 2, 2, 3, 4, 2 ]
298
- @s.places( :marking )
299
- .must_equal( { @p1 => 2, @p2 => 2, @p3 => 3, @p4 => 4, @p5 => 2 } )
300
- @s.pp( :marking ).must_equal( { P1: 2, P2: 2, P3: 3, P4: 4, P5: 2 } )
301
- @s.marking_vector.must_equal Matrix[[2], [2], [3], [4], [2]]
302
- end
303
-
304
- it "has #S_for / #stoichiometry_matrix_for" do
305
- assert_equal Matrix.empty(3, 0), @s.S_for( [] )
306
- assert_equal Matrix[[-1], [0], [1]], @s.S_for( [@t1] )
307
- x = Matrix[[-1, -1], [0, 0], [1, 1]]
308
- x.must_equal @s.S_for( [@t1, @t3] )
309
- x.must_equal( @s.S_for( [@t1, @t3] ) )
310
- @s.stoichiometry_matrix_for( [] ).must_equal Matrix.empty( 5, 0 )
311
- end
312
-
313
- it "has stoichiometry matrix for 3. tS transitions" do
314
- @s.S_for_tS.must_equal Matrix.empty( 3, 0 )
315
- end
316
-
317
- it "has stoichiometry matrix for 4. Sr transitions" do
318
- @s.S_for_TSr.must_equal Matrix.empty( 3, 0 )
319
- end
320
-
321
- it "has stoichiometry matrix for 6. SR transitions" do
322
- @s.S_for_SR.must_equal Matrix[[-1, 0, -1], [0, 1, 0], [1, 0, 1]]
323
- @s.S.must_equal @s.S_for_SR
324
- end
325
-
326
- it "presents 1. ts" do
327
- assert_equal [], @s.ts_transitions
328
- assert_equal( {}, @s.ts_transitions( :ts_transitions ) )
329
- assert_equal [], @s.ts_tt
330
- assert_equal( {}, @s.ts_tt( :ts_tt ) )
331
- end
332
-
333
- it "presents 2. tS transitions" do
334
- assert_equal [], @s.tS_transitions
335
- assert_equal( {}, @s.tS_transitions( :tS_transitions ) )
336
- assert_equal [], @s.tS_tt
337
- assert_equal( {}, @s.tS_tt( :tS_tt ) )
338
- end
339
-
340
- it "presents 3. Tsr transitions" do
341
- assert_equal [], @s.Tsr_transitions
342
- assert_equal( {}, @s.Tsr_transitions( :Tsr_transitions ) )
343
- assert_equal [], @s.Tsr_tt
344
- assert_equal( {}, @s.Tsr_tt( :Tsr_tt ) )
345
- end
346
-
347
- it "presents 4. TSr transitions" do
348
- assert_equal [], @s.TSr_transitions
349
- assert_equal( {}, @s.TSr_transitions( :TSr_tt ) )
350
- assert_equal [], @s.TSr_tt
351
- assert_equal( {}, @s.TSr_tt( :TSr_tt ) )
352
- end
353
-
354
- it "presents 5. sR transitions" do
355
- assert_equal [], @s.sR_transitions
356
- assert_equal( {}, @s.sR_transitions( :sR_transitions ) )
357
- assert_equal [], @s.sR_tt
358
- assert_equal( {}, @s.sR_tt( :sR_tt ) )
359
- end
360
-
361
- it "presents SR transitions" do
362
- assert_equal [@t1, @t2, @t3], @s.SR_transitions
363
- assert_equal( { @t1 => :T1, @t2 => :T2, @t3 => :T3 },
364
- @s.SR_transitions( :SR_tt ) )
365
- assert_equal [:T1, :T2, :T3], @s.SR_tt
366
- assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.SR_tt( :SR_tt ) )
367
- end
368
-
369
- it "presents A transitions" do
370
- assert_equal [], @s.A_transitions
371
- assert_equal( {}, @s.A_transitions( :A_tt ) )
372
- assert_equal [], @s.A_tt
373
- assert_equal( {}, @s.A_tt( :A_tt ) )
374
- end
375
-
376
- it "presents S transitions" do
377
- assert_equal [@t1, @t2, @t3], @s.S_transitions
378
- assert_equal [:T1, :T2, :T3], @s.S_tt
379
- assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.S_tt( :S_tt ) )
380
- end
381
-
382
- it "presents s transitions" do
383
- assert_equal [], @s.s_transitions
384
- assert_equal [], @s.s_tt
385
- assert_equal( {}, @s.s_tt( :s_tt ) )
386
- end
387
-
388
- it "presents R transitions" do
389
- assert_equal [@t1, @t2, @t3], @s.R_transitions
390
- assert_equal [:T1, :T2, :T3], @s.R_tt
391
- assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.R_tt( :R_tt ) )
392
- end
393
-
394
- it "presents r transitions" do
395
- assert_equal [], @s.r_transitions
396
- assert_equal [], @s.r_tt
397
- end
398
-
399
- it "1. handles ts transitions" do
400
- @s.Δ_closures_for_tsa.must_equal []
401
- @s.Δ_if_tsa_fire_once.must_equal Matrix.zero( @s.free_pp.size, 1 )
402
- end
403
-
404
- it "2. handles Tsr transitions" do
405
- @s.Δ_closures_for_Tsr.must_equal []
406
- @s.Δ_for_Tsr( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
407
- end
408
-
409
- it "3. handles tS transitions" do
410
- @s.action_closures_for_tS.must_equal []
411
- @s.action_vector_for_tS.must_equal Matrix.column_vector( [] )
412
- @s.α_for_t.must_equal Matrix.column_vector( [] )
413
- @s.Δ_if_tS_fire_once.must_equal Matrix.zero( @s.free_pp.size, 1 )
414
- end
415
-
416
- it "4. handles TSr transitions" do
417
- @s.action_closures_for_TSr.must_equal []
418
- @s.action_closures_for_Tr.must_equal []
419
- @s.action_vector_for_TSr( 1.0 ).must_equal Matrix.column_vector( [] )
420
- @s.action_vector_for_Tr( 1.0 ).must_equal Matrix.column_vector( [] )
421
- @s.Δ_for_TSr( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
422
- end
423
-
424
- it "5. handles sR transitions" do
425
- assert_equal [], @s.rate_closures_for_sR
426
- assert_equal [], @s.rate_closures_for_s
427
- # @s.gradient_for_sR.must_equal Matrix.zero( @s.free_pp.size, 1 )
428
- @s.Δ_Euler_for_sR( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
429
- end
430
-
431
- it "6. handles stoichiometric transitions with rate" do
432
- @s.rate_closures_for_SR.size.must_equal 3
433
- @s.rate_closures_for_S.size.must_equal 3
434
- @s.rate_closures.size.must_equal 3
435
- @s.flux_vector_for_SR.must_equal Matrix.column_vector( [ 0.4, 1.0, 1.5 ] )
436
- @s.φ_for_SR.must_equal @s.flux_vector
437
- @s.SR_tt( :φ_for_SR ).must_equal( { T1: 0.4, T2: 1.0, T3: 1.5 } )
438
- @s.Euler_action_vector_for_SR( 1 )
439
- .must_equal Matrix.column_vector [ 0.4, 1.0, 1.5 ]
440
- @s.SR_tt( :Euler_action_for_SR, 1 ).must_equal( T1: 0.4, T2: 1.0, T3: 1.5 )
441
- @s.Δ_Euler_for_SR( 1 ).must_equal Matrix[[-1.9], [1.0], [1.9]]
442
- @s.free_pp( :Δ_Euler_for_SR, 1 ).must_equal( { P2: -1.9, P3: 1.0, P4: 1.9 } )
443
- end
444
-
445
- it "presents sparse stoichiometry vectors for its transitions" do
446
- @s.sparse_σ( @t1 ).must_equal Matrix.cv( [-1, 0, 1] )
447
- @s.sparse_stoichiometry_vector( @t1 )
448
- .must_equal Matrix.cv( [-1, -1, 0, 1, 0] )
449
- end
450
-
451
- it "presents correspondence matrices free, clamped => all places" do
452
- @s.F2A.must_equal Matrix[[0, 0, 0], [1, 0, 0], [0, 1, 0],
453
- [0, 0, 1], [0, 0, 0]]
454
- @s.C2A.must_equal Matrix[[1, 0], [0, 0], [0, 0], [0, 0], [0, 1]]
455
- end
456
- end
457
-
458
-
459
- # **************************************************************************
460
- # Test of TimedSimulation class.
461
- # **************************************************************************
462
- #
463
- describe ::YPetri::TimedSimulation do
464
- before do
465
- # skip "to speed up testing"
466
- @a = ::YPetri::Place.new default_marking: 1.0
467
- @b = ::YPetri::Place.new default_marking: 2.0
468
- @c = ::YPetri::Place.new default_marking: 3.0
469
- end
470
-
471
- describe "timed assembly a + b >> c" do
472
- before do
473
- @t1 = ::YPetri::Transition.new s: { @a => -1, @b => -1, @c => 1 }, rate: 0.1
474
- @net = ::YPetri::Net.new << @a << @b << @c << @t1
475
- @im_collection = [@a, @b, @c].τBmχHτ &:default_marking
476
- end
477
-
478
- describe "simulation with step size 1" do
479
- before do
480
- @sim = ::YPetri::TimedSimulation.new net: @net,
481
- initial_marking: @im_collection,
482
- step: 1,
483
- sampling: 10,
484
- target_time: 100
485
- end
486
-
487
- it "should #step! with expected results" do
488
- m = @sim.step!.marking
489
- assert_in_delta 0.8, m[ 0 ], 1e-9
490
- assert_in_delta 1.8, m[ 1 ], 1e-9
491
- assert_in_delta 3.2, m[ 2 ], 1e-9
492
- end
493
-
494
- it "should behave" do
495
- assert_in_delta 0, ( Matrix.column_vector( [-0.02, -0.02, 0.02] ) -
496
- @sim.ΔE( 0.1 ) ).column( 0 ).norm, 1e-9
497
- @sim.step! 0.1
498
- assert_in_delta 0, ( Matrix.column_vector( [0.98, 1.98, 3.02] ) -
499
- @sim.marking_vector ).column( 0 ).norm, 1e-9
500
-
501
- end
502
- end
503
-
504
- describe "simulation with step size 0.1" do
505
- before do
506
- @sim = ::YPetri::TimedSimulation.new net: @net,
507
- initial_marking: @im_collection,
508
- step: 0.1,
509
- sampling: 10,
510
- target_time: 100
511
- end
512
-
513
- it "should behave" do
514
- m = @sim.step!.marking
515
- assert_equal 10, @sim.sampling_period
516
- assert_in_delta 0.98, m[ 0 ], 1e-9
517
- assert_in_delta 1.98, m[ 1 ], 1e-9
518
- assert_in_delta 3.02, m[ 2 ], 1e-9
519
- end
520
-
521
- it "should behave" do
522
- @sim.run_until_target_time! 31
523
- expected_recording = {
524
- 0 => [ 1, 2, 3 ],
525
- 10 => [ 0.22265, 1.22265, 3.77735 ],
526
- 20 => [ 0.07131, 1.07131, 3.92869 ],
527
- 30 => [ 0.02496, 1.02496, 3.97503 ]
528
- }
529
- assert_equal expected_recording.keys, @sim.recording.keys
530
- assert_in_delta 0, expected_recording.values.zip( @sim.recording.values )
531
- .map{ |expected, actual| ( Vector[ *expected ] -
532
- Vector[ *actual ] ).norm }.reduce( :+ ), 1e-4
533
- expected_recording_string =
534
- "0.0,1.0,2.0,3.0\n" +
535
- "10.0,0.22265,1.22265,3.77735\n" +
536
- "20.0,0.07131,1.07131,3.92869\n" +
537
- "30.0,0.02496,1.02496,3.97504\n"
538
- assert_equal expected_recording_string, @sim.recording_csv_string
539
- end
540
- end
541
- end
542
-
543
- describe "timed 'isomerization' with given as λ" do
544
- before do
545
- @t2 = ::YPetri::Transition.new s: { @a => -1, @c => 1 },
546
- rate_closure: -> a { a * 0.5 }
547
- @net = ::YPetri::Net.new << @a << @b << @c << @t2
548
- end
549
-
550
- describe "behavior of #step" do
551
- before do
552
- @sim = ::YPetri::TimedSimulation.new net: @net,
553
- initial_marking: [ @a, @b, @c ].τBᴍHτ( &:default_marking ),
554
- step: 1,
555
- sampling: 10
556
- end
557
-
558
- it "should have expected stoichiometry matrix" do
559
- @sim.S.must_equal Matrix[ [-1, 0, 1] ].t
560
- m = @sim.step!.marking
561
- m[ 0 ].must_be_within_epsilon( 0.5, 1e-6 )
562
- m[ 1 ].must_equal 2
563
- m[ 2 ].must_be_within_delta( 3.5, 1e-9 )
564
- end
565
- end
566
- end
567
-
568
- describe "timed controlled isomerization" do
569
- before do
570
- @t3 = ::YPetri::Transition.new s: { @a => -1, @c => 1 },
571
- domain: @b,
572
- rate: -> a { a * 0.5 }
573
- @net = ::YPetri::Net.new << @a << @b << @c << @t3
574
- @sim = ::YPetri::TimedSimulation.new net: @net,
575
- initial_marking: { @a => 1, @b => 0.6, @c => 3 },
576
- step: 1,
577
- sampling: 10,
578
- target_time: 2
579
- end
580
-
581
- it "should exhibit correct behavior of #step" do
582
- @sim.marking.must_equal [1.0, 0.6, 3.0]
583
- @t3.stoichiometric?.must_equal true
584
- @t3.timed?.must_equal true
585
- @t3.has_rate?.must_equal true
586
- @sim.gradient.must_equal Matrix.cv [-0.3, 0.0, 0.3]
587
- @sim.Δ_Euler.must_equal Matrix.cv [-0.3, 0.0, 0.3]
588
- @sim.step!
589
- @sim.marking_vector.must_equal Matrix.cv [0.7, 0.6, 3.3]
590
- @sim.euler_step!
591
- @sim.run!
592
- @sim.marking_vector.map( &[:round, 5] )
593
- .must_equal Matrix.cv [0.4, 0.6, 3.6]
594
- end
595
- end
596
- end
597
-
598
-
599
- # **************************************************************************
600
- # Test of Workspace class.
601
- # **************************************************************************
602
- #
603
- describe ::YPetri::Workspace do
604
- before do
605
- # skip "to speed up testing"
606
- @w = ::YPetri::Workspace.new
607
- a = @w.Place.new!( default_marking: 1.0, name: "AA" )
608
- b = @w.Place.new!( default_marking: 2.0, name: "BB" )
609
- c = @w.Place.new!( ɴ: "CC", default_marking: 3.0 )
610
- t1 = @w.Transition.new! s: { a => -1, b => -1, c => 1 },
611
- rate: 0.1,
612
- ɴ: "AA_BB_assembly"
613
- t2 = @w.Transition.new! ɴ: "AA_appearing",
614
- codomain: a,
615
- rate: -> { 0.1 },
616
- stoichiometry: 1
617
- @pp, @tt = [a, b, c], [t1, t2]
618
- @f_name = "test_output.csv"
619
- @w.set_imc @pp.τBᴍHτ( &:default_marking )
620
- @w.set_ssc step: 0.1, sampling: 10, target_time: 50
621
- @w.set_cc( {} )
622
- @sim = @w.new_timed_simulation
623
- File.delete @f_name rescue nil
624
- end
625
-
626
- it "should present places, transitions, nets, simulations" do
627
- assert_kind_of ::YPetri::Net, @w.Net::Top
628
- assert_equal @pp[0], @w.place( "AA" )
629
- assert_equal :AA, @w.pl( @pp[0] )
630
- assert_equal @tt[0], @w.transition( "AA_BB_assembly" )
631
- assert_equal :AA_appearing, @w.tr( @tt[1] )
632
- assert_equal @pp, @w.places
633
- assert_equal @tt, @w.transitions
634
- assert_equal 1, @w.nets.size
635
- assert_equal 1, @w.simulations.size
636
- assert_equal 0, @w.cc.size
637
- assert_equal 3, @w.imc.size
638
- assert [0.1, 10, 50].each { |e| @w.ssc.include? e }
639
- assert_equal @sim, @w.simulation
640
- assert_equal [:Base], @w.clamp_collections.keys
641
- assert_equal [:Base], @w.initial_marking_collections.keys
642
- assert_equal [:Base], @w.simulation_settings_collections.keys
643
- assert_equal [:AA, :BB, :CC], @w.pp
644
- assert_equal [:AA_BB_assembly, :AA_appearing], @w.tt
645
- assert_equal [:Top], @w.nn
646
- end
647
-
648
- it "should simulate" do
649
- assert_equal 1, @w.simulations.size
650
- assert_kind_of( ::YPetri::Simulation, @w.simulation )
651
- assert_equal 2, @w.simulation.SR_transitions.size
652
- @tt[0].domain.must_equal [ @pp[0], @pp[1] ]
653
- @tt[1].domain.must_equal []
654
- assert_equal [0.2, 0.1], @w.simulation.φ.column_to_a
655
- @w.simulation.step!
656
- @w.simulation.run!
657
- rec_string = @w.simulation.recording_csv_string
658
- expected_recording_string =
659
- "0.0,1.0,2.0,3.0\n" +
660
- "10.0,0.86102,0.86102,4.13898\n" +
661
- "20.0,1.29984,0.29984,4.70016\n"
662
- assert rec_string.start_with?( expected_recording_string )
663
- end
664
- end
665
-
666
- # **************************************************************************
667
- # Test of Manipulator class.
668
- # **************************************************************************
669
- #
670
- describe ::YPetri::Manipulator do
671
- before do
672
- # skip "for now"
673
- @m = ::YPetri::Manipulator.new
674
- end
675
-
676
- it "has net basic points" do
677
- # --- net point related assets ---
678
- @m.net_point_reset
679
- @m.net_point_set @m.workspace.net( :Top )
680
- @m.net.must_equal @m.workspace.Net::Top
681
- # --- simulation point related assets ---
682
- @m.simulation_point.reset
683
- @m.simulation.must_equal nil
684
- @m.simulation_point.key.must_equal nil
685
- # --- cc point related assets ---
686
- @m.cc_point.reset
687
- @m.cc_point.set :Base
688
- @m.cc.must_equal @m.workspace.clamp_collection
689
- @m.cc.wont_equal :Base
690
- @m.cc_point.key.must_equal :Base
691
- # --- imc point related assets ---
692
- @m.imc_point.reset
693
- @m.imc_point.set :Base
694
- @m.imc.must_equal @m.workspace.initial_marking_collection
695
- @m.imc.wont_equal :Base
696
- @m.imc_point.key.must_equal :Base
697
- # --- ssc point related assets ---
698
- @m.ssc_point.reset
699
- @m.ssc_point.set :Base
700
- @m.ssc.must_equal @m.workspace.simulation_settings_collection
701
- @m.ssc.wont_equal :Base
702
- @m.ssc_point.key.must_equal :Base
703
- end
704
-
705
- it "has basic selections" do
706
- @m.net_selection.clear
707
- @m.simulation_selection.clear
708
- @m.cc_selection.clear
709
- @m.imc_selection.clear
710
- @m.ssc_selection.clear
711
- @m.net_selection.get.must_equal []
712
- @m.simulation_selection.get.must_equal []
713
- @m.ssc_selection.get.must_equal []
714
- @m.cc_selection.get.must_equal []
715
- @m.imc_selection.get.must_equal []
716
- end
717
-
718
- it "presents some methods from workspace" do
719
- [ @m.places, @m.transitions, @m.nets, @m.simulations ].map( &:size )
720
- .must_equal [ 0, 0, 1, 0 ]
721
- [ @m.clamp_collections,
722
- @m.initial_marking_collections,
723
- @m.simulation_settings_collections ].map( &:size ).must_equal [ 1, 1, 1 ]
724
- [ @m.clamp_collections,
725
- @m.initial_marking_collections,
726
- @m.simulation_settings_collections ]
727
- .map( &:keys ).must_equal [[:Base]] * 3
728
- @m.pp.must_equal []
729
- @m.tt.must_equal []
730
- @m.nn.must_equal [ :Top ] # ie. :Top net spanning whole workspace
731
- end
732
-
733
- describe "slightly more complicated case" do
734
- before do
735
- @p = @m.Place ɴ: "P", default_marking: 1
736
- @q = @m.Place ɴ: "Q", default_marking: 1
737
- @decay_t = @m.Transition ɴ: "Tp", s: { P: -1 }, rate: 0.1
738
- @constant_flux_t = @m.Transition ɴ: "Tq", s: { Q: 1 }, rate: -> { 0.02 }
739
- @m.initial_marking @p => 1.2
740
- @m.initial_marking @q => 2
741
- @m.set_step 0.01
742
- @m.set_sampling 1
743
- @m.set_time 30
744
- end
745
-
746
- it "works" do
747
- @m.run!
748
- @m.simulation.places.must_equal [ @p, @q ]
749
- @m.simulation.transitions.must_equal [ @decay_t, @constant_flux_t ]
750
- @m.simulation.SR_tt.must_equal [ :Tp, :Tq ]
751
- @m.simulation.sparse_stoichiometry_vector( :Tp )
752
- .must_equal Matrix.column_vector( [-1, 0] )
753
- @m.simulation.stoichiometry_matrix_for( @m.transitions ).column_size
754
- .must_equal 2
755
- @m.simulation.stoichiometry_matrix_for( @m.transitions ).row_size
756
- .must_equal 2
757
- @m.simulation.flux_vector.row_size.must_equal 2
758
- # @m.plot_recording
759
- end
760
- end
761
- end
762
-
763
-
764
- # **************************************************************************
765
- # Test of YPetri class itself.
766
- # **************************************************************************
767
- #
768
- describe ::YPetri do
769
- before do
770
- # skip "to speed up testing"
771
- end
772
-
10
+ # Unit tests for the YPetri module.
11
+ #
12
+ describe YPetri do
773
13
  it "should have basic classes" do
774
- [ :Place, :Transition, :Net,
775
- :Simulation, :TimedSimulation,
776
- :Workspace, :Manipulator ].each { |ß|
777
- assert_kind_of Module, ::YPetri.const_get( ß ) }
14
+ assert [ :Place, :Transition, :Net,
15
+ :Simulation, :TimedSimulation,
16
+ :Workspace, :Manipulator
17
+ ].all? { |ß| YPetri.const_get( ß ).is_a? Module }
778
18
  end
779
19
  end
780
20
 
781
-
782
- # **************************************************************************
783
- # ACCEPTANCE TESTS
784
- # **************************************************************************
785
-
786
- # describe "Token game" do
787
- # before do
788
- # @m = YPetri::Manipulator.new
789
- # @m.Place name: "A"
790
- # @m.Place name: "B"
791
- # @m.Place name: "C", marking: 7.77
792
- # @m.Transition name: "A2B", stoichiometry: { A: -1, B: 1 }
793
- # @m.Transition name: "C_decay", stoichiometry: { C: -1 }, rate: 0.05
794
- # end
795
-
796
- # it "should work" do
797
- # @m.place( :A ).marking = 2
798
- # @m.place( :B ).marking = 5
799
- # @m.places.map( &:name ).must_equal [:A, :B, :C]
800
- # @m.places.map( &:marking ).must_equal [2, 5, 7.77]
801
- # @m.transition( :A2B ).arcs.must_equal [ @m.place( :A ), @m.place( :B ) ]
802
- # @m.transition( :A2B ).fire!
803
- # @m.places.map( &:marking ).must_equal [1, 6, 7.77]
804
- # @m.transition( :A2B ).fire!
805
- # @m.place( :A ).marking.must_equal 0
806
- # @m.place( :B ).marking.must_equal 7
807
- # 2.times do @m.transition( :C_decay ).fire! 1 end
808
- # @m.transition( :C_decay ).fire! 0.1
809
- # 200.times do @m.transition( :C_decay ).fire! 1 end
810
- # assert_in_delta @m.place( :C ).marking, 0.00024, 0.00001
811
- # end
812
- # end
813
-
814
- # describe "Basic use of TimedSimulation" do
815
- # before do
816
- # @m = YPetri::Manipulator.new
817
- # @m.Place( name: "A", default_marking: 0.5 )
818
- # @m.Place( name: "B", default_marking: 0.5 )
819
- # @m.Transition( name: "A_pump",
820
- # stoichiometry: { A: -1 },
821
- # rate: proc { 0.005 } )
822
- # @m.Transition( name: "B_decay",
823
- # stoichiometry: { B: -1 },
824
- # rate: 0.05 )
825
- # end
826
-
827
- # it "should work" do
828
- # @m.net.must_be_kind_of ::YPetri::Net
829
- # @m.run!
830
- # @m.simulation.must_be_kind_of ::YPetri::TimedSimulation
831
- # @m.plot_state
832
- # sleep 3
833
- # end
834
- # end
835
-
836
- # describe "Graphviz visualization" do
837
- # before do
838
- # @m = YPetri::Manipulator.new
839
- # @m.Place name: :A, m!: 1
840
- # @m.Place name: :B, m!: 1.5
841
- # @m.Place name: :C, m!: 2
842
- # @m.Place name: :D, m!: 2.5
843
- # @m.Transition name: :A_pump, s: { A: -1 }, rate: proc { 0.005 }
844
- # @m.Transition name: :B_decay, s: { B: -1 }, rate: 0.05
845
- # @m.Transition name: :C_guard, assignment: true, codomain: :C, action: λ { 2 }
846
- # end
847
-
848
- # it "should work" do
849
- # @m.net.visualize
850
- # end
851
- # end
852
-
853
- # describe "Simplified dTTP pathway used for demo with Dr. Chang" do
854
- # before do
855
- # @m = YPetri::Manipulator.new
856
- # Cytoplasm_volume_in_litres = 5.0e-11
857
- # NA = 6.022e23
858
- # Pieces_per_micromolar = NA / 1_000_000 * Cytoplasm_volume_in_litres
859
- # @m.set_step 60
860
- # @m.set_sampling 300
861
- # @m.set_target_time 60 * 60 * 2
862
- # AMP = @m.Place( name: :AMP, m!: 8695.0 )
863
- # ADP = @m.Place( name: :ADP, m!: 6521.0 )
864
- # ATP = @m.Place( name: :ATP, m!: 3152.0 )
865
- # Deoxycytidine = @m.Place( name: :Deoxycytidine, m!: 0.5 )
866
- # DeoxyCTP = @m.Place( name: :DeoxyCTP, m!: 1.0 )
867
- # DeoxyGMP = @m.Place( name: :DeoxyGMP, m!: 1.0 )
868
- # UMP_UDP_pool = @m.Place( name: :UMP_UDP_pool, m!: 2737.0 )
869
- # DeoxyUMP_DeoxyUDP_pool = @m.Place( name: :DeoxyUMP_DeoxyUDP_pool, m!: 0.0 )
870
- # DeoxyTMP = @m.Place( name: :DeoxyTMP, m!: 3.3 )
871
- # DeoxyTDP_DeoxyTTP_pool = @m.Place( name: :DeoxyTDP_DeoxyTTP_pool, m!: 5.0 )
872
- # Thymidine = @m.Place( name: :Thymidine, m!: 0.5 )
873
- # TK1 = @m.Place( name: :TK1, m!: 100_000 )
874
- # TYMS = @m.Place( name: :TYMS, m!: 100_000 )
875
- # RNR = @m.Place( name: :RNR, m!: 100_000 )
876
- # TMPK = @m.Place( name: :TMPK, m!: 100_000 )
877
- # TK1_kDa = 24.8
878
- # TYMS_kDa = 66.0
879
- # RNR_kDa = 140.0
880
- # TMPK_kDa = 50.0
881
- # TK1_a = 5.40
882
- # TYMS_a = 3.80
883
- # RNR_a = 1.00
884
- # TMPK_a = 0.83
885
- # @m.clamp AMP: 8695.0, ADP: 6521.0, ATP: 3152.0
886
- # @m.clamp Deoxycytidine: 0.5, DeoxyCTP: 1.0, DeoxyGMP: 1.0
887
- # @m.clamp Thymidine: 0.5
888
- # @m.clamp UMP_UDP_pool: 2737.0
889
- # # Functions
890
- # Vmax_per_minute_per_enzyme_molecule =
891
- # lambda { |enzyme_specific_activity_in_micromol_per_minute_per_mg,
892
- # enzyme_molecular_mass_in_kDa|
893
- # enzyme_specific_activity_in_micromol_per_minute_per_mg *
894
- # enzyme_molecular_mass_in_kDa }
895
- # Vmax_per_minute =
896
- # lambda { |specific_activity, kDa, enzyme_molecules_per_cell|
897
- # Vmax_per_minute_per_enzyme_molecule.( specific_activity, kDa ) *
898
- # enzyme_molecules_per_cell }
899
- # Vmax_per_second =
900
- # lambda { |specific_activity, kDa, enzyme_molecules_per_cell|
901
- # Vmax_per_minute.( specific_activity,
902
- # kDa,
903
- # enzyme_molecules_per_cell ) / 60 }
904
- # Km_reduced =
905
- # lambda { |km, ki_hash={}|
906
- # ki_hash.map { |concentration, ci_Ki|
907
- # concentration / ci_Ki
908
- # }.reduce( 1, :+ ) * km }
909
- # Occupancy =
910
- # lambda { |concentration, reactant_Km, compet_inh_w_Ki_hash={}|
911
- # concentration / ( concentration +
912
- # Km_reduced.( reactant_Km,
913
- # compet_inh_w_Ki_hash ) ) }
914
- # MM_with_inh_micromolars_per_second =
915
- # lambda { |reactant_concentration,
916
- # enzyme_specific_activity,
917
- # enzyme_mass_in_kDa,
918
- # enzyme_molecules_per_cell,
919
- # reactant_Km,
920
- # competitive_inh_w_Ki_hash={}|
921
- # Vmax_per_second.( enzyme_specific_activity,
922
- # enzyme_mass_in_kDa,
923
- # enzyme_molecules_per_cell ) *
924
- # Occupancy.( reactant_concentration,
925
- # reactant_Km,
926
- # competitive_inh_w_Ki_hash ) }
927
- # MMi = MM_with_inh_micromolars_per_second
928
- # TK1_Thymidine_Km = 5.0
929
- # TYMS_DeoxyUMP_Km = 2.0
930
- # RNR_UDP_Km = 1.0
931
- # DNA_creation_speed = 3_000_000_000 / ( 12 * 3600 )
932
- # TMPK_DeoxyTMP_Km = 12.0
933
-
934
- # # transitions
935
- # @m.Transition name: :TK1_Thymidine_DeoxyTMP,
936
- # domain: [ Thymidine, TK1, DeoxyTDP_DeoxyTTP_pool, DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
937
- # stoichiometry: { Thymidine: -1, DeoxyTMP: 1 },
938
- # rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
939
- # ci1 = pool1 * master3 / ( master2 + master3 )
940
- # MMi.( rc, TK1_a, TK1_kDa, e, TK1_Thymidine_Km,
941
- # ci1 => 13.5, ci2 => 0.8, ci3 => 40.0 ) }
942
- # @m.Transition name: :TYMS_DeoxyUMP_DeoxyTMP,
943
- # domain: [ DeoxyUMP_DeoxyUDP_pool, TYMS, AMP, ADP, ATP ],
944
- # stoichiometry: { DeoxyUMP_DeoxyUDP_pool: -1, DeoxyTMP: 1 },
945
- # rate: proc { |pool, e, master1, master2, master3|
946
- # rc = pool * master2 / ( master1 + master2 )
947
- # MMi.( rc, TYMS_a, TYMS_kDa, e, TYMS_DeoxyUMP_Km ) }
948
- # @m.Transition name: :RNR_UDP_DeoxyUDP,
949
- # domain: [ UMP_UDP_pool, RNR, DeoxyUMP_DeoxyUDP_pool, AMP, ADP, ATP ],
950
- # stoichiometry: { UMP_UDP_pool: -1, DeoxyUMP_DeoxyUDP_pool: 1 },
951
- # rate: proc { |pool, e, master1, master2, master3|
952
- # rc = pool * master2 / ( master1 + master2 )
953
- # MMi.( rc, RNR_a, RNR_kDa, e, RNR_UDP_Km ) }
954
- # @m.Transition name: :DNA_polymerase_consumption_of_DeoxyTTP,
955
- # stoichiometry: { DeoxyTDP_DeoxyTTP_pool: -1 },
956
- # rate: proc { DNA_creation_speed / 4 }
957
- # @m.Transition name: :TMPK_DeoxyTMP_DeoxyTDP,
958
- # domain: [ DeoxyTMP, TMPK, ADP,
959
- # DeoxyTDP_DeoxyTTP_pool,
960
- # DeoxyGMP, AMP, ATP ],
961
- # stoichiometry: { DeoxyTMP: -1, TMPK: 0, DeoxyTDP_DeoxyTTP_pool: 1 },
962
- # rate: proc { |rc, e, ci1, pool, ci4, master1, master3|
963
- # master2 = ci1
964
- # ci2 = pool * master2 / ( master2 + master3 )
965
- # ci3 = pool * master3 / ( master2 + master3 )
966
- # MMi.( rc, TMPK_a, TMPK_kDa, e, TMPK_DeoxyTMP_Km,
967
- # ci1 => 250.0, ci2 => 30.0, ci3 => 750, ci4 => 117 ) }
968
- # end
969
-
970
- # it "should work" do
971
- # @m.run!
972
- # @m.plot_state
973
- # sleep 3
974
- # end
975
- # end
976
-
977
- # describe "Use of TimedSimulation with units" do
978
- # before do
979
- # require 'sy'
980
-
981
- # @m = YPetri::Manipulator.new
982
-
983
- # # === General assumptions
984
- # Cytoplasm_volume = 5.0e-11.l
985
- # Pieces_per_concentration = SY::Nᴀ * Cytoplasm_volume
986
-
987
- # # === Simulation settings
988
- # @m.set_step 60.s
989
- # @m.set_target_time 10.min
990
- # @m.set_sampling 120.s
991
-
992
- # # === Places
993
- # AMP = @m.Place m!: 8695.0.µM
994
- # ADP = @m.Place m!: 6521.0.µM
995
- # ATP = @m.Place m!: 3152.0.µM
996
- # Deoxycytidine = @m.Place m!: 0.5.µM
997
- # DeoxyCTP = @m.Place m!: 1.0.µM
998
- # DeoxyGMP = @m.Place m!: 1.0.µM
999
- # U12P = @m.Place m!: 2737.0.µM
1000
- # DeoxyU12P = @m.Place m!: 0.0.µM
1001
- # DeoxyTMP = @m.Place m!: 3.3.µM
1002
- # DeoxyT23P = @m.Place m!: 5.0.µM
1003
- # Thymidine = @m.Place m!: 0.5.µM
1004
- # TK1 = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
1005
- # TYMS = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
1006
- # RNR = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
1007
- # TMPK = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
1008
-
1009
- # # === Enzyme molecular masses
1010
- # TK1_m = 24.8.kDa
1011
- # TYMS_m = 66.0.kDa
1012
- # RNR_m = 140.0.kDa
1013
- # TMPK_m = 50.0.kDa
1014
-
1015
- # # === Specific activities of the enzymes
1016
- # TK1_a = 5.40.µmol.min⁻¹.mg⁻¹
1017
- # TYMS_a = 3.80.µmol.min⁻¹.mg⁻¹
1018
- # RNR_a = 1.00.µmol.min⁻¹.mg⁻¹
1019
- # TMPK_a = 0.83.µmol.min⁻¹.mg⁻¹
1020
-
1021
- # # === Clamps
1022
- # @m.clamp AMP: 8695.0.µM, ADP: 6521.0.µM, ATP: 3152.0.µM
1023
- # @m.clamp Deoxycytidine: 0.5.µM, DeoxyCTP: 1.0.µM, DeoxyGMP: 1.0.µM
1024
- # @m.clamp Thymidine: 0.5.µM
1025
- # @m.clamp U12P: 2737.0.µM
1026
-
1027
- # # === Function closures
1028
-
1029
- # # Vmax of an enzyme.
1030
- # #
1031
- # Vmax_enzyme = lambda { |specific_activity, mass, enzyme_conc|
1032
- # specific_activity * mass * enzyme_conc.( SY::Molecularity )
1033
- # }
1034
-
1035
- # # Michaelis constant reduced for competitive inhibitors.
1036
- # #
1037
- # Km_reduced = lambda { |km, ki_hash={}|
1038
- # ki_hash.map { |concentration, ci_Ki|
1039
- # concentration / ci_Ki }
1040
- # .reduce( 1, :+ ) * km
1041
- # }
1042
-
1043
- # # Occupancy of enzyme active sites at given concentration of reactants
1044
- # # and competitive inhibitors.
1045
- # #
1046
- # Occupancy = lambda { |ʀ_conc, ʀ_Km, cɪ_Kɪ={}|
1047
- # ʀ_conc / ( ʀ_conc + Km_reduced.( ʀ_Km, cɪ_Kɪ ) )
1048
- # }
1049
-
1050
- # # Michaelis and Menten equation with competitive inhibitors.
1051
- # #
1052
- # MMi = MM_equation_with_inhibitors = lambda {
1053
- # |ʀ_conc, ᴇ_specific_activity, ᴇ_mass, ᴇ_conc, ʀ_Km, cɪ_Kɪ={}|
1054
- # Vmax_enzyme.( ᴇ_specific_activity, ᴇ_mass, ᴇ_conc ) *
1055
- # Occupancy.( ʀ_conc, ʀ_Km, cɪ_Kɪ )
1056
- # }
1057
-
1058
- # # === Michaelis constants of the enzymes involved.
1059
-
1060
- # TK1_Thymidine_Km = 5.0.µM
1061
- # TYMS_DeoxyUMP_Km = 2.0.µM
1062
- # RNR_UDP_Km = 1.0.µM
1063
- # TMPK_DeoxyTMP_Km = 12.0.µM
1064
-
1065
- # # === DNA synthesis speed.
1066
-
1067
- # DNA_creation_speed = 3_000_000_000.unit.( SY::MoleAmount ) / 12.h / Cytoplasm_volume
1068
-
1069
- # # === Transitions
1070
-
1071
- # # Synthesis of TMP by TK1.
1072
- # #
1073
- # TK1_Thymidine_DeoxyTMP = @m.Transition s: { Thymidine: -1, DeoxyTMP: 1 },
1074
- # domain: [ Thymidine, TK1, DeoxyT23P, DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
1075
- # rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
1076
- # ci1 = pool1 * master3 / ( master2 + master3 )
1077
- # MMi.( rc, TK1_a, TK1_m, e, TK1_Thymidine_Km,
1078
- # ci1 => 13.5.µM, ci2 => 0.8.µM, ci3 => 40.0.µM )
1079
- # }
1080
-
1081
- # # Methylation of DeoxyUMP into TMP by TYMS.
1082
- # TYMS_DeoxyUMP_DeoxyTMP = @m.Transition s: { DeoxyU12P: -1, DeoxyTMP: 1 },
1083
- # domain: [ DeoxyU12P, TYMS, AMP, ADP, ATP ],
1084
- # rate: proc { |pool, e, master1, master2, master3|
1085
- # rc = pool * master2 / ( master1 + master2 )
1086
- # MMi.( rc, TYMS_a, TYMS_m, e, TYMS_DeoxyUMP_Km )
1087
- # }
1088
-
1089
- # # Reduction of UDP into DeoxyUDP by RNR.
1090
- # RNR_UDP_DeoxyUDP = @m.Transition s: { U12P: -1, DeoxyU12P: 1 },
1091
- # domain: [ U12P, RNR, DeoxyU12P, AMP, ADP, ATP ],
1092
- # rate: proc { |pool, e, master1, master2, master3|
1093
- # rc = pool * master2 / ( master1 + master2 )
1094
- # MMi.( rc, RNR_a, RNR_m, e, RNR_UDP_Km )
1095
- # }
1096
-
1097
- # # Consumption of TTP by DNA synthesis.
1098
- # DeoxyTTP_to_DNA = @m.Transition s: { DeoxyT23P: -1 },
1099
- # rate: proc { DNA_creation_speed / 4 }
1100
-
1101
- # # Phosphorylation of TMP into TDP-TTP pool.
1102
- # TMPK_DeoxyTMP_DeoxyTDP = @m.Transition s: { DeoxyTMP: -1, TMPK: 0, DeoxyT23P: 1 },
1103
- # domain: [ DeoxyTMP, TMPK, ADP, DeoxyT23P, DeoxyGMP, AMP, ATP ],
1104
- # rate: proc { |rc, e, ci1, pool, ci4, master1, master3|
1105
- # master2 = ci1
1106
- # ci2 = pool * master2 / ( master2 + master3 )
1107
- # ci3 = pool * master3 / ( master2 + master3 )
1108
- # MMi.( rc, TMPK_a, TMPK_m, e, TMPK_DeoxyTMP_Km,
1109
- # ci1 => 250.0.µM, ci2 => 30.0.µM, ci3 => 750.µM, ci4 => 117.µM )
1110
- # }
1111
- # end
1112
-
1113
- # it "should work" do
1114
- # # === Simulation execution
1115
- # @m.run!
1116
- # # === Plotting of the results
1117
- # @m.plot_state
1118
- # sleep 20
1119
- # end
1120
- # end
21
+ # Run all other unit tests.
22
+ #
23
+ require_relative 'place_test'
24
+ require_relative 'transition_test'
25
+ require_relative 'net_test'
26
+ require_relative 'simulation_test'
27
+ require_relative 'timed_simulation_test'
28
+ require_relative 'workspace_test'
29
+ require_relative 'manipulator_test'