cdo 1.0.10 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/gemspec +1 -1
- data/lib/cdo.rb +51 -25
- data/test/test_cdo.rb +68 -22
- metadata +3 -3
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.0
|
6
|
+
s.version = '1.1.0'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.files = ["lib/cdo.rb"] + ["gemspec","COPYING","README.rdoc","ChangeLog"]
|
9
9
|
s.test_file = "test/test_cdo.rb"
|
data/lib/cdo.rb
CHANGED
@@ -16,12 +16,13 @@ require 'pp'
|
|
16
16
|
# CDO calling mechnism
|
17
17
|
module Cdo
|
18
18
|
|
19
|
-
VERSION = "1.0
|
19
|
+
VERSION = "1.1.0"
|
20
20
|
|
21
21
|
State = {
|
22
22
|
:debug => false,
|
23
|
-
:
|
24
|
-
:operators => []
|
23
|
+
:returnCdf => false,
|
24
|
+
:operators => [],
|
25
|
+
:forceOutput => true
|
25
26
|
}
|
26
27
|
State[:debug] = true unless ENV['DEBUG'].nil?
|
27
28
|
|
@@ -51,7 +52,7 @@ module Cdo
|
|
51
52
|
tstepcount vardes vardup varmul varquot2test varrms vertwind write_e5ml
|
52
53
|
writegrid writerandom yearcount]
|
53
54
|
|
54
|
-
@@outputOperatorsPattern = /(diff|info|output|griddes|zaxisdes|show)/
|
55
|
+
@@outputOperatorsPattern = /(diff|info|output|griddes|zaxisdes|show|ncode|ndate|nlevel|nmon|nvar|nyear|ntime|npar|gradsdes|pardes)/
|
55
56
|
|
56
57
|
private
|
57
58
|
def Cdo.getOperators(force=false)
|
@@ -84,38 +85,50 @@ module Cdo
|
|
84
85
|
system(cmd + ' 1>/dev/null 2>&1 ')
|
85
86
|
end
|
86
87
|
end
|
87
|
-
def Cdo.run(cmd,ofile='',options='',returnArray=
|
88
|
+
def Cdo.run(cmd,ofile='',options='',returnCdf=false,force=nil,returnArray=nil)
|
88
89
|
cmd = "#{@@CDO} -O #{options} #{cmd} "
|
89
90
|
case ofile
|
90
91
|
when $stdout
|
91
92
|
cmd << " 2>/dev/null"
|
93
|
+
puts cmd if Cdo.debug
|
92
94
|
return IO.popen(cmd).readlines.map {|l| l.chomp.strip}
|
93
|
-
|
94
|
-
|
95
|
+
else
|
96
|
+
force = State[:forceOutput] if force.nil?
|
97
|
+
if force or not File.exists?(ofile.to_s)
|
98
|
+
ofile = MyTempfile.path if ofile.nil?
|
99
|
+
cmd << "#{ofile}"
|
100
|
+
call(cmd)
|
101
|
+
else
|
102
|
+
warn "Use existing file '#{ofile}'" if Cdo.debug
|
103
|
+
end
|
95
104
|
end
|
96
|
-
|
97
|
-
call(cmd)
|
98
|
-
if returnArray or State[:returnArray]
|
105
|
+
if returnCdf or State[:returnCdf]
|
99
106
|
Cdo.readCdf(ofile)
|
100
107
|
else
|
101
108
|
return ofile
|
102
109
|
end
|
103
110
|
end
|
111
|
+
def Cdo.parseArgs(args)
|
112
|
+
# splitinto hash-like args and the rest
|
113
|
+
operatorArgs = args.reject {|a| a.class == Hash}
|
114
|
+
opts = operatorArgs.empty? ? '' : ',' + operatorArgs.join(',')
|
115
|
+
io = args.find {|a| a.class == Hash}
|
116
|
+
io = {} if io.nil?
|
117
|
+
args.delete_if {|a| a.class == Hash}
|
118
|
+
return [io,opts]
|
119
|
+
end
|
104
120
|
def Cdo.method_missing(sym, *args, &block)
|
105
|
-
|
121
|
+
## args is expected to look like [opt1,...,optN,:in => iStream,:out => oStream] where
|
106
122
|
# iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
|
107
123
|
puts "Operator #{sym.to_s} is called" if State[:debug]
|
108
124
|
if getOperators.include?(sym.to_s)
|
109
|
-
|
110
|
-
opts = operatorArgs.empty? ? '' : ',' + operatorArgs.join(',')
|
111
|
-
io = args.find {|a| a.class == Hash}
|
112
|
-
io = {} if io.nil?
|
113
|
-
args.delete_if {|a| a.class == Hash}
|
125
|
+
io,opts = Cdo.parseArgs(args)
|
114
126
|
if @@outputOperatorsPattern.match(sym)
|
115
127
|
run(" -#{sym.to_s}#{opts} #{io[:in]} ",$stdout)
|
116
128
|
else
|
117
|
-
opts
|
118
|
-
|
129
|
+
#if opts[:force] or not File.exist?(opts[:out]) then
|
130
|
+
run(" -#{sym.to_s}#{opts} #{io[:in]} ",io[:out],io[:options],io[:returnCdf],io[:force])
|
131
|
+
#end
|
119
132
|
end
|
120
133
|
else
|
121
134
|
warn "Operator #{sym.to_s} not found"
|
@@ -138,6 +151,12 @@ module Cdo
|
|
138
151
|
def Cdo.debug
|
139
152
|
State[:debug]
|
140
153
|
end
|
154
|
+
def Cdo.forceOutput=(value)
|
155
|
+
State[:forceOutput] = value
|
156
|
+
end
|
157
|
+
def Cdo.forceOutput
|
158
|
+
State[:forceOutput]
|
159
|
+
end
|
141
160
|
def Cdo.version
|
142
161
|
cmd = @@CDO + ' 2>&1'
|
143
162
|
help = IO.popen(cmd).readlines.map {|l| l.chomp.lstrip}
|
@@ -145,17 +164,17 @@ module Cdo
|
|
145
164
|
line = help.find {|v| v =~ regexp}
|
146
165
|
version = regexp.match(line)[1]
|
147
166
|
end
|
148
|
-
def Cdo.
|
167
|
+
def Cdo.setReturnCdf(value=true)
|
149
168
|
if value
|
150
169
|
Cdo.loadCdf
|
151
170
|
end
|
152
|
-
State[:
|
171
|
+
State[:returnCdf] = value
|
153
172
|
end
|
154
|
-
def Cdo.
|
155
|
-
|
173
|
+
def Cdo.unsetReturnCdf
|
174
|
+
setReturnCdf(false)
|
156
175
|
end
|
157
|
-
def Cdo.
|
158
|
-
State[:
|
176
|
+
def Cdo.returnCdf
|
177
|
+
State[:returnCdf]
|
159
178
|
end
|
160
179
|
|
161
180
|
def Cdo.hasCdo?(bin=@@CDO)
|
@@ -213,9 +232,16 @@ module Cdo
|
|
213
232
|
end
|
214
233
|
|
215
234
|
def Cdo.readCdf(iFile)
|
216
|
-
Cdo.loadCdf unless State[:
|
235
|
+
Cdo.loadCdf unless State[:returnCdf]
|
217
236
|
NetCDF.open(iFile)
|
218
237
|
end
|
238
|
+
|
239
|
+
def Cdo.selindexlist(args)
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
def Cdo.plot(args)
|
244
|
+
end
|
219
245
|
end
|
220
246
|
|
221
247
|
# Helper module for easy temp file handling
|
data/test/test_cdo.rb
CHANGED
@@ -35,6 +35,7 @@ class TestCdo < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_outputOperators
|
38
|
+
Cdo.debug = true
|
38
39
|
levels = Cdo.showlevel(:in => "-stdatm,0")
|
39
40
|
assert_equal([0,0].map(&:to_s),levels)
|
40
41
|
|
@@ -66,9 +67,8 @@ class TestCdo < Test::Unit::TestCase
|
|
66
67
|
(1...info.size).each {|i| assert_equal(0.0,info[i].split[-1].to_f)}
|
67
68
|
end
|
68
69
|
def test_operator_options
|
69
|
-
ofile = MyTempfile.path
|
70
70
|
targetLevels = [0,10,50,100,200,400,1000]
|
71
|
-
Cdo.stdatm(targetLevels
|
71
|
+
ofile = Cdo.stdatm(targetLevels)
|
72
72
|
levels = Cdo.showlevel(:in => ofile)
|
73
73
|
[0,1].each {|i| assert_equal(targetLevels.map(&:to_s),levels[i].split)}
|
74
74
|
end
|
@@ -82,17 +82,17 @@ class TestCdo < Test::Unit::TestCase
|
|
82
82
|
end
|
83
83
|
def test_chain
|
84
84
|
ofile = MyTempfile.path
|
85
|
-
|
85
|
+
Cdo.Debug = true
|
86
86
|
Cdo.setname('veloc',:in => " -copy -random,r1x1",:out => ofile,:options => "-f nc")
|
87
87
|
assert_equal(["veloc"],Cdo.showname(:in => ofile))
|
88
88
|
end
|
89
89
|
|
90
90
|
def test_diff
|
91
91
|
diffv = Cdo.diffn(:in => "-random,r1x1 -random,r1x1")
|
92
|
-
assert_equal(diffv[1].split(' ')[
|
93
|
-
assert_equal(diffv[1].split(' ')[-
|
92
|
+
assert_equal(diffv[1].split(' ')[-1],"random")
|
93
|
+
assert_equal(diffv[1].split(' ')[-3],"0.53060")
|
94
94
|
diff = Cdo.diff(:in => "-random,r1x1 -random,r1x1")
|
95
|
-
assert_equal(diff[1].split(' ')[-
|
95
|
+
assert_equal(diff[1].split(' ')[-3],"0.53060")
|
96
96
|
end
|
97
97
|
|
98
98
|
def test_operators
|
@@ -113,12 +113,12 @@ class TestCdo < Test::Unit::TestCase
|
|
113
113
|
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
114
114
|
Cdo.fldsum(:in => Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc"),:out => ofile0)
|
115
115
|
Cdo.fldsum(:in => "-stdatm,25,100,250,500,875,1400,2100,3000,4000,5000",:options => "-f nc",:out => ofile1)
|
116
|
-
Cdo.
|
116
|
+
Cdo.setReturnCdf
|
117
117
|
MyTempfile.showFiles
|
118
118
|
diff = Cdo.sub(:in => [ofile0,ofile1].join(' ')).var('T').get
|
119
119
|
assert_equal(0.0,diff.min)
|
120
120
|
assert_equal(0.0,diff.max)
|
121
|
-
Cdo.
|
121
|
+
Cdo.setReturnCdf(false)
|
122
122
|
end
|
123
123
|
|
124
124
|
def test_tempfile
|
@@ -131,27 +131,67 @@ class TestCdo < Test::Unit::TestCase
|
|
131
131
|
assert(File.exist?(ofile0))
|
132
132
|
end
|
133
133
|
|
134
|
-
def
|
134
|
+
def test_returnCdf
|
135
135
|
ofile = MyTempfile.path
|
136
|
-
vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc")
|
136
|
+
vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc",:force => true)
|
137
137
|
assert_equal(ofile,vals)
|
138
|
-
Cdo.
|
138
|
+
Cdo.setReturnCdf
|
139
139
|
vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc")
|
140
140
|
assert_equal(["lon","lat","level","P","T"],vals.var_names)
|
141
141
|
assert_equal(276,vals.var("T").get.flatten.mean.floor)
|
142
|
-
Cdo.
|
142
|
+
Cdo.unsetReturnCdf
|
143
143
|
vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc")
|
144
144
|
assert_equal(ofile,vals)
|
145
145
|
end
|
146
|
-
def
|
146
|
+
def test_simple_returnCdf
|
147
147
|
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
148
148
|
sum = Cdo.fldsum(:in => Cdo.stdatm(0,:options => "-f nc"),
|
149
|
-
:
|
149
|
+
:returnCdf => true).var("P").get
|
150
150
|
assert_equal(1013.25,sum.min)
|
151
151
|
sum = Cdo.fldsum(:in => Cdo.stdatm(0,:options => "-f nc"),:out => ofile0)
|
152
152
|
assert_equal(ofile0,sum)
|
153
|
-
|
153
|
+
test_returnCdf
|
154
|
+
end
|
155
|
+
def test_force
|
156
|
+
outs = []
|
157
|
+
# tempfiles
|
158
|
+
outs << Cdo.stdatm(0,10,20)
|
159
|
+
outs << Cdo.stdatm(0,10,20)
|
160
|
+
assert_not_equal(outs[0],outs[1])
|
154
161
|
|
162
|
+
# deticated output, force = true
|
163
|
+
outs.clear
|
164
|
+
outs << Cdo.stdatm(0,10,20,:out => 'test_force')
|
165
|
+
mtime0 = File.stat(outs[-1]).mtime
|
166
|
+
outs << Cdo.stdatm(0,10,20,:out => 'test_force')
|
167
|
+
mtime1 = File.stat(outs[-1]).mtime
|
168
|
+
assert_not_equal(mtime0,mtime1)
|
169
|
+
assert_equal(outs[0],outs[1])
|
170
|
+
FileUtils.rm('test_force')
|
171
|
+
outs.clear
|
172
|
+
|
173
|
+
# dedicated output, force = false
|
174
|
+
ofile = 'test_force_false'
|
175
|
+
outs << Cdo.stdatm(0,10,20,:out => ofile,:force => false)
|
176
|
+
mtime0 = File.stat(outs[-1]).mtime
|
177
|
+
outs << Cdo.stdatm(0,10,20,:out => ofile,:force => false)
|
178
|
+
mtime1 = File.stat(outs[-1]).mtime
|
179
|
+
assert_equal(mtime0,mtime1)
|
180
|
+
assert_equal(outs[0],outs[1])
|
181
|
+
FileUtils.rm(ofile)
|
182
|
+
outs.clear
|
183
|
+
|
184
|
+
# dedicated output, global force setting
|
185
|
+
ofile = 'test_force_global'
|
186
|
+
Cdo.forceOutput = false
|
187
|
+
outs << Cdo.stdatm(0,10,20,:out => ofile)
|
188
|
+
mtime0 = File.stat(outs[-1]).mtime
|
189
|
+
outs << Cdo.stdatm(0,10,20,:out => ofile)
|
190
|
+
mtime1 = File.stat(outs[-1]).mtime
|
191
|
+
assert_equal(mtime0,mtime1)
|
192
|
+
assert_equal(outs[0],outs[1])
|
193
|
+
FileUtils.rm(ofile)
|
194
|
+
outs.clear
|
155
195
|
end
|
156
196
|
|
157
197
|
def test_thickness
|
@@ -167,11 +207,22 @@ class TestCdo < Test::Unit::TestCase
|
|
167
207
|
end
|
168
208
|
|
169
209
|
def test_verticalLevels
|
210
|
+
Cdo.debug = true
|
170
211
|
targetThicknesses = [50.0, 100.0, 200.0, 300.0, 450.0, 600.0, 800.0, 1000.0, 1000.0, 1000.0]
|
171
212
|
sourceLevels = %W{25 100 250 500 875 1400 2100 3000 4000 5000}
|
172
213
|
thicknesses = Cdo.thicknessOfLevels(:in => "-selname,T #{Cdo.stdatm(*sourceLevels,:options => '-f nc')}")
|
173
214
|
assert_equal(targetThicknesses,thicknesses)
|
174
215
|
end
|
216
|
+
|
217
|
+
def test_parseArgs
|
218
|
+
io,opts = Cdo.parseArgs([1,2,3,:in => '1',:out => '2',:force => true,:returnCdf => "T"])
|
219
|
+
assert_equal("1",io[:in])
|
220
|
+
assert_equal("2",io[:out])
|
221
|
+
assert_equal(true,io[:force])
|
222
|
+
assert_equal("T",io[:returnCdf])
|
223
|
+
pp [io,opts]
|
224
|
+
end
|
225
|
+
|
175
226
|
if 'thingol' == `hostname`.chomp then
|
176
227
|
def test_readCdf
|
177
228
|
input = "-settunits,days -setyear,2000 -for,1,4"
|
@@ -179,13 +230,8 @@ class TestCdo < Test::Unit::TestCase
|
|
179
230
|
cdf = Cdo.readCdf(cdfFile)
|
180
231
|
assert_equal(['lon','lat','time','for'],cdf.var_names)
|
181
232
|
end
|
182
|
-
def
|
183
|
-
|
184
|
-
tempfilesEnd = Dir.glob('/tmp/Module*').sort
|
185
|
-
assert_equal(tempfilesStart,tempfilesEnd)
|
186
|
-
test_combine()
|
187
|
-
tempfilesEnd = Dir.glob('/tmp/Module**')
|
188
|
-
assert_empty(tempfilesStart-tempfilesEnd)
|
233
|
+
def test_selIndexListFromIcon
|
234
|
+
input = "~/data/icon/oce.nc"
|
189
235
|
end
|
190
236
|
end
|
191
237
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cdo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Easy access to the Climate Data operators
|
15
15
|
email: stark.dreamdetective@gmail.com
|
@@ -46,7 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
46
|
version: '0'
|
47
47
|
requirements: []
|
48
48
|
rubyforge_project:
|
49
|
-
rubygems_version: 1.8.
|
49
|
+
rubygems_version: 1.8.23
|
50
50
|
signing_key:
|
51
51
|
specification_version: 3
|
52
52
|
summary: Easy access to the Climate Data operators
|