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.
Files changed (6) hide show
  1. data/ChangeLog +3 -0
  2. data/README.rdoc +1 -1
  3. data/gemspec +2 -2
  4. data/lib/cdo.rb +88 -45
  5. data/test/test_cdo.rb +61 -1
  6. metadata +3 -2
data/ChangeLog ADDED
@@ -0,0 +1,3 @@
1
+ 1.0.0 2011-12-14: initial version
2
+ 1.0.1 2011-12-15: bugix release
3
+ 1.0.2 2012-01-11: return NetCDF/NArray (optional)
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.1'
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 TestJobQueue < Test::Unit::TestCase
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.1
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: 2011-12-15 00:00:00.000000000 Z
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: