cdp 0.0.4 → 0.0.5

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 (5) hide show
  1. data/README.textile +1 -1
  2. data/gemspec +1 -1
  3. data/lib/cdp.rb +156 -23
  4. data/test/test_cdp.rb +43 -2
  5. metadata +2 -2
data/README.textile CHANGED
@@ -11,7 +11,7 @@ h2. changelog
11
11
 
12
12
  At this early stage, please look at the commits. The release number are only used for charing the gems.
13
13
 
14
- |0.0.x | |
14
+ |0.0.5 | update for cdo.rb 1.2.0 |
15
15
  | ||
16
16
 
17
17
  h2. license
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 = "cdp"
6
- s.version = '0.0.4'
6
+ s.version = '0.0.5'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.files = ["lib/cdp.rb"] + ["gemspec"]
9
9
  s.test_file = "test/test_cdp.rb"
data/lib/cdp.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  require 'cdo'
2
2
  require 'socket'
3
- module Cdp
3
+ require "numru/netcdf"
4
+ require 'numru/netcdf_miss'
5
+ include NumRu
4
6
 
7
+ module Cdp
5
8
  @@debug = false
6
9
 
7
-
8
10
  # setup of CDO on different machines based on the hostname
9
11
  def Cdp.setCDO
10
12
  hostname = Socket.gethostname
@@ -60,40 +62,171 @@ module Cdp
60
62
 
61
63
  # compute area weights from an area variable
62
64
  def Cdp.areaWeights(areaVarname,areaFile,ofile=nil,force=false)
63
- area = Cdo.selname(areaVarname,:in => areaFile)
64
- areaSum = Cdo.enlarge(area,:in => "-fldsum #{area}")
65
65
  if ofile.nil?
66
- weights = Cdo.setname("area_weight",:in => " -div #{area} #{areaSum}")
66
+ area = Cdo.selname(areaVarname,:input => areaFile)
67
+ Cdo.setname("area_weight",:input => " -div #{area} -enlarge,#{area} -fldsum #{area}")
67
68
  else
68
- unless force
69
- unless File.exist?(ofile)
70
- Cdo.setname("area_weight",:in => " -div #{area} #{areaSum}", :out => ofile)
71
- else
72
- puts "Resuse existing file #{ofile}" if @@debug
73
- return ofile
74
- end
69
+ unless File.exist?(ofile) and not force
70
+ puts "Resuse existing file #{ofile}" if @@debug
71
+ return ofile
75
72
  else
76
- Cdo.setname("area_weight",:in => " -div #{area} #{areaSum}", :out => ofile)
73
+ area = Cdo.selname(areaVarname,:input => areaFile)
74
+ Cdo.setname("area_weight",:input => " -div #{area} -enlarge,#{area} -fldsum #{area}", :output => ofile)
77
75
  end
78
76
  end
79
77
  end
80
78
 
81
79
  # compute area weights from an area variable with a mask from another file
82
80
  def Cdp.maskedAreaWeights(areaVarname,areaFile,maskVarname,maskFile,ofile=nil,force=false)
83
- maskedArea = Cdo.div(:in => " -selname,#{areaVarname} #{areaFile} -selname,#{maskVarname} #{maskFile}")
84
81
  if ofile.nil?
85
- maskedAreaSum = Cdo.setname("area_weight", :in => " -div #{maskedArea} -enlarge,#{maskedArea} -fldsum #{maskedArea}")
82
+ maskedArea = Cdo.div(:input => " -selname,#{areaVarname} #{areaFile} -selname,#{maskVarname} #{maskFile}")
83
+ Cdo.setname("area_weight", :input => " -div #{maskedArea} -enlarge,#{maskedArea} -fldsum #{maskedArea}")
86
84
  else
87
- unless force
88
- unless File.exist?(ofile)
89
- Cdo.setname("area_weight", :in => " -div #{maskedArea} -enlarge,#{maskedArea} -fldsum #{maskedArea}", :out => ofile)
90
- else
91
- puts "Resuse existing file #{ofile}" if @@debug
92
- return ofile
93
- end
85
+ if File.exist?(ofile) and not force
86
+ puts "Resuse existing file #{ofile}" if @@debug
87
+ return ofile
94
88
  else
95
- Cdo.setname("area_weight", :in => " -div #{maskedArea} -enlarge,#{maskedArea} -fldsum #{maskedArea}", :out => ofile)
89
+ maskedArea = Cdo.div(:input => " -selname,#{areaVarname} #{areaFile} -selname,#{maskVarname} #{maskFile}")
90
+ Cdo.setname("area_weight", :input => " -div #{maskedArea} -enlarge,#{maskedArea} -fldsum #{maskedArea}", :output => ofile)
96
91
  end
97
92
  end
98
93
  end
94
+
95
+ # split data file with global grid into 2 separate files with northern and
96
+ # southern hemisphere grid
97
+ # TODO: currently ICON cell variable are supported only
98
+ def Cdp.splitHemisphere(iFilename,varname,lon,lat,dim='2d')
99
+ iFile = NetCDF.open(iFilename)
100
+ unless iFile.var_names.include?(varname)
101
+ warn "Could not find #{varname} in #{iFilename}"
102
+ raise IOError
103
+ end
104
+ lats = iFile.var(lat).get
105
+ var = iFile.var(varname)
106
+ varDims = var.dim_names
107
+ varValues = var.get_with_miss
108
+ splittedDim = varDims[0]
109
+
110
+ # compute location indices and corresponding values
111
+ nhIndeces = (lats>0.0).where
112
+ shIndeces = (lats<0.0).where
113
+
114
+ case varValues.shape.size
115
+ when 3
116
+ varValuesNH = varValues[nhIndeces,true,true]
117
+ varValuesSH = varValues[shIndeces,true,true]
118
+ when 2
119
+ varValuesNH = varValues[nhIndeces,true]
120
+ varValuesSH = varValues[shIndeces,true]
121
+ when 1
122
+ varValuesNH = varValues[nhIndeces]
123
+ varValuesSH = varValues[shIndeces]
124
+ end
125
+
126
+ # create output
127
+ iBaseFilename = File.basename(iFilename)
128
+ nhFile,shFile = "nh_#{iBaseFilename}","sh_#{iBaseFilename}"
129
+ [nhFile,shFile].each_with_index {|file,i|
130
+ puts "Creating '#{file}' ...."
131
+ indeces = [nhIndeces,shIndeces][i]
132
+ oFile = NetCDF.create(file)
133
+
134
+ # create data definitions
135
+ iFile.each_dim {|dim|
136
+ pp dim.name
137
+ if splittedDim == dim.name
138
+ oFile.def_dim(dim.name,indeces.size)
139
+ else
140
+ oFile.def_dim(dim.name,dim.length)
141
+ end
142
+ }
143
+
144
+ # copy attributes
145
+ iFile.each_var {|var|
146
+ next unless ([varname] + varDims + [lon,lat] + [lon,lat].map {|c| c+"_vertices"}).flatten.include?(var.name)
147
+ newvar = oFile.def_var( var.name, var.ntype, var.dim_names )
148
+ var.each_att{|att| newvar.put_att( att.name, att.get )}
149
+ }
150
+ oFile.enddef
151
+ iFile.each_var {|var|
152
+ next unless ([varname] + varDims + [lon,lat] + [lon,lat].map {|c| c+"_vertices"}).flatten.include?(var.name)
153
+ case var.name
154
+ when varname
155
+ case varDims.size
156
+ when 3
157
+ oFile.var(var.name).put(var.get[indeces,true,true])
158
+ when 2
159
+ oFile.var(var.name).put(var.get[indeces,true])
160
+ end
161
+ when 'p_ice_concSum'
162
+ oFile.var(var.name).put(var.get[indeces,true])
163
+ when 'cell_area'
164
+ oFile.var(var.name).put(var.get[indeces])
165
+ when lon,lat
166
+ oFile.var(var.name).put(var.get[indeces])
167
+ when lon+'_vertices',lat+'_vertices'
168
+ oFile.var(var.name).put(var.get[true,indeces])
169
+ else
170
+ oFile.var(var.name).put(var.get)
171
+ end
172
+ }
173
+ oFile.close
174
+ }
175
+
176
+ [nhFile,shFile]
177
+ end
178
+ def Cdp.splitICONHemisphere(iFilename,varname,lon,lat)
179
+ iFile = NetCDF.open(iFilename)
180
+ lats = iFile.var(lat).get
181
+ iceValues = iFile.var(varname).get_with_miss
182
+
183
+ # compute location indices and corresponding values
184
+ nhIndeces = (lats>0.0).where
185
+ shIndeces = (lats<0.0).where
186
+ iceValuesNH = iceValues[nhIndeces,true,1..-1]
187
+ iceValuesSH = iceValues[shIndeces,true,1..-1]
188
+
189
+
190
+ # create output
191
+ nhFile,shFile = "nh_#{iFilename}","sh_#{iFilename}"
192
+ [nhFile,shFile].each_with_index {|file,i|
193
+ puts "Creating '#{file}' ...."
194
+ indeces = [nhIndeces,shIndeces][i]
195
+ f = NetCDF.create(file)
196
+ iFile.each_dim {|dim|
197
+ next if ['clon','clat','ncells'].include?(dim.name) or
198
+ f.def_dim(dim.name,dim.length)
199
+ }
200
+ ["clon","clat","ncells"].each {|hdim|
201
+ f.def_dim(hdim,indeces.size)
202
+ }
203
+
204
+ iFile.each_var{|var|
205
+ a = {var.name => var.dim_names}
206
+ newvar = f.def_var( var.name, var.ntype, var.dim_names )
207
+ var.each_att{|att| newvar.put_att( att.name, att.get )}
208
+ }
209
+ f.enddef
210
+ iFile.each_var{|var|
211
+ #puts var.name
212
+ case var.name
213
+ when varname
214
+ f.var(var.name).put(var.get[indeces,true,true])
215
+ when 'p_ice_concSum'
216
+ f.var(var.name).put(var.get[indeces,true])
217
+ when 'cell_area'
218
+ f.var(var.name).put(var.get[indeces])
219
+ when lon,lat
220
+ f.var(var.name).put(var.get[indeces])
221
+ when lon+'_vertices',lat+'_vertices'
222
+ f.var(var.name).put(var.get[true,indeces])
223
+ else
224
+ f.var(var.name).put(var.get)
225
+ end
226
+ }
227
+ f.close
228
+ }
229
+
230
+ [nhFile,shFile]
231
+ end
99
232
  end
data/test/test_cdp.rb CHANGED
@@ -6,6 +6,9 @@ require 'pp'
6
6
  DATADIR = ENV['HOME'] + "/data/icon"
7
7
  ICONGRID = DATADIR + "/icon-R2B04-grid-etopo.nc"
8
8
  ICONMASK = DATADIR + "/mask.nc"
9
+ ICONOCE = DATADIR + "/oce.nc"
10
+ ICONOCEL = DATADIR + "/oceLong.nc"
11
+ ICONICE = DATADIR + "/oce.nc"
9
12
  WEIGHTS = File.dirname(__FILE__) + "/weights.nc"
10
13
 
11
14
  class TestCdp < Test::Unit::TestCase
@@ -22,20 +25,30 @@ class TestCdp < Test::Unit::TestCase
22
25
  Cdp.setDebug
23
26
  weights = Cdp.areaWeights("cell_area",ICONGRID)
24
27
  # global sum over all weights should be 1
25
- assert_equal("1",Cdo.outputkey("value", :in => Cdo.fldsum(:in => weights)).first)
28
+ assert_equal("1",Cdo.outputkey("value", :input => Cdo.fldsum(:input => weights)).first)
26
29
  weights = Cdp.areaWeights("cell_area",ICONGRID,weights)
27
30
  weights = Cdp.areaWeights("cell_area",ICONGRID,WEIGHTS)
28
31
  assert_equal(WEIGHTS,weights)
29
32
  weights = Cdp.areaWeights("cell_area",ICONGRID,WEIGHTS)
30
33
  assert_equal(WEIGHTS,weights)
31
34
  end
35
+
36
+ def test_splitFiles
37
+ files = []
38
+ files << '../A/a' << '../A/aa' << '../B/b' << '../B/bb' << 'gridfile'
39
+ grid, exp, exp4ana = Cdp.splitFilesIntoExperiments(files)
40
+ assert_equal('gridfile',grid)
41
+ assert_equal(exp['A'],['../A/a','../A/aa'])
42
+ assert_equal(exp['B'],['../B/b','../B/bb'])
43
+ end
32
44
  def test_masked_area_weight
33
45
  Cdo.debug = false
34
46
  Cdp.setCDO
35
47
  Cdp.setDebug
36
48
  weights = Cdp.maskedAreaWeights("cell_area",ICONGRID,"wet_c",ICONMASK)
37
49
  # global sum over all weights should be 1
38
- assert_equal("1",Cdo.outputkey("value", :in => Cdo.fldsum(:in => weights)).uniq.first)
50
+ pp Cdo.outputkey("value", :input => Cdo.fldsum(:input => weights))
51
+ assert_equal("1",Cdo.outputkey("value", :input => Cdo.fldsum(:input => weights)).uniq.first)
39
52
 
40
53
  weights = Cdp.maskedAreaWeights("cell_area",ICONGRID,"wet_c",ICONMASK,WEIGHTS)
41
54
  assert_equal(WEIGHTS,weights)
@@ -44,4 +57,32 @@ class TestCdp < Test::Unit::TestCase
44
57
  weights = Cdp.maskedAreaWeights("cell_area",ICONGRID,"wet_c",ICONMASK,WEIGHTS,true)
45
58
  assert_equal(WEIGHTS,weights)
46
59
  end
60
+ def test_split_sphere
61
+ # one timesteps
62
+ Cdp.splitHemisphere(ICONOCE,"ELEV",'clon','clat')
63
+ return
64
+ # with missing values
65
+ Cdo.debug = true
66
+ maskedOce = Cdo.div(:input => "-selname,T #{ICONOCE} -selname,wet_c #{ICONOCE}")
67
+ Cdp.splitHemisphere(maskedOce,"T",'clon','clat')
68
+ maskedOce = Cdo.div(:input => "-selname,ELEV #{ICONOCE} -sellevidx,1 -selname,wet_c #{ICONOCE}")
69
+ Cdp.splitHemisphere(maskedOce,"ELEV",'clon','clat')
70
+
71
+ # 10 timesteps
72
+ Cdp.splitHemisphere(ICONOCEL,"ELEV",'clon','clat')
73
+ Cdp.splitHemisphere(ICONOCEL,"T",'clon','clat')
74
+ # with missing values
75
+ Cdo.debug = true
76
+ maskedOce = Cdo.div(:input => "-selname,T #{ICONOCEL} -selname,wet_c #{ICONOCEL}")
77
+ Cdp.splitHemisphere(maskedOce,"T",'clon','clat')
78
+ maskedOce = Cdo.div(:input => "-selname,ELEV #{ICONOCEL} -sellevidx,1 -selname,wet_c #{ICONOCEL}")
79
+ Cdp.splitHemisphere(maskedOce,"ELEV",'clon','clat')
80
+ end
81
+ def test_split_icon_sphere
82
+
83
+ # one timesteps
84
+ elev = Cdo.selname("ELEV",:input => ICONOCEL)
85
+ pp Cdo.infov(:input => elev)
86
+ Cdp.splitICONHemisphere(elev,"ELEV",'clon','clat')
87
+ end
47
88
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cdp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
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-10-31 00:00:00.000000000 Z
12
+ date: 2012-11-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cdo