cdo 1.2.7 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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