coderunner 0.11.0

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