rb-grib 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ #Total precipitation
2
+ 'Total precipitation' = {
3
+ discipline = 0 ;
4
+ parameterCategory = 1 ;
5
+ parameterNumber = 8 ;
6
+ }
7
+ #Total cloud cover
8
+ 'Total cloud cover' = {
9
+ discipline = 0 ;
10
+ parameterCategory = 6 ;
11
+ parameterNumber = 1 ;
12
+ }
13
+ #Low cloud cover
14
+ 'Low cloud cover' = {
15
+ discipline = 0 ;
16
+ parameterCategory = 6 ;
17
+ parameterNumber = 3 ;
18
+ }
19
+ #Medium cloud cover
20
+ 'Medium cloud cover' = {
21
+ discipline = 0 ;
22
+ parameterCategory = 6 ;
23
+ parameterNumber = 4 ;
24
+ }
25
+ #High cloud cover
26
+ 'High cloud cover' = {
27
+ discipline = 0 ;
28
+ parameterCategory = 6 ;
29
+ parameterNumber = 5 ;
30
+ }
@@ -0,0 +1,30 @@
1
+ #Total precipitation
2
+ '228' = {
3
+ discipline = 0 ;
4
+ parameterCategory = 1 ;
5
+ parameterNumber = 8 ;
6
+ }
7
+ #Total cloud cover
8
+ '164' = {
9
+ discipline = 0 ;
10
+ parameterCategory = 6 ;
11
+ parameterNumber = 1 ;
12
+ }
13
+ #Low cloud cover
14
+ '186' = {
15
+ discipline = 0 ;
16
+ parameterCategory = 6 ;
17
+ parameterNumber = 3 ;
18
+ }
19
+ #Medium cloud cover
20
+ '187' = {
21
+ discipline = 0 ;
22
+ parameterCategory = 6 ;
23
+ parameterNumber = 4 ;
24
+ }
25
+ #High cloud cover
26
+ '188' = {
27
+ discipline = 0 ;
28
+ parameterCategory = 6 ;
29
+ parameterNumber = 5 ;
30
+ }
@@ -0,0 +1,30 @@
1
+ #Total precipitation
2
+ 'tp' = {
3
+ discipline = 0 ;
4
+ parameterCategory = 1 ;
5
+ parameterNumber = 8 ;
6
+ }
7
+ #Total cloud cover
8
+ 'tcc' = {
9
+ discipline = 0 ;
10
+ parameterCategory = 6 ;
11
+ parameterNumber = 1 ;
12
+ }
13
+ #Low cloud cover
14
+ 'lcc' = {
15
+ discipline = 0 ;
16
+ parameterCategory = 6 ;
17
+ parameterNumber = 3 ;
18
+ }
19
+ #Medium cloud cover
20
+ 'mcc' = {
21
+ discipline = 0 ;
22
+ parameterCategory = 6 ;
23
+ parameterNumber = 4 ;
24
+ }
25
+ #High cloud cover
26
+ 'hcc' = {
27
+ discipline = 0 ;
28
+ parameterCategory = 6 ;
29
+ parameterNumber = 5 ;
30
+ }
@@ -0,0 +1,30 @@
1
+ #Total precipitation
2
+ 'kg m**-2' = {
3
+ discipline = 0 ;
4
+ parameterCategory = 1 ;
5
+ parameterNumber = 8 ;
6
+ }
7
+ #Total cloud cover
8
+ '%' = {
9
+ discipline = 0 ;
10
+ parameterCategory = 6 ;
11
+ parameterNumber = 1 ;
12
+ }
13
+ #Low cloud cover
14
+ '%' = {
15
+ discipline = 0 ;
16
+ parameterCategory = 6 ;
17
+ parameterNumber = 4 ;
18
+ }
19
+ #Medium cloud cover
20
+ '%' = {
21
+ discipline = 0 ;
22
+ parameterCategory = 6 ;
23
+ parameterNumber = 4 ;
24
+ }
25
+ #High cloud cover
26
+ '%' = {
27
+ discipline = 0 ;
28
+ parameterCategory = 6 ;
29
+ parameterNumber = 5 ;
30
+ }
@@ -1,8 +1,3 @@
1
- require "narray_miss"
2
- require "date"
3
- require "numru/grib.so"
4
-
5
-
6
1
  module NumRu
7
2
  class Grib
8
3
  class << self
@@ -45,45 +40,9 @@ module NumRu
45
40
  return false
46
41
  end
47
42
 
48
- def var_names
49
- parse_vars unless @vars
50
- return @vars.keys
51
- end
52
- def var(name)
53
- parse_vars unless @vars
54
- var = @vars[name]
55
- return nil if var.nil?
56
- return ::NumRu::GribVar.parse(self, var, name)
57
- end
58
43
  def inspect
59
44
  "Grib: #{path}"
60
45
  end
61
- private
62
- def parse_vars
63
- vars = Hash.new
64
- get_messages.each do |msg|
65
- name = msg.sname
66
- # zn = msg.z_sname
67
- # name << "_" << zn unless /\A(pl|isobaricIn)/ =~ zn
68
- hash = (vars[name] ||= Hash.new)
69
- nij = [msg.get_value("Ni"), msg.get_value("Nj"), msg.gtype, msg.z_type]
70
- if hash[nij]
71
- hash[nij][1].push msg
72
- else
73
- hash[nij] = [hash.length, [msg]]
74
- end
75
- end
76
- @vars = Hash.new
77
- vars.each do |name,hash|
78
- if hash.length == 1
79
- @vars[name] = hash.values[0][1]
80
- else
81
- hash.each do |k,ary|
82
- @vars[name+"_"+ary[0].to_s] = ary[1]
83
- end
84
- end
85
- end
86
- end
87
46
  end # class Grib
88
47
 
89
48
  class GribMessage
@@ -110,7 +69,7 @@ module NumRu
110
69
  get_value("indicatorOfTypeOfLevel") || get_value("typeOfLevel") || "level"
111
70
  end
112
71
  def z_value
113
- get_value("level")
72
+ get_value("levels") || get_value("level")
114
73
  end
115
74
  def z_units
116
75
  get_value("pressureUnits")
@@ -120,8 +79,8 @@ module NumRu
120
79
  h = get_value("dataTime").to_s.rjust(4,"0")
121
80
  return DateTime.parse(d << h)
122
81
  end
123
- def forecast_time
124
- get_value("forecastTime")
82
+ def step
83
+ get_value("step")
125
84
  end
126
85
  def time_interval
127
86
  get_value("lengthOfTimeRange")
@@ -180,136 +139,7 @@ module NumRu
180
139
 
181
140
  class GribVar
182
141
  Day0 = DateTime.new(1900)
183
- MAXNDIM = 7 # lon, lat, lev, t, forecastTime, timeInterval, ensemble
184
- class << self
185
- def parse(file,msgs,name)
186
- msg = msgs[0]
187
- va = ::NumRu::GribVar.new(file,name)
188
- va.put_att("long_name", msg.name)
189
- # va.put_att("standard_name",std_name)
190
- va.put_att("units",msg.units) if msg.units
191
- va.put_att("grid_type", msg.gtype)
192
- va.put_att("missing_value", [msg.missing_value]) if msg.missing_value
193
- vdim = Array.new
194
- xy_dims = 0
195
- msg.get_xy.sort{|x,y| x["ij"]<=>y["ij"] }.each do |xy|
196
- val = xy.delete("value")
197
- sname = xy.delete("short_name")
198
- ij = xy.delete("ij")
199
- if val.length > 1
200
- d = va.def_dim(sname, -1)
201
- d.put(val)
202
- xy.each{|k,v| d.put_att(k,v)}
203
- xy_dims += 1
204
- else
205
- #xy.each{|k,v| va.put_att(k,v)}
206
- end
207
- end
208
- z = Array.new
209
- t = Array.new
210
- ft = Array.new
211
- ti = Array.new
212
- en = Array.new
213
- hash = Hash.new
214
- msgs.each_with_index do |msg,i|
215
- zv = msg.z_value
216
- tv = get_time(msg.date)
217
- ftv = msg.forecast_time
218
- tiv = msg.time_interval
219
- env = msg.ensemble_member
220
- z.push zv
221
- t.push tv
222
- ft.push ftv
223
- ti.push tiv
224
- en.push env
225
- ary = [zv,tv,ftv,tiv,env]
226
- if hash[ary] # error
227
- m1 = msgs[hash[ary]]
228
- m2 = msgs[i]
229
- a1 = m1.get_keys.map{|k| [k,m1.get_value(k)]}
230
- a2 = m2.get_keys.map{|k| [k,m2.get_value(k)]}
231
- a = Array.new
232
- a1.length.times{|j| a.push [a1[j],a2[j]] if a1[j]!=a2[j]}
233
- warn "BUG: send the following message to the developers"
234
- p ary
235
- p a
236
- raise("error")
237
- end
238
- hash[ary] = i
239
- end
240
- hash = hash.invert
241
- [z, t, ft, ti, en].each{|a| a.uniq!}
242
- # [z, t, ft, ti, en].each{|a| a.uniq!; a.sort!}
243
- idx = Array.new(msgs.length) do |i|
244
- zv, tv, ftv, tiv, env = hash[i]
245
- [z.index(zv), t.index(tv), ft.index(ftv), ti.index(tiv), en.index(env)]
246
- end
247
- del_dims = Array.new
248
- if z.length == 1
249
- va.put_att("level_type", msg.z_type)
250
- va.put_att("level_value", [z[0]])
251
- va.put_att("level_units", msg.z_units) if msg.z_units
252
- del_dims.push xy_dims
253
- else
254
- d = va.def_dim(msg.z_sname, -1)
255
- d.put_att("long_name", msg.z_type)
256
- d.put_att("units", msg.z_units) if msg.z_units
257
- d.put(NArray.to_na(z))
258
- end
259
- if t.length == 1
260
- va.put_att("time", msg.date.to_s)
261
- del_dims.push xy_dims + 1
262
- else
263
- d = va.def_dim("time", -1)
264
- d.put_att("long_name","time")
265
- d.put_att("units","hours since #{Day0.strftime('%Y-%m-%d %H:%M:%S')}")
266
- d.put(NArray.to_na(t))
267
- end
268
- if ft.length == 1
269
- va.put_att("forecast_time", [msg.forecast_time]) if msg.forecast_time
270
- va.put_att("forcast_time_units", msg.step_units) if msg.step_units
271
- del_dims.push xy_dims + 2
272
- else
273
- d = va.def_dim("forecast_time", -1)
274
- d.put_att("long_name", "forecast_time")
275
- d.put_att("units", msg.step_units) if msg.step_units
276
- d.put(NArray.to_na(ft))
277
- end
278
- if ti.length == 1
279
- del_dims.push xy_dims + 3
280
- else
281
- d = va.def_dim("time_interval", -1)
282
- d.put_att("long_name", "time_interval")
283
- d.put_att("units", msg.step_units) if msg.step_units
284
- d.put(NArray.to_na(ti))
285
- end
286
- if en.length == 1
287
- del_dims.push xy_dims + 4
288
- else
289
- d = va.def_dim("member", -1)
290
- d.put_att("long_name", "ensemble_member")
291
- d.put(NArray.to_na(en))
292
- end
293
- va.set_msgs(msgs, idx, xy_dims, del_dims)
294
- return va
295
- end
296
- def get_time(date)
297
- ((date - Day0)*24).to_f
298
- end
299
- end # class << self
300
- attr_reader :file, :name
301
- def initialize(file,name)
302
- @file = file
303
- @name = name
304
- @attr = Hash.new
305
- @dims = Array.new
306
- end
307
- def set_msgs(msgs, idx, xy_dims, del_dims)
308
- @msgs = msgs
309
- @idx = idx
310
- @xy_dims = xy_dims
311
- @del_dims = del_dims
312
- end
142
+ MAXNDIM = 7 # lon, lat, lev, t, step, timeInterval, ensemble
313
143
  def rank
314
144
  @dims.length
315
145
  end
@@ -362,13 +192,14 @@ module NumRu
362
192
  mask = nil
363
193
  first = Array.new(rank-@xy_dims,0)
364
194
  if indices.length != 0
365
- if indices[0] == false
366
- indices[0] = [true]*(sha.length-indices.length+1)
367
- elsif indices[-1] == false
368
- indices[-1] = [true]*(sha.length-indices.length+1)
369
- elsif indices.include?(false) || indices.length != rank
370
- raise "invalid indices"
195
+ if indices.include?(false)
196
+ sha2 = sha.dup
197
+ sha2.delete(false)
198
+ raise ArgumentError, 'multiple "false" in indices' if sha.length - sha2.length > 1
199
+ indices[indices.index(false)] = [true]*(sha.length-indices.length+1)
200
+ indices.flatten!
371
201
  end
202
+
372
203
  rank.times{|n|
373
204
  ind = indices[n]
374
205
  case ind
@@ -422,7 +253,7 @@ module NumRu
422
253
  val.reshape!(*shape[0...@xy_dims])
423
254
  # val = msg.get_data[2].reshape!(*shape[0...@xy_dims])
424
255
  unless indices.length==0 || indices[0...@xy_dims].inject(true){|t,v| t &&= v==true}
425
- val = val[*indices[0...@xy_dims]]
256
+ val = val.slice(*indices[0...@xy_dims])
426
257
  end
427
258
  end
428
259
  (MAXNDIM-2).times do |i| index[i] = idx[i]-first[i] end
@@ -442,7 +273,126 @@ module NumRu
442
273
  alias :[] :get
443
274
  alias :val :get
444
275
  def inspect
445
- "GribVar: #{name} in #{@file.path}, [#{shape.join(",")}]"
276
+ "GribVar: #{name} in #{file.path}, [#{shape.join(",")}]"
277
+ end
278
+ private
279
+ def get_time(date)
280
+ (date - Day0).to_f*24
281
+ end
282
+ def init
283
+ @attr = Hash.new
284
+ @dims = Array.new
285
+ msgs = get_messages
286
+ msg = msgs[0]
287
+ put_att("long_name", msg.name)
288
+ # put_att("standard_name",std_name)
289
+ put_att("units",msg.units) if msg.units
290
+ put_att("grid_type", msg.gtype)
291
+ put_att("missing_value", [msg.missing_value]) if msg.missing_value
292
+ vdim = Array.new
293
+ xy_dims = 0
294
+ msg.get_xy.sort{|x,y| x["ij"]<=>y["ij"] }.each do |xy|
295
+ val = xy.delete("value")
296
+ sname = xy.delete("short_name")
297
+ ij = xy.delete("ij")
298
+ if val.length > 1
299
+ d = def_dim(sname, -1)
300
+ d.put(val)
301
+ xy.each{|k,v| d.put_att(k,v)}
302
+ xy_dims += 1
303
+ else
304
+ #xy.each{|k,v| va.put_att(k,v)}
305
+ end
306
+ end
307
+ z = Array.new
308
+ t = Array.new
309
+ st = Array.new
310
+ ti = Array.new
311
+ en = Array.new
312
+ hash = Hash.new
313
+ msgs.each_with_index do |msg,i|
314
+ zv = msg.z_value
315
+ tv = get_time(msg.date)
316
+ stv = msg.step
317
+ tiv = msg.time_interval
318
+ env = msg.ensemble_member
319
+ z.push zv
320
+ t.push tv
321
+ st.push stv
322
+ ti.push tiv
323
+ en.push env
324
+ ary = [zv,tv,stv,tiv,env]
325
+ if hash[ary] # error
326
+ m1 = msgs[hash[ary]]
327
+ m2 = msgs[i]
328
+ a1 = m1.get_keys.map{|k| [k,m1.get_value(k)]}
329
+ a2 = m2.get_keys.map{|k| [k,m2.get_value(k)]}
330
+ a = Array.new
331
+ a1.length.times{|j| a.push [a1[j],a2[j]] if a1[j]!=a2[j]}
332
+ warn "BUG: send the following message to the developers"
333
+ p self
334
+ p ary
335
+ p a
336
+ raise("error")
337
+ end
338
+ hash[ary] = i
339
+ end
340
+ [z, t, st, ti, en].each{|a| a.uniq!}
341
+ # [z, t, st, ti, en].each{|a| a.uniq!; a.sort!}
342
+ @idx = Array.new(msgs.length)
343
+ hash.each do |ary, i|
344
+ zv, tv, stv, tiv, env = ary
345
+ @idx[i] = [z.index(zv), t.index(tv), st.index(stv), ti.index(tiv), en.index(env)]
346
+ end
347
+ del_dims = Array.new
348
+ if z.length == 1
349
+ put_att("level_type", msg.z_type)
350
+ put_att("level_value", z[0].kind_of?(Numeric) ? [z[0]] : z[0])
351
+ put_att("level_units", msg.z_units) if msg.z_units
352
+ del_dims.push xy_dims
353
+ else
354
+ d = def_dim(msg.z_sname, -1)
355
+ d.put_att("long_name", msg.z_type)
356
+ d.put_att("units", msg.z_units) if msg.z_units
357
+ d.put(NArray.to_na(z))
358
+ end
359
+ if t.length == 1
360
+ put_att("time", msg.date.to_s)
361
+ del_dims.push xy_dims + 1
362
+ else
363
+ d = def_dim("time", -1)
364
+ d.put_att("long_name","time")
365
+ d.put_att("units","hours since #{Day0.strftime('%Y-%m-%d %H:%M:%S')}")
366
+ d.put(NArray.to_na(t))
367
+ end
368
+ if st.length == 1
369
+ put_att("step", [msg.step]) if msg.step
370
+ put_att("step_units", msg.step_units) if msg.step_units
371
+ del_dims.push xy_dims + 2
372
+ else
373
+ d = def_dim("step", -1)
374
+ d.put_att("long_name", "step")
375
+ d.put_att("units", msg.step_units) if msg.step_units
376
+ d.put(NArray.to_na(st))
377
+ end
378
+ if ti.length == 1
379
+ del_dims.push xy_dims + 3
380
+ else
381
+ d = def_dim("time_interval", -1)
382
+ d.put_att("long_name", "time_interval")
383
+ d.put_att("units", msg.step_units) if msg.step_units
384
+ d.put(NArray.to_na(ti))
385
+ end
386
+ if en.length == 1
387
+ del_dims.push xy_dims + 4
388
+ else
389
+ d = def_dim("member", -1)
390
+ d.put_att("long_name", "ensemble_member")
391
+ d.put(NArray.to_na(en))
392
+ end
393
+ @xy_dims = xy_dims
394
+ @del_dims = del_dims
395
+ @msgs = msgs
446
396
  end
447
397
  end # class GribVar
448
398