coderunner 0.11.0

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.
@@ -0,0 +1,744 @@
1
+ ###########################
2
+ # Graph and Film Methods
3
+ ##########################
4
+
5
+ #
6
+
7
+ class CodeRunner
8
+
9
+ # Parse graphkit shorthand for a general graph and return it as [axes, options]. GraphKit shorthand is:
10
+ # '<axis1>[ : <axis2> [ : <axis3 [ : <axis4> ] ] ] [ ; <graph_options> [ ; <conditions> [ ; <sort> ] ] ]'
11
+ # i.e. all commands for the graph in one string
12
+
13
+ def graphkit_shorthand(*gr)
14
+ return gr if gr.size > 1
15
+ gr = gr[0]
16
+ return gr if gr.class == Array
17
+ axes, options, cons, srt = gr.split(/;/)
18
+ axes = eval("['#{axes.split(/(?<!\\|:):(?!:)/).map{|s| s.gsub(/\\:/, ':')}.join("','")}']")
19
+ options = (options and options =~ /\S/) ? eval(options): {}
20
+ # p srt
21
+ cons = nil unless cons and cons=~ /\S/
22
+ srt = nil unless srt and srt=~ /\S/
23
+
24
+ options[:conditions] ||= cons
25
+ options[:sort] ||= srt
26
+ return [axes, options]
27
+ end
28
+
29
+ def sweep_graphkits(sweeps, options, &block)
30
+ server = @server; @server = false
31
+ intial_conditions = @conditions
32
+ initial_sort = @sort
33
+ @conditions = (options[:conditions] or @conditions)
34
+ @sort = (options[:sort] or @sort)
35
+
36
+ sweeps = sweeps.class == Array ? sweeps : [sweeps]
37
+ generate_combined_ids
38
+ # ep sweeps
39
+ sweep_values = filtered_ids.inject([]) do |arr, id|
40
+ arr.push(sweeps.inject([]) do |sweep_arr, var|
41
+
42
+ sweep_arr.push @combined_run_list[id].send(var)
43
+ # ep sweep_arr, var
44
+ sweep_arr
45
+ end)
46
+ arr.uniq
47
+ end
48
+ old_conditions = @conditions
49
+ new_options = options.dup
50
+ new_options.delete(:sweep) if new_options[:sweep]
51
+ # p new_options; gets
52
+ kits = sweep_values.sort.map do |values|
53
+ new_cons = (sweeps.zip(values).map do |name, value|
54
+ "#{name}==#{value}"
55
+ end).join(" and ")
56
+ new_options[:conditions] = old_conditions ? old_conditions + " and #{new_cons}" : new_cons
57
+ # ep new_options[:conditions]
58
+ kit = yield(new_options)
59
+
60
+
61
+ kit.data[0].gp.title = new_cons.gsub(/==/, '=')
62
+ # p kit
63
+ kit
64
+ end
65
+ # @conditions = old_conditions
66
+ @conditions = intial_conditions
67
+ @sort = initial_sort
68
+ if options[:sweep_multid]
69
+ kitdata = kits.map do |kit|
70
+ kit.data[0].axes.values.map{|axiskit| axiskit.data}
71
+ end
72
+ final_axes = (kitdata[0].size + sweeps.size - 1).times.inject([]){|arr, i| arr.push []}
73
+ data_hash = {}
74
+ sweep_values.sort.each_with_index do |vals, i|
75
+ # ep 'v', vals
76
+ data = kitdata[i]
77
+ length = data[0].size
78
+ vals.each_with_index do |val, j|
79
+ final_axes[j].push val
80
+ # final_axes[j].uniq!
81
+ end
82
+ function = data.pop
83
+ for j in 0...length
84
+
85
+ data.each_with_index do |axisdata, k|
86
+ # ep 'vk', vals.size + k
87
+ # break if k == data.size - 1
88
+ final_axes[vals.size + k].push axisdata[j]
89
+ final_axes[vals.size + k].uniq!
90
+ end
91
+ # ep 'h', final_axes, function
92
+ data_hash[vals + data.map{|axisdata| axisdata[j]}] = function[j]
93
+ end
94
+ end
95
+ final_axes.map!{|vals| vals.uniq.sort}
96
+ final_data = SparseTensor.new(final_axes.size)
97
+ data_hash.each do |coordinates, function|
98
+ indices = []
99
+ coordinates.each_with_index do |val, i|
100
+ indices[i] = final_axes[i].index(val)
101
+ end
102
+ final_data[*indices] = function
103
+ end
104
+ hash = {}
105
+
106
+ # pp final_axes, final_data
107
+
108
+ titles = sweeps + kits[0].data[0].axes.values.map{|axiskit| axiskit[:title]}
109
+ (final_axes + [final_data]).each_with_index do |d, i|
110
+ hash[GraphKit::AXES[i]] = {data: d, title: titles[i].to_s}
111
+ end
112
+ kit = GraphKit.autocreate(hash)
113
+
114
+
115
+
116
+ # length = data[i].size
117
+ # array = vals.map{|val| [val] * length} + data
118
+ # p array
119
+ # end
120
+ # final_data = [[]] * (kitdata[0].size + sweeps.size)
121
+ # sweep_values.sort.each_with_index do |vals, i|
122
+ # data = kitdata[0]
123
+ # length = data[0].size
124
+ # array = vals.map{|val| [val] * length} + data
125
+ # p array
126
+ # end
127
+ else
128
+ kit = kits.inject{|ans, kit| ans + kit}
129
+ end
130
+
131
+
132
+ #Kernel.puts server_dump(kit) if server
133
+
134
+ return kit
135
+
136
+ end
137
+
138
+ def sweep_graphkits(sweeps, options, &block)
139
+ server = @server; @server = false
140
+ intial_conditions = @conditions
141
+ initial_sort = @sort
142
+ @conditions = (options[:conditions] or @conditions)
143
+ @sort = (options[:sort] or @sort)
144
+
145
+ sweeps = sweeps.class == Array ? sweeps : [sweeps]
146
+ generate_combined_ids
147
+ # ep sweeps
148
+ sweep_values = filtered_ids.inject([]) do |arr, id|
149
+ arr.push(sweeps.inject([]) do |sweep_arr, sweep|
150
+
151
+ sweep_arr.push @combined_run_list[id].instance_eval(sweep.to_s)
152
+ # ep sweep_arr, var
153
+ sweep_arr
154
+ end)
155
+ arr.uniq
156
+ end
157
+ old_conditions = @conditions
158
+ new_options = options.dup
159
+ new_options.delete(:sweep) if new_options[:sweep]
160
+ # p new_options; gets
161
+ kits = sweep_values.sort.map do |values|
162
+ new_cons = (sweeps.zip(values).map do |name, value|
163
+ "#{name}==#{value.inspect}"
164
+ end).join(" and ")
165
+ new_options[:conditions] = old_conditions ? old_conditions + " and #{new_cons}" : new_cons
166
+ # ep new_options[:conditions]
167
+ kit = yield(new_options)
168
+
169
+
170
+ kit.data[0].gp.title = new_cons.gsub(/==/, '=')
171
+ # p kit
172
+ kit
173
+ end
174
+ # @conditions = old_conditions
175
+ @conditions = intial_conditions
176
+ @sort = initial_sort
177
+ if options[:sweep_multid]
178
+ kitdata = kits.map do |kit|
179
+ kit.data[0].axes.values.map{|axiskit| axiskit.data}
180
+ end
181
+ final_axes = (kitdata[0].size + sweeps.size - 1).times.inject([]){|arr, i| arr.push []}
182
+ data_hash = {}
183
+ sweep_values.sort.each_with_index do |vals, i|
184
+ # ep 'v', vals
185
+ data = kitdata[i]
186
+ length = data[0].size
187
+ vals.each_with_index do |val, j|
188
+ final_axes[j].push val
189
+ # final_axes[j].uniq!
190
+ end
191
+ function = data.pop
192
+ for j in 0...length
193
+
194
+ data.each_with_index do |axisdata, k|
195
+ # ep 'vk', vals.size + k
196
+ # break if k == data.size - 1
197
+ final_axes[vals.size + k].push axisdata[j]
198
+ final_axes[vals.size + k].uniq!
199
+ end
200
+ # ep 'h', final_axes, function
201
+ data_hash[vals + data.map{|axisdata| axisdata[j]}] = function[j]
202
+ end
203
+ end
204
+ final_axes.map!{|vals| vals.nuniq.sort}
205
+ # ep final_axes
206
+ final_data = SparseTensor.new(final_axes.size)
207
+ data_hash.each do |coordinates, function|
208
+ indices = []
209
+ # p coordinates
210
+ coordinates.each_with_index do |val, i|
211
+ indices[i] = final_axes[i].index(val)
212
+ end
213
+ final_data[*indices] = function
214
+ end
215
+ hash = {}
216
+
217
+ # pp final_axes, final_data
218
+
219
+ titles = sweeps + kits[0].data[0].axes.values.map{|axiskit| axiskit[:title]}
220
+ (final_axes + [final_data]).each_with_index do |d, i|
221
+ hash[GraphKit::AXES[i]] = {data: d, title: titles[i].to_s}
222
+ end
223
+ kit = GraphKit.autocreate(hash)
224
+
225
+
226
+
227
+ # length = data[i].size
228
+ # array = vals.map{|val| [val] * length} + data
229
+ # p array
230
+ # end
231
+ # final_data = [[]] * (kitdata[0].size + sweeps.size)
232
+ # sweep_values.sort.each_with_index do |vals, i|
233
+ # data = kitdata[0]
234
+ # length = data[0].size
235
+ # array = vals.map{|val| [val] * length} + data
236
+ # p array
237
+ # end
238
+ else
239
+ kit = kits.inject{|ans, kit| ans + kit}
240
+ end
241
+
242
+
243
+ #Kernel.puts server_dump(kit) if server
244
+ return kit
245
+
246
+ end
247
+
248
+ # call-seq: graphkit(axes, options)
249
+ # Make a general graphkit, i.e. a graph that combines output from lots of runs. The axes should be an array of strings, each string defining what should be plotted on each axis. Each string is actually a fragment of Ruby code which will be evaluated by each run for whom option[:conditions] or @conditions evaulates to true. The most important other option is options[:sweep]. This is a string or an array of strings, each of which will be evaluated by each run; the data will then be grouped for the values of these strings.
250
+ # E.g.
251
+ # graphkit(['a', 'b'], {sweep: ["c"], conditions: 'd==1'}
252
+ #
253
+
254
+ def graphkit(*args)
255
+ logf(:graphkit)
256
+ if args.size == 1
257
+ axes, options = graphkit_shorthand(args[0])
258
+ elsif args.size == 2
259
+ axes, options = args
260
+ else
261
+ raise ArgumentError
262
+ end
263
+ # p axes
264
+ # return named_graphkit(axes, options) if axes.class == String or axes.class == Symbol
265
+ # ep @sort
266
+ (return sweep_graphkits(options[:sweep], options) do |new_options|
267
+ graphkit(axes, new_options)
268
+ end) if options [:sweep]
269
+
270
+ intial_conditions = @conditions
271
+ initial_sort = @sort
272
+ @conditions = (options[:conditions] or @conditions)
273
+ @sort = (options[:sort] or @sort)
274
+
275
+ sort_runs
276
+
277
+ case axes.size
278
+ when 1
279
+ kit = GraphKit.autocreate({x: axiskit(axes[0])})
280
+ kit.data[0].gp.with = "linespoints"
281
+ when 2
282
+ kit = GraphKit.autocreate({x: axiskit(axes[0]), y: axiskit(axes[1])})
283
+ kit.data[0].gp.with = "linespoints"
284
+
285
+ when 3
286
+ kit = GraphKit.autocreate({x: axiskit(axes[0]), y: axiskit(axes[1]), z: axiskit(axes[2])})
287
+ kit.data[0].gp.with = "linespoints"
288
+
289
+ when 4
290
+ kit = GraphKit.autocreate({x: axiskit(axes[0]), y: axiskit(axes[1]), z: axiskit(axes[2]), f: axiskit(axes[3])})
291
+ kit.data[0].gp.with = "linespoints palette"
292
+ else
293
+ raise CRError.new("Bad graph string")
294
+ end
295
+
296
+ kit.title += %| for #{@conditions.gsub(/==/, "=").gsub(/\&\&/, " and ").gsub(/\|\|/, " or ").gsub(/\A(.{,40}).*\s/m, '\1')}| if @conditions
297
+ kit.file_name = kit.title.gsub(/=/, ' eq ').gsub(/\&\&/, " and ").gsub(/\|\|/, " or ").gsub(/ /, "_").gsub(/\//, "over").gsub(/\*/, '.')
298
+ kit.modify(options)
299
+
300
+
301
+ # p kit
302
+ kit.data[0].gp.title = "#@code:#{kit.data[0].title}"
303
+ #Kernel.puts server_dump(kit) if @server
304
+ return kit
305
+
306
+
307
+
308
+
309
+ end
310
+
311
+ # def gnuplot(axes, options)
312
+ # a = graphkit(axes, options).gnuplot
313
+ # end
314
+
315
+ def axiskit(string)
316
+ generate_combined_ids
317
+ data = filtered_ids.inject([]) do |arr, id|
318
+ begin
319
+ arr.push @combined_run_list[id].instance_eval(string)
320
+ rescue => err
321
+ eputs "Evaluation of #{string} failed for run #{id}"
322
+ raise err
323
+ end
324
+ end
325
+ # p data
326
+ return GraphKit::AxisKit.new(title: string, data: data)
327
+ end
328
+
329
+ def run_graphkit_shorthand(*grs)
330
+ # p grs
331
+ return grs if grs.size > 1
332
+ gr = grs[0]
333
+ # p gr
334
+ return gr if gr.class == Array
335
+ name, options, cons, srt = gr.split(/;/)
336
+ options = (options and options =~ /\S/) ? eval(options): {}
337
+ cons = nil unless cons and cons=~ /\S/
338
+ srt = nil unless srt and srt=~ /\S/
339
+ options[:conditions] ||= cons if cons
340
+ options[:sort] ||= srt if srt
341
+ [name, options]
342
+ end
343
+
344
+
345
+ def run_graphkit(*args)
346
+ if args.size == 1
347
+ name, options = run_graphkit_shorthand(args[0])
348
+ elsif args.size == 2
349
+ name, options = args
350
+ else
351
+ raise ArgumentError
352
+ end
353
+
354
+ (return sweep_graphkits(options[:sweep], options) do |new_options|
355
+ run_graphkit(name, new_options)
356
+ end) if options [:sweep]
357
+
358
+ old_sort, old_conditions = @sort, @conditions
359
+ @sort = options[:sort] if options[:sort]
360
+ @conditions = options[:conditions] if options[:conditions]
361
+ generate_combined_ids
362
+ fids = filtered_ids
363
+ raise CRError.new("No ids match these conditions: #@conditions") unless fids.size > 0
364
+ kit = (fids.map do |id|
365
+ run = @combined_run_list[id];
366
+ # p run; STDIN.gets
367
+ kit = run.graphkit(name, options.dup);
368
+ kit.data[0].title ||= run.run_name;
369
+ kit
370
+ end).inject{|kit, k| kit+k}
371
+ @sort, @conditions = old_sort, old_conditions
372
+ #Kernel.puts server_dump(kit) if @server
373
+ kit
374
+ end
375
+
376
+ def graphkit_from_lists(graphs, run_graphs, extra_options = {})
377
+ run_kits = run_graphs.map do |gr|
378
+ name, options = run_graphkit_shorthand(gr)
379
+ options += extra_options
380
+ run_graphkit(name, options.dup)
381
+ end
382
+ kits = graphs.map do |gr|
383
+ axes, options = graphkit_shorthand(gr)
384
+ options += extra_options
385
+ graphkit(axes, options.dup)
386
+ end
387
+
388
+ (run_kits + kits).inject{|kit, k| kit+k}
389
+ end
390
+ def graphkit_from_lists_with_frame_array(frame_array, graphs, run_graphs, extra_options = {})
391
+ server = @server; @server = false
392
+ # ep "Frame array to calculate is", frame_array, "\n\n"
393
+ i=0
394
+ array = frame_array.map do |frame_index|
395
+ # if print_message
396
+ eputs "\033[2A" # Terminal jargon - go back one line
397
+ eputs sprintf("Fetching graphs: %2.2f", i.to_f/frame_array.size.to_f * 100.0) + "% Complete"
398
+ # end
399
+ i+=1
400
+ [frame_index, graphkit_from_lists(graphs, run_graphs, extra_options.absorb({frame_index: frame_index}))]
401
+ end
402
+ # eputs Marshal.load(Marshal.dump(array)).pretty_inspect
403
+ #Kernel.puts server_dump(array) if server
404
+ return array
405
+ end
406
+
407
+
408
+ def film_graphkit(axes, options, film_options = {})
409
+ # self.class.make_film_multiple_runners([[self,[[[axes, options]],[]]]], film_options)
410
+ film_from_lists([[axes, options]], [], film_options)
411
+ end
412
+
413
+ def film_run_graphkit(name, options, film_options = {})
414
+ # self.class.make_film_multiple_runners([[self,[[],[[name, options]]]]], film_options)
415
+ film_from_lists([], [[name, options]], film_options)
416
+ end
417
+
418
+ def make_film_from_lists(graphs, run_graphs, film_options = {})
419
+ self.class.make_film_multiple_runners([[self,[graphs, run_graphs]]], film_options)
420
+ end
421
+
422
+ # list is an array of [[runner, [graphs, run_graphs]], ... ]
423
+
424
+ def self.graphkit_multiple_runners(list, options={})
425
+ return list.inject(nil) do |kit, (runner, graph_lists)|
426
+ graphs, run_graphs = graph_lists
427
+ graphs.map!{|graph| runner.graphkit_shorthand(graph)}
428
+ run_graphs.map!{|graph| runner.run_graphkit_shorthand(graph)}
429
+ newkit = runner.graphkit_from_lists(graphs, run_graphs, options)
430
+ kit ? kit + newkit : newkit
431
+ end
432
+ end
433
+
434
+ def self.graphkit_multiple_runners_with_frame_array(frame_array, list, print_message = false)
435
+ i = 0
436
+ #
437
+ return list.inject(nil) do |kit_array, (runner, graph_lists)|
438
+ graphs, run_graphs = graph_lists
439
+ graphs.map!{|graph| runner.graphkit_shorthand(graph)}
440
+ run_graphs.map!{|graph| runner.run_graphkit_shorthand(graph)}
441
+ newkit_array = runner.graphkit_from_lists_with_frame_array(frame_array, graphs, run_graphs, {})
442
+ # eputs newkit_array.pretty_inspect
443
+ kit_array ? (i=-1; kit.map{|(frame_index, kit)| i+= 1;[frame_index, new_kit[i][1]]}) : newkit_array
444
+ end
445
+ end
446
+
447
+ def self.make_film_multiple_runners(list, options)
448
+ possible_options = [:frame_array, :fa, :skip_frames, :sf, :normalize, :n, :normalize_pieces, :np, :increment, :i, :skip_encoding, :se]
449
+ fa = (options[:frame_array] or options[:fa] or list[0][0].run_list[list[0][0].filtered_ids[0]].frame_array(options) )
450
+
451
+ fd = frame_digits = Math.log10(fa[1]).ceil
452
+ unless options[:skip_frames] or options[:sf]
453
+ `rm -rf film_frames`
454
+ extension = (options[:extension] or options[:ext] or '.png')
455
+ extension = '.' + extension unless extension =~ /^\./
456
+
457
+ FileUtils.makedirs('film_frames')
458
+ # puts @@multiple_processes; gets
459
+ no_forks = (@@multiple_processes or 1)
460
+ ep @@multiple_processes, no_forks
461
+ end_graphkit = graphkit_multiple_runners(list, frame_index: fa[1])
462
+ begin_graphkit = graphkit_multiple_runners(list, frame_index: fa[0])
463
+
464
+ end_area = end_graphkit.plot_area_size
465
+ begin_area = begin_graphkit.plot_area_size
466
+ # p end_area, begin_area, options
467
+ plot_size = {}
468
+ axes = [:x, :y, :z]
469
+ options[:normalize] ||= options[:nm]
470
+ options[:normalize_pieces] ||= options[:nmp]
471
+ for i in 0...end_area.size
472
+ next unless options[:normalize] and options[:normalize].include? axes[i]
473
+ min = [end_area[i][0], begin_area[i][0]].min
474
+ max = [end_area[i][1], begin_area[i][1]].max
475
+ key = axes[i]
476
+ plot_size[key + :range] = [min, max]
477
+ end
478
+ ep plot_size
479
+ # exit
480
+ frames = []
481
+ actual_frames = {}
482
+ i = fa[0]
483
+ j = 0
484
+ while i <= fa[1]
485
+ frames.push i
486
+ actual_frames[i] = j
487
+ i += (options[:ic] or options[:increment] or 1)
488
+ j += 1
489
+ end
490
+ frames.pieces(no_forks).each_with_index do |piece, myrank|
491
+ fork do
492
+ if options[:normalize_pieces]
493
+ end_area = graphkit_multiple_runners(list, frame_index: piece.max).plot_area_size
494
+ begin_area = graphkit_multiple_runners(list, frame_index: piece.min).plot_area_size
495
+ axes = [:x, :y, :z]
496
+ for i in 0...end_area.size
497
+ next unless options[:normalize_pieces].include? axes[i]
498
+ min = [end_area[i][0], begin_area[i][0]].min
499
+ max = [end_area[i][1], begin_area[i][1]].max
500
+ key = axes[i]
501
+
502
+ plot_size[key + :range] = [min, max]
503
+ end
504
+ end
505
+ eputs 'making graphs...'; sleep 1
506
+ graph_array = graphkit_multiple_runners_with_frame_array(piece, list, myrank==0)
507
+ # ep graph_array
508
+ eputs
509
+ graph_array.each_with_index do |(frame_index,g), pindex|
510
+ if myrank == 0
511
+ eputs "\033[2A" # Terminal jargon - go back one line
512
+ eputs sprintf("Plotting graphs: %2.2f", pindex.to_f/piece.size.to_f * 100.0) + "% Complete"
513
+ end
514
+ # g = graph_kit_multiple_runners(list, plot_size + {frame_index: frame_index})
515
+
516
+ g.modify(plot_size)
517
+ g.modify(options)
518
+ # p g; exit
519
+ g.title += sprintf(", frame %0#{fd}d", frame_index) unless options[:frame_title] == false
520
+ folder = ("film_frames/");
521
+ file_name = sprintf("frame_%0#{fd}d", actual_frames[frame_index])
522
+ # g.gnuplot; gets; g.close
523
+ # ep folder + file_name + '.png'; gets
524
+ g.gnuplot_write(folder + file_name + extension)
525
+ end
526
+ end
527
+ end
528
+ eputs "Waiting on subprocesses..."
529
+ Process.waitall
530
+ end
531
+ unless options[:skip_encoding]
532
+ eputs "making film"
533
+ frame_rate = (options[:frame_rate] or options[:fr] || 15)
534
+ film_name = (options[:film_name] or options [:fn] or end_graphkit.file_name + '_film').gsub(/\s/, '_')
535
+ puts `ffmpeg -y #{options[:bitrate] ? "-b #{options[:bitrate]}" : ""} -r #{frame_rate} -threads #{(@multiple_processes or 1)} -i film_frames/frame_%0#{fd}d#{extension} -sameq #{film_name}.mp4`
536
+ end
537
+ end
538
+
539
+ # end
540
+
541
+ # __END__
542
+
543
+ def self.make_film_multiple_runners(list, options)
544
+ possible_options = [:frame_array, :fa, :skip_frames, :sf, :normalize, :n, :normalize_pieces, :np, :increment, :i, :skip_encoding, :se]
545
+ fa = (options[:frame_array] or options[:fa] or list[0][0].run_list[list[0][0].filtered_ids[0]].frame_array(options) )
546
+
547
+ fd = frame_digits = Math.log10(fa[1]).ceil
548
+ unless options[:skip_frames] or options[:sf]
549
+ # `rm -rf film_frames`
550
+ # extension = (options[:extension] or options[:ext] or '.png')
551
+ # extension = '.' + extension unless extension =~ /^\./
552
+
553
+ # FileUtils.makedirs('film_frames')
554
+ # puts @@multiple_processes; gets
555
+ no_forks = (@@multiple_processes or 1)
556
+ ep @@multiple_processes, no_forks
557
+ end_graphkit = graphkit_multiple_runners(list, frame_index: fa[1])
558
+ begin_graphkit = graphkit_multiple_runners(list, frame_index: fa[0])
559
+
560
+ end_area = end_graphkit.plot_area_size
561
+ begin_area = begin_graphkit.plot_area_size
562
+ # p end_area, begin_area, options
563
+ plot_size = {}
564
+ axes = [:x, :y, :z]
565
+ options[:normalize] ||= options[:nm]
566
+ options[:normalize_pieces] ||= options[:nmp]
567
+ for i in 0...end_area.size
568
+ next unless options[:normalize] and options[:normalize].include? axes[i]
569
+ min = [end_area[i][0], begin_area[i][0]].min
570
+ max = [end_area[i][1], begin_area[i][1]].max
571
+ key = axes[i]
572
+ plot_size[key + :range] = [min, max]
573
+ end
574
+ ep plot_size
575
+ # exit
576
+ frames = []
577
+ actual_frames = {}
578
+ i = fa[0]
579
+ j = 0
580
+ while i <= fa[1]
581
+ frames.push i
582
+ actual_frames[i] = j
583
+ i += (options[:ic] or options[:increment] or 1)
584
+ j += 1
585
+ end
586
+ # graphkit_frame_array = []
587
+
588
+ myrank = -1
589
+ # graphkit_frame_array = (frames.pieces(no_forks).parallel_map(n_procs: no_forks, with_rank: true) do |piece, myrank|
590
+ graphkit_frame_array = (frames.pieces(no_forks).map do |piece|
591
+ myrank +=1
592
+ # ep 'myrank is', myrank
593
+ # unless myrank==0
594
+ # # $stdout = $stderr = StringIO.new
595
+ # end
596
+ # fork do
597
+ if options[:normalize_pieces]
598
+ end_area = graphkit_multiple_runners(list, frame_index: piece.max).plot_area_size
599
+ begin_area = graphkit_multiple_runners(list, frame_index: piece.min).plot_area_size
600
+ axes = [:x, :y, :z]
601
+ for i in 0...end_area.size
602
+ next unless options[:normalize_pieces].include? axes[i]
603
+ min = [end_area[i][0], begin_area[i][0]].min
604
+ max = [end_area[i][1], begin_area[i][1]].max
605
+ key = axes[i]
606
+
607
+ plot_size[key + :range] = [min, max]
608
+ end
609
+ end
610
+ eputs 'making graphs...'; sleep 1 if myrank==0
611
+ graph_array = graphkit_multiple_runners_with_frame_array(piece, list, myrank==0)
612
+ # ep graph_array
613
+ eputs
614
+ graph_array.each_with_index do |(frame_index,g), pindex|
615
+ # if myrank == 0
616
+ # eputs "\033[2A" # Terminal jargon - go back one line
617
+ # eputs sprintf("Plotting graphs: %2.2f", pindex.to_f/piece.size.to_f * 100.0) + "% Complete"
618
+ # end
619
+ # g = graph_kit_multiple_runners(list, plot_size + {frame_index: frame_index})
620
+
621
+ g.modify(plot_size)
622
+ g.modify(options)
623
+ g.instance_eval options[:graphkit_modify] if options[:graphkit_modify]
624
+ # p g; exit
625
+ g.title += sprintf(", frame %0#{fd}d", frame_index) unless options[:frame_title] == false
626
+ # folder = ("film_frames/");
627
+ # file_name = sprintf("frame_%0#{fd}d", actual_frames[frame_index])
628
+ # g.gnuplot; gets; g.close
629
+ # ep folder + file_name + '.png'; gets
630
+ # g.gnuplot_write(folder + file_name + extension)
631
+ end
632
+ graph_array
633
+ # end
634
+ end).sum
635
+ # eputs "Waiting on subprocesses..."
636
+ # Process.waitall
637
+ end
638
+
639
+ film_graphkit_frame_array(graphkit_frame_array, options)
640
+ # unless options[:skip_encoding]
641
+ # eputs "making film"
642
+ # frame_rate = (options[:frame_rate] or options[:fr] || 15)
643
+ # film_name = (options[:film_name] or options [:fn] or end_graphkit.file_name + '_film').gsub(/\s/, '_')
644
+ # puts `ffmpeg -y #{options[:bitrate] ? "-b #{options[:bitrate]}" : ""} -r #{frame_rate} -threads #{(@multiple_processes or 1)} -i film_frames/frame_%0#{fd}d#{extension} -sameq #{film_name}.mp4`
645
+ # end
646
+ end
647
+
648
+ def self.film_graphkit_frame_array(graphkit_frame_array, options)
649
+ possible_options = [:frame_array, :fa, :skip_frames, :sf, :normalize, :n, :normalize_pieces, :np, :increment, :i, :skip_encoding, :se, :frame_rate, :fr, :size]
650
+ # fa = (options[:frame_array] or options[:fa] or list[0][0].run_list[list[0][0].filtered_ids[0]].frame_array(options) )
651
+
652
+ fd = frame_digits = options[:fd]||Math.log10(graphkit_frame_array.map{|f, g| f}.max).ceil
653
+ extension = (options[:extension] or options[:ext] or '.png')
654
+ extension = '.' + extension unless extension =~ /^\./
655
+ unless options[:skip_frames] or options[:sf]
656
+ FileUtils.rm_r('film_frames') if FileTest.exist?('film_frames')
657
+
658
+ FileUtils.makedirs('film_frames')
659
+ # puts @@multiple_processes; gets
660
+ no_forks = (@@multiple_processes or 1)
661
+ ep @@multiple_processes, no_forks
662
+ # end_graphkit = graphkit_multiple_runners(list, frame_index: fa[1])
663
+ # begin_graphkit = graphkit_multiple_runners(list, frame_index: fa[0])
664
+
665
+ # end_area = end_graphkit.plot_area_size
666
+ # begin_area = begin_graphkit.plot_area_size
667
+ # p end_area, begin_area, options
668
+ # plot_size = {}
669
+ # axes = [:x, :y, :z]
670
+ # options[:normalize] ||= options[:nm]
671
+ # options[:normalize_pieces] ||= options[:nmp]
672
+ # for i in 0...end_area.size
673
+ # next unless options[:normalize] and options[:normalize].include? axes[i]
674
+ # min = [end_area[i][0], begin_area[i][0]].min
675
+ # max = [end_area[i][1], begin_area[i][1]].max
676
+ # key = axes[i]
677
+ # plot_size[key + :range] = [min, max]
678
+ # end
679
+ # ep plot_size
680
+ # exit
681
+ # frames = []
682
+ # actual_frames = {}
683
+ # i = fa[0]
684
+ # j = 0
685
+ # while i <= fa[1]
686
+ # frames.push i
687
+ # actual_frames[i] = j
688
+ # i += (options[:ic] or options[:increment] or 1)
689
+ # j += 1
690
+ # end
691
+ i = 0
692
+ actual_frames = graphkit_frame_array.map{|f, g| f}.inject({}){|hash, f| hash[f] = i; i+=1; hash}
693
+ graphkit_frame_array.pieces(no_forks).each_with_index do |graphkit_frame_array_piece, myrank|
694
+ fork do
695
+ # if options[:normalize_pieces]
696
+ # end_area = graphkit_multiple_runners(list, frame_index: piece.max).plot_area_size
697
+ # begin_area = graphkit_multiple_runners(list, frame_index: piece.min).plot_area_size
698
+ # axes = [:x, :y, :z]
699
+ # for i in 0...end_area.size
700
+ # next unless options[:normalize_pieces].include? axes[i]
701
+ # min = [end_area[i][0], begin_area[i][0]].min
702
+ # max = [end_area[i][1], begin_area[i][1]].max
703
+ # key = axes[i]
704
+ #
705
+ # plot_size[key + :range] = [min, max]
706
+ # end
707
+ # end
708
+ # eputs 'making graphs...'; sleep 1
709
+ # graph_array = graphkit_multiple_runners_with_frame_array(piece, list, myrank==0)
710
+ # # ep graph_array
711
+ # eputs
712
+ graphkit_frame_array_piece.each_with_index do |(frame_index,g), pindex|
713
+ if myrank == 0
714
+ eputs "\033[2A" # Terminal jargon - go back one line
715
+ eputs sprintf("Plotting graphs: %2.2f", pindex.to_f/graphkit_frame_array_piece.size.to_f * 100.0) + "% Complete"
716
+ end
717
+ # g = graph_kit_multiple_runners(list, plot_size + {frame_index: frame_index})
718
+
719
+ # g.modify(plot_size)
720
+ # g.modify(options)
721
+ # p g; exit
722
+ # g.title += sprintf(", frame %0#{fd}d", frame_index) unless options[:frame_title] == false
723
+ folder = ("film_frames/");
724
+ file_name = sprintf("frame_%0#{fd}d", actual_frames[frame_index])
725
+ # g.gnuplot; gets; g.close
726
+ # ep folder + file_name + '.png'; gets
727
+ g.gnuplot_write(folder + file_name + extension, size: options[:size])
728
+ end
729
+ end
730
+ end
731
+ eputs "Waiting on subprocesses..."
732
+ Process.waitall
733
+ end
734
+ unless options[:skip_encoding]
735
+ eputs "making film"
736
+ frame_rate = (options[:frame_rate] or options[:fr] || 15)
737
+ film_name = (options[:film_name] or options [:fn] or graphkit_frame_array[0][1].file_name + '_film').gsub(/\s/, '_')
738
+ puts `ffmpeg -y #{options[:bitrate] ? "-b #{options[:bitrate]}" : ""} -r #{frame_rate} -threads #{(@multiple_processes or 1)} -i film_frames/frame_%0#{fd}d#{extension} -sameq #{film_name}.mp4`
739
+ end
740
+ end
741
+
742
+
743
+ end
744
+