rb-grib-0.2.2/0000755000004100000410000000000011732375622013077 5ustar www-datawww-datarb-grib-0.2.2/ext/0000755000004100000410000000000011732375622013677 5ustar www-datawww-datarb-grib-0.2.2/ext/extconf.rb0000644000004100000410000000054711732375622015700 0ustar www-datawww-datarequire "mkmf" begin require "rubygems" paths = Gem.find_files("narray.h").map{|d| File.dirname(d)} rescue LoadError paths = [] end paths += [$archdir, $sitearchdir, $vendorarchdir] dir_config("narray") find_header("narray.h", *paths) dir_config("grib_api") if have_header("grib_api.h") && have_library("grib_api") create_makefile("numru/grib") end rb-grib-0.2.2/ext/grib.c0000644000004100000410000004734711732375622015005 0ustar www-datawww-data#include #include #include "ruby.h" #include "grib_api.h" #include "narray.h" #define MAX_VALUE_LENGTH 1024 // error check static void check_error(int code) { if (code) rb_raise(rb_eRuntimeError, grib_get_error_message(code)); }; // flexible length array #define BUF_SIZE 256 #define MAX_BUF_NUM 1000 typedef struct { grib_handle ***buffer; size_t size; size_t len; } msg_array; static msg_array* alloc_msg_array(void) { msg_array *ary = ALLOC(msg_array); if (ary) { ary->buffer = (grib_handle***) malloc(sizeof(grib_handle**)*MAX_BUF_NUM); if (ary->buffer) { ary->buffer[0] = (grib_handle**) malloc(sizeof(grib_handle*)*BUF_SIZE); if (ary->buffer[0]) { ary->size = BUF_SIZE; ary->len = 0; return ary; } free(ary->buffer); } free(ary); } return NULL; } static void free_msg_array(msg_array *ary) { int i, j; int num = ary->size/BUF_SIZE; int len; for (i=0; ilen%BUF_SIZE : BUF_SIZE; for (j=0; jbuffer[i][j]); free(ary->buffer[i]); } free(ary->buffer); free(ary); } static void push_msg(msg_array *ary, grib_handle *handle) { int idx = ary->size/BUF_SIZE-1; if (ary->len >= ary->size) { idx += 1; if (idx < MAX_BUF_NUM) { ary->buffer[idx] = (grib_handle**)malloc(sizeof(grib_handle*)*BUF_SIZE); if (ary->buffer[idx]) { ary->size += BUF_SIZE; } else { rb_raise(rb_eRuntimeError, "cannot allocate memory"); } } else { rb_raise(rb_eRuntimeError, "cannot allocate memory"); } } ary->buffer[idx][ary->len%BUF_SIZE] = handle; ary->len += 1; } static grib_handle* get_msg(msg_array *ary, size_t index) { if (index < ary->len) { return ary->buffer[index/BUF_SIZE][index%BUF_SIZE]; } else { rb_raise(rb_eRuntimeError, "index exceed size of array"); } return NULL; } // variable list typedef struct var_list var_list; struct var_list { char *vname; long ni; long nj; char *gtype; long ltype_id; char *ltype; msg_array *ary; var_list *next; VALUE file; long disc; long mtabl; long cent; long ltabl; long categ; long pnum; }; static var_list* var_list_alloc(VALUE file) { var_list *var = ALLOC(var_list); if (var) { var->ary = alloc_msg_array(); if (var->ary) { var->vname = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH*2); if (var->vname) { var->gtype = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH); if (var->gtype) { var->ltype = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH); if (var->ltype) { var->next = NULL; var->file = file; return var; } free(var->gtype); } free(var->vname); } free_msg_array(var->ary); } free(var); } return NULL; } static void var_list_free(var_list *var) { var_list *next; while(var) { free_msg_array(var->ary); free(var->vname); free(var->gtype); free(var->ltype); var->file = Qnil; next = var->next; free(var); var = next; } } static void push_msg_var(var_list **pvar, grib_handle *handle, VALUE file) { size_t len = MAX_VALUE_LENGTH; char vname[MAX_VALUE_LENGTH]; /* if (grib_get_string(handle, "shortName", vname, &len) != GRIB_SUCCESS || strcmp("unknown", vname) == 0) { long id; if (grib_get_long(handle, "indicatorOfParameter", &id) == GRIB_SUCCESS || grib_get_long(handle, "parameterNumber", &id) == GRIB_SUCCESS) { sprintf(vname, "id%ld", id); } else { printf("%s\n", vname); rb_raise(rb_eRuntimeError, "cannot get variable name"); } } */ long edition; long cent, mtabl, pnum; long disc, ltabl, categ; long ni, nj, ltype_id; char gtype[MAX_VALUE_LENGTH]; len = MAX_VALUE_LENGTH; grib_get_long(handle, "editionNumber", &edition); grib_get_long(handle, "centre", ¢); if(grib_get_long(handle, "Ni", &ni) != GRIB_SUCCESS || grib_get_long(handle, "Nj", &nj) != GRIB_SUCCESS || grib_get_string(handle, "typeOfGrid", gtype, &len) != GRIB_SUCCESS || (grib_get_long(handle, "indicatorOfTypeOfLevel", <ype_id) != GRIB_SUCCESS && grib_get_long(handle, "typeOfFirstFixedSurface", <ype_id) != GRIB_SUCCESS)) rb_raise(rb_eRuntimeError, "connot identify grid type"); switch (edition) { case 1: if(grib_get_long(handle, "table2Version", &mtabl) != GRIB_SUCCESS || grib_get_long(handle, "indicatorOfParameter", &pnum) != GRIB_SUCCESS) rb_raise(rb_eRuntimeError, "connot identify variable"); break; case 2: if (grib_get_long(handle, "tablesVersion", &mtabl) != GRIB_SUCCESS || grib_get_long(handle, "parameterNumber", &pnum) != GRIB_SUCCESS || grib_get_long(handle, "discipline", &disc) != GRIB_SUCCESS || grib_get_long(handle, "localTablesVersion", <abl) != GRIB_SUCCESS || grib_get_long(handle, "parameterCategory", &categ) != GRIB_SUCCESS) rb_raise(rb_eRuntimeError, "connot identify variable"); } var_list *last = NULL; var_list *var = pvar[0]; if (var) { while (var) { if (var->cent == cent && var->mtabl == mtabl && var->pnum == pnum && var->ni == ni && var->nj == nj && strcmp(var->gtype,gtype)==0 && var->ltype_id==ltype_id) { if (edition == 1) push_msg(var->ary, handle); else if (edition == 2 && var->disc == disc && var->ltabl == ltabl && var->categ == categ) push_msg(var->ary, handle); return; } last = var; var = var->next; } } var_list *var_new = var_list_alloc(file); if (var_new == NULL) rb_raise(rb_eRuntimeError, "cannot allocate memory"); var_new->cent = cent; var_new->mtabl = mtabl; var_new->pnum = pnum; if (edition == 2) { var_new->disc = disc; var_new->ltabl = ltabl; var_new->categ = categ; } var_new->ni = ni; var_new->nj = nj; var_new->ltype_id = ltype_id; strcpy(var_new->gtype, gtype); len = MAX_VALUE_LENGTH; bzero(vname, len); if (grib_get_string(handle, "shortName", vname, &len) != GRIB_SUCCESS || strcmp("unknown", vname) == 0) { sprintf(vname, "id%ld", pnum); } strcpy(var_new->vname, vname); len = MAX_VALUE_LENGTH; bzero(vname, len); check_error(grib_get_string(handle, "typeOfLevel", vname, &len)); if (strcmp(vname, "unknown")==0 || strcmp(vname,"isobaricInhPa")== 0 || strcmp(vname,"pl")==0) strcpy(var_new->ltype, vname); else { int i, j; var_new->ltype[0] = vname[0]; for (i=1,j=1; i=65 && vname[i]<=90) { var_new->ltype[j] = vname[i]+32; j++; } } if (j==1) strcpy(var_new->ltype, vname); else var_new->ltype[j] = 0; } push_msg(var_new->ary, handle); if (last) last->next = var_new; else pvar[0] = var_new; } VALUE cGrib; VALUE cVar; VALUE cMessage; typedef struct { FILE *file; char *fname; var_list *var; } rg_file; typedef struct { VALUE file; var_list *var_list; } rg_var; typedef struct { VALUE file; grib_handle *handle; } rg_message; static void message_free(rg_message *message) { if (message) free(message); } static void message_mark(rg_message *message) { if (message && message->file != Qnil) rb_gc_mark(message->file); } static VALUE message_alloc(VALUE klass) { rg_message *message = ALLOC(rg_message); message->file = Qnil; return Data_Wrap_Struct(klass, message_mark, message_free, message); } static void var_free(rg_var *var) { if (var) free(var); } static void var_mark(rg_var *var) { if (var && var->file != Qnil) rb_gc_mark(var->file); } static VALUE var_alloc(VALUE klass) { rg_var *var = ALLOC(rg_var); var->file = Qnil; return Data_Wrap_Struct(klass, var_mark, var_free, var); } static void file_close(rg_file *gfile) { if (gfile) { if (gfile->var) { var_list_free(gfile->var); gfile->var = NULL; } if (gfile->file) { fclose(gfile->file); gfile->file = NULL; } if (gfile->fname) { free(gfile->fname); gfile->fname = NULL; } } } static void file_free(rg_file *gfile) { if (gfile) { file_close(gfile); free(gfile); } } static VALUE file_alloc(VALUE klass) { rg_file *gfile = ALLOC(rg_file); gfile->file = NULL; gfile->fname = NULL; gfile->var = NULL; return Data_Wrap_Struct(klass, 0, file_free, gfile); } /* NumRu::Grib.multi=(flag) -> True/False */ static VALUE rg_multi(VALUE self, VALUE flag) { if (flag == Qtrue) grib_multi_support_on(0); else if (flag == Qfalse) grib_multi_support_off(0); else rb_raise(rb_eArgError, "flag must be true or false"); return flag; } /* NumRu::Grib#initialize(filename, [, mode]) */ static VALUE rg_file_initialize(int argc, VALUE *argv, VALUE self) { char *fname, *mode; VALUE rfname, rmode; rb_scan_args(argc, argv, "11", &rfname, &rmode); fname = StringValueCStr(rfname); if (rmode == Qnil) mode = "r"; else mode = StringValueCStr(rmode); FILE *file = fopen(fname, mode); if (!file) rb_raise(rb_eRuntimeError, "unable to open file %s", fname); rg_file *gfile; Data_Get_Struct(self, rg_file, gfile); gfile->file = file; gfile->fname = ALLOC_N(char, strlen(fname)+1); strcpy(gfile->fname, fname); int error; grib_handle *handle; var_list *var = NULL; while ((handle = grib_handle_new_from_file(0, file, &error))) { check_error(error); if (handle == NULL) rb_raise(rb_eRuntimeError, "unable to create handle in %s", fname); push_msg_var(&var, handle, self); } gfile->var = var; var_list *var2; const char *vname; char buf[MAX_VALUE_LENGTH]; int first_ltype, first_gtype; int i; while (var) { vname = var->vname; var2 = var->next; i = 0; first_ltype = 1; first_gtype = 1; while (var2) { if (strcmp(var2->vname, vname) == 0) { if (var->ltype_id != var2->ltype_id) { if (first_ltype) { if (strcmp(var->ltype,"isobaricInhPa") != 0 && strcmp(var->ltype,"pl") !=0) { if (strcmp(var->ltype, "unknown")==0) sprintf(buf, "%s_level%ld", var->vname, var->ltype_id); else sprintf(buf, "%s_%s", var->vname, var->ltype); strcpy(var->vname, buf); } first_ltype = 0; } if (strcmp(var2->ltype,"isobaricInhPa") != 0 && strcmp(var2->ltype,"pl") != 0) { if (strcmp(var2->ltype, "unknown")==0) sprintf(buf, "%s_level%ld", var2->vname, var2->ltype_id); else sprintf(buf, "%s_%s", var2->vname, var2->ltype); strcpy(var2->vname, buf); } } else if (strcmp(var->gtype, var2->gtype) != 0) { if (first_gtype) { sprintf(buf, "%s_%s", var->vname, var->gtype); strcpy(var->vname, buf); first_gtype = 0; } sprintf(buf, "%s_%s", var2->vname, var2->gtype); strcpy(var2->vname, buf); } else { if (i==0) { sprintf(buf, "%s_%d", var->vname, i); strcpy(var->vname, buf); i += 1; } sprintf(buf, "%s_%d", var2->vname, i); strcpy(var2->vname, buf); i += 1; } } var2 = var2->next; } var = var->next; } return self; } /* NumRu::Grib#close() -> nil */ static VALUE rg_file_close(VALUE self) { rg_file *gfile; Data_Get_Struct(self, rg_file, gfile); file_close(gfile); return Qnil; } /* NumRu::Grib#path() -> String */ static VALUE rg_file_path(VALUE self) { rg_file *gfile; Data_Get_Struct(self, rg_file, gfile); return rb_str_new2(gfile->fname); } /* NumRu::Grib#var_names() -> Array */ static VALUE rg_file_var_names(VALUE self) { rg_file *gfile; Data_Get_Struct(self, rg_file, gfile); VALUE ary = rb_ary_new(); var_list *var = gfile->var; while (var) { rb_ary_push(ary, rb_str_new2(var->vname)); var = var->next; } return ary; } static VALUE id_init; /* NumRu::Grib#var(String) -> NumRu::GribVar */ static VALUE rg_file_var(VALUE self, VALUE rvname) { char *vname = StringValueCStr(rvname); rg_file *gfile; Data_Get_Struct(self, rg_file, gfile); var_list *var_list = gfile->var; while (var_list) { if (strcmp(var_list->vname, vname) == 0) { VALUE rvar = var_alloc(cVar); rg_var *var; Data_Get_Struct(rvar, rg_var, var); var->file = self; var->var_list = var_list; rb_funcall(rvar, id_init, 0); return rvar; } var_list = var_list->next; } rb_raise(rb_eArgError, "cannot find variable: %s", vname); } /* NumRu::GribVar#file() -> NumRu::Grib */ static VALUE rg_var_file(VALUE self) { rg_var *var; Data_Get_Struct(self, rg_var, var); return var->file; } /* NumRu::GribVar#name() -> String */ static VALUE rg_var_name(VALUE self) { rg_var *var; Data_Get_Struct(self, rg_var, var); return rb_str_new2(var->var_list->vname); } /* NumRu::GribVar#get_messages() -> Array */ static VALUE rg_var_get_messages(VALUE self) { rg_var *var; Data_Get_Struct(self, rg_var, var); var_list *var_list = var->var_list; size_t len = var_list->ary->len; VALUE ary = rb_ary_new2(len); rg_message *message; VALUE rmessage; int i; for (i=0; ifile = self; message->handle = get_msg(var_list->ary, i); rb_ary_store(ary, i, rmessage); } return ary; } /* NumRu::GribMessage#initialize() */ static VALUE rg_message_initialize(VALUE self, VALUE file) { rg_message *message; Data_Get_Struct(self, rg_message, message); message->file = file; return self; } /* NumRu::GribMessage#get_keys() -> Array */ static VALUE rg_message_get_keys(int argc, VALUE *argv, VALUE self) { VALUE rflag, rns; unsigned long flag = GRIB_KEYS_ITERATOR_SKIP_READ_ONLY || GRIB_KEYS_ITERATOR_SKIP_COMPUTED; // unsigned long flag = GRIB_KEYS_ITERATOR_ALL_KEYS; char *name_space = NULL; rb_scan_args(argc, argv, "02", &rflag, &rns); if (rflag != Qnil) flag = NUM2ULONG(rflag); if (rns != Qnil) name_space = StringValueCStr(rns); rg_message *message; Data_Get_Struct(self, rg_message, message); grib_keys_iterator *ki = NULL; ki = grib_keys_iterator_new(message->handle, flag, name_space); if (!ki) rb_raise(rb_eRuntimeError, "unable to create key iterator"); VALUE keys = rb_ary_new(); while (grib_keys_iterator_next(ki)) { const char *name = grib_keys_iterator_get_name(ki); rb_ary_push(keys, rb_str_new2(name)); } grib_keys_iterator_delete(ki); return keys; } /* NumRu::GribMessage#get_value(name [,type]) -> String */ static VALUE rg_message_get_value(int argc, VALUE *argv, VALUE self) { VALUE rname, rtype; rb_scan_args(argc, argv, "11", &rname, &rtype); char *name = StringValueCStr(rname); int type; rg_message *message; Data_Get_Struct(self, rg_message, message); if (rtype == Qnil) grib_get_native_type(message->handle, name, &type); else type = NUM2INT(rtype); size_t len; VALUE ret = Qnil; grib_get_size(message->handle, name, &len); switch (type) { case GRIB_TYPE_UNDEFINED: case GRIB_TYPE_STRING: case GRIB_TYPE_LABEL: { char value[MAX_VALUE_LENGTH]; len = MAX_VALUE_LENGTH; bzero(value, len); if (grib_get_string(message->handle, name, value, &len) == GRIB_SUCCESS) { if (value[len-1] == '\0') len--; ret = rb_str_new(value, len); } } break; case GRIB_TYPE_BYTES: { unsigned char value[MAX_VALUE_LENGTH]; len = MAX_VALUE_LENGTH; bzero(value, len); if (grib_get_bytes(message->handle, name, value, &len) == GRIB_SUCCESS) ret = rb_str_new((char*)value, len); } break; case GRIB_TYPE_LONG: { if (len == 1) { long l; if (rtype == Qnil) { char value[MAX_VALUE_LENGTH]; len = MAX_VALUE_LENGTH; bzero(value, len); if (grib_get_string(message->handle, name, value, &len) == GRIB_SUCCESS) { check_error(grib_get_long(message->handle, name, &l)); if (atol(value) == l) ret = LONG2NUM(l); else ret = rb_str_new2(value); } } else { check_error(grib_get_long(message->handle, name, &l)); ret = LONG2NUM(l); } } else { int shape[1]; struct NARRAY *nary; shape[0] = len; VALUE rnary = na_make_object(NA_LINT, 1, shape, cNArray); GetNArray(rnary, nary); if (grib_get_long_array(message->handle, name, (long*)nary->ptr, &len) == GRIB_SUCCESS) ret = rnary; } } break; case GRIB_TYPE_DOUBLE: { if (len == 1) { double value; if (grib_get_double(message->handle, name, &value) == GRIB_SUCCESS) ret = rb_float_new(value); } else { int shape[1]; struct NARRAY *nary; shape[0] = len; VALUE rnary = na_make_object(NA_DFLOAT, 1, shape, cNArray); GetNArray(rnary, nary); if (grib_get_double_array(message->handle, name, (double*)nary->ptr, &len) == GRIB_SUCCESS) ret = rnary; } } break; default: rb_raise(rb_eArgError, "type is invalid: %d", type); } return ret; } /* NumRu::GribMessage#get_data() -> [lon, lat, value] */ static VALUE rg_message_get_data(VALUE self) { rg_message *message; Data_Get_Struct(self, rg_message, message); int error; grib_iterator *iter = grib_iterator_new(message->handle, 0, &error); check_error(error); long np; check_error(grib_get_long(message->handle, "numberOfPoints", &np)); double *lon, *lat, *value; VALUE na_lon, na_lat, na_value; struct NARRAY *nary; int shape[1]; shape[0] = np; na_lon = na_make_object(NA_DFLOAT, 1, shape, cNArray); GetNArray(na_lon, nary); lon = (double*) nary->ptr; na_lat = na_make_object(NA_DFLOAT, 1, shape, cNArray); GetNArray(na_lat, nary); lat = (double*) nary->ptr; na_value = na_make_object(NA_DFLOAT, 1, shape, cNArray); GetNArray(na_value, nary); value = (double*) nary->ptr; int n = 0; double lo, la, val; while( grib_iterator_next(iter, &la, &lo, &val) ) { lat[n] = la; lon[n] = lo; value[n] = val; n++; } grib_iterator_delete(iter); return rb_ary_new3(3, na_lon, na_lat, na_value); } void Init_grib() { rb_require("narray"); id_init = rb_intern("init"); VALUE mNumRu = rb_define_module("NumRu"); cGrib = rb_define_class_under(mNumRu, "Grib", rb_cObject); cVar = rb_define_class_under(mNumRu, "GribVar", rb_cObject); cMessage = rb_define_class_under(mNumRu, "GribMessage", rb_cObject); grib_multi_support_on(0); //rb_define_singleton_method(cGrib, "open", rg_open, -1); rb_define_singleton_method(cGrib, "multi=", rg_multi, 1); rb_define_alloc_func(cGrib, file_alloc); rb_define_method(cGrib, "initialize", rg_file_initialize, -1); rb_define_method(cGrib, "close", rg_file_close, 0); rb_define_method(cGrib, "path", rg_file_path, 0); rb_define_method(cGrib, "var_names", rg_file_var_names, 0); rb_define_method(cGrib, "var", rg_file_var, 1); rb_define_alloc_func(cVar, var_alloc); rb_define_method(cVar, "file", rg_var_file, 0); rb_define_method(cVar, "name", rg_var_name, 0); rb_define_method(cVar, "get_messages", rg_var_get_messages, 0); rb_define_alloc_func(cMessage, message_alloc); rb_define_method(cMessage, "initialize", rg_message_initialize, 1); rb_define_method(cMessage, "get_keys", rg_message_get_keys, -1); rb_define_method(cMessage, "get_value", rg_message_get_value, -1); rb_define_method(cMessage, "get_data", rg_message_get_data, 0); rb_define_const(cGrib, "TYPE_UNDEFINED", INT2NUM(GRIB_TYPE_UNDEFINED)); rb_define_const(cGrib, "TYPE_LONG", INT2NUM(GRIB_TYPE_LONG)); rb_define_const(cGrib, "TYPE_DOUBLE", INT2NUM(GRIB_TYPE_DOUBLE)); rb_define_const(cGrib, "TYPE_STRING", INT2NUM(GRIB_TYPE_STRING)); rb_define_const(cGrib, "TYPE_BYTES", INT2NUM(GRIB_TYPE_BYTES)); rb_define_const(cGrib, "TYPE_SECTION", INT2NUM(GRIB_TYPE_SECTION)); rb_define_const(cGrib, "TYPE_LABEL", INT2NUM(GRIB_TYPE_LABEL)); rb_define_const(cGrib, "TYPE_MISSING", INT2NUM(GRIB_TYPE_MISSING)); rb_define_const(cGrib, "NEAREST_SAME_GRID", ULONG2NUM(GRIB_NEAREST_SAME_GRID)); rb_define_const(cGrib, "NEAREST_SAME_DATA", ULONG2NUM(GRIB_NEAREST_SAME_DATA)); rb_define_const(cGrib, "NEAREST_SAME_POINT", ULONG2NUM(GRIB_NEAREST_SAME_POINT)); rb_define_const(cGrib, "KEYS_ITERATOR_ALL_KEYS", ULONG2NUM(GRIB_KEYS_ITERATOR_ALL_KEYS)); rb_define_const(cGrib, "KEYS_ITERATOR_SKIP_READ_ONLY", ULONG2NUM(GRIB_KEYS_ITERATOR_SKIP_READ_ONLY)); } rb-grib-0.2.2/README.rdoc0000644000004100000410000000174011732375622014707 0ustar www-datawww-data= What's rb-GRIB rb-GRIB is a class library to handle GRIB file. = rb-GRIB home-page The URL of the rb-GRIB home-page is: http://ruby.gfd-dennou.org/products/rb-grib/ = Requires * Ruby (http://www.ruby-lang.org/) * NArray (http://narray.rubyforge.org/index.html.en) * NArrayMiss (http://ruby.gfd-dennou.org/products/narray_miss/) * GRIB API (http://www.ecmwf.int/products/data/software/grib_api.html) = Install # gem install rb-grib = Copying See the file LICENSE.txt. = Usage To use this library, put the following in your script. require 'numru/grib' = Example require 'numru/grib' include NumRu filename = "test.grib" grib = Grib.open(filename) varnames = grib.var_names # => Array varnames.each do |vname| var = grib.var(vname) # => GribVar dimnames = var.dim_names # => Array ary = var.get # => NArray end grib.close = The Author Feel free to send comments and bug reports to the author. The author's e-mail addess is seiya@gfd-dennou.org rb-grib-0.2.2/Rakefile0000644000004100000410000000021011732375622014535 0ustar www-datawww-datarequire "bundler/gem_tasks" require "rspec/core/rake_task" desc "Run all spec" RSpec::Core::RakeTask.new(:spec) task :default => :spec rb-grib-0.2.2/spec/0000755000004100000410000000000011732375622014031 5ustar www-datawww-datarb-grib-0.2.2/spec/grib_read_spec.rb0000644000004100000410000001416211732375622017312 0ustar www-datawww-datarequire File.expand_path(File.join('.','spec_helper'), File.dirname(__FILE__)) dir = File.expand_path(File.join('..','data'), File.dirname(__FILE__)) GribData = { File.join(dir, 'regular_gaussian_surface.grib1') => {"2t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>2.4552479553e2}} }, File.join(dir, 'regular_gaussian_surface.grib2') => {"2t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>2.4552479553e2}} }, File.join(dir, 'regular_gaussian_model_level.grib1') => {"t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>1.9907820129e2}} }, File.join(dir, 'regular_gaussian_model_level.grib2') => {"t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>1.9907820129e2}} }, File.join(dir, 'regular_gaussian_pressure_level.grib1') => {"t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>2.4746011353e2}} }, File.join(dir, 'regular_gaussian_pressure_level.grib2') => {"t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>2.4746011353e2}} }, File.join(dir, 'regular_gaussian_pressure_level_constant.grib1') => {"t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>1.0}} }, File.join(dir, 'regular_gaussian_pressure_level_constant.grib2') => {"t"=>{:dims=>["lon","lat"], :shape=>[128,64], :val=>{[0,0]=>1.0}} }, File.join(dir, 'regular_latlon_surface.grib1') => {"2t"=>{:dims=>["lon","lat"], :shape=>[16,31], :val=>{[0,0]=>279.0}} }, File.join(dir, 'regular_latlon_surface.grib2') => {"2t"=>{:dims=>["lon","lat"], :shape=>[16,31], :val=>{[0,0]=>279.0}} }, File.join(dir, 'regular_latlon_surface_constant.grib1') => {"2t"=>{:dims=>["lon","lat"], :shape=>[16,31], :val=>{[0,0]=>1.0}} }, File.join(dir, 'regular_latlon_surface_constant.grib2') => {"2t"=>{:dims=>["lon","lat"], :shape=>[16,31], :val=>{[0,0]=>1.0}} }, File.join(dir, 'tp_ecmwf.grib') => {"tp"=>{:dims=>["lon","lat","step"], :shape=>[16,31,4], :val=>{[0,0,0]=>2.0546913147e-3}} } } fname_not_exist = 'not_exist' describe NumRu::Grib do describe 'Grib.is_a_Grib?' do it 'returns whether the specific file is a GRIB1/2 file' do GribData.each do |fname, hash| NumRu::Grib.is_a_Grib?(fname).should be_true end end end describe 'Grib.open' do before { @files = [] } after { @files.each{|file| file.close} } it 'returns Grib object' do GribData.each do |fname, hash| file = NumRu::Grib.open(fname) file.should be_a_kind_of(NumRu::Grib) @files.push file end end it 'raise exception when file name which does not exist is given' do proc { NumRu::Grib.open(fname_not_exist)}.should raise_error end end describe '#close' do before do @files = [] GribData.each{|fname,hash| @files.push NumRu::Grib.open(fname) } end it do @files.each do |file| proc {file.close}.should_not raise_error end end end describe 'instance methods' do before do @files = {} GribData.each{|fname,hash| @files[fname] = NumRu::Grib.open(fname) } end after do @files.each{|fname,file| file.close} end it '#path returns path' do @files.each {|fname,file| file.path.should == fname} end it '#var_names returns Array of variable names' do @files.each {|fname, file| file.var_names.should == GribData[fname].keys} end it '#var returns GribVar object' do @files.each do |fname, file| GribData[fname].each do |vname, hash| file.var(vname).should be_a_kind_of NumRu::GribVar end end end end end describe NumRu::GribVar do before do @files = [] @vars = Hash.new GribData.each do |fname,vars| file = NumRu::Grib.open(fname) @files.push file vars.each{|vname, hash| @vars[file.var(vname)] = hash} end end after { @files.each{|file| file.close}} it '#rank returns rank' do @vars.each{|var,hash| var.rank.should == hash[:shape].length} end it '#total returns total length' do @vars.each{|var,hash| var.total.should == hash[:shape].inject(1,:*)} end it '#dim_names returns Array of dimension names' do @vars.each{|var,hash| var.dim_names.should == hash[:dims]} end it '#shape returns Array of shape' do @vars.each{|var,hash| var.shape.should == hash[:shape]} end it '#dim returns GribDim' do @vars.each do |var,hash| hash[:dims].each{|dname| var.dim(dname).should be_a_kind_of NumRu::GribDim} end end it '#att_names returns Array of attribute names' do @vars.each{|var,hash| var.att_names.should be_a_kind_of Array} end it '#att returns attribute value' do @vars.each do |var,hash| var.att_names.each{|aname| var.att(aname).should_not == nil } end end it '#typecode returns type code' do @vars.each{|var,hash| var.typecode.should be_a_kind_of Fixnum} end it '#missing_value returns missing value' do @vars.each{|var,hash| var.missing_value.should be_a_kind_of Numeric} end it '#get returns value' do @vars.each do |var,hash| hash[:val].each do |idx,val| v = var.get[*idx] ((v-val).abs/((v+val)/2)).should < 1e-10 end end end end describe NumRu::GribDim do before do @files = [] @dims = Hash.new GribData.each do |fname, vars| file = NumRu::Grib.open(fname) @files.push file vars.each do |vname, hash| var = file.var(vname) hash[:dims].each_with_index do |dname,i| @dims[var.dim(dname)] = hash[:shape][i] end end end end after do @files.each{|file| file.close} end it '#length returns length' do @dims.each{|dim,len| dim.length.should == len} end it '#val returns value' do @dims.each do |dim,len| dim.val.should be_a_kind_of NArray dim.val.length.should == len end end it '#typecode returns typecode' do @dims.each{|dim,len| dim.typecode.should be_a_kind_of Fixnum} end it '#att_names returns Array of attribute names' do @dims.each{|dim,len| dim.att_names.should be_a_kind_of Array} end it '#att returns attributes value' do @dims.each do |dim,len| dim.att_names.each{|aname| dim.att(aname).should_not == nil } end end end rb-grib-0.2.2/spec/spec_helper.rb0000644000004100000410000000044511732375622016652 0ustar www-datawww-data$LOAD_PATH.unshift File.expand_path(File.join('..','ext'), File.dirname(__FILE__)) $LOAD_PATH.unshift File.expand_path(File.join('..','lib'), File.dirname(__FILE__)) alias :_require :require def require(arg) arg = "grib.so" if arg == "numru/grib.so" _require(arg) end require "numru/grib" rb-grib-0.2.2/LICENSE.txt0000644000004100000410000000510311732375622014721 0ustar www-datawww-datarb-GRIB is copyrighted free software by Seiya Nishizawa and GFD Dennou Club. You can redistribute it and/or modify it under either the terms of the 2-clause BSDL (see the file BSDL), or the conditions below: 1. You may make and give away verbatim copies of the source form of the software without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may modify your copy of the software in any way, provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or by allowing the author to include your modifications in the software. b) use the modified software only within your corporation or organization. c) give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 3. You may distribute the software in object code or binary form, provided that you do at least ONE of the following: a) distribute the binaries and library files of the software, together with instructions (in the manual page or equivalent) on where to get the original distribution. b) accompany the distribution with the machine-readable source of the software. c) give non-standard binaries non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 4. You may modify and include the part of the software into any other software (possibly commercial). But some files in the distribution are not written by the authors, so that they are not under these terms. The data files in the "data" directory are provided by GRIB API (http://www.ecmwf.int/products/data/software/grib_api.html) under the GNU Lesser General Public License. 5. The scripts and library files supplied as input to or produced as output from the software do not automatically fall under the copyright of the software, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this software. 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. rb-grib-0.2.2/rb-grib.gemspec0000644000004100000410000000166611732375622016001 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "numru/grib/version" Gem::Specification.new do |s| s.name = "rb-grib" s.version = NumRu::Grib::VERSION s.authors = ["Seiya Nishizawa"] s.email = ["seiya@gfd-dennou.org"] s.homepage = "http://ruby.gfd-dennou.org/products/rb-grib/" s.summary = %q{Ruby class library to hanlde GRIB file} s.description = %q{This class library enable you to handle GRIB file.} s.rubyforge_project = "rb-grib" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.extensions << "ext/extconf.rb" # specify any dependencies here; for example: s.add_development_dependency "rspec" s.add_runtime_dependency "narray" s.add_runtime_dependency "narray_miss" end rb-grib-0.2.2/BSDL0000644000004100000410000000241711732375622013552 0ustar www-datawww-dataCopyright (C) 2011 Seiya Nishizawa and GFD Dennou Club. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rb-grib-0.2.2/data/0000755000004100000410000000000011732375622014010 5ustar www-datawww-datarb-grib-0.2.2/data/regular_gaussian_surface.grib20000644000004100000410000003430411732375622022006 0ustar www-datawww-dataGRIB8b 0001H (@<0<J?*T "g CZVY86`` j5HsF3X Z0B/b .tK.XBK. o-RKa-RKn-ķB݋v-ȷBދ.Pˡ.ˠ.K.닱.Ȼ/2/.Kx- ,4++,D̋D-\˚.̼ 0cL2C9M4tӃS`5b 6Xh͟GcQfE5TJB=Τ9C^2ţ/".0BKM,bKa.ۋ6, L(`p &<2hɺ'X H)̨J*B$'<2b&Ho'hJ*)¤Jx)P"(r&|n' +Dˠ/42 i1 -< )› q)XJe*Я˥0t+ 5tLM3~9cQ*2 J&H% zzuZyA!2:&Т2-OI$ M/\M,P3`s:#:D1PY=4ڒiu6gV]hUlWIU= M*ԑK4QDO;,6 k/0)4 كn8CΨ7c! :0C̭5C5Cd͑7RLS*Ӎf9gM40PĒ08܊+1RgudPDMH }/3T9 c(5PM}3L@Ø:7lcG1t#(N/=4 /8tW@dPC9dR?% ^ B $RZJ6.B). 5S*ࣝ=%i'jmpɷ#tfyQF6p;q1ǧjMvu;eUWZuN;%PNŃTSDSP'`P G5c

2QI41&M!)$G똌c]Ig ?S$FП<\vxgYt0 #OL6Ռ3ID :ȢM2c+M5H8Ȕ&JDdVWyN3l.cu=էxyg{Iy}jZuYȗ۸kVNg&mc鉶\bPC"UHL87GmQIO}Vj?DTnT1|f'{T6f$ZoYFl}Y&c U>MmhA\OdT*A2 CC$A|;ړlT9AZ(!PRoEرd[{sWB]yɟ|]|%^{˞2t7ofXI]ц\dq}rD[}bV(VYKL cOI37K0LA SD8vӤSQtVzYP Pfn5fonmۖoaNr='%tʦHXb^[fNITc7Rv :)ȵB&8CŐN1_5j휔qGJ(`,~'Qٟ@~v ^xWMq&؏Wha5WQOeCUXQ]Չ=D zA[eҺK5$'-D>48-QiU%SMї֎lsrΗBLtQЗL(v%ww]t5շyY^1wFd%MD搑2Rj9t{O%A,ԑVvRo7/x)w{jG _ۃ~Mr$]wV[cfca#W:UH.Jm:laו.F(NR! Gv~ ~i8zUqiYqY_lՁT=%>8Di q8%J+G{U+?QfZ]ZZ\jJnq\or]y9w|ܟS~ *{gsaY)a&UL)/WrUղ\f.Hd=&@lxqn`(~<ɋ.⃈F b >8%&{'xmUjv9dC/#Sgd.ce4H.dc_@Fܜ&vU8g MuH4\Z\7cOr=v+tߑ2 ℇ~""/bNrGy14N<䃔K ғPYE䟐;bӉhaaMjq+Y=dѷ' ޭrXi &Re9ieUZeaB#1#]rK?dNYS%ag\u%ԏ&2#쑦I)T!*NLwJEޞtot^Ee6 kGr1zibc3H⸊. cR9_i则`ʗXketRYbeCN@r&8m t1cNf=fh}4\_.rU[ȒnJ9VIcvU9z6XiLe}FQ%A%3RD(eEbI>:䎍XQ]"-eA[9fY_Tx_'㗏OI|jay~<[yj%әi8nY&c&JYe|Ld@F8؊^, ]ݪ}* Oe֟Ieqɜhi惙ZcɉeZ]XsZ~Xv祠[%Zz9Xd2HX"ꏦ5='C >>x*?x#1R@Bf=XK&JVcQߏ{H: 2Ky;hqI'w)%pʧ@Jzܧs nҚaWICdđnBc.H#~&]~8gĝr}y'rb}9fϛm){hfR`ىܖU0h*v&:tdeZo:e]JK9/e(P LPI'e`j#ڜv'葡8$NjYŜڏj0(vbߠh7~ Ryy[Rp &ם2pfQ[fS^K < ^L9KMjAIgp nd ~Yfbiæmif͚j9ȖZٌTjx(ȩʌ 8h&j^#fi*ۮ:%iF+e6Xr&Z`i)ogΠ<讞excܒbI%~9h]N@:;ţZ衢Z(^{gߞvsi暚p&bhi&U9E$ƒPfUg洅5ٓfeh|CFpg~vg2qi濘dwk)ȨJ;ij(]:ifzh+c:M(ȒH&i&۪:jh[~[i{ޗȜZ(2#ev9iv:E)ގ 6֢R*)(Q 'ŞtfJpI̦ÛivhI挙r9vfڝ҂ H7(ꊪ'|'Zzgug:l'f{z@+jjꩳ"j/Zl7[r*M)'xygZ{_j (䣂uާji'J6Lh:hajT= !h:|'Ebuܧr'7n &s})SR:f9CZ L_}I'Vw'7?0-*FƬK;-kj{*ʎ$Rz磡Z!{ڔThꦺsj*IґOi(2h6 {飥zTnSi j::(ߣ#(6Z|A}tۧt焝s窟2z([&~Y*hނIV%te:h*I'Ȟ| 縠^J\*˻C-,b[mf{$ :nƁl ʯ)'^y(!|j2^*pꗤ"JȤjM)NdZ9i~Wi7b:^ejZ:`ʍ5'V6y'Ýu窞z'2heh ʊ43098^XɆcJh/!(`:h|ҏ)cjĥj)㫀^ jj9hnz#(~XŤR%Dr)~z%认Ru>ijR(Ҥ2iZLib覡ʌJ/(ؠ bzg{)g~yѦ:rgft 玞6'r19ϙJQJxJhs7(ގ3͢~:6ݦ&)":w)ϦΓçy٨ߡNmܟ*hwj.,2o)ΌJ)o2#b7gӝszʊ((N:n"Z:hNZ;Z'㠲ݞ}i_wާH{\vIjg'h}' g[SbiemJ(ԥҔKhD&.HΓcĦJ`)ZJdiԦڥ*.*{+e 'ނ*iʓW6"ʂj.:lhvs袒j9IQ&ȢN:(ѤJu)JTQ+-: hFIgWZuܧHtYFr¦ԚFpg4ogdjyg&:(8sNz'r9'trl)JꖪF{ hcjS)?>;(MV6NۣfRZx(nS Wi%:)MRnѦbF+nJ^)bZ6((6~?izf銤@趣Nj>֡ZJ瘞~ Ş2y'wᧁ>w灞y~I縍zgwoۧtJ)E)hң;ڣ>3&+hhj5)*xʀۣڑ+{n(ʇh6J(h짦Q~ç^zNעjP) %Zi)TwWCjS> drh& hg})'|x^Z()"gqt 6oimti珗&Ĝ~oog(ʥ>z;hJ(oچZ(nƁ(S^gwZ؛RmݧN*+wRY襣6FJ ԤFE)3Vc:(ͤc6J~麦*+ƅ2H⑊6*8h}::hI~d*tY&њg擙oiԧ;if:u&"{(?uA)LƉ:6 g埆(%w'=YIU波Zw ) ^INjV)ۡjzJ;áچIhށhdڌZ>(n6軦E)Ү h~) J*Qɟ+h:i: h,}i((`چ9gq)&Ze`hi&hh6'myfe)l*(~I'*vigcZh&_)ʦןJx[Cꥪca:rq*-6-jhZ(@}i翟;i>p>GirP(Vg&ƚ:)/j/(à~gmw&śk&xlf6k*VʳkqmJ'tog[|1(WƇ*+3Z'ꠎyyr爝vv¦2a&qfkIf?fs>mҧ}9u&xIV"(etgj&Lja[khҙ:(DCހ!grz ӧnfva}cɩ&N ڣ*gbjL(kL_Failh&(-^oygztɸ',vfꘚXُfʜRlI_cf82Xv#F)(3ru(~IthzΧ%Zjimb9f6iI-R*ɤ6j4ơyfygFnj&Wag弗^&no86eI' ߛdHm{)怖nU]\9oL2gܟꂉ'EdY焝Jr ƦJ>milO^og$vefQF\MFʞni甞jx']d9fϠ"ig=Rsffj^I].JU(ڠgםr|gy&fc&3`&J"^m%QT Pe Gg:K3䍌Fi[&n6歝u%O+$W97sr6zIs^]i~&qh &6c9zeYjel˦j`i1%fZOy*ߟJ^t!F^ك%ŗjɈf@x'\qԘaeV x&ߞN~9 nYfhf7WIKe`P]X JTigePA%,Zђ~C卾68Q8m<n*HI1$.SI6/j殙gyʕJYcFW)vX9N%nWIG.N]XQ,d$2F_&rgk%-HCe)MW&NR^9fZoɰ&ZWiG$A9JehَV`xf!ZcezWO䶐nC!d^I NL$>F -Z@ic" dMI,Q2dRYݖN#6&XcqA!dדL9-I9.M$J6"/8b=8j0hc+ăbs0HAHheUR$1.H#3:#}2#O0zb!(#F~>X棡?8#BI6%qNm4|NQIc$s"89#>8cR"-(bD$TKy)8N/~Eh!؈$hⷊr4H#"%H"C*"_#xbFnH] t HࠂdbZ9ۤK h!j ⮋5x"Ɗ's nᡄXka܊)x~A^2$E^Ac42($ۜJRi ƈ/H֣HZ e!Ņ>m!("Ō^$v{1Nza臥dz97(~ ,:+r68~3aS<`~7_A}5'ᨄJX"3#aj υ_!݉'Htᣇ& 6 `"0aYN(SaĈ"ȋbӋr+x"D. 䎋#"A2)ؓ(J% A=_jD`䁶wdSuQ[4tҧIvaᷓ^{]RuDy釫_}%_|_L|׭ޓ{|)͞{G_w8}Xa< h8+b8_a}']րX`X !V:U!.j a .jJ :րngٟ(|ׂywz}^7su̧&ܡrqgt)7Or!uЧW]wI߷~x)z]rw܇h]vqs]w^Wxg|g_nH' ((~7_My㧵z=GC|w怒O}5}執~7}EwK}YG_ {9wxmht3*umǎxK]o鿦oupaq%7[p \Qru6u\jtjuwW6sw?]tGi]v!7nvIGyvŸ%|ɟj}ܟ~z|7^z7 uN3uugI~G]xנިzLjz57^{=7Nw퇉 ya姄tIpm sק[@t',nuZn[p) \paV[oMnVrʇܛq.rq'&܁q Tq@u%D!tχIFtP y'|ɞ{)ǯ^z9g{wuG/\`qM rR^${5觬xiw^:y!xx׆ wG^NrLJ>rrgmQ[q9ć\rr lqm&ۉmf䛗m6ʛn1nuG[p!#pin pfq!'"zrMg+s5sɷs}w7z]wui]tΗ"po' ,pq \tdvmWjwixv[u7W&sY$[mY 8qö[mI[nݺvmfOlY\m6QmVcm6՛em6}n oY[nٺᛃn[o)oapQfoŻ\@qƗp9cp`qg;p&n}ۮo [o9[pgtҧQIt'[]Cu!H r5iqݛ#kѪlvlvkYZluě(kƹ[WlV-lM/ljٹf۱o5enVljijElfaF|ىeZl)vja!Hadϖ;haSaM*@N4;3N9#] 1t3.i0\K-D C(2Ƌ3dtRd5&01eI;hfZijͫvjni֖Chfjqjͦښk5rcO5Y:trT3Ƀ.h2 O0RK)+2%2+c Ā!H2*"|#H")$LPIx'DR +سs.#& 9 %PYRT6QFIL$4mG5rxEbI)RH)RcHIt7=<3oCDHC $бD)#4RtIa(d/=<\s5ӃM,)ȥ";(r r*+b .'a f%HK $:#h." 2H _!1H$g (J,2/2 ;Xr 4s̎F>CTVa[eKRF;R9C4GmCF4c;Le/2LZ5.9䓗r8ճl7CO-4P=2Pd1c,l«ʍ$E#2=$<M ?$ؑ:"08 tAG{a釚ц8D!! dC)ȓ(X H^Ɔ*0yhWX%*DIJ> @3 PXB`BW1 e v6+iz kS}38ѽj=p>E 4QԎn#CRP0 EA)tv*3ArÀ@8.N @@ gCt(dxGf8 Tp)jDisx(7Ѭ ^Dp*J PT¸$ 1A ;aPDBC%2Q`&:AO=AwC˟AaSU E'8ɔKzVҮԲ%),H6j44 '^6ѕKWr"!t6 I (OB>pQh4~ QB3(sT9 ic/h8$0$ 0At@ц6 hNB `: @b2|H#.V7A opm=)Px)>JS"5[+ TXOfԖt&%.i9Gz,4Y"J?r#lм6#F(!D"(pĆ&[tqC G^5a ]#G 6[Bņp4 a0%)GB@@PX9PӇP?"#F?BZF6 p&C2էG*[VjUŕ+NIFP0DLYB xH':_"؃Ed#)l ~4AdL xj,164Mdž ~\8hw#ʝFf.YQ ~Ba hdÿ%Q] pURA_»@F>2*&Q/ A1S ;Y2l0IxOrZؚ$$G<(u#V^#AdCx.X"L c,+A|d<'Y|N~'HTR'E cT֢b]/$HjC芤PG4|JVB|E,#GP:qŇ1 &]K\bƔ@GP;Aˍh#Ah&>Qpĺ!`<+-.4 s(\ pDz/Q؆!)E(p.IL^̘D()EUWr!=>NpS*}"Adɥ- ZJjNC|զ8k%A4ECixR]C*L[c801pSbm H2 @D!NYB͖l,`*WzŖ5 j*U2Tt&';+hF=MnC:(f803GIA1Q}Cͦ?2 N] Iȣ?Qt&?M:bF'!7iNZA4QPd΢D4e˜lƦ5ѕ}#QHLKGP$5)U Q_S%ZZVpү| YjԸ'&:at;Nq<(hAaM9f<mf/0z_h6@zѪ%;1Td*UjVjŅ, [T—SިX=\Rה‹̲%b%Ɯ3A; ͎bocTI eʣGufkb"լ]K#^ 0w]\zղe 3D PbD ьhKZU5-uLf4Y4 .n˟`kæ15^bU|!6ɽM2a@J" ?qp'Qy}G 7ƚ#) HeI”V>.郬iC>YP631,f :1\_ɔel+j+mUf;y (@`ި3 H1XzL&5aNzs(?4;HHRIƦֶ1;OJwDY@*rTڦ֌1*as %鯭Sd Xq6jU^w) dpµQ\"ժ&7jd3ܨۗ9i׮rÔ\' u̚c$Fql\ }4Ŷs[4֦qMkCRtϷ kGYu.iak_`ٔ67Mo'}k^q1 fOeaC^KYZZuLc֩-nn~z77Mo z~ƯdC Em=aڴUd'Af &gN:r{zƳaLf[9YڸQMmqDه5t x6%_lh|}>Y mNpv_1eJbk+p"8ۯ~\_/cOrTex/}L~h3Gb6r4Qmcj#Kڨvӧ48nCq\6]-$gc ؒe0Y]bOdzLgO}#h-o}bG>aO{_X>MoU{ (IJRJ= vIrt&O1BGb:RD4RG>1O_:P-u E?,`&A~ P, 1H:A+"Ogھ5f{ ǽO|>o|Xψ{`ӾO~~ߚ>O~S8YE3H51Dd$iQAR_=G$?<.!q HOv?l .@)`@Z P`(T%?1/}߆ȿ|;8Ƿ=in{^=l} :?>|ߞ79O~`Y<h 0 U8t: qu{ߞזjzl<Qz#Ξþ/} п}ψ{#Ҟh/`#g?`1j03 Mx?E,*! HFoՀ\ q)Pi  ApɅ|/! dCr0`@lA8 @b .!9 8DA OlW@M~\?1|^=o{׽>MOߞG>ycng=ϴ9 Ol@F)HD1 am Hx> ~H p}V@DkxKŽ𘃤'MA*74_h8AZ0t$[@ p#ac o~_X;ap{؞Ǥ=}}x?)bz;^lg)/ˀ`S@S_>~wC=O$(A /A |?uϝ}?3AwG hBb pD5a' HbBZ߆d)! Gp}"?P4 3*>aVz^p `@~r? |_:WC7H=O, ?ނ  (AІ`yHEApȂ q8,Ž0ĉU"? HXzɆd-@ 0A)@~B7o2y{^y1Nw79O_G޾ ?M|g>)z^GB>х!M@o _>ώ|=Owwk]7VАt6"q0y`i@u/~ @R3JGb p6oH;RĊ" TCvДd'`:A2Ok Gh!Ao~GMo}3_=oHzNGu{] gPI} ?C_>ϫ{ʞ񧖼uu{T79rHPDkHfCb È 5@i0 {>{>bCHFWS Ǥh4A> L qY ?A*O~ss{^ǢYAz^Z7{< vGI:eN}sM7}@>m|{X7;=ntӯ@rbm{ކwpծt;NRSF]?P_>7?Yop{#\~W;1ܯy;џ@#>qzk^Lg<-w^0W;v 29ɏ s?m/ yty O}zvqàD7*bd >o|=eO*xpOv]Uaܯ w1O&>@~3g491.v{]O~כCyk7^).sæ]ruæ0%95ďHG%9x񧉻{^t] >ܲetbG>ky#Z;u]TB:؎uí7=9a͎xlǃ͹pW[|]l' %Ɏ1t3܂߾}|C^f'P9Nw㵝wL14r\P.t덜 g8E ;rsR;-wCҟG<1ٮsÜ9zS'A.tW89iaqKw*r \'8au06-lcXZ巋/y]ZF81 q?HyƝVg/7p˛ G6!-p [9s}[6)n~߰w; ˍmo[9nt發AՎr܄vescu]t\.nncrFݶ5ͪp <6-lkcZ׶qmqmk?-:xSP㷥 TlcvFNtێF뵵1jSdp8% nۆ8ENrCyFٹR|^'M-jUצ q Tb}Vn3XzÖ 1! l t"GiscV-n#bZ6koFYe;"eLecZv߸.tܢ7E,iKVѷ-kkSZdՆ3g9ɶIZjS*Жqq}ZҶ3}c0ƣ%rkNZ4ѶM&kk[f5Ma "i+t^f4e Lj+RZƣɓfSBZѦ^u,!dM0˖@\BՖr.y] 8f pk 7Me;Z64 g3&FG1,ec8Φ c,Φ-nCmӦ2٩$|+Fe81LxfHv49pW̧HXXbX~laY:.]s\~20~ _s.l+Vr¯ko[v`vmdZV4=`T2a FbnۮvkbXxMy!`pMXjKٞ&k2͇n+_ھҖ~4Qle  .r˝^4*/q>RT&(JeTZr,aj\.1^k&YR͖eүayk[",T*rSpuf:Yb f6d61QK]J~0} [z-j+_SX80}~]W$1vbz.{,aS آ_zꖜu,mZ*Yb¥ \OoSZ( C(RBU6J*WShE-*1SVŖrSWp,u?O…zF*X*VU°ն/)~k_؈a+\De!^W2pq\Yߗ%sQX2>k ,W²\E},-`YVµ%-ulSYCEX عմ+uN*8Me4'5:PB%7YEIO |T(J*pU2EU+aVZڣ'=PPWU^Ej,rk\Ve-p+]򗞺u,ZWj5(K Tʷ.anK.W]*eOjpSX~,5_W⿕֭s+_ VRUE!GXzǖfAC)L\Ɨ&7O"}Si:NpS㧁AETB|E8T*S禡3iOڑ5/yMsS*2MQ[D[ȭkKXZ%![T T&7Oj-=fUҢM*=O wTz쥥8*YJVZ KU2Td?jUڴUED(:)K\֖Խ&1 LhSXϦ}5Mm(GVS(u@IMjd'u? QTNjTN)KVr:ubWھ歕V1O*XPx'i;INqS57qU TԾEAuTjTʣTE+)N*]QS')<Pڄ&6iO xSq/)rJ Q0IK\d&1)Ld:tMGRR*$'-5Mtƞ$A Mhn&7IOrwӾu5*iR nSTu)(Ej#QJTGJ*P2ydE9iNs'C*DĦ6ɦLrex&3LWm6iO rJ% &1IT晤'y0u˥,T8P/QLjep&6;n{4 h3>φ4Mllqg 8iMoo0F4Mg;fU2!L6`2He,cKX01i3a::w D6DEB}E#`E:EQEks#ESXE8EE@EE=EkE7hFҀF8FF@F$F/F;:FFFR4F] Fi*FtX8F&@F@FFF9FFFFFFPFpFFFF)FݦFF0FA,FtFDFe&FUTFEF4\F#@FFE9PEƏ`EvhE1EinE<"ZEC>DXD5D_dDCbC" BXX@k;O4>^7ie8eJt9 97H:p::;50K;Ҙ;*0<>>4Q8>N[L>jф>R>*>>r>d>߲0>5Z?fM? ,b?}? f*?)?2?;s?C ?KV?R?Y?`!?e?j,?oft?sE%?v?y5?{s?}9!?~*?d? C @ 4Tf5)Mg:f[2̎d&-1)6aS%/yy˺]2%,dKWeQ*IPJrSR%)G>R2))yMJrTDee+y^YԖ칥/ɄLRd3.Ҧ6r=OTe7B Ц.u [BP(?iOz̞'S9"otl'o;)ζuT'K:9rsS')99N>q&5d {*IFIKI$9!9*ARdQ#I!JL2r eA*]KY֖.vK]򗴾0ٌLgT|c=iКT}M4R ՂU%l\W~ﯽ,` Z–-}\:U⩵m/)F R~ߦ' F-Q':ip34)9NFpoΦ7/pKU$$YȆAz#Gb;qߏ$zZD44$(KʶXؗl1y~cæ0i"a,&6=-4CW*2VMMt۷:Wž!xn/1,Ja7λ}-9c:UbVZ+i FZ)Q"@ (>MeT$'I~OԵ/vˆYҸ d&0IJH4$ 8@ I#!jOe0Ra2t/̾jSs'm;O&zse(LjUV -xa1˦gcfw3n~_=FjTsSwʖ4~\~+uXZT4'2gJMRXԙ)IWK"\&5̆^r%8>-OLqE2nHL;&u3{D%.Ip˾a34B06Զ5:*KWY)0KLS/ǽMnGn[cNi pˆ|n|jHV͈ 6%[:jt=df]1̆ged'{;*n3dd7:YMcc[D'qQeyG?Q|l9HFCt'-=)|slfg1IK_sLh]MغVl`;fo3mm|69nt;:mo>4OPu^:n׾t789VF gsVx'@jvڞS9yMZg;/9ɼLV7U"#E2Q4d&Y0IZI6HLr6MmSD,nLeSQeNZW.mk^vrt#=g7x<9)͎= Dz/?|nr۔ S&pssVVl ]|lqf;$Wβ5@/hZ2薌d%4J6V2L[hF92 e1̖_dS$H˦eH&wپw2FXu%}\c%9KRr;|W{_|e;u7'h5Υs']Զu2e|%_6VuoCxv eVQ<{INAR&o6M`|.ɺO圌-9aYۗ|e%Fv5&_3ɖXrv# I.˺o&:[XʞRDk#Jycu5>6s]O\zծr\(8%7vޏ 9U;ڎso|fųuܚo|vĴEjHiT6ٸq3n,Φ>CSte'>*_r'y8IBr=gQ<9ΦoA$d!H~NrT/Pⵗ2pq(FͶU^r+{'|m&xg>8qݧٿz^w޻s|{曲G+ݦw[]ߚyO~K vY{1?)zܞW'ۮFu2LM`w8{P2ܞd,ٍ%`r4׬kYvRkZY*նX=?WTcmuaT4H?PN5S*]DzHJBҒc1O}o-geoϾ4m{mO~<~}~W=jx;ߏy3ɞCw+~.pq7|bx[3);9ul_VjUzݪml Fپzݡ-kk0Z^7 N+[f3X\n[vV%ADJQ5kT*M^5q"r[q3yFzib[F:>wwǬ|篡wݾYw.O\ֶt7}tlXnnq3M|e!Nqsl"fk7nMuۮvxMioF[7q -9v|X~mW-Yzmr֗kL [l`y̠M'4IyM΋/KLWc &wrc5ڈ&6m'wz/R ~˼|'6Mw#Ƕ8ىeS$N@g[)9qˍLk# -/y_ v o~_斷ml;^ź.7~6ȶtqKVں6.'\Վ mb~tsd7R|8-{,ifGAj6C ͎hṙb-ʶ/Λt?u1ƥL?m.qk]x(17*yǞ3 `~VQn8RŖm-r[ުw z"Ӗ5i:v5ӮMeWl-XRx}f9)vƧݒ,n\b vnhka3WQIjXX~1gP{tEY,Yf9},g{@R̖.g+gڶ6CkqYjް Bh_5`I@xp#,rƶ),^hm~Td W#`9 0rJ#I#J&OR؜UQ;IXҷ dq([L~jQiI`TR\NSjZ嗀4j`TL&.y:Y% kaӪ5%eYM:mTʩ4Lj\knUֳdX"_ )fu-9~ʪL?GW]))u3]7E8/8{#h %.whGj9l&],I)KWd_c y-J]3 '9bPjҎsPT#GB`DiVL~tu@RvO )Tjڬ5UIc&XrT 3yMfr[K( [;Yծoۏۮg Y{zZ16m~-ѩܛ&7J"Kqɍt])!=~UtY0 dNMKBOh蚵(?iΖgr? f5(2-R&A: >Z/8O% R0ޠz+WUbg >:P*{s@t#8B" IS^^1/A|+F n"Q?$I"HDN(nLl/x=q$ 'RʒOid[4jI6Fcle#-r*1,&#-yTM#$+yKIAӍe,VȲ8r*ē!y(&FRۦ;L2c(CJ*Sv_MY*UꑴI':پ~h$I.ɦA_:W@Q}cQȎFE6j#gG>=L!HEd-uJXח &4XOR[%S.NrW4%& HF2 d#iHAQte7,Y`Nxĥ_.9\֙U69aRG`TʲmByOJT\ m@Nnet#7GJFQ卌C)BF"R26I 9HOy.rJP2,6n3#,-4t*Q2{'yLjT2JLd%0b8ѽ$g%):ILWU0ɉK]|hCPF4&;Lfse)S:6Ep_RkT`G:Ϊkse%9)9\JWÔ~! yĶ&q8lf%Dr=ŏԓU!I,J[S.l&_3irnUA2v-f4iXҖdeG)iPIEԒ*WZ/Tlw$K%IMnXĕ16ٽdAVʮVάCiIy*t bev&-kR kM-)SH:ͺks4&'/IN*RRTq HEb( ,gc$&dž3qŏ)ym˂ZԘͦ9&YjmN]>d駧=2fSte'Ce* F*Qw ?!9K~aRg/;9OsUVc0[Wl U*nSM-Un]r&'.uZגᨕ'@M~_r]ܥ(NLVȉFW"hFJ1䒤*W>URۙ;5`P:bZ< Mni31e%xG5D%{%hG5,$(O̦inhUA.P4_m[kxǖnjKJvv'y^xNVNh"f%$8H1dI D9 Q؋%2DNĢ$m d!H@Ol&7yQu;)MFBF3흌f39zKb<$"XD/t&9I?qL&7N:kE$iQGj7Rjeou !92PqY{K~Zm5|&O-&Lpnm_m#)MJv774e"`!ɋE!E)#A xö"Ql,^ FN/QӐdd/ɨRx'uA:!ue'7ʺa3=/q|d*^TrgI:YFnS -Mz]bh}zl2\Ķ۾q+^' 7V\^7(fH Qv šPvU 8Ŗ"QQPm?|n?!HFv?Vy'TJNQ2feIHH~Q,D([ %7j}3|&M0M:bD[K*VY~wȞ7僻~ڗ%ž.%w;]&wJUSY"ΕjE$اF&/p{Hps#"i6221W!?ozĝwI)nz 8YB1:t]#5 GrFr3DU(GZG,egþ%Dy1yOyTfU+9BKT|)^"Y6v-gwk'92K^VSzޒӷejKwTί-8`As觯j q|c&~KO㌜L 5@|ݮg:YҎvs_nċ Xc;A2#SHF4ɥ!hC&؊h$-iS;d%?&LJJIZ}`[VL -Is`>v^UVMxKar6Hqc;J8$U8*yݢ0=Dv&YLT1Q"{{& ~#fC:}Ҏt̞𗄾~Ɗl\6?ۍgc =JFKԤdCn&Qdk#SKWd YKWRZ,(Yj:•F݊mv ^5zkYۦEk_:Ӷ E+)q\:f- N{3_B?F#%"Yp>1YEL _8B9̎@qKt}0DP#HD1Ǝ]"YJPҳ$cCZ+2$/ X3D4M6_򔎤MeUΦ4wukga̷/9W⩴/ucl|< Zt$)<h'E叒tG>*zbM97Qa7bgHG3QFD0Gc9xr'===bIWr6Ab{ GTȒl#%Xb"1͓ԣ$#hE2r<ܑ$5YP]L&q5Rta%AkM[YJ϶,m+ ɟm-fKUvu$DbghH6+2g,?YΟT^H>uN3*a INj< b &i9FOÞU(AnTo+5HZI򌓟Dfu<NZ|\hIπv+T>߈ ^@8nwSهL?I$pö V¢$1 ئD^:$ܕ"A؍bƍ܇d)HHH ! YDqt5ؔPsd,PZd?f*G{a^? EB i |L&h,a#50 -gKw:8=tcg;|ۯTf8Inq^ <Ѭh6ARPTE K8~F&3rsbhtò0ɋjw XVD63v1%v)͈-qgCOrdڥ8$rI#=9˪bҴ,!IEH/q1T5%OAwkg91+W".~L\c@Y1ݗmLn+\&:uܮqq&c7-hcG 7ř,g w> H6Dv&QdB͍T} {`U=0'v7r%T#؀Â1)v\r$_x@A:ܢfd]:u [چ6 Rz+Z:\RX[eK. Nqm,i;F79+\k޲IkjkWk;Ox7A,J!أC6 pvlqa:rNx%"=QD4% xNqF,y" hkE5$L'$<2|Cĕ0ݎiEƖFnQՊe%BOrS4&-)T³Uŗ}] 19vJIV+ bP/kKecC7.n\W =P,'"IHvM0gV8ſn*v#TG9z^ǵ=>t : {FZscn%/vk^ڲE~,mTiMڌTj( -D1Q@D'cCz.XTMLjRO'G Q^,dO]$6z5ݫMe!: P4 BA}{C7MNt \z捷/yۤ6ۼNeoC\7z<nrۚF7@9Nrk`YfֻQގDl+>1OTr~ӰĿ]0iJi %H{@xc{4ا5n~D YCy3"IMBTȧ5.OYJޗ&̀^*B6x[H@-u8m ohԖ4Mj(B%b+ũc/Znؖ2͟Ml(׀N5cVbˤY$Hj-ZFBDR gX7 ldBs*ak.o#8vdÄ5(NHb[lA:S곖v5Y+QU2V6-mVp]dw9kIVlb H.r]V .~\VD1ɀ}Y٘6P1L^`ksV:dQ9bvAœԥ*[RHO#1[쿦 0vZS4GB*.'2i3K}Ԯi9I*oMwZ=qc-6 a:&/wknXuN6j]W45'(AOTBu-EjTR/oNiS؟%%LC3LEx,n 4fKlǚ=k.l"QF r  LtȣF*qRK^܇A3$ hF>.9&}DLSJ¦=:1Tz./u~KYRc(:N"ZRL$)OJoHjaSZD(N*fQrԔ%D)CXDr >\(B kC<$e&GJV8&5LYȘ4hT>2z(HLGF (D`32D"4Q#AiyC m2<P}vFBQ$PcP}֤mD |6 X`pP H \0EH@`- ip>;@q8 op`1 Z@+X X-` Sx@ `7`@P!< f & @> `@0@ H P ` @ `( x&` hJ/ hp`<@~  A0"D(@`# HH&4 Nx@ )H `S(< M7777rb-grib-0.2.2/data/regular_latlon_surface.grib20000644000004100000410000000224411732375622021463 0ustar www-datawww-dataGRIBb 0001H0À"gC; ""% B1+!$&&q$Z"! /|7 [''(((''g%O'!mQ,'())'*=+b+-# ,k,c,**+s)042.%mXl3!0++$/.L!.;/p'*$6,9_:98$3@ (2.1;+u%+$,vAx682+w++$;*(33.03W{[]Cc0|G=5<_6<=563) BCB B BA?!2B6Ap98&E LHGKHDGE3OF42 i1 -< )› q)XJe*Я˥0t+ 5tLM3~9cQ*2 J&H% zzuZyA!2:&Т2-OI$ M/\M,P3`s:#:D1PY=4ڒiu6gV]hUlWIU= M*ԑK4QDO;,6 k/0)4 كn8CΨ7c! :0C̭5C5Cd͑7RLS*Ӎf9gM40PĒ08܊+1RgudPDMH }/3T9 c(5PM}3L@Ø:7lcG1t#(N/=4 /8tW@dPC9dR?% ^ B $RZJ6.B). 5S*ࣝ=%i'jmpɷ#tfyQF6p;q1ǧjMvu;eUWZuN;%PNŃTSDSP'`P G5c

2QI41&M!)$G똌c]Ig ?S$FП<\vxgYt0 #OL6Ռ3ID :ȢM2c+M5H8Ȕ&JDdVWyN3l.cu=էxyg{Iy}jZuYȗ۸kVNg&mc鉶\bPC"UHL87GmQIO}Vj?DTnT1|f'{T6f$ZoYFl}Y&c U>MmhA\OdT*A2 CC$A|;ړlT9AZ(!PRoEرd[{sWB]yɟ|]|%^{˞2t7ofXI]ц\dq}rD[}bV(VYKL cOI37K0LA SD8vӤSQtVzYP Pfn5fonmۖoaNr='%tʦHXb^[fNITc7Rv :)ȵB&8CŐN1_5j휔qGJ(`,~'Qٟ@~v ^xWMq&؏Wha5WQOeCUXQ]Չ=D zA[eҺK5$'-D>48-QiU%SMї֎lsrΗBLtQЗL(v%ww]t5շyY^1wFd%MD搑2Rj9t{O%A,ԑVvRo7/x)w{jG _ۃ~Mr$]wV[cfca#W:UH.Jm:laו.F(NR! Gv~ ~i8zUqiYqY_lՁT=%>8Di q8%J+G{U+?QfZ]ZZ\jJnq\or]y9w|ܟS~ *{gsaY)a&UL)/WrUղ\f.Hd=&@lxqn`(~<ɋ.⃈F b >8%&{'xmUjv9dC/#Sgd.ce4H.dc_@Fܜ&vU8g MuH4\Z\7cOr=v+tߑ2 ℇ~""/bNrGy14N<䃔K ғPYE䟐;bӉhaaMjq+Y=dѷ' ޭrXi &Re9ieUZeaB#1#]rK?dNYS%ag\u%ԏ&2#쑦I)T!*NLwJEޞtot^Ee6 kGr1zibc3H⸊. cR9_i则`ʗXketRYbeCN@r&8m t1cNf=fh}4\_.rU[ȒnJ9VIcvU9z6XiLe}FQ%A%3RD(eEbI>:䎍XQ]"-eA[9fY_Tx_'㗏OI|jay~<[yj%әi8nY&c&JYe|Ld@F8؊^, ]ݪ}* Oe֟Ieqɜhi惙ZcɉeZ]XsZ~Xv祠[%Zz9Xd2HX"ꏦ5='C >>x*?x#1R@Bf=XK&JVcQߏ{H: 2Ky;hqI'w)%pʧ@Jzܧs nҚaWICdđnBc.H#~&]~8gĝr}y'rb}9fϛm){hfR`ىܖU0h*v&:tdeZo:e]JK9/e(P LPI'e`j#ڜv'葡8$NjYŜڏj0(vbߠh7~ Ryy[Rp &ם2pfQ[fS^K < ^L9KMjAIgp nd ~Yfbiæmif͚j9ȖZٌTjx(ȩʌ 8h&j^#fi*ۮ:%iF+e6Xr&Z`i)ogΠ<讞excܒbI%~9h]N@:;ţZ衢Z(^{gߞvsi暚p&bhi&U9E$ƒPfUg洅5ٓfeh|CFpg~vg2qi濘dwk)ȨJ;ij(]:ifzh+c:M(ȒH&i&۪:jh[~[i{ޗȜZ(2#ev9iv:E)ގ 6֢R*)(Q 'ŞtfJpI̦ÛivhI挙r9vfڝ҂ H7(ꊪ'|'Zzgug:l'f{z@+jjꩳ"j/Zl7[r*M)'xygZ{_j (䣂uާji'J6Lh:hajT= !h:|'Ebuܧr'7n &s})SR:f9CZ L_}I'Vw'7?0-*FƬK;-kj{*ʎ$Rz磡Z!{ڔThꦺsj*IґOi(2h6 {飥zTnSi j::(ߣ#(6Z|A}tۧt焝s窟2z([&~Y*hނIV%te:h*I'Ȟ| 縠^J\*˻C-,b[mf{$ :nƁl ʯ)'^y(!|j2^*pꗤ"JȤjM)NdZ9i~Wi7b:^ejZ:`ʍ5'V6y'Ýu窞z'2heh ʊ43098^XɆcJh/!(`:h|ҏ)cjĥj)㫀^ jj9hnz#(~XŤR%Dr)~z%认Ru>ijR(Ҥ2iZLib覡ʌJ/(ؠ bzg{)g~yѦ:rgft 玞6'r19ϙJQJxJhs7(ގ3͢~:6ݦ&)":w)ϦΓçy٨ߡNmܟ*hwj.,2o)ΌJ)o2#b7gӝszʊ((N:n"Z:hNZ;Z'㠲ݞ}i_wާH{\vIjg'h}' g[SbiemJ(ԥҔKhD&.HΓcĦJ`)ZJdiԦڥ*.*{+e 'ނ*iʓW6"ʂj.:lhvs袒j9IQ&ȢN:(ѤJu)JTQ+-: hFIgWZuܧHtYFr¦ԚFpg4ogdjyg&:(8sNz'r9'trl)JꖪF{ hcjS)?>;(MV6NۣfRZx(nS Wi%:)MRnѦbF+nJ^)bZ6((6~?izf銤@趣Nj>֡ZJ瘞~ Ş2y'wᧁ>w灞y~I縍zgwoۧtJ)E)hң;ڣ>3&+hhj5)*xʀۣڑ+{n(ʇh6J(h짦Q~ç^zNעjP) %Zi)TwWCjS> drh& hg})'|x^Z()"gqt 6oimti珗&Ĝ~oog(ʥ>z;hJ(oچZ(nƁ(S^gwZ؛RmݧN*+wRY襣6FJ ԤFE)3Vc:(ͤc6J~麦*+ƅ2H⑊6*8h}::hI~d*tY&њg擙oiԧ;if:u&"{(?uA)LƉ:6 g埆(%w'=YIU波Zw ) ^INjV)ۡjzJ;áچIhށhdڌZ>(n6軦E)Ү h~) J*Qɟ+h:i: h,}i((`چ9gq)&Ze`hi&hh6'myfe)l*(~I'*vigcZh&_)ʦןJx[Cꥪca:rq*-6-jhZ(@}i翟;i>p>GirP(Vg&ƚ:)/j/(à~gmw&śk&xlf6k*VʳkqmJ'tog[|1(WƇ*+3Z'ꠎyyr爝vv¦2a&qfkIf?fs>mҧ}9u&xIV"(etgj&Lja[khҙ:(DCހ!grz ӧnfva}cɩ&N ڣ*gbjL(kL_Failh&(-^oygztɸ',vfꘚXُfʜRlI_cf82Xv#F)(3ru(~IthzΧ%Zjimb9f6iI-R*ɤ6j4ơyfygFnj&Wag弗^&no86eI' ߛdHm{)怖nU]\9oL2gܟꂉ'EdY焝Jr ƦJ>milO^og$vefQF\MFʞni甞jx']d9fϠ"ig=Rsffj^I].JU(ڠgםr|gy&fc&3`&J"^m%QT Pe Gg:K3䍌Fi[&n6歝u%O+$W97sr6zIs^]i~&qh &6c9zeYjel˦j`i1%fZOy*ߟJ^t!F^ك%ŗjɈf@x'\qԘaeV x&ߞN~9 nYfhf7WIKe`P]X JTigePA%,Zђ~C卾68Q8m<n*HI1$.SI6/j殙gyʕJYcFW)vX9N%nWIG.N]XQ,d$2F_&rgk%-HCe)MW&NR^9fZoɰ&ZWiG$A9JehَV`xf!ZcezWO䶐nC!d^I NL$>F -Z@ic" dMI,Q2dRYݖN#6&XcqA!dדL9-I9.M$J6"/8b=8j0hc+ăbs0HAHheUR$1.H#3:#}2#O0zb!(#F~>X棡?8#BI6%qNm4|NQIc$s"89#>8cR"-(bD$TKy)8N/~Eh!؈$hⷊr4H#"%H"C*"_#xbFnH] t HࠂdbZ9ۤK h!j ⮋5x"Ɗ's nᡄXka܊)x~A^2$E^Ac42($ۜJRi ƈ/H֣HZ e!Ņ>m!("Ō^$v{1Nza臥dz97(~ ,:+r68~3aS<`~7_A}5'ᨄJX"3#aj υ_!݉'Htᣇ& 6 `"0aYN(SaĈ"ȋbӋr+x"D. 䎋#"A2)ؓ(J% A=_jD`䁶wdSuQ[4tҧIvaᷓ^{]RuDy釫_}%_|_L|׭ޓ{|)͞{G_w8}Xa< h8+b8_a}']րX`X !V:U!.j a .jJ :րngٟ(|ׂywz}^7su̧&ܡrqgt)7Or!uЧW]wI߷~x)z]rw܇h]vqs]w^Wxg|g_nH' ((~7_My㧵z=GC|w怒O}5}執~7}EwK}YG_ {9wxmht3*umǎxK]o鿦oupaq%7[p \Qru6u\jtjuwW6sw?]tGi]v!7nvIGyvŸ%|ɟj}ܟ~z|7^z7 uN3uugI~G]xנިzLjz57^{=7Nw퇉 ya姄tIpm sק[@t',nuZn[p) \paV[oMnVrʇܛq.rq'&܁q Tq@u%D!tχIFtP y'|ɞ{)ǯ^z9g{wuG/\`qM rR^${5觬xiw^:y!xx׆ wG^NrLJ>rrgmQ[q9ć\rr lqm&ۉmf䛗m6ʛn1nuG[p!#pin pfq!'"zrMg+s5sɷs}w7z]wui]tΗ"po' ,pq \tdvmWjwixv[u7W&sY$[mY 8qö[mI[nݺvmfOlY\m6QmVcm6՛em6}n oY[nٺᛃn[o)oapQfoŻ\@qƗp9cp`qg;p&n}ۮo [o9[pgtҧQIt'[]Cu!H r5iqݛ#kѪlvlvkYZluě(kƹ[WlV-lM/ljٹf۱o5enVljijElfaF|ىeZl)vja!Hadϖ;haSaM*@N4;3N9#] 1t3.i0\K-D C(2Ƌ3dtRd5&01eI;hfZijͫvjni֖Chfjqjͦښk5rcO5Y:trT3Ƀ.h2 O0RK)+2%2+c Ā!H2*"|#H")$LPIx'DR +سs.#& 9 %PYRT6QFIL$4mG5rxEbI)RH)RcHIt7=<3oCDHC $бD)#4RtIa(d/=<\s5ӃM,)ȥ";(r r*+b .'a f%HK $:#h." 2H _!1H$g (J,2/2 ;Xr 4s̎F>CTVa[eKRF;R9C4GmCF4c;Le/2LZ5.9䓗r8ճl7CO-4P=2Pd1c,l«ʍ$E#2=$<M ?$ؑ:"08 tAG{a釚D+|D.ΩD1D4:D7pD:JD=D?ɐDB^DDHDGDIDJDLDMDNeDO|DO(DO8DO_DNDMI\DKDInDFLDCD@D=D9ID5U8D1@bD-+D(PD$9D AD*DD.D7CnC"ZCC>CoCQC7C$C \B B65VAi5>;I/F>#\>Ay>o{O>0K?zS?F?%?3;?E?Z{?u0 ?b?'?8@;@@@1@!{@'&@-N@3@:a@Br)@J@SS@\O@f2I@o@y@fM@,b@}@f*@@@s@ @˞V@@@!@@,@ft@E%@@5@s@9!@*@dA4 B@ Tf5)Mg:f[2̎d&-1)6aS%/yy˺]2%,dKWeQ*IPJrSR%)G>R2))yMJrTDee+y^YԖ칥/ɄLRd3.Ҧ6r=OTe7B Ц.u [BP(?iOz̞'S9"otl'o;)ζuT'K:9rsS')99N>q&5d {*IFIKI$9!9*ARdQ#I!JL2r eA*]KY֖.vK]򗴾0ٌLgT|c=iКT}M4R ՂU%l\W~ﯽ,` Z–-}\:U⩵m/)F R~ߦ' F-Q':ip34)9NFpoΦ7/pKU$$YȆAz#Gb;qߏ$zZD44$(KʶXؗl1y~cæ0i"a,&6=-4CW*2VMMt۷:Wž!xn/1,Ja7λ}-9c:UbVZ+i FZ)Q"@ (>MeT$'I~OԵ/vˆYҸ d&0IJH4$ 8@ I#!jOe0Ra2t/̾jSs'm;O&zse(LjUV -xa1˦gcfw3n~_=FjTsSwʖ4~\~+uXZT4'2gJMRXԙ)IWK"\&5̆^r%8>-OLqE2nHL;&u3{D%.Ip˾a34B06Զ5:*KWY)0KLS/ǽMnGn[cNi pˆ|n|jHV͈ 6%[:jt=df]1̆ged'{;*n3dd7:YMcc[D'qQeyG?Q|l9HFCt'-=)|slfg1IK_sLh]MغVl`;fo3mm|69nt;:mo>4OPu^:n׾t789VF gsVx'@jvڞS9yMZg;/9ɼLV7U"#E2Q4d&Y0IZI6HLr6MmSD,nLeSQeNZW.mk^vrt#=g7x<9)͎= Dz/?|nr۔ S&pssVVl ]|lqf;$Wβ5@/hZ2薌d%4J6V2L[hF92 e1̖_dS$H˦eH&wپw2FXu%}\c%9KRr;|W{_|e;u7'h5Υs']Զu2e|%_6VuoCxv eVQ<{INAR&o6M`|.ɺO圌-9aYۗ|e%Fv5&_3ɖXrv# I.˺o&:[XʞRDk#Jycu5>6s]O\zծr\(8%7vޏ 9U;ڎso|fųuܚo|vĴEjHiT6ٸq3n,Φ>CSte'>*_r'y8IBr=gQ<9ΦoA$d!H~NrT/Pⵗ2pq(FͶU^r+{'|m&xg>8qݧٿz^w޻s|{曲G+ݦw[]ߚyO~K vY{1?)zܞW'ۮFu2LM`w8{P2ܞd,ٍ%`r4׬kYvRkZY*նX=?WTcmuaT4H?PN5S*]DzHJBҒc1O}o-geoϾ4m{mO~<~}~W=jx;ߏy3ɞCw+~.pq7|bx[3);9ul_VjUzݪml Fپzݡ-kk0Z^7 N+[f3X\n[vV%ADJQ5kT*M^5q"r[q3yFzib[F:>wwǬ|篡wݾYw.O\ֶt7}tlXnnq3M|e!Nqsl"fk7nMuۮvxMioF[7q -9v|X~mW-Yzmr֗kL [l`y̠M'4IyM΋/KLWc &wrc5ڈ&6m'wz/R ~˼|'6Mw#Ƕ8ىeS$N@g[)9qˍLk# -/y_ v o~_斷ml;^ź.7~6ȶtqKVں6.'\Վ mb~tsd7R|8-{,ifGAj6C ͎hṙb-ʶ/Λt?u1ƥL?m.qk]x(17*yǞ3 `~VQn8RŖm-r[ުw z"Ӗ5i:v5ӮMeWl-XRx}f9)vƧݒ,n\b vnhka3WQIjXX~1gP{tEY,Yf9},g{@R̖.g+gڶ6CkqYjް Bh_5`I@xp#,rƶ),^hm~Td W#`9 0rJ#I#J&OR؜UQ;IXҷ dq([L~jQiI`TR\NSjZ嗀4j`TL&.y:Y% kaӪ5%eYM:mTʩ4Lj\knUֳdX"_ )fu-9~ʪL?GW]))u3]7E8/8{#h %.whGj9l&],I)KWd_c y-J]3 '9bPjҎsPT#GB`DiVL~tu@RvO )Tjڬ5UIc&XrT 3yMfr[K( [;Yծoۏۮg Y{zZ16m~-ѩܛ&7J"Kqɍt])!=~UtY0 dNMKBOh蚵(?iΖgr? f5(2-R&A: >Z/8O% R0ޠz+WUbg >:P*{s@t#8B" IS^^1/A|+F n"Q?$I"HDN(nLl/x=q$ 'RʒOid[4jI6Fcle#-r*1,&#-yTM#$+yKIAӍe,VȲ8r*ē!y(&FRۦ;L2c(CJ*Sv_MY*UꑴI':پ~h$I.ɦA_:W@Q}cQȎFE6j#gG>=L!HEd-uJXח &4XOR[%S.NrW4%& HF2 d#iHAQte7,Y`Nxĥ_.9\֙U69aRG`TʲmByOJT\ m@Nnet#7GJFQ卌C)BF"R26I 9HOy.rJP2,6n3#,-4t*Q2{'yLjT2JLd%0b8ѽ$g%):ILWU0ɉK]|hCPF4&;Lfse)S:6Ep_RkT`G:Ϊkse%9)9\JWÔ~! yĶ&q8lf%Dr=ŏԓU!I,J[S.l&_3irnUA2v-f4iXҖdeG)iPIEԒ*WZ/Tlw$K%IMnXĕ16ٽdAVʮVάCiIy*t bev&-kR kM-)SH:ͺks4&'/IN*RRTq HEb( ,gc$&dž3qŏ)ym˂ZԘͦ9&YjmN]>d駧=2fSte'Ce* F*Qw ?!9K~aRg/;9OsUVc0[Wl U*nSM-Un]r&'.uZגᨕ'@M~_r]ܥ(NLVȉFW"hFJ1䒤*W>URۙ;5`P:bZ< Mni31e%xG5D%{%hG5,$(O̦inhUA.P4_m[kxǖnjKJvv'y^xNVNh"f%$8H1dI D9 Q؋%2DNĢ$m d!H@Ol&7yQu;)MFBF3흌f39zKb<$"XD/t&9I?qL&7N:kE$iQGj7Rjeou !92PqY{K~Zm5|&O-&Lpnm_m#)MJv774e"`!ɋE!E)#A xö"Ql,^ FN/QӐdd/ɨRx'uA:!ue'7ʺa3=/q|d*^TrgI:YFnS -Mz]bh}zl2\Ķ۾q+^' 7V\^7(fH Qv šPvU 8Ŗ"QQPm?|n?!HFv?Vy'TJNQ2feIHH~Q,D([ %7j}3|&M0M:bD[K*VY~wȞ7僻~ڗ%ž.%w;]&wJUSY"ΕjE$اF&/p{Hps#"i6221W!?ozĝwI)nz 8YB1:t]#5 GrFr3DU(GZG,egþ%Dy1yOyTfU+9BKT|)^"Y6v-gwk'92K^VSzޒӷejKwTί-8`As觯j q|c&~KO㌜L 5@|ݮg:YҎvs_nċ Xc;A2#SHF4ɥ!hC&؊h$-iS;d%?&LJJIZ}`[VL -Is`>v^UVMxKar6Hqc;J8$U8*yݢ0=Dv&YLT1Q"{{& ~#fC:}Ҏt̞𗄾~Ɗl\6?ۍgc =JFKԤdCn&Qdk#SKWd YKWRZ,(Yj:•F݊mv ^5zkYۦEk_:Ӷ E+)q\:f- N{3_B?F#%"Yp>1YEL _8B9̎@qKt}0DP#HD1Ǝ]"YJPҳ$cCZ+2$/ X3D4M6_򔎤MeUΦ4wukga̷/9W⩴/ucl|< Zt$)<h'E叒tG>*zbM97Qa7bgHG3QFD0Gc9xr'===bIWr6Ab{ GTȒl#%Xb"1͓ԣ$#hE2r<ܑ$5YP]L&q5Rta%AkM[YJ϶,m+ ɟm-fKUvu$DbghH6+2g,?YΟT^H>uN3*a INj< b &i9FOÞU(AnTo+5HZI򌓟Dfu<NZ|\hIπv+T>߈ ^@8nwSهL?I$pö V¢$1 ئD^:$ܕ"A؍bƍ܇d)HHH ! YDqt5ؔPsd,PZd?f*G{a^? EB i |L&h,a#50 -gKw:8=tcg;|ۯTf8Inq^ <Ѭh6ARPTE K8~F&3rsbhtò0ɋjw XVD63v1%v)͈-qgCOrdڥ8$rI#=9˪bҴ,!IEH/q1T5%OAwkg91+W".~L\c@Y1ݗmLn+\&:uܮqq&c7-hcG 7ř,g w> H6Dv&QdB͍T} {`U=0'v7r%T#؀Â1)v\r$_x@A:ܢfd]:u [چ6 Rz+Z:\RX[eK. Nqm,i;F79+\k޲IkjkWk;Ox7A,J!أC6 pvlqa:rNx%"=QD4% xNqF,y" hkE5$L'$<2|Cĕ0ݎiEƖFnQՊe%BOrS4&-)T³Uŗ}] 19vJIV+ bP/kKecC7.n\W =P,'"IHvM0gV8ſn*v#TG9z^ǵ=>t : {FZscn%/vk^ڲE~,mTiMڌTj( -D1Q@D'cCz.XTMLjRO'G Q^,dO]$6z5ݫMe!: P4 BA}{C7MNt \z捷/yۤ6ۼNeoC\7z<nrۚF7@9Nrk`YfֻQގDl+>1OTr~ӰĿ]0iJi %H{@xc{4ا5n~D YCy3"IMBTȧ5.OYJޗ&̀^*B6x[H@-u8m ohԖ4Mj(B%b+ũc/Znؖ2͟Ml(׀N5cVbˤY$Hj-ZFBDR gX7 ldBs*ak.o#8vdÄ5(NHb[lA:S곖v5Y+QU2V6-mVp]dw9kIVlb H.r]V .~\VD1ɀ}Y٘6P1L^`ksV:dQ9bvAœԥ*[RHO#1[쿦 0vZS4GB*.'2i3K}Ԯi9I*oMwZ=qc-6 a:&/wknXuN6j]W45'(AOTBu-EjTR/oNiS؟%%LC3LEx,n 4fKlǚ=k.l"QF r  LtȣF*qRK^܇A3$ hF>.9&}DLSJ¦=:1Tz./u~KYRc(:N"ZRL$)OJoHjaSZD(N*fQrԔ%D)CXDr >\(B kC<$e&GJV8&5LYȘ4hT>2z(HLGF (D`32D"4Q#AiyC m2<P}vFBQ$PcP}֤mD |6 X`pP H \0EH@`- ip>;@q8 op`1 Z@+X X-` Sx@ `7`@P!< f & @> `@0@ H P ` @ `( x&` hJ/ hp`<@~  A0"D(@`# HH&4 Nx@ )H `S(< M7777rb-grib-0.2.2/data/regular_latlon_surface_prec.grib10000644000004100000410000000015411732375622022471 0ustar www-datawww-dataGRIBl4b 0001 `u0 A7777rb-grib-0.2.2/data/regular_gaussian_pressure_level_constant.grib10000644000004100000410000000015411732375622025321 0ustar www-datawww-dataGRIBl4bd 0001 @W8W8sD A7777rb-grib-0.2.2/data/regular_gaussian_pressure_level.grib10000644000004100000410000003215411732375622023415 0ustar www-datawww-dataGRIB4l4bd 0001 @W8W8sD 4 B F|3ឌf2`61 ]En*M 4Os8$ Fb-@DF"|C L"FB6Џ$q& @JZ&9O0)ALtTBPb+A\ W诅z+]V³xL*N \RB@'=O"yПE(QEDS"X~,j ]b†&1 f#6,)dK:Z.IplZ2ĕ&(BoKŬ+RPPzxD$!DP@P:!uC@@z$*|LmD'= O)K hS E.(B Mb]xDh"PA}Cц8D!! dC)ȓ(X H^Ɔ*0yhWX%*DIJ> @3 PXB`BW1 e v6+iz kS}38ѽj=p>E 4QԎn#CRP0 EA)tv*3ArÀ@8.N @@ gCt(dxGf8 Tp)jDisx(7Ѭ ^Dp*J PT¸$ 1A ;aPDBC%2Q`&:AO=AwC˟AaSU E'8ɔKzVҮԲ%),H6j44 '^6ѕKWr"!t6 I (OB>pQh4~ QB3(sT9 ic/h8$0$ 0At@ц6 hNB `: @b2|H#.V7A opm=)Px)>JS"5[+ TXOfԖt&%.i9Gz,4Y"J?r#lм6#F(!D"(pĆ&[tqC G^5a ]#G 6[Bņp4 a0%)GB@@PX9PӇP?"#F?BZF6 p&C2էG*[VjUŕ+NIFP0DLYB xH':_"؃Ed#)l ~4AdL xj,164Mdž ~\8hw#ʝFf.YQ ~Ba hdÿ%Q] pURA_»@F>2*&Q/ A1S ;Y2l0IxOrZؚ$$G<(u#V^#AdCx.X"L c,+A|d<'Y|N~'HTR'E cT֢b]/$HjC芤PG4|JVB|E,#GP:qŇ1 &]K\bƔ@GP;Aˍh#Ah&>Qpĺ!`<+-.4 s(\ pDz/Q؆!)E(p.IL^̘D()EUWr!=>NpS*}"Adɥ- ZJjNC|զ8k%A4ECixR]C*L[c801pSbm H2 @D!NYB͖l,`*WzŖ5 j*U2Tt&';+hF=MnC:(f803GIA1Q}Cͦ?2 N] Iȣ?Qt&?M:bF'!7iNZA4QPd΢D4e˜lƦ5ѕ}#QHLKGP$5)U Q_S%ZZVpү| YjԸ'&:at;Nq<(hAaM9f<mf/0z_h6@zѪ%;1Td*UjVjŅ, [T—SިX=\Rה‹̲%b%Ɯ3A; ͎bocTI eʣGufkb"լ]K#^ 0w]\zղe 3D PbD ьhKZU5-uLf4Y4 .n˟`kæ15^bU|!6ɽM2a@J" ?qp'Qy}G 7ƚ#) HeI”V>.郬iC>YP631,f :1\_ɔel+j+mUf;y (@`ި3 H1XzL&5aNzs(?4;HHRIƦֶ1;OJwDY@*rTڦ֌1*as %鯭Sd Xq6jU^w) dpµQ\"ժ&7jd3ܨۗ9i׮rÔ\' u̚c$Fql\ }4Ŷs[4֦qMkCRtϷ kGYu.iak_`ٔ67Mo'}k^q1 fOeaC^KYZZuLc֩-nn~z77Mo z~ƯdC Em=aڴUd'Af &gN:r{zƳaLf[9YڸQMmqDه5t x6%_lh|}>Y mNpv_1eJbk+p"8ۯ~\_/cOrTex/}L~h3Gb6r4Qmcj#Kڨvӧ48nCq\6]-$gc ؒe0Y]bOdzLgO}#h-o}bG>aO{_X>MoU{ (IJRJ= vIrt&O1BGb:RD4RG>1O_:P-u E?,`&A~ P, 1H:A+"Ogھ5f{ ǽO|>o|Xψ{`ӾO~~ߚ>O~S8YE3H51Dd$iQAR_=G$?<.!q HOv?l .@)`@Z P`(T%?1/}߆ȿ|;8Ƿ=in{^=l} :?>|ߞ79O~`Y<h 0 U8t: qu{ߞזjzl<Qz#Ξþ/} п}ψ{#Ҟh/`#g?`1j03 Mx?E,*! HFoՀ\ q)Pi  ApɅ|/! dCr0`@lA8 @b .!9 8DA OlW@M~\?1|^=o{׽>MOߞG>ycng=ϴ9 Ol@F)HD1 am Hx> ~H p}V@DkxKŽ𘃤'MA*74_h8AZ0t$[@ p#ac o~_X;ap{؞Ǥ=}}x?)bz;^lg)/ˀ`S@S_>~wC=O$(A /A |?uϝ}?3AwG hBb pD5a' HbBZ߆d)! Gp}"?P4 3*>aVz^p `@~r? |_:WC7H=O, ?ނ  (AІ`yHEApȂ q8,Ž0ĉU"? HXzɆd-@ 0A)@~B7o2y{^y1Nw79O_G޾ ?M|g>)z^GB>х!M@o _>ώ|=Owwk]7VАt6"q0y`i@u/~ @R3JGb p6oH;RĊ" TCvДd'`:A2Ok Gh!Ao~GMo}3_=oHzNGu{] gPI} ?C_>ϫ{ʞ񧖼uu{T79rHPDkHfCb È 5@i0 {>{>bCHFWS Ǥh4A> L qY ?A*O~ss{^ǢYAz^Z7{< vGI:eN}sM7}@>m|{X7;=ntӯ@rbm{ކwpծt;NRSF]?P_>7?Yop{#\~W;1ܯy;џ@#>qzk^Lg<-w^0W;v 29ɏ s?m/ yty O}zvqàD7*bd >o|=eO*xpOv]Uaܯ w1O&>@~3g491.v{]O~כCyk7^).sæ]ruæ0%95ďHG%9x񧉻{^t] >ܲetbG>ky#Z;u]TB:؎uí7=9a͎xlǃ͹pW[|]l' %Ɏ1t3܂߾}|C^f'P9Nw㵝wL14r\P.t덜 g8E ;rsR;-wCҟG<1ٮsÜ9zS'A.tW89iaqKw*r \'8au06-lcXZ巋/y]ZF81 q?HyƝVg/7p˛ G6!-p [9s}[6)n~߰w; ˍmo[9nt發AՎr܄vescu]t\.nncrFݶ5ͪp <6-lkcZ׶qmqmk?-:xSP㷥 TlcvFNtێF뵵1jSdp8% nۆ8ENrCyFٹR|^'M-jUצ q Tb}Vn3XzÖ 1! l t"GiscV-n#bZ6koFYe;"eLecZv߸.tܢ7E,iKVѷ-kkSZdՆ3g9ɶIZjS*Жqq}ZҶ3}c0ƣ%rkNZ4ѶM&kk[f5Ma "i+t^f4e Lj+RZƣɓfSBZѦ^u,!dM0˖@\BՖr.y] 8f pk 7Me;Z64 g3&FG1,ec8Φ c,Φ-nCmӦ2٩$|+Fe81LxfHv49pW̧HXXbX~laY:.]s\~20~ _s.l+Vr¯ko[v`vmdZV4=`T2a FbnۮvkbXxMy!`pMXjKٞ&k2͇n+_ھҖ~4Qle  .r˝^4*/q>RT&(JeTZr,aj\.1^k&YR͖eүayk[",T*rSpuf:Yb f6d61QK]J~0} [z-j+_SX80}~]W$1vbz.{,aS آ_zꖜu,mZ*Yb¥ \OoSZ( C(RBU6J*WShE-*1SVŖrSWp,u?O…zF*X*VU°ն/)~k_؈a+\De!^W2pq\Yߗ%sQX2>k ,W²\E},-`YVµ%-ulSYCEX عմ+uN*8Me4'5:PB%7YEIO |T(J*pU2EU+aVZڣ'=PPWU^Ej,rk\Ve-p+]򗞺u,ZWj5(K Tʷ.anK.W]*eOjpSX~,5_W⿕֭s+_ VRUE!GXzǖfAC)L\Ɨ&7O"}Si:NpS㧁AETB|E8T*S禡3iOڑ5/yMsS*2MQ[D[ȭkKXZ%![T T&7Oj-=fUҢM*=O wTz쥥8*YJVZ KU2Td?jUڴUED(:)K\֖Խ&1 LhSXϦ}5Mm(GVS(u@IMjd'u? QTNjTN)KVr:ubWھ歕V1O*XPx'i;INqS57qU TԾEAuTjTʣTE+)N*]QS')<Pڄ&6iO xSq/)rJ Q0IK\d&1)Ld:tMGRR*$'-5Mtƞ$A Mhn&7IOrwӾu5*iR nSTu)(Ej#QJTGJ*P2ydE9iNs'C*DĦ6ɦLrex&3LWm6iO rJ% &1IT晤'y0u˥,T8P/QLjep&6;n{4 h3>φ4Mllqg 8iMoo0F4Mg;fU2!L6`2He,cKX01i3a::w *uO0 @#rV$$5+q 0T> z $ Nm ]  N M 'v ,+'D X5zNW}W z,?d/" $zMIZ   ^z~}shZ#0d,*:arp ."gBX1)G]A%39P@%" 98 ~_ `7777GRIBL4b   0001 `u0,\GcF6d0r5 if iZp yh]l(!V4 f7_ ,2$PK1v-g /63w r$$J-!3Q KD-()q,{  BtUA?OLbA7/" (={ ;3rVWWHpTd/#,2kc*;fsd'"U)& #B"(%SW\C@X j]Z  DF3j   5$f!f~qU?%-b!- Pg--:GyaI{O=@@BB<,i~51fRBD4X=AU&6#<#0i "wh6Nr%O7777GRIBL4b  $ 0001 `u0#k2KG[Ti5# . (0ajA3QP33,$Tz iaC}EYsG :x U tCN wu''OwCCyL@9ځ D @TI7FP^\'@9*( 52y k5:%cd7777GRIBL4b  0 0001 `u0"Jp$)c 4 *e5*\ ? +%_&9w  ZW^] ,D  n ( . p X2 2;+%{ 2CmjJ+  {p ^* cR6jNO&K$ |-$NcrmPCH zG 4*p[<qn>*  BMA[gp$px? 1#5= [/ =D Y<* (.L]  I(%]v/  . W n4<W"RL#O}"5M j G"|aF;T*!T 0 %gD*iY/# 7777rb-grib-0.2.2/metadata.yml0000644000004100000410000000670511732375622015412 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: rb-grib version: !ruby/object:Gem::Version hash: 19 prerelease: segments: - 0 - 2 - 2 version: 0.2.2 platform: ruby authors: - Seiya Nishizawa autorequire: bindir: bin cert_chain: [] date: 2012-03-09 00:00:00 Z dependencies: - !ruby/object:Gem::Dependency name: rspec prerelease: false requirement: &id001 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" type: :development version_requirements: *id001 - !ruby/object:Gem::Dependency name: narray prerelease: false requirement: &id002 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" type: :runtime version_requirements: *id002 - !ruby/object:Gem::Dependency name: narray_miss prerelease: false requirement: &id003 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" type: :runtime version_requirements: *id003 description: This class library enable you to handle GRIB file. email: - seiya@gfd-dennou.org executables: [] extensions: - ext/extconf.rb extra_rdoc_files: [] files: - .gitignore - BSDL - Gemfile - LICENSE.txt - README.rdoc - Rakefile - data/regular_gaussian_model_level.grib1 - data/regular_gaussian_model_level.grib2 - data/regular_gaussian_pressure_level.grib1 - data/regular_gaussian_pressure_level.grib2 - data/regular_gaussian_pressure_level_constant.grib1 - data/regular_gaussian_pressure_level_constant.grib2 - data/regular_gaussian_surface.grib1 - data/regular_gaussian_surface.grib2 - data/regular_latlon_surface.grib1 - data/regular_latlon_surface.grib2 - data/regular_latlon_surface_constant.grib1 - data/regular_latlon_surface_constant.grib2 - data/regular_latlon_surface_prec.grib1 - data/tp_ecmwf.grib - ext/extconf.rb - ext/grib.c - lib/numru/grib.rb - lib/numru/grib/definitions/grib1/localConcepts/kwbc/name.def - lib/numru/grib/definitions/grib1/localConcepts/kwbc/paramId.def - lib/numru/grib/definitions/grib1/localConcepts/kwbc/shortName.def - lib/numru/grib/definitions/grib1/localConcepts/kwbc/units.def - lib/numru/grib/definitions/grib2/localConcepts/rjtd/name.def - lib/numru/grib/definitions/grib2/localConcepts/rjtd/paramId.def - lib/numru/grib/definitions/grib2/localConcepts/rjtd/shortName.def - lib/numru/grib/definitions/grib2/localConcepts/rjtd/units.def - lib/numru/grib/grib.rb - lib/numru/grib/setenv.rb - lib/numru/grib/version.rb - rb-grib.gemspec - spec/grib_read_spec.rb - spec/spec_helper.rb homepage: http://ruby.gfd-dennou.org/products/rb-grib/ licenses: [] post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" requirements: [] rubyforge_project: rb-grib rubygems_version: 1.8.11 signing_key: specification_version: 3 summary: Ruby class library to hanlde GRIB file test_files: - spec/grib_read_spec.rb - spec/spec_helper.rb rb-grib-0.2.2/Gemfile0000644000004100000410000000020411732375622014366 0ustar www-datawww-datasource "http://rubygems.org" # Specify your gem's dependencies in rb-grib.gemspec gemspec group :development do gem "rspec" end rb-grib-0.2.2/.gitignore0000644000004100000410000000011411732375622015063 0ustar www-datawww-data*.gem .bundle Gemfile.lock pkg/* ext/Makefile ext/mkmf.log ext/*.o ext/*.so rb-grib-0.2.2/lib/0000755000004100000410000000000011732375622013645 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/0000755000004100000410000000000011732375622015013 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/0000755000004100000410000000000011732375622015736 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/version.rb0000644000004100000410000000007211732375622017747 0ustar www-datawww-datamodule NumRu class Grib VERSION = "0.2.2" end end rb-grib-0.2.2/lib/numru/grib/setenv.rb0000644000004100000410000000051211732375622017565 0ustar www-datawww-datadef_path = File.join(File.expand_path(File.dirname(__FILE__)),"definitions") if File.exist?(def_path) env_name = 'GRIB_DEFINITION_PATH' if gdp = ENV[env_name] ENV[env_name] = "#{gdp}:#{def_path}" else path = `grib_info -d`.strip if File.exist?(path) ENV[env_name] = "#{path}:#{def_path}" end end end rb-grib-0.2.2/lib/numru/grib/grib.rb0000644000004100000410000002777611732375622017231 0ustar www-datawww-datamodule NumRu class Grib class << self # cache due to momery leak in the original grib_api library @@gribs = Hash.new def is_a_Grib?(fname) is = false File.open(fname) do |file| is = (file.read(4) == "GRIB") end return is end alias :_new :new def new(fname, mode="r") key = [fname,mode] if (obj = @@gribs[key]) obj[1] += 1 return obj[0] else grib = _new(fname, mode) @@gribs[key] = [grib, 1] return grib end end alias :open :new end # class << self alias :_close :close def close @@gribs.each do |k, val| if self == val[0] val[1] -= 1 if val[1] < 1 _close @@gribs.delete(k) return true end end end return false end def inspect "Grib: #{path}" end end # class Grib class GribMessage def name n = get_value("name") return n if (n && n != "unknown") get_value("parameterName") || get_value("indicatorOfParameter") end def sname sn = get_value("shortName") return sn if (sn && sn != "unknown") "id" + (get_value("indicatorOfParameter", ::NumRu::Grib::TYPE_LONG) || get_value("parameterNumber", ::NumRu::Grib::TYPE_LONG)).to_s end def units get_value("parameterUnits") || get_value("units") end alias :unit :units def z_type zt = get_value("typeOfLevel") return zt if zt && zt != "unknown" z_sname end def z_sname get_value("indicatorOfTypeOfLevel") || get_value("typeOfLevel") || "level" end def z_value get_value("levels") || get_value("level") end def z_units get_value("pressureUnits") end def date return DateTime.parse(date_raw) end def date_raw d = get_value("dataDate").to_s.rjust(8,"0") h = get_value("dataTime").to_s.rjust(4,"0") d << h end def step get_value("step") end def time_interval get_value("lengthOfTimeRange") end def step_units get_value("stepUnits") end MEMBER_NAME = {1 => "", 2 => "n", 3 => "p"} def ensemble_member pn = get_value("perturbationNumber") te = get_value("typeOfEnsembleForecast") name = "" name << pn.to_s if pn name << (MEMBER_NAME[te] || te.to_s) if te name end def gtype get_value("typeOfGrid") end def missing_value get_value("missingValue") end def get_xy lo, la, = get_data case gtype when "regular_ll", "regular_gg" lon = Hash.new lat = Hash.new if get_value("jPointsAreConsecutive") == 1 lon["ij"] = 1 lat["ij"] = 0 shape = [get_value("Nj"), get_value("Ni")] else lon["ij"] = 0 lat["ij"] = 1 shape = [get_value("Ni"), get_value("Nj")] end lo.reshape!(*shape) la.reshape!(*shape) lon["short_name"] = "lon" lon["long_name"] = "longitude" lon["units"] = "degrees_east" idx = [0,0]; idx[lon["ij"]] = true lon["value"] = lo[*idx] lat["short_name"] = "lat" lat["long_name"] = "latitude" lat["units"] = "degrees_north" idx = [0,0]; idx[lat["ij"]] = true lat["value"] = la[*idx] return [lon,lat] else raise "not defined yet: #{gtype}" end end end # class GribMessage class GribVar Day0 = DateTime.new(1900) MAXNDIM = 7 # lon, lat, lev, t, step, timeInterval, ensemble def rank @dims.length end alias :ndims :rank def total @dims.inject(1){|t,d| t*d.length} end def dim_names @dims.collect{|d| d.name} end def shape @dims.collect{|d| d.length} end def dim(index) index = dim_names.index(index) if String===index return nil if index.nil? @dims[index] end def def_dim(name,index) d = ::NumRu::GribDim.new(self,name) if index == -1 @dims.push(d) else @dims[index] = d end return d end def put_att(key,val) @attr[key] = val end alias :set_att :put_att def att(key) @attr[key] end def att_names @attr.keys end def typecode if missing_value NArrayMiss::FLOAT else NArray::FLOAT end end def missing_value @msgs[0].missing_value end def get(*indices) sha = shape mask = nil first = Array.new(rank-@xy_dims,0) if indices.length != 0 if indices.include?(false) sha2 = sha.dup sha2.delete(false) raise ArgumentError, 'multiple "false" in indices' if sha.length - sha2.length > 1 indices[indices.index(false)] = [true]*(sha.length-indices.length+1) indices.flatten! end rank.times{|n| ind = indices[n] case ind when true indices[n] = 0..sha[n]-1 when Fixnum sha[n] = 1 when Range f = ind.first e = ind.end e = sha[n]-1 if e==-1 e -= 1 if ind.exclude_end? sha[n] = e-f+1 indices[n] = f..e else raise "invalid indices" end } if rank > @xy_dims mask = NArray.byte(*shape[@xy_dims..-1]) mask[*indices[@xy_dims..-1]] = 1 (rank-@xy_dims).times do |i| ind = indices[@xy_dims+i] case ind when Fixnum first[i] = ind when Range first[i] = ind.first first[i] += shape[@xy_dims+i] if first[i] < 0 end end end end shape2 = shape.dup sha2 = sha.dup @del_dims.each do |i| shape2.insert(i,1) sha2.insert(i,1) first.insert(i-@xy_dims,0) end mask.reshape!(*shape2[@xy_dims..-1]) if mask value = missing_value ? NArrayMiss.sfloat(*sha2) : NArray.sfloat(*sha2) index = Array.new(MAXNDIM-2) @msgs.each_with_index do |msg,i| idx = @idx[i] next if (mask && mask[*idx]==0) val = msg.get_value("values") if @xy_dims > 0 val.reshape!(*shape[0...@xy_dims]) # val = msg.get_data[2].reshape!(*shape[0...@xy_dims]) unless indices.length==0 || indices[0...@xy_dims].inject(true){|t,v| t &&= v==true} val = val.slice(*indices[0...@xy_dims]) end end (MAXNDIM-2).times do |i| index[i] = idx[i]-first[i] end value[*(Array.new(@xy_dims,true)+index)] = val end ns = sha.length ns.times do |ii| i = ns-ii-1 sha.delete_at(i) if indices[i].kind_of?(Fixnum) end value.reshape!(*sha) if missing_value value.set_mask value.get_array!.ne(missing_value) end return value end alias :[] :get alias :val :get def inspect "GribVar: #{name} in #{file.path}, [#{shape.join(",")}]" end private def get_time(date) (DateTime.parse(date) - Day0).to_f*24 end def init @attr = Hash.new @dims = Array.new msgs = get_messages msg = msgs[0] put_att("long_name", msg.name) # put_att("standard_name",std_name) put_att("units",msg.units) if msg.units put_att("grid_type", msg.gtype) put_att("missing_value", [msg.missing_value]) if msg.missing_value vdim = Array.new xy_dims = 0 msg.get_xy.sort{|x,y| x["ij"]<=>y["ij"] }.each do |xy| val = xy.delete("value") sname = xy.delete("short_name") ij = xy.delete("ij") if val.length > 1 d = def_dim(sname, -1) d.put(val) xy.each{|k,v| d.put_att(k,v)} xy_dims += 1 else #xy.each{|k,v| va.put_att(k,v)} end end z = Array.new t = Array.new st = Array.new ti = Array.new en = Array.new hash = Hash.new msgs.each_with_index do |msg,i| zv = msg.z_value tv = msg.date_raw stv = msg.step tiv = msg.time_interval env = msg.ensemble_member z.push zv t.push tv st.push stv ti.push tiv en.push env ary = [zv,tv,stv,tiv,env] if hash[ary] # error m1 = msgs[hash[ary]] m2 = msgs[i] a1 = m1.get_keys.map{|k| [k,m1.get_value(k)]} a2 = m2.get_keys.map{|k| [k,m2.get_value(k)]} a = Array.new a1.length.times{|j| a.push [a1[j],a2[j]] if a1[j]!=a2[j]} warn "BUG: send the following message to the developers" p self p ary p a raise("error") end hash[ary] = i end [z, t, st, ti, en].each{|a| a.uniq!} # [z, t, st, ti, en].each{|a| a.uniq!; a.sort!} @idx = Array.new(msgs.length) hash.each do |ary, i| zv, tv, stv, tiv, env = ary @idx[i] = [z.index(zv), t.index(tv), st.index(stv), ti.index(tiv), en.index(env)] end del_dims = Array.new if z.length == 1 put_att("level_type", msg.z_type) put_att("level_value", z[0].kind_of?(Numeric) ? [z[0]] : z[0]) put_att("level_units", msg.z_units) if msg.z_units del_dims.push xy_dims else d = def_dim(msg.z_sname, -1) d.put_att("long_name", msg.z_type) d.put_att("units", msg.z_units) if msg.z_units d.put(NArray.to_na(z)) end if t.length == 1 put_att("time", msg.date.to_s) del_dims.push xy_dims + 1 else d = def_dim("time", -1) d.put_att("long_name","time") d.put_att("units","hours since #{Day0.strftime('%Y-%m-%d %H:%M:%S')}") d.put(NArray.to_na(t.map{|tv|get_time(tv)})) end if st.length == 1 put_att("step", [msg.step]) if msg.step put_att("step_units", msg.step_units) if msg.step_units del_dims.push xy_dims + 2 else d = def_dim("step", -1) d.put_att("long_name", "step") d.put_att("units", msg.step_units) if msg.step_units d.put(NArray.to_na(st)) end if ti.length == 1 del_dims.push xy_dims + 3 else d = def_dim("time_interval", -1) d.put_att("long_name", "time_interval") d.put_att("units", msg.step_units) if msg.step_units d.put(NArray.to_na(ti)) end if en.length == 1 del_dims.push xy_dims + 4 else d = def_dim("member", -1) d.put_att("long_name", "ensemble_member") d.put(NArray.to_na(en)) end @xy_dims = xy_dims @del_dims = del_dims @msgs = msgs end end # class GribVar class GribDim attr_reader :var, :length, :name def initialize(var,name) @var = var @name = name @attr = Hash.new end alias :total :length def get @ary end def typecode if NArray===@ary @ary.typecode elsif Array===@ary @ary[0]["value"].typecode end end def val return @ary end def [](*ind) return val[*ind] end def put(ary) @ary = ary @length = val.length return @ary end def put_att(key,val) @attr[key]=val end alias :set_att :put_att def att(key) @attr[key] end def att_names @attr.keys end def inspect "GribDim: #{name} length=#{length}" end end # class GribDim end # module NumRu ##################################################### if $0 == __FILE__ include NumRu if ARGV.length>0 infname = ARGV.shift else infname = "../../../testdata/T.jan.grib" end Grib.is_a_Grib?(infname) || raise("file is not a Grib dataset") p grib = Grib.open(infname) print "\nVars\n" grib.var_names.each{|vn| p v = grib.var(vn) p v.dim_names v.dim_names.each{|dn| p dn; p v.dim(dn).get } p v.shape v.att_names.each{|an| print an, " => ", v.att(an), "\n" } puts "\n" p v.val } end rb-grib-0.2.2/lib/numru/grib/definitions/0000755000004100000410000000000011732375622020251 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib2/0000755000004100000410000000000011732375622021256 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib2/localConcepts/0000755000004100000410000000000011732375622024047 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib2/localConcepts/rjtd/0000755000004100000410000000000011732375622025012 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib2/localConcepts/rjtd/name.def0000644000004100000410000000124311732375622026412 0ustar www-datawww-data#Total precipitation 'Total precipitation' = { discipline = 0 ; parameterCategory = 1 ; parameterNumber = 8 ; } #Total cloud cover 'Total cloud cover' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 1 ; } #Low cloud cover 'Low cloud cover' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 3 ; } #Medium cloud cover 'Medium cloud cover' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 4 ; } #High cloud cover 'High cloud cover' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 5 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib2/localConcepts/rjtd/paramId.def0000644000004100000410000000113511732375622027047 0ustar www-datawww-data#Total precipitation '228' = { discipline = 0 ; parameterCategory = 1 ; parameterNumber = 8 ; } #Total cloud cover '164' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 1 ; } #Low cloud cover '186' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 3 ; } #Medium cloud cover '187' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 4 ; } #High cloud cover '188' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 5 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib2/localConcepts/rjtd/shortName.def0000644000004100000410000000113411732375622027431 0ustar www-datawww-data#Total precipitation 'tp' = { discipline = 0 ; parameterCategory = 1 ; parameterNumber = 8 ; } #Total cloud cover 'tcc' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 1 ; } #Low cloud cover 'lcc' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 3 ; } #Medium cloud cover 'mcc' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 4 ; } #High cloud cover 'hcc' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 5 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib2/localConcepts/rjtd/units.def0000644000004100000410000000113211732375622026631 0ustar www-datawww-data#Total precipitation 'kg m**-2' = { discipline = 0 ; parameterCategory = 1 ; parameterNumber = 8 ; } #Total cloud cover '%' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 1 ; } #Low cloud cover '%' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 4 ; } #Medium cloud cover '%' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 4 ; } #High cloud cover '%' = { discipline = 0 ; parameterCategory = 6 ; parameterNumber = 5 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib1/0000755000004100000410000000000011732375622021255 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib1/localConcepts/0000755000004100000410000000000011732375622024046 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib1/localConcepts/kwbc/0000755000004100000410000000000011732375622024774 5ustar www-datawww-datarb-grib-0.2.2/lib/numru/grib/definitions/grib1/localConcepts/kwbc/name.def0000644000004100000410000000662011732375622026400 0ustar www-datawww-data#Surface lifted index 'Surface lifted index' = { table2Version = 2 ; indicatorOfParameter = 131 ; } #Best (4-layer) lifted index 'Best (4-layer) lifted index' = { table2Version = 2 ; indicatorOfParameter = 132 ; } #Vertical speed shear 'Vertical speed shear' = { table2Version = 2 ; indicatorOfParameter = 136 ; } #Categorical rain 'Categorical rain' = { table2Version = 2 ; indicatorOfParameter = 140 ; } #Categorical freezing rain 'Categorical freezing rain' = { table2Version = 2 ; indicatorOfParameter = 141 ; } #Categorical ice pellets 'Categorical ice pellets' = { table2Version = 2 ; indicatorOfParameter = 142 ; } #Categorical snow 'Categorical snow' = { table2Version = 2 ; indicatorOfParameter = 143 ; } #Volumetric soil moisture content 'Volumetric soil moisture content' = { table2Version = 2 ; indicatorOfParameter = 144 ; } #Potential evaporation rate 'Potential evaporation rate' = { table2Version = 2 ; indicatorOfParameter = 145 ; } #Cloud work function 'Cloud work function' = { table2Version = 2 ; indicatorOfParameter = 146 ; } #Zonal flux of gravity wave stress 'Zonal flux of gravity wave stress' = { table2Version = 2 ; indicatorOfParameter = 147 ; } #Meridional flux of gravity wave stress 'Meridional flux of gravity wave stress' = { table2Version = 2 ; indicatorOfParameter = 148 ; } #Cloud water mixing ratio 'Cloud water mixing ratio' = { table2Version = 2 ; indicatorOfParameter = 153 ; } #Ozone mixing ratio 'Ozone mixing ratio' = { table2Version = 2 ; indicatorOfParameter = 154 ; } #Ground heat flux 'Ground heat flux' = { table2Version = 2 ; indicatorOfParameter = 155 ; } #Convective inhibition 'Convective inhibition' = { table2Version = 2 ; indicatorOfParameter = 156 ; } #Convective available potential energy 'Convective available potential energy' = { table2Version = 2 ; indicatorOfParameter = 157 ; } #Downward short-wave radiation flux 'Downward short-wave radiation flux' = { table2Version = 2 ; indicatorOfParameter = 204 ; } #Downward long-wave radiation flux 'Downward long-wave radiation flux' = { table2Version = 2 ; indicatorOfParameter = 205 ; } #Upward short-wave radiation flux 'Upward short-wave radiation flux' = { table2Version = 2 ; indicatorOfParameter = 211 ; } #Upward long-wave radiation flux 'Upward long-wave radiation flux' = { table2Version = 2 ; indicatorOfParameter = 212 ; } #Convective precipitation rate 'Convective precipitation rate' = { table2Version = 2 ; indicatorOfParameter = 214 ; } #Planetary boundary layer height 'Planetary boundary layer height' = { table2Version = 2 ; indicatorOfParameter = 221 ; } #5-wave geopotential height '5-wave geopotential height' = { table2Version = 2 ; indicatorOfParameter = 222 ; } #5-wave geopotential height anomaly '5-wave geopotential height anomaly' = { table2Version = 2 ; indicatorOfParameter = 230 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib1/localConcepts/kwbc/paramId.def0000644000004100000410000000561211732375622027035 0ustar www-datawww-data#Surface lifted index '260127' = { table2Version = 2 ; indicatorOfParameter = 131 ; } #Best (4-layer) lifted index '260128' = { table2Version = 2 ; indicatorOfParameter = 132 ; } #Vertical speed shear '260068' = { table2Version = 2 ; indicatorOfParameter = 136 ; } #Categorical rain '260029' = { table2Version = 2 ; indicatorOfParameter = 140 ; } #Categorical freezing rain '260030' = { table2Version = 2 ; indicatorOfParameter = 141 ; } #Categorical ice pellets '260031' = { table2Version = 2 ; indicatorOfParameter = 142 ; } #Categorical snow '260032' = { table2Version = 2 ; indicatorOfParameter = 143 ; } #Volumetric soil moisture content '260185' = { table2Version = 2 ; indicatorOfParameter = 144 ; } #Potential evaporation rate '260037' = { table2Version = 2 ; indicatorOfParameter = 145 ; } #Cloud work function '260111' = { table2Version = 2 ; indicatorOfParameter = 146 ; } #Zonal flux of gravity wave stress '260081' = { table2Version = 2 ; indicatorOfParameter = 147 ; } #Meridional flux of gravity wave stress '260082' = { table2Version = 2 ; indicatorOfParameter = 148 ; } #Colud water mixing ratio '22' = { table2Version = 2 ; indicatorOfParameter = 153 ; } #Ozone mixing ratio '260131' = { table2Version = 2 ; indicatorOfParameter = 154 ; } #Ground heat flux '260186' = { table2Version = 2 ; indicatorOfParameter = 155 ; } #Convective inhibition '228001' = { table2Version = 2 ; indicatorOfParameter = 156 ; } #Convective available potential energy '59' = { table2Version = 2 ; indicatorOfParameter = 157 ; } #Downward short-wave radiation flux '260087' = { table2Version = 2 ; indicatorOfParameter = 204 ; } #Downward long-wave radiation flux '260097' = { table2Version = 2 ; indicatorOfParameter = 205 ; } #Upward short-wave radiation flux '260088' = { table2Version = 2 ; indicatorOfParameter = 211 ; } #Upward long-wave radiation flux '260098' = { table2Version = 2 ; indicatorOfParameter = 212 ; } #Convective precipitation rate '260033' = { table2Version = 2 ; indicatorOfParameter = 214 ; } #Planetary boundary layer height '260083' = { table2Version = 2 ; indicatorOfParameter = 221 ; } #5-wave geopotential height '260080' = { table2Version = 2 ; indicatorOfParameter = 222 ; } #5-wave geopotential height anomaly '260084' = { table2Version = 2 ; indicatorOfParameter = 230 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib1/localConcepts/kwbc/shortName.def0000644000004100000410000000556111732375622027423 0ustar www-datawww-data#Surface lifted index 'lftx' = { table2Version = 2 ; indicatorOfParameter = 131 ; } #Best (4-layer) lifted index '4lftx' = { table2Version = 2 ; indicatorOfParameter = 132 ; } #Vertical speed shear 'vwsh' = { table2Version = 2 ; indicatorOfParameter = 136 ; } #Categorical rain 'crain' = { table2Version = 2 ; indicatorOfParameter = 140 ; } #Categorical freezing rain 'cfrzr' = { table2Version = 2 ; indicatorOfParameter = 141 ; } #Categorical ice pellets 'cicep' = { table2Version = 2 ; indicatorOfParameter = 142 ; } #Categorical snow 'csnow' = { table2Version = 2 ; indicatorOfParameter = 143 ; } #Volumetric soil moisture content 'soilw' = { table2Version = 2 ; indicatorOfParameter = 144 ; } #Potential evaporation rate 'pevpr' = { table2Version = 2 ; indicatorOfParameter = 145 ; } #Cloud work function 'cwork' = { table2Version = 2 ; indicatorOfParameter = 146 ; } #Zonal flux of gravity wave stress 'u-gwd' = { table2Version = 2 ; indicatorOfParameter = 147 ; } #Meridional flux of gravity wave stress 'v-gwd' = { table2Version = 2 ; indicatorOfParameter = 148 ; } #Cloud water mixing ratio 'clwmr' = { table2Version = 2 ; indicatorOfParameter = 153 ; } #Ozone mixing ratio 'o3mr' = { table2Version = 2 ; indicatorOfParameter = 154 ; } #Ground heat flux 'gflux' = { table2Version = 2 ; indicatorOfParameter = 155 ; } #Convective inhibition 'cin' = { table2Version = 2 ; indicatorOfParameter = 156 ; } #Convective available potential energy 'cape' = { table2Version = 2 ; indicatorOfParameter = 157 ; } #Downward short-wave radiation flux 'dswrf' = { table2Version = 2 ; indicatorOfParameter = 204 ; } #Downward long-wave radiation flux 'dlwrf' = { table2Version = 2 ; indicatorOfParameter = 205 ; } #Upward short-wave radiation flux 'uswrf' = { table2Version = 2 ; indicatorOfParameter = 211 ; } #Upward long-wave radiation flux 'ulwrf' = { table2Version = 2 ; indicatorOfParameter = 212 ; } #Convective precipitation rate 'cprat' = { table2Version = 2 ; indicatorOfParameter = 214 ; } #Planetary boundary layer height 'hpbl' = { table2Version = 2 ; indicatorOfParameter = 221 ; } #5-wave geopotential height '5wavh' = { table2Version = 2 ; indicatorOfParameter = 222 ; } #5-wave geopotential height anomaly '5wava' = { table2Version = 2 ; indicatorOfParameter = 230 ; } rb-grib-0.2.2/lib/numru/grib/definitions/grib1/localConcepts/kwbc/units.def0000644000004100000410000000571411732375622026625 0ustar www-datawww-data#Surface lifted index 'K' = { table2Version = 2 ; indicatorOfParameter = 131 ; } #Best (4-layer) lifted index 'K' = { table2Version = 2 ; indicatorOfParameter = 132 ; } #Vertical speed shear 's**-1' = { table2Version = 2 ; indicatorOfParameter = 136 ; } #Categorical rain '(Code table 4.222)' = { table2Version = 2 ; indicatorOfParameter = 140 ; } #Categorical freezing rain '(Code table 4.222)' = { table2Version = 2 ; indicatorOfParameter = 141 ; } #Categorical ice pellets '(Code table 4.222)' = { table2Version = 2 ; indicatorOfParameter = 142 ; } #Categorical snow '(Code table 4.222)' = { table2Version = 2 ; indicatorOfParameter = 143 ; } #Volumetric soil moisture content 'Proportion' = { table2Version = 2 ; indicatorOfParameter = 144 ; } #Potential evaporation rate 'W m**-2' = { table2Version = 2 ; indicatorOfParameter = 145 ; } #Cloud work function 'J kg**-1' = { table2Version = 2 ; indicatorOfParameter = 146 ; } #Zonal flux of gravity wave stress 'N m**-2' = { table2Version = 2 ; indicatorOfParameter = 147 ; } #Meridional flux of gravity wave stress 'N m**-2' = { table2Version = 2 ; indicatorOfParameter = 148 ; } #Cloud water mixing ratio 'kg kg**-1' = { table2Version = 2 ; indicatorOfParameter = 153 ; } #Ozone mixing ratio 'kg kg**-1' = { table2Version = 2 ; indicatorOfParameter = 154 ; } #Ground heat flux 'W m**-2' = { table2Version = 2 ; indicatorOfParameter = 155 ; } #Convective inhibition 'J kg**-1' = { table2Version = 2 ; indicatorOfParameter = 156 ; } #Convective available potential energy 'J kg**-1' = { table2Version = 2 ; indicatorOfParameter = 157 ; } #Downward short-wave radiation flux 'W m**-2' = { table2Version = 2 ; indicatorOfParameter = 204 ; } #Downward long-wave radiation flux 'W m**-2' = { table2Version = 2 ; indicatorOfParameter = 205 ; } #Upward short-wave radiation flux 'W m**-2' = { table2Version = 2 ; indicatorOfParameter = 211 ; } #Upward long-wave radiation flux 'W m**-2' = { table2Version = 2 ; indicatorOfParameter = 212 ; } #Convective precipitation rate 'kg m**-2 s**-1' = { table2Version = 2 ; indicatorOfParameter = 214 ; } #Planetary boundary layer height 'm' = { table2Version = 2 ; indicatorOfParameter = 221 ; } #5-wave geopotential height 'gpm' = { table2Version = 2 ; indicatorOfParameter = 222 ; } #5-wave geopotential height anomaly 'gpm' = { table2Version = 2 ; indicatorOfParameter = 230 ; } rb-grib-0.2.2/lib/numru/grib.rb0000644000004100000410000000023111732375622016257 0ustar www-datawww-datarequire "narray_miss" require "date" require "numru/grib/setenv.rb" require "numru/grib/version.rb" require "numru/grib.so" require "numru/grib/grib.rb"