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.
- data/.gitignore +4 -0
- data/BSDL +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -12
- data/README.rdoc +23 -0
- data/Rakefile +5 -0
- data/data/tp_ecmwf.grib +0 -0
- data/ext/grib.c +376 -68
- data/lib/numru/grib.rb +5 -1
- data/lib/numru/grib/definitions/grib1/localConcepts/kwbc/name.def +125 -0
- data/lib/numru/grib/definitions/grib1/localConcepts/kwbc/paramId.def +126 -0
- data/lib/numru/grib/definitions/grib1/localConcepts/kwbc/shortName.def +125 -0
- data/lib/numru/grib/definitions/grib1/localConcepts/kwbc/units.def +126 -0
- data/lib/numru/grib/definitions/grib2/localConcepts/rjtd/name.def +30 -0
- data/lib/numru/grib/definitions/grib2/localConcepts/rjtd/paramId.def +30 -0
- data/lib/numru/grib/definitions/grib2/localConcepts/rjtd/shortName.def +30 -0
- data/lib/numru/grib/definitions/grib2/localConcepts/rjtd/units.def +30 -0
- data/lib/numru/grib/grib.rb +132 -182
- data/lib/numru/grib/setenv.rb +12 -0
- data/lib/numru/grib/version.rb +1 -1
- data/rb-grib.gemspec +2 -1
- data/spec/grib_read_spec.rb +105 -76
- metadata +48 -7
data/.gitignore
CHANGED
data/BSDL
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 2011 Seiya Nishizawa and GFD Dennou Club. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
GFD Dennou Club.
|
1
|
+
rb-GRIB is copyrighted free software by Seiya Nishizawa <seiya@gfd-dennou.org>
|
2
|
+
and GFD Dennou Club.
|
3
3
|
You can redistribute it and/or modify it under either the terms of the
|
4
|
-
|
5
|
-
(http://www.ruby-lang.org/en/LICENSE.txt):
|
4
|
+
2-clause BSDL (see the file BSDL), or the conditions below:
|
6
5
|
|
7
6
|
1. You may make and give away verbatim copies of the source form of the
|
8
7
|
software without restriction, provided that you duplicate all of the
|
@@ -19,31 +18,33 @@ GPL, or the conditions below, which is idential to Ruby's license
|
|
19
18
|
b) use the modified software only within your corporation or
|
20
19
|
organization.
|
21
20
|
|
22
|
-
c)
|
23
|
-
|
21
|
+
c) give non-standard binaries non-standard names, with
|
22
|
+
instructions on where to get the original software distribution.
|
24
23
|
|
25
24
|
d) make other distribution arrangements with the author.
|
26
25
|
|
27
|
-
3. You may distribute the software in object code or
|
28
|
-
|
26
|
+
3. You may distribute the software in object code or binary form,
|
27
|
+
provided that you do at least ONE of the following:
|
29
28
|
|
30
|
-
a) distribute the
|
29
|
+
a) distribute the binaries and library files of the software,
|
31
30
|
together with instructions (in the manual page or equivalent)
|
32
31
|
on where to get the original distribution.
|
33
32
|
|
34
33
|
b) accompany the distribution with the machine-readable source of
|
35
34
|
the software.
|
36
35
|
|
37
|
-
c) give non-standard
|
36
|
+
c) give non-standard binaries non-standard names, with
|
38
37
|
instructions on where to get the original software distribution.
|
39
38
|
|
40
39
|
d) make other distribution arrangements with the author.
|
41
40
|
|
42
41
|
4. You may modify and include the part of the software into any other
|
43
42
|
software (possibly commercial). But some files in the distribution
|
44
|
-
are not written by the
|
43
|
+
are not written by the authors, so that they are not under these terms.
|
45
44
|
|
46
|
-
|
45
|
+
The data files in the "data" directory are provided by GRIB API
|
46
|
+
(http://www.ecmwf.int/products/data/software/grib_api.html)
|
47
|
+
under the GNU Lesser General Public License.
|
47
48
|
|
48
49
|
5. The scripts and library files supplied as input to or produced as
|
49
50
|
output from the software do not automatically fall under the
|
data/README.rdoc
CHANGED
@@ -2,16 +2,31 @@
|
|
2
2
|
|
3
3
|
rb-GRIB is a class library to handle GRIB file.
|
4
4
|
|
5
|
+
|
6
|
+
= rb-GRIB home-page
|
7
|
+
|
8
|
+
The URL of the rb-GRIB home-page is:
|
9
|
+
http://ruby.gfd-dennou.org/products/rb-grib/
|
10
|
+
|
11
|
+
|
5
12
|
= Requires
|
6
13
|
|
7
14
|
* Ruby (http://www.ruby-lang.org/)
|
8
15
|
* NArray (http://narray.rubyforge.org/index.html.en)
|
16
|
+
* NArrayMiss (http://ruby.gfd-dennou.org/products/narray_miss/)
|
9
17
|
* GRIB API (http://www.ecmwf.int/products/data/software/grib_api.html)
|
10
18
|
|
19
|
+
|
11
20
|
= Install
|
12
21
|
|
13
22
|
# gem install rb-grib
|
14
23
|
|
24
|
+
|
25
|
+
= Copying
|
26
|
+
|
27
|
+
See the file LICENSE.txt.
|
28
|
+
|
29
|
+
|
15
30
|
= Usage
|
16
31
|
|
17
32
|
To use this library, put the following in your script.
|
@@ -32,3 +47,11 @@ To use this library, put the following in your script.
|
|
32
47
|
ary = var.get # => NArray
|
33
48
|
end
|
34
49
|
grib.close
|
50
|
+
|
51
|
+
|
52
|
+
= The Author
|
53
|
+
|
54
|
+
Feel free to send comments and bug reports to the author.
|
55
|
+
The author's e-mail addess is
|
56
|
+
|
57
|
+
seiya@gfd-dennou.org
|
data/Rakefile
CHANGED
data/data/tp_ecmwf.grib
ADDED
Binary file
|
data/ext/grib.c
CHANGED
@@ -7,63 +7,264 @@
|
|
7
7
|
|
8
8
|
#define MAX_VALUE_LENGTH 1024
|
9
9
|
|
10
|
+
// error check
|
11
|
+
static void
|
12
|
+
check_error(int code)
|
13
|
+
{
|
14
|
+
if (code) rb_raise(rb_eRuntimeError, grib_get_error_message(code));
|
15
|
+
};
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
// flexible length array
|
21
|
+
#define BUF_SIZE 256
|
22
|
+
#define MAX_BUF_NUM 1000
|
23
|
+
typedef struct {
|
24
|
+
grib_handle ***buffer;
|
25
|
+
size_t size;
|
26
|
+
size_t len;
|
27
|
+
} msg_array;
|
28
|
+
static msg_array*
|
29
|
+
alloc_msg_array(void)
|
30
|
+
{
|
31
|
+
msg_array *ary = ALLOC(msg_array);
|
32
|
+
if (ary) {
|
33
|
+
ary->buffer = (grib_handle***) malloc(sizeof(grib_handle**)*MAX_BUF_NUM);
|
34
|
+
if (ary->buffer) {
|
35
|
+
ary->buffer[0] = (grib_handle**) malloc(sizeof(grib_handle*)*BUF_SIZE);
|
36
|
+
if (ary->buffer[0]) {
|
37
|
+
ary->size = BUF_SIZE;
|
38
|
+
ary->len = 0;
|
39
|
+
return ary;
|
40
|
+
}
|
41
|
+
free(ary->buffer);
|
42
|
+
}
|
43
|
+
free(ary);
|
44
|
+
}
|
45
|
+
return NULL;
|
46
|
+
}
|
47
|
+
static
|
48
|
+
void free_msg_array(msg_array *ary)
|
49
|
+
{
|
50
|
+
int i, j;
|
51
|
+
int num = ary->size/BUF_SIZE;
|
52
|
+
int len;
|
53
|
+
for (i=0; i<num; i++) {
|
54
|
+
len = i==num-1 ? ary->len%BUF_SIZE : BUF_SIZE;
|
55
|
+
for (j=0; j<len; j++) grib_handle_delete(ary->buffer[i][j]);
|
56
|
+
free(ary->buffer[i]);
|
57
|
+
}
|
58
|
+
free(ary->buffer);
|
59
|
+
free(ary);
|
60
|
+
}
|
61
|
+
static void
|
62
|
+
push_msg(msg_array *ary, grib_handle *handle)
|
63
|
+
{
|
64
|
+
int idx = ary->size/BUF_SIZE-1;
|
65
|
+
if (ary->len >= ary->size) {
|
66
|
+
idx += 1;
|
67
|
+
if (idx < MAX_BUF_NUM) {
|
68
|
+
ary->buffer[idx] = (grib_handle**)malloc(sizeof(grib_handle*)*BUF_SIZE);
|
69
|
+
if (ary->buffer[idx]) {
|
70
|
+
ary->size += BUF_SIZE;
|
71
|
+
} else {
|
72
|
+
rb_raise(rb_eRuntimeError, "cannot allocate memory");
|
73
|
+
}
|
74
|
+
} else {
|
75
|
+
rb_raise(rb_eRuntimeError, "cannot allocate memory");
|
76
|
+
}
|
77
|
+
}
|
78
|
+
ary->buffer[idx][ary->len%BUF_SIZE] = handle;
|
79
|
+
ary->len += 1;
|
80
|
+
}
|
81
|
+
static grib_handle*
|
82
|
+
get_msg(msg_array *ary, size_t index)
|
83
|
+
{
|
84
|
+
if (index < ary->len) {
|
85
|
+
return ary->buffer[index/BUF_SIZE][index%BUF_SIZE];
|
86
|
+
} else {
|
87
|
+
rb_raise(rb_eRuntimeError, "index exceed size of array");
|
88
|
+
}
|
89
|
+
return NULL;
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
// variable list
|
94
|
+
typedef struct var_list var_list;
|
95
|
+
struct var_list {
|
96
|
+
char *vname;
|
97
|
+
long ni;
|
98
|
+
long nj;
|
99
|
+
char *gtype;
|
100
|
+
long ltype_id;
|
101
|
+
char *ltype;
|
102
|
+
msg_array *ary;
|
103
|
+
var_list *next;
|
104
|
+
VALUE file;
|
105
|
+
};
|
106
|
+
static var_list*
|
107
|
+
var_list_alloc(VALUE file)
|
108
|
+
{
|
109
|
+
var_list *var = ALLOC(var_list);
|
110
|
+
if (var) {
|
111
|
+
var->ary = alloc_msg_array();
|
112
|
+
if (var->ary) {
|
113
|
+
var->vname = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH*2);
|
114
|
+
if (var->vname) {
|
115
|
+
var->gtype = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH);
|
116
|
+
if (var->gtype) {
|
117
|
+
var->ltype = (char*) malloc(sizeof(char)*MAX_VALUE_LENGTH);
|
118
|
+
if (var->ltype) {
|
119
|
+
var->next = NULL;
|
120
|
+
var->file = file;
|
121
|
+
return var;
|
122
|
+
}
|
123
|
+
free(var->gtype);
|
124
|
+
}
|
125
|
+
free(var->vname);
|
126
|
+
}
|
127
|
+
free_msg_array(var->ary);
|
128
|
+
}
|
129
|
+
free(var);
|
130
|
+
}
|
131
|
+
return NULL;
|
132
|
+
}
|
133
|
+
static void
|
134
|
+
var_list_free(var_list *var)
|
135
|
+
{
|
136
|
+
var_list *next;
|
137
|
+
while(var) {
|
138
|
+
free_msg_array(var->ary);
|
139
|
+
free(var->vname);
|
140
|
+
free(var->gtype);
|
141
|
+
free(var->ltype);
|
142
|
+
var->file = Qnil;
|
143
|
+
next = var->next;
|
144
|
+
free(var);
|
145
|
+
var = next;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
static void
|
149
|
+
push_msg_var(var_list **pvar, grib_handle *handle, VALUE file)
|
150
|
+
{
|
151
|
+
size_t len = MAX_VALUE_LENGTH;
|
152
|
+
char vname[MAX_VALUE_LENGTH];
|
153
|
+
bzero(vname, len);
|
154
|
+
if (grib_get_string(handle, "shortName", vname, &len) != GRIB_SUCCESS ||
|
155
|
+
strcmp("unknown", vname) == 0) {
|
156
|
+
long id;
|
157
|
+
if (grib_get_long(handle, "indicatorOfParameter", &id) == GRIB_SUCCESS ||
|
158
|
+
grib_get_long(handle, "parameterNumber", &id) == GRIB_SUCCESS) {
|
159
|
+
sprintf(vname, "id%ld", id);
|
160
|
+
} else {
|
161
|
+
printf("%s\n", vname);
|
162
|
+
rb_raise(rb_eRuntimeError, "cannot get variable name");
|
163
|
+
}
|
164
|
+
}
|
165
|
+
long ni, nj, ltype_id;
|
166
|
+
char gtype[MAX_VALUE_LENGTH];
|
167
|
+
len = MAX_VALUE_LENGTH;
|
168
|
+
if (grib_get_long(handle, "Ni", &ni) != GRIB_SUCCESS ||
|
169
|
+
grib_get_long(handle, "Nj", &nj) != GRIB_SUCCESS ||
|
170
|
+
grib_get_string(handle, "typeOfGrid", gtype, &len) != GRIB_SUCCESS ||
|
171
|
+
(grib_get_long(handle, "indicatorOfTypeOfLevel", <ype_id) != GRIB_SUCCESS && grib_get_long(handle, "typeOfFirstFixedSurface", <ype_id) != GRIB_SUCCESS)) {
|
172
|
+
rb_raise(rb_eRuntimeError, "connot identify grid type");
|
173
|
+
}
|
174
|
+
var_list *last = NULL;
|
175
|
+
var_list *var = pvar[0];
|
176
|
+
if (var) {
|
177
|
+
while (var) {
|
178
|
+
if (strcmp(var->vname, vname)==0 && var->ni == ni && var->nj == nj && strcmp(var->gtype,gtype)==0 && var->ltype_id==ltype_id) {
|
179
|
+
push_msg(var->ary, handle);
|
180
|
+
return;
|
181
|
+
}
|
182
|
+
last = var;
|
183
|
+
var = var->next;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
var_list *var_new = var_list_alloc(file);
|
187
|
+
if (var_new == NULL)
|
188
|
+
rb_raise(rb_eRuntimeError, "cannot allocate memory");
|
189
|
+
var_new->ni = ni;
|
190
|
+
var_new->nj = nj;
|
191
|
+
var_new->ltype_id = ltype_id;
|
192
|
+
strcpy(var_new->vname, vname);
|
193
|
+
strcpy(var_new->gtype, gtype);
|
194
|
+
len = MAX_VALUE_LENGTH;
|
195
|
+
check_error(grib_get_string(handle, "typeOfLevel", vname, &len));
|
196
|
+
strcpy(var_new->ltype, vname);
|
197
|
+
push_msg(var_new->ary, handle);
|
198
|
+
if (last)
|
199
|
+
last->next = var_new;
|
200
|
+
else
|
201
|
+
pvar[0] = var_new;
|
202
|
+
}
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
|
10
207
|
VALUE cGrib;
|
208
|
+
VALUE cVar;
|
11
209
|
VALUE cMessage;
|
12
210
|
|
13
211
|
typedef struct {
|
14
212
|
FILE *file;
|
15
213
|
char *fname;
|
16
|
-
|
17
|
-
int n;
|
214
|
+
var_list *var;
|
18
215
|
} rg_file;
|
19
|
-
|
216
|
+
typedef struct {
|
217
|
+
VALUE file;
|
218
|
+
var_list *var_list;
|
219
|
+
} rg_var;
|
20
220
|
typedef struct {
|
21
221
|
VALUE file;
|
22
222
|
grib_handle *handle;
|
23
223
|
} rg_message;
|
24
224
|
|
25
|
-
static void
|
26
|
-
check_error(int code)
|
27
|
-
{
|
28
|
-
if (code)
|
29
|
-
rb_raise(rb_eRuntimeError, grib_get_error_message(code));
|
30
|
-
};
|
31
|
-
|
32
225
|
|
33
226
|
static void
|
34
227
|
message_free(rg_message *message)
|
35
228
|
{
|
36
|
-
if (message)
|
37
|
-
free(message);
|
38
|
-
}
|
229
|
+
if (message) free(message);
|
39
230
|
}
|
40
231
|
static void
|
41
232
|
message_mark(rg_message *message)
|
42
233
|
{
|
43
|
-
if (message && message->file != Qnil)
|
44
|
-
rb_gc_mark(message->file);
|
234
|
+
if (message && message->file != Qnil) rb_gc_mark(message->file);
|
45
235
|
}
|
46
236
|
static VALUE
|
47
237
|
message_alloc(VALUE klass)
|
48
238
|
{
|
49
239
|
rg_message *message = ALLOC(rg_message);
|
50
240
|
message->file = Qnil;
|
51
|
-
message->handle = NULL;
|
52
241
|
return Data_Wrap_Struct(klass, message_mark, message_free, message);
|
53
242
|
}
|
54
|
-
|
243
|
+
static void
|
244
|
+
var_free(rg_var *var)
|
245
|
+
{
|
246
|
+
if (var) free(var);
|
247
|
+
}
|
248
|
+
static void
|
249
|
+
var_mark(rg_var *var)
|
250
|
+
{
|
251
|
+
if (var && var->file != Qnil) rb_gc_mark(var->file);
|
252
|
+
}
|
253
|
+
static VALUE
|
254
|
+
var_alloc(VALUE klass)
|
255
|
+
{
|
256
|
+
rg_var *var = ALLOC(rg_var);
|
257
|
+
var->file = Qnil;
|
258
|
+
return Data_Wrap_Struct(klass, var_mark, var_free, var);
|
259
|
+
}
|
55
260
|
static void
|
56
261
|
file_close(rg_file *gfile)
|
57
262
|
{
|
58
|
-
int i;
|
59
263
|
if (gfile) {
|
60
|
-
if (gfile->
|
61
|
-
|
62
|
-
|
63
|
-
free(gfile->handles);
|
64
|
-
gfile->handles = NULL;
|
264
|
+
if (gfile->var) {
|
265
|
+
var_list_free(gfile->var);
|
266
|
+
gfile->var = NULL;
|
65
267
|
}
|
66
|
-
gfile->n = 0;
|
67
268
|
if (gfile->file) {
|
68
269
|
fclose(gfile->file);
|
69
270
|
gfile->file = NULL;
|
@@ -88,23 +289,10 @@ file_alloc(VALUE klass)
|
|
88
289
|
rg_file *gfile = ALLOC(rg_file);
|
89
290
|
gfile->file = NULL;
|
90
291
|
gfile->fname = NULL;
|
91
|
-
gfile->
|
92
|
-
gfile->n = 0;
|
292
|
+
gfile->var = NULL;
|
93
293
|
return Data_Wrap_Struct(klass, 0, file_free, gfile);
|
94
294
|
}
|
95
295
|
|
96
|
-
/*
|
97
|
-
NumRu::Grib.open(filename [, mode]) -> NumRu::Grib::File
|
98
|
-
*/
|
99
|
-
/*
|
100
|
-
static VALUE
|
101
|
-
rg_open(int argc, VALUE *argv, VALUE self)
|
102
|
-
{
|
103
|
-
VALUE rgfile = file_alloc(self);
|
104
|
-
return rg_file_initialize(argc, argv, rgfile);
|
105
|
-
}
|
106
|
-
*/
|
107
|
-
|
108
296
|
/*
|
109
297
|
NumRu::Grib.multi=(flag) -> True/False
|
110
298
|
*/
|
@@ -145,29 +333,71 @@ rg_file_initialize(int argc, VALUE *argv, VALUE self)
|
|
145
333
|
gfile->fname = ALLOC_N(char, strlen(fname)+1);
|
146
334
|
strcpy(gfile->fname, fname);
|
147
335
|
|
148
|
-
int n = 0;
|
149
336
|
int error;
|
150
337
|
grib_handle *handle;
|
338
|
+
var_list *var = NULL;
|
151
339
|
while ((handle = grib_handle_new_from_file(0, file, &error))) {
|
152
340
|
check_error(error);
|
153
341
|
if (handle == NULL)
|
154
342
|
rb_raise(rb_eRuntimeError, "unable to create handle in %s", fname);
|
155
|
-
|
156
|
-
n++;
|
343
|
+
push_msg_var(&var, handle, self);
|
157
344
|
}
|
158
|
-
|
159
|
-
|
345
|
+
gfile->var = var;
|
346
|
+
var_list *var2;
|
347
|
+
const char *vname;
|
348
|
+
char buf[MAX_VALUE_LENGTH];
|
349
|
+
int first_ltype, first_gtype;
|
160
350
|
int i;
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
351
|
+
while (var) {
|
352
|
+
vname = var->vname;
|
353
|
+
var2 = var->next;
|
354
|
+
i = 0;
|
355
|
+
first_ltype = 1;
|
356
|
+
first_gtype = 1;
|
357
|
+
while (var2) {
|
358
|
+
if (strcmp(var2->vname, vname) == 0) {
|
359
|
+
if (var->ltype_id != var2->ltype_id) {
|
360
|
+
if (first_ltype) {
|
361
|
+
if (strcmp(var->ltype,"isobaricInhPa") != 0 && strcmp(var->ltype,"pl") !=0) {
|
362
|
+
if (strcmp(var->ltype, "unknown")==0)
|
363
|
+
sprintf(buf, "%s_level%ld", var->vname, var->ltype_id);
|
364
|
+
else
|
365
|
+
sprintf(buf, "%s_%s", var->vname, var->ltype);
|
366
|
+
strcpy(var->vname, buf);
|
367
|
+
}
|
368
|
+
first_ltype = 0;
|
369
|
+
}
|
370
|
+
if (strcmp(var2->ltype,"isobaricInhPa") != 0 && strcmp(var2->ltype,"pl") != 0) {
|
371
|
+
if (strcmp(var2->ltype, "unknown")==0)
|
372
|
+
sprintf(buf, "%s_level%ld", var2->vname, var2->ltype_id);
|
373
|
+
else
|
374
|
+
sprintf(buf, "%s_%s", var2->vname, var2->ltype);
|
375
|
+
strcpy(var2->vname, buf);
|
376
|
+
}
|
377
|
+
} else if (strcmp(var->gtype, var2->gtype) != 0) {
|
378
|
+
if (first_gtype) {
|
379
|
+
sprintf(buf, "%s_%s", var->vname, var->gtype);
|
380
|
+
strcpy(var->vname, buf);
|
381
|
+
first_gtype = 0;
|
382
|
+
}
|
383
|
+
sprintf(buf, "%s_%s", var2->vname, var2->gtype);
|
384
|
+
strcpy(var2->vname, buf);
|
385
|
+
} else {
|
386
|
+
if (i==0) {
|
387
|
+
sprintf(buf, "%s_%d", var->vname, i);
|
388
|
+
strcpy(var->vname, buf);
|
389
|
+
i += 1;
|
390
|
+
}
|
391
|
+
sprintf(buf, "%s_%d", var2->vname, i);
|
392
|
+
strcpy(var2->vname, buf);
|
393
|
+
i += 1;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
var2 = var2->next;
|
397
|
+
}
|
398
|
+
var = var->next;
|
168
399
|
}
|
169
|
-
|
170
|
-
gfile->handles = handles;
|
400
|
+
|
171
401
|
return self;
|
172
402
|
}
|
173
403
|
/*
|
@@ -183,36 +413,104 @@ rg_file_close(VALUE self)
|
|
183
413
|
}
|
184
414
|
|
185
415
|
/*
|
186
|
-
NumRu::Grib#
|
416
|
+
NumRu::Grib#path() -> String
|
187
417
|
*/
|
188
418
|
static VALUE
|
189
|
-
|
419
|
+
rg_file_path(VALUE self)
|
190
420
|
{
|
191
421
|
rg_file *gfile;
|
192
422
|
Data_Get_Struct(self, rg_file, gfile);
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
423
|
+
return rb_str_new2(gfile->fname);
|
424
|
+
}
|
425
|
+
|
426
|
+
/*
|
427
|
+
NumRu::Grib#var_names() -> Array
|
428
|
+
*/
|
429
|
+
static VALUE
|
430
|
+
rg_file_var_names(VALUE self)
|
431
|
+
{
|
432
|
+
rg_file *gfile;
|
433
|
+
Data_Get_Struct(self, rg_file, gfile);
|
434
|
+
VALUE ary = rb_ary_new();
|
435
|
+
var_list *var = gfile->var;
|
436
|
+
while (var) {
|
437
|
+
rb_ary_push(ary, rb_str_new2(var->vname));
|
438
|
+
var = var->next;
|
203
439
|
}
|
204
440
|
return ary;
|
205
441
|
}
|
206
442
|
|
443
|
+
static VALUE id_init;
|
207
444
|
/*
|
208
|
-
NumRu::Grib#
|
445
|
+
NumRu::Grib#var(String) -> NumRu::GribVar
|
209
446
|
*/
|
210
447
|
static VALUE
|
211
|
-
|
448
|
+
rg_file_var(VALUE self, VALUE rvname)
|
212
449
|
{
|
450
|
+
char *vname = StringValueCStr(rvname);
|
213
451
|
rg_file *gfile;
|
214
452
|
Data_Get_Struct(self, rg_file, gfile);
|
215
|
-
|
453
|
+
var_list *var_list = gfile->var;
|
454
|
+
while (var_list) {
|
455
|
+
if (strcmp(var_list->vname, vname) == 0) {
|
456
|
+
VALUE rvar = var_alloc(cVar);
|
457
|
+
rg_var *var;
|
458
|
+
Data_Get_Struct(rvar, rg_var, var);
|
459
|
+
var->file = self;
|
460
|
+
var->var_list = var_list;
|
461
|
+
rb_funcall(rvar, id_init, 0);
|
462
|
+
return rvar;
|
463
|
+
}
|
464
|
+
var_list = var_list->next;
|
465
|
+
}
|
466
|
+
rb_raise(rb_eArgError, "cannot find variable: %s", vname);
|
467
|
+
}
|
468
|
+
|
469
|
+
/*
|
470
|
+
NumRu::GribVar#file() -> NumRu::Grib
|
471
|
+
*/
|
472
|
+
static VALUE
|
473
|
+
rg_var_file(VALUE self)
|
474
|
+
{
|
475
|
+
rg_var *var;
|
476
|
+
Data_Get_Struct(self, rg_var, var);
|
477
|
+
return var->file;
|
478
|
+
}
|
479
|
+
|
480
|
+
/*
|
481
|
+
NumRu::GribVar#name() -> String
|
482
|
+
*/
|
483
|
+
static VALUE
|
484
|
+
rg_var_name(VALUE self)
|
485
|
+
{
|
486
|
+
rg_var *var;
|
487
|
+
Data_Get_Struct(self, rg_var, var);
|
488
|
+
return rb_str_new2(var->var_list->vname);
|
489
|
+
}
|
490
|
+
|
491
|
+
/*
|
492
|
+
NumRu::GribVar#get_messages() -> Array
|
493
|
+
*/
|
494
|
+
static VALUE
|
495
|
+
rg_var_get_messages(VALUE self)
|
496
|
+
{
|
497
|
+
rg_var *var;
|
498
|
+
Data_Get_Struct(self, rg_var, var);
|
499
|
+
var_list *var_list = var->var_list;
|
500
|
+
size_t len = var_list->ary->len;
|
501
|
+
VALUE ary = rb_ary_new2(len);
|
502
|
+
rg_message *message;
|
503
|
+
VALUE rmessage;
|
504
|
+
int i;
|
505
|
+
for (i=0; i<len; i++) {
|
506
|
+
rmessage = message_alloc(cMessage);
|
507
|
+
Data_Get_Struct(rmessage, rg_message, message);
|
508
|
+
message->file = self;
|
509
|
+
message->handle = get_msg(var_list->ary, i);
|
510
|
+
rb_ary_store(ary, i, rmessage);
|
511
|
+
}
|
512
|
+
return ary;
|
513
|
+
|
216
514
|
}
|
217
515
|
|
218
516
|
/*
|
@@ -396,8 +694,11 @@ void Init_grib()
|
|
396
694
|
{
|
397
695
|
rb_require("narray");
|
398
696
|
|
697
|
+
id_init = rb_intern("init");
|
698
|
+
|
399
699
|
VALUE mNumRu = rb_define_module("NumRu");
|
400
700
|
cGrib = rb_define_class_under(mNumRu, "Grib", rb_cObject);
|
701
|
+
cVar = rb_define_class_under(mNumRu, "GribVar", rb_cObject);
|
401
702
|
cMessage = rb_define_class_under(mNumRu, "GribMessage", rb_cObject);
|
402
703
|
|
403
704
|
grib_multi_support_on(0);
|
@@ -408,8 +709,15 @@ void Init_grib()
|
|
408
709
|
rb_define_alloc_func(cGrib, file_alloc);
|
409
710
|
rb_define_method(cGrib, "initialize", rg_file_initialize, -1);
|
410
711
|
rb_define_method(cGrib, "close", rg_file_close, 0);
|
411
|
-
rb_define_method(cGrib, "get_messages", rg_file_get_messages, 0);
|
412
712
|
rb_define_method(cGrib, "path", rg_file_path, 0);
|
713
|
+
rb_define_method(cGrib, "var_names", rg_file_var_names, 0);
|
714
|
+
rb_define_method(cGrib, "var", rg_file_var, 1);
|
715
|
+
|
716
|
+
rb_define_alloc_func(cVar, var_alloc);
|
717
|
+
rb_define_method(cVar, "file", rg_var_file, 0);
|
718
|
+
rb_define_method(cVar, "name", rg_var_name, 0);
|
719
|
+
rb_define_method(cVar, "get_messages", rg_var_get_messages, 0);
|
720
|
+
|
413
721
|
|
414
722
|
rb_define_alloc_func(cMessage, message_alloc);
|
415
723
|
rb_define_method(cMessage, "initialize", rg_message_initialize, 1);
|