cdp 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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