cdo 1.2.7 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/gemspec +2 -2
  2. data/lib/cdo.rb +204 -279
  3. data/lib/cdo_lib.rb +415 -0
  4. data/test/test_cdo.rb +180 -181
  5. metadata +3 -3
  6. data/lib/cdo_oo.rb +0 -301
@@ -0,0 +1,415 @@
1
+ require 'pp'
2
+ require 'open3'
3
+ require 'logger'
4
+ require 'stringio'
5
+
6
+ # Copyright (C) 2011-2013 Ralf Mueller, ralf.mueller@zmaw.de
7
+ # See COPYING file for copying and redistribution conditions.
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation; version 2 of the License.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+
18
+ # ==============================================================================
19
+ # CDO calling mechnism
20
+ module Cdo
21
+
22
+ VERSION = "1.2.5"
23
+ @@file = StringIO.new
24
+
25
+ State = {
26
+ :debug => false,
27
+ :returnCdf => false,
28
+ :operators => [],
29
+ :forceOutput => true,
30
+ :env => {},
31
+ :log => false,
32
+ :logger => Logger.new(@@file),
33
+ }
34
+ State[:debug] = ENV.has_key?('DEBUG')
35
+ State[:logger].formatter = proc do |serverity, time, progname, msg|
36
+ msg
37
+ end
38
+
39
+ @@CDO = ENV['CDO'].nil? ? 'cdo' : ENV['CDO']
40
+
41
+ # Since cdo-1.5.4 undocumented operators are given with the -h option. For
42
+ # earlier version, they have to be provided manually
43
+ @@undocumentedOperators = %w[anomaly beta boxavg change_e5lsm change_e5mask
44
+ change_e5slm chisquare chvar cloudlayer cmd com command complextorect
45
+ covar0 covar0r daycount daylogs del29feb delday delete deltap deltap_fl
46
+ delvar diffv divcoslat dumplogo dumplogs duplicate eca_r1mm enlargegrid
47
+ ensrkhistspace ensrkhisttime eof3d eof3dspatial eof3dtime export_e5ml
48
+ export_e5res fc2gp fc2sp fillmiss fisher fldcovar fldrms fourier fpressure
49
+ gather gengrid geopotheight ggstat ggstats globavg gp2fc gradsdes
50
+ gridverify harmonic hourcount hpressure import_e5ml import_e5res
51
+ import_obs imtocomplex infos infov interpolate intgrid intgridbil
52
+ intgridtraj intpoint isosurface lmavg lmean lmmean lmstd log lsmean
53
+ meandiff2test mergegrid mod moncount monlogs mrotuv mrotuvb mulcoslat ncode
54
+ ncopy nmltest normal nvar outputbounds outputboundscpt outputcenter
55
+ outputcenter2 outputcentercpt outputkey outputtri outputvector outputvrml
56
+ pardup parmul pinfo pinfov pressure_fl pressure_hl read_e5ml remapcon1
57
+ remapdis1 retocomplex scalllogo scatter seascount select selgridname
58
+ seloperator selvar selzaxisname setrcaname setvar showvar sinfov smemlogo
59
+ snamelogo sort sortcode sortlevel sortname sorttaxis sorttimestamp sortvar
60
+ sp2fc specinfo spectrum sperclogo splitvar stimelogo studentt template1
61
+ template2 test test2 testdata thinout timcount timcovar tinfo transxy trms
62
+ tstepcount vardes vardup varmul varquot2test varrms vertwind write_e5ml
63
+ writegrid writerandom yearcount]
64
+
65
+ @@outputOperatorsPattern = /(diff|info|output|griddes|zaxisdes|show|ncode|ndate|nlevel|nmon|nvar|nyear|ntime|npar|gradsdes|pardes)/
66
+
67
+ private
68
+ def Cdo.getOperators(force=false)
69
+ # Do NOT compute anything, if it is not required
70
+ return State[:operators] unless (State[:operators].empty? or force)
71
+ cmd = @@CDO + ' 2>&1'
72
+ help = IO.popen(cmd).readlines.map {|l| l.chomp.lstrip}
73
+ if 5 >= help.size
74
+ warn "Operators could not get listed by running the CDO binary (#{@@CDO})"
75
+ pp help if Cdo.debug
76
+ exit
77
+ end
78
+ # in version 1.5.6 the output of '-h' has changed
79
+ State[:operators] = case
80
+ when Cdo.version < "1.5.6"
81
+ (help[help.index("Operators:")+1].split + @@undocumentedOperators).uniq
82
+ when Cdo.version <= "1.7.0"
83
+ help[(help.index("Operators:")+1)..help.index(help.find {|v| v =~ /CDO version/}) - 2].join(' ').split
84
+ else
85
+ IO.popen(@@CDO + ' --operators').readlines.map {|l| l.split(' ').first}
86
+ end
87
+ end
88
+
89
+ def Cdo.hasError(cmd,retvals)
90
+ if (State[:debug])
91
+ puts("RETURNCODE: #{retvals[:returncode]}")
92
+ end
93
+ if ( 0 != retvals[:returncode] )
94
+ puts("Error in calling:")
95
+ puts(">>> "+cmd+"<<<")
96
+ puts(retvals[:stderr])
97
+ return true
98
+ else
99
+ return false
100
+ end
101
+ end
102
+
103
+ def Cdo.env=(envHash)
104
+ State[:env] = envHash
105
+ end
106
+ def Cdo.env; State[:env]; end
107
+
108
+ def Cdo.call(cmd)
109
+ if (State[:debug])
110
+ puts '# DEBUG ====================================================================='
111
+ pp Cdo.env unless Cdo.env.empty?
112
+ puts 'CMD: '
113
+ puts cmd
114
+ puts '# DEBUG ====================================================================='
115
+ end
116
+ stdin, stdout, stderr, wait_thr = Open3.popen3(Cdo.env,cmd)
117
+
118
+ {
119
+ :stdout => stdout.read,
120
+ :stderr => stderr.read,
121
+ :returncode => wait_thr.value.exitstatus
122
+ }
123
+ end
124
+
125
+ def Cdo.run(cmd,ofile='',options='',returnCdf=false,force=nil,returnArray=nil,returnMaArray=nil)
126
+ cmd = "#{@@CDO} -O #{options} #{cmd} "
127
+ case ofile
128
+ when $stdout
129
+ retvals = Cdo.call(cmd)
130
+ State[:logger].info(cmd+"\n") if State[:log]
131
+ unless hasError(cmd,retvals)
132
+ return retvals[:stdout].split($/).map {|l| l.chomp.strip}
133
+ else
134
+ raise ArgumentError,"CDO did NOT run successfully!"
135
+ end
136
+ else
137
+ force = State[:forceOutput] if force.nil?
138
+ if force or not File.exists?(ofile.to_s)
139
+ ofile = MyTempfile.path if ofile.nil?
140
+ cmd << "#{ofile}"
141
+ retvals = call(cmd)
142
+ State[:logger].info(cmd+"\n") if State[:log]
143
+ if hasError(cmd,retvals)
144
+ raise ArgumentError,"CDO did NOT run successfully!"
145
+ end
146
+ else
147
+ warn "Use existing file '#{ofile}'" if Cdo.debug
148
+ end
149
+ end
150
+ if not returnArray.nil?
151
+ Cdo.readArray(ofile,returnArray)
152
+ elsif not returnMaArray.nil?
153
+ Cdo.readMaArray(ofile,returnMaArray)
154
+ elsif returnCdf or State[:returnCdf]
155
+ Cdo.readCdf(ofile)
156
+ else
157
+ return ofile
158
+ end
159
+ end
160
+
161
+ def Cdo.parseArgs(args)
162
+ # splitinto hash-like args and the rest
163
+ operatorArgs = args.reject {|a| a.class == Hash}
164
+ opts = operatorArgs.empty? ? '' : ',' + operatorArgs.join(',')
165
+ io = args.find {|a| a.class == Hash}
166
+ io = {} if io.nil?
167
+ args.delete_if {|a| a.class == Hash}
168
+ # join input streams together if possible
169
+ io[:input] = io[:input].join(' ') if io[:input].respond_to?(:join)
170
+ return [io,opts]
171
+ end
172
+
173
+ def Cdo.method_missing(sym, *args, &block)
174
+ ## args is expected to look like [opt1,...,optN,:input => iStream,:output => oStream] where
175
+ # iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
176
+ puts "Operator #{sym.to_s} is called" if State[:debug]
177
+ if getOperators.include?(sym.to_s)
178
+ io, opts = Cdo.parseArgs(args)
179
+ if @@outputOperatorsPattern.match(sym)
180
+ run(" -#{sym.to_s}#{opts} #{io[:input]} ",$stdout)
181
+ else
182
+ run(" -#{sym.to_s}#{opts} #{io[:input]} ",io[:output],io[:options],io[:returnCdf],io[:force],io[:returnArray],io[:returnMaArray])
183
+ end
184
+ else
185
+ raise ArgumentError,"Operator #{sym.to_s} not found"
186
+ end
187
+ end
188
+
189
+ def Cdo.loadCdf
190
+ begin
191
+ require "numru/netcdf_miss"
192
+ include NumRu
193
+ rescue LoadError
194
+ warn "Could not load ruby's netcdf bindings. Please install it."
195
+ raise
196
+ end
197
+ end
198
+
199
+ def Cdo.getSupportedLibs(force=false)
200
+ return unless (State[:libs].nil? or force)
201
+ _, _, stderr, _ = Open3.popen3(@@CDO + " -V")
202
+ supported = stderr.readlines.map(&:chomp)
203
+ with = supported.grep(/(with|Features)/)[0].split(':')[1].split.map(&:downcase)
204
+ libs = supported.grep(/library version/).map {|l|
205
+ l.strip.split(':').map {|l|
206
+ l.split.first.downcase
207
+ }[0,2]
208
+ }
209
+ State[:libs] = {}
210
+ with.flatten.each {|k| State[:libs][k]=true}
211
+ libs.each {|lib,version| State[:libs][lib] = version}
212
+ end
213
+
214
+ public
215
+ def Cdo.debug=(value)
216
+ State[:debug] = value
217
+ end
218
+ def Cdo.debug
219
+ State[:debug]
220
+ end
221
+ def Cdo.forceOutput=(value)
222
+ State[:forceOutput] = value
223
+ end
224
+ def Cdo.forceOutput
225
+ State[:forceOutput]
226
+ end
227
+ def Cdo.log=(value)
228
+ State[:log] = value
229
+ end
230
+
231
+ def Cdo.log
232
+ State[:log]
233
+ end
234
+
235
+ def Cdo.version
236
+ cmd = @@CDO + ' 2>&1'
237
+ help = IO.popen(cmd).readlines.map {|l| l.chomp.lstrip}
238
+ regexp = %r{CDO version (\d.*), Copyright}
239
+ line = help.find {|v| v =~ regexp}
240
+ version = regexp.match(line)[1]
241
+ end
242
+
243
+ def Cdo.setReturnCdf(value=true)
244
+ if value
245
+ Cdo.loadCdf
246
+ end
247
+ State[:returnCdf] = value
248
+ end
249
+
250
+ def Cdo.unsetReturnCdf
251
+ setReturnCdf(false)
252
+ end
253
+
254
+ def Cdo.returnCdf
255
+ State[:returnCdf]
256
+ end
257
+
258
+ def Cdo.hasCdo?(bin=@@CDO)
259
+ return true if File.exists?(@@CDO) and File.executable?(@@CDO)
260
+ ENV['PATH'].split(File::PATH_SEPARATOR).each {|path|
261
+ return true if File.exists?([path,bin].join(File::SEPARATOR))
262
+ }
263
+ end
264
+
265
+ # test if @@CDO can be used
266
+ def Cdo.checkCdo
267
+ unless hasCdo?(@@CDO)
268
+ warn "Testing application #@@CDO is not available!"
269
+ exit 1
270
+ else
271
+ puts "Using CDO: #@@CDO"
272
+ puts IO.popen(@@CDO + " -V").readlines
273
+ end
274
+ return true
275
+ end
276
+
277
+ def Cdo.setCdo(cdo)
278
+ puts "Will use #{cdo} instead of #@@CDO" if Cdo.debug
279
+ @@CDO = cdo
280
+ Cdo.getOperators(true)
281
+ Cdo.getSupportedLibs(true)
282
+ end
283
+
284
+ def Cdo.getCdo
285
+ @@CDO
286
+ end
287
+
288
+ def Cdo.operators
289
+ Cdo.getOperators if State[:operators].empty?
290
+ State[:operators]
291
+ end
292
+
293
+ def Cdo.libs
294
+ getSupportedLibs
295
+ State[:libs]
296
+ end
297
+
298
+ def Cdo.hasLib?(lib)
299
+ return Cdo.libs.has_key?(lib)
300
+ return false
301
+ end
302
+
303
+ def Cdo.libsVersion(lib)
304
+ unless Cdo.hasLib?(lib)
305
+ raise ArgumentError, "Cdo does NOT have support for '#{lib}'"
306
+ else
307
+ if State[:libs][lib].kind_of? String
308
+ return State[:libs][lib]
309
+ else
310
+ warn "No version information available about '#{lib}'"
311
+ return false
312
+ end
313
+ end
314
+ end
315
+
316
+ def Cdo.showlog
317
+ @@file.rewind
318
+ puts @@file.read
319
+ end
320
+
321
+ #==================================================================
322
+ # Addional operotors:
323
+ #------------------------------------------------------------------
324
+ def Cdo.boundaryLevels(args)
325
+ ilevels = Cdo.showlevel(:input => args[:input])[0].split.map(&:to_f)
326
+ bound_levels = Array.new(ilevels.size+1)
327
+ bound_levels[0] = 0
328
+ (1..ilevels.size).each {|i|
329
+ bound_levels[i] =bound_levels[i-1] + 2*(ilevels[i-1]-bound_levels[i-1])
330
+ }
331
+ bound_levels
332
+ end
333
+
334
+ def Cdo.thicknessOfLevels(args)
335
+ bound_levels = Cdo.boundaryLevels(args)
336
+ delta_levels = []
337
+ bound_levels.each_with_index {|v,i|
338
+ next if 0 == i
339
+ delta_levels << v - bound_levels[i-1]
340
+ }
341
+ delta_levels
342
+ end
343
+
344
+ def Cdo.readCdf(iFile)
345
+ Cdo.loadCdf unless State[:returnCdf]
346
+ NetCDF.open(iFile)
347
+ end
348
+
349
+ def Cdo.openCdf(iFile)
350
+ Cdo.loadCdf unless State[:returnCdf]
351
+ NetCDF.open(iFile,'r+')
352
+ end
353
+
354
+ def Cdo.readArray(iFile,varname)
355
+ filehandle = Cdo.readCdf(iFile)
356
+ if filehandle.var_names.include?(varname)
357
+ # return the data array
358
+ filehandle.var(varname).get
359
+ else
360
+ raise ArgumentError, "Cannot find variable '#{varname}'"
361
+ end
362
+ end
363
+
364
+ def Cdo.readMaArray(iFile,varname)
365
+ filehandle = Cdo.readCdf(iFile)
366
+ if filehandle.var_names.include?(varname)
367
+ # return the data array
368
+ filehandle.var(varname).get_with_miss
369
+ else
370
+ raise ArgumentError,"Cannot find variable '#{varname}'"
371
+ end
372
+ end
373
+
374
+ def Cdo.help(operator=nil)
375
+ if operator.nil?
376
+ puts Cdo.call([@@CDO,'-h'].join(' '))[:stderr]
377
+ else
378
+ operator = operator.to_s unless String == operator.class
379
+ if Cdo.operators.include?(operator)
380
+ puts Cdo.call([@@CDO,'-h',operator].join(' '))[:stdout]
381
+ else
382
+ puts "Unknown operator #{operator}"
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ # Helper module for easy temp file handling
389
+ module MyTempfile
390
+ require 'tempfile'
391
+ @@_tempfiles = []
392
+ @@persistent_tempfiles = false
393
+ @@N = 10000000
394
+
395
+ def MyTempfile.setPersist(value)
396
+ @@persistent_tempfiles = value
397
+ end
398
+
399
+ def MyTempfile.path
400
+ unless @@persistent_tempfiles
401
+ t = Tempfile.new(self.class.to_s)
402
+ @@_tempfiles << t
403
+ @@_tempfiles << t.path
404
+ t.path
405
+ else
406
+ t = "_"+rand(@@N).to_s
407
+ @@_tempfiles << t
408
+ t
409
+ end
410
+ end
411
+
412
+ def MyTempfile.showFiles
413
+ @@_tempfiles.each {|f| print(f+" ") if f.kind_of? String}
414
+ end
415
+ end
@@ -9,91 +9,88 @@ require 'pp'
9
9
  #===============================================================================
10
10
  def rm(files); files.each {|f| FileUtils.rm(f) if File.exists?(f)};end
11
11
 
12
+ @show = ENV.has_key?('SHOW')
13
+
12
14
  class TestCdo < Minitest::Test
13
15
 
14
16
  DEFAULT_CDO_PATH = 'cdo'
15
17
 
18
+ def setup
19
+ @cdo = Cdo.new
20
+ end
21
+
16
22
  def test_cdo
17
- assert_equal(true,Cdo.checkCdo)
23
+ assert_equal(true,@cdo.check)
18
24
  if ENV['CDO']
19
- assert_equal(ENV['CDO'],Cdo.getCdo)
25
+ assert_equal(ENV['CDO'],@cdo.cdo)
20
26
  else
21
- assert_equal(DEFAULT_CDO_PATH,Cdo.getCdo)
27
+ assert_equal(DEFAULT_CDO_PATH,@cdo.cdo)
22
28
  end
23
- newCDO="#{ENV['HOME']}/local/bin/cdo"
29
+ newCDO="#{ENV['HOME']}/local/bin/cdo-dev"
24
30
  if File.exist?(newCDO) then
25
- Cdo.setCdo(newCDO)
26
- assert_equal(true,Cdo.checkCdo)
27
- assert_equal(newCDO,Cdo.getCdo)
31
+ cdo = Cdo.new(:cdo => newCDO)
32
+ assert_equal(true,cdo.check)
33
+ assert_equal(newCDO,cdo.cdo)
28
34
  end
29
35
  end
30
36
  def test_getOperators
31
37
  %w[for random stdatm info showlevel sinfo remap geopotheight mask topo thicknessOfLevels].each {|op|
32
38
  if ["thicknessOfLevels"].include?(op)
33
- assert(Cdo.respond_to?(op),"Operator '#{op}' not found")
39
+ assert(@cdo.respond_to?(op),"Operator '#{op}' not found")
34
40
  else
35
- assert(Cdo.getOperators.include?(op),"Operator '#{op}' not found")
41
+ assert(@cdo.operators.include?(op),"Operator '#{op}' not found")
36
42
  end
37
43
  }
38
- assert(Cdo.respond_to?('diff')) # an alias
44
+ assert(@cdo.operators.include?('diff'),"Operator alias 'diff' is not callable")
39
45
  end
40
46
  def test_listAllOperators
41
- print Cdo.operators.join("\n")
47
+ assert(@cdo.operators.size > 700,"cound not find enough operators")
42
48
  end
43
49
 
44
50
  def test_outputOperators
45
- Cdo.debug = true
46
- levels = Cdo.showlevel(:input => "-stdatm,0")
51
+ @cdo.debug = true
52
+ levels = @cdo.showlevel(:input => "-stdatm,0")
47
53
  assert_equal([0,0].map(&:to_s),levels)
48
54
 
49
- info = Cdo.sinfo(:input => "-stdatm,0")
50
- assert_equal("File format: GRIB",info[0])
55
+ info = @cdo.sinfo(:input => "-stdatm,0")
56
+ assert_equal("GRIB",info[0].split(':').last.strip)
51
57
 
52
- values = Cdo.outputkey("value",:input => "-stdatm,0")
53
- assert_equal(["1013.25", "288"],values)
54
- values = Cdo.outputkey("value",:input => "-stdatm,0,10000")
55
- assert_equal(["1013.25", "271.913", "288", "240.591"],values)
56
- values = Cdo.outputkey("level",:input => "-stdatm,0,10000")
57
- assert_equal(["0", "10000","0", "10000"],values)
58
+ values = @cdo.outputkey("value",:input => "-stdatm,0")
59
+ assert_equal(["1013.25", "288"],values[-2..-1])
60
+ values = @cdo.outputkey("value",:input => "-stdatm,0,10000")
61
+ assert_equal(["1013.25", "271.913", "288", "240.591"],values[-4..-1])
62
+ values = @cdo.outputkey("level",:input => "-stdatm,0,10000")
63
+ assert_equal(["0", "10000","0", "10000"],values[-4..-1])
58
64
  end
59
65
  def test_CDO_version
60
- assert("1.4.3.1" < Cdo.version,"Version to low: #{Cdo.version}")
66
+ assert("1.4.3.1" < @cdo.version,"Version too low: #{@cdo.version}")
67
+ assert("1.8.0" > @cdo.version,"Version too high: #{@cdo.version}")
61
68
  end
62
69
  def test_args
63
- ofile0 = Cdo.stdatm(0,20,40,80,200,230,400,600,1100)
64
- ofile1 = Cdo.intlevel(0,10,50,100,500,1000, :input => ofile0)
65
- ofile2 = Cdo.intlevel([0,10,50,100,500,1000],:input => ofile0)
66
- ofile3 = Cdo.sub(:input => [ofile1,ofile2].join(' '))
67
- info = Cdo.infon(:input => ofile3)
70
+ ofile0 = @cdo.stdatm(0,20,40,80,200,230,400,600,1100)
71
+ ofile1 = @cdo.intlevel(0,10,50,100,500,1000, :input => ofile0)
72
+ ofile2 = @cdo.intlevel([0,10,50,100,500,1000],:input => ofile0)
73
+ ofile3 = @cdo.sub(:input => [ofile1,ofile2].join(' '))
74
+ info = @cdo.infon(:input => ofile3)
68
75
  (1...info.size).each {|i| assert_equal(0.0,info[i].split[-1].to_f)}
69
76
  end
70
77
  def test_operator_options
71
- Cdo.debug=true
78
+ @cdo.debug=true
72
79
  targetLevels = [0,10,50,100,200,400,1000]
73
- levels = Cdo.showlevel(:input => " -stdatm,#{targetLevels.join(',')}")
80
+ levels = @cdo.showlevel(:input => " -stdatm,#{targetLevels.join(',')}")
74
81
  [0,1].each {|i| assert_equal(targetLevels.join(' '),levels[i])}
75
- end
76
- def test_CDO_options
77
- names = Cdo.showname(:input => "-stdatm,0",:options => "-f nc")
82
+ names = @cdo.showname(:input => "-stdatm,0",:options => "-f nc")
78
83
  assert_equal(["P T"],names)
79
-
80
- if Cdo.hasLib?("sz")
81
- ofile = Cdo.topo(:output => ofile,:options => "-z szip")
82
- assert_equal(["GRIB SZIP"],Cdo.showformat(:input => ofile))
83
- else
84
- ofile = Cdo.topo
85
- assert_equal(["GRIB"],Cdo.showformat(:input => ofile))
86
- end
87
84
  end
88
85
  def test_chain
89
- Cdo.debug = true
90
- ofile = Cdo.setname('veloc',:input => " -copy -random,r1x1",:options => "-f nc")
91
- assert_equal(["veloc"],Cdo.showname(:input => ofile))
86
+ @cdo.debug = true
87
+ ofile = @cdo.setname('veloc',:input => " -copy -random,r1x1",:options => "-f nc")
88
+ assert_equal(["veloc"],@cdo.showname(:input => ofile))
92
89
  end
93
90
 
94
91
  def test_diff
95
- diffv_ = Cdo.diffn(:input => "-random,r1x1 -random,r1x1")
96
- diff_ = Cdo.diffv(:input => "-random,r1x1 -random,r1x1")
92
+ diffv_ = @cdo.diffn(:input => "-random,r1x1 -random,r1x1")
93
+ diff_ = @cdo.diffv(:input => "-random,r1x1 -random,r1x1")
97
94
  return
98
95
 
99
96
  assert_equal(diffv[1].split(' ')[-1],"random")
@@ -102,34 +99,29 @@ class TestCdo < Minitest::Test
102
99
  assert_equal(diff[1].split(' ')[-3],"0.53060")
103
100
  end
104
101
 
105
- def test_operators
106
- assert_includes(Cdo.operators,"infov")
107
- assert_includes(Cdo.operators,"showlevel")
108
- end
109
-
110
102
  def test_bndLevels
111
- ofile = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc")
103
+ ofile = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc")
112
104
  assert_equal([0, 50.0, 150.0, 350.0, 650.0, 1100.0, 1700.0, 2500.0, 3500.0, 4500.0, 5500.0],
113
- Cdo.boundaryLevels(:input => "-selname,T #{ofile}"))
105
+ @cdo.boundaryLevels(:input => "-selname,T #{ofile}"))
114
106
  assert_equal([50.0, 100.0, 200.0, 300.0, 450.0, 600.0, 800.0, 1000.0, 1000.0, 1000.0],
115
- Cdo.thicknessOfLevels(:input => ofile))
107
+ @cdo.thicknessOfLevels(:input => ofile))
116
108
  end
117
109
 
118
110
  def test_combine
119
111
  ofile0, ofile1 = MyTempfile.path, MyTempfile.path
120
- Cdo.fldsum(:input => Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc"),:output => ofile0)
121
- Cdo.fldsum(:input => "-stdatm,25,100,250,500,875,1400,2100,3000,4000,5000",:options => "-f nc",:output => ofile1)
122
- Cdo.setReturnCdf
112
+ @cdo.fldsum(:input => @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc"),:output => ofile0)
113
+ @cdo.fldsum(:input => "-stdatm,25,100,250,500,875,1400,2100,3000,4000,5000",:options => "-f nc",:output => ofile1)
114
+ @cdo.returnCdf = true
123
115
  MyTempfile.showFiles
124
- diff = Cdo.sub(:input => [ofile0,ofile1].join(' ')).var('T').get
116
+ diff = @cdo.sub(:input => [ofile0,ofile1].join(' ')).var('T').get
125
117
  assert_equal(0.0,diff.min)
126
118
  assert_equal(0.0,diff.max)
127
- Cdo.setReturnCdf(false)
119
+ @cdo.returnCdf = false
128
120
  end
129
121
 
130
122
  def test_tempfile
131
123
  ofile0, ofile1 = MyTempfile.path, MyTempfile.path
132
- assert_not_equal(ofile0,ofile1)
124
+ assert(ofile0 != ofile1, "Found equal tempfiles!")
133
125
  # Tempfile should not disappeare even if the GC was started
134
126
  puts ofile0
135
127
  assert(File.exist?(ofile0))
@@ -139,49 +131,49 @@ class TestCdo < Minitest::Test
139
131
 
140
132
  def test_returnCdf
141
133
  ofile = rand(0xfffff).to_s + '_test_returnCdf.nc'
142
- vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
134
+ vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
143
135
  assert_equal(ofile,vals)
144
- Cdo.setReturnCdf
145
- vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
136
+ @cdo.returnCdf = true
137
+ vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
146
138
  assert_equal(["lon","lat","level","P","T"],vals.var_names)
147
139
  assert_equal(276,vals.var("T").get.flatten.mean.floor)
148
- Cdo.unsetReturnCdf
149
- vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
140
+ @cdo.returnCdf = false
141
+ vals = @cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:output => ofile,:options => "-f nc")
150
142
  assert_equal(ofile,vals)
151
143
  FileUtils.rm(ofile)
152
144
  end
153
145
  def test_simple_returnCdf
154
146
  ofile0, ofile1 = MyTempfile.path, MyTempfile.path
155
- sum = Cdo.fldsum(:input => Cdo.stdatm(0,:options => "-f nc"),
147
+ sum = @cdo.fldsum(:input => @cdo.stdatm(0,:options => "-f nc"),
156
148
  :returnCdf => true).var("P").get
157
149
  assert_equal(1013.25,sum.min)
158
- sum = Cdo.fldsum(:input => Cdo.stdatm(0,:options => "-f nc"),:output => ofile0)
150
+ sum = @cdo.fldsum(:input => @cdo.stdatm(0,:options => "-f nc"),:output => ofile0)
159
151
  assert_equal(ofile0,sum)
160
152
  test_returnCdf
161
153
  end
162
154
  def test_force
163
155
  outs = []
164
156
  # tempfiles
165
- outs << Cdo.stdatm(0,10,20)
166
- outs << Cdo.stdatm(0,10,20)
167
- assert_not_equal(outs[0],outs[1])
157
+ outs << @cdo.stdatm(0,10,20)
158
+ outs << @cdo.stdatm(0,10,20)
159
+ assert(outs[0] != outs[1])
168
160
 
169
161
  # deticated output, force = true
170
162
  outs.clear
171
- outs << Cdo.stdatm(0,10,20,:output => 'test_force')
163
+ outs << @cdo.stdatm(0,10,20,:output => 'test_force')
172
164
  mtime0 = File.stat(outs[-1]).mtime
173
- outs << Cdo.stdatm(0,10,20,:output => 'test_force')
165
+ outs << @cdo.stdatm(0,10,20,:output => 'test_force')
174
166
  mtime1 = File.stat(outs[-1]).mtime
175
- assert_not_equal(mtime0,mtime1)
167
+ assert(mtime0 != mtime1)
176
168
  assert_equal(outs[0],outs[1])
177
169
  FileUtils.rm('test_force')
178
170
  outs.clear
179
171
 
180
172
  # dedicated output, force = false
181
173
  ofile = 'test_force_false'
182
- outs << Cdo.stdatm(0,10,20,:output => ofile,:force => false)
174
+ outs << @cdo.stdatm(0,10,20,:output => ofile,:force => false)
183
175
  mtime0 = File.stat(outs[-1]).mtime
184
- outs << Cdo.stdatm(0,10,20,:output => ofile,:force => false)
176
+ outs << @cdo.stdatm(0,10,20,:output => ofile,:force => false)
185
177
  mtime1 = File.stat(outs[-1]).mtime
186
178
  assert_equal(mtime0,mtime1)
187
179
  assert_equal(outs[0],outs[1])
@@ -190,10 +182,10 @@ class TestCdo < Minitest::Test
190
182
 
191
183
  # dedicated output, global force setting
192
184
  ofile = 'test_force_global'
193
- Cdo.forceOutput = false
194
- outs << Cdo.stdatm(0,10,20,:output => ofile)
185
+ @cdo.forceOutput = false
186
+ outs << @cdo.stdatm(0,10,20,:output => ofile)
195
187
  mtime0 = File.stat(outs[-1]).mtime
196
- outs << Cdo.stdatm(0,10,20,:output => ofile)
188
+ outs << @cdo.stdatm(0,10,20,:output => ofile)
197
189
  mtime1 = File.stat(outs[-1]).mtime
198
190
  assert_equal(mtime0,mtime1)
199
191
  assert_equal(outs[0],outs[1])
@@ -204,20 +196,20 @@ class TestCdo < Minitest::Test
204
196
  def test_thickness
205
197
  levels = "25 100 250 500 875 1400 2100 3000 4000 5000".split
206
198
  targetThicknesses = [50.0, 100.0, 200.0, 300.0, 450.0, 600.0, 800.0, 1000.0, 1000.0, 1000.0]
207
- assert_equal(targetThicknesses, Cdo.thicknessOfLevels(:input => "-selname,T -stdatm,#{levels.join(',')}"))
199
+ assert_equal(targetThicknesses, @cdo.thicknessOfLevels(:input => "-selname,T -stdatm,#{levels.join(',')}"))
208
200
  end
209
201
 
210
202
  def test_showlevels
211
203
  sourceLevels = %W{25 100 250 500 875 1400 2100 3000 4000 5000}
212
204
  assert_equal(sourceLevels,
213
- Cdo.showlevel(:input => "-selname,T #{Cdo.stdatm(*sourceLevels,:options => '-f nc')}")[0].split)
205
+ @cdo.showlevel(:input => "-selname,T #{@cdo.stdatm(*sourceLevels,:options => '-f nc')}")[0].split)
214
206
  end
215
207
 
216
208
  def test_verticalLevels
217
- Cdo.debug = true
209
+ @cdo.debug = true
218
210
  targetThicknesses = [50.0, 100.0, 200.0, 300.0, 450.0, 600.0, 800.0, 1000.0, 1000.0, 1000.0]
219
211
  sourceLevels = %W{25 100 250 500 875 1400 2100 3000 4000 5000}
220
- thicknesses = Cdo.thicknessOfLevels(:input => "-selname,T #{Cdo.stdatm(*sourceLevels,:options => '-f nc')}")
212
+ thicknesses = @cdo.thicknessOfLevels(:input => "-selname,T #{@cdo.stdatm(*sourceLevels,:options => '-f nc')}")
221
213
  assert_equal(targetThicknesses,thicknesses)
222
214
  end
223
215
 
@@ -231,31 +223,31 @@ class TestCdo < Minitest::Test
231
223
  end
232
224
 
233
225
  def test_returnArray
234
- temperature = Cdo.stdatm(0,:options => '-f nc',:returnCdf => true).var('T').get.flatten[0]
235
- assert_raise ArgumentError do
236
- Cdo.stdatm(0,:options => '-f nc',:returnArray => 'TT')
226
+ temperature = @cdo.stdatm(0,:options => '-f nc',:returnCdf => true).var('T').get.flatten[0]
227
+ assert_raises ArgumentError do
228
+ @cdo.stdatm(0,:options => '-f nc',:returnArray => 'TT')
237
229
  end
238
- temperature = Cdo.stdatm(0,:options => '-f nc',:returnArray => 'T')
230
+ temperature = @cdo.stdatm(0,:options => '-f nc',:returnArray => 'T')
239
231
  assert_equal(288.0,temperature.flatten[0])
240
- pressure = Cdo.stdatm(0,1000,:options => '-f nc -b F64',:returnArray => 'P')
232
+ pressure = @cdo.stdatm(0,1000,:options => '-f nc -b F64',:returnArray => 'P')
241
233
  assert_equal("1013.25 898.543456035875",pressure.flatten.to_a.join(' '))
242
234
  end
243
235
  def test_returnMaArray
244
- Cdo.debug = true
245
- topo = Cdo.topo(:options => '-f nc',:returnMaArray => 'topo')
236
+ @cdo.debug = true
237
+ topo = @cdo.topo(:options => '-f nc',:returnMaArray => 'topo')
246
238
  assert_equal(-1890.0,topo.mean.round)
247
- bathy = Cdo.setrtomiss(0,10000,
248
- :input => Cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
239
+ bathy = @cdo.setrtomiss(0,10000,
240
+ :input => @cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
249
241
  assert_equal(-3386.0,bathy.mean.round)
250
- oro = Cdo.setrtomiss(-10000,0,
251
- :input => Cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
242
+ oro = @cdo.setrtomiss(-10000,0,
243
+ :input => @cdo.topo(:options => '-f nc'),:returnMaArray => 'topo')
252
244
  assert_equal(1142.0,oro.mean.round)
253
- bathy = Cdo.remapnn('r2x2',:input => Cdo.topo(:options => '-f nc'), :returnMaArray => 'topo')
245
+ bathy = @cdo.remapnn('r2x2',:input => @cdo.topo(:options => '-f nc'), :returnMaArray => 'topo')
254
246
  assert_equal(-4298.0,bathy[0,0])
255
247
  assert_equal(-2669.0,bathy[1,0])
256
- ta = Cdo.remapnn('r2x2',:input => Cdo.topo(:options => '-f nc'))
257
- tb = Cdo.subc(-2669.0,:input => ta)
258
- withMask = Cdo.div(:input => ta+" "+tb,:returnMaArray => 'topo')
248
+ ta = @cdo.remapnn('r2x2',:input => @cdo.topo(:options => '-f nc'))
249
+ tb = @cdo.subc(-2669.0,:input => ta)
250
+ withMask = @cdo.div(:input => ta+" "+tb,:returnMaArray => 'topo')
259
251
  assert(-8.0e+33 > withMask[1,0])
260
252
  assert(0 < withMask[0,0])
261
253
  assert(0 < withMask[0,1])
@@ -263,131 +255,123 @@ class TestCdo < Minitest::Test
263
255
  end
264
256
 
265
257
  def test_errorException
266
- Cdo.debug = true
258
+ @cdo.debug = true
267
259
  # stdout operators get get wrong input
268
- assert_raise ArgumentError do
269
- Cdo.showname(:input => '-for,d')
260
+ assert_raises ArgumentError do
261
+ @cdo.showname(:input => '-for,d')
270
262
  end
271
263
  # non-existing operator
272
- assert_raise ArgumentError do
273
- Cdo.neverDefinedOperator()
264
+ assert_raises ArgumentError do
265
+ @cdo.neverDefinedOperator()
274
266
  end
275
267
  # standard opertor get mis-spelled value
276
- assert_raise ArgumentError do
277
- Cdo.remapnn('r-10x10')
268
+ assert_raises ArgumentError do
269
+ @cdo.remapnn('r-10x10')
278
270
  end
279
271
  # standard operator get unexisting operator as input stream
280
- assert_raise ArgumentError do
281
- Cdo.remapnn('r10x10',:input => '-99topo')
272
+ assert_raises ArgumentError do
273
+ @cdo.remapnn('r10x10',:input => '-99topo')
282
274
  end
283
275
  # missing input stream
284
- assert_raise ArgumentError do
285
- Cdo.setname('setname')
276
+ assert_raises ArgumentError do
277
+ @cdo.setname('setname')
286
278
  end
287
279
  # missing input stream for stdout-operator
288
- assert_raise ArgumentError do
289
- Cdo.showname
280
+ assert_raises ArgumentError do
281
+ @cdo.showname
290
282
  end
291
283
  end
292
284
 
293
285
  def test_inputArray
294
286
  # check for file input
295
- fileA = Cdo.stdatm(0)
296
- fileB = Cdo.stdatm(0)
287
+ fileA = @cdo.stdatm(0)
288
+ fileB = @cdo.stdatm(0)
297
289
  files = [fileA,fileB]
298
- assert_equal(Cdo.diffv(:input => files.join(' ')),
299
- Cdo.diffv(:input => files))
300
- assert_nil(Cdo.diffv(:input => files).last)
290
+ assert_equal(@cdo.diffv(:input => files.join(' ')),
291
+ @cdo.diffv(:input => files))
292
+ assert_nil(@cdo.diffv(:input => files).last)
301
293
  # check for operator input
302
- assert_nil(Cdo.diffv(:input => ["-stdatm,0","-stdatm,0"]).last)
294
+ assert_nil(@cdo.diffv(:input => ["-stdatm,0","-stdatm,0"]).last)
303
295
  # check for operator input and files
304
- assert_nil(Cdo.diffv(:input => ["-stdatm,0",fileB]).last)
296
+ assert_nil(@cdo.diffv(:input => ["-stdatm,0",fileB]).last)
305
297
  end
306
298
 
307
- def test_libs
308
- assert(Cdo.hasLib?("cdi"),"CDI support missing")
309
- assert(Cdo.hasLib?("nc4"),"netcdf4 support missing")
310
- assert(Cdo.hasLib?("netcdf"),"netcdf support missing")
311
- assert_equal(false,Cdo.hasLib?("boost"))
312
- #if 'thingol' == `hostname`.chomp
313
- # assert_equal('1.10.0',Cdo.libsVersion("grib_api")) if Cdo.hasLib?("grib_api")
314
- # Cdo.debug = true
315
- # warn "Found magics support" if Cdo.libs.has_key?('magics')
316
- # Cdo.setCdo('../../src/cdo')
317
- # assert(Cdo.libs.has_key?('magics'),"Magics support is expected in the local development binary")
318
- #end
319
- assert_raise ArgumentError do
320
- Cdo.libsVersion("foo")
299
+ def test_filetypes
300
+ assert(@cdo.filetypes.include?("grb"),"GRIB support missing")
301
+ assert(@cdo.filetypes.include?("nc4"),"NETCDF4 support missing")
302
+ assert(@cdo.filetypes.include?("ext"),"EXTRA support missing")
303
+ assert_raises ArgumentError do
304
+ @cdo.filetypes("foo")
321
305
  end
322
306
  end
323
307
 
324
308
  def test_output_set_to_nil
325
- assert_equal(String,Cdo.topo(:output => nil).class)
326
- assert_equal("File format: GRIB",Cdo.sinfov(:input => "-topo", :output => nil)[0])
309
+ assert_equal(String,@cdo.topo(:output => nil).class)
310
+ assert_equal("File format: GRIB".tr(' ',''),@cdo.sinfov(:input => "-topo", :output => nil)[0].tr(' ',''))
327
311
  end
328
312
 
329
- if 'thingol' == `hostname`.chomp then
313
+ if 'luthien' == `hostname`.chomp then
330
314
  def test_readCdf
331
315
  input = "-settunits,days -setyear,2000 -for,1,4"
332
- cdfFile = Cdo.copy(:options =>"-f nc",:input=>input)
333
- cdf = Cdo.readCdf(cdfFile)
316
+ cdfFile = @cdo.copy(:options =>"-f nc",:input=>input)
317
+ cdf = @cdo.readCdf(cdfFile)
334
318
  assert_equal(['lon','lat','time','for'],cdf.var_names)
335
319
  end
336
320
  def test_selIndexListFromIcon
337
321
  input = "~/data/icon/oce.nc"
338
322
  end
339
323
  def test_readArray
340
- ifile = '/home/ram/data/examples/EH5_AMIP_1_TSURF_1991-1995.nc'
341
- assert_equal([192, 96, 10],Cdo.readArray(Cdo.seltimestep('1/10',:input => ifile), 'tsurf').shape)
324
+ @cdo.debug = true
325
+ assert_equal([40,80],@cdo.readArray(@cdo.sellonlatbox(-10,10,-20,20,:input => '-topo',:options => '-f nc'), 'topo').shape)
342
326
  end
343
327
  def test_doc
344
- Cdo.debug = true
345
- Cdo.help(:remap)
346
- Cdo.help(:infov)
347
- Cdo.help(:topo)
348
- Cdo.help(:notDefinedOP)
349
- Cdo.help
328
+ @cdo.debug = true
329
+ @cdo.help(:remap)
330
+ @cdo.help(:infov)
331
+ @cdo.help(:topo)
332
+ @cdo.help(:notDefinedOP)
333
+ @cdo.help
350
334
  end
351
335
  def test_fillmiss
352
- Cdo.debug = true
336
+ @cdo.debug = true
353
337
  # check up-down replacement
354
- rand = Cdo.setname('v',:input => '-random,r1x10 ', :options => ' -f nc',:output => '/tmp/rand.nc')
355
- cdf = Cdo.openCdf(rand)
338
+ rand = @cdo.setname('v',:input => '-random,r1x10 ', :options => ' -f nc',:output => '/tmp/rand.nc')
339
+ cdf = @cdo.openCdf(rand)
356
340
  vals = cdf.var('v').get
357
341
  cdf.var('v').put(vals.sort)
358
342
  cdf.sync
359
343
  cdf.close
360
344
 
361
345
  missRange = '0.3,0.8'
362
- arOrg = Cdo.setrtomiss(missRange,:input => cdf.path,:returnMaArray => 'v')
363
- arFm = Cdo.fillmiss(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
364
- arFm1s= Cdo.fillmiss2(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
346
+ arOrg = @cdo.setrtomiss(missRange,:input => cdf.path,:returnMaArray => 'v')
347
+ arFm = @cdo.fillmiss(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
348
+ arFm1s= @cdo.fillmiss2(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
365
349
  vOrg = arOrg[0,0..-1]
366
350
  vFm = arFm[0,0..-1]
367
351
  vFm1s = arFm1s[0,0..-1]
368
352
  UnifiedPlot.linePlot([{:y => vOrg, :style => 'line',:title => 'org'},
369
353
  {:y => vFm, :style => 'points',:title => 'fillmiss'},
370
354
  {:y => vFm1s,:style => 'points',:title => 'fillmiss2'}],
371
- plotConf: {:yrange => '[0:1]'},title: 'r1x10')
355
+ plotConf: {:yrange => '[0:1]'},title: 'r1x10') if @show
372
356
  # check left-right replacement
373
- rand = Cdo.setname('v',:input => '-random,r10x1 ', :options => ' -f nc',:output => '/tmp/rand.nc')
374
- cdf = Cdo.openCdf(rand)
357
+ rand = @cdo.setname('v',:input => '-random,r10x1 ', :options => ' -f nc',:output => '/tmp/rand.nc')
358
+ cdf = @cdo.openCdf(rand)
375
359
  vals = cdf.var('v').get
376
360
  cdf.var('v').put(vals.sort)
377
361
  cdf.sync
378
362
  cdf.close
379
363
 
380
364
  missRange = '0.3,0.8'
381
- arOrg = Cdo.setrtomiss(missRange,:input => cdf.path,:returnMaArray => 'v')
382
- arFm = Cdo.fillmiss(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
383
- arFm1s= Cdo.fillmiss2(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
365
+ arOrg = @cdo.setrtomiss(missRange,:input => cdf.path,:returnMaArray => 'v')
366
+ arFm = @cdo.fillmiss(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
367
+ arFm1s= @cdo.fillmiss2(:input => "-setrtomiss,#{missRange} #{cdf.path}",:returnMaArray => 'v')
384
368
  vOrg = arOrg[0..-1,0]
385
369
  vFm = arFm[0..-1,0]
386
370
  vFm1s = arFm1s[0..-1,0]
387
371
  UnifiedPlot.linePlot([{:y => vOrg, :style => 'line',:title => 'org'},
388
372
  {:y => vFm, :style => 'points',:title => 'fillmiss'},
389
373
  {:y => vFm1s,:style => 'points',:title => 'fillmiss2'}],
390
- plotConf: {:yrange => '[0:1]'},title: 'r10x1')
374
+ plotConf: {:yrange => '[0:1]'},title: 'r10x1') if @show
391
375
  end
392
376
  end
393
377
 
@@ -400,39 +384,54 @@ class TestCdo < Minitest::Test
400
384
 
401
385
  # oType = grb (default)
402
386
  ofiles = expected.map {|f| f += '.grb'}
403
- Cdo.splitlevel(input: "-stdatm,0,10,100",output: oTag)
387
+ @cdo.splitlevel(input: "-stdatm,0,10,100",output: oTag)
404
388
  assert_equal(ofiles,Dir.glob(oTag+'*').sort)
405
389
  rm(ofiles)
406
390
 
407
391
  # oType = nc, from cdo options
408
392
  ofiles = expected.map {|f| f += '.nc'}
409
- Cdo.splitlevel(input: "-stdatm,0,10,100",output: oTag,options: '-f nc')
393
+ @cdo.splitlevel(input: "-stdatm,0,10,100",output: oTag,options: '-f nc')
410
394
  assert_equal(ofiles,Dir.glob(oTag+'*').sort)
411
395
  rm(ofiles)
412
396
 
413
397
  # oType = nc, from input type
414
398
  ofiles = expected.map {|f| f += '.nc'}
415
- Cdo.splitlevel(input: Cdo.stdatm(0,10,100,options: '-f nc'),output: oTag)
399
+ @cdo.splitlevel(input: @cdo.stdatm(0,10,100,options: '-f nc'),output: oTag)
416
400
  assert_equal(ofiles,Dir.glob(oTag+'*').sort)
417
401
  rm(ofiles)
418
402
 
419
403
  # oType = nc, from input ENV
420
404
  ofiles = expected.map {|f| f += '.nc2'}
421
- Cdo.env = {'CDO_FILE_SUFFIX' => '.nc2'}
422
- Cdo.splitlevel(input: Cdo.stdatm(0,10,100,options: '-f nc'),output: oTag)
405
+ @cdo.env = {'CDO_FILE_SUFFIX' => '.nc2'}
406
+ @cdo.splitlevel(input: @cdo.stdatm(0,10,100,options: '-f nc'),output: oTag)
423
407
  assert_equal(ofiles,Dir.glob(oTag+'*').sort)
424
408
  rm(ofiles)
425
409
 
426
410
  # oType = nc, from input ENV setting for each call
427
411
  ofiles = expected.map {|f| f += '.nc2'}
428
- Cdo.splitlevel(input: Cdo.stdatm(0,10,100,options: '-f nc'),output: oTag,env: {'CDO_FILE_SUFFIX' => '.nc2'})
412
+ @cdo.splitlevel(input: @cdo.stdatm(0,10,100,options: '-f nc'),output: oTag,env: {'CDO_FILE_SUFFIX' => '.nc2'})
429
413
  assert_equal(ofiles,Dir.glob(oTag+'*').sort)
430
414
  rm(ofiles)
431
415
  end
432
416
  def test_log
433
- Cdo.log = true
434
- Cdo.topo
435
- Cdo.showlog
417
+ cmd = '-fldmean -mul -random,r20x20 -topo,r20x20'
418
+ # logging without a real file
419
+ @cdo = Cdo.new( returnNilOnError: true)
420
+ @cdo.debug = false
421
+ @cdo.logging = true
422
+ @cdo.topo
423
+ @cdo.temp
424
+ @cdo.sinfov(input: cmd)
425
+ puts @cdo.showLog
426
+ @cdo.sinfov(input: '-top')
427
+ @cdo.topo
428
+ puts @cdo.showLog
429
+ # use a use definded file for looging
430
+ @cdo = Cdo.new(logFile: 'test.log',logging: true, returnNilOnError: true)
431
+ @cdo.topo
432
+ @cdo.temp
433
+ @cdo.sinfov(input: cmd)
434
+ puts @cdo.showLog
436
435
  end
437
436
  end
438
437
 
@@ -440,30 +439,30 @@ end
440
439
  # #
441
440
  # # merge:
442
441
  # # let files be an erray of valid filenames and ofile is a string
443
- # Cdo.merge(:input => outvars.join(" "),:output => ofile)
442
+ # @cdo.merge(:input => outvars.join(" "),:output => ofile)
444
443
  # # or with multiple arrays:
445
- # Cdo.merge(:input => [ifiles0,ifiles1].flatten.join(' '),:output => ofile)
444
+ # @cdo.merge(:input => [ifiles0,ifiles1].flatten.join(' '),:output => ofile)
446
445
  # # selname:
447
446
  # # lets grep out some variables from ifile:
448
447
  # ["T","U","V"].each {|varname|
449
448
  # varfile = varname+".nc"
450
- # Cdo.selname(varname,:input => ifile,:output => varfile)
449
+ # @cdo.selname(varname,:input => ifile,:output => varfile)
451
450
  # }
452
451
  # # a threaded version of this could look like:
453
452
  # ths = []
454
453
  # ["T","U","V"].each {|outvar|
455
454
  # ths << Thread.new(outvar) {|ovar|
456
455
  # varfile = varname+".nc"
457
- # Cdo.selname(varname,:input => ifile,:output => varfile)
456
+ # @cdo.selname(varname,:input => ifile,:output => varfile)
458
457
  # }
459
458
  # }
460
459
  # ths.each {|th| th.join}
461
460
  # # another example with sub:
462
- # Cdo.sub(:input => [oldfile,newfile].join(' '), :output => diff)
461
+ # @cdo.sub(:input => [oldfile,newfile].join(' '), :output => diff)
463
462
  #
464
463
  # # It is possible too use the 'send' method
465
464
  # operator = /grb/.match(File.extname(ifile)) ? :showcode : :showname
466
- # inputVars = Cdo.send(operator,:input => ifile)
465
+ # inputVars = @cdo.send(operator,:input => ifile)
467
466
  # # show and info operators are writing to stdout. cdo.rb tries to collects this into arrays
468
467
  # #
469
468
  # # Same stuff with other operators:
@@ -473,15 +472,15 @@ end
473
472
  # else
474
473
  # warn "Wrong usage of variable identifier for '#{var}' (class #{var.class})!"
475
474
  # end
476
- # Cdo.send(operator,var,:input => @ifile, :output => varfile)
475
+ # @cdo.send(operator,var,:input => @ifile, :output => varfile)
477
476
  #
478
477
  # # Pass an array for operators with multiple options:
479
478
  # # Perform conservative remapping with pregenerated weights
480
- # Cdo.remap([gridfile,weightfile],:input => copyfile,:output => outfile)
479
+ # @cdo.remap([gridfile,weightfile],:input => copyfile,:output => outfile)
481
480
  # # Create vertical height levels out of hybrid model levels
482
- # Cdo.ml2hl([0,20,50,100,200,400,800,1200].join(','),:input => hybridlayerfile, :output => reallayerfile)
481
+ # @cdo.ml2hl([0,20,50,100,200,400,800,1200].join(','),:input => hybridlayerfile, :output => reallayerfile)
483
482
  # # or use multiple arguments directly
484
- # Cdo.remapeta(vctfile,orofile,:input => ifile,:output => hybridlayerfile)
483
+ # @cdo.remapeta(vctfile,orofile,:input => ifile,:output => hybridlayerfile)
485
484
  #
486
485
  # # the powerfull expr operator:
487
486
  # # taken from the tutorial in https://code.zmaw.de/projects/cdo/wiki/Tutorial#The-_expr_-Operator
@@ -492,8 +491,8 @@ end
492
491
  # TEMP_EXPR = lambda {|height| "213.0+75.0*exp(-#{height}/#{SCALEHEIGHT})"}
493
492
  #
494
493
  # # Create Pressure and Temperature out of a height field 'geopotheight' from ifile
495
- # Cdo.expr("'p=#{PRES_EXPR['geopotheight']}'", :input => ifile, :output => presFile)
496
- # Cdo.expr("'t=#{TEMP_EXPR['geopotheight']}'", :input => ifile, :output => tempFile)
494
+ # @cdo.expr("'p=#{PRES_EXPR['geopotheight']}'", :input => ifile, :output => presFile)
495
+ # @cdo.expr("'t=#{TEMP_EXPR['geopotheight']}'", :input => ifile, :output => tempFile)
497
496
  #
498
497
  #
499
498
  # # TIPS: I often work with temporary files and for getting rid of handling them manually the MyTempfile module can be used:
@@ -503,11 +502,11 @@ end
503
502
  # end
504
503
  # # As an example, the computation of simple atmospherric density could look like
505
504
  # presFile, tempFile = tfile, tfile
506
- # Cdo.expr("'p=#{PRES_EXPR['geopotheight']}'", :input => ifile, :output => presFile)
507
- # Cdo.expr("'t=#{TEMP_EXPR['geopotheight']}'", :input => ifile, :output => tempFile)
508
- # Cdo.chainCall("setname,#{rho} -divc,#{C_R} -div",in: [presFile,tempFile].join(' '), out: densityFile)
505
+ # @cdo.expr("'p=#{PRES_EXPR['geopotheight']}'", :input => ifile, :output => presFile)
506
+ # @cdo.expr("'t=#{TEMP_EXPR['geopotheight']}'", :input => ifile, :output => tempFile)
507
+ # @cdo.chainCall("setname,#{rho} -divc,#{C_R} -div",in: [presFile,tempFile].join(' '), out: densityFile)
509
508
  #
510
509
  # # For debugging, it is helpfull, to avoid the automatic cleanup at the end of the scripts:
511
510
  # MyTempfile.setPersist(true)
512
511
  # # creates randomly names files. Switch on debugging with
513
- # Cdo.Debug = true
512
+ # @cdo.Debug = true