tokfile 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 56d00d7bbe51b7d1ca893cabb57159cac8d096da
4
- data.tar.gz: d527953a54706db2426433aa326bd10de322cd99
3
+ metadata.gz: 3683172314a29647ad38abf97453fc714f38b546
4
+ data.tar.gz: 426fad8bfc5dff6b42dbc3a66b16e1909e1f30ee
5
5
  SHA512:
6
- metadata.gz: 7574e494bc4e413d32066777ea8d0beb1eda38bb44f818944fa362bfd3bf83a203899eb11ade69baa5ecdb7a2de54a174b304d2b387318c11412a556dac19778
7
- data.tar.gz: 00732176b38419bf2395a99832dc179d0e8ff1ee4cbab1d94d79e4aef1c55db6e11443dcf0ed50e38729f59248b9637624036fd93eaaab8c23a6ef6271a4004e
6
+ metadata.gz: 6479a42f64a2bf13ec6d0e908a8d6760c0ec9808b38d946f2d5d62a5531ebfb11d26342c702c543eddda64b825d6415157465dde38a1aa3adc27ec133bf2243a
7
+ data.tar.gz: 219c554c4673e79074dd407bd7625a7b0f4a182a7b15034f52632c6772d7f21b428911e5896382becfa308a8a6c86ddbd7baf3a1e59cc669a6caa0990fb47a69
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  gem "coderunner", ">= 0.14.13"
5
+ gem "graphkit", ">= 0.3.3"
6
+ gem 'command-line-flunky', ">=1.0.0"
5
7
 
6
8
  # Add dependencies to develop your gem here.
7
9
  # Include everything needed to run rake, tests, features, etc.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'tokfile'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'tokfile'
8
+ end
9
+
10
+ CommandLineFlunky.run_script
@@ -0,0 +1,111 @@
1
+
2
+ # A tool for reading, manipulating and converting files containing
3
+ # tokamak data.
4
+
5
+ require 'getoptlong'
6
+
7
+ module CommandLineFlunky
8
+
9
+ STARTUP_MESSAGE = "\n------Tokamak File Utility (c) Edmund Highcock------"
10
+
11
+ MANUAL_HEADER = <<EOF
12
+
13
+ -------------Tokamak File Utility Manual---------------
14
+
15
+ Written by Edmund Highcock (2014)
16
+
17
+ NAME
18
+
19
+ tokfile
20
+
21
+
22
+ SYNOPSIS
23
+
24
+ tokfile <command> [arguments] [options]
25
+
26
+
27
+ DESCRIPTION
28
+
29
+ Convert, manipulate and display files containing tokamak-like data, for example
30
+ EQDSK, tokamak profile database, iterdb output files from one-two etc.
31
+
32
+ EXAMPLES
33
+
34
+ $ tokfile convert EQDSK ogyropsi.dat -f eqdsk,ogyropsi
35
+
36
+ $ tokfile merge ogyropsi.dat,ogyropsi2.dat ogyropsi3.dat -f ogyropsi -m profiles,geometry
37
+
38
+ $ tokfile disp EQDSK -f eqdsk
39
+
40
+
41
+ EOF
42
+
43
+ COMMANDS_WITH_HELP = [
44
+ ['convert', 'cv', 2, 'Convert files of one format into another. Not all file formats contain the same information. If information is missing from the input files, a warning will be printed and tokfile will attempt to fill in the gaps using sensible assumptions like Ti/Te = 1. More than one output file can be specified.', ['inputfile', 'outputfile(s)'], [:f, :t]],
45
+ ['display_summary_graph', 'disp', 1, 'Display a summary graph of the file using gnuplot.', ['inputfile',], [:f]],
46
+ ['merge', 'mg', 2, 'Merge data from two input files to create a single output file. ', ['inputfile', 'outputfile(s)'], [:f, :t, :m]],
47
+ ['write_summary_graph', 'wsg', 2, 'Write a summary graph of the file to disk using gnuplot. The file format is determined by the extension of the graph file', ['inputfile', 'graph file'], [:f,:w]],
48
+
49
+ ]
50
+
51
+ SUPPORTED_FORMATS = ['eqdsk', 'ogyropsi']
52
+ SUPPORTED_MERGE_SOURCES = ['profiles', 'geometry']
53
+
54
+
55
+ COMMAND_LINE_FLAGS_WITH_HELP = [
56
+ #['--boolean', '-b', GetoptLong::NO_ARGUMENT, 'A boolean option'],
57
+ ['--formats', '-f', GetoptLong::REQUIRED_ARGUMENT, "A list of formats pertaining to the various input and output files (in the order which they appear), separated by commas. If they are all the same, only one value may be given. If a value is left empty (i.e. there are two commas in a row) then the previous value will be used. Currently supported formats are #{SUPPORTED_FORMATS.inspect}. "],
58
+ ['--merge-sources', '-m', GetoptLong::REQUIRED_ARGUMENT, "A list of which bits of information should come from which input file during a merge. Currently supported merge sources are #{SUPPORTED_MERGE_SOURCES.inspect} "],
59
+ ['--modify-graph', '-w', GetoptLong::REQUIRED_ARGUMENT, "A string of Ruby code which is evaluated by the graphkit before the graph is displayed. Can be used for arbitrary manipulation of the graph. E.g. 'self.title=\"A graph\"; self.gp.logscale = \"y\"' "],
60
+
61
+ ]
62
+
63
+ LONG_COMMAND_LINE_OPTIONS = [
64
+ #["--no-short-form", "", GetoptLong::NO_ARGUMENT, %[This boolean option has no short form]],
65
+ ]
66
+
67
+ # specifying flag sets a bool to be true
68
+
69
+ CLF_BOOLS = []
70
+
71
+ CLF_INVERSE_BOOLS = [] # specifying flag sets a bool to be false
72
+
73
+ PROJECT_NAME = 'tokfile'
74
+
75
+ def self.method_missing(method, *args)
76
+ # p method, args
77
+ TokFile.send(method, *args)
78
+ end
79
+
80
+ #def self.setup(copts)
81
+ #CommandLineFlunkyTestUtility.setup(copts)
82
+ #end
83
+
84
+ SCRIPT_FILE = __FILE__
85
+ end
86
+
87
+ class TokFile
88
+ class << self
89
+ # This function gets called before every command
90
+ # and allows arbitrary manipulation of the command
91
+ # options (copts) hash
92
+ def setup(copts)
93
+ # None neededed
94
+ end
95
+ def verbosity
96
+ 2
97
+ end
98
+ end
99
+ end
100
+
101
+ $has_put_startup_message_for_code_runner = true
102
+ require 'coderunner'
103
+ require 'tokfile/commands'
104
+ require 'tokfile/eqdsk'
105
+ require 'tokfile/ogyropsi'
106
+
107
+ ######################################
108
+ # This must be at the end of the file
109
+ #
110
+ require 'command-line-flunky'
111
+ ###############################
@@ -0,0 +1,65 @@
1
+
2
+ class TokFile
3
+ class << self
4
+
5
+ #######################################
6
+ # Class methods that implement commands
7
+ #######################################
8
+
9
+ def display_summary_graph(inputfiles, copts)
10
+ summary_graphkit(inputfiles, copts).gnuplot
11
+ end
12
+
13
+ def merge(inputfiles, outputfile, copts)
14
+ inputfiles = inputfiles.split(/,/)
15
+ formats = copts[:f].split(/,/)
16
+ formsize = inputfiles.size + 1
17
+ case formats.size
18
+ when 1
19
+ formats = formats * formsize
20
+ when formsize
21
+ else
22
+ raise "Number of formats should be either 1 for all the same or #{formsize}"
23
+ end
24
+ raise "Please specify merges as a comma separated list" unless copts[:m].kind_of? String and copts[:m] =~ /,/
25
+ merges = copts[:m].split(/,/)
26
+ raise "Please specify the same number of merges as inputfiles" unless merges.size == inputfiles.size
27
+ output = file_object(outputfile, formats[inputfiles.size] )
28
+ inputfiles.each_with_index do |file,i|
29
+ input = file_object(file, formats[i])
30
+ output.read_data(input, merges[i], copts[:t])
31
+ end
32
+ output.write
33
+ end
34
+
35
+ def write_summary_graph(inputfiles, graphname, copts)
36
+ summary_graphkit(inputfiles, copts).gnuplot_write graphname
37
+ end
38
+
39
+ ###############################
40
+ # Other class methods
41
+ ###############################
42
+
43
+
44
+ def file_object(file, format)
45
+ case format
46
+ when 'eqdsk'
47
+ TokFile::Eqdsk.new(file)
48
+ when 'ogyropsi'
49
+ TokFile::Ogyropsi.new(file)
50
+ else
51
+ raise "Can't read this file format yet: #{format}"
52
+ end
53
+ end
54
+
55
+ def summary_graphkit(inputfiles, copts)
56
+ raise 'Only one format allowed for summary_graphkit ' if copts[:f] =~ /,/
57
+ inputfiles = inputfiles.split(',')
58
+ kit = inputfiles.map{|inputfile|
59
+ file_object(inputfile, copts[:f]).summary_graphkit
60
+ }.inject{|o,n| o.merge(n)}
61
+ kit.instance_eval(copts[:w]) if copts[:w]
62
+ kit
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,243 @@
1
+
2
+ class TokFile::Eqdsk
3
+ attr_accessor :nrbox, :nzbox
4
+ #attr_accessor :rboxlen, :zboxlen, :r0exp, :rboxlft
5
+ DATANAMES = [
6
+ :rboxlen, :zboxlen, :r0exp, :rboxlft, :dummy,
7
+ :raxis, :zaxis, :psiaxis, :dummy, :b0exp,
8
+ :current, :dummy, :dummy, :dummy, :dummy,
9
+ :dummy, :dummy, :dummy, :dummy, :dummy,
10
+ :t,
11
+ :pr,
12
+ :ttprime,
13
+ :pprime,
14
+ :psi,
15
+ :q,
16
+ :nbound, :nlimiter,
17
+ :bound,
18
+ #:limiter
19
+ ]
20
+ attr_accessor :rbound, :zbound, :rlimiter, :zlimiter
21
+
22
+ require 'scanf'
23
+ def read(line)
24
+ #@lines_columns[i] = @lines[i].split(/\s+|(?<=\d)[+-]/).map{|s| eval(s)}
25
+ line.sub(/\A\s+/, '').sub(/\s+\Z/, '').split(/\s+|(?<=\d)(?=[+-])/).map{|s| eval(s)}
26
+ #line.scan(/.{15}/).map{|s| eval(s)}
27
+
28
+ #ep ['line', line]
29
+ #arr = []
30
+ #res = line.scanf("%16.9E"){|n| arr.push n}
31
+ #line.scanf("%E"){|n| arr.push n[0]}
32
+ #ep ['res', res, arr]
33
+ #ep ['res', arr]
34
+ #arr
35
+
36
+ end
37
+
38
+
39
+ def initialize(file)
40
+
41
+ iline = 0
42
+ counter = 0
43
+
44
+ #filehandle = File.open(file, 'r')
45
+
46
+ lines = File.read(file).split("\n")
47
+ #@datastarts = DATANAMES.inject({}){|h, name| h[name] = nil; h}
48
+
49
+ #line1 = filehandle.gets
50
+ #@nrbox, @nzbox = filehandle.gets.split(/\s+/).slice(-2..-1).map{|s| eval(s)}
51
+ @nrbox, @nzbox = lines[0].split(/\s+/).slice(-2..-1).map{|s| eval(s)}
52
+ #@rboxlen, @zboxlen, @r0exp, @rboxlft, dummy = read(filehandle.gets)
53
+ #@raxis, @zaxis, @psiaxis, dummy, @b0exp = read(filehandle.gets)
54
+ #@current, dummy, dummy, dummy, dummy = read(filehandle.gets)
55
+ #dummy, dummy, dummy, dummy, dummy = read(filehandle.gets)
56
+ array = []
57
+ i = 1
58
+ vb2 = TokFile.verbosity > 1
59
+
60
+ if vb2
61
+ eputs
62
+ eputs "Reading data from eqdsk file #{file}."
63
+ eputs
64
+ end
65
+ total_size = 0
66
+ DATANAMES.each do |name|
67
+ sz = size(name)
68
+ total_size += sz
69
+ #ep ['name', name, 'size', sz]
70
+ if vb2
71
+ Terminal.erewind(1)
72
+ eputs "#{name}(#{sz})#{Terminal::CLEAR_LINE}" if vb2
73
+ end
74
+ if array.size < sz
75
+ #array += read(filehandle.gets)
76
+ #array += read(lines[i])
77
+ #i+=1
78
+ array += read(lines.slice(i...(i+=(sz.to_f/5.0).ceil)).join(' '))
79
+ #array += lines.slice(i...(i+=(sz.to_f/5.0).ceil)).join(' ')
80
+
81
+ #filehandle.gets.scanf("%e"){|scan| array.push scan[0]}
82
+ end
83
+ if array.size == sz
84
+ data = array
85
+ array = []
86
+ else
87
+ data = []
88
+ while data.size < sz
89
+ data.push array.shift
90
+ end
91
+ end
92
+ self.class.attr_accessor name
93
+ case name
94
+ when :psi
95
+ set(name, GSL::Matrix.alloc(*data.pieces(@nzbox)).transpose)
96
+ when :bound
97
+ data = data.pieces(@nbound).transpose
98
+ set(:rbound, data[0].to_gslv)
99
+ set(:zbound, data[1].to_gslv)
100
+ when :limiter
101
+ data = data.pieces(@nlimiter).transpose
102
+ set(:rlimiter, data[0].to_gslv)
103
+ set(:zlimiter, data[1].to_gslv)
104
+ else
105
+ case sz
106
+ when 1
107
+ set(name, data[0])
108
+ else
109
+ set(name, data.to_gslv)
110
+ end
111
+ end
112
+ end
113
+ @r = GSL::Vector.linspace(@rboxlft, @rboxlft+@rboxlen, @nrbox)
114
+ @z = GSL::Vector.linspace(-@zboxlen/2.0, @zboxlen/2.0, @nzbox)
115
+
116
+ if vb2
117
+ Terminal.erewind(1)
118
+ eputs "Read total data size of #{total_size.to_f * 8.0/1.0e6} MB"
119
+ end
120
+
121
+ if TokFile.verbosity > 0
122
+ eputs <<EOF
123
+ --------------------------------------
124
+ Tokfile
125
+ --------------------------------------
126
+ Successfully read an eqdsk file called
127
+ #{file}
128
+ with the following parameters:
129
+
130
+ nrbox = #@nrbox
131
+ nzbox = #@nzbox
132
+ nbound = #@nbound
133
+ raxis = #@raxis
134
+ --------------------------------------
135
+ EOF
136
+
137
+ end
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+ #@lines = File.read(file).split("\n").map{|str| str.sub(/\A\s+/, '').sub(/\s+\Z/, '')}
146
+ #@nrbox, @nzbox = @lines[0].split(/\s+/).slice(-2..-1).map{|s| eval(s)}
147
+ #in_data = true; i = 1
148
+ #@atoms = []
149
+ #@lines_columns = []
150
+ #while in_data
151
+ #@lines_columns[i] = @lines[i].split(/\s+|(?<=\d)[+-]/).map{|s| eval(s)}
152
+ #@atoms += @lines_columns[i]
153
+ #if @nbound = @atoms[start(:nbound)]
154
+ #if @atoms.size > start(:limiter)
155
+ #in_data = false
156
+ #end
157
+ #end
158
+ #i+=1
159
+ #end
160
+
161
+ #[:t, :p, :pprime, :ttprime, :psi, :q, :rzbound].each do |var|
162
+ #attr_accessor var
163
+ #st = start(var)
164
+ #set(var, @atoms.slice(st...(st+@nrbox))).to_gslv
165
+ #end
166
+
167
+
168
+ #@rboxlen, @zboxlen, @r0exp, @rboxlft, dummy = @lines_columns[1]
169
+ #ep ['lines_columns', @lines_columns[1], @lines[1]]
170
+
171
+
172
+ end
173
+ def summary_graphkit
174
+ psivec = GSL::Vector.linspace(@psi.min, 0.0, @nrbox)
175
+ multkit = GraphKit::MultiWindow.new([:pr, :pprime, :t, :ttprime, :q].map{|name|
176
+ kit = GraphKit.quick_create([psivec, send(name)])
177
+ kit.title = name.to_s
178
+ kit.ylabel = nil
179
+ kit.xlabel = 'psi'
180
+ kit
181
+ })
182
+ psikit = GraphKit.quick_create([@r, @z, @psi])
183
+ psikit.data[0].gp.with = 'pm3d'
184
+ psikit.gp.view = "map"
185
+ boundkit = GraphKit.quick_create([@rbound, @zbound, @rbound.collect{0.0}])
186
+ psikit += boundkit
187
+ psikit.gp.key = "off"
188
+ psikit.title = 'psi'
189
+ psikit.xlabel = 'R'
190
+ psikit.ylabel = 'Z'
191
+ multkit.push psikit
192
+ multkit.gp.multiplot = "layout 2,3"
193
+ multkit
194
+ end
195
+ def size(var)
196
+ case var
197
+ #when :nbound, :nlimiter
198
+ #1
199
+ when :bound
200
+ @nbound * 2
201
+ when :limiter
202
+ @nlimiter * 2
203
+ when :psi
204
+ @nrbox * @nzbox
205
+ when :t, :pr, :pprime, :ttprime, :q
206
+ @nrbox
207
+ else
208
+ 1
209
+ end
210
+ end
211
+
212
+ #def start(var)
213
+ #case var
214
+ #when :t
215
+ #20
216
+ #when :p
217
+ #start(:t) + @nrbox
218
+ #when :ttprime
219
+ #start(:p) + @nrbox
220
+ #when :pprime
221
+ #start(:ttprime) + @nrbox
222
+ #when :psi
223
+ #start(:pprime) + @nrbox
224
+ #when :q
225
+ #start(:psi) + @nrbox * @nzbox
226
+ #when :nbound
227
+ #start(:q) + @nrbox + 1
228
+ #when :rzbound
229
+ #start(:q) + @nrbox + 3
230
+ #when :limiter
231
+ #start(:rzbound) + @nbound * 2
232
+ #else
233
+ #raise "Start of #{var} unknown"
234
+ #end
235
+ #end
236
+
237
+
238
+ #def
239
+ #def get_int(line, col)
240
+ #end
241
+
242
+
243
+ end