cdo 1.0.1 → 1.0.2
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.
- data/ChangeLog +3 -0
- data/README.rdoc +1 -1
- data/gemspec +2 -2
- data/lib/cdo.rb +88 -45
- data/test/test_cdo.rb +61 -1
- metadata +3 -2
data/ChangeLog
ADDED
data/README.rdoc
CHANGED
@@ -59,6 +59,6 @@ Cdo.rb makes use of the GPLv2D License, see COPYING
|
|
59
59
|
|
60
60
|
Author:: Ralf Mueller <stark.dreamdetective@gmail.com>
|
61
61
|
Requires:: CDO version 1.5.x
|
62
|
-
License:: Copyright 2011 by Ralf Mueller
|
62
|
+
License:: Copyright 2011-2012 by Ralf Mueller
|
63
63
|
Released under GPLv2 license. See the COPYING
|
64
64
|
file included in the distribution.
|
data/gemspec
CHANGED
@@ -2,9 +2,9 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
spec = Gem::Specification.new do |s|
|
4
4
|
s.name = "cdo"
|
5
|
-
s.version = '1.0.
|
5
|
+
s.version = '1.0.2'
|
6
6
|
s.platform = Gem::Platform::RUBY
|
7
|
-
s.files = ["lib/cdo.rb"] + ["gemspec","COPYING","README.rdoc"]
|
7
|
+
s.files = ["lib/cdo.rb"] + ["gemspec","COPYING","README.rdoc","ChangeLog"]
|
8
8
|
s.test_file = "test/test_cdo.rb"
|
9
9
|
s.description = "Easy access to the Climate Data operators"
|
10
10
|
s.summary = "Easy access to the Climate Data operators"
|
data/lib/cdo.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
require 'pp'
|
2
2
|
|
3
|
+
# Copyright (C) 2011-2012 Ralf Mueller, ralf.mueller@zmaw.de
|
4
|
+
# See COPYING file for copying and redistribution conditions.
|
5
|
+
#
|
6
|
+
# This program is free software; you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation; version 2 of the License.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
|
3
15
|
# ==============================================================================
|
4
16
|
# CDO calling mechnism
|
5
17
|
module Cdo
|
6
|
-
State = {
|
18
|
+
State = {
|
19
|
+
:debug => false,
|
20
|
+
:returnArray => false
|
21
|
+
}
|
7
22
|
@@CDO = ENV['CDO'].nil? ? '/usr/bin/cdo' : ENV['CDO']
|
8
23
|
|
9
24
|
# Only operators with documentation are accessible vie the build-in help.
|
@@ -11,12 +26,60 @@ module Cdo
|
|
11
26
|
@@undocumentedOperators = %w[geopotheight pressure_fl pressure_hl]
|
12
27
|
@@addOperators = %w[boundaryLevels thicknessOfLevels]
|
13
28
|
|
29
|
+
private
|
30
|
+
def Cdo.call(cmd)
|
31
|
+
if (State[:debug])
|
32
|
+
puts '# DEBUG ====================================================================='
|
33
|
+
puts cmd
|
34
|
+
puts '# DEBUG ====================================================================='
|
35
|
+
puts IO.popen(cmd).read
|
36
|
+
else
|
37
|
+
system(cmd + ' 1>/dev/null 2>&1 ')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
def Cdo.run(cmd,ofile=nil,options='',returnArray=false)
|
41
|
+
cmd = "#{@@CDO} -O #{options} #{cmd} "
|
42
|
+
case ofile
|
43
|
+
when $stdout
|
44
|
+
cmd << " 2>/dev/null"
|
45
|
+
return IO.popen(cmd).readlines.map {|l| l.chomp.strip}
|
46
|
+
when nil
|
47
|
+
ofile = Tempfile.new("Cdo.rb").path
|
48
|
+
end
|
49
|
+
cmd << "#{ofile}"
|
50
|
+
call(cmd)
|
51
|
+
if State[:returnArray] or returnArray
|
52
|
+
return NetCDF.open(ofile)
|
53
|
+
else
|
54
|
+
return ofile
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
public
|
14
59
|
def Cdo.Debug=(value)
|
15
60
|
State[:debug] = value
|
16
61
|
end
|
17
62
|
def Cdo.Debug
|
18
63
|
State[:debug]
|
19
64
|
end
|
65
|
+
def Cdo.returnArray=(value)
|
66
|
+
if value
|
67
|
+
begin
|
68
|
+
require "numru/netcdf"
|
69
|
+
include NumRu
|
70
|
+
State[:returnArray] = true
|
71
|
+
|
72
|
+
rescue LoadError
|
73
|
+
warn "Could not load ruby's netcdf bindings. Please install it."
|
74
|
+
raise
|
75
|
+
end
|
76
|
+
else
|
77
|
+
State[:returnArray] = value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
def Cdo.returnArray
|
81
|
+
State[:returnArray]
|
82
|
+
end
|
20
83
|
|
21
84
|
# test if @@CDO can be used
|
22
85
|
def Cdo.checkCdo
|
@@ -28,13 +91,11 @@ module Cdo
|
|
28
91
|
puts IO.popen(@@CDO + " -V").readlines
|
29
92
|
end
|
30
93
|
end
|
31
|
-
|
32
94
|
def Cdo.setCdo(cdo)
|
33
95
|
puts "Will use #{cdo} instead of #@@CDO" if Cdo.Debug
|
34
96
|
@@CDO = cdo
|
35
97
|
end
|
36
98
|
|
37
|
-
|
38
99
|
def Cdo.getOperators
|
39
100
|
cmd = @@CDO + ' 2>&1'
|
40
101
|
help = IO.popen(cmd).readlines.map {|l| l.chomp.lstrip}
|
@@ -46,29 +107,6 @@ module Cdo
|
|
46
107
|
help[help.index("Operators:")+1].split
|
47
108
|
end
|
48
109
|
end
|
49
|
-
def Cdo.call(cmd)
|
50
|
-
if (State[:debug])
|
51
|
-
puts '# DEBUG ====================================================================='
|
52
|
-
puts cmd
|
53
|
-
puts '# DEBUG ====================================================================='
|
54
|
-
puts IO.popen(cmd).read
|
55
|
-
else
|
56
|
-
system(cmd + ' 1>/dev/null 2>&1 ')
|
57
|
-
end
|
58
|
-
end
|
59
|
-
def Cdo.run(cmd,ofile=nil,options='')
|
60
|
-
cmd = "#{@@CDO} -O #{options} #{cmd} "
|
61
|
-
case ofile
|
62
|
-
when $stdout
|
63
|
-
cmd << " 2>/dev/null"
|
64
|
-
return IO.popen(cmd).readlines.map {|l| l.chomp.strip}
|
65
|
-
when nil
|
66
|
-
ofile = Tempfile.new("Cdo.rb").path
|
67
|
-
end
|
68
|
-
cmd << "#{ofile}"
|
69
|
-
call(cmd)
|
70
|
-
return ofile
|
71
|
-
end
|
72
110
|
|
73
111
|
# Call an operator chain without checking opeartors
|
74
112
|
def Cdo.chainCall(chain,*args)
|
@@ -87,8 +125,29 @@ module Cdo
|
|
87
125
|
end
|
88
126
|
end
|
89
127
|
|
128
|
+
def Cdo.method_missing(sym, *args, &block)
|
129
|
+
# args is expected to look like [opt1,...,optN,:in => iStream,:out => oStream] where
|
130
|
+
# iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
|
131
|
+
puts "Operator #{sym.to_s} is called" if State[:debug]
|
132
|
+
if getOperators.include?(sym.to_s) or @@undocumentedOperators.include?(sym.to_s)
|
133
|
+
io = args.find {|a| a.class == Hash}
|
134
|
+
args.delete_if {|a| a.class == Hash}
|
135
|
+
if /(diff|info|show|griddes)/.match(sym)
|
136
|
+
run(" -#{sym.to_s} #{io[:in]} ",$stdout)
|
137
|
+
else
|
138
|
+
opts = args.empty? ? '' : ',' + args.reject {|a| a.class == Hash}.join(',')
|
139
|
+
run(" -#{sym.to_s}#{opts} #{io[:in]} ",io[:out],io[:options],io[:returnArray])
|
140
|
+
end
|
141
|
+
else
|
142
|
+
warn "Operator #{sym.to_s} not found"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
#==================================================================
|
147
|
+
# Addional operotors:
|
148
|
+
#------------------------------------------------------------------
|
90
149
|
def Cdo.boundaryLevels(args)
|
91
|
-
ilevels = Cdo.showlevel(:in => args[:in]).map(&:to_f)
|
150
|
+
ilevels = Cdo.showlevel(:in => args[:in])[0].split.map(&:to_f)
|
92
151
|
bound_levels = Array.new(ilevels.size+1)
|
93
152
|
bound_levels[0] = 0
|
94
153
|
(1..ilevels.size).each {|i|
|
@@ -106,25 +165,9 @@ module Cdo
|
|
106
165
|
}
|
107
166
|
delta_levels
|
108
167
|
end
|
109
|
-
|
110
|
-
def Cdo.method_missing(sym, *args, &block)
|
111
|
-
# args is expected to look like [opt1,...,optN,:in => iStream,:out => oStream] where
|
112
|
-
# iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
|
113
|
-
puts "Operator #{sym.to_s} is called" if State[:debug]
|
114
|
-
if getOperators.include?(sym.to_s) or @@undocumentedOperators.include?(sym.to_s)
|
115
|
-
io = args.find {|a| a.class == Hash}
|
116
|
-
args.delete_if {|a| a.class == Hash}
|
117
|
-
if /(info|show|griddes)/.match(sym)
|
118
|
-
run(" -#{sym.to_s} #{io[:in]} ",$stdout)
|
119
|
-
else
|
120
|
-
opts = args.empty? ? '' : ',' + args.reject {|a| a.class == Hash}.join(',')
|
121
|
-
run(" -#{sym.to_s}#{opts} #{io[:in]} ",io[:out],io[:options])
|
122
|
-
end
|
123
|
-
else
|
124
|
-
warn "Operator #{sym.to_s} not found"
|
125
|
-
end
|
126
|
-
end
|
127
168
|
end
|
169
|
+
|
170
|
+
# Helper module for easy temp file handling
|
128
171
|
module MyTempfile
|
129
172
|
require 'tempfile'
|
130
173
|
@@_tempfiles = []
|
data/test/test_cdo.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
2
|
require 'test/unit'
|
3
3
|
require 'cdo'
|
4
|
+
require 'pp'
|
4
5
|
|
5
|
-
class
|
6
|
+
class TestCdo < Test::Unit::TestCase
|
6
7
|
|
7
8
|
DEFAULT_CDO_PATH = '/usr/bin/cdo'
|
8
9
|
def setup
|
@@ -40,6 +41,20 @@ class TestJobQueue < Test::Unit::TestCase
|
|
40
41
|
assert_equal("File format: GRIB",info[0])
|
41
42
|
|
42
43
|
end
|
44
|
+
def test_args
|
45
|
+
#Cdo.Debug = true
|
46
|
+
#MyTempfile.setPersist(true)
|
47
|
+
ofile0 = MyTempfile.path
|
48
|
+
ofile1 = MyTempfile.path
|
49
|
+
ofile2 = MyTempfile.path
|
50
|
+
ofile3 = MyTempfile.path
|
51
|
+
Cdo.stdatm(0,20,40,80,200,230,400,600,1100,:out => ofile0)
|
52
|
+
Cdo.intlevel(0,10,50,100,500,1000, :in => ofile0,:out => ofile1)
|
53
|
+
Cdo.intlevel([0,10,50,100,500,1000],:in => ofile0,:out => ofile2)
|
54
|
+
Cdo.sub(:in => [ofile1,ofile2].join(' '),:out => ofile3)
|
55
|
+
info = Cdo.infon(:in => ofile3)
|
56
|
+
(1...info.size).each {|i| assert_equal(0.0,info[i].split[-1].to_f)}
|
57
|
+
end
|
43
58
|
def test_operator_options
|
44
59
|
ofile = MyTempfile.path
|
45
60
|
targetLevels = [0,10,50,100,200,400,1000]
|
@@ -61,6 +76,51 @@ class TestJobQueue < Test::Unit::TestCase
|
|
61
76
|
Cdo.chainCall("-setname,veloc -copy",:in => "-random,r1x1",:out => ofile,:options => "-f nc")
|
62
77
|
assert_equal(["veloc"],Cdo.showname(:in => ofile))
|
63
78
|
end
|
79
|
+
|
80
|
+
def test_diff
|
81
|
+
diffv = Cdo.diffn(:in => "-random,r1x1 -random,r1x1")
|
82
|
+
assert_equal(diffv[1].split(' ')[4],"random")
|
83
|
+
assert_equal(diffv[1].split(' ')[-1],"0.53060")
|
84
|
+
diff = Cdo.diff(:in => "-random,r1x1 -random,r1x1")
|
85
|
+
assert_equal(diff[1].split(' ')[-1],"0.53060")
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_bndLevels
|
89
|
+
ofile = MyTempfile.path
|
90
|
+
Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc")
|
91
|
+
assert_equal([0, 50.0, 150.0, 350.0, 650.0, 1100.0, 1700.0, 2500.0, 3500.0, 4500.0, 5500.0],
|
92
|
+
Cdo.boundaryLevels(:in => "-selname,T #{ofile}"))
|
93
|
+
assert_equal([50.0, 100.0, 200.0, 300.0, 450.0, 600.0, 800.0, 1000.0, 1000.0, 1000.0],
|
94
|
+
Cdo.thicknessOfLevels(:in => ofile))
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_returnArray
|
98
|
+
ofile = MyTempfile.path
|
99
|
+
vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc")
|
100
|
+
assert_equal(ofile,vals)
|
101
|
+
Cdo.returnArray = true
|
102
|
+
vals = Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:out => ofile,:options => "-f nc")
|
103
|
+
assert_equal(["lon","lat","level","P","T"],vals.var_names)
|
104
|
+
assert_equal(276,vals.var("T").get.flatten.mean.floor)
|
105
|
+
Cdo.returnArray = false
|
106
|
+
end
|
107
|
+
def test_combine
|
108
|
+
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
109
|
+
Cdo.fldsum(:in => Cdo.stdatm(25,100,250,500,875,1400,2100,3000,4000,5000,:options => "-f nc"),:out => ofile0)
|
110
|
+
ofile1 = Cdo.fldsum(:in => "-stdatm,25,100,250,500,875,1400,2100,3000,4000,5000",:options => "-f nc")
|
111
|
+
Cdo.returnArray = true
|
112
|
+
diff = Cdo.sub(:in => [ofile0,ofile1].join(' '),:out => MyTempfile.path).var('T').get
|
113
|
+
assert_equal(0.0,diff.min)
|
114
|
+
assert_equal(0.0,diff.max)
|
115
|
+
Cdo.returnArray = false
|
116
|
+
end
|
117
|
+
def test_simple_returnArray
|
118
|
+
ofile0, ofile1 = MyTempfile.path, MyTempfile.path
|
119
|
+
sum = Cdo.fldsum(:in => Cdo.stdatm(0,:options => "-f nc"),
|
120
|
+
:returnArray => true).var("P").get
|
121
|
+
assert_equal(1013.25,sum.min)
|
122
|
+
test_returnArray
|
123
|
+
end
|
64
124
|
end
|
65
125
|
|
66
126
|
# # Calling simple operators
|
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.0.2
|
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:
|
12
|
+
date: 2012-01-11 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
|
@@ -23,6 +23,7 @@ files:
|
|
23
23
|
- gemspec
|
24
24
|
- COPYING
|
25
25
|
- README.rdoc
|
26
|
+
- ChangeLog
|
26
27
|
- test/test_cdo.rb
|
27
28
|
homepage: http://code.zmaw.de/projects/cdo
|
28
29
|
licenses:
|