y_petri 2.0.7 → 2.0.14.p1

Sign up to get free protection for your applications and to get access to all the features.
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'