y_petri 2.0.2 → 2.0.3
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/.gitignore +1 -0
- data/lib/y_petri/manipulator/hash_key_pointer.rb +38 -0
- data/lib/y_petri/manipulator/petri_net_related_methods.rb +55 -0
- data/lib/y_petri/manipulator/selection.rb +11 -0
- data/lib/y_petri/manipulator/simulation_related_methods.rb +361 -0
- data/lib/y_petri/manipulator.rb +9 -587
- data/lib/y_petri/net.rb +65 -106
- data/lib/y_petri/simulation.rb +28 -9
- data/lib/y_petri/timed_simulation.rb +10 -3
- data/lib/y_petri/transition.rb +13 -28
- data/lib/y_petri/version.rb +2 -1
- data/lib/y_petri/workspace/petri_net_related_methods.rb +88 -0
- data/lib/y_petri/workspace/{instance_methods.rb → simulation_related_methods.rb} +7 -80
- data/lib/y_petri/workspace.rb +8 -8
- data/lib/y_petri.rb +29 -58
- data/test/y_petri_test.rb +38 -43
- metadata +9 -6
- data/test/y_petri_graph.png +0 -0
data/lib/y_petri/manipulator.rb
CHANGED
@@ -3,596 +3,18 @@
|
|
3
3
|
# Public command interface of YPetri.
|
4
4
|
#
|
5
5
|
class YPetri::Manipulator
|
6
|
-
|
7
|
-
# Current workspace.
|
8
|
-
#
|
9
|
-
def workspace;
|
10
|
-
# puts "Manipulator is #{self}, obj. id #{object_id}."
|
11
|
-
@workspace
|
12
|
-
end
|
6
|
+
attr_reader :workspace
|
13
7
|
|
14
8
|
def initialize
|
15
|
-
|
16
|
-
|
17
|
-
net_point_reset
|
18
|
-
net_selection_clear
|
19
|
-
simulation_point_reset
|
20
|
-
simulation_selection_clear
|
21
|
-
ssc_point_reset
|
22
|
-
ssc_selection_clear
|
23
|
-
cc_point_reset
|
24
|
-
cc_selection_clear
|
25
|
-
imc_point_reset
|
26
|
-
imc_selection_clear
|
27
|
-
end
|
28
|
-
|
29
|
-
delegate :place, :transition, :p, :t,
|
30
|
-
:places, :transitions, :nets, :simulations,
|
31
|
-
:pp, :tt, :nn,
|
32
|
-
:clamp_collections,
|
33
|
-
:initial_marking_collections,
|
34
|
-
:simulation_settings_collections,
|
35
|
-
:clamp_cc, :initial_marking_cc, :simulation_settings_cc,
|
36
|
-
to: :workspace
|
37
|
-
|
38
|
-
# Place constructor: Creates a new place in the current workspace.
|
39
|
-
#
|
40
|
-
def Place *args, &block
|
41
|
-
workspace.Place.new *args, &block
|
42
|
-
end
|
43
|
-
|
44
|
-
# Transiton constructor: Creates a new transition in the current workspace.
|
45
|
-
#
|
46
|
-
def Transition *args, &block
|
47
|
-
workspace.Transition.new *args, &block
|
48
|
-
end
|
49
|
-
|
50
|
-
# Net constructor: Creates a new Net instance in the current workspace.
|
51
|
-
#
|
52
|
-
def Net *args, &block
|
53
|
-
workspace.Net.new *args, &block
|
54
|
-
end
|
55
|
-
|
56
|
-
# ==== Net point
|
57
|
-
|
58
|
-
# Sets net point to workspace.Net::Top
|
59
|
-
#
|
60
|
-
def net_point_reset
|
61
|
-
net_point_to( workspace.Net::Top )
|
62
|
-
end
|
63
|
-
|
64
|
-
# Sets net point to the one identified in the argument (Net instance or
|
65
|
-
# its name).
|
66
|
-
#
|
67
|
-
def net_point_to which_net
|
68
|
-
@net_point = workspace.net which_net
|
69
|
-
end
|
70
|
-
alias :net→ :net_point_to
|
71
|
-
|
72
|
-
# Returns the net identified by the argument, or the net at the point, if
|
73
|
-
# none given.
|
74
|
-
#
|
75
|
-
def net which=nil
|
76
|
-
which.nil? ? @net_point : workspace.net( which )
|
77
|
-
end
|
78
|
-
|
79
|
-
# Returns the name of the net identified by the argument, or the net at the
|
80
|
-
# point (if no argument is given).
|
81
|
-
#
|
82
|
-
def n which=nil
|
83
|
-
net( which ).name
|
84
|
-
end
|
85
|
-
|
86
|
-
# ==== Simulation point
|
87
|
-
|
88
|
-
# Sets simulation point to the first key of the workspace's collection of
|
89
|
-
# simulations (or nil if there are no simulations yet).
|
90
|
-
#
|
91
|
-
def simulation_point_reset
|
92
|
-
@simulation_point =
|
93
|
-
workspace.simulations.empty? ? nil :
|
94
|
-
simulation_point_to( workspace.simulations.first[0] )
|
95
|
-
end
|
96
|
-
|
97
|
-
# Sets simulation point to the simulation identified by the argument.
|
98
|
-
# A simulation can be identified either by its name (if named), or by
|
99
|
-
# its parameters and settings (simulated net, clamp collection, initial
|
100
|
-
# marking collection, and simulation settings collection).
|
101
|
-
#
|
102
|
-
# If a single ordered (non-hash) argument is supplied, it is assumed to be
|
103
|
-
# a simulation name. If a hash is supplied, it is expected that it will
|
104
|
-
# contain four pairs with keys :net, :cc, :imc, :ssc, identifying the
|
105
|
-
# simulation by its parameters and settings. Alternatively, use of hash
|
106
|
-
# can be forgone - if exactly 4 ordered arguments are supplied, it is
|
107
|
-
# assumed that they specified the parameter settings in the order set forth
|
108
|
-
# earlier.
|
109
|
-
#
|
110
|
-
def simulation_point_to *args
|
111
|
-
key = normalize_simulation_identifier *args
|
112
|
-
@simulation_point = if key.nil? then nil
|
113
|
-
elsif workspace.simulations.has_key? key then key
|
114
|
-
else raise "No such simulation" end
|
115
|
-
end
|
116
|
-
alias :sim→ :simulation_point_to
|
117
|
-
|
118
|
-
# Returns the simulation identified by the argument, or one indicated by the
|
119
|
-
# simulation point (if no argument was given). The simulation is identified
|
120
|
-
# by the arguments in the same way as for #simulation_point_to method.
|
121
|
-
#
|
122
|
-
def simulation *args
|
123
|
-
workspace.simulation( normalize_simulation_identifier *args )
|
124
|
-
end
|
125
|
-
|
126
|
-
# TEMPORARY KLUGE - FIXME
|
127
|
-
#
|
128
|
-
def simulation; @workspace.simulations.values[-1] end
|
129
|
-
|
130
|
-
# Returns the index (position) of the simulation point.
|
131
|
-
#
|
132
|
-
def simulation_point_position
|
133
|
-
# FIXME: Change @simulations from being a has of { key => simulation } pairs
|
134
|
-
# to be the hash of { simulation => names } pairs, in which simulations are
|
135
|
-
# looked up either by rassoc or by sniffing their parameters and settings.
|
136
|
-
@simulation_point
|
137
|
-
end
|
138
|
-
|
139
|
-
# ==== cc point (cc = clamp collection)
|
140
|
-
|
141
|
-
# Clamp collections are stored in workplace in a hash. The cc point
|
142
|
-
# points to its keys.
|
143
|
-
|
144
|
-
# Resets cc point to :base.
|
145
|
-
#
|
146
|
-
def cc_point_reset
|
147
|
-
@cc_point = :Base
|
148
|
-
end
|
149
|
-
|
150
|
-
# Sets the cc point to the specified cc.
|
151
|
-
#
|
152
|
-
def cc_point_to arg
|
153
|
-
if workspace.clamp_collections.has_key? arg
|
154
|
-
@cc_point = arg
|
155
|
-
else
|
156
|
-
raise "No clamp collection #{arg} in this workspace"
|
157
|
-
end
|
158
|
-
end
|
159
|
-
alias :cc→ :cc_point_to
|
160
|
-
|
161
|
-
# Returns clamp collection corresp. to cc point (if no argument), or to
|
162
|
-
# the argument (if this was given).
|
163
|
-
#
|
164
|
-
def clamp_collection collection_name=nil
|
165
|
-
cɴ = collection_name.nil? ? @cc_point : collection_name
|
166
|
-
workspace.clamp_collections[ cɴ ] or
|
167
|
-
raise AE, "No clamp collection #{cɴ} in this workspace."
|
168
|
-
end
|
169
|
-
alias :cc :clamp_collection
|
170
|
-
|
171
|
-
# Returns the cc point position (cc hash key).
|
172
|
-
#
|
173
|
-
def cc_point_position; @cc_point end
|
174
|
-
|
175
|
-
# ==== imc point ( imc = initial marking collection )
|
176
|
-
|
177
|
-
# Initial marking collections are stored in a workplace in a hash.
|
178
|
-
# The imc point points to its keys.
|
179
|
-
|
180
|
-
# Resets imc point to :base.
|
181
|
-
#
|
182
|
-
def imc_point_reset; @imc_point = :Base end
|
183
|
-
|
184
|
-
# Sets the imc point to the specified imc.
|
185
|
-
#
|
186
|
-
def imc_point_to arg
|
187
|
-
if workspace.initial_marking_collections.has_key? arg
|
188
|
-
@imc_point = arg
|
189
|
-
else
|
190
|
-
raise "No initial marking collection #{arg} in this workspace."
|
191
|
-
end
|
192
|
-
end
|
193
|
-
alias :imc→ :imc_point_to
|
194
|
-
|
195
|
-
# Returns initial marking collection corresp. to imc point (if no
|
196
|
-
# argument), or to the argument (if this was given).
|
197
|
-
#
|
198
|
-
def initial_marking_collection collection_name=nil
|
199
|
-
cɴ = collection_name.nil? ? @imc_point : collection_name
|
200
|
-
workspace.initial_marking_collections[ cɴ ] or
|
201
|
-
raise AE, "No initial marking collection #{cɴ} in this workspace."
|
202
|
-
end
|
203
|
-
alias :imc :initial_marking_collection
|
204
|
-
|
205
|
-
# Returns the ssc point position (ssc hash key).
|
206
|
-
#
|
207
|
-
def imc_point_position; @imc_point end
|
208
|
-
|
209
|
-
# ==== ssc point (ssc = simulation settings collection)
|
210
|
-
|
211
|
-
# Simulation settings collections are stored in workplace in a hash.
|
212
|
-
# The ssc point of manipulator points to its keys.
|
213
|
-
|
214
|
-
# Resets ssc point to :base.
|
215
|
-
#
|
216
|
-
def ssc_point_reset; @ssc_point = :Base end
|
217
|
-
|
218
|
-
# Sets the ssc point to the specified ssc.
|
219
|
-
#
|
220
|
-
def ssc_point_to arg
|
221
|
-
if workspace.simulation_settings_collections.has_key? arg
|
222
|
-
@ssc_point = arg
|
223
|
-
else raise "No such simulation settings collection: #{arg}" end
|
224
|
-
end
|
225
|
-
alias :ssc→ :ssc_point_to
|
226
|
-
|
227
|
-
# Returns the ssc identified by the argument, or that at ssc point (if no
|
228
|
-
# argument is given).
|
229
|
-
#
|
230
|
-
def simulation_settings_collection collection_name=nil
|
231
|
-
cɴ = collection_name.nil? ? @ssc_point : collection_name
|
232
|
-
# puts "Target workspace is #{workspace}, obj. id #{workspace.object_id}"
|
233
|
-
workspace.simulation_settings_collections[ cɴ ] or
|
234
|
-
raise AE, "No simulations settings collection #{cɴ} in this workspace."
|
235
|
-
end
|
236
|
-
alias :ssc :simulation_settings_collection
|
237
|
-
|
238
|
-
# Returns the ssc point position (ssc hash key).
|
239
|
-
#
|
240
|
-
def ssc_point_position; @ssc_point end
|
241
|
-
|
242
|
-
|
243
|
-
# ==== Selection mechanism for net, simulation, cc, imc and ssc
|
244
|
-
# TODO
|
245
|
-
|
246
|
-
# Net selection.
|
247
|
-
#
|
248
|
-
attr_reader :net_selection
|
249
|
-
|
250
|
-
# Simulation selection.
|
251
|
-
#
|
252
|
-
attr_reader :simulation_selection
|
253
|
-
|
254
|
-
# Simulation settings collection selection.
|
255
|
-
#
|
256
|
-
attr_reader :ssc_selection
|
257
|
-
|
258
|
-
# Clamp collection selection.
|
259
|
-
#
|
260
|
-
attr_reader :cc_selection
|
261
|
-
|
262
|
-
# Initial marking collection selection.
|
263
|
-
#
|
264
|
-
attr_reader :imc_selection
|
265
|
-
|
266
|
-
# ==== Net selection
|
267
|
-
|
268
|
-
def net_selection_clear
|
269
|
-
@net_selection ||= []
|
270
|
-
@net_selection.clear
|
271
|
-
end
|
272
|
-
|
273
|
-
def net_select! *aa; net_selection_clear; net_select *aa end
|
274
|
-
|
275
|
-
def net_select *aa
|
276
|
-
case aa.size
|
277
|
-
when 0 then ( @net_selection << net ).uniq!
|
278
|
-
when 1 then ( @net_selection << aa[0] ).uniq!
|
279
|
-
else aa.each { |a| net_select a } end
|
280
|
-
end
|
281
|
-
|
282
|
-
def net_unselect *aa
|
283
|
-
if aa.empty? then @net_selection.delete net else
|
284
|
-
aa.each { |arg| @net_selection.delete net( arg ) }
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
# --- simulation selection ---------------------------------------------
|
289
|
-
|
290
|
-
def simulation_selection_clear
|
291
|
-
@simulation_selection ||= []
|
292
|
-
@simulation_selection.clear
|
293
|
-
end
|
294
|
-
|
295
|
-
def simulation_select! *aa
|
296
|
-
simulation_selection_clear
|
297
|
-
simulation_select *aa
|
298
|
-
end
|
299
|
-
|
300
|
-
def simulation_select *aa
|
301
|
-
# FIXME
|
302
|
-
end
|
303
|
-
|
304
|
-
def simulation_unselect *aa
|
305
|
-
# FIXME
|
306
|
-
end
|
307
|
-
|
308
|
-
# --- cc selection -----------------------------------------------------
|
309
|
-
|
310
|
-
def cc_selection_clear; @cc_selection ||= []; @cc_selection.clear end
|
311
|
-
|
312
|
-
def cc_select! *aa; cc_selection_clear; cc_select *aa end
|
313
|
-
|
314
|
-
def cc_select
|
315
|
-
# FIXME
|
316
|
-
end
|
317
|
-
|
318
|
-
def cc_unselect *aa
|
319
|
-
# FIXME
|
320
|
-
end
|
321
|
-
|
322
|
-
# --- imc selection ----------------------------------------------------
|
323
|
-
|
324
|
-
def imc_selection_clear; @imc_selection ||= []; @imc_selection.clear end
|
325
|
-
|
326
|
-
def imc_select! *aa; imc_selection_clear; imc_select *aa end
|
327
|
-
|
328
|
-
def imc_select
|
329
|
-
# FIXME
|
330
|
-
end
|
331
|
-
|
332
|
-
def imc_unselect *aa
|
333
|
-
# FIXME
|
9
|
+
@workspace = YPetri::Workspace.new
|
10
|
+
super
|
334
11
|
end
|
335
12
|
|
336
|
-
|
13
|
+
require_relative 'manipulator/selection'
|
14
|
+
require_relative 'manipulator/hash_key_pointer'
|
15
|
+
require_relative 'manipulator/petri_net_related_methods'
|
16
|
+
require_relative 'manipulator/simulation_related_methods'
|
337
17
|
|
338
|
-
|
339
|
-
|
340
|
-
def ssc_select! *aa; ssc_selection_clear; ssc_select *aa end
|
341
|
-
|
342
|
-
def ssc_select
|
343
|
-
# FIXME
|
344
|
-
end
|
345
|
-
|
346
|
-
def ssc_unselect *aa
|
347
|
-
# FIXME
|
348
|
-
end
|
349
|
-
|
350
|
-
# --- rest of the world ------------------------------------------------
|
351
|
-
# FIXME: This is going to be tested
|
352
|
-
|
353
|
-
def clamp clamp_hash
|
354
|
-
clamp_hash.each_pair { |pl, cl|
|
355
|
-
clamp_collection.merge! workspace.place( pl ) => cl
|
356
|
-
}
|
357
|
-
end
|
358
|
-
|
359
|
-
# Returns or modifies current initial marking(s) as indicated by the argument
|
360
|
-
# field:
|
361
|
-
# * No arguments: returns current imc
|
362
|
-
# * Exactly one ordered argument: it is assumed to identify a place whose
|
363
|
-
# im in teh current imc will be returned.
|
364
|
-
# * A hash: Assumed to be { place_id => im }, current imc is updated with it.
|
365
|
-
# * One ordered argument, and a hash: The imc identified by the ordered
|
366
|
-
# ordered arg is updated with the hash.
|
367
|
-
# * 2 ordered arguments: First is assumed to identify an imc, second place
|
368
|
-
# whose im acc. to that imc to return.
|
369
|
-
#
|
370
|
-
def initial_marking *args;
|
371
|
-
oo = args.extract_options!
|
372
|
-
case args.size
|
373
|
-
when 0 then
|
374
|
-
if oo.empty? then # no ordered arguments were given,
|
375
|
-
initial_marking_collection # current imc will be returned
|
376
|
-
else # hash was supplied, assumed of pairs { place_id => marking },
|
377
|
-
initial_marking_collection # it will be merged to imc
|
378
|
-
.update( oo.with_keys do |key| place( key ) end )
|
379
|
-
end
|
380
|
-
when 1 then # exactly one ordered argument was given,
|
381
|
-
if oo.empty? then # without any named arguments, it is
|
382
|
-
place = place( args[0] ) # assumed that it identifies a place,
|
383
|
-
initial_marking_collection[ place ] # return its init. marking in imc
|
384
|
-
else # One ordered argument (imc), and one hash (update values) given.
|
385
|
-
im_coll = initial_marking_collection( args[0] )
|
386
|
-
im_coll.update( oo.with_keys do |key| place( key ) end )
|
387
|
-
end
|
388
|
-
when 2 then # 2 ordered arguments (imc, place whose marking to return)
|
389
|
-
im_coll = initial_marking_collection( args[0] )
|
390
|
-
place = place( args[1] )
|
391
|
-
im_coll[ place ]
|
392
|
-
else raise AE, "Too many ordered parameters" end
|
393
|
-
end
|
394
|
-
alias :im :initial_marking
|
395
|
-
|
396
|
-
# Changes the time step of the current ssc (ssc = simulation settings
|
397
|
-
# collection).
|
398
|
-
#
|
399
|
-
def set_step Δt
|
400
|
-
ssc.update step_size: Δt
|
401
|
-
end
|
402
|
-
alias :set_step_size :set_step
|
403
|
-
|
404
|
-
# Changes the simulation time of the current ssc (ssc = simulation
|
405
|
-
# settings collection).
|
406
|
-
#
|
407
|
-
def set_time t
|
408
|
-
ssc.update target_time: t
|
409
|
-
end
|
410
|
-
alias :set_target_time :set_time
|
411
|
-
|
412
|
-
# Changes the sampling period of the current ssc (ssc = simulation
|
413
|
-
# settings collection).
|
414
|
-
#
|
415
|
-
def set_sampling Δt
|
416
|
-
ssc.update sampling_period: Δt
|
417
|
-
end
|
418
|
-
|
419
|
-
# Changes the simulation method of the current ssc (ssc = simulation
|
420
|
-
# settings collection).
|
421
|
-
#
|
422
|
-
def set_simulation_method m
|
423
|
-
ssc.update method: m
|
424
|
-
end
|
425
|
-
|
426
|
-
# Create a new timed simulation and make it available in the simulations
|
427
|
-
# table.
|
428
|
-
#
|
429
|
-
def new_timed_simulation *args, &block
|
430
|
-
instance = workspace.new_timed_simulation( *args, &block )
|
431
|
-
# Set the point to it
|
432
|
-
simulation_point_to( simulations.rassoc( instance )[0] )
|
433
|
-
return instance
|
434
|
-
end
|
435
|
-
|
436
|
-
# Create a new timed simulation and run it.
|
437
|
-
#
|
438
|
-
def run!
|
439
|
-
new_timed_simulation.run!
|
440
|
-
end
|
441
|
-
|
442
|
-
# Write the recorded samples in a file (csv).
|
443
|
-
#
|
444
|
-
def print_recording( filename = nil )
|
445
|
-
if filename.nil? then
|
446
|
-
puts simulation.recording_csv_string
|
447
|
-
else
|
448
|
-
File.open( filename, "w" ) do |f|
|
449
|
-
f << simulation.recording_csv_string
|
450
|
-
end
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
# Plot the recorded samples.
|
455
|
-
#
|
456
|
-
def plot *args
|
457
|
-
oo = args.extract_options!
|
458
|
-
case args.size
|
459
|
-
when 0 then plot_recording oo
|
460
|
-
when 1 then
|
461
|
-
plot_what = args[0]
|
462
|
-
case plot_what
|
463
|
-
when :state then plot_recording oo
|
464
|
-
when :flux then plot_flux oo
|
465
|
-
when :all then plot_all oo
|
466
|
-
else plot_selected *args end
|
467
|
-
else raise "Too many ordered arguments!" end
|
468
|
-
end
|
469
|
-
|
470
|
-
# Plot the selected features.
|
471
|
-
#
|
472
|
-
def plot_selected *args
|
473
|
-
oo = args.extract_options!
|
474
|
-
collection = Array args[0]
|
475
|
-
return nil unless sim = @workspace.simulations.values[-1] # sim@point
|
476
|
-
# Decide abnout the features
|
477
|
-
features = sim.places.dup.map { |p|
|
478
|
-
collection.include?( p ) ? p : nil
|
479
|
-
}
|
480
|
-
# Get recording
|
481
|
-
rec = sim.recording
|
482
|
-
# Select a time series for each feature.
|
483
|
-
time_series = features.map.with_index do |feature, i|
|
484
|
-
feature and rec.map { |key, val| [ key, val[i] ] }.transpose
|
485
|
-
end
|
486
|
-
# Time axis
|
487
|
-
ᴛ = sim.target_time
|
488
|
-
# Gnuplot call
|
489
|
-
gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
|
490
|
-
title: "Selected features plot", ylabel: "Marking" )
|
491
|
-
end
|
492
|
-
|
493
|
-
|
494
|
-
# Plot the recorded samples (system state history).
|
495
|
-
#
|
496
|
-
def plot_state( *args )
|
497
|
-
oo = args.extract_options!
|
498
|
-
excluded = Array oo[:except]
|
499
|
-
return nil unless sim = @workspace.simulations.values[-1] # sim@point
|
500
|
-
# Decide about the features to plot.
|
501
|
-
features = excluded.each_with_object sim.places.dup do |x, α|
|
502
|
-
i = α.index x
|
503
|
-
α[i] = nil if i
|
504
|
-
end
|
505
|
-
# Get recording
|
506
|
-
rec = sim.recording
|
507
|
-
# Select a time series for each feature.
|
508
|
-
time_series = features.map.with_index do |feature, i|
|
509
|
-
feature and rec.map { |key, val| [ key, val[i] ] }.transpose
|
510
|
-
end
|
511
|
-
# Time axis
|
512
|
-
ᴛ = sim.target_time
|
513
|
-
# Gnuplot call
|
514
|
-
gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
|
515
|
-
title: "State plot", ylabel: "Marking" )
|
516
|
-
end
|
517
|
-
|
518
|
-
# Plot the recorded flux (computed flux history at the sampling points).
|
519
|
-
#
|
520
|
-
def plot_flux( *args )
|
521
|
-
oo = args.extract_options!
|
522
|
-
excluded = Array oo[:except]
|
523
|
-
return nil unless sim = @workspace.simulations.values[-1] # sim@point
|
524
|
-
# Decide about the features to plot.
|
525
|
-
all = sim.SR_transitions
|
526
|
-
features = excluded.each_with_object all.dup do |x, α|
|
527
|
-
i = α.index x
|
528
|
-
if i then α[i] = nil end
|
529
|
-
end
|
530
|
-
# Get recording.
|
531
|
-
rec = sim.recording
|
532
|
-
# Get flux recording.
|
533
|
-
flux = rec.modify { |ᴛ, ᴍ| [ ᴛ, sim.at( t: ᴛ, m: ᴍ ).flux_for( *all ) ] }
|
534
|
-
# Select a time series for each feature.
|
535
|
-
time_series = features.map.with_index do |feature, i|
|
536
|
-
feature and flux.map { |ᴛ, flux| [ ᴛ, flux[i] ] }.transpose
|
537
|
-
end
|
538
|
-
# Time axis
|
539
|
-
ᴛ = sim.target_time
|
540
|
-
# Gnuplot call
|
541
|
-
gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
|
542
|
-
title: "Flux plot", ylabel: "Flux [µMⁿ.s⁻¹]" )
|
543
|
-
end
|
544
|
-
|
545
|
-
private
|
546
|
-
|
547
|
-
# Gnuplots things.
|
548
|
-
#
|
549
|
-
def gnuplot( time, labels, time_series, *args )
|
550
|
-
labels = labels.dup
|
551
|
-
time_series = time_series.dup
|
552
|
-
oo = args.extract_options!
|
553
|
-
|
554
|
-
Gnuplot.open do |gp|
|
555
|
-
Gnuplot::Plot.new( gp ) do |plot|
|
556
|
-
plot.xrange "[-0:#{SY::Time.magnitude( time ).amount rescue time}]"
|
557
|
-
plot.title oo[:title] || "Simulation plot"
|
558
|
-
plot.ylabel oo[:ylabel] || "Values"
|
559
|
-
plot.xlabel oo[:xlabel] || "Time [s]"
|
560
|
-
|
561
|
-
labels.zip( time_series ).each { |label, series|
|
562
|
-
plot.data << Gnuplot::DataSet.new( series ) do |data_series|
|
563
|
-
data_series.with = "linespoints"
|
564
|
-
data_series.title = label
|
565
|
-
end
|
566
|
-
}
|
567
|
-
end
|
568
|
-
end
|
569
|
-
end
|
570
|
-
|
571
|
-
# Helper method allowing more flexible access to the simulations stored in
|
572
|
-
# the current workspace. A single, non-hash ordered argument is considered
|
573
|
-
# a simulation name. A hash argument is assumed to be have keys :net, :cc,
|
574
|
-
# :imc, :ssc, by which to identify a simulation. Hash keys can be forgone if
|
575
|
-
# 4 ordered arguments are supplied: These are then considered to represent
|
576
|
-
# the values of a hash with the above keys, and are converted to such hash.
|
577
|
-
# Summarizing this, there is a single return value, with which a simulation
|
578
|
-
# can be identified - this return value is either a hash of simulation
|
579
|
-
# parameters and settings, if it is a hash, or a simulation name, if it is
|
580
|
-
# non-hash.
|
581
|
-
#
|
582
|
-
def normalize_simulation_identifier *args
|
583
|
-
oo = args.extract_options!
|
584
|
-
if args.empty? then
|
585
|
-
raise AE, "Simulation point position not supplied" if oo.empty?
|
586
|
-
oo
|
587
|
-
else
|
588
|
-
if oo.empty? then
|
589
|
-
case args.size
|
590
|
-
when 1 then args[0]
|
591
|
-
when 4 then Hash[ [:net, :cc, :imc, :ssc].zip( args ) ]
|
592
|
-
else raise AE, "Wrong number of ordered arguments." end
|
593
|
-
else
|
594
|
-
raise AE, "Bad arguments: Can't combine named & ordered args."
|
595
|
-
end
|
596
|
-
end
|
597
|
-
end
|
18
|
+
include YPetri::Manipulator::PetriNetRelatedMethods
|
19
|
+
include YPetri::Manipulator::SimulationRelatedMethods
|
598
20
|
end # class YPetri::Manipulator
|