cdo 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/gemspec +3 -1
- data/lib/cdo.rb +67 -28
- data/test/test_cdo.rb +147 -90
- metadata +31 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0405bd1a58c7c4342a4f921157849396a67d4c56
|
4
|
+
data.tar.gz: '09fe64c812dad7b1b63ff25abeee1d2a9de5a8cc'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45d2c037d3956bb1da49ebbc53e9be594af2d206fa85a268e20e5a03d0df3aa0deb168af00f9776c96f815222f11f71320e84366e58cdb33e3c9542e7ef79a8c
|
7
|
+
data.tar.gz: 528faea8e6188b8908ae7d7b4327da8d1cd130f893cd86aa8c6e6b99afd1cbf55e72597d5d50b7d5cdc195e2daf8ebab04e924d7d049d3b708c678b5a0905196
|
data/gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
|
3
3
|
|
4
4
|
spec = Gem::Specification.new do |s|
|
5
5
|
s.name = "cdo"
|
6
|
-
s.version = '1.3.
|
6
|
+
s.version = '1.3.3'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.files = ["lib/cdo.rb","lib/cdo_lib.rb"] + ["gemspec","LICENSE"]
|
9
9
|
s.test_file = "test/test_cdo.rb"
|
@@ -15,6 +15,8 @@ spec = Gem::Specification.new do |s|
|
|
15
15
|
s.license = "GPLv2"
|
16
16
|
s.required_ruby_version = ">= 1.9"
|
17
17
|
s.add_development_dependency('unifiedPlot')
|
18
|
+
s.add_development_dependency('minitest')
|
19
|
+
s.add_development_dependency('rake')
|
18
20
|
end
|
19
21
|
|
20
22
|
# vim:ft=ruby
|
data/lib/cdo.rb
CHANGED
@@ -4,9 +4,10 @@ require 'logger'
|
|
4
4
|
require 'stringio'
|
5
5
|
|
6
6
|
class Cdo
|
7
|
-
OutputOperatorsPattern = /(diff|info|output|griddes|zaxisdes|show|ncode|ndate|nlevel|nmon|nvar|nyear|ntime|npar|gradsdes|pardes)/
|
8
7
|
|
9
|
-
|
8
|
+
# hardcoded fallback list of output operators - from 1.8.0 there is an
|
9
|
+
# options for this: --operators_no_output
|
10
|
+
NoOutputOperators = %w[cdiread cmor codetab conv_cmor_table diff diffc diffn diffp
|
10
11
|
diffv dump_cmor_table dumpmap filedes ggstat ggstats gmtcells gmtxyz gradsdes
|
11
12
|
griddes griddes2 gridverify info infoc infon infop infos infov map ncode
|
12
13
|
ncode ndate ngridpoints ngrids nlevel nmon npar ntime nvar nyear output
|
@@ -16,7 +17,7 @@ class Cdo
|
|
16
17
|
partab2 seinfo seinfoc seinfon seinfop showcode showdate showformat showlevel
|
17
18
|
showltype showmon showname showparam showstdname showtime showtimestamp
|
18
19
|
showunit showvar showyear sinfo sinfoc sinfon sinfop sinfov
|
19
|
-
spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
20
|
+
spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
20
21
|
|
21
22
|
attr_accessor :cdo, :returnCdf, :forceOutput, :env, :debug, :logging, :logFile
|
22
23
|
attr_reader :operators, :filetypes
|
@@ -34,11 +35,12 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
34
35
|
# setup path to cdo executable
|
35
36
|
@cdo = ENV.has_key?('CDO') ? ENV['CDO'] : cdo
|
36
37
|
|
37
|
-
@operators = getOperators(
|
38
|
+
@operators = getOperators(@cdo)
|
38
39
|
@returnCdf = returnCdf
|
39
40
|
@forceOutput = forceOutput
|
40
41
|
@env = env
|
41
42
|
@debug = ENV.has_key?('DEBUG') ? true : debug
|
43
|
+
@noOutputOperators = getNoOuputOperators(@cdo)
|
42
44
|
@returnNilOnError = returnNilOnError
|
43
45
|
|
44
46
|
@filetypes = getFiletypes
|
@@ -76,7 +78,7 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
76
78
|
exit
|
77
79
|
end
|
78
80
|
|
79
|
-
@operators = help[(help.index("Operators:")+1)..help.index(help.find {|v| v =~ /CDO version/}) - 2].join(' ').split
|
81
|
+
@operators = help[(help.index("Operators:")+1)..help.index(help.find {|v| v =~ /CDO version/ }) - 2].join(' ').split
|
80
82
|
else
|
81
83
|
cmd = "#{path2cdo} --operators"
|
82
84
|
|
@@ -84,6 +86,15 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
89
|
+
def getNoOuputOperators(path2cdo)
|
90
|
+
if version > '1.8.0' then
|
91
|
+
puts 'CMD:'+path2cdo+' --operators_no_output' if @debug
|
92
|
+
IO.popen(path2cdo+' --operators_no_output').readlines.map{|line| line.split(' ')[0]}.flatten
|
93
|
+
else
|
94
|
+
NoOutputOperators
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
87
98
|
# get supported IO filetypes form the binary
|
88
99
|
def getFiletypes
|
89
100
|
_, _, stderr, _ = Open3.popen3(@cdo + " -V")
|
@@ -92,7 +103,6 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
92
103
|
supported.grep(/(Filetypes)/)[0].split(':')[1].split.map(&:downcase)
|
93
104
|
end
|
94
105
|
|
95
|
-
|
96
106
|
# Execute the given cdo call and return all outputs
|
97
107
|
def _call(cmd,env={})
|
98
108
|
@logger.info(cmd+"\n") if @logging
|
@@ -136,7 +146,17 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
136
146
|
end
|
137
147
|
|
138
148
|
# command execution wrapper, which handles the possible return types
|
139
|
-
def _run(
|
149
|
+
def _run(operatorName,
|
150
|
+
operatorParameters,
|
151
|
+
input: nil,
|
152
|
+
output: nil,
|
153
|
+
options: nil,
|
154
|
+
returnCdf: false,
|
155
|
+
force: nil,
|
156
|
+
returnArray: nil,
|
157
|
+
returnMaArray: nil,
|
158
|
+
env: nil,
|
159
|
+
autoSplit: nil)
|
140
160
|
options = options.to_s
|
141
161
|
|
142
162
|
options << '-f nc' if options.empty? and ( \
|
@@ -144,16 +164,23 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
144
164
|
( not returnArray.nil? ) or \
|
145
165
|
( not returnMaArray.nil?) \
|
146
166
|
)
|
147
|
-
|
167
|
+
#
|
168
|
+
# setup basic operator execution command
|
169
|
+
cmd = "#{@cdo} -O #{options} -#{operatorName}#{operatorParameters} #{input} "
|
148
170
|
|
149
171
|
# use an empty hash for non-given environment
|
150
172
|
env = {} if env.nil?
|
151
173
|
|
152
|
-
case
|
174
|
+
case output
|
153
175
|
when $stdout
|
154
176
|
retvals = _call(cmd,env)
|
155
177
|
unless _hasError(cmd,retvals)
|
156
|
-
|
178
|
+
_output = retvals[:stdout].split($/).map {|l| l.chomp.strip}
|
179
|
+
unless autoSplit.nil?
|
180
|
+
_output.map! {|line| line.split(autoSplit)}
|
181
|
+
_output = _output[0] if 1 == _output.size
|
182
|
+
end
|
183
|
+
return _output
|
157
184
|
else
|
158
185
|
if @returnNilOnError then
|
159
186
|
return nil
|
@@ -163,10 +190,15 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
163
190
|
end
|
164
191
|
else
|
165
192
|
force = @forceOutput if force.nil?
|
166
|
-
if force or not File.exists?(
|
167
|
-
|
168
|
-
|
193
|
+
if force or not File.exists?(output.to_s)
|
194
|
+
# create a tempfile if output is not given
|
195
|
+
output = MyTempfile.path if output.nil?
|
196
|
+
|
197
|
+
#finalize the execution command
|
198
|
+
cmd << "#{output}"
|
199
|
+
|
169
200
|
retvals = _call(cmd,env)
|
201
|
+
|
170
202
|
if _hasError(cmd,retvals)
|
171
203
|
if @returnNilOnError then
|
172
204
|
return nil
|
@@ -175,18 +207,20 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
175
207
|
end
|
176
208
|
end
|
177
209
|
else
|
178
|
-
warn "Use existing file '#{
|
210
|
+
warn "Use existing file '#{output}'" if @debug
|
179
211
|
end
|
180
212
|
end
|
181
213
|
|
182
214
|
if not returnArray.nil?
|
183
|
-
readArray(
|
215
|
+
readArray(output,returnArray)
|
184
216
|
elsif not returnMaArray.nil?
|
185
|
-
readMaArray(
|
217
|
+
readMaArray(output,returnMaArray)
|
186
218
|
elsif returnCdf or @returnCdf
|
187
|
-
readCdf(
|
219
|
+
readCdf(output)
|
220
|
+
elsif /^split/.match(operatorName)
|
221
|
+
Dir.glob("#{output}*")
|
188
222
|
else
|
189
|
-
|
223
|
+
output
|
190
224
|
end
|
191
225
|
end
|
192
226
|
|
@@ -196,19 +230,21 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
196
230
|
# [opt1,...,optN,:input => iStream,:output => oStream, :options => ' ']
|
197
231
|
# where iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
|
198
232
|
def method_missing(sym, *args, &block)
|
199
|
-
|
233
|
+
operatorName = sym.to_s
|
234
|
+
puts "Operator #{operatorName} is called" if @debug
|
200
235
|
|
201
|
-
|
202
|
-
|
203
|
-
if OutputOperators.include?(sym.to_s)
|
204
|
-
_run(" -#{sym.to_s}#{opts} #{io[:input]} ",$stdout,nil,nil,nil,nil,nil,env)
|
205
|
-
else
|
206
|
-
_run(" -#{sym.to_s}#{opts} #{io[:input]} ",io[:output],io[:options],io[:returnCdf],io[:force],io[:returnArray],io[:returnMaArray],io[:env])
|
207
|
-
end
|
208
|
-
else
|
236
|
+
# exit eary on missing operator
|
237
|
+
unless @operators.include?(operatorName)
|
209
238
|
return false if @returnFalseOnError
|
210
|
-
raise ArgumentError,"Operator #{
|
239
|
+
raise ArgumentError,"Operator #{operatorName} not found"
|
211
240
|
end
|
241
|
+
|
242
|
+
io, operatorParameters = Cdo.parseArgs(args)
|
243
|
+
|
244
|
+
# mark calls for operators without output files
|
245
|
+
io[:output] = $stdout if @noOutputOperators.include?(operatorName)
|
246
|
+
|
247
|
+
_run(operatorName,operatorParameters,io)
|
212
248
|
end
|
213
249
|
|
214
250
|
# load the netcdf bindings
|
@@ -297,6 +333,9 @@ spartab specinfo tinfo vardes vct vct2 verifygrid vlist zaxisdes]
|
|
297
333
|
end
|
298
334
|
end
|
299
335
|
|
336
|
+
def noOutputOps
|
337
|
+
getNoOuputOperators(@cdo)
|
338
|
+
end
|
300
339
|
# }}}
|
301
340
|
|
302
341
|
# Addional operators: {{{
|
data/test/test_cdo.rb
CHANGED
@@ -2,7 +2,6 @@ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
|
2
2
|
|
3
3
|
require 'minitest/autorun'
|
4
4
|
require 'cdo'
|
5
|
-
require 'unifiedPlot'
|
6
5
|
require 'pp'
|
7
6
|
|
8
7
|
|
@@ -30,7 +29,8 @@ class TestCdo < Minitest::Test
|
|
30
29
|
end
|
31
30
|
newCDO="#{ENV['HOME']}/local/bin/cdo-dev"
|
32
31
|
if File.exist?(newCDO) then
|
33
|
-
cdo = Cdo.new
|
32
|
+
cdo = Cdo.new
|
33
|
+
cdo.cdo = newCDO
|
34
34
|
assert_equal(true,cdo.check)
|
35
35
|
assert_equal(newCDO,cdo.cdo)
|
36
36
|
end
|
@@ -69,7 +69,7 @@ class TestCdo < Minitest::Test
|
|
69
69
|
end
|
70
70
|
def test_CDO_version
|
71
71
|
assert("1.4.3.1" < @cdo.version,"Version too low: #{@cdo.version}")
|
72
|
-
assert("1.8.
|
72
|
+
assert("1.8.1" > @cdo.version,"Version too high: #{@cdo.version}")
|
73
73
|
end
|
74
74
|
def test_args
|
75
75
|
ofile0 = @cdo.stdatm(0,20,40,80,200,230,400,600,1100)
|
@@ -112,50 +112,6 @@ class TestCdo < Minitest::Test
|
|
112
112
|
@cdo.thicknessOfLevels(:input => ofile))
|
113
113
|
end
|
114
114
|
|
115
|
-
def test_combine
|
116
|
-
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
117
|
-
@cdo.fldsum(:input => @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc"),:output => ofile0)
|
118
|
-
@cdo.fldsum(:input => "-stdatm,25,100,250,500,875,1400,2100,3000,4000,5000",:options => "-f nc",:output => ofile1)
|
119
|
-
@cdo.returnCdf = true
|
120
|
-
MyTempfile.showFiles
|
121
|
-
diff = @cdo.sub(:input => [ofile0,ofile1].join(' ')).var('T').get
|
122
|
-
assert_equal(0.0,diff.min)
|
123
|
-
assert_equal(0.0,diff.max)
|
124
|
-
@cdo.returnCdf = false
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_tempfile
|
128
|
-
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
129
|
-
assert(ofile0 != ofile1, "Found equal tempfiles!")
|
130
|
-
# Tempfile should not disappeare even if the GC was started
|
131
|
-
puts ofile0
|
132
|
-
assert(File.exist?(ofile0))
|
133
|
-
GC.start
|
134
|
-
assert(File.exist?(ofile0))
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_returnCdf
|
138
|
-
ofile = rand(0xfffff).to_s + '_test_returnCdf.nc'
|
139
|
-
vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
|
140
|
-
assert_equal(ofile,vals)
|
141
|
-
@cdo.returnCdf = true
|
142
|
-
vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
|
143
|
-
assert_equal(["lon","lat","level","P","T"],vals.var_names)
|
144
|
-
assert_equal(276,vals.var("T").get.flatten.mean.floor)
|
145
|
-
@cdo.returnCdf = false
|
146
|
-
vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
|
147
|
-
assert_equal(ofile,vals)
|
148
|
-
FileUtils.rm(ofile)
|
149
|
-
end
|
150
|
-
def test_simple_returnCdf
|
151
|
-
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
152
|
-
sum = @cdo.fldsum(:input => @cdo.stdatm(0,:options => "-f nc"),
|
153
|
-
:returnCdf => true).var("P").get
|
154
|
-
assert_equal(1013.25,sum.min)
|
155
|
-
sum = @cdo.fldsum(:input => @cdo.stdatm(0,:options => "-f nc"),:output => ofile0)
|
156
|
-
assert_equal(ofile0,sum)
|
157
|
-
test_returnCdf
|
158
|
-
end
|
159
115
|
def test_force
|
160
116
|
outs = []
|
161
117
|
# tempfiles
|
@@ -204,10 +160,33 @@ class TestCdo < Minitest::Test
|
|
204
160
|
assert_equal(targetThicknesses, @cdo.thicknessOfLevels(:input => "-selname,T -stdatm,#{levels.join(',')}"))
|
205
161
|
end
|
206
162
|
|
207
|
-
def
|
163
|
+
def test_outputOperators
|
208
164
|
sourceLevels = %W{25 100 250 500 875 1400 2100 3000 4000 5000}
|
209
165
|
assert_equal(sourceLevels,
|
210
166
|
@cdo.showlevel(:input => "-selname,T #{@cdo.stdatm(*sourceLevels,:options => '-f nc')}")[0].split)
|
167
|
+
|
168
|
+
# test autoSplit usage
|
169
|
+
levels = @cdo.showlevel(input: "-stdatm,0,10,20",autoSplit: ' ')
|
170
|
+
assert_equal([['0','10','20'],['0','10','20']],levels)
|
171
|
+
assert_equal(sourceLevels,
|
172
|
+
@cdo.showlevel(:input => "-selname,T #{@cdo.stdatm(*sourceLevels,:options => '-f nc')}",
|
173
|
+
:autoSplit => ' '))
|
174
|
+
|
175
|
+
timesExpected = ['2001-01-01T12:00:00',
|
176
|
+
'2001-01-01T13:00:00',
|
177
|
+
'2001-01-01T14:00:00',
|
178
|
+
'2001-01-01T15:00:00',
|
179
|
+
'2001-01-01T16:00:00',
|
180
|
+
'2001-01-01T17:00:00',
|
181
|
+
'2001-01-01T18:00:00',
|
182
|
+
'2001-01-01T19:00:00',
|
183
|
+
'2001-01-01T20:00:00',
|
184
|
+
'2001-01-01T21:00:00']
|
185
|
+
assert_equal(timesExpected,
|
186
|
+
@cdo.showtimestamp(input: "-settaxis,2001-01-01,12:00,1hour -for,1,10", autoSplit: ' '))
|
187
|
+
|
188
|
+
assert_equal(['P T'],@cdo.showname(input: "-stdatm,0"))
|
189
|
+
assert_equal(['P','T'],@cdo.showname(input: "-stdatm,0",autoSplit: ' '))
|
211
190
|
end
|
212
191
|
|
213
192
|
def test_verticalLevels
|
@@ -219,44 +198,13 @@ class TestCdo < Minitest::Test
|
|
219
198
|
end
|
220
199
|
|
221
200
|
def test_parseArgs
|
222
|
-
io,opts = Cdo.parseArgs([1,2,3,:input => '1',:output => '2',:force => true,:returnCdf => "T"])
|
201
|
+
io,opts = Cdo.parseArgs([1,2,3,:input => '1',:output => '2',:force => true,:returnCdf => "T",:autoSplit => ' '])
|
223
202
|
assert_equal("1",io[:input])
|
224
203
|
assert_equal("2",io[:output])
|
225
204
|
assert_equal(true,io[:force])
|
226
205
|
assert_equal("T",io[:returnCdf])
|
206
|
+
assert_equal(" ",io[:autoSplit])
|
227
207
|
pp [io,opts]
|
228
|
-
end
|
229
|
-
|
230
|
-
def test_returnArray
|
231
|
-
temperature = @cdo.stdatm(0,:options => '-f nc',:returnCdf => true).var('T').get.flatten[0]
|
232
|
-
assert_raises ArgumentError do
|
233
|
-
@cdo.stdatm(0,:options => '-f nc',:returnArray => 'TT')
|
234
|
-
end
|
235
|
-
temperature = @cdo.stdatm(0,:options => '-f nc',:returnArray => 'T')
|
236
|
-
assert_equal(288.0,temperature.flatten[0])
|
237
|
-
pressure = @cdo.stdatm(0,1000,:options => '-f nc -b F64',:returnArray => 'P')
|
238
|
-
assert_equal("1013.25 898.543456035875",pressure.flatten.to_a.join(' '))
|
239
|
-
end
|
240
|
-
def test_returnMaArray
|
241
|
-
@cdo.debug = true
|
242
|
-
topo = @cdo.topo(:options => '-f nc',:returnMaArray => 'topo')
|
243
|
-
assert_equal(-1890.0,topo.mean.round)
|
244
|
-
bathy = @cdo.setrtomiss(0,10000,
|
245
|
-
:input => @cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
|
246
|
-
assert_equal(-3386.0,bathy.mean.round)
|
247
|
-
oro = @cdo.setrtomiss(-10000,0,
|
248
|
-
:input => @cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
|
249
|
-
assert_equal(1142.0,oro.mean.round)
|
250
|
-
bathy = @cdo.remapnn('r2x2',:input => @cdo.topo(:options => '-f nc'), :returnMaArray => 'topo')
|
251
|
-
assert_equal(-4298.0,bathy[0,0])
|
252
|
-
assert_equal(-2669.0,bathy[1,0])
|
253
|
-
ta = @cdo.remapnn('r2x2',:input => @cdo.topo(:options => '-f nc'))
|
254
|
-
tb = @cdo.subc(-2669.0,:input => ta)
|
255
|
-
withMask = @cdo.div(:input => ta+" "+tb,:returnMaArray => 'topo')
|
256
|
-
assert(-8.0e+33 > withMask[1,0])
|
257
|
-
assert(0 < withMask[0,0])
|
258
|
-
assert(0 < withMask[0,1])
|
259
|
-
assert(0 < withMask[1,1])
|
260
208
|
end
|
261
209
|
|
262
210
|
def test_errorException
|
@@ -302,7 +250,7 @@ class TestCdo < Minitest::Test
|
|
302
250
|
end
|
303
251
|
|
304
252
|
def test_filetypes
|
305
|
-
assert(@cdo.filetypes.
|
253
|
+
assert(@cdo.filetypes.find{|ft| /^grb/.match(ft)},"GRIB support missing")
|
306
254
|
assert(@cdo.filetypes.include?("nc4"),"NETCDF4 support missing")
|
307
255
|
assert(@cdo.filetypes.include?("ext"),"EXTRA support missing")
|
308
256
|
assert_raises ArgumentError do
|
@@ -310,12 +258,121 @@ class TestCdo < Minitest::Test
|
|
310
258
|
end
|
311
259
|
end
|
312
260
|
|
261
|
+
def test_noOutputOps
|
262
|
+
case
|
263
|
+
when "1.8.0" == @cdo.version then
|
264
|
+
assert_equal(Cdo::NoOutputOperators,@cdo.noOutputOps)
|
265
|
+
when "1.8.0" < @cdo.version
|
266
|
+
assert((Cdo::NoOutputOperators - @cdo.noOutputOps).empty?)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
313
270
|
def test_output_set_to_nil
|
314
271
|
assert_equal(String,@cdo.topo(:output => nil).class)
|
315
272
|
assert_equal("File format: GRIB".tr(' ',''),@cdo.sinfov(:input => "-topo", :output => nil)[0].tr(' ',''))
|
316
273
|
end
|
317
274
|
|
275
|
+
def test_splitOps
|
276
|
+
pattern = 'stdAtm'
|
277
|
+
resultsFiles = @cdo.splitname(input: '-stdatm,0',output: pattern)
|
278
|
+
assert_equal(2,resultsFiles.size)
|
279
|
+
%w[T P].each {|var|
|
280
|
+
assert(resultsFiles.include?("#{pattern}#{var}.grb"))
|
281
|
+
}
|
282
|
+
|
283
|
+
pattern = 'sel'
|
284
|
+
resultsFiles = @cdo.splitsel(1,input: '-for,0,9',output: pattern)
|
285
|
+
assert_equal(10,resultsFiles.size)
|
286
|
+
(0..9).each {|var|
|
287
|
+
assert(resultsFiles.include?("#{pattern}00000#{var}.grb"))
|
288
|
+
}
|
289
|
+
|
290
|
+
pattern = 'lev'
|
291
|
+
resultsFiles = @cdo.splitlevel(input: '-stdatm,100,2000,5000',output: pattern)
|
292
|
+
assert_equal(3,resultsFiles.size)
|
293
|
+
%w[0100 2000 5000].each {|var|
|
294
|
+
assert(resultsFiles.include?("#{pattern}00#{var}.grb"))
|
295
|
+
}
|
296
|
+
end
|
297
|
+
|
318
298
|
if @@maintainermode then
|
299
|
+
require 'unifiedPlot'
|
300
|
+
|
301
|
+
def test_returnArray
|
302
|
+
temperature = @cdo.stdatm(0,:options => '-f nc',:returnCdf => true).var('T').get.flatten[0]
|
303
|
+
assert_raises ArgumentError do
|
304
|
+
@cdo.stdatm(0,:options => '-f nc',:returnArray => 'TT')
|
305
|
+
end
|
306
|
+
temperature = @cdo.stdatm(0,:options => '-f nc',:returnArray => 'T')
|
307
|
+
assert_equal(288.0,temperature.flatten[0])
|
308
|
+
pressure = @cdo.stdatm(0,1000,:options => '-f nc -b F64',:returnArray => 'P')
|
309
|
+
assert_equal("1013.25 898.543456035875",pressure.flatten.to_a.join(' '))
|
310
|
+
end
|
311
|
+
def test_returnMaArray
|
312
|
+
@cdo.debug = true
|
313
|
+
topo = @cdo.topo(:options => '-f nc',:returnMaArray => 'topo')
|
314
|
+
assert_equal(-1890.0,topo.mean.round)
|
315
|
+
bathy = @cdo.setrtomiss(0,10000,
|
316
|
+
:input => @cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
|
317
|
+
assert_equal(-3386.0,bathy.mean.round)
|
318
|
+
oro = @cdo.setrtomiss(-10000,0,
|
319
|
+
:input => @cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
|
320
|
+
assert_equal(1142.0,oro.mean.round)
|
321
|
+
bathy = @cdo.remapnn('r2x2',:input => @cdo.topo(:options => '-f nc'), :returnMaArray => 'topo')
|
322
|
+
assert_equal(-4298.0,bathy[0,0])
|
323
|
+
assert_equal(-2669.0,bathy[1,0])
|
324
|
+
ta = @cdo.remapnn('r2x2',:input => @cdo.topo(:options => '-f nc'))
|
325
|
+
tb = @cdo.subc(-2669.0,:input => ta)
|
326
|
+
withMask = @cdo.div(:input => ta+" "+tb,:returnMaArray => 'topo')
|
327
|
+
assert(-8.0e+33 > withMask[1,0])
|
328
|
+
assert(0 < withMask[0,0])
|
329
|
+
assert(0 < withMask[0,1])
|
330
|
+
assert(0 < withMask[1,1])
|
331
|
+
end
|
332
|
+
def test_combine
|
333
|
+
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
334
|
+
@cdo.fldsum(:input => @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc"),:output => ofile0)
|
335
|
+
@cdo.fldsum(:input => "-stdatm,25,100,250,500,875,1400,2100,3000,4000,5000",:options => "-f nc",:output => ofile1)
|
336
|
+
@cdo.returnCdf = true
|
337
|
+
MyTempfile.showFiles
|
338
|
+
diff = @cdo.sub(:input => [ofile0,ofile1].join(' ')).var('T').get
|
339
|
+
assert_equal(0.0,diff.min)
|
340
|
+
assert_equal(0.0,diff.max)
|
341
|
+
@cdo.returnCdf = false
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_tempfile
|
345
|
+
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
346
|
+
assert(ofile0 != ofile1, "Found equal tempfiles!")
|
347
|
+
# Tempfile should not disappeare even if the GC was started
|
348
|
+
puts ofile0
|
349
|
+
assert(File.exist?(ofile0))
|
350
|
+
GC.start
|
351
|
+
assert(File.exist?(ofile0))
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_returnCdf
|
355
|
+
ofile = rand(0xfffff).to_s + '_test_returnCdf.nc'
|
356
|
+
vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
|
357
|
+
assert_equal(ofile,vals)
|
358
|
+
@cdo.returnCdf = true
|
359
|
+
vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
|
360
|
+
assert_equal(["lon","lat","level","P","T"],vals.var_names)
|
361
|
+
assert_equal(276,vals.var("T").get.flatten.mean.floor)
|
362
|
+
@cdo.returnCdf = false
|
363
|
+
vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
|
364
|
+
assert_equal(ofile,vals)
|
365
|
+
FileUtils.rm(ofile)
|
366
|
+
end
|
367
|
+
def test_simple_returnCdf
|
368
|
+
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
369
|
+
sum = @cdo.fldsum(:input => @cdo.stdatm(0,:options => "-f nc"),
|
370
|
+
:returnCdf => true).var("P").get
|
371
|
+
assert_equal(1013.25,sum.min)
|
372
|
+
sum = @cdo.fldsum(:input => @cdo.stdatm(0,:options => "-f nc"),:output => ofile0)
|
373
|
+
assert_equal(ofile0,sum)
|
374
|
+
test_returnCdf
|
375
|
+
end
|
319
376
|
def test_readCdf
|
320
377
|
input = "-settunits,days -setyear,2000 -for,1,4"
|
321
378
|
cdfFile = @cdo.copy(:options =>"-f nc",:input=>input)
|
@@ -464,7 +521,7 @@ end
|
|
464
521
|
# ths.each {|th| th.join}
|
465
522
|
# # another example with sub:
|
466
523
|
# @cdo.sub(:input => [oldfile,newfile].join(' '), :output => diff)
|
467
|
-
#
|
524
|
+
#
|
468
525
|
# # It is possible too use the 'send' method
|
469
526
|
# operator = /grb/.match(File.extname(ifile)) ? :showcode : :showname
|
470
527
|
# inputVars = @cdo.send(operator,:input => ifile)
|
@@ -478,7 +535,7 @@ end
|
|
478
535
|
# warn "Wrong usage of variable identifier for '#{var}' (class #{var.class})!"
|
479
536
|
# end
|
480
537
|
# @cdo.send(operator,var,:input => @ifile, :output => varfile)
|
481
|
-
#
|
538
|
+
#
|
482
539
|
# # Pass an array for operators with multiple options:
|
483
540
|
# # Perform conservative remapping with pregenerated weights
|
484
541
|
# @cdo.remap([gridfile,weightfile],:input => copyfile,:output => outfile)
|
@@ -486,7 +543,7 @@ end
|
|
486
543
|
# @cdo.ml2hl([0,20,50,100,200,400,800,1200].join(','),:input => hybridlayerfile, :output => reallayerfile)
|
487
544
|
# # or use multiple arguments directly
|
488
545
|
# @cdo.remapeta(vctfile,orofile,:input => ifile,:output => hybridlayerfile)
|
489
|
-
#
|
546
|
+
#
|
490
547
|
# # the powerfull expr operator:
|
491
548
|
# # taken from the tutorial in https://code.zmaw.de/projects/cdo/wiki/Tutorial#The-_expr_-Operator
|
492
549
|
# SCALEHEIGHT = 10000.0
|
@@ -494,12 +551,12 @@ end
|
|
494
551
|
# # function for later computation of hydrostatic atmosphere pressure
|
495
552
|
# PRES_EXPR = lambda {|height| "101325.0*exp((-1)*(1.602769777072154)*log((exp(#{height}/#{SCALEHEIGHT})*213.15+75.0)/288.15))"}
|
496
553
|
# TEMP_EXPR = lambda {|height| "213.0+75.0*exp(-#{height}/#{SCALEHEIGHT})"}
|
497
|
-
#
|
554
|
+
#
|
498
555
|
# # Create Pressure and Temperature out of a height field 'geopotheight' from ifile
|
499
556
|
# @cdo.expr("'p=#{PRES_EXPR['geopotheight']}'", :input => ifile, :output => presFile)
|
500
557
|
# @cdo.expr("'t=#{TEMP_EXPR['geopotheight']}'", :input => ifile, :output => tempFile)
|
501
|
-
#
|
502
|
-
#
|
558
|
+
#
|
559
|
+
#
|
503
560
|
# # TIPS: I often work with temporary files and for getting rid of handling them manually the MyTempfile module can be used:
|
504
561
|
# # Simply include the following methods into you scripts and use tfile for any temporary variable
|
505
562
|
# def tfile
|
@@ -510,8 +567,8 @@ end
|
|
510
567
|
# @cdo.expr("'p=#{PRES_EXPR['geopotheight']}'", :input => ifile, :output => presFile)
|
511
568
|
# @cdo.expr("'t=#{TEMP_EXPR['geopotheight']}'", :input => ifile, :output => tempFile)
|
512
569
|
# @cdo.chainCall("setname,#{rho} -divc,#{C_R} -div",in: [presFile,tempFile].join(' '), out: densityFile)
|
513
|
-
#
|
570
|
+
#
|
514
571
|
# # For debugging, it is helpfull, to avoid the automatic cleanup at the end of the scripts:
|
515
572
|
# MyTempfile.setPersist(true)
|
516
|
-
# # creates randomly names files. Switch on debugging with
|
573
|
+
# # creates randomly names files. Switch on debugging with
|
517
574
|
# @cdo.Debug = true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cdo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ralf Mueller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: unifiedPlot
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
description: Easy access to the Climate Data operators
|
28
56
|
email: stark.dreamdetective@gmail.com
|
29
57
|
executables: []
|
@@ -55,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
83
|
version: '0'
|
56
84
|
requirements: []
|
57
85
|
rubyforge_project:
|
58
|
-
rubygems_version: 2.
|
86
|
+
rubygems_version: 2.6.8
|
59
87
|
signing_key:
|
60
88
|
specification_version: 4
|
61
89
|
summary: Easy access to the Climate Data operators
|