New upstream version 0.7.2
Youhei SASAKI
7 years ago
0 | Tue Jan 27 2015 T Horinouchi | |
1 | * ruby-netcdf-0.7.1 released (relase tag: ruby-netcdf-0_7_1) | |
2 | Tue Jan 27 2015 T Horinouchi | |
3 | * doc/ updated | |
4 | * demo/demo5-netcdf4.rb: created | |
5 | * netcdfraw.c: | |
6 | * added new NetCDF-4 methods: | |
7 | * NetCDFVar::deflate : to set compression | |
8 | * NetCDFVar::deflate_params : returns current values of | |
9 | compression parameters | |
10 | * NetCDFVar::endian= : set (change) the endian | |
11 | * NetCDFVar::endian : returns the current endian setting | |
12 | * added new constants: NC_ENDIAN_NATIVE (=0), | |
13 | NC_ENDIAN_LITTLE (=1), NC_ENDIAN_BIG (=2) | |
14 | * updated the safe-level condition, which was missed in the | |
15 | change on Jan 22. | |
16 | Fri Jan 23 2015 T Horinouchi | |
17 | * doc/ updated | |
18 | Thu Jan 22 2015 T Horinouchi | |
19 | * ruby-netcdf-0.7.0 released (relase tag: ruby-netcdf-0_7_0) | |
20 | Thu Jan 22 2015 T Horinouchi | |
21 | * netcdfraw.c: | |
22 | * revised based on the patch posted by seiya with | |
23 | [dennou-ruby:003705] but adopted the typedef in the latest | |
24 | narray-bigmem (namely, used na_shape_t). | |
25 | * changed rb_secure(4) to rb_secure(3), since security | |
26 | level 4 is abolished in ruby 2. | |
27 | * further type update to na_shape_t (not covered | |
28 | by the patch) | |
29 | * deleted the unused variable nc_tlen in many methods. | |
30 | * lib/netcdf.rb: revised along the patch [dennou-ruby:003705]. | |
31 | * extconf.rb: supported to configure gem-installed narray | |
32 | Mon Sep 8 2014 T Horinouchi | |
33 | * lib/netcdf.rb: Tentative treatment of the very slow netcdf-4's | |
34 | strided reading. | |
35 | Sat Sep 6 2014 T Horinouchi | |
36 | * netcdfraw.c: Added constants such as NC_NETCDF4; | |
37 | This enables one to individually specify the creation format by | |
38 | using the low level interface NetCDF.nc_create | |
39 | * lib/netcdf.rb: Supported the "default" file creation format | |
40 | by adding NetCDF.creation_format= and NetCDF.creation_format. | |
41 | * lib/netcdf.rb: Refactoring of NetCDF#simple_get. | |
42 | Sat Sep 6 2014 T Horinouchi | |
43 | * extconf.rb | |
44 | * introduced the macro NCVER | |
45 | * changed to give a higer priority to NetCDF 4; | |
46 | * added $vendorarchdir to dir_config | |
47 | * netcdfraw.c: Added the class method NetCDF.libvers (<- nc_inq_libvers) | |
48 | * lib/netcdf.rb: Added the class constant NCVERSION (<- NetCDF.libvers) | |
49 | Mon Aug 25 2014 T Horinouchi | |
50 | * netcdfraw.c: to avoid a compile error when -Werror=format-security | |
51 | Sun Feb 19 2011 T Horinouchi | |
52 | * ruby-netcdf-0.6.6 released (relase tag: ruby-netcdf-0_6_6) | |
53 | * lib/netcdf.rb: method pack: debug of enbug made | |
54 | when 1.1 -> 1.2 (cvs tag) commited in Jan 2010. | |
55 | * netcdfraw.c: Added macro NC_RAISE2. Enhanced error | |
56 | messaging in NetCDF_open and NetCDF_create to show file name. | |
57 | ||
58 | Thu Feb 17 2011 T Horinouchi | |
59 | * ruby-netcdf-0.6.5 released (relase tag: ruby-netcdf-0_6_5) | |
60 | Thu Feb 17 2011 T Horinouchi | |
61 | * extconf.rb: Debug to have the --disable-opendap option really work | |
62 | Sat Feb 12 2011 T Horinouchi | |
63 | * ruby-netcdf-0.6.5 preview release. | |
64 | Thu Dec 23 2010 T Koshiro | |
65 | * test/aref_aset.rb : updated for Ruby 1.9.2 | |
66 | * lib/netcdf.rb: NetCDF.clean_tmpfile : lambda -> proc | |
67 | * verified that all test programs work fine with Ruby 1.9.2. | |
68 | ||
69 | Tue Dec 14 2010 T Koshiro | |
70 | * netcdfraw.c : nctype2natype : char* -> const char* | |
71 | * test/aref_aset.rb, test/factor_offset.rb : bug fix. | |
72 | ||
73 | Mon Dec 13 2010 T Koshiro | |
74 | * netcdfraw.c : patch for Ruby 1.9.2 | |
75 | - by S Kouketsu (dennou-ruby:003191) | |
76 | - by T Koshiro (dennou-ruby:003226) | |
77 | ||
78 | Mon Mar 15 2010 T Horinouchi | |
79 | * ruby-netcdf-0.6.4 released (relase tag: ruby-netcdf-0_6_4) | |
80 | ||
81 | Thu Jan 14 2010 T Horinouchi < T Koshiro | |
82 | * netcdfraw.c : patch for Ruby 1.9.1 (dennou-ruby:003138) | |
83 | * extconf.rb : patch for NetCDF-4.1-beta2 (dcdvlop Nov 20, 2009) | |
84 | ||
85 | Fri Aug 15 2008 T Horinouchi | |
86 | * lib/netcdf_miss.rb: in __interpret_missing_params, | |
87 | changed just to warn, not to raise an exception, | |
88 | if the missing value or fill value is within the | |
89 | valid range (warning can be suppressed by $VERBOSE = nil) | |
90 | Thu Jul 17 2008 T Horinouchi | |
91 | * lib/netcdf.rb: NetCDFVar's private method pack : to take | |
92 | round if the type of self is integer. | |
93 | * lib/netcdf_miss.rb: debug in the handling of missing data | |
94 | specification using the external data type. | |
95 | Wed Jul 16 2008 T Horinouchi < M Otsuka | |
96 | * netcdfraw.c : patch for Ruby 1.9 | |
97 | Tue Dec 25 2007 T Horinouchi | |
98 | * ruby-netcdf-0.6.3 released | |
99 | * netcdfra.c : (kind of) bugfix. (default attribute type for | |
100 | Fixnum and Bignum was changed from NA_SINT to NA_LINT). | |
101 | * lib/netcdf_miss.rb: improved to judge missing_value validity | |
102 | considering its typecode. | |
103 | Thu Jun 30 2005 | |
104 | * netcdf.rb: NetCDFVar#[] : debug for Array/NArray indices | |
105 | Thu Jun 23 2005 T Horinouchi < S Koshiro | |
106 | * ruby-netcdf-0.6.2 re-released (I am really sorry about that) | |
107 | * extconf.rb: updated to configure the prefix for DODS (useful if | |
108 | the DODS is installed in a non-standard path) | |
109 | Wed Jun 22 2005 T Horinouchi | |
110 | * ruby-netcdf-0.6.2 released | |
111 | * extconf.rb: updated to support opendap 3.5 | |
112 | Fri May 13 2005 T Horinouchi | |
113 | * ruby-netcdf-0.6.1 released | |
114 | Mon Apr 11 2005 Takeshi Horinouchi | |
115 | * netcdfraw.c: changed global variables such as mNumRu to file locale. | |
116 | Tue Mar 15 2005 Takeshi Horinouchi | |
117 | * netcdfraw.c: debug: changed the type of c_stride from size_t to | |
118 | ptrdiff_t. Removed unsuned variables. | |
119 | Mon Mar 14 2005 Takeshi Horinouchi | |
120 | * ruby-netcdf-0.6.0 released | |
121 | * netcdfraw.c: NetCDF_get_var*_*: debug for rank-zero scalar | |
122 | NetCDFVar. It used to SEGV. | |
123 | NetCDF_get_var_*, which reads the whole variable, | |
124 | is modified to return in a NArray of shape==[1]. | |
125 | On the other hand, subset reading by NetCDF_get_var[s1]_* | |
126 | is prohibited for rank-zero scalars by raising an exception. | |
127 | * lib/netcdf.rb: minor modification in [], to support its call | |
128 | without arguments of a rank-zero scalar. | |
129 | * netcdfraw.c: debug: changed size_t to int when NArray functions | |
130 | are called (for 64-bit machines). | |
131 | * extconf.rb: minor change in opendap configuration. | |
132 | Thu Mar 10 2005 Takeshi Horinouchi | |
133 | * extconf.rb: to link OPeNDAP/DODS-enabled version of NetCDF | |
134 | if available and if --disable-opendap is not specified. | |
135 | * lib/netcdf.rb: created pack and unpack by separating from | |
136 | scaled_put and scaled_get, respectvely. Changed type to | |
137 | unpack in to follow the coerce mechanism, so the upacked | |
138 | type depend on the type of scale_factor and add_offset. | |
139 | Renamed NetCDFVar.scaled_get_type[=] to NetCDFVar.unpack_type[=]. | |
140 | * lib/netcdf_miss.rb: revised [put|get]_with_miss_and_scaling: | |
141 | Now, missing data handling using valid_* / missing_value is applied | |
142 | basically to packed data, which is consistent with most | |
143 | conventions. However, it is applied to unpacked data | |
144 | if and only if the type of valid_* / missing_value is not the same as | |
145 | the packed data and is the samed as the unpacked data. | |
146 | * doc/ Updated in response to the modification. | |
147 | Mon Jun 7 2004 Takeshi Horinouchi | |
148 | * ruby-netcdf-0.5.5 released | |
149 | Wed Apr 28 2004 Takeshi Horinouchi < S. Nishizawa | |
150 | * lib/netcdf.rb: minor debug in [](l.662) and []= (l.733 & l.736) | |
151 | to avoid error with NArrayMiss. | |
152 | Mon Mar 8 2004 Takeshi Horinouchi | |
153 | * ruby-netcdf-0.5.4 released | |
154 | * lib/netcdf.rb: created NetCDFVar.scaled_get_type= and | |
155 | NetCDFVar.scaled_get_type | |
156 | Mon Feb 23 2004 Takeshi Horinouchi | |
157 | * lib/netcdf_miss.rb: debug in __interpret_missing_params | |
158 | Tue Oct 28 2003 Takeshi Horinouchi | |
159 | * lib/netcdf.rb: support empty [], []=. Debug in []=. | |
160 | Fri Oct 2 2003 Takeshi Horinouchi | |
161 | * ruby-netcdf-0.5.3 released | |
162 | * lib/netcdf.rb: (by S Nishizawa) enhanced NetCDF#[]= to support | |
163 | array indices. | |
164 | * lib/netcdf.rb: supported the rubber dimension (=false) in | |
165 | NetCDF#[] and NetCDF#[]=. | |
166 | * doc/*rd: updated for NetCDF#[] and NetCDF#[]= | |
167 | * INSTALL: updated | |
168 | Thu Oct 2 2003 Takeshi Horinouchi < S Nishizawa | |
169 | * lib/netcdf.rb: enhanced NetCDF#[] to support array indices. | |
170 | Tue Sep 23 2003 Takeshi Horinouchi | |
171 | * extconf.rb: debug for windows (by T Koshiro) | |
172 | * lib/netcdf_miss.rb: debug get_with_miss_* | |
173 | Wed Aug 27 2003 Takeshi Horinouchi | |
174 | * ruby-netcdf-0.5.2 released | |
175 | * Verified that all test programs work fine with Ruby 1.8.0. | |
176 | * netcdfraw.c: functions NetCDF_dim, NetCDF_var (methods | |
177 | NetCDF#dim, NetCDF#var). Changed behavior back to return nil | |
178 | if not found (by name), as opposed to the change on Feb 3 2003. | |
179 | Debug NetCDF_att_rename (NetCDFAtt#name=). | |
180 | Init_netcdfraw: No longer asks whether NumRu has been | |
181 | defined -- ok for Ruby 1.6.5 or so or later | |
182 | * doc/Ref_man.rd,doc/Ref_man_jp.rd: updated for the changes above | |
183 | * test/test.rb updated for the debug of NetCDFAtt#name=. | |
184 | * lib/netcdf.rb: editted NetCDF#vars and NetCDF#dims not to change | |
185 | the behavior despite the change above. Corrected exception types | |
186 | to raise where needed. | |
187 | Tue Aug 19 2003 Takeshi Horinouchi | |
188 | * demo/demo4-copy.rb: created | |
189 | Tue Aug 12 2003 Takeshi Horinouchi | |
190 | * ruby-netcdf-0.5.1 released | |
191 | * extconf.rb: do not edit "install:" anymore (for Ruby 1.8; works | |
192 | with 1.6 too.) / Debug | |
193 | * doc/Ref_man.rd,doc/Ref_man_jp.rd: corrected a few typos. | |
194 | ||
195 | Tue Aug 12 2003 Takeshi Horinouchi | |
196 | * ruby-netcdf-0.5.0 released | |
197 | * lib/netcdf_miss.rb: created. handles data missing by NArrayMiss. | |
198 | * doc/Ref_man.rd,doc/Ref_man_jp.rd: updated. | |
199 | ||
200 | Mon Aug 11 2003 Takeshi Horinouchi | |
201 | * extconf.rb: modification to cover Cygwin | |
202 | * netcdfraw.c: extern -> EXTERN | |
203 | * lib/netcdf.rb: renamed get|put as simple_(get|put) and | |
204 | made get|put aliased to them. Changed scaled_(get|put) | |
205 | to depend on simple_(put|get). This is to allow the user | |
206 | to redefine get|put, if he/she likes, as: | |
207 | alias get scaled_get | |
208 | alias put scaled_put | |
209 | Or (by using singleton methods) | |
210 | def a_ncvar.get(*arg) | |
211 | scaled_get(*arg) | |
212 | end | |
213 | def a_ncvar.put(*arg) | |
214 | scaled_put(*arg) | |
215 | end | |
216 | Now these do not cause recurrence. By doing so, one can | |
217 | also change the behavior of [] and []=. | |
218 | ||
219 | Sat Mar 24 2003 Takeshi Horinouchi | |
220 | * ruby-netcdf-0.4.0 released | |
221 | Sat Mar 22 2003 Takeshi Horinouchi | |
222 | * lib/netcdf.rb: NetCDFVar#[]: behavior changed -- to eliminate the | |
223 | dimensions designated by Integer's (for better agreement with | |
224 | NArray#[]) | |
225 | * doc/: correct the description of the IO mode for NetCDF.open | |
226 | Fri Mar 21 2003 Takeshi Horinouchi | |
227 | * ruby-netcdf-0.3.9 released | |
228 | Wed Mar 19 2003 Takeshi Horinouchi | |
229 | * netcdfraw.c: changed return values of NetCDF#redef and NetCDF#enddef | |
230 | (NetCDF_redef, NetCDF_enddef) --- return true if succesful and | |
231 | nil if not (the latter means that the file is already in | |
232 | define mode for redef and that it is already in the data mode | |
233 | for enddef). Previously, these methods always retuned nil. | |
234 | * doc/: updated | |
235 | * lib/netcdf.rb: DEBUG [] and []= : treatment of the end of ranges. | |
236 | Tue Mar 18 2003 Takeshi Horinouchi | |
237 | * netcdfraw.c: added NetCDF#define_mode? | |
238 | (NetCDF_whether_in_define_mode) | |
239 | Mon Mar 17 2003 Takeshi Horinouchi | |
240 | * ruby-netcdf-0.3.8 released | |
241 | * netcdfraw.c: deleted function NetCDF_put_var1_long, which was | |
242 | unnecessary (not called by anything). | |
243 | * netcdfraw.c: added methods NetCDFVar#typcode, NetCDFAtt#typcode | |
244 | (functions NetCDF_var_typecode, NetCDF_att_typecode) | |
245 | * netcdfraw.c: NetCDFVar#def_var(NetCDF_def_var) functionarity enhanced | |
246 | to accept NArray's typcodes to specifiy a variable type (vartye). | |
247 | * netcdfraw.c:put_var_*(NetCDF_put_var_*),put_vars_*(NetCDF_put_vars_*) | |
248 | functionality enhanced to accept scalar values to set uniform values | |
249 | * lib/netcdf.rb alias rank ndims (in NetCDFVar) | |
250 | * doc/Ref_man* updated accordingly | |
251 | Fri Mar 14 2003 Takeshi Horinouchi | |
252 | * ruby-netcdf-0.3.7 released | |
253 | Mon Feb 5 2003 Takeshi Horinouchi | |
254 | * doc/Ref_man.rd,doc/Ref_man_jp.rd update (added [] and []= methods) | |
255 | Mon Feb 3 2003 Takeshi Horinouchi | |
256 | * netcdf.rb: added NetCDF#dims, NetCDF#vars | |
257 | * netcdfraw.f: functions NetCDF_dim, NetCDF_var (methods | |
258 | NetCDF#dim, NetCDF#var). Changed behavior to raise exception | |
259 | if not found (by name). | |
260 | Thu Jan 30 2003 Takeshi Horinouchi | |
261 | * ruby-netcdf-0.3.6 released | |
262 | * netcdfraw.c: debug NetCDF_free and NetCDF_close not to close | |
263 | a file that has already been closed | |
264 | * netcdfraw.c: debug nc_mark_obj -- incorrect typing (though in | |
265 | many cases innocuous) | |
266 | * demo/: deleted *_withAdvancedDCL.rb (obsolete) | |
267 | ||
268 | Tue Jun 11 2002 Takeshi Horinouchi | |
269 | * ruby-netcdf-0.3.5 released | |
270 | * netcdfraw.rb: eliminated references to char *na_typestring[] | |
271 | (to make the source compilable with narray-0.5.6p2) | |
272 | * lib/netcdf.rb: eliminated uri methods: this is for a future | |
273 | incorpolation of DODS | |
274 | * demo/demo[23]*:written to use RubyDCL directly instead of AdvancedDCL | |
275 | ||
276 | Tue Feb 26 2002 Takeshi Horinouchi | |
277 | * ruby-netcdf-0.3.4 released | |
278 | ||
279 | Sun Feb 24 2002 Takeshi Horinouchi | |
280 | * lib/netcdf.rb: NetCDF#open minor debug | |
281 | ||
282 | Thu Dec 27 2001 Takeshi Horinouchi | |
283 | * extconf.rb: corrected an error message | |
284 | ||
285 | Thu Dec 26 2001 Takeshi Horinouchi | |
286 | * ruby-netcdf-0.3.3 released | |
287 | * lib/netcdf.rb: changes are made to get around a bug in NArray. | |
288 | Should be re-changed to the original if the bug is fixed. | |
289 | (The changed pars are marked by "TEMPORARY CHANGE 2001/12/27" in | |
290 | the source code) | |
291 | * netcdfraw.c: debug NetCDF_get_vars_sint | |
292 | * doc/Ref_man*rd: added the usage section. | |
293 | ||
294 | Thu Dec 26 2001 Takeshi Horinouchi | |
295 | * ruby-netcdf-0.3.2 released | |
296 | * doc/Ref_man*rd: added a "Data Type" section. Plus, some updates | |
297 | * lib/netcdf.rb: added NetCDF#scaled_put and NetCDF#scaled_get | |
298 | * netcdfraw.c,lib/netcdf.rb: added methods to treat the "char" type | |
299 | ||
300 | Thu Dec 26 2001 Takeshi Horinouchi | |
301 | * ruby-netcdf-0.3.1 released | |
302 | * doc/Ref_man*rd: updated | |
303 | * lib/netcdf/rb: added NetCDF#def_var_with_dim | |
304 | * netcdfraw.c: NetCDF*_eql: debug / do not redefine eql?, since the | |
305 | hash method is not refefined | |
306 | * lib/netcdf/rb: added NetCDFDim#length_ul0 | |
307 | * netcdfraw.c: NetCDF#close: error will not be raised on NetcdfBadid | |
308 | * lib/netcdf/rb: added NetCDFVar#shape_current, NetCDFVar#shape_ul0 | |
309 | * lib/netcdf/rb: added NetCDF.create_tmp -- temporary file | |
310 | * lib/netcdf/rb: NetCDFVar#uri returns path+'?var='+name instead | |
311 | of path+'?'+name | |
312 | ||
313 | Thu Dec 23 2001 Takeshi Horinouchi | |
314 | * ruby-netcdf-0.3.0 released | |
315 | * netcdfraw.c: NetCDFVar#vartype is aliased to NetCDFVar#ntype | |
316 | * INSTALL: updated | |
317 | * extconf.rb: updated thoroughly (better handling of dependent libs) | |
318 | * lib/netcdr.rb: NetCDF.open: changed mode specification -- | |
319 | it became much closer to that for the File class | |
320 | (Also, NetCDF.create was changed a little -- but no effect for users) | |
321 | * netcdfraw.c: NetCDF_open was modified to be a simple wrapper | |
322 | only of nc_open. | |
323 | * netcdfraw.c: completely renew NetCDF_put_att__ --> NArray available | |
324 | (accordingly changed are NetCDF_(put_att|put_att_var|att_put), and | |
325 | lib/netcdf.rb:NetCDF(|Var)#put_att,NetCDFAtt#put) | |
326 | * netcdfraw.c: minor debug -- eliminate global variables rb_cNetCDF* | |
327 | * netcdfraw.c: initialization of mNumRu was improved | |
328 | ||
329 | Thu Dec 7 2001 Takeshi Horinouchi | |
330 | * ruby-netcdf-0.2.0 released | |
331 | * lib/netcdf.rb: debug NetCDFVar#[], NetCDFVar#[]= | |
332 | * doc/Ref_man[_jp].rd: updated | |
333 | * netcdfraw.c: added clone methods | |
334 | * netcdfraw.c: added security check | |
335 | nc_open, nc_create: Check_SafeStr(filename) | |
336 | file modifying methods: rb_secure(4) | |
337 | file reading methods: taint return values | |
338 | * netcdfraw.c: remove unused def of "new" (it's in netcdf.rb) | |
339 | ||
340 | Thu Dec 6 2001 Takeshi Horinouchi | |
341 | * ruby-netcdf-0.1.10 released | |
342 | * demo/demo2-graphic.rb adapted to advanceddcl-0.2.0 | |
343 | * demo/demo3-ncepclim.rb minor change | |
344 | * netcdfraw.c: rename mNum as mNumRu; initialize it only at first time | |
345 | * mkdir test/; mv test.rb test/; and updated test.rb (to include NumRu) | |
346 | * correctet ChangeLog | |
347 | ||
348 | ?? Nov? ?? 2001 Naoki Kawanabe (log added by Horinouchi) | |
349 | * netcdf.rb added NetCDFVar#[] and NetCDFVar#[]= | |
350 | ||
351 | Sat Nov 16 2001 Takeshi Horinouchi | |
352 | * netcdf.rb: added NetCDFVar.new, NetCDFVar.open (these are the same) | |
353 | ||
354 | Sat Nov ?? 2001 Naoki Kawanabe (log added by Horinouchi) | |
355 | * ruby-netcdf-0.1.9 released | |
356 | * extconf.rb debug | |
357 | ||
358 | Sat Nov 03 2001 Naoki Kawanabe | |
359 | * ruby-netcdf-0.1.7 released (memo by Horinouchi: this should be 0.1.8) | |
360 | * changed install directry (require 'netcdf' -> require | |
361 | 'numru/netcdf') | |
362 | * added module 'NumRu' | |
363 | * changed class name (NetCDF -> NumRu::NetCDF etc.) | |
364 | * demo program renewed | |
365 | Thu Oct 25 2001 Takeshi Horinouchi | |
366 | ||
367 | * ruby-netcdf-0.1.7 released | |
368 | * doc/Ref_man.rd Created (English translation) | |
369 | * doc/Ref_man_jp.rd Revised | |
370 | * netcdfraw.c, NetCDF_att_copy: support file as a destination | |
371 | (global attribute) | |
372 | ||
373 | Thu Oct 23 2001 Takeshi Horinouchi | |
374 | ||
375 | * doc/Ref_man_jp.html regenerated from doc/Ref_man_jp.rd | |
376 | * doc/Ref_man_jp.rd Revised. | |
377 | * doc/Ref_man_jp.rd index added. | |
378 | ||
379 | Thu Oct 23 2001 Takeshi Horinouchi | |
380 | ||
381 | * ruby-netcdf-0.1.6 released | |
382 | * NetCDFruby is renamed to RubyNetCDF. | |
383 | Documents are changed accordingly. | |
384 | * INSTALL was made | |
385 | * Ref_man_jp.rd: a bit modified | |
386 | * documents moved to doc/ | |
387 | * Ref_man_jp.[doc|pdf] is renamed to Ref_man_jp_obsolete.[doc|pdf] | |
388 | Will not be maintained any more. | |
389 | ||
390 | Fri Oct 05, 2001 Naoki Kawanabe <kawanabe@kurasc.kyoto-u.ac.jp> | |
391 | ||
392 | * version 0.1.5 released | |
393 | * added Ref_man_jp.rd and Ref_man_jp.html (in Japanese) | |
394 | ||
395 | Wed Sep 21, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
396 | ||
397 | * version 0.1.4 released | |
398 | * netcdfraw.c: debug get_var_<type> correct dimension order | |
399 | * test.rb truely get rid of xmp | |
400 | ||
401 | Wed Sep 20, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
402 | ||
403 | * version 0.1.3 released | |
404 | * README_JP.txt modified accordingly | |
405 | * extconf.rb modifyed (support the "test" target) | |
406 | * netcdf.rb: debug (NetCDFAtt#put) | |
407 | * netcdfraw.c: debug (NetCDF_put_att, NetCDF_put_att_var) | |
408 | * test.rb --> debug (usage of NetDCFAtt#put) | |
409 | * test.rb --> do not use xmp. Accordingly, xmp.rb is removed from | |
410 | the package | |
411 | ||
412 | Wed Sep 20, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
413 | ||
414 | * version 0.1.2 re-released | |
415 | * xmp.rb (an almost standard program) is copied to the top directory | |
416 | * version 0.1.2 released | |
417 | * changed extconf.rb | |
418 | use standard mkmf.rb | |
419 | Makefile modified after creation by mkmf | |
420 | * mv netcdf.rb lib/netcdf.rb | |
421 | ||
422 | Wed Sep 19, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
423 | ||
424 | * started ToDo list | |
425 | ||
426 | Wed Sep 19, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
427 | ||
428 | * version 0.1.1 released | |
429 | * Reference manual (in japanese) updated and renamed to Ref_man_jp* | |
430 | * mkmf.rb changed (*.nc included for cleaning), README_JP.txt | |
431 | changed accordingly | |
432 | * demo directly added: | |
433 | demo/demo1-create-alt.rb | |
434 | demo/demo1-create.rb | |
435 | demo/demo2-graphic.rb | |
436 | demo/demo2-graphic_old.rb | |
437 | demo/demo3-ncepclim.rb | |
438 | * netcdfraw.c: NetCDFDim#unlimdim? added | |
439 | * (acutally on Sep 12) netcdf.rb: NetCDFVar#put_att added | |
440 | NetCDF#put_att debug | |
441 | * (acutally on Sep 12) netcdfraw.c: a number of debug, | |
442 | NetCDF_put_att_var (NetCDFVar#put_attraw) added | |
443 | ||
444 | Wed Sep 19, 2001 Toshihiro Sakakima <sakakima@kurasc.kyoto-u.ac.jp> | |
445 | ||
446 | * version 0.01 released |
0 | Tue Jan 27 2015 T Horinouchi | |
1 | * ruby-netcdf-0.7.1 released (relase tag: ruby-netcdf-0_7_1) | |
2 | Tue Jan 27 2015 T Horinouchi | |
3 | * doc/ updated | |
4 | * demo/demo5-netcdf4.rb: created | |
5 | * netcdfraw.c: | |
6 | * added new NetCDF-4 methods: | |
7 | * NetCDFVar::deflate : to set compression | |
8 | * NetCDFVar::deflate_params : returns current values of | |
9 | compression parameters | |
10 | * NetCDFVar::endian= : set (change) the endian | |
11 | * NetCDFVar::endian : returns the current endian setting | |
12 | * added new constants: NC_ENDIAN_NATIVE (=0), | |
13 | NC_ENDIAN_LITTLE (=1), NC_ENDIAN_BIG (=2) | |
14 | * updated the safe-level condition, which was missed in the | |
15 | change on Jan 22. | |
16 | Fri Jan 23 2015 T Horinouchi | |
17 | * doc/ updated | |
18 | Thu Jan 22 2015 T Horinouchi | |
19 | * ruby-netcdf-0.7.0 released (relase tag: ruby-netcdf-0_7_0) | |
20 | Thu Jan 22 2015 T Horinouchi | |
21 | * netcdfraw.c: | |
22 | * revised based on the patch posted by seiya with | |
23 | [dennou-ruby:003705] but adopted the typedef in the latest | |
24 | narray-bigmem (namely, used na_shape_t). | |
25 | * changed rb_secure(4) to rb_secure(3), since security | |
26 | level 4 is abolished in ruby 2. | |
27 | * further type update to na_shape_t (not covered | |
28 | by the patch) | |
29 | * deleted the unused variable nc_tlen in many methods. | |
30 | * lib/netcdf.rb: revised along the patch [dennou-ruby:003705]. | |
31 | * extconf.rb: supported to configure gem-installed narray | |
32 | Mon Sep 8 2014 T Horinouchi | |
33 | * lib/netcdf.rb: Tentative treatment of the very slow netcdf-4's | |
34 | strided reading. | |
35 | Sat Sep 6 2014 T Horinouchi | |
36 | * netcdfraw.c: Added constants such as NC_NETCDF4; | |
37 | This enables one to individually specify the creation format by | |
38 | using the low level interface NetCDF.nc_create | |
39 | * lib/netcdf.rb: Supported the "default" file creation format | |
40 | by adding NetCDF.creation_format= and NetCDF.creation_format. | |
41 | * lib/netcdf.rb: Refactoring of NetCDF#simple_get. | |
42 | Sat Sep 6 2014 T Horinouchi | |
43 | * extconf.rb | |
44 | * introduced the macro NCVER | |
45 | * changed to give a higer priority to NetCDF 4; | |
46 | * added $vendorarchdir to dir_config | |
47 | * netcdfraw.c: Added the class method NetCDF.libvers (<- nc_inq_libvers) | |
48 | * lib/netcdf.rb: Added the class constant NCVERSION (<- NetCDF.libvers) | |
49 | Mon Aug 25 2014 T Horinouchi | |
50 | * netcdfraw.c: to avoid a compile error when -Werror=format-security | |
51 | Sun Feb 19 2011 T Horinouchi | |
52 | * ruby-netcdf-0.6.6 released (relase tag: ruby-netcdf-0_6_6) | |
53 | * lib/netcdf.rb: method pack: debug of enbug made | |
54 | when 1.1 -> 1.2 (cvs tag) commited in Jan 2010. | |
55 | * netcdfraw.c: Added macro NC_RAISE2. Enhanced error | |
56 | messaging in NetCDF_open and NetCDF_create to show file name. | |
57 | ||
58 | Thu Feb 17 2011 T Horinouchi | |
59 | * ruby-netcdf-0.6.5 released (relase tag: ruby-netcdf-0_6_5) | |
60 | Thu Feb 17 2011 T Horinouchi | |
61 | * extconf.rb: Debug to have the --disable-opendap option really work | |
62 | Sat Feb 12 2011 T Horinouchi | |
63 | * ruby-netcdf-0.6.5 preview release. | |
64 | Thu Dec 23 2010 T Koshiro | |
65 | * test/aref_aset.rb : updated for Ruby 1.9.2 | |
66 | * lib/netcdf.rb: NetCDF.clean_tmpfile : lambda -> proc | |
67 | * verified that all test programs work fine with Ruby 1.9.2. | |
68 | ||
69 | Tue Dec 14 2010 T Koshiro | |
70 | * netcdfraw.c : nctype2natype : char* -> const char* | |
71 | * test/aref_aset.rb, test/factor_offset.rb : bug fix. | |
72 | ||
73 | Mon Dec 13 2010 T Koshiro | |
74 | * netcdfraw.c : patch for Ruby 1.9.2 | |
75 | - by S Kouketsu (dennou-ruby:003191) | |
76 | - by T Koshiro (dennou-ruby:003226) | |
77 | ||
78 | Mon Mar 15 2010 T Horinouchi | |
79 | * ruby-netcdf-0.6.4 released (relase tag: ruby-netcdf-0_6_4) | |
80 | ||
81 | Thu Jan 14 2010 T Horinouchi < T Koshiro | |
82 | * netcdfraw.c : patch for Ruby 1.9.1 (dennou-ruby:003138) | |
83 | * extconf.rb : patch for NetCDF-4.1-beta2 (dcdvlop Nov 20, 2009) | |
84 | ||
85 | Fri Aug 15 2008 T Horinouchi | |
86 | * lib/netcdf_miss.rb: in __interpret_missing_params, | |
87 | changed just to warn, not to raise an exception, | |
88 | if the missing value or fill value is within the | |
89 | valid range (warning can be suppressed by $VERBOSE = nil) | |
90 | Thu Jul 17 2008 T Horinouchi | |
91 | * lib/netcdf.rb: NetCDFVar's private method pack : to take | |
92 | round if the type of self is integer. | |
93 | * lib/netcdf_miss.rb: debug in the handling of missing data | |
94 | specification using the external data type. | |
95 | Wed Jul 16 2008 T Horinouchi < M Otsuka | |
96 | * netcdfraw.c : patch for Ruby 1.9 | |
97 | Tue Dec 25 2007 T Horinouchi | |
98 | * ruby-netcdf-0.6.3 released | |
99 | * netcdfra.c : (kind of) bugfix. (default attribute type for | |
100 | Fixnum and Bignum was changed from NA_SINT to NA_LINT). | |
101 | * lib/netcdf_miss.rb: improved to judge missing_value validity | |
102 | considering its typecode. | |
103 | Thu Jun 30 2005 | |
104 | * netcdf.rb: NetCDFVar#[] : debug for Array/NArray indices | |
105 | Thu Jun 23 2005 T Horinouchi < S Koshiro | |
106 | * ruby-netcdf-0.6.2 re-released (I am really sorry about that) | |
107 | * extconf.rb: updated to configure the prefix for DODS (useful if | |
108 | the DODS is installed in a non-standard path) | |
109 | Wed Jun 22 2005 T Horinouchi | |
110 | * ruby-netcdf-0.6.2 released | |
111 | * extconf.rb: updated to support opendap 3.5 | |
112 | Fri May 13 2005 T Horinouchi | |
113 | * ruby-netcdf-0.6.1 released | |
114 | Mon Apr 11 2005 Takeshi Horinouchi | |
115 | * netcdfraw.c: changed global variables such as mNumRu to file locale. | |
116 | Tue Mar 15 2005 Takeshi Horinouchi | |
117 | * netcdfraw.c: debug: changed the type of c_stride from size_t to | |
118 | ptrdiff_t. Removed unsuned variables. | |
119 | Mon Mar 14 2005 Takeshi Horinouchi | |
120 | * ruby-netcdf-0.6.0 released | |
121 | * netcdfraw.c: NetCDF_get_var*_*: debug for rank-zero scalar | |
122 | NetCDFVar. It used to SEGV. | |
123 | NetCDF_get_var_*, which reads the whole variable, | |
124 | is modified to return in a NArray of shape==[1]. | |
125 | On the other hand, subset reading by NetCDF_get_var[s1]_* | |
126 | is prohibited for rank-zero scalars by raising an exception. | |
127 | * lib/netcdf.rb: minor modification in [], to support its call | |
128 | without arguments of a rank-zero scalar. | |
129 | * netcdfraw.c: debug: changed size_t to int when NArray functions | |
130 | are called (for 64-bit machines). | |
131 | * extconf.rb: minor change in opendap configuration. | |
132 | Thu Mar 10 2005 Takeshi Horinouchi | |
133 | * extconf.rb: to link OPeNDAP/DODS-enabled version of NetCDF | |
134 | if available and if --disable-opendap is not specified. | |
135 | * lib/netcdf.rb: created pack and unpack by separating from | |
136 | scaled_put and scaled_get, respectvely. Changed type to | |
137 | unpack in to follow the coerce mechanism, so the upacked | |
138 | type depend on the type of scale_factor and add_offset. | |
139 | Renamed NetCDFVar.scaled_get_type[=] to NetCDFVar.unpack_type[=]. | |
140 | * lib/netcdf_miss.rb: revised [put|get]_with_miss_and_scaling: | |
141 | Now, missing data handling using valid_* / missing_value is applied | |
142 | basically to packed data, which is consistent with most | |
143 | conventions. However, it is applied to unpacked data | |
144 | if and only if the type of valid_* / missing_value is not the same as | |
145 | the packed data and is the samed as the unpacked data. | |
146 | * doc/ Updated in response to the modification. | |
147 | Mon Jun 7 2004 Takeshi Horinouchi | |
148 | * ruby-netcdf-0.5.5 released | |
149 | Wed Apr 28 2004 Takeshi Horinouchi < S. Nishizawa | |
150 | * lib/netcdf.rb: minor debug in [](l.662) and []= (l.733 & l.736) | |
151 | to avoid error with NArrayMiss. | |
152 | Mon Mar 8 2004 Takeshi Horinouchi | |
153 | * ruby-netcdf-0.5.4 released | |
154 | * lib/netcdf.rb: created NetCDFVar.scaled_get_type= and | |
155 | NetCDFVar.scaled_get_type | |
156 | Mon Feb 23 2004 Takeshi Horinouchi | |
157 | * lib/netcdf_miss.rb: debug in __interpret_missing_params | |
158 | Tue Oct 28 2003 Takeshi Horinouchi | |
159 | * lib/netcdf.rb: support empty [], []=. Debug in []=. | |
160 | Fri Oct 2 2003 Takeshi Horinouchi | |
161 | * ruby-netcdf-0.5.3 released | |
162 | * lib/netcdf.rb: (by S Nishizawa) enhanced NetCDF#[]= to support | |
163 | array indices. | |
164 | * lib/netcdf.rb: supported the rubber dimension (=false) in | |
165 | NetCDF#[] and NetCDF#[]=. | |
166 | * doc/*rd: updated for NetCDF#[] and NetCDF#[]= | |
167 | * INSTALL: updated | |
168 | Thu Oct 2 2003 Takeshi Horinouchi < S Nishizawa | |
169 | * lib/netcdf.rb: enhanced NetCDF#[] to support array indices. | |
170 | Tue Sep 23 2003 Takeshi Horinouchi | |
171 | * extconf.rb: debug for windows (by T Koshiro) | |
172 | * lib/netcdf_miss.rb: debug get_with_miss_* | |
173 | Wed Aug 27 2003 Takeshi Horinouchi | |
174 | * ruby-netcdf-0.5.2 released | |
175 | * Verified that all test programs work fine with Ruby 1.8.0. | |
176 | * netcdfraw.c: functions NetCDF_dim, NetCDF_var (methods | |
177 | NetCDF#dim, NetCDF#var). Changed behavior back to return nil | |
178 | if not found (by name), as opposed to the change on Feb 3 2003. | |
179 | Debug NetCDF_att_rename (NetCDFAtt#name=). | |
180 | Init_netcdfraw: No longer asks whether NumRu has been | |
181 | defined -- ok for Ruby 1.6.5 or so or later | |
182 | * doc/Ref_man.rd,doc/Ref_man_jp.rd: updated for the changes above | |
183 | * test/test.rb updated for the debug of NetCDFAtt#name=. | |
184 | * lib/netcdf.rb: editted NetCDF#vars and NetCDF#dims not to change | |
185 | the behavior despite the change above. Corrected exception types | |
186 | to raise where needed. | |
187 | Tue Aug 19 2003 Takeshi Horinouchi | |
188 | * demo/demo4-copy.rb: created | |
189 | Tue Aug 12 2003 Takeshi Horinouchi | |
190 | * ruby-netcdf-0.5.1 released | |
191 | * extconf.rb: do not edit "install:" anymore (for Ruby 1.8; works | |
192 | with 1.6 too.) / Debug | |
193 | * doc/Ref_man.rd,doc/Ref_man_jp.rd: corrected a few typos. | |
194 | ||
195 | Tue Aug 12 2003 Takeshi Horinouchi | |
196 | * ruby-netcdf-0.5.0 released | |
197 | * lib/netcdf_miss.rb: created. handles data missing by NArrayMiss. | |
198 | * doc/Ref_man.rd,doc/Ref_man_jp.rd: updated. | |
199 | ||
200 | Mon Aug 11 2003 Takeshi Horinouchi | |
201 | * extconf.rb: modification to cover Cygwin | |
202 | * netcdfraw.c: extern -> EXTERN | |
203 | * lib/netcdf.rb: renamed get|put as simple_(get|put) and | |
204 | made get|put aliased to them. Changed scaled_(get|put) | |
205 | to depend on simple_(put|get). This is to allow the user | |
206 | to redefine get|put, if he/she likes, as: | |
207 | alias get scaled_get | |
208 | alias put scaled_put | |
209 | Or (by using singleton methods) | |
210 | def a_ncvar.get(*arg) | |
211 | scaled_get(*arg) | |
212 | end | |
213 | def a_ncvar.put(*arg) | |
214 | scaled_put(*arg) | |
215 | end | |
216 | Now these do not cause recurrence. By doing so, one can | |
217 | also change the behavior of [] and []=. | |
218 | ||
219 | Sat Mar 24 2003 Takeshi Horinouchi | |
220 | * ruby-netcdf-0.4.0 released | |
221 | Sat Mar 22 2003 Takeshi Horinouchi | |
222 | * lib/netcdf.rb: NetCDFVar#[]: behavior changed -- to eliminate the | |
223 | dimensions designated by Integer's (for better agreement with | |
224 | NArray#[]) | |
225 | * doc/: correct the description of the IO mode for NetCDF.open | |
226 | Fri Mar 21 2003 Takeshi Horinouchi | |
227 | * ruby-netcdf-0.3.9 released | |
228 | Wed Mar 19 2003 Takeshi Horinouchi | |
229 | * netcdfraw.c: changed return values of NetCDF#redef and NetCDF#enddef | |
230 | (NetCDF_redef, NetCDF_enddef) --- return true if succesful and | |
231 | nil if not (the latter means that the file is already in | |
232 | define mode for redef and that it is already in the data mode | |
233 | for enddef). Previously, these methods always retuned nil. | |
234 | * doc/: updated | |
235 | * lib/netcdf.rb: DEBUG [] and []= : treatment of the end of ranges. | |
236 | Tue Mar 18 2003 Takeshi Horinouchi | |
237 | * netcdfraw.c: added NetCDF#define_mode? | |
238 | (NetCDF_whether_in_define_mode) | |
239 | Mon Mar 17 2003 Takeshi Horinouchi | |
240 | * ruby-netcdf-0.3.8 released | |
241 | * netcdfraw.c: deleted function NetCDF_put_var1_long, which was | |
242 | unnecessary (not called by anything). | |
243 | * netcdfraw.c: added methods NetCDFVar#typcode, NetCDFAtt#typcode | |
244 | (functions NetCDF_var_typecode, NetCDF_att_typecode) | |
245 | * netcdfraw.c: NetCDFVar#def_var(NetCDF_def_var) functionarity enhanced | |
246 | to accept NArray's typcodes to specifiy a variable type (vartye). | |
247 | * netcdfraw.c:put_var_*(NetCDF_put_var_*),put_vars_*(NetCDF_put_vars_*) | |
248 | functionality enhanced to accept scalar values to set uniform values | |
249 | * lib/netcdf.rb alias rank ndims (in NetCDFVar) | |
250 | * doc/Ref_man* updated accordingly | |
251 | Fri Mar 14 2003 Takeshi Horinouchi | |
252 | * ruby-netcdf-0.3.7 released | |
253 | Mon Feb 5 2003 Takeshi Horinouchi | |
254 | * doc/Ref_man.rd,doc/Ref_man_jp.rd update (added [] and []= methods) | |
255 | Mon Feb 3 2003 Takeshi Horinouchi | |
256 | * netcdf.rb: added NetCDF#dims, NetCDF#vars | |
257 | * netcdfraw.f: functions NetCDF_dim, NetCDF_var (methods | |
258 | NetCDF#dim, NetCDF#var). Changed behavior to raise exception | |
259 | if not found (by name). | |
260 | Thu Jan 30 2003 Takeshi Horinouchi | |
261 | * ruby-netcdf-0.3.6 released | |
262 | * netcdfraw.c: debug NetCDF_free and NetCDF_close not to close | |
263 | a file that has already been closed | |
264 | * netcdfraw.c: debug nc_mark_obj -- incorrect typing (though in | |
265 | many cases innocuous) | |
266 | * demo/: deleted *_withAdvancedDCL.rb (obsolete) | |
267 | ||
268 | Tue Jun 11 2002 Takeshi Horinouchi | |
269 | * ruby-netcdf-0.3.5 released | |
270 | * netcdfraw.rb: eliminated references to char *na_typestring[] | |
271 | (to make the source compilable with narray-0.5.6p2) | |
272 | * lib/netcdf.rb: eliminated uri methods: this is for a future | |
273 | incorpolation of DODS | |
274 | * demo/demo[23]*:written to use RubyDCL directly instead of AdvancedDCL | |
275 | ||
276 | Tue Feb 26 2002 Takeshi Horinouchi | |
277 | * ruby-netcdf-0.3.4 released | |
278 | ||
279 | Sun Feb 24 2002 Takeshi Horinouchi | |
280 | * lib/netcdf.rb: NetCDF#open minor debug | |
281 | ||
282 | Thu Dec 27 2001 Takeshi Horinouchi | |
283 | * extconf.rb: corrected an error message | |
284 | ||
285 | Thu Dec 26 2001 Takeshi Horinouchi | |
286 | * ruby-netcdf-0.3.3 released | |
287 | * lib/netcdf.rb: changes are made to get around a bug in NArray. | |
288 | Should be re-changed to the original if the bug is fixed. | |
289 | (The changed pars are marked by "TEMPORARY CHANGE 2001/12/27" in | |
290 | the source code) | |
291 | * netcdfraw.c: debug NetCDF_get_vars_sint | |
292 | * doc/Ref_man*rd: added the usage section. | |
293 | ||
294 | Thu Dec 26 2001 Takeshi Horinouchi | |
295 | * ruby-netcdf-0.3.2 released | |
296 | * doc/Ref_man*rd: added a "Data Type" section. Plus, some updates | |
297 | * lib/netcdf.rb: added NetCDF#scaled_put and NetCDF#scaled_get | |
298 | * netcdfraw.c,lib/netcdf.rb: added methods to treat the "char" type | |
299 | ||
300 | Thu Dec 26 2001 Takeshi Horinouchi | |
301 | * ruby-netcdf-0.3.1 released | |
302 | * doc/Ref_man*rd: updated | |
303 | * lib/netcdf/rb: added NetCDF#def_var_with_dim | |
304 | * netcdfraw.c: NetCDF*_eql: debug / do not redefine eql?, since the | |
305 | hash method is not refefined | |
306 | * lib/netcdf/rb: added NetCDFDim#length_ul0 | |
307 | * netcdfraw.c: NetCDF#close: error will not be raised on NetcdfBadid | |
308 | * lib/netcdf/rb: added NetCDFVar#shape_current, NetCDFVar#shape_ul0 | |
309 | * lib/netcdf/rb: added NetCDF.create_tmp -- temporary file | |
310 | * lib/netcdf/rb: NetCDFVar#uri returns path+'?var='+name instead | |
311 | of path+'?'+name | |
312 | ||
313 | Thu Dec 23 2001 Takeshi Horinouchi | |
314 | * ruby-netcdf-0.3.0 released | |
315 | * netcdfraw.c: NetCDFVar#vartype is aliased to NetCDFVar#ntype | |
316 | * INSTALL: updated | |
317 | * extconf.rb: updated thoroughly (better handling of dependent libs) | |
318 | * lib/netcdr.rb: NetCDF.open: changed mode specification -- | |
319 | it became much closer to that for the File class | |
320 | (Also, NetCDF.create was changed a little -- but no effect for users) | |
321 | * netcdfraw.c: NetCDF_open was modified to be a simple wrapper | |
322 | only of nc_open. | |
323 | * netcdfraw.c: completely renew NetCDF_put_att__ --> NArray available | |
324 | (accordingly changed are NetCDF_(put_att|put_att_var|att_put), and | |
325 | lib/netcdf.rb:NetCDF(|Var)#put_att,NetCDFAtt#put) | |
326 | * netcdfraw.c: minor debug -- eliminate global variables rb_cNetCDF* | |
327 | * netcdfraw.c: initialization of mNumRu was improved | |
328 | ||
329 | Thu Dec 7 2001 Takeshi Horinouchi | |
330 | * ruby-netcdf-0.2.0 released | |
331 | * lib/netcdf.rb: debug NetCDFVar#[], NetCDFVar#[]= | |
332 | * doc/Ref_man[_jp].rd: updated | |
333 | * netcdfraw.c: added clone methods | |
334 | * netcdfraw.c: added security check | |
335 | nc_open, nc_create: Check_SafeStr(filename) | |
336 | file modifying methods: rb_secure(4) | |
337 | file reading methods: taint return values | |
338 | * netcdfraw.c: remove unused def of "new" (it's in netcdf.rb) | |
339 | ||
340 | Thu Dec 6 2001 Takeshi Horinouchi | |
341 | * ruby-netcdf-0.1.10 released | |
342 | * demo/demo2-graphic.rb adapted to advanceddcl-0.2.0 | |
343 | * demo/demo3-ncepclim.rb minor change | |
344 | * netcdfraw.c: rename mNum as mNumRu; initialize it only at first time | |
345 | * mkdir test/; mv test.rb test/; and updated test.rb (to include NumRu) | |
346 | * correctet ChangeLog | |
347 | ||
348 | ?? Nov? ?? 2001 Naoki Kawanabe (log added by Horinouchi) | |
349 | * netcdf.rb added NetCDFVar#[] and NetCDFVar#[]= | |
350 | ||
351 | Sat Nov 16 2001 Takeshi Horinouchi | |
352 | * netcdf.rb: added NetCDFVar.new, NetCDFVar.open (these are the same) | |
353 | ||
354 | Sat Nov ?? 2001 Naoki Kawanabe (log added by Horinouchi) | |
355 | * ruby-netcdf-0.1.9 released | |
356 | * extconf.rb debug | |
357 | ||
358 | Sat Nov 03 2001 Naoki Kawanabe | |
359 | * ruby-netcdf-0.1.7 released (memo by Horinouchi: this should be 0.1.8) | |
360 | * changed install directry (require 'netcdf' -> require | |
361 | 'numru/netcdf') | |
362 | * added module 'NumRu' | |
363 | * changed class name (NetCDF -> NumRu::NetCDF etc.) | |
364 | * demo program renewed | |
365 | Thu Oct 25 2001 Takeshi Horinouchi | |
366 | ||
367 | * ruby-netcdf-0.1.7 released | |
368 | * doc/Ref_man.rd Created (English translation) | |
369 | * doc/Ref_man_jp.rd Revised | |
370 | * netcdfraw.c, NetCDF_att_copy: support file as a destination | |
371 | (global attribute) | |
372 | ||
373 | Thu Oct 23 2001 Takeshi Horinouchi | |
374 | ||
375 | * doc/Ref_man_jp.html regenerated from doc/Ref_man_jp.rd | |
376 | * doc/Ref_man_jp.rd Revised. | |
377 | * doc/Ref_man_jp.rd index added. | |
378 | ||
379 | Thu Oct 23 2001 Takeshi Horinouchi | |
380 | ||
381 | * ruby-netcdf-0.1.6 released | |
382 | * NetCDFruby is renamed to RubyNetCDF. | |
383 | Documents are changed accordingly. | |
384 | * INSTALL was made | |
385 | * Ref_man_jp.rd: a bit modified | |
386 | * documents moved to doc/ | |
387 | * Ref_man_jp.[doc|pdf] is renamed to Ref_man_jp_obsolete.[doc|pdf] | |
388 | Will not be maintained any more. | |
389 | ||
390 | Fri Oct 05, 2001 Naoki Kawanabe <kawanabe@kurasc.kyoto-u.ac.jp> | |
391 | ||
392 | * version 0.1.5 released | |
393 | * added Ref_man_jp.rd and Ref_man_jp.html (in Japanese) | |
394 | ||
395 | Wed Sep 21, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
396 | ||
397 | * version 0.1.4 released | |
398 | * netcdfraw.c: debug get_var_<type> correct dimension order | |
399 | * test.rb truely get rid of xmp | |
400 | ||
401 | Wed Sep 20, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
402 | ||
403 | * version 0.1.3 released | |
404 | * README_JP.txt modified accordingly | |
405 | * extconf.rb modifyed (support the "test" target) | |
406 | * netcdf.rb: debug (NetCDFAtt#put) | |
407 | * netcdfraw.c: debug (NetCDF_put_att, NetCDF_put_att_var) | |
408 | * test.rb --> debug (usage of NetDCFAtt#put) | |
409 | * test.rb --> do not use xmp. Accordingly, xmp.rb is removed from | |
410 | the package | |
411 | ||
412 | Wed Sep 20, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
413 | ||
414 | * version 0.1.2 re-released | |
415 | * xmp.rb (an almost standard program) is copied to the top directory | |
416 | * version 0.1.2 released | |
417 | * changed extconf.rb | |
418 | use standard mkmf.rb | |
419 | Makefile modified after creation by mkmf | |
420 | * mv netcdf.rb lib/netcdf.rb | |
421 | ||
422 | Wed Sep 19, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
423 | ||
424 | * started ToDo list | |
425 | ||
426 | Wed Sep 19, 2001 Takeshi Horiouchi <horinout@kurasc.kyoto-u.ac.jp> | |
427 | ||
428 | * version 0.1.1 released | |
429 | * Reference manual (in japanese) updated and renamed to Ref_man_jp* | |
430 | * mkmf.rb changed (*.nc included for cleaning), README_JP.txt | |
431 | changed accordingly | |
432 | * demo directly added: | |
433 | demo/demo1-create-alt.rb | |
434 | demo/demo1-create.rb | |
435 | demo/demo2-graphic.rb | |
436 | demo/demo2-graphic_old.rb | |
437 | demo/demo3-ncepclim.rb | |
438 | * netcdfraw.c: NetCDFDim#unlimdim? added | |
439 | * (acutally on Sep 12) netcdf.rb: NetCDFVar#put_att added | |
440 | NetCDF#put_att debug | |
441 | * (acutally on Sep 12) netcdfraw.c: a number of debug, | |
442 | NetCDF_put_att_var (NetCDFVar#put_attraw) added | |
443 | ||
444 | Wed Sep 19, 2001 Toshihiro Sakakima <sakakima@kurasc.kyoto-u.ac.jp> | |
445 | ||
446 | * version 0.01 released |
0 | require "bundler/gem_tasks" | |
0 | # -* coding: utf-8 -*- | |
1 | require 'rake/testtask' | |
2 | require 'rake/extensiontask' | |
3 | require 'rake/packagetask' | |
4 | begin | |
5 | require 'bundler/gem_helper' # instead of 'bundler/gem_tasks' -> need manual | |
6 | # calls of install_tasks (see below) | |
7 | rescue LoadError | |
8 | puts 'If you want to create gem, You must install Bundler' | |
9 | end | |
1 | 10 | |
11 | # manual calls of install_tasks to support multiple gemspec files | |
12 | Bundler::GemHelper.install_tasks(name: "ruby-netcdf") | |
13 | #Bundler::GemHelper.install_tasks(name: "ruby-netcdf-bigmem") | |
14 | ||
15 | require './lib/numru/netcdf/version' | |
16 | def version | |
17 | NumRu::NetCDF::VERSION | |
18 | end | |
19 | ||
20 | task :default => :test | |
21 | task :test => :compile | |
22 | Rake::TestTask.new do |t| | |
23 | t.libs << 'lib' << 'test' | |
24 | t.test_files = FileList['test/*.rb'] | |
25 | end | |
26 | ||
27 | Rake::ExtensionTask.new do |ext| | |
28 | ext.name = 'netcdfraw' | |
29 | ext.ext_dir = 'ext/numru' | |
30 | ext.lib_dir = 'lib/numru' | |
31 | end | |
32 | ||
33 | Rake::PackageTask.new('ruby-netcdf', "#{version}") do |t| | |
34 | t.need_tar_gz = true | |
35 | t.package_files.include `git ls-files`.split("\n") | |
36 | end |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "bundler/setup" | |
3 | require "ruby/netcdf" | |
4 | ||
5 | # You can add fixtures and/or initialization code here to make experimenting | |
6 | # with your gem easier. You can also use a different console, if you like. | |
7 | ||
8 | # (If you use this, don't forget to add pry to your Gemfile!) | |
9 | # require "pry" | |
10 | # Pry.start | |
11 | ||
12 | require "irb" | |
13 | IRB.start |
0 | #!/bin/bash | |
1 | set -euo pipefail | |
2 | IFS=$'\n\t' | |
3 | ||
4 | bundle install | |
5 | ||
6 | # Do any other automated setup that you need to do here |
0 | require "mkmf" | |
1 | require "rubygems" unless defined?(Gem) | |
2 | ||
3 | ar = ARGV.grep( /^--with-netcdf-version=/ ) | |
4 | if ar.length > 0 | |
5 | ncversion = ar[0].sub(/^--with-netcdf-version=/,"") | |
6 | else | |
7 | ncversion = nil | |
8 | end | |
9 | ||
10 | if Gem.respond_to?(:find_files) and Gem.find_files("narray.h").length > 0 | |
11 | require "rbconfig" | |
12 | so = RbConfig::CONFIG["DLEXT"] | |
13 | narray_include = File.expand_path(File.dirname(Gem.find_files("narray.h")[0])) | |
14 | narray_lib = File.expand_path(File.dirname(Gem.find_files("narray." + so)[0])) | |
15 | else | |
16 | gem_home=(`gem environment GEM_HOME`).chomp | |
17 | narray_dir = Dir.glob("#{gem_home}/gems/narray-*/ext/narray").sort[-1] | |
18 | if narray_dir | |
19 | narray_include = narray_lib = narray_dir | |
20 | else | |
21 | narray_include = narray_lib = [ $sitearchdir, $vendorarchdir] | |
22 | end | |
23 | end | |
24 | dir_config('narray', narray_include, narray_lib) | |
25 | ||
26 | dir_config('netcdf', '/usr/local') | |
27 | ||
28 | if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then | |
29 | print <<EOS | |
30 | ** configure error ** | |
31 | Header narray.h or narray_config.h is not found. If you have these files in | |
32 | /narraydir/include, try the following: | |
33 | ||
34 | % ruby extconf.rb --with-narray-include=/narraydir/include | |
35 | ||
36 | EOS | |
37 | exit(-1) | |
38 | end | |
39 | ||
40 | unless ncversion | |
41 | # configure netcdf version | |
42 | if xsystem("nc-config --version") | |
43 | ncversion = `nc-config --version`.chomp!.sub!(/^n.* /i,"") # rm "netCDF " | |
44 | ncversion.sub!(/^([^\.]+\.[^\.]+\.[^\.]+).+$/,'\1') # e.g. 4.2.1.1 -> 4.2.1 | |
45 | else | |
46 | ncversion = "3.0.0" # assume version 3 (only for compilation) | |
47 | # For compilation, there is no difference among subversions of netcdf 3 | |
48 | end | |
49 | end | |
50 | ||
51 | ncver0 = ncversion[0..0] # "3" or "4" | |
52 | ncver = ncversion.gsub(/\./,'') | |
53 | unless /^\d\d\d$/ =~ ncver # 3 digits | |
54 | raise("Invalid netcdf version: #{ncversion}. Use --with-netcdf-version=") | |
55 | end | |
56 | $CFLAGS += ' -DNCVER='+ncver | |
57 | ||
58 | case ncver0 | |
59 | when "4" | |
60 | if xsystem("nc-config --libs") # for NetCDF 4 | |
61 | cflags = `nc-config --cflags`.gsub(/\n/, " ") | |
62 | libs = `nc-config --libs`.gsub(/\n/, " ") | |
63 | prefix_nc = `nc-config --prefix`.gsub(/\n/, "") | |
64 | ||
65 | dir_config("netcdf",prefix_nc) | |
66 | $CFLAGS += ' ' + cflags | |
67 | $LOCAL_LIBS += ' ' + libs | |
68 | end | |
69 | when "3" | |
70 | # for NetCDF 3, which needs external libraries for OpenDAP | |
71 | if xsystem("ncdap-config --libs") | |
72 | libncdods = "nc-dap" | |
73 | cflags = `ncdap-config --cflags`.gsub(/\n/, " ") | |
74 | libs = `ncdap-config --libs`.gsub(/\n/, " ") | |
75 | prefix_dods = `ncdap-config --prefix`.gsub(/\n/, "") | |
76 | elsif xsystem("opendap-config --libs") | |
77 | libncdods = "nc-dods" | |
78 | cflags = `opendap-config --cflags`.gsub(/\n/, " ") | |
79 | libs = `opendap-config --libs-nc`.gsub(/\n/, " ") | |
80 | prefix_dods = `opendap-config --prefix`.gsub(/\n/, "") | |
81 | end | |
82 | if (enable_config('opendap',true) && ( xsystem("opendap-config --libs") || | |
83 | xsystem("ncdap-config --libs") ) ) | |
84 | ||
85 | dir_config(libncdods,prefix_dods) | |
86 | ||
87 | if (!have_library(libncdods)) | |
88 | print <<-EOS | |
89 | ** ERROR ** Library not found: nc-dods (OPeNDAP/DODS-enabled NetCDF lib) | |
90 | Install it, or run extconf.rb with option --disable-opendap. | |
91 | ^^^^^^^^^^^^^^^^^ | |
92 | EOS | |
93 | exit(-1) | |
94 | else | |
95 | print <<-EOS | |
96 | ** Message ** Compiling with OPeNDAP/DODS-enabled NetCDF library. | |
97 | ||
98 | This is because the command opendap-config is found in your system. | |
99 | If you want to use the ordinary (non-DODS) version of NetCDF, | |
100 | run extconf.rb with option --disable-opendap. | |
101 | ^^^^^^^^^^^^^^^^^ | |
102 | EOS | |
103 | end | |
104 | ||
105 | $CFLAGS += ' '+cflags | |
106 | $LOCAL_LIBS += ' ' + libs | |
107 | ||
108 | # non portable treatments: should be improved (by Horinouchi) | |
109 | CONFIG['LDSHARED'].sub!(/gcc/,'g++') | |
110 | $LIBS.sub!(/-lc\s/,'') ; $LIBS.sub!(/-lc$/,'') | |
111 | print <<-EOS | |
112 | ** Warning ** non-portable treatments are made, | |
113 | which was sucessfull redhat linux 9: | |
114 | * gcc was replaced with g++ in CONFIG['LDSHARED'] | |
115 | * -lc library was removed if in $LIBS | |
116 | ||
117 | EOS | |
118 | # p '@@@' | |
119 | # ary = [] | |
120 | # CONFIG.each{|k,v| ary.push([k,v])} | |
121 | # ary.sort.each{|x| p x} | |
122 | else | |
123 | if ( ! ( have_header("netcdf.h") && have_library("netcdf") ) )then | |
124 | print <<-EOS | |
125 | ** configure error ** | |
126 | Header netcdf.h or the compiled netcdf library is not found. | |
127 | If you have the library installed under /netcdfdir (that is, netcdf.h is | |
128 | in /netcdfdir/include and the library in /netcdfdir/lib/), | |
129 | try the following: | |
130 | ||
131 | % ruby extconf.rb --with-netcdf-dir=/netcdfdir | |
132 | ||
133 | Alternatively, you can specify the two directory separately | |
134 | with --with-netcdf-include and --with-netcdf-lib. | |
135 | EOS | |
136 | exit(-1) | |
137 | end | |
138 | end | |
139 | else | |
140 | raise "Netcdf version #{ncver0} is not supported" | |
141 | end | |
142 | ||
143 | ||
144 | ||
145 | if /cygwin|mingw/ =~ RUBY_PLATFORM | |
146 | have_library("narray") || raise("ERROR: narray library is not found") | |
147 | end | |
148 | ||
149 | create_makefile "numru/netcdfraw" | |
150 | ||
151 | ###### Modify Makefile: ####### | |
152 | File.rename("Makefile","Makefile.orig") | |
153 | oldmkfl = File.open("Makefile.orig") | |
154 | newmkfl = File.open("Makefile","w") | |
155 | oldmkfl.each_line{ |line| | |
156 | case(line) | |
157 | when /^distclean:/ | |
158 | newmkfl.puts(line) | |
159 | newmkfl.puts("\t\t@$(RM) *.nc demo/*.nc demo/*~ lib/*~ doc/*~ test/*.nc test/*~ Makefile.orig") | |
160 | when /^all:/ | |
161 | newmkfl.puts(line) | |
162 | newmkfl.puts("") | |
163 | newmkfl.puts("test: all") # insert the "test" target | |
164 | newmkfl.puts("\t\t@cd test && ruby test.rb && echo 'test did not fail :-p (please ignore the warnings)' && cd ..") | |
165 | # when /lib\/netcdf/ | |
166 | # line = line.chomp! + "/" | |
167 | # newmkfl.puts(line) | |
168 | else | |
169 | newmkfl.puts(line) | |
170 | end | |
171 | } | |
172 | newmkfl.close |
0 | #include<stdio.h> | |
1 | #include "ruby.h" | |
2 | #include "narray.h" | |
3 | #include<netcdf.h> | |
4 | #include<string.h> | |
5 | ||
6 | /* for compatibility with ruby 1.6 */ | |
7 | #ifndef RSTRING_PTR | |
8 | #define RSTRING_PTR(s) (RSTRING(s)->ptr) | |
9 | #endif | |
10 | #ifndef RSTRING_LEN | |
11 | #define RSTRING_LEN(s) (RSTRING(s)->len) | |
12 | #endif | |
13 | #ifndef RARRAY_PTR | |
14 | #define RARRAY_PTR(a) (RARRAY(a)->ptr) | |
15 | #endif | |
16 | #ifndef RARRAY_LEN | |
17 | #define RARRAY_LEN(a) (RARRAY(a)->len) | |
18 | #endif | |
19 | #ifndef StringValueCStr | |
20 | #define StringValueCStr(s) STR2CSTR(s) | |
21 | #endif | |
22 | #ifndef SafeStringValue | |
23 | #define SafeStringValue(s) Check_SafeStr(s) | |
24 | #endif | |
25 | ||
26 | /* for compatibility for NArray and NArray with big memory patch */ | |
27 | #ifndef NARRAY_BIGMEM | |
28 | typedef int na_shape_t; | |
29 | #endif | |
30 | ||
31 | /* Data to NArray */ | |
32 | ||
33 | /* memcpy(ary->ptr,nc_ptr,na_sizeof[NA_SINT]*ary->total); \ */ | |
34 | ||
35 | #define Cbyte_to_NArray(v, rank, shape, up) \ | |
36 | { \ | |
37 | struct NARRAY *ary; \ | |
38 | v = na_make_object(NA_BYTE, rank, shape, cNArray); \ | |
39 | GetNArray(v,ary); \ | |
40 | up = (unsigned char *)ary->ptr; \ | |
41 | } | |
42 | ||
43 | #define Csint_to_NArray(v, rank, shape, sp) \ | |
44 | { \ | |
45 | struct NARRAY *ary; \ | |
46 | v = na_make_object(NA_SINT, rank, shape, cNArray); \ | |
47 | GetNArray(v, ary); \ | |
48 | sp = (short *)ary->ptr; \ | |
49 | } | |
50 | ||
51 | #define Clint_to_NArray(v, rank, shape, lp) \ | |
52 | { \ | |
53 | struct NARRAY *ary; \ | |
54 | v = na_make_object(NA_LINT, rank, shape, cNArray); \ | |
55 | GetNArray(v, ary); \ | |
56 | lp = (int *)ary->ptr; \ | |
57 | } | |
58 | #define Cfloat_to_NArray(v, rank, shape, fp) \ | |
59 | { \ | |
60 | struct NARRAY *ary; \ | |
61 | v = na_make_object(NA_SFLOAT, rank, shape, cNArray); \ | |
62 | GetNArray(v, ary); \ | |
63 | fp = (float *)ary->ptr; \ | |
64 | } | |
65 | #define Cdouble_to_NArray(v, rank, shape, dp); \ | |
66 | { \ | |
67 | struct NARRAY *ary; \ | |
68 | v = na_make_object(NA_DFLOAT, rank, shape, cNArray); \ | |
69 | GetNArray(v, ary); \ | |
70 | dp = (double *)ary->ptr; \ | |
71 | } | |
72 | ||
73 | /* Array or NArray to pointer and length (with no new allocation) */ | |
74 | ||
75 | #define Array_to_Cfloat_len(obj, ptr, len) \ | |
76 | { \ | |
77 | struct NARRAY *na; \ | |
78 | obj = na_cast_object(obj, NA_SFLOAT); \ | |
79 | GetNArray(obj, na); \ | |
80 | ptr = (float *) NA_PTR(na,0); \ | |
81 | len = na->total; \ | |
82 | } | |
83 | ||
84 | #define Array_to_Cfloat_len_shape(obj, ptr, len, shape) \ | |
85 | { \ | |
86 | struct NARRAY *na; \ | |
87 | obj = na_cast_object(obj, NA_SFLOAT); \ | |
88 | GetNArray(obj, na); \ | |
89 | ptr = (float *) NA_PTR(na,0); \ | |
90 | len = na->total; \ | |
91 | shape = na->shape; \ | |
92 | } | |
93 | ||
94 | #define Array_to_Cdouble_len(obj, ptr, len) \ | |
95 | { \ | |
96 | struct NARRAY *na; \ | |
97 | obj = na_cast_object(obj, NA_DFLOAT); \ | |
98 | GetNArray(obj, na); \ | |
99 | ptr = (double *) NA_PTR(na,0); \ | |
100 | len = na->total; \ | |
101 | } | |
102 | #define Array_to_Cdouble_len_shape(obj, ptr, len, shape) \ | |
103 | { \ | |
104 | struct NARRAY *na; \ | |
105 | obj = na_cast_object(obj, NA_DFLOAT); \ | |
106 | GetNArray(obj, na); \ | |
107 | ptr = (double *) NA_PTR(na,0); \ | |
108 | len = na->total; \ | |
109 | shape = na->shape; \ | |
110 | } | |
111 | ||
112 | #define Array_to_Cbyte_len(obj, ptr, len) \ | |
113 | { \ | |
114 | struct NARRAY *na; \ | |
115 | obj = na_cast_object(obj, NA_BYTE); \ | |
116 | GetNArray(obj, na); \ | |
117 | ptr = (u_int8_t *) NA_PTR(na,0); \ | |
118 | len = na->total; \ | |
119 | } | |
120 | ||
121 | #define Array_to_Cbyte_len_shape(obj, ptr, len, shape) \ | |
122 | { \ | |
123 | struct NARRAY *na; \ | |
124 | obj = na_cast_object(obj, NA_BYTE); \ | |
125 | GetNArray(obj, na); \ | |
126 | ptr = (u_int8_t *) NA_PTR(na,0); \ | |
127 | len = na->total; \ | |
128 | shape = na->shape; \ | |
129 | } | |
130 | ||
131 | #define Array_to_Csint_len(obj, ptr, len) \ | |
132 | { \ | |
133 | struct NARRAY *na; \ | |
134 | obj = na_cast_object(obj, NA_SINT); \ | |
135 | GetNArray(obj, na); \ | |
136 | ptr = (int16_t *) NA_PTR(na,0); \ | |
137 | len = na->total; \ | |
138 | } | |
139 | ||
140 | #define Array_to_Csint_len_shape(obj, ptr, len, shape) \ | |
141 | { \ | |
142 | struct NARRAY *na; \ | |
143 | obj = na_cast_object(obj, NA_SINT); \ | |
144 | GetNArray(obj, na); \ | |
145 | ptr = (int16_t *) NA_PTR(na,0); \ | |
146 | len = na->total; \ | |
147 | shape = na->shape; \ | |
148 | } | |
149 | ||
150 | ||
151 | #define Array_to_Clint_len(obj, ptr, len) \ | |
152 | { \ | |
153 | struct NARRAY *na; \ | |
154 | obj = na_cast_object(obj, NA_LINT); \ | |
155 | GetNArray(obj, na); \ | |
156 | ptr = (int32_t *) NA_PTR(na,0); \ | |
157 | len = na->total; \ | |
158 | } | |
159 | ||
160 | #define Array_to_Clint_len_shape(obj, ptr, len, shape) \ | |
161 | { \ | |
162 | struct NARRAY *na; \ | |
163 | obj = na_cast_object(obj, NA_LINT); \ | |
164 | GetNArray(obj, na); \ | |
165 | ptr = (int32_t *) NA_PTR(na,0); \ | |
166 | len = na->total; \ | |
167 | shape = na->shape; \ | |
168 | } | |
169 | ||
170 | ||
171 | /* Array or NArray to pointer (with no new allocation) */ | |
172 | ||
173 | #define Array_to_Cfloat(obj, ptr) \ | |
174 | { \ | |
175 | struct NARRAY *na; \ | |
176 | obj = na_cast_object(obj, NA_SFLOAT); \ | |
177 | GetNArray(obj, na); \ | |
178 | ptr = (float *) NA_PTR(na,0); \ | |
179 | } | |
180 | #define Array_to_Cdouble(obj, ptr) \ | |
181 | { \ | |
182 | struct NARRAY *na; \ | |
183 | obj = na_cast_object(obj, NA_DFLOAT); \ | |
184 | GetNArray(obj, na); \ | |
185 | ptr = (double *) NA_PTR(na,0); \ | |
186 | } | |
187 | #define Array_to_Cbyte(obj, ptr) \ | |
188 | { \ | |
189 | struct NARRAY *na; \ | |
190 | obj = na_cast_object(obj, NA_BYTE); \ | |
191 | GetNArray(obj, na); \ | |
192 | ptr = (u_int8_t *) NA_PTR(na,0); \ | |
193 | } | |
194 | #define Array_to_Csint(obj, ptr) \ | |
195 | { \ | |
196 | struct NARRAY *na; \ | |
197 | obj = na_cast_object(obj, NA_SINT); \ | |
198 | GetNArray(obj, na); \ | |
199 | ptr = (int16_t *) NA_PTR(na,0); \ | |
200 | } | |
201 | #define Array_to_Clint(obj, ptr) \ | |
202 | { \ | |
203 | struct NARRAY *na; \ | |
204 | obj = na_cast_object(obj, NA_LINT); \ | |
205 | GetNArray(obj, na); \ | |
206 | ptr = (int32_t *) NA_PTR(na,0); \ | |
207 | } | |
208 | ||
209 | #define NC_RAISE(status) rb_raise(err_status2class(status),"%s",(nc_strerror(status))) | |
210 | #define NC_RAISE2(status, str) rb_raise(err_status2class(status),"%s (%s)",nc_strerror(status),(str) ) | |
211 | ||
212 | static VALUE mNumRu = 0; | |
213 | static VALUE cNetCDF; | |
214 | static VALUE cNetCDFDim; | |
215 | static VALUE cNetCDFAtt; | |
216 | static VALUE cNetCDFVar; | |
217 | ||
218 | static VALUE rb_eNetcdfError; | |
219 | static VALUE rb_eNetcdfBadid; | |
220 | static VALUE rb_eNetcdfNfile; | |
221 | static VALUE rb_eNetcdfExist; | |
222 | static VALUE rb_eNetcdfInval; | |
223 | static VALUE rb_eNetcdfPerm; | |
224 | static VALUE rb_eNetcdfNotindefine; | |
225 | static VALUE rb_eNetcdfIndefine; | |
226 | static VALUE rb_eNetcdfInvalcoords; | |
227 | static VALUE rb_eNetcdfMaxdims; | |
228 | static VALUE rb_eNetcdfNameinuse; | |
229 | static VALUE rb_eNetcdfNotatt; | |
230 | static VALUE rb_eNetcdfMaxatts; | |
231 | static VALUE rb_eNetcdfBadtype; | |
232 | static VALUE rb_eNetcdfBaddim; | |
233 | static VALUE rb_eNetcdfUnlimpos; | |
234 | static VALUE rb_eNetcdfMaxvars; | |
235 | static VALUE rb_eNetcdfNotvar; | |
236 | static VALUE rb_eNetcdfGlobal; | |
237 | static VALUE rb_eNetcdfNotnc; | |
238 | static VALUE rb_eNetcdfSts; | |
239 | static VALUE rb_eNetcdfMaxname; | |
240 | static VALUE rb_eNetcdfUnlimit; | |
241 | static VALUE rb_eNetcdfNorecvars; | |
242 | static VALUE rb_eNetcdfChar; | |
243 | static VALUE rb_eNetcdfEdge; | |
244 | static VALUE rb_eNetcdfStride; | |
245 | static VALUE rb_eNetcdfBadname; | |
246 | static VALUE rb_eNetcdfRange; | |
247 | static VALUE rb_eNetcdfNomem; | |
248 | ||
249 | /* Special Error */ | |
250 | /* Global error status */ | |
251 | ||
252 | static VALUE rb_eNetcdfFatal; | |
253 | ||
254 | /* Global options variable. Used to determine behavior of error handler. */ | |
255 | ||
256 | static VALUE rb_eNetcdfEntool; | |
257 | static VALUE rb_eNetcdfExdr; | |
258 | static VALUE rb_eNetcdfSyserr; | |
259 | ||
260 | ||
261 | struct Netcdf{ | |
262 | int ncid; | |
263 | char *name; | |
264 | int closed; | |
265 | }; | |
266 | ||
267 | struct NetCDFDim{ | |
268 | int dimid; | |
269 | int ncid; | |
270 | }; | |
271 | ||
272 | struct NetCDFVar{ | |
273 | int varid; | |
274 | int ncid; | |
275 | VALUE file; | |
276 | }; | |
277 | ||
278 | struct NetCDFAtt{ | |
279 | int varid; | |
280 | int ncid; | |
281 | char *name; | |
282 | }; | |
283 | ||
284 | static struct Netcdf * | |
285 | NetCDF_init(int ncid,char *filename) | |
286 | { | |
287 | struct Netcdf *Netcdffile; | |
288 | Netcdffile=xmalloc(sizeof(struct Netcdf)); | |
289 | Netcdffile->ncid=ncid; | |
290 | Netcdffile->closed=0; | |
291 | Netcdffile->name=xmalloc((strlen(filename)+1)*sizeof(char)); | |
292 | strcpy(Netcdffile->name,filename); | |
293 | return(Netcdffile); | |
294 | } | |
295 | ||
296 | static struct NetCDFDim * | |
297 | NetCDF_dim_init(int ncid,int dimid) | |
298 | { | |
299 | struct NetCDFDim *Netcdf_dim; | |
300 | Netcdf_dim=xmalloc(sizeof(struct NetCDFDim)); | |
301 | Netcdf_dim->dimid=dimid; | |
302 | Netcdf_dim->ncid=ncid; | |
303 | return(Netcdf_dim); | |
304 | } | |
305 | ||
306 | static struct NetCDFVar * | |
307 | NetCDF_var_init(int ncid,int varid,VALUE file) | |
308 | { | |
309 | struct NetCDFVar *Netcdf_var; | |
310 | Netcdf_var=xmalloc(sizeof(struct NetCDFVar)); | |
311 | Netcdf_var->varid=varid; | |
312 | Netcdf_var->ncid=ncid; | |
313 | Netcdf_var->file=file; | |
314 | return(Netcdf_var); | |
315 | } | |
316 | static struct NetCDFAtt * | |
317 | NetCDF_att_init(int ncid,int varid,char *attname) | |
318 | { | |
319 | struct NetCDFAtt *Netcdf_att; | |
320 | Netcdf_att=xmalloc(sizeof(struct NetCDFAtt)); | |
321 | Netcdf_att->ncid=ncid; | |
322 | Netcdf_att->varid=varid; | |
323 | Netcdf_att->name=xmalloc((strlen(attname)+1)*sizeof(char)); | |
324 | strcpy(Netcdf_att->name,attname); | |
325 | return(Netcdf_att); | |
326 | } | |
327 | ||
328 | void | |
329 | Netcdf_att_free(struct NetCDFAtt *Netcdf_att) | |
330 | { | |
331 | free(Netcdf_att->name); | |
332 | free(Netcdf_att); | |
333 | } | |
334 | ||
335 | void | |
336 | NetCDF_var_free(struct NetCDFVar *Netcdf_var) | |
337 | { | |
338 | free(Netcdf_var); | |
339 | } | |
340 | ||
341 | void | |
342 | NetCDF_dim_free(struct NetCDFDim *Netcdf_dim) | |
343 | { | |
344 | free(Netcdf_dim); | |
345 | } | |
346 | ||
347 | void | |
348 | NetCDF_free(struct Netcdf *Netcdffile) | |
349 | { | |
350 | if (!Netcdffile->closed){ | |
351 | nc_close(Netcdffile->ncid); /* no error check -- not to stop during GC */ | |
352 | } | |
353 | free(Netcdffile->name); | |
354 | free(Netcdffile); | |
355 | } | |
356 | ||
357 | static VALUE | |
358 | err_status2class(int status) | |
359 | { | |
360 | if(NC_ISSYSERR(status)){ | |
361 | return(rb_eNetcdfSyserr); | |
362 | } | |
363 | switch(status) | |
364 | { | |
365 | case(NC_EBADID): | |
366 | return(rb_eNetcdfBadid);break; | |
367 | case(NC_ENFILE): | |
368 | return(rb_eNetcdfNfile);break; | |
369 | case(NC_EEXIST): | |
370 | return(rb_eNetcdfExist);break; | |
371 | case(NC_EINVAL): | |
372 | return(rb_eNetcdfInval);break; | |
373 | case(NC_EPERM): | |
374 | return(rb_eNetcdfPerm);break; | |
375 | case(NC_ENOTINDEFINE): | |
376 | return(rb_eNetcdfNotindefine);break; | |
377 | case(NC_EINDEFINE): | |
378 | return(rb_eNetcdfIndefine);break; | |
379 | case(NC_EINVALCOORDS): | |
380 | return(rb_eNetcdfInvalcoords);break; | |
381 | case(NC_EMAXDIMS): | |
382 | return(rb_eNetcdfMaxdims);break; | |
383 | case(NC_ENAMEINUSE): | |
384 | return(rb_eNetcdfNameinuse);break; | |
385 | case(NC_ENOTATT): | |
386 | return(rb_eNetcdfNotatt);break; | |
387 | case(NC_EMAXATTS): | |
388 | return(rb_eNetcdfMaxatts);break; | |
389 | case(NC_EBADTYPE): | |
390 | return(rb_eNetcdfBadtype);break; | |
391 | case(NC_EBADDIM): | |
392 | return(rb_eNetcdfBaddim);break; | |
393 | case(NC_EUNLIMPOS): | |
394 | return(rb_eNetcdfUnlimpos);break; | |
395 | case(NC_EMAXVARS): | |
396 | return(rb_eNetcdfMaxvars);break; | |
397 | case(NC_ENOTVAR): | |
398 | return(rb_eNetcdfNotvar);break; | |
399 | case(NC_EGLOBAL): | |
400 | return(rb_eNetcdfGlobal);break; | |
401 | case(NC_ENOTNC): | |
402 | return(rb_eNetcdfNotnc);break; | |
403 | case(NC_ESTS): | |
404 | return(rb_eNetcdfSts);break; | |
405 | case(NC_EMAXNAME): | |
406 | return(rb_eNetcdfMaxname);break; | |
407 | case(NC_EUNLIMIT): | |
408 | return(rb_eNetcdfUnlimit);break; | |
409 | case(NC_ENORECVARS): | |
410 | return(rb_eNetcdfNorecvars);break; | |
411 | case(NC_ECHAR): | |
412 | return(rb_eNetcdfChar);break; | |
413 | case(NC_EEDGE): | |
414 | return(rb_eNetcdfEdge);break; | |
415 | case(NC_ESTRIDE): | |
416 | return(rb_eNetcdfStride);break; | |
417 | case(NC_EBADNAME): | |
418 | return(rb_eNetcdfBadname);break; | |
419 | case(NC_ERANGE): | |
420 | return(rb_eNetcdfRange);break; | |
421 | case(NC_ENOMEM): | |
422 | return(rb_eNetcdfNomem);break; | |
423 | /* case(NC_ENTOOL): | |
424 | return(rb_eNetcdfEntool);break; */ | |
425 | case(NC_EXDR): | |
426 | return(rb_eNetcdfExdr);break; | |
427 | case(NC_SYSERR): | |
428 | return(rb_eNetcdfSyserr);break; | |
429 | case(NC_FATAL): | |
430 | return(rb_eNetcdfFatal);break; | |
431 | } | |
432 | return rb_eNetcdfError; | |
433 | } | |
434 | ||
435 | static const char* | |
436 | nctype2natype(int nctype){ | |
437 | switch(nctype){ | |
438 | case NC_CHAR: | |
439 | return("char"); | |
440 | case NC_BYTE: | |
441 | return("byte"); | |
442 | case NC_SHORT: | |
443 | return("sint"); | |
444 | case NC_INT: | |
445 | return("int"); | |
446 | case NC_FLOAT: | |
447 | return("sfloat"); | |
448 | case NC_DOUBLE: | |
449 | return("float"); | |
450 | default: | |
451 | rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype); | |
452 | } | |
453 | } | |
454 | ||
455 | static int | |
456 | nctype2natypecode(int nctype){ | |
457 | switch(nctype){ | |
458 | case NC_CHAR: | |
459 | return(NA_BYTE); | |
460 | case NC_BYTE: | |
461 | return(NA_BYTE); | |
462 | case NC_SHORT: | |
463 | return(NA_SINT); | |
464 | case NC_INT: | |
465 | return(NA_LINT); | |
466 | case NC_FLOAT: | |
467 | return(NA_SFLOAT); | |
468 | case NC_DOUBLE: | |
469 | return(NA_DFLOAT); | |
470 | default: | |
471 | rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype); | |
472 | } | |
473 | } | |
474 | ||
475 | static int | |
476 | natype2nctype(char *natype) | |
477 | { | |
478 | if(strcmp(natype,"byte")==0) return(NC_BYTE); | |
479 | else if(strcmp(natype,"char")==0) return(NC_CHAR); | |
480 | else if(strcmp(natype,"text")==0) return(NC_CHAR); /* alias of char */ | |
481 | else if(strcmp(natype,"string")==0) return(NC_CHAR); /* alias of char */ | |
482 | else if(strcmp(natype,"sint")==0) return(NC_SHORT); | |
483 | else if(strcmp(natype,"int")==0) return(NC_INT); | |
484 | else if(strcmp(natype,"sfloat")==0) return(NC_FLOAT); | |
485 | else if(strcmp(natype,"float")==0) return(NC_DOUBLE); | |
486 | else rb_raise(rb_eNetcdfError, "No such NArray type '%s'",natype); | |
487 | } | |
488 | ||
489 | static int | |
490 | natypecode2nctype(int natypecode) | |
491 | { | |
492 | if(natypecode==NA_BYTE) return(NC_BYTE); | |
493 | else if(natypecode==NA_SINT) return(NC_SHORT); | |
494 | else if(natypecode==NA_LINT) return(NC_INT); | |
495 | else if(natypecode==NA_SFLOAT) return(NC_FLOAT); | |
496 | else if(natypecode==NA_DFLOAT) return(NC_DOUBLE); | |
497 | else rb_raise(rb_eNetcdfError, "No such NArray typecode '%d'",natypecode); | |
498 | } | |
499 | ||
500 | static void | |
501 | nc_mark_obj(struct NetCDFVar *netcdf_var) | |
502 | { | |
503 | VALUE ptr; | |
504 | ||
505 | ptr = netcdf_var->file; | |
506 | rb_gc_mark(ptr); | |
507 | } | |
508 | ||
509 | ||
510 | VALUE | |
511 | NetCDF_clone(VALUE file) | |
512 | { | |
513 | VALUE clone; | |
514 | struct Netcdf *nc1, *nc2; | |
515 | ||
516 | Data_Get_Struct(file, struct Netcdf, nc1); | |
517 | nc2 = NetCDF_init(nc1->ncid, nc1->name); | |
518 | clone = Data_Wrap_Struct(cNetCDF, 0, NetCDF_free, nc2); | |
519 | CLONESETUP(clone, file); | |
520 | return clone; | |
521 | } | |
522 | ||
523 | VALUE | |
524 | NetCDF_dim_clone(VALUE dim) | |
525 | { | |
526 | VALUE clone; | |
527 | struct NetCDFDim *nd1, *nd2; | |
528 | ||
529 | Data_Get_Struct(dim, struct NetCDFDim, nd1); | |
530 | nd2 = NetCDF_dim_init(nd1->ncid, nd1->dimid); | |
531 | clone = Data_Wrap_Struct(cNetCDFDim, 0, NetCDF_dim_free, nd2); | |
532 | CLONESETUP(clone, dim); | |
533 | return clone; | |
534 | } | |
535 | ||
536 | VALUE | |
537 | NetCDF_att_clone(VALUE att) | |
538 | { | |
539 | VALUE clone; | |
540 | struct NetCDFAtt *na1, *na2; | |
541 | ||
542 | Data_Get_Struct(att, struct NetCDFAtt, na1); | |
543 | na2 = NetCDF_att_init(na1->ncid, na1->varid, na1->name); | |
544 | clone = Data_Wrap_Struct(cNetCDFAtt, 0, Netcdf_att_free, na2); | |
545 | CLONESETUP(clone, att); | |
546 | return clone; | |
547 | } | |
548 | ||
549 | VALUE | |
550 | NetCDF_var_clone(VALUE var) | |
551 | { | |
552 | VALUE clone; | |
553 | struct NetCDFVar *nv1, *nv2; | |
554 | ||
555 | Data_Get_Struct(var, struct NetCDFVar, nv1); | |
556 | nv2 = NetCDF_var_init(nv1->ncid, nv1->varid, nv1->file); | |
557 | clone = Data_Wrap_Struct(cNetCDFVar, nc_mark_obj, NetCDF_var_free, nv2); | |
558 | CLONESETUP(clone, var); | |
559 | return clone; | |
560 | } | |
561 | ||
562 | VALUE | |
563 | NetCDF_inq_libvers(VALUE mod) | |
564 | { | |
565 | VALUE str; | |
566 | str = rb_str_new2(nc_inq_libvers()); | |
567 | return(str); | |
568 | } | |
569 | ||
570 | VALUE | |
571 | NetCDF_close(file) | |
572 | VALUE file; | |
573 | { | |
574 | int status; | |
575 | int ncid; | |
576 | struct Netcdf *Netcdffile; | |
577 | ||
578 | if (rb_safe_level() >= 3 && !OBJ_TAINTED(file)) { | |
579 | rb_raise(rb_eSecurityError, "Insecure: can't close"); | |
580 | } | |
581 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
582 | ncid=Netcdffile->ncid; | |
583 | if(!Netcdffile->closed){ | |
584 | status = nc_close(ncid); | |
585 | if(status != NC_NOERR) NC_RAISE(status); | |
586 | Netcdffile->closed = 1; | |
587 | } else { | |
588 | rb_warn("file %s is already closed", Netcdffile->name); | |
589 | } | |
590 | return Qnil; | |
591 | } | |
592 | ||
593 | VALUE | |
594 | NetCDF_def_dim(VALUE file,VALUE dim_name,VALUE length) | |
595 | { | |
596 | char* c_dim_name; | |
597 | size_t c_length; | |
598 | int ncid; | |
599 | int dimidp; | |
600 | int status; | |
601 | struct Netcdf *Netcdffile; | |
602 | struct NetCDFDim *Netcdf_dim; | |
603 | VALUE Dimension; | |
604 | ||
605 | rb_secure(3); | |
606 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
607 | ||
608 | Check_Type(dim_name,T_STRING); | |
609 | c_dim_name=RSTRING_PTR(dim_name); | |
610 | c_length=NUM2UINT(length); | |
611 | ncid=Netcdffile->ncid; | |
612 | ||
613 | status = nc_def_dim(ncid,c_dim_name,c_length,&dimidp); | |
614 | if(status !=NC_NOERR) NC_RAISE(status); | |
615 | ||
616 | Netcdf_dim = NetCDF_dim_init(ncid,dimidp); | |
617 | ||
618 | Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
619 | return Dimension; | |
620 | } | |
621 | ||
622 | ||
623 | static VALUE | |
624 | NetCDF_put_att_char(int ncid, char *name,VALUE value,VALUE atttype, int varid) | |
625 | { | |
626 | int status; | |
627 | struct NetCDFAtt *ncatt; | |
628 | ||
629 | /* check atttype (not necessarily needed but it's better to do it) */ | |
630 | if (TYPE(atttype) == T_STRING){ | |
631 | if ( natype2nctype(RSTRING_PTR(atttype)) != NC_CHAR ) { | |
632 | rb_raise(rb_eNetcdfError, | |
633 | "attribute type must be 'char' (or nil) for a String value"); | |
634 | } | |
635 | } else if (TYPE(atttype) != T_NIL) { | |
636 | rb_raise(rb_eNetcdfError, | |
637 | "type specfication must be by a string or nil"); | |
638 | } | |
639 | /* put value */ | |
640 | Check_Type(value,T_STRING); | |
641 | status = nc_put_att_text(ncid, varid, name, | |
642 | RSTRING_LEN(value), RSTRING_PTR(value)); | |
643 | if(status != NC_NOERR) NC_RAISE(status); | |
644 | ||
645 | ncatt = NetCDF_att_init(ncid,varid,name); | |
646 | return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt)); | |
647 | } | |
648 | ||
649 | static VALUE | |
650 | NetCDF_put_att_numeric(int ncid, char *name,VALUE value,VALUE atttype, int varid) | |
651 | { | |
652 | VALUE val; | |
653 | struct NARRAY *na_val; | |
654 | int na_typecode, status, len; | |
655 | char *ptr; | |
656 | struct NetCDFAtt *ncatt; | |
657 | ||
658 | /* check atttype and cast to an appropriate NArray if needed */ | |
659 | ||
660 | if (TYPE(atttype) != T_NIL){ | |
661 | na_typecode = na_get_typecode(atttype); | |
662 | GetNArray( na_cast_object(value, na_typecode), na_val ); | |
663 | } else { | |
664 | if (TYPE(value)==T_ARRAY) { | |
665 | val = RARRAY_PTR(value)[0]; /* to check the 1st elemnt if Array */ | |
666 | } else { | |
667 | val = value; | |
668 | } | |
669 | switch(TYPE(val)){ | |
670 | case T_FIXNUM: | |
671 | case T_BIGNUM: | |
672 | na_typecode = NA_LINT; | |
673 | GetNArray( na_cast_object(value, na_typecode), na_val ); | |
674 | break; | |
675 | case T_FLOAT: | |
676 | na_typecode = NA_DFLOAT; | |
677 | GetNArray( na_cast_object(value, na_typecode), na_val ); | |
678 | break; | |
679 | case T_DATA: | |
680 | if ( IsNArray(value) ){ | |
681 | GetNArray(value,na_val); | |
682 | na_typecode = na_val->type; | |
683 | } else { | |
684 | rb_raise(rb_eNetcdfError,"value has a wrong data type"); | |
685 | } | |
686 | break; | |
687 | default: | |
688 | rb_raise(rb_eNetcdfError, | |
689 | "value (or its first element) has a wrong type"); | |
690 | } | |
691 | } | |
692 | ||
693 | /* put value */ | |
694 | ||
695 | len = na_val->total; | |
696 | ptr = na_val->ptr; | |
697 | switch(na_typecode){ | |
698 | case NA_BYTE: | |
699 | status = nc_put_att_uchar(ncid,varid,name,NC_BYTE,len,(unsigned char *)ptr); | |
700 | break; | |
701 | case NA_SINT: | |
702 | status = nc_put_att_short(ncid,varid,name,NC_SHORT,len,(short *)ptr); | |
703 | break; | |
704 | case NA_LINT: | |
705 | status = nc_put_att_int(ncid,varid,name,NC_INT,len,(int *)ptr); | |
706 | break; | |
707 | case NA_SFLOAT: | |
708 | status = nc_put_att_float(ncid,varid,name,NC_FLOAT,len,(float *)ptr); | |
709 | break; | |
710 | case NA_DFLOAT: | |
711 | status = nc_put_att_double(ncid,varid,name,NC_DOUBLE,len,(double*)ptr); | |
712 | break; | |
713 | default: | |
714 | rb_raise(rb_eNetcdfError, | |
715 | "unsupported type. code = %d",na_typecode); | |
716 | } | |
717 | if(status != NC_NOERR) NC_RAISE(status); | |
718 | ||
719 | ncatt = NetCDF_att_init(ncid,varid,name); | |
720 | return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt)); | |
721 | } | |
722 | ||
723 | static VALUE | |
724 | NetCDF_put_att__(int ncid, char *name, VALUE value, VALUE atttype, int varid) | |
725 | /* | |
726 | * atttype: nil or a String ("string","int",etc). If nil, | |
727 | * the type of attribute is determined from the type of value | |
728 | */ | |
729 | { | |
730 | switch(TYPE(value)){ | |
731 | case T_STRING: | |
732 | return(NetCDF_put_att_char(ncid, name, value, atttype, varid)); | |
733 | default: | |
734 | return(NetCDF_put_att_numeric(ncid, name, value, atttype, varid)); | |
735 | } | |
736 | } | |
737 | ||
738 | VALUE | |
739 | NetCDF_put_att(VALUE file,VALUE att_name,VALUE value,VALUE atttype) | |
740 | /* | |
741 | * atttype: nil or a String ("string","int",etc). If nil, | |
742 | * the type of attribute is determined from the type of value | |
743 | */ | |
744 | { | |
745 | struct Netcdf *ncfile; | |
746 | char *name; | |
747 | ||
748 | rb_secure(3); | |
749 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
750 | Check_Type(att_name,T_STRING); | |
751 | name = RSTRING_PTR(att_name); | |
752 | ||
753 | return( NetCDF_put_att__(ncfile->ncid, name, value, atttype, NC_GLOBAL) ); | |
754 | } | |
755 | ||
756 | VALUE | |
757 | NetCDF_put_att_var(VALUE var,VALUE att_name,VALUE value,VALUE atttype) | |
758 | /* | |
759 | * atttype: nil or a String ("string","int",etc). If nil, | |
760 | * the type of attribute is determined from the type of value | |
761 | */ | |
762 | { | |
763 | struct NetCDFVar *ncvar; | |
764 | char *name; | |
765 | ||
766 | rb_secure(3); | |
767 | Data_Get_Struct(var,struct NetCDFVar,ncvar); | |
768 | Check_Type(att_name,T_STRING); | |
769 | name = RSTRING_PTR(att_name); | |
770 | ||
771 | return( NetCDF_put_att__(ncvar->ncid, name, value, atttype, ncvar->varid)); | |
772 | } | |
773 | ||
774 | ||
775 | VALUE | |
776 | NetCDF_def_var(VALUE file,VALUE var_name,VALUE vartype,VALUE dimensions) | |
777 | { | |
778 | int ncid; | |
779 | char *c_var_name; | |
780 | static int xtype; | |
781 | long c_ndims; | |
782 | int varidp; | |
783 | int dimidp; | |
784 | int i=0; | |
785 | int status; | |
786 | char *c_dim_name; | |
787 | int c_dimids[NC_MAX_DIMS]; | |
788 | struct Netcdf *Netcdffile; | |
789 | struct NetCDFVar *Netcdf_var; | |
790 | struct NetCDFDim *Netcdf_dim; | |
791 | VALUE Var; | |
792 | ||
793 | rb_secure(3); | |
794 | Check_Type(var_name,T_STRING); | |
795 | Check_Type(dimensions,T_ARRAY); | |
796 | ||
797 | c_var_name=RSTRING_PTR(var_name); | |
798 | c_ndims=RARRAY_LEN(dimensions); | |
799 | ||
800 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
801 | ncid=Netcdffile->ncid; | |
802 | ||
803 | if (TYPE(vartype) == T_STRING){ | |
804 | xtype = natype2nctype(RSTRING_PTR(vartype)); | |
805 | } else if (TYPE(vartype) == T_FIXNUM){ | |
806 | xtype = natypecode2nctype(NUM2INT(vartype)); | |
807 | } else { | |
808 | rb_raise(rb_eNetcdfError, | |
809 | "type specfication must be by a string or nil"); | |
810 | } | |
811 | ||
812 | for(i=0;i<c_ndims;i++){ | |
813 | switch(TYPE(RARRAY_PTR(dimensions)[c_ndims-1-i])){ | |
814 | case T_STRING: | |
815 | Check_Type(RARRAY_PTR(dimensions)[c_ndims-1-i],T_STRING); | |
816 | c_dim_name=StringValueCStr(RARRAY_PTR(dimensions)[c_ndims-1-i]); | |
817 | status=nc_inq_dimid(ncid,c_dim_name,&dimidp); | |
818 | if(status != NC_NOERR) NC_RAISE(status); | |
819 | c_dimids[i]=dimidp; | |
820 | break; | |
821 | case T_DATA: | |
822 | Data_Get_Struct(RARRAY_PTR(dimensions)[c_ndims-1-i],struct NetCDFDim,Netcdf_dim); | |
823 | c_dimids[i]=Netcdf_dim->dimid; | |
824 | break; | |
825 | default: | |
826 | rb_raise(rb_eNetcdfError, "No such object of the netCDF dimension class."); | |
827 | } | |
828 | } | |
829 | ||
830 | status = nc_def_var(ncid,c_var_name,xtype,c_ndims,c_dimids,&varidp); | |
831 | if(status != NC_NOERR) NC_RAISE(status); | |
832 | ||
833 | Netcdf_var = NetCDF_var_init(ncid,varidp,file); | |
834 | ||
835 | Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var); | |
836 | return Var; | |
837 | } | |
838 | ||
839 | VALUE | |
840 | NetCDF_dim(VALUE file,VALUE dim_name) | |
841 | { | |
842 | int ncid; | |
843 | char *c_dim_name; | |
844 | int dimidp; | |
845 | int status; | |
846 | struct Netcdf *Netcdffile; | |
847 | struct NetCDFDim *Netcdf_dim; | |
848 | VALUE Dimension; | |
849 | ||
850 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
851 | ncid=Netcdffile->ncid; | |
852 | Check_Type(dim_name,T_STRING); | |
853 | c_dim_name=RSTRING_PTR(dim_name); | |
854 | ||
855 | status = nc_inq_dimid(ncid,c_dim_name,&dimidp); | |
856 | if(status !=NC_NOERR){ | |
857 | if(status == NC_EBADDIM){ | |
858 | return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/ | |
859 | } else{ | |
860 | NC_RAISE(status); | |
861 | } | |
862 | } | |
863 | ||
864 | Netcdf_dim=NetCDF_dim_init(ncid,dimidp); | |
865 | ||
866 | Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
867 | return Dimension; | |
868 | } | |
869 | ||
870 | VALUE | |
871 | NetCDF_var(VALUE file,VALUE var_name) | |
872 | { | |
873 | int ncid; | |
874 | int status; | |
875 | int varidp; | |
876 | char *c_var_name; | |
877 | struct Netcdf *Netcdffile; | |
878 | struct NetCDFVar *Netcdf_var; | |
879 | VALUE Variable; | |
880 | ||
881 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
882 | ncid=Netcdffile->ncid; | |
883 | Check_Type(var_name,T_STRING); | |
884 | c_var_name=RSTRING_PTR(var_name); | |
885 | ||
886 | status=nc_inq_varid(ncid,c_var_name,&varidp); | |
887 | if(status != NC_NOERR){ | |
888 | if(status == NC_ENOTVAR){ | |
889 | return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/ | |
890 | } else{ | |
891 | NC_RAISE(status); | |
892 | } | |
893 | } | |
894 | ||
895 | Netcdf_var = NetCDF_var_init(ncid,varidp,file); | |
896 | Variable = Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var); | |
897 | return Variable; | |
898 | } | |
899 | ||
900 | VALUE | |
901 | NetCDF_att(VALUE file,VALUE att_name) | |
902 | { | |
903 | int ncid; | |
904 | int status; | |
905 | int attnump; | |
906 | char *c_att_name; | |
907 | struct Netcdf *Netcdffile; | |
908 | struct NetCDFAtt *Netcdf_att; | |
909 | VALUE Attribute; | |
910 | ||
911 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
912 | ncid=Netcdffile->ncid; | |
913 | Check_Type(att_name,T_STRING); | |
914 | c_att_name=RSTRING_PTR(att_name); | |
915 | ||
916 | ||
917 | status = nc_inq_attid(ncid,NC_GLOBAL,c_att_name,&attnump); | |
918 | if(status != NC_NOERR){ | |
919 | if(status == NC_ENOTATT){ | |
920 | return(Qnil); | |
921 | } | |
922 | else{ | |
923 | NC_RAISE(status); | |
924 | } | |
925 | } | |
926 | ||
927 | Netcdf_att = NetCDF_att_init(ncid,NC_GLOBAL,c_att_name); | |
928 | ||
929 | Attribute = Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
930 | ||
931 | return Attribute; | |
932 | } | |
933 | VALUE | |
934 | NetCDF_fill(VALUE file,VALUE mode) | |
935 | { | |
936 | int ncid; | |
937 | int status; | |
938 | struct Netcdf *Netcdffile; | |
939 | int old_modep; | |
940 | ||
941 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
942 | ncid = Netcdffile->ncid; | |
943 | if(mode==Qfalse){ | |
944 | status = nc_set_fill(ncid,NC_NOFILL,&old_modep); | |
945 | if(status != NC_NOERR) NC_RAISE(status); | |
946 | } | |
947 | else if(mode == Qtrue){ | |
948 | status = nc_set_fill(ncid,NC_FILL,&old_modep); | |
949 | if(status != NC_NOERR) NC_RAISE(status); | |
950 | } | |
951 | else | |
952 | rb_raise(rb_eNetcdfError,"Usage:self.fill(true) or self.fill(false)"); | |
953 | return Qnil; | |
954 | } | |
955 | ||
956 | VALUE | |
957 | NetCDF_redef(VALUE file) | |
958 | { | |
959 | int ncid; | |
960 | int status; | |
961 | struct Netcdf *Netcdffile; | |
962 | ||
963 | rb_secure(3); | |
964 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
965 | ncid=Netcdffile->ncid; | |
966 | status = nc_redef(ncid); | |
967 | if(status !=NC_NOERR){ | |
968 | if(status == NC_EINDEFINE){ | |
969 | return Qnil; | |
970 | } | |
971 | else{ | |
972 | NC_RAISE(status); | |
973 | } | |
974 | } | |
975 | return Qtrue; | |
976 | } | |
977 | ||
978 | VALUE | |
979 | NetCDF_enddef(VALUE file) | |
980 | { | |
981 | int ncid; | |
982 | int status; | |
983 | struct Netcdf *Netcdffile; | |
984 | ||
985 | rb_secure(3); | |
986 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
987 | ncid=Netcdffile->ncid; | |
988 | status = nc_enddef(ncid); | |
989 | if(status !=NC_NOERR){ | |
990 | if(status == NC_ENOTINDEFINE){ | |
991 | return Qnil; | |
992 | } | |
993 | else{ | |
994 | NC_RAISE(status); | |
995 | } | |
996 | } | |
997 | return Qtrue; | |
998 | } | |
999 | ||
1000 | VALUE | |
1001 | NetCDF_whether_in_define_mode(VALUE file) | |
1002 | { | |
1003 | /* returns true if the NetCDF object is currently in the define mode, | |
1004 | false if in the data mode, and | |
1005 | nil if else (possibly the file is read-only, or some other | |
1006 | error occurred) | |
1007 | */ | |
1008 | int ncid; | |
1009 | int status; | |
1010 | struct Netcdf *Netcdffile; | |
1011 | ||
1012 | rb_secure(3); | |
1013 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
1014 | ncid=Netcdffile->ncid; | |
1015 | status = nc_redef(ncid); | |
1016 | if(status == NC_EINDEFINE){ | |
1017 | return Qtrue; | |
1018 | } else if(status == NC_NOERR) { | |
1019 | /* was in the data mode --> recover the data mode and report false */ | |
1020 | status = nc_enddef(ncid); | |
1021 | if(status == NC_NOERR) { | |
1022 | return Qfalse; | |
1023 | } else { | |
1024 | return Qnil; | |
1025 | } | |
1026 | } else { | |
1027 | return Qnil; | |
1028 | } | |
1029 | } | |
1030 | ||
1031 | VALUE | |
1032 | NetCDF_open(VALUE mod,VALUE filename,VALUE omode) | |
1033 | { | |
1034 | int status; | |
1035 | int ncid; | |
1036 | char* c_filename; | |
1037 | int c_omode; | |
1038 | struct Netcdf *ncfile; | |
1039 | VALUE retval; | |
1040 | ||
1041 | Check_Type(filename,T_STRING); | |
1042 | SafeStringValue(filename); | |
1043 | c_filename=RSTRING_PTR(filename); | |
1044 | Check_Type(omode,T_FIXNUM); | |
1045 | c_omode=NUM2INT(omode); | |
1046 | ||
1047 | status = nc_open(c_filename,c_omode,&ncid); | |
1048 | if(status !=NC_NOERR){NC_RAISE2(status,c_filename);} | |
1049 | ||
1050 | ncfile = NetCDF_init(ncid,c_filename); | |
1051 | retval = Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile); | |
1052 | return( retval ); | |
1053 | } | |
1054 | ||
1055 | VALUE | |
1056 | NetCDF_create(VALUE mod,VALUE filename,VALUE cmode) | |
1057 | { | |
1058 | int ncid; | |
1059 | int status; | |
1060 | char* c_filename; | |
1061 | int c_cmode; | |
1062 | struct Netcdf *ncfile; | |
1063 | ||
1064 | Check_Type(filename,T_STRING); | |
1065 | SafeStringValue(filename); | |
1066 | c_filename=RSTRING_PTR(filename); | |
1067 | Check_Type(cmode,T_FIXNUM); | |
1068 | c_cmode=NUM2INT(cmode); | |
1069 | ||
1070 | status = nc_create(c_filename,c_cmode,&ncid); | |
1071 | if(status != NC_NOERR) NC_RAISE2(status, c_filename); | |
1072 | ||
1073 | ncfile = NetCDF_init(ncid,c_filename); | |
1074 | return( Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile) ); | |
1075 | } | |
1076 | ||
1077 | VALUE | |
1078 | NetCDF_ndims(VALUE file) | |
1079 | { | |
1080 | int ncid; | |
1081 | int ndimsp; | |
1082 | VALUE Integer; | |
1083 | int status; | |
1084 | struct Netcdf *ncfile; | |
1085 | ||
1086 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1087 | ncid=ncfile->ncid; | |
1088 | status = nc_inq_ndims(ncid,&ndimsp); | |
1089 | if(status != NC_NOERR) NC_RAISE (status); | |
1090 | Integer = INT2NUM(ndimsp); | |
1091 | return Integer; | |
1092 | } | |
1093 | ||
1094 | VALUE | |
1095 | NetCDF_nvars(VALUE file) | |
1096 | { | |
1097 | int ncid; | |
1098 | int nvarsp; | |
1099 | int status; | |
1100 | VALUE Integer; | |
1101 | struct Netcdf *ncfile; | |
1102 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1103 | ncid=ncfile->ncid; | |
1104 | status = nc_inq_nvars(ncid,&nvarsp); | |
1105 | if(status != NC_NOERR) NC_RAISE (status); | |
1106 | Integer = INT2NUM(nvarsp); | |
1107 | return Integer; | |
1108 | } | |
1109 | ||
1110 | VALUE | |
1111 | NetCDF_natts(VALUE file) | |
1112 | { | |
1113 | int ncid; | |
1114 | int nattsp; | |
1115 | int status; | |
1116 | VALUE Integer; | |
1117 | struct Netcdf *ncfile; | |
1118 | ||
1119 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1120 | ncid=ncfile->ncid; | |
1121 | status=nc_inq_natts(ncid,&nattsp); | |
1122 | if(status != NC_NOERR) NC_RAISE (status); | |
1123 | Integer = INT2NUM(nattsp); | |
1124 | return Integer; | |
1125 | } | |
1126 | ||
1127 | VALUE | |
1128 | NetCDF_unlimited(VALUE file) | |
1129 | { | |
1130 | int ncid; | |
1131 | int unlimdimidp; | |
1132 | int status; | |
1133 | struct Netcdf *ncfile; | |
1134 | struct NetCDFDim *Netcdf_dim; | |
1135 | VALUE Dimension; | |
1136 | ||
1137 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1138 | ncid=ncfile->ncid; | |
1139 | status=nc_inq_unlimdim(ncid,&unlimdimidp); | |
1140 | if(status !=NC_NOERR) NC_RAISE(status); | |
1141 | ||
1142 | Netcdf_dim = NetCDF_dim_init(ncid,unlimdimidp); | |
1143 | ||
1144 | /* If unlimdimidp=-1,No unlimited dimension is defined in the netCDF dataset */ | |
1145 | if(unlimdimidp != -1) | |
1146 | { | |
1147 | Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
1148 | return Dimension; | |
1149 | } | |
1150 | else | |
1151 | { | |
1152 | return Qnil; | |
1153 | } | |
1154 | } | |
1155 | ||
1156 | #if NCVER >= 400 | |
1157 | ||
1158 | VALUE | |
1159 | NetCDF_format(VALUE file) | |
1160 | { | |
1161 | int ncid; | |
1162 | int formatp; | |
1163 | int status; | |
1164 | VALUE Integer; | |
1165 | struct Netcdf *ncfile; | |
1166 | ||
1167 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1168 | ncid=ncfile->ncid; | |
1169 | status=nc_inq_format(ncid,&formatp); | |
1170 | if(status != NC_NOERR) NC_RAISE (status); | |
1171 | Integer = INT2NUM(formatp); | |
1172 | /* one of NC_FORMAT_CLASSIC (1), NC_FORMAT_64BIT (2), NC_FORMAT_NETCDF4 (3), | |
1173 | NC_FORMAT_NETCDF4_CLASSIC (4) | |
1174 | */ | |
1175 | return Integer; | |
1176 | } | |
1177 | ||
1178 | #endif | |
1179 | ||
1180 | VALUE | |
1181 | NetCDF_sync(VALUE file) | |
1182 | { | |
1183 | int ncid; | |
1184 | int status; | |
1185 | struct Netcdf *ncfile; | |
1186 | ||
1187 | rb_secure(3); | |
1188 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1189 | ncid=ncfile->ncid; | |
1190 | status = nc_sync(ncid); | |
1191 | if(status !=NC_NOERR) NC_RAISE (status); | |
1192 | return Qnil; | |
1193 | } | |
1194 | ||
1195 | VALUE | |
1196 | NetCDF_path(VALUE file) | |
1197 | { | |
1198 | char *path; | |
1199 | struct Netcdf *ncfile; | |
1200 | ||
1201 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1202 | path=ncfile->name; | |
1203 | return(rb_str_new2(path)); | |
1204 | } | |
1205 | ||
1206 | VALUE | |
1207 | NetCDF_dim_length(VALUE Dim) | |
1208 | { | |
1209 | int ncid; | |
1210 | int status; | |
1211 | int dimid; | |
1212 | size_t lengthp; | |
1213 | struct NetCDFDim *Netcdf_dim; | |
1214 | ||
1215 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1216 | ncid=Netcdf_dim->ncid; | |
1217 | dimid=Netcdf_dim->dimid; | |
1218 | ||
1219 | status = nc_inq_dimlen(ncid,dimid,&lengthp); | |
1220 | if(status != NC_NOERR) NC_RAISE(status); | |
1221 | ||
1222 | return(INT2NUM(lengthp)); | |
1223 | } | |
1224 | ||
1225 | VALUE | |
1226 | NetCDF_dim_name(VALUE Dim,VALUE dimension_newname) | |
1227 | { | |
1228 | int ncid; | |
1229 | int status; | |
1230 | int dimid; | |
1231 | char *c_dim_name; | |
1232 | struct NetCDFDim *Netcdf_dim; | |
1233 | ||
1234 | rb_secure(3); | |
1235 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1236 | ncid=Netcdf_dim->ncid; | |
1237 | dimid=Netcdf_dim->dimid; | |
1238 | Check_Type(dimension_newname,T_STRING); | |
1239 | c_dim_name = StringValueCStr(dimension_newname); | |
1240 | ||
1241 | status = nc_rename_dim(ncid,dimid,c_dim_name); | |
1242 | if(status !=NC_NOERR) NC_RAISE(status); | |
1243 | ||
1244 | return Qnil; | |
1245 | } | |
1246 | ||
1247 | VALUE | |
1248 | NetCDF_dim_inqname(VALUE Dim) | |
1249 | { | |
1250 | int ncid; | |
1251 | int status; | |
1252 | int dimid; | |
1253 | char c_dim_name[NC_MAX_NAME]; | |
1254 | struct NetCDFDim *Netcdf_dim; | |
1255 | VALUE str; | |
1256 | ||
1257 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1258 | ncid=Netcdf_dim->ncid; | |
1259 | dimid=Netcdf_dim->dimid; | |
1260 | ||
1261 | status = nc_inq_dimname(ncid,dimid,c_dim_name); | |
1262 | if(status !=NC_NOERR) NC_RAISE(status); | |
1263 | ||
1264 | str = rb_str_new2(c_dim_name); | |
1265 | OBJ_TAINT(str); | |
1266 | return(str); | |
1267 | } | |
1268 | ||
1269 | VALUE | |
1270 | NetCDF_dim_whether_unlimited(VALUE Dim) | |
1271 | { | |
1272 | int status; | |
1273 | int uldid; | |
1274 | struct NetCDFDim *Netcdf_dim; | |
1275 | ||
1276 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1277 | status=nc_inq_unlimdim(Netcdf_dim->ncid,&uldid); | |
1278 | if(status !=NC_NOERR) NC_RAISE(status); | |
1279 | if(Netcdf_dim->dimid == uldid){ | |
1280 | return(Qtrue); | |
1281 | } else { | |
1282 | return(Qfalse); | |
1283 | } | |
1284 | } | |
1285 | ||
1286 | VALUE | |
1287 | NetCDF_att_inq_name(VALUE Att) | |
1288 | { | |
1289 | char *c_att_name; | |
1290 | struct NetCDFAtt *Netcdf_att; | |
1291 | VALUE str; | |
1292 | ||
1293 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1294 | c_att_name=Netcdf_att->name; | |
1295 | ||
1296 | str = rb_str_new2(c_att_name); | |
1297 | OBJ_TAINT(str); | |
1298 | return(str); | |
1299 | } | |
1300 | ||
1301 | VALUE | |
1302 | NetCDF_att_rename(VALUE Att,VALUE new_att_name) | |
1303 | { | |
1304 | int ncid; | |
1305 | int status; | |
1306 | int varid; | |
1307 | char *c_att_name; | |
1308 | char *c_new_att_name; | |
1309 | struct NetCDFAtt *Netcdf_att; | |
1310 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1311 | ncid=Netcdf_att->ncid; | |
1312 | varid=Netcdf_att->varid; | |
1313 | ||
1314 | c_att_name=Netcdf_att->name; | |
1315 | ||
1316 | Check_Type(new_att_name,T_STRING); | |
1317 | SafeStringValue(new_att_name); | |
1318 | c_new_att_name=StringValueCStr(new_att_name); | |
1319 | ||
1320 | status = nc_rename_att(ncid,varid,c_att_name,c_new_att_name); | |
1321 | if(status != NC_NOERR) NC_RAISE(status); | |
1322 | ||
1323 | strcpy(Netcdf_att->name,c_new_att_name); | |
1324 | return Qnil; | |
1325 | } | |
1326 | ||
1327 | VALUE | |
1328 | NetCDF_id2dim(VALUE file,VALUE dimid) | |
1329 | { | |
1330 | int ncid; | |
1331 | int c_dimid; | |
1332 | struct Netcdf *ncfile; | |
1333 | struct NetCDFDim *Netcdf_dim; | |
1334 | VALUE Dim; | |
1335 | ||
1336 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1337 | ncid=ncfile->ncid; | |
1338 | Check_Type(dimid,T_FIXNUM); | |
1339 | c_dimid=NUM2INT(dimid); | |
1340 | Netcdf_dim = NetCDF_dim_init(ncid,c_dimid); | |
1341 | Dim=Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
1342 | return(Dim); | |
1343 | } | |
1344 | ||
1345 | VALUE | |
1346 | NetCDF_id2var(VALUE file,VALUE varid) | |
1347 | { | |
1348 | int ncid; | |
1349 | int c_varid; | |
1350 | struct Netcdf *ncfile; | |
1351 | struct NetCDFVar *Netcdf_var; | |
1352 | VALUE Var; | |
1353 | ||
1354 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1355 | ncid=ncfile->ncid; | |
1356 | Check_Type(varid,T_FIXNUM); | |
1357 | c_varid=NUM2INT(varid); | |
1358 | Netcdf_var = NetCDF_var_init(ncid,c_varid,file); | |
1359 | Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var); | |
1360 | return(Var); | |
1361 | } | |
1362 | ||
1363 | ||
1364 | VALUE | |
1365 | NetCDF_id2att(VALUE file,VALUE attnum) | |
1366 | { | |
1367 | int ncid; | |
1368 | int c_attnum; | |
1369 | int status; | |
1370 | struct Netcdf *ncfile; | |
1371 | struct NetCDFAtt *Netcdf_att; | |
1372 | char *c_att_name; | |
1373 | VALUE Att; | |
1374 | c_att_name=ALLOCA_N(char,NC_MAX_NAME); | |
1375 | ||
1376 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1377 | ncid=ncfile->ncid; | |
1378 | ||
1379 | Check_Type(attnum,T_FIXNUM); | |
1380 | c_attnum=NUM2INT(attnum); | |
1381 | ||
1382 | status = nc_inq_attname(ncid,NC_GLOBAL,c_attnum,c_att_name); | |
1383 | if(status != NC_NOERR) NC_RAISE(status); | |
1384 | ||
1385 | Netcdf_att=NetCDF_att_init(ncid,NC_GLOBAL,c_att_name); | |
1386 | ||
1387 | Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
1388 | return(Att); | |
1389 | ||
1390 | } | |
1391 | ||
1392 | #if NCVER >= 400 | |
1393 | /* USAGE | |
1394 | NetCDFVar#deflate(deflate_level, shuffle=false) | |
1395 | */ | |
1396 | VALUE | |
1397 | NetCDF_var_deflate(int argc, VALUE *argv, VALUE Var) | |
1398 | { | |
1399 | int ncid, varid, status; | |
1400 | struct NetCDFVar *Netcdf_var; | |
1401 | ||
1402 | int shuffle; | |
1403 | /* If non-zero, turn on the shuffle filter. | |
1404 | ||
1405 | http://www.unidata.ucar.edu/software/netcdf/papers/AMS_2008.pdf : | |
1406 | The shuffle algorithm changes the byte order in the data stream; | |
1407 | when used with integers that are all close together, this | |
1408 | results in a better compression ratio. There is no benefit | |
1409 | from using the shuffle filter without also using | |
1410 | compression. | |
1411 | ||
1412 | MEMO by horinouchi: shuffling filter was also effective for float | |
1413 | variables in some test (demo5-netcdf4.rb). | |
1414 | */ | |
1415 | int deflate_level; | |
1416 | int deflate=1; | |
1417 | /* Always set to non-zero: | |
1418 | See https://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar_005fdeflate.html#nc_005fdef_005fvar_005fdeflate | |
1419 | If non-zero, turn on the deflate filter at the | |
1420 | level specified by the deflate_level parameter. | |
1421 | */ | |
1422 | ||
1423 | if (argc>2 || argc<1) rb_raise(rb_eArgError, | |
1424 | "wrong # of arguments (%d). It must be 1 or 2", argc); | |
1425 | ||
1426 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1427 | ncid = Netcdf_var->ncid; | |
1428 | varid = Netcdf_var->varid; | |
1429 | ||
1430 | deflate_level = NUM2INT(argv[0]); | |
1431 | ||
1432 | if (argc==1) { | |
1433 | shuffle = 0; /* default: false */ | |
1434 | } else { | |
1435 | if ( argv[1] == Qnil || argv[1] == Qfalse ) { | |
1436 | shuffle = 0; | |
1437 | } else { | |
1438 | shuffle = 1; | |
1439 | } | |
1440 | } | |
1441 | ||
1442 | status = nc_def_var_deflate(ncid, varid, shuffle, deflate, deflate_level); | |
1443 | if(status != NC_NOERR) NC_RAISE(status); | |
1444 | ||
1445 | return(Var); | |
1446 | } | |
1447 | ||
1448 | VALUE | |
1449 | NetCDF_var_deflate_params(VALUE Var) | |
1450 | { | |
1451 | int ncid, varid, status; | |
1452 | struct NetCDFVar *Netcdf_var; | |
1453 | int shufflep, deflatep, deflate_levelp; | |
1454 | VALUE sh, df, params; | |
1455 | ||
1456 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1457 | ncid = Netcdf_var->ncid; | |
1458 | varid = Netcdf_var->varid; | |
1459 | status = nc_inq_var_deflate(ncid, varid, &shufflep, &deflatep, | |
1460 | &deflate_levelp); | |
1461 | if(status != NC_NOERR) NC_RAISE(status); | |
1462 | if (shufflep==0) {sh=Qfalse;} else {sh=Qtrue;} | |
1463 | if (deflatep==0) {df=Qfalse;} else {df=Qtrue;} | |
1464 | params = rb_ary_new3(3, sh, df, INT2NUM(deflate_levelp) ); | |
1465 | return(params); | |
1466 | } | |
1467 | ||
1468 | VALUE | |
1469 | NetCDF_var_set_endian(VALUE Var, VALUE endian) | |
1470 | { | |
1471 | int ncid, varid, status; | |
1472 | struct NetCDFVar *Netcdf_var; | |
1473 | ||
1474 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1475 | ncid = Netcdf_var->ncid; | |
1476 | varid = Netcdf_var->varid; | |
1477 | status = nc_def_var_endian(ncid, varid, NUM2INT(endian)); | |
1478 | if(status != NC_NOERR) NC_RAISE(status); | |
1479 | return(Var); | |
1480 | } | |
1481 | ||
1482 | VALUE | |
1483 | NetCDF_var_endian(VALUE Var) | |
1484 | { | |
1485 | int ncid, varid, status; | |
1486 | struct NetCDFVar *Netcdf_var; | |
1487 | int endian; | |
1488 | ||
1489 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1490 | ncid = Netcdf_var->ncid; | |
1491 | varid = Netcdf_var->varid; | |
1492 | status = nc_inq_var_endian(ncid, varid, &endian); | |
1493 | if(status != NC_NOERR) NC_RAISE(status); | |
1494 | return(INT2FIX(endian)); | |
1495 | } | |
1496 | ||
1497 | #endif | |
1498 | ||
1499 | VALUE | |
1500 | NetCDF_var_id2att(VALUE Var,VALUE attnum) | |
1501 | { | |
1502 | int ncid; | |
1503 | int c_attnum; | |
1504 | int status; | |
1505 | int c_varid; | |
1506 | struct NetCDFVar *Netcdf_var; | |
1507 | struct NetCDFAtt *Netcdf_att; | |
1508 | char *c_att_name; | |
1509 | VALUE Att; | |
1510 | ||
1511 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1512 | ncid=Netcdf_var->ncid; | |
1513 | c_varid=Netcdf_var->varid; | |
1514 | ||
1515 | Check_Type(attnum,T_FIXNUM); | |
1516 | c_attnum=NUM2INT(attnum); | |
1517 | ||
1518 | c_att_name=ALLOCA_N(char,NC_MAX_NAME); | |
1519 | ||
1520 | status = nc_inq_attname(ncid,c_varid,c_attnum,c_att_name); | |
1521 | if(status != NC_NOERR) NC_RAISE(status); | |
1522 | ||
1523 | Netcdf_att=NetCDF_att_init(ncid,c_varid,c_att_name); | |
1524 | Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
1525 | return(Att); | |
1526 | } | |
1527 | ||
1528 | VALUE | |
1529 | NetCDF_var_dims(VALUE Var) | |
1530 | { | |
1531 | int ncid, *dimids, ndims, varid, i, status; | |
1532 | struct NetCDFVar *Netcdf_var; | |
1533 | struct NetCDFDim *Netcdf_dim; | |
1534 | VALUE Dims; | |
1535 | ||
1536 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1537 | ncid = Netcdf_var->ncid; | |
1538 | varid = Netcdf_var->varid; | |
1539 | status = nc_inq_varndims(ncid,varid,&ndims); | |
1540 | if(status != NC_NOERR) NC_RAISE(status); | |
1541 | dimids=ALLOCA_N(int,ndims); | |
1542 | status = nc_inq_vardimid(ncid,varid,dimids); | |
1543 | if(status != NC_NOERR) NC_RAISE(status); | |
1544 | Dims = rb_ary_new(); | |
1545 | for(i=0;i<ndims;i++){ | |
1546 | Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-i]); | |
1547 | rb_ary_push(Dims, | |
1548 | Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim)); | |
1549 | } | |
1550 | return(Dims); | |
1551 | } | |
1552 | ||
1553 | VALUE | |
1554 | NetCDF_var_dim(VALUE Var, VALUE ith) | |
1555 | { | |
1556 | int ncid, *dimids, ndims, varid, status, c_ith; | |
1557 | struct NetCDFVar *Netcdf_var; | |
1558 | struct NetCDFDim *Netcdf_dim; | |
1559 | VALUE Dim; | |
1560 | ||
1561 | Check_Type(ith,T_FIXNUM); | |
1562 | c_ith=NUM2INT(ith); | |
1563 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1564 | ncid = Netcdf_var->ncid; | |
1565 | varid = Netcdf_var->varid; | |
1566 | status = nc_inq_varndims(ncid,varid,&ndims); | |
1567 | if(status != NC_NOERR) NC_RAISE(status); | |
1568 | if(c_ith < 0 || c_ith >= ndims) { | |
1569 | rb_raise(rb_eNetcdfError, "dimension count less than zero or greater than ndims-1"); | |
1570 | } | |
1571 | dimids=ALLOCA_N(int,ndims); | |
1572 | status = nc_inq_vardimid(ncid,varid,dimids); | |
1573 | if(status != NC_NOERR) NC_RAISE(status); | |
1574 | Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-c_ith]); | |
1575 | Dim = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
1576 | return(Dim); | |
1577 | } | |
1578 | ||
1579 | VALUE | |
1580 | NetCDF_att_copy(VALUE Att,VALUE Var_or_File) | |
1581 | { | |
1582 | int ncid_in,ncid_out; | |
1583 | int status; | |
1584 | int varid_in,varid_out; | |
1585 | char *att_name; | |
1586 | struct NetCDFAtt *Netcdf_att; | |
1587 | struct NetCDFVar *Netcdf_var; | |
1588 | struct Netcdf *ncfile; | |
1589 | struct NetCDFAtt *Netcdf_att_out; | |
1590 | ||
1591 | rb_secure(3); | |
1592 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1593 | ncid_in=Netcdf_att->ncid; | |
1594 | varid_in=Netcdf_att->varid; | |
1595 | att_name=Netcdf_att->name; | |
1596 | ||
1597 | if( rb_obj_is_kind_of(Var_or_File, cNetCDFVar) ){ | |
1598 | Data_Get_Struct(Var_or_File,struct NetCDFVar, Netcdf_var); | |
1599 | ncid_out=Netcdf_var->ncid; | |
1600 | varid_out=Netcdf_var->varid; | |
1601 | } else if ( rb_obj_is_kind_of(Var_or_File, cNetCDF) ){ | |
1602 | Data_Get_Struct(Var_or_File,struct Netcdf, ncfile); | |
1603 | ncid_out=ncfile->ncid; | |
1604 | varid_out=NC_GLOBAL; | |
1605 | } else { | |
1606 | rb_raise(rb_eNetcdfError,"The argument must be a NetCDFVar or a NetCDF"); | |
1607 | } | |
1608 | ||
1609 | status = nc_copy_att(ncid_in,varid_in,att_name,ncid_out,varid_out); | |
1610 | if(status != NC_NOERR) NC_RAISE(status); | |
1611 | Netcdf_att_out = NetCDF_att_init(ncid_out,varid_out,att_name); | |
1612 | return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att_out)); | |
1613 | } | |
1614 | ||
1615 | VALUE | |
1616 | NetCDF_att_atttype(VALUE Att) | |
1617 | { | |
1618 | int ncid; | |
1619 | int varid; | |
1620 | int status; | |
1621 | char *att_name; | |
1622 | const char *Attname; | |
1623 | struct NetCDFAtt *Netcdf_att; | |
1624 | nc_type xtypep; | |
1625 | ||
1626 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1627 | ncid = Netcdf_att->ncid; | |
1628 | varid = Netcdf_att->varid; | |
1629 | att_name = Netcdf_att->name; | |
1630 | ||
1631 | status = nc_inq_atttype(ncid,varid,att_name,&xtypep); | |
1632 | if(status != NC_NOERR) NC_RAISE(status); | |
1633 | ||
1634 | Attname = nctype2natype(xtypep); | |
1635 | return(rb_str_new2(Attname)); | |
1636 | } | |
1637 | ||
1638 | VALUE | |
1639 | NetCDF_att_typecode(VALUE Att) | |
1640 | { | |
1641 | int ncid; | |
1642 | int varid; | |
1643 | int status; | |
1644 | char *att_name; | |
1645 | struct NetCDFAtt *Netcdf_att; | |
1646 | nc_type xtypep; | |
1647 | ||
1648 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1649 | ncid = Netcdf_att->ncid; | |
1650 | varid = Netcdf_att->varid; | |
1651 | att_name = Netcdf_att->name; | |
1652 | ||
1653 | status = nc_inq_atttype(ncid,varid,att_name,&xtypep); | |
1654 | if(status != NC_NOERR) NC_RAISE(status); | |
1655 | ||
1656 | return(INT2NUM(nctype2natypecode(xtypep))); | |
1657 | } | |
1658 | ||
1659 | VALUE | |
1660 | NetCDF_att_delete(VALUE Att) | |
1661 | { | |
1662 | int ncid; | |
1663 | int status; | |
1664 | int varid; | |
1665 | char *c_att_name; | |
1666 | struct NetCDFAtt *Netcdf_att; | |
1667 | ||
1668 | rb_secure(3); | |
1669 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1670 | ||
1671 | ncid=Netcdf_att->ncid; | |
1672 | varid=Netcdf_att->varid; | |
1673 | c_att_name=Netcdf_att->name; | |
1674 | ||
1675 | status = nc_del_att(ncid,varid,c_att_name); | |
1676 | if(status != NC_NOERR) NC_RAISE(status); | |
1677 | ||
1678 | return Qnil; | |
1679 | } | |
1680 | ||
1681 | VALUE | |
1682 | NetCDF_att_put(VALUE Att,VALUE value,VALUE atttype) | |
1683 | /* | |
1684 | * atttype: nil or a String ("string","int",etc). If nil, | |
1685 | * the type of attribute is determined from the type of value | |
1686 | */ | |
1687 | { | |
1688 | struct NetCDFAtt *ncatt; | |
1689 | ||
1690 | rb_secure(3); | |
1691 | Data_Get_Struct(Att,struct NetCDFAtt,ncatt); | |
1692 | return( NetCDF_put_att__(ncatt->ncid, ncatt->name, value, | |
1693 | atttype, ncatt->varid) ); | |
1694 | } | |
1695 | ||
1696 | VALUE | |
1697 | NetCDF_att_get(VALUE Att) | |
1698 | { | |
1699 | int ncid; | |
1700 | int varid; | |
1701 | char *c_attname; | |
1702 | int status; | |
1703 | struct NetCDFAtt *Netcdf_att; | |
1704 | nc_type xtypep; | |
1705 | size_t lenp; | |
1706 | na_shape_t attlen[1]; /* NArray uses int instead of size_t */ | |
1707 | char *tp; | |
1708 | unsigned char *up; | |
1709 | short *sp; | |
1710 | int *ip; | |
1711 | float *fp; | |
1712 | double *dp; | |
1713 | VALUE NArray; | |
1714 | VALUE str; | |
1715 | ||
1716 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1717 | ncid = Netcdf_att->ncid; | |
1718 | varid = Netcdf_att->varid; | |
1719 | c_attname = Netcdf_att->name; | |
1720 | ||
1721 | status = nc_inq_atttype(ncid,varid,c_attname,&xtypep); | |
1722 | if(status != NC_NOERR) NC_RAISE(status); | |
1723 | ||
1724 | switch(xtypep){ | |
1725 | case NC_CHAR: | |
1726 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1727 | if(status != NC_NOERR) NC_RAISE(status); | |
1728 | tp = ALLOCA_N(char,lenp+1); | |
1729 | tp[lenp]= '\0'; | |
1730 | status = nc_get_att_text(ncid,varid,c_attname,tp); | |
1731 | if(status != NC_NOERR) NC_RAISE(status); | |
1732 | str = rb_str_new2(tp); | |
1733 | OBJ_TAINT(str); | |
1734 | return(str); | |
1735 | break; | |
1736 | case NC_BYTE: | |
1737 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1738 | if(status != NC_NOERR) NC_RAISE(status); | |
1739 | ||
1740 | attlen[0]=lenp; | |
1741 | Cbyte_to_NArray(NArray,1,attlen,up); | |
1742 | ||
1743 | status = nc_get_att_uchar(ncid,varid,c_attname,up); | |
1744 | if(status != NC_NOERR) NC_RAISE(status); | |
1745 | ||
1746 | OBJ_TAINT(NArray); | |
1747 | return NArray; | |
1748 | break; | |
1749 | case NC_SHORT: | |
1750 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1751 | if(status != NC_NOERR) NC_RAISE(status); | |
1752 | ||
1753 | attlen[0]=lenp; | |
1754 | Csint_to_NArray(NArray,1,attlen,sp); | |
1755 | ||
1756 | status = nc_get_att_short(ncid,varid,c_attname,sp); | |
1757 | if(status != NC_NOERR) NC_RAISE(status); | |
1758 | OBJ_TAINT(NArray); | |
1759 | return NArray; | |
1760 | break; | |
1761 | case NC_INT: | |
1762 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1763 | if(status != NC_NOERR) NC_RAISE(status); | |
1764 | ||
1765 | attlen[0]=lenp; | |
1766 | Clint_to_NArray(NArray,1,attlen,ip); | |
1767 | ||
1768 | status = nc_get_att_int(ncid,varid,c_attname,ip); | |
1769 | if(status != NC_NOERR) NC_RAISE(status); | |
1770 | ||
1771 | OBJ_TAINT(NArray); | |
1772 | return NArray; | |
1773 | break; | |
1774 | case NC_FLOAT: | |
1775 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1776 | if(status != NC_NOERR) NC_RAISE(status); | |
1777 | ||
1778 | attlen[0]=lenp; | |
1779 | Cfloat_to_NArray(NArray,1,attlen,fp); | |
1780 | ||
1781 | status = nc_get_att_float(ncid,varid,c_attname,fp); | |
1782 | if(status != NC_NOERR) NC_RAISE(status); | |
1783 | ||
1784 | OBJ_TAINT(NArray); | |
1785 | return NArray; | |
1786 | break; | |
1787 | case NC_DOUBLE: | |
1788 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1789 | if(status != NC_NOERR) NC_RAISE(status); | |
1790 | ||
1791 | attlen[0]=lenp; | |
1792 | Cdouble_to_NArray(NArray,1,attlen,dp); | |
1793 | ||
1794 | status = nc_get_att_double(ncid,varid,c_attname,dp); | |
1795 | if(status != NC_NOERR) NC_RAISE(status); | |
1796 | OBJ_TAINT(NArray); | |
1797 | return NArray; | |
1798 | break; | |
1799 | default: | |
1800 | rb_raise(rb_eNetcdfError,"atttype isn't supported in netCDF"); | |
1801 | } | |
1802 | return Qnil; | |
1803 | } | |
1804 | ||
1805 | ||
1806 | VALUE | |
1807 | NetCDF_var_inq_name(VALUE Var) | |
1808 | { | |
1809 | int ncid; | |
1810 | int status; | |
1811 | int varid; | |
1812 | char c_var_name[NC_MAX_NAME]; | |
1813 | struct NetCDFVar *Netcdf_var; | |
1814 | VALUE Var_name; | |
1815 | ||
1816 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1817 | ||
1818 | ncid=Netcdf_var->ncid; | |
1819 | varid=Netcdf_var->varid; | |
1820 | status = nc_inq_varname(ncid,varid,c_var_name); | |
1821 | if(status != NC_NOERR) NC_RAISE(status); | |
1822 | ||
1823 | Var_name=rb_str_new2(c_var_name); | |
1824 | OBJ_TAINT(Var_name); | |
1825 | return Var_name; | |
1826 | } | |
1827 | ||
1828 | VALUE | |
1829 | NetCDF_var_ndims(VALUE Var) | |
1830 | { | |
1831 | int ncid; | |
1832 | int status; | |
1833 | int varid; | |
1834 | int ndimsp; | |
1835 | struct NetCDFVar *Netcdf_var; | |
1836 | VALUE Var_ndims; | |
1837 | ||
1838 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1839 | ||
1840 | ncid=Netcdf_var->ncid; | |
1841 | varid=Netcdf_var->varid; | |
1842 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
1843 | if(status != NC_NOERR) NC_RAISE(status); | |
1844 | Var_ndims=INT2FIX(ndimsp); | |
1845 | return Var_ndims; | |
1846 | } | |
1847 | ||
1848 | VALUE | |
1849 | NetCDF_var_vartype(VALUE Var) | |
1850 | { | |
1851 | int ncid; | |
1852 | int status; | |
1853 | int varid; | |
1854 | nc_type xtypep; | |
1855 | struct NetCDFVar *Netcdf_var; | |
1856 | const char *Vartype; | |
1857 | ||
1858 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1859 | ||
1860 | ncid=Netcdf_var->ncid; | |
1861 | varid=Netcdf_var->varid; | |
1862 | ||
1863 | status = nc_inq_vartype(ncid,varid,&xtypep); | |
1864 | if(status != NC_NOERR) NC_RAISE(status); | |
1865 | ||
1866 | Vartype=nctype2natype(xtypep); | |
1867 | return(rb_str_new2(Vartype)); | |
1868 | } | |
1869 | ||
1870 | VALUE | |
1871 | NetCDF_var_typecode(VALUE Var) | |
1872 | { | |
1873 | int ncid; | |
1874 | int status; | |
1875 | int varid; | |
1876 | nc_type xtypep; | |
1877 | struct NetCDFVar *Netcdf_var; | |
1878 | ||
1879 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1880 | ||
1881 | ncid=Netcdf_var->ncid; | |
1882 | varid=Netcdf_var->varid; | |
1883 | ||
1884 | status = nc_inq_vartype(ncid,varid,&xtypep); | |
1885 | if(status != NC_NOERR) NC_RAISE(status); | |
1886 | ||
1887 | return(INT2NUM(nctype2natypecode(xtypep))); | |
1888 | } | |
1889 | ||
1890 | ||
1891 | VALUE | |
1892 | NetCDF_var_natts(VALUE Var) | |
1893 | { | |
1894 | int ncid; | |
1895 | int status; | |
1896 | int varid; | |
1897 | int nattsp; | |
1898 | struct NetCDFVar *Netcdf_var; | |
1899 | VALUE Var_natts; | |
1900 | ||
1901 | ||
1902 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1903 | ||
1904 | ncid=Netcdf_var->ncid; | |
1905 | varid=Netcdf_var->varid; | |
1906 | ||
1907 | status= nc_inq_varnatts(ncid,varid,&nattsp); | |
1908 | if(status !=NC_NOERR) NC_RAISE(status); | |
1909 | ||
1910 | Var_natts=INT2FIX(nattsp); | |
1911 | return Var_natts; | |
1912 | } | |
1913 | ||
1914 | VALUE | |
1915 | NetCDF_var_file(VALUE Var) | |
1916 | { | |
1917 | struct NetCDFVar *Netcdf_var; | |
1918 | /* VALUE file; */ | |
1919 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1920 | ||
1921 | return (Netcdf_var->file); | |
1922 | } | |
1923 | ||
1924 | VALUE | |
1925 | NetCDF_var_rename(VALUE Var,VALUE var_new_name) | |
1926 | { | |
1927 | int ncid; | |
1928 | int status; | |
1929 | int varid; | |
1930 | char *c_var_new_name; | |
1931 | struct NetCDFVar *Netcdf_var; | |
1932 | ||
1933 | rb_secure(3); | |
1934 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1935 | ncid=Netcdf_var->ncid; | |
1936 | varid=Netcdf_var->varid; | |
1937 | ||
1938 | Check_Type(var_new_name,T_STRING); | |
1939 | c_var_new_name=StringValueCStr(var_new_name); | |
1940 | ||
1941 | status = nc_rename_var(ncid,varid,c_var_new_name); | |
1942 | if(status !=NC_NOERR) NC_RAISE(status); | |
1943 | ||
1944 | return Qnil; | |
1945 | } | |
1946 | ||
1947 | VALUE | |
1948 | NetCDF_var_att(VALUE Var,VALUE att_name) | |
1949 | { | |
1950 | int ncid; | |
1951 | int status; | |
1952 | int varid; | |
1953 | char *c_att_name; | |
1954 | int c_attnump; | |
1955 | struct NetCDFVar *Netcdf_var; | |
1956 | struct NetCDFAtt *Netcdf_att; | |
1957 | VALUE Att; | |
1958 | ||
1959 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1960 | ||
1961 | ncid=Netcdf_var->ncid; | |
1962 | varid=Netcdf_var->varid; | |
1963 | ||
1964 | Check_Type(att_name,T_STRING); | |
1965 | c_att_name=StringValueCStr(att_name); | |
1966 | ||
1967 | status = nc_inq_attid(ncid,varid,c_att_name,&c_attnump); | |
1968 | if(status == NC_NOERR){ | |
1969 | Netcdf_att=NetCDF_att_init(ncid,varid,c_att_name); | |
1970 | Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
1971 | return Att; | |
1972 | } | |
1973 | else if(status == NC_ENOTATT){ | |
1974 | return Qnil; | |
1975 | } | |
1976 | else{ | |
1977 | NC_RAISE(status); | |
1978 | return Qnil; | |
1979 | } | |
1980 | } | |
1981 | ||
1982 | /* Redifinition of the "==" and "eql?" methods */ | |
1983 | ||
1984 | VALUE | |
1985 | NetCDF_eql(VALUE filea,VALUE fileb) | |
1986 | { | |
1987 | struct Netcdf *ncfilea; | |
1988 | struct Netcdf *ncfileb; | |
1989 | ||
1990 | if( rb_obj_is_kind_of(fileb, cNetCDF) ){ | |
1991 | Data_Get_Struct(filea,struct Netcdf,ncfilea); | |
1992 | Data_Get_Struct(fileb,struct Netcdf,ncfileb); | |
1993 | ||
1994 | if(ncfilea->ncid == ncfileb->ncid && | |
1995 | strcmp(ncfilea->name,ncfileb->name)==0){ | |
1996 | return Qtrue; | |
1997 | } else { | |
1998 | return Qfalse; | |
1999 | } | |
2000 | } else { | |
2001 | return Qfalse; | |
2002 | } | |
2003 | } | |
2004 | ||
2005 | VALUE | |
2006 | NetCDF_var_eql(VALUE Vara,VALUE Varb) | |
2007 | { | |
2008 | struct NetCDFVar *Netcdf_vara; | |
2009 | struct NetCDFVar *Netcdf_varb; | |
2010 | ||
2011 | if( rb_obj_is_kind_of(Varb, cNetCDFVar) ){ | |
2012 | Data_Get_Struct(Vara,struct NetCDFVar,Netcdf_vara); | |
2013 | Data_Get_Struct(Varb,struct NetCDFVar,Netcdf_varb); | |
2014 | ||
2015 | if(Netcdf_vara->ncid == Netcdf_varb->ncid && | |
2016 | Netcdf_vara->varid == Netcdf_varb->varid){ | |
2017 | return Qtrue; | |
2018 | } else { | |
2019 | return Qfalse; | |
2020 | } | |
2021 | } else { | |
2022 | return Qfalse; | |
2023 | } | |
2024 | } | |
2025 | ||
2026 | VALUE | |
2027 | NetCDF_dim_eql(VALUE Dima,VALUE Dimb) | |
2028 | { | |
2029 | struct NetCDFDim *Netcdf_dima; | |
2030 | struct NetCDFDim *Netcdf_dimb; | |
2031 | ||
2032 | if( rb_obj_is_kind_of(Dimb, cNetCDFDim) ){ | |
2033 | Data_Get_Struct(Dima,struct NetCDFDim,Netcdf_dima); | |
2034 | Data_Get_Struct(Dimb,struct NetCDFDim,Netcdf_dimb); | |
2035 | ||
2036 | if(Netcdf_dima->ncid == Netcdf_dimb->ncid && | |
2037 | Netcdf_dima->dimid == Netcdf_dimb->dimid){ | |
2038 | return Qtrue; | |
2039 | } else { | |
2040 | return Qfalse; | |
2041 | } | |
2042 | } else { | |
2043 | return Qfalse; | |
2044 | } | |
2045 | } | |
2046 | ||
2047 | VALUE | |
2048 | NetCDF_att_eql(VALUE Atta,VALUE Attb) | |
2049 | { | |
2050 | struct NetCDFAtt *Netcdf_atta; | |
2051 | struct NetCDFAtt *Netcdf_attb; | |
2052 | ||
2053 | if( rb_obj_is_kind_of(Attb, cNetCDFAtt) ){ | |
2054 | Data_Get_Struct(Atta,struct NetCDFAtt,Netcdf_atta); | |
2055 | Data_Get_Struct(Attb,struct NetCDFAtt,Netcdf_attb); | |
2056 | ||
2057 | if(Netcdf_atta->ncid == Netcdf_atta->ncid && | |
2058 | Netcdf_atta->varid == Netcdf_attb->varid && | |
2059 | strcmp(Netcdf_atta->name,Netcdf_attb->name)==0){ | |
2060 | return Qtrue; | |
2061 | } else { | |
2062 | return Qfalse; | |
2063 | } | |
2064 | } else { | |
2065 | return Qfalse; | |
2066 | } | |
2067 | } | |
2068 | ||
2069 | /* Follow methods is to connect "NArray" with "Netcdf" */ | |
2070 | VALUE | |
2071 | NetCDF_get_var_char(VALUE Var) | |
2072 | { | |
2073 | int ncid; | |
2074 | int varid; | |
2075 | int status; | |
2076 | unsigned char *ptr; | |
2077 | struct NetCDFVar *Netcdf_var; | |
2078 | int i=0; | |
2079 | int ndimsp; | |
2080 | int *dimids; | |
2081 | size_t lengthp; | |
2082 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2083 | VALUE NArray; | |
2084 | ||
2085 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2086 | ncid = Netcdf_var->ncid; | |
2087 | varid = Netcdf_var->varid; | |
2088 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2089 | if(status != NC_NOERR) NC_RAISE(status); | |
2090 | dimids = ALLOCA_N(int,ndimsp); | |
2091 | if (ndimsp != 0){ | |
2092 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2093 | for(i=0;i<ndimsp;i++){ | |
2094 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2095 | if(status != NC_NOERR) NC_RAISE(status); | |
2096 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2097 | shape[ndimsp-1-i]=lengthp; | |
2098 | } | |
2099 | } else { | |
2100 | ndimsp = 1; | |
2101 | shape = ALLOCA_N(na_shape_t,1); | |
2102 | shape[0]=1; | |
2103 | } | |
2104 | ||
2105 | Cbyte_to_NArray(NArray,ndimsp,shape,ptr); | |
2106 | ||
2107 | status = nc_get_var_text(ncid,varid,(char *)ptr); | |
2108 | if(status != NC_NOERR) NC_RAISE(status); | |
2109 | ||
2110 | OBJ_TAINT(NArray); | |
2111 | return NArray; | |
2112 | } | |
2113 | ||
2114 | VALUE | |
2115 | NetCDF_get_var_byte(VALUE Var) | |
2116 | { | |
2117 | int ncid; | |
2118 | int varid; | |
2119 | int status; | |
2120 | unsigned char *ptr; | |
2121 | struct NetCDFVar *Netcdf_var; | |
2122 | int i=0; | |
2123 | int ndimsp; | |
2124 | int *dimids; | |
2125 | size_t lengthp; | |
2126 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2127 | VALUE NArray; | |
2128 | ||
2129 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2130 | ncid = Netcdf_var->ncid; | |
2131 | varid = Netcdf_var->varid; | |
2132 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2133 | if(status != NC_NOERR) NC_RAISE(status); | |
2134 | dimids = ALLOCA_N(int,ndimsp); | |
2135 | if (ndimsp != 0){ | |
2136 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2137 | for(i=0;i<ndimsp;i++){ | |
2138 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2139 | if(status != NC_NOERR) NC_RAISE(status); | |
2140 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2141 | shape[ndimsp-1-i]=lengthp; | |
2142 | } | |
2143 | } else { | |
2144 | ndimsp = 1; | |
2145 | shape = ALLOCA_N(na_shape_t,1); | |
2146 | shape[0]=1; | |
2147 | } | |
2148 | ||
2149 | Cbyte_to_NArray(NArray,ndimsp,shape,ptr); | |
2150 | ||
2151 | status = nc_get_var_uchar(ncid,varid,ptr); | |
2152 | if(status != NC_NOERR) NC_RAISE(status); | |
2153 | ||
2154 | OBJ_TAINT(NArray); | |
2155 | return NArray; | |
2156 | } | |
2157 | ||
2158 | VALUE | |
2159 | NetCDF_get_var_sint(VALUE Var) | |
2160 | { | |
2161 | int ncid; | |
2162 | int varid; | |
2163 | int status; | |
2164 | short *ptr; | |
2165 | struct NetCDFVar *Netcdf_var; | |
2166 | int i=0; | |
2167 | int ndimsp; | |
2168 | int *dimids; | |
2169 | size_t lengthp; | |
2170 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2171 | VALUE NArray; | |
2172 | ||
2173 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2174 | ncid = Netcdf_var->ncid; | |
2175 | varid = Netcdf_var->varid; | |
2176 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2177 | if(status != NC_NOERR) NC_RAISE(status); | |
2178 | dimids = ALLOCA_N(int,ndimsp); | |
2179 | if (ndimsp != 0){ | |
2180 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2181 | for(i=0;i<ndimsp;i++){ | |
2182 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2183 | if(status != NC_NOERR) NC_RAISE(status); | |
2184 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2185 | shape[ndimsp-1-i]=lengthp; | |
2186 | } | |
2187 | } else { | |
2188 | ndimsp = 1; | |
2189 | shape = ALLOCA_N(na_shape_t,1); | |
2190 | shape[0]=1; | |
2191 | } | |
2192 | ||
2193 | Csint_to_NArray(NArray,ndimsp,shape,ptr); | |
2194 | ||
2195 | status = nc_get_var_short(ncid,varid,ptr); | |
2196 | if(status != NC_NOERR) NC_RAISE(status); | |
2197 | ||
2198 | OBJ_TAINT(NArray); | |
2199 | return NArray; | |
2200 | } | |
2201 | ||
2202 | VALUE | |
2203 | NetCDF_get_var_int(VALUE Var) | |
2204 | { | |
2205 | int ncid; | |
2206 | int varid; | |
2207 | int status; | |
2208 | int *ptr; | |
2209 | struct NetCDFVar *Netcdf_var; | |
2210 | int i=0; | |
2211 | int ndimsp; | |
2212 | int *dimids; | |
2213 | size_t lengthp; | |
2214 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2215 | VALUE NArray; | |
2216 | ||
2217 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2218 | ncid = Netcdf_var->ncid; | |
2219 | varid = Netcdf_var->varid; | |
2220 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2221 | if(status != NC_NOERR) NC_RAISE(status); | |
2222 | dimids = ALLOCA_N(int,ndimsp); | |
2223 | if (ndimsp != 0){ | |
2224 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2225 | for(i=0;i<ndimsp;i++){ | |
2226 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2227 | if(status != NC_NOERR) NC_RAISE(status); | |
2228 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2229 | shape[ndimsp-1-i]=lengthp; | |
2230 | } | |
2231 | } else { | |
2232 | ndimsp = 1; | |
2233 | shape = ALLOCA_N(na_shape_t,1); | |
2234 | shape[0]=1; | |
2235 | } | |
2236 | ||
2237 | Clint_to_NArray(NArray,ndimsp,shape,ptr); | |
2238 | ||
2239 | status = nc_get_var_int(ncid,varid,ptr); | |
2240 | if(status != NC_NOERR) NC_RAISE(status); | |
2241 | ||
2242 | OBJ_TAINT(NArray); | |
2243 | return NArray; | |
2244 | } | |
2245 | ||
2246 | VALUE | |
2247 | NetCDF_get_var_float(VALUE Var) | |
2248 | { | |
2249 | int ncid; | |
2250 | int varid; | |
2251 | int status; | |
2252 | float *ptr; | |
2253 | struct NetCDFVar *Netcdf_var; | |
2254 | int i=0; | |
2255 | int ndimsp; | |
2256 | int *dimids; | |
2257 | size_t lengthp; | |
2258 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2259 | VALUE NArray; | |
2260 | ||
2261 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2262 | ncid = Netcdf_var->ncid; | |
2263 | varid = Netcdf_var->varid; | |
2264 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2265 | if(status != NC_NOERR) NC_RAISE(status); | |
2266 | dimids = ALLOCA_N(int,ndimsp); | |
2267 | if (ndimsp != 0){ | |
2268 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2269 | for(i=0;i<ndimsp;i++){ | |
2270 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2271 | if(status != NC_NOERR) NC_RAISE(status); | |
2272 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2273 | shape[ndimsp-1-i]=lengthp; | |
2274 | } | |
2275 | } else { | |
2276 | ndimsp = 1; | |
2277 | shape = ALLOCA_N(na_shape_t,1); | |
2278 | shape[0]=1; | |
2279 | } | |
2280 | ||
2281 | Cfloat_to_NArray(NArray,ndimsp,shape,ptr); | |
2282 | ||
2283 | status = nc_get_var_float(ncid,varid,ptr); | |
2284 | if(status != NC_NOERR) NC_RAISE(status); | |
2285 | ||
2286 | OBJ_TAINT(NArray); | |
2287 | return NArray; | |
2288 | } | |
2289 | ||
2290 | VALUE | |
2291 | NetCDF_get_var_double(VALUE Var) | |
2292 | { | |
2293 | int ncid; | |
2294 | int varid; | |
2295 | int status; | |
2296 | double *ptr; | |
2297 | struct NetCDFVar *Netcdf_var; | |
2298 | int i=0; | |
2299 | int ndimsp; | |
2300 | int *dimids; | |
2301 | size_t lengthp; | |
2302 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2303 | VALUE NArray; | |
2304 | ||
2305 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2306 | ncid = Netcdf_var->ncid; | |
2307 | varid = Netcdf_var->varid; | |
2308 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2309 | if(status != NC_NOERR) NC_RAISE(status); | |
2310 | dimids = ALLOCA_N(int,ndimsp); | |
2311 | if (ndimsp != 0){ | |
2312 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2313 | for(i=0;i<ndimsp;i++){ | |
2314 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2315 | if(status != NC_NOERR) NC_RAISE(status); | |
2316 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2317 | shape[ndimsp-1-i]=lengthp; | |
2318 | } | |
2319 | } else { | |
2320 | ndimsp = 1; | |
2321 | shape = ALLOCA_N(na_shape_t,1); | |
2322 | shape[0]=1; | |
2323 | } | |
2324 | ||
2325 | Cdouble_to_NArray(NArray,ndimsp,shape,ptr); | |
2326 | ||
2327 | status = nc_get_var_double(ncid,varid,ptr); | |
2328 | if(status != NC_NOERR) NC_RAISE(status); | |
2329 | ||
2330 | OBJ_TAINT(NArray); | |
2331 | return NArray; | |
2332 | } | |
2333 | ||
2334 | VALUE | |
2335 | NetCDF_get_var1_char(VALUE Var,VALUE start) | |
2336 | { | |
2337 | int ncid; | |
2338 | int varid; | |
2339 | int status; | |
2340 | unsigned char *ptr; | |
2341 | int i; | |
2342 | struct NetCDFVar *Netcdf_var; | |
2343 | na_shape_t l_start; | |
2344 | size_t *c_start; | |
2345 | int ndims; | |
2346 | int dimids[NC_MAX_DIMS]; | |
2347 | size_t dimlen; | |
2348 | na_shape_t *c_count; | |
2349 | VALUE NArray; | |
2350 | ||
2351 | ||
2352 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2353 | ncid = Netcdf_var->ncid; | |
2354 | varid = Netcdf_var->varid; | |
2355 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2356 | if(status != NC_NOERR)NC_RAISE(status); | |
2357 | if(ndims == 0) { | |
2358 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2359 | } | |
2360 | ||
2361 | Check_Type(start,T_ARRAY); | |
2362 | if(RARRAY_LEN(start) < ndims) { | |
2363 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2364 | } | |
2365 | ||
2366 | c_start=ALLOCA_N(size_t,ndims); | |
2367 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2368 | for(i=0;i<ndims;i++){ | |
2369 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2370 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2371 | if(status != NC_NOERR) NC_RAISE(status); | |
2372 | if(l_start < 0) { | |
2373 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2374 | if(status != NC_NOERR) NC_RAISE(status); | |
2375 | l_start += dimlen; | |
2376 | } | |
2377 | c_start[i]=l_start; | |
2378 | ||
2379 | c_count[i]=1; | |
2380 | } | |
2381 | ||
2382 | ||
2383 | ||
2384 | ||
2385 | Cbyte_to_NArray(NArray,ndims,c_count,ptr); | |
2386 | status = nc_get_var1_text(ncid,varid,c_start,(char *)ptr); | |
2387 | if(status != NC_NOERR) NC_RAISE(status); | |
2388 | ||
2389 | OBJ_TAINT(NArray); | |
2390 | return NArray; | |
2391 | ||
2392 | } | |
2393 | ||
2394 | VALUE | |
2395 | NetCDF_get_var1_byte(VALUE Var,VALUE start) | |
2396 | { | |
2397 | int ncid; | |
2398 | int varid; | |
2399 | int status; | |
2400 | unsigned char *ptr; | |
2401 | int i; | |
2402 | struct NetCDFVar *Netcdf_var; | |
2403 | na_shape_t l_start; | |
2404 | size_t *c_start; | |
2405 | int ndims; | |
2406 | int dimids[NC_MAX_DIMS]; | |
2407 | size_t dimlen; | |
2408 | na_shape_t *c_count; | |
2409 | VALUE NArray; | |
2410 | ||
2411 | ||
2412 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2413 | ncid = Netcdf_var->ncid; | |
2414 | varid = Netcdf_var->varid; | |
2415 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2416 | if(status != NC_NOERR)NC_RAISE(status); | |
2417 | if(ndims == 0) { | |
2418 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2419 | } | |
2420 | ||
2421 | Check_Type(start,T_ARRAY); | |
2422 | if(RARRAY_LEN(start) < ndims) { | |
2423 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2424 | } | |
2425 | ||
2426 | c_start=ALLOCA_N(size_t,ndims); | |
2427 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2428 | for(i=0;i<ndims;i++){ | |
2429 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2430 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2431 | if(status != NC_NOERR) NC_RAISE(status); | |
2432 | if(l_start < 0) { | |
2433 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2434 | if(status != NC_NOERR) NC_RAISE(status); | |
2435 | l_start += dimlen; | |
2436 | } | |
2437 | c_start[i]=l_start; | |
2438 | ||
2439 | c_count[i]=1; | |
2440 | } | |
2441 | ||
2442 | ||
2443 | ||
2444 | ||
2445 | Cbyte_to_NArray(NArray,ndims,c_count,ptr); | |
2446 | status = nc_get_var1_uchar(ncid,varid,c_start,ptr); | |
2447 | if(status != NC_NOERR) NC_RAISE(status); | |
2448 | ||
2449 | OBJ_TAINT(NArray); | |
2450 | return NArray; | |
2451 | ||
2452 | } | |
2453 | ||
2454 | VALUE | |
2455 | NetCDF_get_var1_sint(VALUE Var,VALUE start) | |
2456 | { | |
2457 | int ncid; | |
2458 | int varid; | |
2459 | int status; | |
2460 | short *ptr; | |
2461 | int i; | |
2462 | struct NetCDFVar *Netcdf_var; | |
2463 | na_shape_t l_start; | |
2464 | size_t *c_start; | |
2465 | int ndims; | |
2466 | int dimids[NC_MAX_DIMS]; | |
2467 | size_t dimlen; | |
2468 | na_shape_t *c_count; | |
2469 | VALUE NArray; | |
2470 | ||
2471 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2472 | ncid = Netcdf_var->ncid; | |
2473 | varid = Netcdf_var->varid; | |
2474 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2475 | if(status != NC_NOERR) NC_RAISE(status); | |
2476 | if(ndims == 0) { | |
2477 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2478 | } | |
2479 | ||
2480 | Check_Type(start,T_ARRAY); | |
2481 | if(RARRAY_LEN(start) < ndims) { | |
2482 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2483 | } | |
2484 | ||
2485 | c_start=ALLOCA_N(size_t,ndims); | |
2486 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2487 | for(i=0;i<ndims;i++){ | |
2488 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2489 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2490 | if(status != NC_NOERR) NC_RAISE(status); | |
2491 | if(l_start < 0) { | |
2492 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2493 | if(status != NC_NOERR) NC_RAISE(status); | |
2494 | l_start += dimlen; | |
2495 | } | |
2496 | c_start[i]=l_start; | |
2497 | c_count[i]=1; | |
2498 | } | |
2499 | ||
2500 | Csint_to_NArray(NArray,ndims,c_count,ptr); | |
2501 | ||
2502 | status = nc_get_var1_short(ncid,varid,c_start,ptr); | |
2503 | if(status != NC_NOERR) NC_RAISE(status); | |
2504 | ||
2505 | OBJ_TAINT(NArray); | |
2506 | return NArray; | |
2507 | ||
2508 | } | |
2509 | ||
2510 | VALUE | |
2511 | NetCDF_get_var1_int(VALUE Var,VALUE start) | |
2512 | { | |
2513 | int ncid; | |
2514 | int varid; | |
2515 | int status; | |
2516 | int *ptr; | |
2517 | int i; | |
2518 | struct NetCDFVar *Netcdf_var; | |
2519 | na_shape_t l_start; | |
2520 | size_t *c_start; | |
2521 | int ndims; | |
2522 | int dimids[NC_MAX_DIMS]; | |
2523 | size_t dimlen; | |
2524 | na_shape_t *c_count; | |
2525 | VALUE NArray; | |
2526 | ||
2527 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2528 | ncid = Netcdf_var->ncid; | |
2529 | varid = Netcdf_var->varid; | |
2530 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2531 | if(status != NC_NOERR)NC_RAISE(status); | |
2532 | if(ndims == 0) { | |
2533 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2534 | } | |
2535 | ||
2536 | Check_Type(start,T_ARRAY); | |
2537 | if(RARRAY_LEN(start) < ndims) { | |
2538 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2539 | } | |
2540 | ||
2541 | c_start=ALLOCA_N(size_t,ndims); | |
2542 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2543 | for(i=0;i<ndims;i++){ | |
2544 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2545 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2546 | if(status != NC_NOERR) NC_RAISE(status); | |
2547 | if(l_start < 0) { | |
2548 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2549 | if(status != NC_NOERR) NC_RAISE(status); | |
2550 | l_start += dimlen; | |
2551 | } | |
2552 | c_start[i]=l_start; | |
2553 | c_count[i]=1; | |
2554 | } | |
2555 | ||
2556 | Clint_to_NArray(NArray,ndims,c_count,ptr); | |
2557 | ||
2558 | status = nc_get_var1_int(ncid,varid,c_start,ptr); | |
2559 | if(status != NC_NOERR) NC_RAISE(status); | |
2560 | ||
2561 | OBJ_TAINT(NArray); | |
2562 | return NArray; | |
2563 | ||
2564 | } | |
2565 | ||
2566 | VALUE | |
2567 | NetCDF_get_var1_float(VALUE Var,VALUE start) | |
2568 | { | |
2569 | int ncid; | |
2570 | int varid; | |
2571 | int status; | |
2572 | float *ptr; | |
2573 | int i; | |
2574 | struct NetCDFVar *Netcdf_var; | |
2575 | na_shape_t l_start; | |
2576 | size_t *c_start; | |
2577 | int ndims; | |
2578 | int dimids[NC_MAX_DIMS]; | |
2579 | size_t dimlen; | |
2580 | na_shape_t *c_count; | |
2581 | VALUE NArray; | |
2582 | ||
2583 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2584 | ncid = Netcdf_var->ncid; | |
2585 | varid = Netcdf_var->varid; | |
2586 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2587 | if(status != NC_NOERR)NC_RAISE(status); | |
2588 | if(ndims == 0) { | |
2589 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2590 | } | |
2591 | ||
2592 | Check_Type(start,T_ARRAY); | |
2593 | if(RARRAY_LEN(start) < ndims) { | |
2594 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2595 | } | |
2596 | ||
2597 | c_start=ALLOCA_N(size_t,ndims); | |
2598 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2599 | for(i=0;i<ndims;i++){ | |
2600 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2601 | status = nc_inq_vardimid(ncid, varid, dimids); | |
2602 | if(status != NC_NOERR) NC_RAISE(status); | |
2603 | if(l_start < 0) { | |
2604 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2605 | if(status != NC_NOERR) NC_RAISE(status); | |
2606 | l_start += dimlen; | |
2607 | } | |
2608 | c_start[i]=l_start; | |
2609 | c_count[i]=1; | |
2610 | } | |
2611 | ||
2612 | Cfloat_to_NArray(NArray,ndims,c_count,ptr); | |
2613 | ||
2614 | status = nc_get_var1_float(ncid,varid,c_start,ptr); | |
2615 | if(status != NC_NOERR) NC_RAISE(status); | |
2616 | ||
2617 | OBJ_TAINT(NArray); | |
2618 | return NArray; | |
2619 | ||
2620 | } | |
2621 | ||
2622 | VALUE | |
2623 | NetCDF_get_var1_double(VALUE Var,VALUE start) | |
2624 | { | |
2625 | int ncid; | |
2626 | int varid; | |
2627 | int status; | |
2628 | double *ptr; | |
2629 | int i; | |
2630 | struct NetCDFVar *Netcdf_var; | |
2631 | na_shape_t l_start; | |
2632 | size_t *c_start; | |
2633 | int ndims; | |
2634 | int dimids[NC_MAX_DIMS]; | |
2635 | size_t dimlen; | |
2636 | na_shape_t *c_count; | |
2637 | VALUE NArray; | |
2638 | ||
2639 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2640 | ncid = Netcdf_var->ncid; | |
2641 | varid = Netcdf_var->varid; | |
2642 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2643 | if(status != NC_NOERR)NC_RAISE(status); | |
2644 | if(ndims == 0) { | |
2645 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2646 | } | |
2647 | ||
2648 | Check_Type(start,T_ARRAY); | |
2649 | if(RARRAY_LEN(start) < ndims) { | |
2650 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2651 | } | |
2652 | ||
2653 | c_start=ALLOCA_N(size_t,ndims); | |
2654 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2655 | for(i=0;i<ndims;i++){ | |
2656 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2657 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2658 | if(status !=NC_NOERR) NC_RAISE(status); | |
2659 | if(l_start < 0) { | |
2660 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2661 | if(status != NC_NOERR) NC_RAISE(status); | |
2662 | l_start += dimlen; | |
2663 | } | |
2664 | c_start[i]=l_start; | |
2665 | c_count[i]=1; | |
2666 | } | |
2667 | ||
2668 | Cdouble_to_NArray(NArray,ndims,c_count,ptr); | |
2669 | ||
2670 | status = nc_get_var1_double(ncid,varid,c_start,ptr); | |
2671 | if(status != NC_NOERR) NC_RAISE(status); | |
2672 | ||
2673 | OBJ_TAINT(NArray); | |
2674 | return NArray; | |
2675 | ||
2676 | } | |
2677 | ||
2678 | VALUE | |
2679 | NetCDF_get_vars_char(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2680 | { | |
2681 | int ncid; | |
2682 | int varid; | |
2683 | int status; | |
2684 | unsigned char *ptr; | |
2685 | int i; | |
2686 | struct NetCDFVar *Netcdf_var; | |
2687 | na_shape_t l_start, l_end; | |
2688 | size_t *c_start; | |
2689 | size_t *c_count; | |
2690 | ptrdiff_t *c_stride; | |
2691 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2692 | int ndims; | |
2693 | int *dimids; | |
2694 | size_t dimlen; | |
2695 | VALUE NArray; | |
2696 | ||
2697 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2698 | ncid = Netcdf_var->ncid; | |
2699 | varid = Netcdf_var->varid; | |
2700 | ||
2701 | status = nc_inq_varndims(ncid,varid,&ndims); | |
2702 | if(status != NC_NOERR) NC_RAISE(status); | |
2703 | if(ndims == 0) { | |
2704 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2705 | } | |
2706 | ||
2707 | dimids = ALLOCA_N(int,ndims); | |
2708 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2709 | if(status != NC_NOERR) NC_RAISE(status); | |
2710 | ||
2711 | Check_Type(start,T_ARRAY); | |
2712 | if(RARRAY_LEN(start) < ndims){ | |
2713 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
2714 | } | |
2715 | c_start = ALLOCA_N(size_t,ndims); | |
2716 | for(i=0; i<ndims; i++){ | |
2717 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2718 | ||
2719 | if(l_start < 0) { | |
2720 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
2721 | if(status != NC_NOERR) NC_RAISE(status); | |
2722 | l_start += dimlen; | |
2723 | } | |
2724 | c_start[i]=l_start; | |
2725 | } | |
2726 | ||
2727 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
2728 | switch(TYPE(stride)){ | |
2729 | case T_NIL: | |
2730 | for(i=0; i<ndims; i++){ | |
2731 | c_stride[i]=1; | |
2732 | } | |
2733 | break; | |
2734 | default: | |
2735 | Check_Type(stride,T_ARRAY); | |
2736 | if(RARRAY_LEN(stride) < ndims) { | |
2737 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
2738 | } | |
2739 | for(i=0;i<ndims; i++){ | |
2740 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
2741 | if(c_stride[i]==0){ | |
2742 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
2743 | } | |
2744 | } | |
2745 | } | |
2746 | ||
2747 | c_count=ALLOCA_N(size_t,ndims); | |
2748 | switch(TYPE(end)){ | |
2749 | case T_NIL: | |
2750 | for(i=0; i<ndims; i++){ | |
2751 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2752 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
2753 | } | |
2754 | break; | |
2755 | default: | |
2756 | Check_Type(end,T_ARRAY); | |
2757 | if(RARRAY_LEN(end) <ndims) { | |
2758 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
2759 | } | |
2760 | for(i=0; i<ndims; i++){ | |
2761 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
2762 | if(l_end < 0) { | |
2763 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2764 | if(status != NC_NOERR) NC_RAISE(status); | |
2765 | l_end +=dimlen; | |
2766 | } | |
2767 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
2768 | } | |
2769 | } | |
2770 | ||
2771 | ||
2772 | shape = ALLOCA_N(na_shape_t,ndims); | |
2773 | for(i=0;i<ndims;i++){ | |
2774 | shape[ndims-1-i]=c_count[i]; | |
2775 | } | |
2776 | ||
2777 | Cbyte_to_NArray(NArray,ndims,shape,ptr); | |
2778 | ||
2779 | status = nc_get_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr); | |
2780 | if(status != NC_NOERR) NC_RAISE(status); | |
2781 | ||
2782 | OBJ_TAINT(NArray); | |
2783 | return NArray; | |
2784 | } | |
2785 | ||
2786 | VALUE | |
2787 | NetCDF_get_vars_byte(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2788 | { | |
2789 | int ncid; | |
2790 | int varid; | |
2791 | int status; | |
2792 | unsigned char *ptr; | |
2793 | int i; | |
2794 | struct NetCDFVar *Netcdf_var; | |
2795 | na_shape_t l_start, l_end; | |
2796 | size_t *c_start; | |
2797 | size_t *c_count; | |
2798 | ptrdiff_t *c_stride; | |
2799 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2800 | int ndims; | |
2801 | int *dimids; | |
2802 | size_t dimlen; | |
2803 | VALUE NArray; | |
2804 | ||
2805 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2806 | ncid = Netcdf_var->ncid; | |
2807 | varid = Netcdf_var->varid; | |
2808 | ||
2809 | status = nc_inq_varndims(ncid,varid,&ndims); | |
2810 | if(status != NC_NOERR) NC_RAISE(status); | |
2811 | if(ndims == 0) { | |
2812 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2813 | } | |
2814 | ||
2815 | dimids = ALLOCA_N(int,ndims); | |
2816 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2817 | if(status != NC_NOERR) NC_RAISE(status); | |
2818 | ||
2819 | Check_Type(start,T_ARRAY); | |
2820 | if(RARRAY_LEN(start) < ndims){ | |
2821 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
2822 | } | |
2823 | c_start = ALLOCA_N(size_t,ndims); | |
2824 | for(i=0; i<ndims; i++){ | |
2825 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2826 | ||
2827 | if(l_start < 0) { | |
2828 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
2829 | if(status != NC_NOERR) NC_RAISE(status); | |
2830 | l_start += dimlen; | |
2831 | } | |
2832 | c_start[i]=l_start; | |
2833 | } | |
2834 | ||
2835 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
2836 | switch(TYPE(stride)){ | |
2837 | case T_NIL: | |
2838 | for(i=0; i<ndims; i++){ | |
2839 | c_stride[i]=1; | |
2840 | } | |
2841 | break; | |
2842 | default: | |
2843 | Check_Type(stride,T_ARRAY); | |
2844 | if(RARRAY_LEN(stride) < ndims) { | |
2845 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
2846 | } | |
2847 | for(i=0;i<ndims; i++){ | |
2848 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
2849 | if(c_stride[i]==0){ | |
2850 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
2851 | } | |
2852 | } | |
2853 | } | |
2854 | ||
2855 | c_count=ALLOCA_N(size_t,ndims); | |
2856 | switch(TYPE(end)){ | |
2857 | case T_NIL: | |
2858 | for(i=0; i<ndims; i++){ | |
2859 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2860 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
2861 | } | |
2862 | break; | |
2863 | default: | |
2864 | Check_Type(end,T_ARRAY); | |
2865 | if(RARRAY_LEN(end) <ndims) { | |
2866 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
2867 | } | |
2868 | for(i=0; i<ndims; i++){ | |
2869 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
2870 | if(l_end < 0) { | |
2871 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2872 | if(status != NC_NOERR) NC_RAISE(status); | |
2873 | l_end +=dimlen; | |
2874 | } | |
2875 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
2876 | } | |
2877 | } | |
2878 | ||
2879 | ||
2880 | shape = ALLOCA_N(na_shape_t,ndims); | |
2881 | for(i=0;i<ndims;i++){ | |
2882 | shape[ndims-1-i]=c_count[i]; | |
2883 | } | |
2884 | ||
2885 | Cbyte_to_NArray(NArray,ndims,shape,ptr); | |
2886 | ||
2887 | status = nc_get_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr); | |
2888 | if(status != NC_NOERR) NC_RAISE(status); | |
2889 | ||
2890 | OBJ_TAINT(NArray); | |
2891 | return NArray; | |
2892 | } | |
2893 | ||
2894 | VALUE | |
2895 | NetCDF_get_vars_sint(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2896 | { | |
2897 | int ncid; | |
2898 | int varid; | |
2899 | int status; | |
2900 | short *ptr; | |
2901 | int i; | |
2902 | struct NetCDFVar *Netcdf_var; | |
2903 | na_shape_t l_start, l_end; | |
2904 | size_t *c_start; | |
2905 | size_t *c_count; | |
2906 | ptrdiff_t *c_stride; | |
2907 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2908 | int ndims; | |
2909 | int *dimids; | |
2910 | size_t dimlen; | |
2911 | VALUE NArray; | |
2912 | ||
2913 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2914 | ncid = Netcdf_var->ncid; | |
2915 | varid = Netcdf_var->varid; | |
2916 | ||
2917 | status = nc_inq_varndims(ncid,varid,&ndims); | |
2918 | if(status != NC_NOERR) NC_RAISE(status); | |
2919 | if(ndims == 0) { | |
2920 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2921 | } | |
2922 | ||
2923 | dimids = ALLOCA_N(int,ndims); | |
2924 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2925 | if(status != NC_NOERR) NC_RAISE(status); | |
2926 | ||
2927 | Check_Type(start,T_ARRAY); | |
2928 | if(RARRAY_LEN(start) < ndims){ | |
2929 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
2930 | } | |
2931 | c_start = ALLOCA_N(size_t,ndims); | |
2932 | for(i=0; i<ndims; i++){ | |
2933 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2934 | ||
2935 | if(l_start < 0) { | |
2936 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
2937 | if(status != NC_NOERR) NC_RAISE(status); | |
2938 | l_start += dimlen; | |
2939 | } | |
2940 | c_start[i]=l_start; | |
2941 | } | |
2942 | ||
2943 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
2944 | switch(TYPE(stride)){ | |
2945 | case T_NIL: | |
2946 | for(i=0; i<ndims; i++){ | |
2947 | c_stride[i]=1; | |
2948 | } | |
2949 | break; | |
2950 | default: | |
2951 | Check_Type(stride,T_ARRAY); | |
2952 | if(RARRAY_LEN(stride) < ndims) { | |
2953 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
2954 | } | |
2955 | for(i=0;i<ndims; i++){ | |
2956 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
2957 | if(c_stride[i]==0){ | |
2958 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
2959 | } | |
2960 | } | |
2961 | } | |
2962 | ||
2963 | c_count=ALLOCA_N(size_t,ndims); | |
2964 | switch(TYPE(end)){ | |
2965 | case T_NIL: | |
2966 | for(i=0; i<ndims; i++){ | |
2967 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2968 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
2969 | } | |
2970 | break; | |
2971 | default: | |
2972 | Check_Type(end,T_ARRAY); | |
2973 | if(RARRAY_LEN(end) <ndims) { | |
2974 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
2975 | } | |
2976 | for(i=0; i<ndims; i++){ | |
2977 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
2978 | if(l_end < 0) { | |
2979 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2980 | if(status != NC_NOERR) NC_RAISE(status); | |
2981 | l_end +=dimlen; | |
2982 | } | |
2983 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
2984 | } | |
2985 | } | |
2986 | ||
2987 | ||
2988 | shape = ALLOCA_N(na_shape_t,ndims); | |
2989 | for(i=0;i<ndims;i++){ | |
2990 | shape[ndims-1-i]=c_count[i]; | |
2991 | } | |
2992 | ||
2993 | Csint_to_NArray(NArray,ndims,shape,ptr); | |
2994 | ||
2995 | ||
2996 | status = nc_get_vars_short(ncid,varid,c_start,c_count,c_stride,ptr); | |
2997 | if(status != NC_NOERR) NC_RAISE(status); | |
2998 | ||
2999 | OBJ_TAINT(NArray); | |
3000 | return NArray; | |
3001 | } | |
3002 | ||
3003 | VALUE | |
3004 | NetCDF_get_vars_int(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
3005 | { | |
3006 | int ncid; | |
3007 | int varid; | |
3008 | int status; | |
3009 | int *ptr; | |
3010 | int i; | |
3011 | struct NetCDFVar *Netcdf_var; | |
3012 | na_shape_t l_start, l_end; | |
3013 | size_t *c_start; | |
3014 | size_t *c_count; | |
3015 | ptrdiff_t *c_stride; | |
3016 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
3017 | int ndims; | |
3018 | int *dimids; | |
3019 | size_t dimlen; | |
3020 | VALUE NArray; | |
3021 | ||
3022 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3023 | ncid = Netcdf_var->ncid; | |
3024 | varid = Netcdf_var->varid; | |
3025 | ||
3026 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3027 | if(status != NC_NOERR) NC_RAISE(status); | |
3028 | if(ndims == 0) { | |
3029 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
3030 | } | |
3031 | ||
3032 | dimids = ALLOCA_N(int,ndims); | |
3033 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3034 | if(status != NC_NOERR) NC_RAISE(status); | |
3035 | ||
3036 | Check_Type(start,T_ARRAY); | |
3037 | if(RARRAY_LEN(start) < ndims){ | |
3038 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3039 | } | |
3040 | c_start = ALLOCA_N(size_t,ndims); | |
3041 | for(i=0; i<ndims; i++){ | |
3042 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3043 | ||
3044 | if(l_start < 0) { | |
3045 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3046 | if(status != NC_NOERR) NC_RAISE(status); | |
3047 | l_start += dimlen; | |
3048 | } | |
3049 | c_start[i]=l_start; | |
3050 | } | |
3051 | ||
3052 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3053 | switch(TYPE(stride)){ | |
3054 | case T_NIL: | |
3055 | for(i=0; i<ndims; i++){ | |
3056 | c_stride[i]=1; | |
3057 | } | |
3058 | break; | |
3059 | default: | |
3060 | Check_Type(stride,T_ARRAY); | |
3061 | if(RARRAY_LEN(stride) < ndims) { | |
3062 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
3063 | } | |
3064 | for(i=0;i<ndims; i++){ | |
3065 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3066 | if(c_stride[i]==0){ | |
3067 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
3068 | } | |
3069 | } | |
3070 | } | |
3071 | ||
3072 | c_count=ALLOCA_N(size_t,ndims); | |
3073 | switch(TYPE(end)){ | |
3074 | case T_NIL: | |
3075 | for(i=0; i<ndims; i++){ | |
3076 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3077 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
3078 | } | |
3079 | break; | |
3080 | default: | |
3081 | Check_Type(end,T_ARRAY); | |
3082 | if(RARRAY_LEN(end) <ndims) { | |
3083 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3084 | } | |
3085 | for(i=0; i<ndims; i++){ | |
3086 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3087 | if(l_end < 0) { | |
3088 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3089 | if(status != NC_NOERR) NC_RAISE(status); | |
3090 | l_end +=dimlen; | |
3091 | } | |
3092 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3093 | } | |
3094 | } | |
3095 | ||
3096 | ||
3097 | shape = ALLOCA_N(na_shape_t,ndims); | |
3098 | for(i=0;i<ndims;i++){ | |
3099 | shape[ndims-1-i]=c_count[i]; | |
3100 | } | |
3101 | ||
3102 | Clint_to_NArray(NArray,ndims,shape,ptr); | |
3103 | ||
3104 | ||
3105 | status = nc_get_vars_int(ncid,varid,c_start,c_count,c_stride,ptr); | |
3106 | if(status != NC_NOERR) NC_RAISE(status); | |
3107 | ||
3108 | OBJ_TAINT(NArray); | |
3109 | return NArray; | |
3110 | } | |
3111 | ||
3112 | VALUE | |
3113 | NetCDF_get_vars_float(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
3114 | { | |
3115 | int ncid; | |
3116 | int varid; | |
3117 | int status; | |
3118 | float *ptr; | |
3119 | int i; | |
3120 | struct NetCDFVar *Netcdf_var; | |
3121 | na_shape_t l_start, l_end; | |
3122 | size_t *c_start; | |
3123 | size_t *c_count; | |
3124 | ptrdiff_t *c_stride; | |
3125 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
3126 | int ndims; | |
3127 | int *dimids; | |
3128 | size_t dimlen; | |
3129 | VALUE NArray; | |
3130 | ||
3131 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3132 | ncid = Netcdf_var->ncid; | |
3133 | varid = Netcdf_var->varid; | |
3134 | ||
3135 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3136 | if(status != NC_NOERR) NC_RAISE(status); | |
3137 | if(ndims == 0) { | |
3138 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
3139 | } | |
3140 | ||
3141 | dimids = ALLOCA_N(int,ndims); | |
3142 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3143 | if(status != NC_NOERR) NC_RAISE(status); | |
3144 | ||
3145 | Check_Type(start,T_ARRAY); | |
3146 | if(RARRAY_LEN(start) < ndims){ | |
3147 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3148 | } | |
3149 | c_start = ALLOCA_N(size_t,ndims); | |
3150 | for(i=0; i<ndims; i++){ | |
3151 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3152 | ||
3153 | if(l_start < 0) { | |
3154 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3155 | if(status != NC_NOERR) NC_RAISE(status); | |
3156 | l_start += dimlen; | |
3157 | } | |
3158 | c_start[i]=l_start; | |
3159 | } | |
3160 | ||
3161 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3162 | switch(TYPE(stride)){ | |
3163 | case T_NIL: | |
3164 | for(i=0; i<ndims; i++){ | |
3165 | c_stride[i]=1; | |
3166 | } | |
3167 | break; | |
3168 | default: | |
3169 | Check_Type(stride,T_ARRAY); | |
3170 | if(RARRAY_LEN(stride) < ndims) { | |
3171 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
3172 | } | |
3173 | for(i=0;i<ndims; i++){ | |
3174 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3175 | if(c_stride[i]==0){ | |
3176 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
3177 | } | |
3178 | } | |
3179 | } | |
3180 | ||
3181 | c_count=ALLOCA_N(size_t,ndims); | |
3182 | switch(TYPE(end)){ | |
3183 | case T_NIL: | |
3184 | for(i=0; i<ndims; i++){ | |
3185 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3186 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
3187 | } | |
3188 | break; | |
3189 | default: | |
3190 | Check_Type(end,T_ARRAY); | |
3191 | if(RARRAY_LEN(end) <ndims) { | |
3192 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3193 | } | |
3194 | for(i=0; i<ndims; i++){ | |
3195 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3196 | if(l_end < 0) { | |
3197 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3198 | if(status != NC_NOERR) NC_RAISE(status); | |
3199 | l_end +=dimlen; | |
3200 | } | |
3201 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3202 | } | |
3203 | } | |
3204 | ||
3205 | ||
3206 | shape = ALLOCA_N(na_shape_t,ndims); | |
3207 | for(i=0;i<ndims;i++){ | |
3208 | shape[ndims-1-i]=c_count[i]; | |
3209 | } | |
3210 | ||
3211 | Cfloat_to_NArray(NArray,ndims,shape,ptr); | |
3212 | ||
3213 | ||
3214 | status = nc_get_vars_float(ncid,varid,c_start,c_count,c_stride,ptr); | |
3215 | if(status != NC_NOERR) NC_RAISE(status); | |
3216 | ||
3217 | OBJ_TAINT(NArray); | |
3218 | return NArray; | |
3219 | } | |
3220 | ||
3221 | VALUE | |
3222 | NetCDF_get_vars_double(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
3223 | { | |
3224 | int ncid; | |
3225 | int varid; | |
3226 | int status; | |
3227 | double *ptr; | |
3228 | int i; | |
3229 | struct NetCDFVar *Netcdf_var; | |
3230 | na_shape_t l_start, l_end; | |
3231 | size_t *c_start; | |
3232 | size_t *c_count; | |
3233 | ptrdiff_t *c_stride; | |
3234 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
3235 | int ndims; | |
3236 | int *dimids; | |
3237 | size_t dimlen; | |
3238 | VALUE NArray; | |
3239 | ||
3240 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3241 | ncid = Netcdf_var->ncid; | |
3242 | varid = Netcdf_var->varid; | |
3243 | ||
3244 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3245 | if(status != NC_NOERR) NC_RAISE(status); | |
3246 | if(ndims == 0) { | |
3247 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
3248 | } | |
3249 | ||
3250 | dimids = ALLOCA_N(int,ndims); | |
3251 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3252 | if(status != NC_NOERR) NC_RAISE(status); | |
3253 | ||
3254 | Check_Type(start,T_ARRAY); | |
3255 | if(RARRAY_LEN(start) < ndims){ | |
3256 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3257 | } | |
3258 | c_start = ALLOCA_N(size_t,ndims); | |
3259 | for(i=0; i<ndims; i++){ | |
3260 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3261 | ||
3262 | if(l_start < 0) { | |
3263 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3264 | if(status != NC_NOERR) NC_RAISE(status); | |
3265 | l_start += dimlen; | |
3266 | } | |
3267 | c_start[i]=l_start; | |
3268 | } | |
3269 | ||
3270 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3271 | switch(TYPE(stride)){ | |
3272 | case T_NIL: | |
3273 | for(i=0; i<ndims; i++){ | |
3274 | c_stride[i]=1; | |
3275 | } | |
3276 | break; | |
3277 | default: | |
3278 | Check_Type(stride,T_ARRAY); | |
3279 | if(RARRAY_LEN(stride) < ndims) { | |
3280 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
3281 | } | |
3282 | for(i=0;i<ndims; i++){ | |
3283 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3284 | if(c_stride[i]==0){ | |
3285 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
3286 | } | |
3287 | } | |
3288 | } | |
3289 | ||
3290 | c_count=ALLOCA_N(size_t,ndims); | |
3291 | switch(TYPE(end)){ | |
3292 | case T_NIL: | |
3293 | for(i=0; i<ndims; i++){ | |
3294 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3295 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
3296 | } | |
3297 | break; | |
3298 | default: | |
3299 | Check_Type(end,T_ARRAY); | |
3300 | if(RARRAY_LEN(end) <ndims) { | |
3301 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3302 | } | |
3303 | for(i=0; i<ndims; i++){ | |
3304 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3305 | if(l_end < 0) { | |
3306 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3307 | if(status != NC_NOERR) NC_RAISE(status); | |
3308 | l_end +=dimlen; | |
3309 | } | |
3310 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3311 | } | |
3312 | } | |
3313 | ||
3314 | ||
3315 | shape = ALLOCA_N(na_shape_t,ndims); | |
3316 | for(i=0;i<ndims;i++){ | |
3317 | shape[ndims-1-i]=c_count[i]; | |
3318 | } | |
3319 | ||
3320 | Cdouble_to_NArray(NArray,ndims,shape,ptr); | |
3321 | ||
3322 | status = nc_get_vars_double(ncid,varid,c_start,c_count,c_stride,ptr); | |
3323 | if(status != NC_NOERR) NC_RAISE(status); | |
3324 | ||
3325 | OBJ_TAINT(NArray); | |
3326 | return NArray; | |
3327 | } | |
3328 | ||
3329 | ||
3330 | VALUE | |
3331 | NetCDF_put_var_char(VALUE Var,VALUE NArray) | |
3332 | { | |
3333 | int ncid; | |
3334 | int varid; | |
3335 | int status; | |
3336 | unsigned char *ptr,scalar; | |
3337 | na_shape_t len,i=0; | |
3338 | struct NetCDFVar *Netcdf_var; | |
3339 | na_shape_t nc_tlen=1; | |
3340 | int ndimsp; | |
3341 | int dimids[NC_MAX_DIMS]; | |
3342 | size_t lengthp; | |
3343 | char *var_name; | |
3344 | ||
3345 | rb_secure(3); | |
3346 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3347 | ncid=Netcdf_var->ncid; | |
3348 | varid=Netcdf_var->varid; | |
3349 | ||
3350 | Array_to_Cbyte_len(NArray,ptr,len); | |
3351 | ||
3352 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3353 | if(status != NC_NOERR) NC_RAISE(status); | |
3354 | for(i=0;i<ndimsp;i++){ | |
3355 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3356 | if(status != NC_NOERR) NC_RAISE(status); | |
3357 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3358 | nc_tlen=lengthp*nc_tlen; | |
3359 | } | |
3360 | if(len == 1 && len != nc_tlen){ | |
3361 | scalar = *ptr; | |
3362 | ptr = ALLOCA_N(unsigned char,nc_tlen); | |
3363 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3364 | } else if(len != nc_tlen){ | |
3365 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3366 | status = nc_inq_varname(ncid,varid,var_name); | |
3367 | if(status != NC_NOERR) NC_RAISE(status ); | |
3368 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name); | |
3369 | } | |
3370 | status = nc_put_var_text(ncid,varid,(char *)ptr); | |
3371 | if(status !=NC_NOERR) NC_RAISE(status); | |
3372 | return Qnil; | |
3373 | } | |
3374 | ||
3375 | VALUE | |
3376 | NetCDF_put_var_byte(VALUE Var,VALUE NArray) | |
3377 | { | |
3378 | int ncid; | |
3379 | int varid; | |
3380 | int status; | |
3381 | unsigned char *ptr,scalar; | |
3382 | na_shape_t len,i=0; | |
3383 | struct NetCDFVar *Netcdf_var; | |
3384 | na_shape_t nc_tlen=1; | |
3385 | int ndimsp; | |
3386 | int dimids[NC_MAX_DIMS]; | |
3387 | size_t lengthp; | |
3388 | char *var_name; | |
3389 | ||
3390 | rb_secure(3); | |
3391 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3392 | ncid=Netcdf_var->ncid; | |
3393 | varid=Netcdf_var->varid; | |
3394 | ||
3395 | Array_to_Cbyte_len(NArray,ptr,len); | |
3396 | ||
3397 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3398 | if(status != NC_NOERR) NC_RAISE(status); | |
3399 | for(i=0;i<ndimsp;i++){ | |
3400 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3401 | if(status != NC_NOERR) NC_RAISE(status); | |
3402 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3403 | nc_tlen=lengthp*nc_tlen; | |
3404 | } | |
3405 | if(len == 1 && len != nc_tlen){ | |
3406 | scalar = *ptr; | |
3407 | ptr = ALLOCA_N(unsigned char,nc_tlen); | |
3408 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3409 | } else if(len != nc_tlen){ | |
3410 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3411 | status = nc_inq_varname(ncid,varid,var_name); | |
3412 | if(status != NC_NOERR) NC_RAISE(status ); | |
3413 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name); | |
3414 | } | |
3415 | status = nc_put_var_uchar(ncid,varid,ptr); | |
3416 | if(status !=NC_NOERR) NC_RAISE(status); | |
3417 | return Qnil; | |
3418 | } | |
3419 | ||
3420 | VALUE | |
3421 | NetCDF_put_var_short(VALUE Var,VALUE NArray) | |
3422 | { | |
3423 | int ncid; | |
3424 | int varid; | |
3425 | int status; | |
3426 | short *ptr,scalar; | |
3427 | na_shape_t len,i=0; | |
3428 | struct NetCDFVar *Netcdf_var; | |
3429 | na_shape_t nc_tlen=1; | |
3430 | int ndimsp; | |
3431 | int dimids[NC_MAX_DIMS]; | |
3432 | size_t lengthp; | |
3433 | char *var_name; | |
3434 | ||
3435 | rb_secure(3); | |
3436 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3437 | ncid=Netcdf_var->ncid; | |
3438 | varid=Netcdf_var->varid; | |
3439 | Array_to_Csint_len(NArray,ptr,len); | |
3440 | ||
3441 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3442 | if(status != NC_NOERR) NC_RAISE(status); | |
3443 | for(i=0;i<ndimsp;i++){ | |
3444 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3445 | if(status != NC_NOERR) NC_RAISE(status); | |
3446 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3447 | nc_tlen=lengthp*nc_tlen; | |
3448 | } | |
3449 | if(len == 1 && len != nc_tlen){ | |
3450 | scalar = *ptr; | |
3451 | ptr = ALLOCA_N(short,nc_tlen); | |
3452 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3453 | } else if(len != nc_tlen){ | |
3454 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3455 | status = nc_inq_varname(ncid,varid,var_name); | |
3456 | if(status != NC_NOERR) NC_RAISE(status); | |
3457 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3458 | } | |
3459 | ||
3460 | status = nc_put_var_short(ncid,varid,ptr); | |
3461 | if(status !=NC_NOERR) NC_RAISE(status); | |
3462 | return Qnil; | |
3463 | } | |
3464 | ||
3465 | VALUE | |
3466 | NetCDF_put_var_int(VALUE Var,VALUE NArray) | |
3467 | { | |
3468 | int ncid; | |
3469 | int varid; | |
3470 | int status; | |
3471 | int *ptr,scalar; | |
3472 | na_shape_t len,i=0; | |
3473 | struct NetCDFVar *Netcdf_var; | |
3474 | na_shape_t nc_tlen=1; | |
3475 | int ndimsp; | |
3476 | int dimids[NC_MAX_DIMS]; | |
3477 | size_t lengthp; | |
3478 | char *var_name; | |
3479 | ||
3480 | rb_secure(3); | |
3481 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3482 | ncid=Netcdf_var->ncid; | |
3483 | varid=Netcdf_var->varid; | |
3484 | ||
3485 | Array_to_Clint_len(NArray,ptr,len); | |
3486 | ||
3487 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3488 | if(status != NC_NOERR) NC_RAISE(status); | |
3489 | for(i=0;i<ndimsp;i++){ | |
3490 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3491 | if(status != NC_NOERR) NC_RAISE(status); | |
3492 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3493 | nc_tlen=lengthp*nc_tlen; | |
3494 | } | |
3495 | if(len == 1 && len != nc_tlen){ | |
3496 | scalar = *ptr; | |
3497 | ptr = ALLOCA_N(int,nc_tlen); | |
3498 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3499 | } else if(len != nc_tlen){ | |
3500 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3501 | status = nc_inq_varname(ncid,varid,var_name); | |
3502 | if(status != NC_NOERR) NC_RAISE(status); | |
3503 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3504 | } | |
3505 | ||
3506 | ||
3507 | status = nc_put_var_int(ncid,varid,ptr); | |
3508 | if(status !=NC_NOERR) NC_RAISE(status); | |
3509 | return Qnil; | |
3510 | } | |
3511 | ||
3512 | ||
3513 | VALUE | |
3514 | NetCDF_put_var_float(VALUE Var,VALUE NArray) | |
3515 | { | |
3516 | int ncid; | |
3517 | int varid; | |
3518 | int status; | |
3519 | float *ptr,scalar; | |
3520 | na_shape_t len,i=0; | |
3521 | struct NetCDFVar *Netcdf_var; | |
3522 | na_shape_t nc_tlen=1; | |
3523 | int ndimsp; | |
3524 | int dimids[NC_MAX_DIMS]; | |
3525 | size_t lengthp; | |
3526 | char *var_name; | |
3527 | ||
3528 | ||
3529 | rb_secure(3); | |
3530 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3531 | ncid=Netcdf_var->ncid; | |
3532 | varid=Netcdf_var->varid; | |
3533 | ||
3534 | Array_to_Cfloat_len(NArray,ptr,len); | |
3535 | ||
3536 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3537 | if(status != NC_NOERR) NC_RAISE(status); | |
3538 | for(i=0;i<ndimsp;i++){ | |
3539 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3540 | if(status != NC_NOERR) NC_RAISE(status); | |
3541 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3542 | nc_tlen=lengthp*nc_tlen; | |
3543 | } | |
3544 | if(len == 1 && len != nc_tlen){ | |
3545 | scalar = *ptr; | |
3546 | ptr = ALLOCA_N(float,nc_tlen); | |
3547 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3548 | } else if(len != nc_tlen){ | |
3549 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3550 | status = nc_inq_varname(ncid,varid,var_name); | |
3551 | if(status != NC_NOERR) NC_RAISE(status); | |
3552 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3553 | } | |
3554 | ||
3555 | status = nc_put_var_float(ncid,varid,ptr); | |
3556 | if(status !=NC_NOERR) NC_RAISE(status); | |
3557 | return Qnil; | |
3558 | } | |
3559 | ||
3560 | VALUE | |
3561 | NetCDF_put_var_double(VALUE Var,VALUE NArray) | |
3562 | { | |
3563 | int ncid; | |
3564 | int varid; | |
3565 | int status; | |
3566 | double *ptr,scalar; | |
3567 | na_shape_t len,i=0; | |
3568 | struct NetCDFVar *Netcdf_var; | |
3569 | na_shape_t nc_tlen=1; | |
3570 | int ndimsp; | |
3571 | int dimids[NC_MAX_DIMS]; | |
3572 | size_t lengthp; | |
3573 | char *var_name; | |
3574 | ||
3575 | ||
3576 | rb_secure(3); | |
3577 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3578 | ncid=Netcdf_var->ncid; | |
3579 | varid=Netcdf_var->varid; | |
3580 | ||
3581 | Array_to_Cdouble_len(NArray,ptr,len); | |
3582 | ||
3583 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3584 | if(status != NC_NOERR) NC_RAISE(status); | |
3585 | for(i=0;i<ndimsp;i++){ | |
3586 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3587 | if(status != NC_NOERR) NC_RAISE(status); | |
3588 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3589 | nc_tlen=lengthp*nc_tlen; | |
3590 | } | |
3591 | if(len == 1 && len != nc_tlen){ | |
3592 | scalar = *ptr; | |
3593 | ptr = ALLOCA_N(double,nc_tlen); | |
3594 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3595 | } else if(len != nc_tlen){ | |
3596 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3597 | status = nc_inq_varname(ncid,varid,var_name); | |
3598 | if(status != NC_NOERR) NC_RAISE(status); | |
3599 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3600 | } | |
3601 | ||
3602 | status = nc_put_var_double(ncid,varid,ptr); | |
3603 | if(status !=NC_NOERR) NC_RAISE(status); | |
3604 | return Qnil; | |
3605 | } | |
3606 | ||
3607 | VALUE | |
3608 | NetCDF_put_var1_char(VALUE Var,VALUE NArray,VALUE start) | |
3609 | { | |
3610 | int ncid; | |
3611 | int varid; | |
3612 | int status; | |
3613 | unsigned char *ptr; | |
3614 | int i; | |
3615 | struct NetCDFVar *Netcdf_var; | |
3616 | na_shape_t l_start; | |
3617 | size_t *c_start; | |
3618 | int ndims; | |
3619 | int *dimids; | |
3620 | size_t dimlen; | |
3621 | ||
3622 | rb_secure(3); | |
3623 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3624 | ncid=Netcdf_var->ncid; | |
3625 | varid=Netcdf_var->varid; | |
3626 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3627 | if(status != NC_NOERR) NC_RAISE(status); | |
3628 | ||
3629 | ||
3630 | dimids = ALLOCA_N(int,ndims); | |
3631 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3632 | if(status != NC_NOERR) NC_RAISE(status); | |
3633 | ||
3634 | Check_Type(start,T_ARRAY); | |
3635 | if(RARRAY_LEN(start) <ndims) { | |
3636 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3637 | } | |
3638 | ||
3639 | c_start=ALLOCA_N(size_t,ndims); | |
3640 | for(i=0;i<ndims;i++){ | |
3641 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3642 | ||
3643 | if(l_start < 0) { | |
3644 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3645 | if(status != NC_NOERR) NC_RAISE(status); | |
3646 | l_start += dimlen; | |
3647 | } | |
3648 | c_start[i]=l_start; | |
3649 | ||
3650 | } | |
3651 | Array_to_Cbyte(NArray,ptr); | |
3652 | ||
3653 | status = nc_put_var1_text(ncid,varid,c_start,(char *)ptr); | |
3654 | if(status != NC_NOERR) NC_RAISE(status); | |
3655 | return Qnil; | |
3656 | } | |
3657 | ||
3658 | VALUE | |
3659 | NetCDF_put_var1_byte(VALUE Var,VALUE NArray,VALUE start) | |
3660 | { | |
3661 | int ncid; | |
3662 | int varid; | |
3663 | int status; | |
3664 | unsigned char *ptr; | |
3665 | int i; | |
3666 | struct NetCDFVar *Netcdf_var; | |
3667 | na_shape_t l_start; | |
3668 | size_t *c_start; | |
3669 | int ndims; | |
3670 | int *dimids; | |
3671 | size_t dimlen; | |
3672 | ||
3673 | rb_secure(3); | |
3674 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3675 | ncid=Netcdf_var->ncid; | |
3676 | varid=Netcdf_var->varid; | |
3677 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3678 | if(status != NC_NOERR) NC_RAISE(status); | |
3679 | ||
3680 | ||
3681 | dimids = ALLOCA_N(int,ndims); | |
3682 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3683 | if(status != NC_NOERR) NC_RAISE(status); | |
3684 | ||
3685 | Check_Type(start,T_ARRAY); | |
3686 | if(RARRAY_LEN(start) <ndims) { | |
3687 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3688 | } | |
3689 | ||
3690 | c_start=ALLOCA_N(size_t,ndims); | |
3691 | for(i=0;i<ndims;i++){ | |
3692 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3693 | ||
3694 | if(l_start < 0) { | |
3695 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3696 | if(status != NC_NOERR) NC_RAISE(status); | |
3697 | l_start += dimlen; | |
3698 | } | |
3699 | c_start[i]=l_start; | |
3700 | ||
3701 | } | |
3702 | Array_to_Cbyte(NArray,ptr); | |
3703 | ||
3704 | status = nc_put_var1_uchar(ncid,varid,c_start,ptr); | |
3705 | if(status != NC_NOERR) NC_RAISE(status); | |
3706 | return Qnil; | |
3707 | } | |
3708 | ||
3709 | VALUE | |
3710 | NetCDF_put_var1_sint(VALUE Var,VALUE NArray,VALUE start) | |
3711 | { | |
3712 | int ncid; | |
3713 | int varid; | |
3714 | int status; | |
3715 | short *ptr; | |
3716 | int i; | |
3717 | struct NetCDFVar *Netcdf_var; | |
3718 | na_shape_t l_start; | |
3719 | size_t *c_start; | |
3720 | int ndims; | |
3721 | int *dimids; | |
3722 | size_t dimlen; | |
3723 | ||
3724 | rb_secure(3); | |
3725 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3726 | ncid=Netcdf_var->ncid; | |
3727 | varid=Netcdf_var->varid; | |
3728 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3729 | if(status != NC_NOERR) NC_RAISE(status); | |
3730 | ||
3731 | ||
3732 | dimids = ALLOCA_N(int,ndims); | |
3733 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3734 | if(status != NC_NOERR) NC_RAISE(status); | |
3735 | ||
3736 | Check_Type(start,T_ARRAY); | |
3737 | if(RARRAY_LEN(start) <ndims) { | |
3738 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3739 | } | |
3740 | ||
3741 | c_start=ALLOCA_N(size_t,ndims); | |
3742 | for(i=0;i<ndims;i++){ | |
3743 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3744 | ||
3745 | if(l_start < 0) { | |
3746 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3747 | if(status != NC_NOERR) NC_RAISE(status); | |
3748 | l_start += dimlen; | |
3749 | } | |
3750 | c_start[i]=l_start; | |
3751 | ||
3752 | } | |
3753 | Array_to_Csint(NArray,ptr); | |
3754 | ||
3755 | status = nc_put_var1_short(ncid,varid,c_start,ptr); | |
3756 | if(status != NC_NOERR) NC_RAISE(status); | |
3757 | return Qnil; | |
3758 | } | |
3759 | VALUE | |
3760 | NetCDF_put_var1_int(VALUE Var,VALUE NArray,VALUE start) | |
3761 | { | |
3762 | int ncid; | |
3763 | int varid; | |
3764 | int status; | |
3765 | int *ptr; | |
3766 | int i; | |
3767 | struct NetCDFVar *Netcdf_var; | |
3768 | na_shape_t l_start; | |
3769 | size_t *c_start; | |
3770 | int ndims; | |
3771 | int *dimids; | |
3772 | size_t dimlen; | |
3773 | ||
3774 | rb_secure(3); | |
3775 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3776 | ncid=Netcdf_var->ncid; | |
3777 | varid=Netcdf_var->varid; | |
3778 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3779 | if(status != NC_NOERR) NC_RAISE(status); | |
3780 | ||
3781 | ||
3782 | dimids = ALLOCA_N(int,ndims); | |
3783 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3784 | if(status != NC_NOERR) NC_RAISE(status); | |
3785 | ||
3786 | Check_Type(start,T_ARRAY); | |
3787 | if(RARRAY_LEN(start) <ndims) { | |
3788 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3789 | } | |
3790 | ||
3791 | c_start=ALLOCA_N(size_t,ndims); | |
3792 | for(i=0;i<ndims;i++){ | |
3793 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3794 | ||
3795 | if(l_start < 0) { | |
3796 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3797 | if(status != NC_NOERR) NC_RAISE(status); | |
3798 | l_start += dimlen; | |
3799 | } | |
3800 | c_start[i]=l_start; | |
3801 | ||
3802 | } | |
3803 | Array_to_Clint(NArray,ptr); | |
3804 | ||
3805 | status = nc_put_var1_int(ncid,varid,c_start,ptr); | |
3806 | if(status != NC_NOERR) NC_RAISE(status); | |
3807 | return Qnil; | |
3808 | } | |
3809 | ||
3810 | VALUE | |
3811 | NetCDF_put_var1_float(VALUE Var,VALUE NArray,VALUE start) | |
3812 | { | |
3813 | int ncid; | |
3814 | int varid; | |
3815 | int status; | |
3816 | float *ptr; | |
3817 | int i; | |
3818 | struct NetCDFVar *Netcdf_var; | |
3819 | na_shape_t l_start; | |
3820 | size_t *c_start; | |
3821 | int ndims; | |
3822 | int *dimids; | |
3823 | size_t dimlen; | |
3824 | ||
3825 | rb_secure(3); | |
3826 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3827 | ncid=Netcdf_var->ncid; | |
3828 | varid=Netcdf_var->varid; | |
3829 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3830 | if(status != NC_NOERR) NC_RAISE(status); | |
3831 | ||
3832 | ||
3833 | dimids = ALLOCA_N(int,ndims); | |
3834 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3835 | if(status != NC_NOERR) NC_RAISE(status); | |
3836 | ||
3837 | Check_Type(start,T_ARRAY); | |
3838 | if(RARRAY_LEN(start) <ndims) { | |
3839 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3840 | } | |
3841 | ||
3842 | c_start=ALLOCA_N(size_t,ndims); | |
3843 | for(i=0;i<ndims;i++){ | |
3844 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3845 | ||
3846 | if(l_start < 0) { | |
3847 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3848 | if(status != NC_NOERR) NC_RAISE(status); | |
3849 | l_start += dimlen; | |
3850 | } | |
3851 | c_start[i]=l_start; | |
3852 | ||
3853 | } | |
3854 | Array_to_Cfloat(NArray,ptr); | |
3855 | ||
3856 | status = nc_put_var1_float(ncid,varid,c_start,ptr); | |
3857 | if(status != NC_NOERR) NC_RAISE(status); | |
3858 | return Qnil; | |
3859 | } | |
3860 | ||
3861 | VALUE | |
3862 | NetCDF_put_var1_double(VALUE Var,VALUE NArray,VALUE start) | |
3863 | { | |
3864 | int ncid; | |
3865 | int varid; | |
3866 | int status; | |
3867 | double *ptr; | |
3868 | int i; | |
3869 | struct NetCDFVar *Netcdf_var; | |
3870 | na_shape_t l_start; | |
3871 | size_t *c_start; | |
3872 | int ndims; | |
3873 | int *dimids; | |
3874 | size_t dimlen; | |
3875 | ||
3876 | rb_secure(3); | |
3877 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3878 | ncid=Netcdf_var->ncid; | |
3879 | varid=Netcdf_var->varid; | |
3880 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3881 | if(status != NC_NOERR) NC_RAISE(status); | |
3882 | ||
3883 | ||
3884 | dimids = ALLOCA_N(int,ndims); | |
3885 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3886 | if(status != NC_NOERR) NC_RAISE(status); | |
3887 | ||
3888 | Check_Type(start,T_ARRAY); | |
3889 | if(RARRAY_LEN(start) <ndims) { | |
3890 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3891 | } | |
3892 | ||
3893 | c_start=ALLOCA_N(size_t,ndims); | |
3894 | for(i=0;i<ndims;i++){ | |
3895 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3896 | ||
3897 | if(l_start < 0) { | |
3898 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3899 | if(status != NC_NOERR) NC_RAISE(status); | |
3900 | l_start += dimlen; | |
3901 | } | |
3902 | c_start[i]=l_start; | |
3903 | ||
3904 | } | |
3905 | Array_to_Cdouble(NArray,ptr); | |
3906 | ||
3907 | status = nc_put_var1_double(ncid,varid,c_start,ptr); | |
3908 | if(status != NC_NOERR) NC_RAISE(status); | |
3909 | return Qnil; | |
3910 | } | |
3911 | ||
3912 | ||
3913 | VALUE | |
3914 | NetCDF_put_vars_char(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
3915 | { | |
3916 | int ncid; | |
3917 | int varid; | |
3918 | int status; | |
3919 | unsigned char *ptr,scalar; | |
3920 | na_shape_t len; | |
3921 | int c_count_all=1; | |
3922 | struct NetCDFVar *Netcdf_var; | |
3923 | na_shape_t l_start, l_end; | |
3924 | size_t *c_start; | |
3925 | size_t *c_count; | |
3926 | ptrdiff_t *c_stride; | |
3927 | int ndims,i; | |
3928 | na_shape_t *shape; | |
3929 | int *dimids; | |
3930 | size_t dimlen; | |
3931 | ||
3932 | rb_secure(3); | |
3933 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3934 | ncid=Netcdf_var->ncid; | |
3935 | varid=Netcdf_var->varid; | |
3936 | status = nc_inq_varndims(ncid, varid, &ndims); | |
3937 | if(status != NC_NOERR) NC_RAISE(status); | |
3938 | ||
3939 | dimids=ALLOCA_N(int,ndims); | |
3940 | status = nc_inq_vardimid(ncid, varid, dimids); | |
3941 | if(status != NC_NOERR) NC_RAISE(status); | |
3942 | ||
3943 | Check_Type(start,T_ARRAY); | |
3944 | if(RARRAY_LEN(start) < ndims) { | |
3945 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3946 | } | |
3947 | c_start=ALLOCA_N(size_t,ndims); | |
3948 | for(i=0; i<ndims; i++){ | |
3949 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3950 | ||
3951 | if(l_start < 0) { | |
3952 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3953 | if(status != NC_NOERR) NC_RAISE(status); | |
3954 | l_start += dimlen; | |
3955 | } | |
3956 | c_start[i]=l_start; | |
3957 | } | |
3958 | ||
3959 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3960 | switch(TYPE(stride)){ | |
3961 | case T_NIL: | |
3962 | for(i=0; i<ndims; i++){ | |
3963 | c_stride[i]=1; | |
3964 | } | |
3965 | break; | |
3966 | default: | |
3967 | Check_Type(stride,T_ARRAY); | |
3968 | if(RARRAY_LEN(stride) < ndims) { | |
3969 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
3970 | } | |
3971 | for(i=0; i<ndims; i++){ | |
3972 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3973 | if(c_stride[i]==0) { | |
3974 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
3975 | } | |
3976 | } | |
3977 | } | |
3978 | ||
3979 | Array_to_Cbyte_len_shape(NArray,ptr,len,shape); | |
3980 | ||
3981 | c_count=ALLOCA_N(size_t,ndims); | |
3982 | switch(TYPE(end)){ | |
3983 | case T_NIL: | |
3984 | for(i=0; i<ndims; i++){ | |
3985 | c_count[i]=shape[i]; | |
3986 | } | |
3987 | c_count_all=len; | |
3988 | break; | |
3989 | default: | |
3990 | Check_Type(end,T_ARRAY); | |
3991 | if(RARRAY_LEN(end) < ndims) { | |
3992 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3993 | } | |
3994 | for(i=0; i<ndims; i++){ | |
3995 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3996 | if(l_end < 0) { | |
3997 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3998 | if(status != NC_NOERR) NC_RAISE(status); | |
3999 | l_end += dimlen; | |
4000 | } | |
4001 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4002 | c_count_all=c_count[i]*c_count_all; | |
4003 | } | |
4004 | if(len == 1 && len != c_count_all){ | |
4005 | scalar = *ptr; | |
4006 | ptr = ALLOCA_N(unsigned char,c_count_all); | |
4007 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4008 | } else if(len != c_count_all) { | |
4009 | rb_raise(rb_eNetcdfError, | |
4010 | "lengh of the array does not agree with that of the subset\n"); | |
4011 | } | |
4012 | } | |
4013 | ||
4014 | status = nc_put_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr); | |
4015 | if(status != NC_NOERR) NC_RAISE(status); | |
4016 | return Qnil; | |
4017 | } | |
4018 | ||
4019 | VALUE | |
4020 | NetCDF_put_vars_byte(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4021 | { | |
4022 | int ncid; | |
4023 | int varid; | |
4024 | int status; | |
4025 | unsigned char *ptr,scalar; | |
4026 | na_shape_t len; | |
4027 | int c_count_all=1; | |
4028 | struct NetCDFVar *Netcdf_var; | |
4029 | na_shape_t l_start, l_end; | |
4030 | size_t *c_start; | |
4031 | size_t *c_count; | |
4032 | ptrdiff_t *c_stride; | |
4033 | int ndims,i; | |
4034 | na_shape_t *shape; | |
4035 | int *dimids; | |
4036 | size_t dimlen; | |
4037 | ||
4038 | rb_secure(3); | |
4039 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4040 | ncid=Netcdf_var->ncid; | |
4041 | varid=Netcdf_var->varid; | |
4042 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4043 | if(status != NC_NOERR) NC_RAISE(status); | |
4044 | ||
4045 | dimids=ALLOCA_N(int,ndims); | |
4046 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4047 | if(status != NC_NOERR) NC_RAISE(status); | |
4048 | ||
4049 | Check_Type(start,T_ARRAY); | |
4050 | if(RARRAY_LEN(start) < ndims) { | |
4051 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4052 | } | |
4053 | c_start=ALLOCA_N(size_t,ndims); | |
4054 | for(i=0; i<ndims; i++){ | |
4055 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4056 | ||
4057 | if(l_start < 0) { | |
4058 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4059 | if(status != NC_NOERR) NC_RAISE(status); | |
4060 | l_start += dimlen; | |
4061 | } | |
4062 | c_start[i]=l_start; | |
4063 | } | |
4064 | ||
4065 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4066 | switch(TYPE(stride)){ | |
4067 | case T_NIL: | |
4068 | for(i=0; i<ndims; i++){ | |
4069 | c_stride[i]=1; | |
4070 | } | |
4071 | break; | |
4072 | default: | |
4073 | Check_Type(stride,T_ARRAY); | |
4074 | if(RARRAY_LEN(stride) < ndims) { | |
4075 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4076 | } | |
4077 | for(i=0; i<ndims; i++){ | |
4078 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4079 | if(c_stride[i]==0) { | |
4080 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4081 | } | |
4082 | } | |
4083 | } | |
4084 | ||
4085 | Array_to_Cbyte_len_shape(NArray,ptr,len,shape); | |
4086 | ||
4087 | c_count=ALLOCA_N(size_t,ndims); | |
4088 | switch(TYPE(end)){ | |
4089 | case T_NIL: | |
4090 | for(i=0; i<ndims; i++){ | |
4091 | c_count[i]=shape[i]; | |
4092 | } | |
4093 | c_count_all=len; | |
4094 | break; | |
4095 | default: | |
4096 | Check_Type(end,T_ARRAY); | |
4097 | if(RARRAY_LEN(end) < ndims) { | |
4098 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4099 | } | |
4100 | for(i=0; i<ndims; i++){ | |
4101 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4102 | if(l_end < 0) { | |
4103 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4104 | if(status != NC_NOERR) NC_RAISE(status); | |
4105 | l_end += dimlen; | |
4106 | } | |
4107 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4108 | c_count_all=c_count[i]*c_count_all; | |
4109 | } | |
4110 | if(len == 1 && len != c_count_all){ | |
4111 | scalar = *ptr; | |
4112 | ptr = ALLOCA_N(unsigned char,c_count_all); | |
4113 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4114 | } else if(len != c_count_all) { | |
4115 | rb_raise(rb_eNetcdfError, | |
4116 | "lengh of the array does not agree with that of the subset\n"); | |
4117 | } | |
4118 | } | |
4119 | ||
4120 | status = nc_put_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr); | |
4121 | if(status != NC_NOERR) NC_RAISE(status); | |
4122 | return Qnil; | |
4123 | } | |
4124 | ||
4125 | VALUE | |
4126 | NetCDF_put_vars_sint(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4127 | { | |
4128 | int ncid; | |
4129 | int varid; | |
4130 | int status; | |
4131 | short *ptr,scalar; | |
4132 | na_shape_t len; | |
4133 | int c_count_all=1; | |
4134 | struct NetCDFVar *Netcdf_var; | |
4135 | na_shape_t l_start, l_end; | |
4136 | size_t *c_start; | |
4137 | size_t *c_count; | |
4138 | ptrdiff_t *c_stride; | |
4139 | int ndims,i; | |
4140 | na_shape_t *shape; | |
4141 | int *dimids; | |
4142 | size_t dimlen; | |
4143 | ||
4144 | rb_secure(3); | |
4145 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4146 | ncid=Netcdf_var->ncid; | |
4147 | varid=Netcdf_var->varid; | |
4148 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4149 | if(status != NC_NOERR) NC_RAISE(status); | |
4150 | ||
4151 | dimids=ALLOCA_N(int,ndims); | |
4152 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4153 | if(status != NC_NOERR) NC_RAISE(status); | |
4154 | ||
4155 | Check_Type(start,T_ARRAY); | |
4156 | if(RARRAY_LEN(start) < ndims) { | |
4157 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4158 | } | |
4159 | c_start=ALLOCA_N(size_t,ndims); | |
4160 | for(i=0; i<ndims; i++){ | |
4161 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4162 | ||
4163 | if(l_start < 0) { | |
4164 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4165 | if(status != NC_NOERR) NC_RAISE(status); | |
4166 | l_start += dimlen; | |
4167 | } | |
4168 | c_start[i]=l_start; | |
4169 | } | |
4170 | ||
4171 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4172 | switch(TYPE(stride)){ | |
4173 | case T_NIL: | |
4174 | for(i=0; i<ndims; i++){ | |
4175 | c_stride[i]=1; | |
4176 | } | |
4177 | break; | |
4178 | default: | |
4179 | Check_Type(stride,T_ARRAY); | |
4180 | if(RARRAY_LEN(stride) < ndims) { | |
4181 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4182 | } | |
4183 | for(i=0; i<ndims; i++){ | |
4184 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4185 | if(c_stride[i]==0) { | |
4186 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4187 | } | |
4188 | } | |
4189 | } | |
4190 | ||
4191 | Array_to_Csint_len_shape(NArray,ptr,len,shape); | |
4192 | ||
4193 | c_count=ALLOCA_N(size_t,ndims); | |
4194 | switch(TYPE(end)){ | |
4195 | case T_NIL: | |
4196 | for(i=0; i<ndims; i++){ | |
4197 | c_count[i]=shape[i]; | |
4198 | } | |
4199 | c_count_all=len; | |
4200 | break; | |
4201 | default: | |
4202 | Check_Type(end,T_ARRAY); | |
4203 | if(RARRAY_LEN(end) < ndims) { | |
4204 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4205 | } | |
4206 | for(i=0; i<ndims; i++){ | |
4207 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4208 | if(l_end < 0) { | |
4209 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4210 | if(status != NC_NOERR) NC_RAISE(status); | |
4211 | l_end += dimlen; | |
4212 | } | |
4213 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4214 | c_count_all=c_count[i]*c_count_all; | |
4215 | } | |
4216 | if(len == 1 && len != c_count_all){ | |
4217 | scalar = *ptr; | |
4218 | ptr = ALLOCA_N(short,c_count_all); | |
4219 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4220 | } else if(len != c_count_all) { | |
4221 | rb_raise(rb_eNetcdfError, | |
4222 | "lengh of the array does not agree with that of the subset\n"); | |
4223 | } | |
4224 | } | |
4225 | ||
4226 | status = nc_put_vars_short(ncid,varid,c_start,c_count,c_stride,ptr); | |
4227 | if(status != NC_NOERR) NC_RAISE(status); | |
4228 | return Qnil; | |
4229 | } | |
4230 | ||
4231 | ||
4232 | VALUE | |
4233 | NetCDF_put_vars_int(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4234 | { | |
4235 | int ncid; | |
4236 | int varid; | |
4237 | int status; | |
4238 | int *ptr,scalar; | |
4239 | na_shape_t len; | |
4240 | int c_count_all=1; | |
4241 | struct NetCDFVar *Netcdf_var; | |
4242 | na_shape_t l_start, l_end; | |
4243 | size_t *c_start; | |
4244 | size_t *c_count; | |
4245 | ptrdiff_t *c_stride; | |
4246 | int ndims,i; | |
4247 | na_shape_t *shape; | |
4248 | int *dimids; | |
4249 | size_t dimlen; | |
4250 | ||
4251 | rb_secure(3); | |
4252 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4253 | ncid=Netcdf_var->ncid; | |
4254 | varid=Netcdf_var->varid; | |
4255 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4256 | if(status != NC_NOERR) NC_RAISE(status); | |
4257 | ||
4258 | dimids=ALLOCA_N(int,ndims); | |
4259 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4260 | if(status != NC_NOERR) NC_RAISE(status); | |
4261 | ||
4262 | Check_Type(start,T_ARRAY); | |
4263 | if(RARRAY_LEN(start) < ndims) { | |
4264 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4265 | } | |
4266 | c_start=ALLOCA_N(size_t,ndims); | |
4267 | for(i=0; i<ndims; i++){ | |
4268 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4269 | ||
4270 | if(l_start < 0) { | |
4271 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4272 | if(status != NC_NOERR) NC_RAISE(status); | |
4273 | l_start += dimlen; | |
4274 | } | |
4275 | c_start[i]=l_start; | |
4276 | } | |
4277 | ||
4278 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4279 | switch(TYPE(stride)){ | |
4280 | case T_NIL: | |
4281 | for(i=0; i<ndims; i++){ | |
4282 | c_stride[i]=1; | |
4283 | } | |
4284 | break; | |
4285 | default: | |
4286 | Check_Type(stride,T_ARRAY); | |
4287 | if(RARRAY_LEN(stride) < ndims) { | |
4288 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4289 | } | |
4290 | for(i=0; i<ndims; i++){ | |
4291 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4292 | if(c_stride[i]==0) { | |
4293 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4294 | } | |
4295 | } | |
4296 | } | |
4297 | ||
4298 | Array_to_Clint_len_shape(NArray,ptr,len,shape); | |
4299 | ||
4300 | c_count=ALLOCA_N(size_t,ndims); | |
4301 | switch(TYPE(end)){ | |
4302 | case T_NIL: | |
4303 | for(i=0; i<ndims; i++){ | |
4304 | c_count[i]=shape[i]; | |
4305 | } | |
4306 | c_count_all=len; | |
4307 | break; | |
4308 | default: | |
4309 | Check_Type(end,T_ARRAY); | |
4310 | if(RARRAY_LEN(end) < ndims) { | |
4311 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4312 | } | |
4313 | for(i=0; i<ndims; i++){ | |
4314 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4315 | if(l_end < 0) { | |
4316 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4317 | if(status != NC_NOERR) NC_RAISE(status); | |
4318 | l_end += dimlen; | |
4319 | } | |
4320 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4321 | c_count_all=c_count[i]*c_count_all; | |
4322 | } | |
4323 | if(len == 1 && len != c_count_all){ | |
4324 | scalar = *ptr; | |
4325 | ptr = ALLOCA_N(int,c_count_all); | |
4326 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4327 | } else if(len != c_count_all) { | |
4328 | rb_raise(rb_eNetcdfError, | |
4329 | "length of the array does not agree with that of the subset\n"); | |
4330 | } | |
4331 | } | |
4332 | ||
4333 | status = nc_put_vars_int(ncid,varid,c_start,c_count,c_stride,ptr); | |
4334 | if(status != NC_NOERR) NC_RAISE(status); | |
4335 | return Qnil; | |
4336 | } | |
4337 | ||
4338 | ||
4339 | VALUE | |
4340 | NetCDF_put_vars_float(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4341 | { | |
4342 | int ncid; | |
4343 | int varid; | |
4344 | int status; | |
4345 | float *ptr,scalar; | |
4346 | na_shape_t len; | |
4347 | int c_count_all=1; | |
4348 | struct NetCDFVar *Netcdf_var; | |
4349 | na_shape_t l_start, l_end; | |
4350 | size_t *c_start; | |
4351 | size_t *c_count; | |
4352 | ptrdiff_t *c_stride; | |
4353 | int ndims,i; | |
4354 | na_shape_t *shape; | |
4355 | int *dimids; | |
4356 | size_t dimlen; | |
4357 | ||
4358 | rb_secure(3); | |
4359 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4360 | ncid=Netcdf_var->ncid; | |
4361 | varid=Netcdf_var->varid; | |
4362 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4363 | if(status != NC_NOERR) NC_RAISE(status); | |
4364 | ||
4365 | dimids=ALLOCA_N(int,ndims); | |
4366 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4367 | if(status != NC_NOERR) NC_RAISE(status); | |
4368 | ||
4369 | Check_Type(start,T_ARRAY); | |
4370 | if(RARRAY_LEN(start) < ndims) { | |
4371 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4372 | } | |
4373 | c_start=ALLOCA_N(size_t,ndims); | |
4374 | for(i=0; i<ndims; i++){ | |
4375 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4376 | ||
4377 | if(l_start < 0) { | |
4378 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4379 | if(status != NC_NOERR) NC_RAISE(status); | |
4380 | l_start += dimlen; | |
4381 | } | |
4382 | c_start[i]=l_start; | |
4383 | } | |
4384 | ||
4385 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4386 | switch(TYPE(stride)){ | |
4387 | case T_NIL: | |
4388 | for(i=0; i<ndims; i++){ | |
4389 | c_stride[i]=1; | |
4390 | } | |
4391 | break; | |
4392 | default: | |
4393 | Check_Type(stride,T_ARRAY); | |
4394 | if(RARRAY_LEN(stride) < ndims) { | |
4395 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4396 | } | |
4397 | for(i=0; i<ndims; i++){ | |
4398 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4399 | if(c_stride[i]==0) { | |
4400 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4401 | } | |
4402 | } | |
4403 | } | |
4404 | ||
4405 | Array_to_Cfloat_len_shape(NArray,ptr,len,shape); | |
4406 | ||
4407 | c_count=ALLOCA_N(size_t,ndims); | |
4408 | switch(TYPE(end)){ | |
4409 | case T_NIL: | |
4410 | for(i=0; i<ndims; i++){ | |
4411 | c_count[i]=shape[i]; | |
4412 | } | |
4413 | c_count_all=len; | |
4414 | break; | |
4415 | default: | |
4416 | Check_Type(end,T_ARRAY); | |
4417 | if(RARRAY_LEN(end) < ndims) { | |
4418 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4419 | } | |
4420 | for(i=0; i<ndims; i++){ | |
4421 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4422 | if(l_end < 0) { | |
4423 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4424 | if(status != NC_NOERR) NC_RAISE(status); | |
4425 | l_end += dimlen; | |
4426 | } | |
4427 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4428 | c_count_all=c_count[i]*c_count_all; | |
4429 | } | |
4430 | if(len == 1 && len != c_count_all){ | |
4431 | scalar = *ptr; | |
4432 | ptr = ALLOCA_N(float,c_count_all); | |
4433 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4434 | } else if(len != c_count_all) { | |
4435 | rb_raise(rb_eNetcdfError, | |
4436 | "lengh of the array does not agree with that of the subset\n"); | |
4437 | } | |
4438 | } | |
4439 | ||
4440 | status = nc_put_vars_float(ncid,varid,c_start,c_count,c_stride,ptr); | |
4441 | if(status != NC_NOERR) NC_RAISE(status); | |
4442 | return Qnil; | |
4443 | } | |
4444 | ||
4445 | ||
4446 | VALUE | |
4447 | NetCDF_put_vars_double(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4448 | { | |
4449 | int ncid; | |
4450 | int varid; | |
4451 | int status; | |
4452 | double *ptr,scalar; | |
4453 | na_shape_t len; | |
4454 | int c_count_all=1; | |
4455 | struct NetCDFVar *Netcdf_var; | |
4456 | na_shape_t l_start, l_end; | |
4457 | size_t *c_start; | |
4458 | size_t *c_count; | |
4459 | ptrdiff_t *c_stride; | |
4460 | int ndims,i; | |
4461 | na_shape_t *shape; | |
4462 | int *dimids; | |
4463 | size_t dimlen; | |
4464 | ||
4465 | rb_secure(3); | |
4466 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4467 | ncid=Netcdf_var->ncid; | |
4468 | varid=Netcdf_var->varid; | |
4469 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4470 | if(status != NC_NOERR) NC_RAISE(status); | |
4471 | ||
4472 | dimids=ALLOCA_N(int,ndims); | |
4473 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4474 | if(status != NC_NOERR) NC_RAISE(status); | |
4475 | ||
4476 | Check_Type(start,T_ARRAY); | |
4477 | if(RARRAY_LEN(start) < ndims) { | |
4478 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4479 | } | |
4480 | c_start=ALLOCA_N(size_t,ndims); | |
4481 | for(i=0; i<ndims; i++){ | |
4482 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4483 | ||
4484 | if(l_start < 0) { | |
4485 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4486 | if(status != NC_NOERR) NC_RAISE(status); | |
4487 | l_start += dimlen; | |
4488 | } | |
4489 | c_start[i]=l_start; | |
4490 | } | |
4491 | ||
4492 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4493 | switch(TYPE(stride)){ | |
4494 | case T_NIL: | |
4495 | for(i=0; i<ndims; i++){ | |
4496 | c_stride[i]=1; | |
4497 | } | |
4498 | break; | |
4499 | default: | |
4500 | Check_Type(stride,T_ARRAY); | |
4501 | if(RARRAY_LEN(stride) < ndims) { | |
4502 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4503 | } | |
4504 | for(i=0; i<ndims; i++){ | |
4505 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4506 | if(c_stride[i]==0) { | |
4507 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4508 | } | |
4509 | } | |
4510 | } | |
4511 | ||
4512 | Array_to_Cdouble_len_shape(NArray,ptr,len,shape); | |
4513 | ||
4514 | c_count=ALLOCA_N(size_t,ndims); | |
4515 | switch(TYPE(end)){ | |
4516 | case T_NIL: | |
4517 | for(i=0; i<ndims; i++){ | |
4518 | c_count[i]=shape[i]; | |
4519 | } | |
4520 | c_count_all=len; | |
4521 | break; | |
4522 | default: | |
4523 | Check_Type(end,T_ARRAY); | |
4524 | if(RARRAY_LEN(end) < ndims) { | |
4525 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4526 | } | |
4527 | for(i=0; i<ndims; i++){ | |
4528 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4529 | if(l_end < 0) { | |
4530 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4531 | if(status != NC_NOERR) NC_RAISE(status); | |
4532 | l_end += dimlen; | |
4533 | } | |
4534 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4535 | c_count_all=c_count[i]*c_count_all; | |
4536 | } | |
4537 | if(len == 1 && len != c_count_all){ | |
4538 | scalar = *ptr; | |
4539 | ptr = ALLOCA_N(double,c_count_all); | |
4540 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4541 | } else if(len != c_count_all) { | |
4542 | rb_raise(rb_eNetcdfError, | |
4543 | "lengh of the array does not agree with that of the subset\n"); | |
4544 | } | |
4545 | } | |
4546 | ||
4547 | status = nc_put_vars_double(ncid,varid,c_start,c_count,c_stride,ptr); | |
4548 | if(status != NC_NOERR) NC_RAISE(status); | |
4549 | return Qnil; | |
4550 | } | |
4551 | ||
4552 | void | |
4553 | Init_netcdfraw(void) | |
4554 | { | |
4555 | mNumRu = rb_define_module("NumRu"); | |
4556 | ||
4557 | /* Difinitions of the classes */ | |
4558 | cNetCDF = rb_define_class_under(mNumRu, "NetCDF", rb_cObject); | |
4559 | cNetCDFDim = rb_define_class_under(mNumRu, "NetCDFDim", rb_cObject); | |
4560 | cNetCDFAtt = rb_define_class_under(mNumRu, "NetCDFAtt", rb_cObject); | |
4561 | cNetCDFVar = rb_define_class_under(mNumRu, "NetCDFVar", rb_cObject); | |
4562 | ||
4563 | rb_eNetcdfError = rb_define_class("NetcdfError",rb_eStandardError); | |
4564 | rb_eNetcdfBadid = rb_define_class("NetcdfBadid",rb_eNetcdfError); | |
4565 | rb_eNetcdfNfile = rb_define_class("NetcdfNfile",rb_eNetcdfError); | |
4566 | rb_eNetcdfExist = rb_define_class("NetcdfExist",rb_eNetcdfError); | |
4567 | rb_eNetcdfInval = rb_define_class("NetcdfInval",rb_eNetcdfError); | |
4568 | rb_eNetcdfPerm = rb_define_class("NetcdfPerm",rb_eNetcdfError); | |
4569 | rb_eNetcdfNotindefine = rb_define_class("NetcdfNotindefine",rb_eNetcdfError); | |
4570 | rb_eNetcdfIndefine = rb_define_class("NetcdfIndefine",rb_eNetcdfError); | |
4571 | rb_eNetcdfInvalcoords = rb_define_class("NetcdfInvalcoords",rb_eNetcdfError); | |
4572 | rb_eNetcdfMaxdims = rb_define_class("NetcdfMaxdims",rb_eNetcdfError); | |
4573 | rb_eNetcdfNameinuse = rb_define_class("NetcdfNameinuse",rb_eNetcdfError); | |
4574 | rb_eNetcdfNotatt = rb_define_class("NetcdfNotatt",rb_eNetcdfError); | |
4575 | rb_eNetcdfMaxatts = rb_define_class("NetcdfMaxatts",rb_eNetcdfError); | |
4576 | rb_eNetcdfBadtype = rb_define_class("NetcdfBadtype",rb_eNetcdfError); | |
4577 | rb_eNetcdfBaddim = rb_define_class("NetcdfBaddim",rb_eNetcdfError); | |
4578 | rb_eNetcdfUnlimpos = rb_define_class("NetcdFUnlimpos",rb_eNetcdfError); | |
4579 | rb_eNetcdfMaxvars = rb_define_class("NetcdfMaxvars",rb_eNetcdfError); | |
4580 | rb_eNetcdfNotvar = rb_define_class("NetcdfNotvar",rb_eNetcdfError); | |
4581 | rb_eNetcdfGlobal = rb_define_class("NetcdfGlobal",rb_eNetcdfError); | |
4582 | rb_eNetcdfNotnc = rb_define_class("NetcdfNotnc",rb_eNetcdfError); | |
4583 | rb_eNetcdfSts = rb_define_class("NetcdfSts",rb_eNetcdfError); | |
4584 | rb_eNetcdfMaxname = rb_define_class("NetcdfMaxname",rb_eNetcdfError); | |
4585 | rb_eNetcdfUnlimit = rb_define_class("NetcdfUnlimit",rb_eNetcdfError); | |
4586 | rb_eNetcdfNorecvars = rb_define_class("NetcdfNorecvars",rb_eNetcdfError); | |
4587 | rb_eNetcdfChar = rb_define_class("NetcdfChar",rb_eNetcdfError); | |
4588 | rb_eNetcdfEdge = rb_define_class("NetcdfEdge",rb_eNetcdfError); | |
4589 | rb_eNetcdfStride = rb_define_class("NetcdfStride",rb_eNetcdfError); | |
4590 | rb_eNetcdfBadname = rb_define_class("NetcdfBadname",rb_eNetcdfError); | |
4591 | /* N.B. following must match value in ncx.h */ | |
4592 | rb_eNetcdfRange = rb_define_class("NetcdfRange",rb_eNetcdfError); | |
4593 | rb_eNetcdfNomem = rb_define_class("NetcdfNomem",rb_eNetcdfError); | |
4594 | /* Global error status */ | |
4595 | rb_eNetcdfEntool = rb_define_class("NetcdfEntool",rb_eNetcdfError); | |
4596 | rb_eNetcdfExdr = rb_define_class("NetcdfExdr",rb_eNetcdfError); | |
4597 | rb_eNetcdfSyserr = rb_define_class("NetcdfSyserr",rb_eNetcdfError); | |
4598 | /* Global options variable. Used to determine behavior of error handler. */ | |
4599 | rb_eNetcdfFatal = rb_define_class("NetcdfFatal",rb_eNetcdfError); | |
4600 | ||
4601 | /* Class Constants Definition */ | |
4602 | rb_define_const(cNetCDF, "NC_NOWRITE", INT2FIX(NC_NOWRITE)); | |
4603 | rb_define_const(cNetCDF, "NC_WRITE", INT2FIX(NC_WRITE)); | |
4604 | rb_define_const(cNetCDF, "NC_SHARE", INT2FIX(NC_SHARE)); | |
4605 | rb_define_const(cNetCDF, "NC_CLOBBER", INT2FIX(NC_CLOBBER)); | |
4606 | rb_define_const(cNetCDF, "NC_NOCLOBBER", INT2FIX(NC_NOCLOBBER)); | |
4607 | #if NCVER >= 400 | |
4608 | rb_define_const(cNetCDF, "NC_64BIT_OFFSET", INT2FIX(NC_64BIT_OFFSET)); | |
4609 | /* NC_64BIT_OFFSET supports large files in the class data format */ | |
4610 | rb_define_const(cNetCDF, "NC_NETCDF4", INT2FIX(NC_NETCDF4)); | |
4611 | rb_define_const(cNetCDF, "NC_CLASSIC_MODEL", INT2FIX(NC_CLASSIC_MODEL)); | |
4612 | /* for use as ( NC_NETCDF4 | NC_CLASSIC_MODEL ) to ensure the classic | |
4613 | data model in NetCDF4 by disabling new features like groups */ | |
4614 | rb_define_const(cNetCDF, "NC_ENDIAN_NATIVE", INT2FIX(NC_ENDIAN_NATIVE)); | |
4615 | rb_define_const(cNetCDF, "NC_ENDIAN_LITTLE", INT2FIX(NC_ENDIAN_LITTLE)); | |
4616 | rb_define_const(cNetCDF, "NC_ENDIAN_BIG", INT2FIX(NC_ENDIAN_BIG)); | |
4617 | ||
4618 | rb_define_const(cNetCDF, "NC_FORMAT_CLASSIC", INT2FIX(NC_FORMAT_CLASSIC)); | |
4619 | rb_define_const(cNetCDF, "NC_FORMAT_64BIT", INT2FIX(NC_FORMAT_64BIT)); | |
4620 | rb_define_const(cNetCDF, "NC_FORMAT_NETCDF4", INT2FIX(NC_FORMAT_NETCDF4)); | |
4621 | rb_define_const(cNetCDF, "NC_FORMAT_NETCDF4_CLASSIC", INT2FIX(NC_FORMAT_NETCDF4_CLASSIC)); | |
4622 | #endif | |
4623 | ||
4624 | #ifdef NARRAY_BIGMEM | |
4625 | rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qtrue); | |
4626 | #else | |
4627 | rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qfalse); | |
4628 | #endif | |
4629 | ||
4630 | /* Difinitions of the ruby methods */ | |
4631 | /* The methods of the NetCDF class */ | |
4632 | rb_define_singleton_method(cNetCDF,"libvers",NetCDF_inq_libvers,0); | |
4633 | rb_define_singleton_method(cNetCDF,"nc_open",NetCDF_open,2); | |
4634 | rb_define_method(cNetCDF,"clone",NetCDF_clone,0); | |
4635 | rb_define_method(cNetCDF,"close",NetCDF_close,0); | |
4636 | /* rb_define_singleton_method(cNetCDF,"new",NetCDF_open,2); */ | |
4637 | rb_define_singleton_method(cNetCDF,"nc_create",NetCDF_create,2); | |
4638 | rb_define_method(cNetCDF,"def_dim",NetCDF_def_dim,2); | |
4639 | rb_define_method(cNetCDF,"def_var",NetCDF_def_var,3); | |
4640 | rb_define_method(cNetCDF,"put_attraw",NetCDF_put_att,3); | |
4641 | rb_define_method(cNetCDF,"redef",NetCDF_redef,0); | |
4642 | rb_define_method(cNetCDF,"enddef",NetCDF_enddef,0); | |
4643 | rb_define_method(cNetCDF,"define_mode?",NetCDF_whether_in_define_mode,0); | |
4644 | rb_define_method(cNetCDF,"fill",NetCDF_fill,1); | |
4645 | rb_define_method(cNetCDF,"ndims",NetCDF_ndims,0); | |
4646 | rb_define_method(cNetCDF,"nvars",NetCDF_nvars,0); | |
4647 | rb_define_method(cNetCDF,"natts",NetCDF_natts,0); | |
4648 | #if NCVER >= 400 | |
4649 | rb_define_method(cNetCDF,"format",NetCDF_format,0); | |
4650 | #endif | |
4651 | rb_define_method(cNetCDF,"sync",NetCDF_sync,0); | |
4652 | rb_define_method(cNetCDF,"path",NetCDF_path,0); | |
4653 | rb_define_method(cNetCDF,"dim",NetCDF_dim,1); | |
4654 | rb_define_method(cNetCDF,"var",NetCDF_var,1); | |
4655 | rb_define_method(cNetCDF,"att",NetCDF_att,1); | |
4656 | rb_define_method(cNetCDF,"unlimited",NetCDF_unlimited,0); | |
4657 | rb_define_private_method(cNetCDF,"id2var",NetCDF_id2var,1); | |
4658 | rb_define_private_method(cNetCDF,"id2dim",NetCDF_id2dim,1); | |
4659 | rb_define_private_method(cNetCDF,"id2att",NetCDF_id2att,1); | |
4660 | rb_define_method(cNetCDF,"==",NetCDF_eql,1); | |
4661 | /* rb_define_method(cNetCDF,"eql?",NetCDF_eql,1); */ | |
4662 | ||
4663 | /* The methods of the NetCDFDim class */ | |
4664 | rb_define_method(cNetCDFDim,"clone",NetCDF_dim_clone,0); | |
4665 | rb_define_method(cNetCDFDim,"length",NetCDF_dim_length,0); | |
4666 | rb_define_method(cNetCDFDim,"name=",NetCDF_dim_name,1); | |
4667 | rb_define_method(cNetCDFDim,"name",NetCDF_dim_inqname,0); | |
4668 | rb_define_method(cNetCDFDim,"unlimited?",NetCDF_dim_whether_unlimited,0); | |
4669 | rb_define_method(cNetCDFDim,"==",NetCDF_dim_eql,1); | |
4670 | /* rb_define_method(cNetCDFDim,"eql?",NetCDF_dim_eql,1); */ | |
4671 | ||
4672 | /* The methods of the NetCDFAtt class */ | |
4673 | rb_define_method(cNetCDFAtt,"clone",NetCDF_att_clone,0); | |
4674 | rb_define_method(cNetCDFAtt,"name",NetCDF_att_inq_name,0); | |
4675 | rb_define_method(cNetCDFAtt,"name=",NetCDF_att_rename,1); | |
4676 | rb_define_method(cNetCDFAtt,"delete",NetCDF_att_delete,0); | |
4677 | rb_define_method(cNetCDFAtt,"copy",NetCDF_att_copy,1); | |
4678 | rb_define_method(cNetCDFAtt,"atttype",NetCDF_att_atttype,0); | |
4679 | rb_define_method(cNetCDFAtt,"typecode",NetCDF_att_typecode,0); | |
4680 | rb_define_method(cNetCDFAtt,"==",NetCDF_att_eql,1); | |
4681 | /* rb_define_method(cNetCDFAtt,"eql?",NetCDF_att_eql,1); */ | |
4682 | rb_define_method(cNetCDFAtt,"putraw",NetCDF_att_put,2); | |
4683 | rb_define_method(cNetCDFAtt,"get",NetCDF_att_get,0); | |
4684 | ||
4685 | /* The methods of the NetCDFVar class */ | |
4686 | #if NCVER >= 400 | |
4687 | rb_define_method(cNetCDFVar,"deflate",NetCDF_var_deflate,-1); | |
4688 | rb_define_method(cNetCDFVar,"deflate_params",NetCDF_var_deflate_params,0); | |
4689 | rb_define_method(cNetCDFVar,"endian=",NetCDF_var_set_endian,1); | |
4690 | rb_define_method(cNetCDFVar,"endian",NetCDF_var_endian,0); | |
4691 | #endif | |
4692 | rb_define_method(cNetCDFVar,"clone",NetCDF_var_clone,0); | |
4693 | rb_define_method(cNetCDFVar,"name",NetCDF_var_inq_name,0); | |
4694 | rb_define_method(cNetCDFVar,"ndims",NetCDF_var_ndims,0); | |
4695 | rb_define_method(cNetCDFVar,"vartype",NetCDF_var_vartype,0); | |
4696 | rb_define_method(cNetCDFVar,"typecode",NetCDF_var_typecode,0); | |
4697 | rb_define_method(cNetCDFVar,"ntype",NetCDF_var_vartype,0); | |
4698 | rb_define_method(cNetCDFVar,"natts",NetCDF_var_natts,0); | |
4699 | rb_define_method(cNetCDFVar,"file",NetCDF_var_file,0); | |
4700 | rb_define_method(cNetCDFVar,"name=",NetCDF_var_rename,1); | |
4701 | rb_define_method(cNetCDFVar,"att",NetCDF_var_att,1); | |
4702 | rb_define_method(cNetCDFVar,"put_attraw",NetCDF_put_att_var,3); | |
4703 | rb_define_method(cNetCDFVar,"dims",NetCDF_var_dims,0); | |
4704 | rb_define_method(cNetCDFVar,"dim",NetCDF_var_dim,1); | |
4705 | /*rb_define_private_method(cNetCDFVar,"id2dim",NetCDF_var_id2dim,1); */ | |
4706 | rb_define_private_method(cNetCDFVar,"id2att",NetCDF_var_id2att,1); | |
4707 | rb_define_method(cNetCDFVar,"==",NetCDF_var_eql,1); | |
4708 | /* rb_define_method(cNetCDFVar,"eql?",NetCDF_var_eql,1); */ | |
4709 | ||
4710 | /* The "get*" or "put*" methods in the NetCDFVar class */ | |
4711 | rb_define_method(cNetCDFVar,"put_var_char",NetCDF_put_var_char,1); | |
4712 | rb_define_method(cNetCDFVar,"put_var_byte",NetCDF_put_var_byte,1); | |
4713 | rb_define_method(cNetCDFVar,"put_var_sint",NetCDF_put_var_short,1); | |
4714 | rb_define_method(cNetCDFVar,"put_var_int",NetCDF_put_var_int,1); | |
4715 | rb_define_method(cNetCDFVar,"put_var_sfloat",NetCDF_put_var_float,1); | |
4716 | rb_define_method(cNetCDFVar,"put_var_float",NetCDF_put_var_double,1); | |
4717 | ||
4718 | rb_define_method(cNetCDFVar,"put_vars_char",NetCDF_put_vars_char,4); | |
4719 | rb_define_method(cNetCDFVar,"put_vars_byte",NetCDF_put_vars_byte,4); | |
4720 | rb_define_method(cNetCDFVar,"put_vars_sint",NetCDF_put_vars_sint,4); | |
4721 | rb_define_method(cNetCDFVar,"put_vars_int",NetCDF_put_vars_int,4); | |
4722 | rb_define_method(cNetCDFVar,"put_vars_sfloat",NetCDF_put_vars_float,4); | |
4723 | rb_define_method(cNetCDFVar,"put_vars_float",NetCDF_put_vars_double,4); | |
4724 | ||
4725 | rb_define_method(cNetCDFVar,"put_var1_char",NetCDF_put_var1_char,2); | |
4726 | rb_define_method(cNetCDFVar,"put_var1_byte",NetCDF_put_var1_byte,2); | |
4727 | rb_define_method(cNetCDFVar,"put_var1_sint",NetCDF_put_var1_sint,2); | |
4728 | rb_define_method(cNetCDFVar,"put_var1_int",NetCDF_put_var1_int,2); | |
4729 | rb_define_method(cNetCDFVar,"put_var1_sfloat",NetCDF_put_var1_float,2); | |
4730 | rb_define_method(cNetCDFVar,"put_var1_float",NetCDF_put_var1_double,2); | |
4731 | ||
4732 | rb_define_method(cNetCDFVar,"get_var_char",NetCDF_get_var_char,0); | |
4733 | rb_define_method(cNetCDFVar,"get_var_byte",NetCDF_get_var_byte,0); | |
4734 | rb_define_method(cNetCDFVar,"get_var_sint",NetCDF_get_var_sint,0); | |
4735 | rb_define_method(cNetCDFVar,"get_var_int",NetCDF_get_var_int,0); | |
4736 | rb_define_method(cNetCDFVar,"get_var_sfloat",NetCDF_get_var_float,0); | |
4737 | rb_define_method(cNetCDFVar,"get_var_float",NetCDF_get_var_double,0); | |
4738 | ||
4739 | rb_define_method(cNetCDFVar,"get_vars_char",NetCDF_get_vars_char,3); | |
4740 | rb_define_method(cNetCDFVar,"get_vars_byte",NetCDF_get_vars_byte,3); | |
4741 | rb_define_method(cNetCDFVar,"get_vars_sint",NetCDF_get_vars_sint,3); | |
4742 | rb_define_method(cNetCDFVar,"get_vars_int",NetCDF_get_vars_int,3); | |
4743 | rb_define_method(cNetCDFVar,"get_vars_sfloat",NetCDF_get_vars_float,3); | |
4744 | rb_define_method(cNetCDFVar,"get_vars_float",NetCDF_get_vars_double,3); | |
4745 | ||
4746 | rb_define_method(cNetCDFVar,"get_var1_char",NetCDF_get_var1_char,1); | |
4747 | rb_define_method(cNetCDFVar,"get_var1_byte",NetCDF_get_var1_byte,1); | |
4748 | rb_define_method(cNetCDFVar,"get_var1_sint",NetCDF_get_var1_sint,1); | |
4749 | rb_define_method(cNetCDFVar,"get_var1_int",NetCDF_get_var1_int,1); | |
4750 | rb_define_method(cNetCDFVar,"get_var1_sfloat",NetCDF_get_var1_float,1); | |
4751 | rb_define_method(cNetCDFVar,"get_var1_float",NetCDF_get_var1_double,1); | |
4752 | } |
0 | require "mkmf" | |
1 | require "rubygems" unless defined?(Gem) | |
2 | ||
3 | ar = ARGV.grep( /^--with-netcdf-version=/ ) | |
4 | if ar.length > 0 | |
5 | ncversion = ar[0].sub(/^--with-netcdf-version=/,"") | |
6 | else | |
7 | ncversion = nil | |
8 | end | |
9 | ||
10 | if Gem.respond_to?(:find_files) | |
11 | require "rbconfig" | |
12 | so = RbConfig::CONFIG["DLEXT"] | |
13 | narray_include = File.expand_path(File.dirname(Gem.find_files("narray.h")[0])) | |
14 | narray_lib = File.expand_path(File.dirname(Gem.find_files("narray." + so)[0])) | |
15 | else | |
16 | gem_home=(`gem environment GEM_HOME`).chomp | |
17 | narray_dir = Dir.glob("#{gem_home}/gems/narray-*").sort[-1] | |
18 | if narray_dir | |
19 | narray_include = narray_lib = narray_dir | |
20 | else | |
21 | narray_include = narray_lib = [ $sitearchdir, $vendorarchdir] | |
22 | end | |
23 | end | |
24 | dir_config('narray', narray_include, narray_lib) | |
25 | ||
26 | dir_config('netcdf', '/usr/local') | |
27 | ||
28 | if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then | |
29 | print <<EOS | |
30 | ** configure error ** | |
31 | Header narray.h or narray_config.h is not found. If you have these files in | |
32 | /narraydir/include, try the following: | |
33 | ||
34 | % ruby extconf.rb --with-narray-include=/narraydir/include | |
35 | ||
36 | EOS | |
37 | exit(-1) | |
38 | end | |
39 | ||
40 | unless ncversion | |
41 | # configure netcdf version | |
42 | if xsystem("nc-config --version") | |
43 | ncversion = `nc-config --version`.chomp!.sub!(/^n.* /i,"") # rm "netCDF " | |
44 | ncversion.sub!(/^([^\.]+\.[^\.]+\.[^\.]+).+$/,'\1') # e.g. 4.2.1.1 -> 4.2.1 | |
45 | else | |
46 | ncversion = "3.0.0" # assume version 3 (only for compilation) | |
47 | # For compilation, there is no difference among subversions of netcdf 3 | |
48 | end | |
49 | end | |
50 | ||
51 | ncver0 = ncversion[0..0] # "3" or "4" | |
52 | ncver = ncversion.gsub(/\./,'') | |
53 | unless /^\d\d\d$/ =~ ncver # 3 digits | |
54 | raise("Invalid netcdf version: #{ncversion}. Use --with-netcdf-version=") | |
55 | end | |
56 | $CFLAGS += ' -DNCVER='+ncver | |
57 | ||
58 | case ncver0 | |
59 | when "4" | |
60 | if xsystem("nc-config --libs") # for NetCDF 4 | |
61 | cflags = `nc-config --cflags`.gsub(/\n/, " ") | |
62 | libs = `nc-config --libs`.gsub(/\n/, " ") | |
63 | prefix_nc = `nc-config --prefix`.gsub(/\n/, "") | |
64 | ||
65 | dir_config("netcdf",prefix_nc) | |
66 | $CFLAGS += ' ' + cflags | |
67 | $LOCAL_LIBS += ' ' + libs | |
68 | end | |
69 | when "3" | |
70 | # for NetCDF 3, which needs external libraries for OpenDAP | |
71 | if xsystem("ncdap-config --libs") | |
72 | libncdods = "nc-dap" | |
73 | cflags = `ncdap-config --cflags`.gsub(/\n/, " ") | |
74 | libs = `ncdap-config --libs`.gsub(/\n/, " ") | |
75 | prefix_dods = `ncdap-config --prefix`.gsub(/\n/, "") | |
76 | elsif xsystem("opendap-config --libs") | |
77 | libncdods = "nc-dods" | |
78 | cflags = `opendap-config --cflags`.gsub(/\n/, " ") | |
79 | libs = `opendap-config --libs-nc`.gsub(/\n/, " ") | |
80 | prefix_dods = `opendap-config --prefix`.gsub(/\n/, "") | |
81 | end | |
82 | if (enable_config('opendap',true) && ( xsystem("opendap-config --libs") || | |
83 | xsystem("ncdap-config --libs") ) ) | |
84 | ||
85 | dir_config(libncdods,prefix_dods) | |
86 | ||
87 | if (!have_library(libncdods)) | |
88 | print <<-EOS | |
89 | ** ERROR ** Library not found: nc-dods (OPeNDAP/DODS-enabled NetCDF lib) | |
90 | Install it, or run extconf.rb with option --disable-opendap. | |
91 | ^^^^^^^^^^^^^^^^^ | |
92 | EOS | |
93 | exit(-1) | |
94 | else | |
95 | print <<-EOS | |
96 | ** Message ** Compiling with OPeNDAP/DODS-enabled NetCDF library. | |
97 | ||
98 | This is because the command opendap-config is found in your system. | |
99 | If you want to use the ordinary (non-DODS) version of NetCDF, | |
100 | run extconf.rb with option --disable-opendap. | |
101 | ^^^^^^^^^^^^^^^^^ | |
102 | EOS | |
103 | end | |
104 | ||
105 | $CFLAGS += ' '+cflags | |
106 | $LOCAL_LIBS += ' ' + libs | |
107 | ||
108 | # non portable treatments: should be improved (by Horinouchi) | |
109 | CONFIG['LDSHARED'].sub!(/gcc/,'g++') | |
110 | $LIBS.sub!(/-lc\s/,'') ; $LIBS.sub!(/-lc$/,'') | |
111 | print <<-EOS | |
112 | ** Warning ** non-portable treatments are made, | |
113 | which was sucessfull redhat linux 9: | |
114 | * gcc was replaced with g++ in CONFIG['LDSHARED'] | |
115 | * -lc library was removed if in $LIBS | |
116 | ||
117 | EOS | |
118 | # p '@@@' | |
119 | # ary = [] | |
120 | # CONFIG.each{|k,v| ary.push([k,v])} | |
121 | # ary.sort.each{|x| p x} | |
122 | else | |
123 | if ( ! ( have_header("netcdf.h") && have_library("netcdf") ) )then | |
124 | print <<-EOS | |
125 | ** configure error ** | |
126 | Header netcdf.h or the compiled netcdf library is not found. | |
127 | If you have the library installed under /netcdfdir (that is, netcdf.h is | |
128 | in /netcdfdir/include and the library in /netcdfdir/lib/), | |
129 | try the following: | |
130 | ||
131 | % ruby extconf.rb --with-netcdf-dir=/netcdfdir | |
132 | ||
133 | Alternatively, you can specify the two directory separately | |
134 | with --with-netcdf-include and --with-netcdf-lib. | |
135 | EOS | |
136 | exit(-1) | |
137 | end | |
138 | end | |
139 | else | |
140 | raise "Netcdf version #{ncver0} is not supported" | |
141 | end | |
142 | ||
143 | ||
144 | ||
145 | if /cygwin|mingw/ =~ RUBY_PLATFORM | |
146 | have_library("narray") || raise("ERROR: narray library is not found") | |
147 | end | |
148 | ||
149 | create_makefile "numru/netcdfraw" | |
150 | ||
151 | ###### Modify Makefile: ####### | |
152 | File.rename("Makefile","Makefile.orig") | |
153 | oldmkfl = File.open("Makefile.orig") | |
154 | newmkfl = File.open("Makefile","w") | |
155 | oldmkfl.each_line{ |line| | |
156 | case(line) | |
157 | when /^distclean:/ | |
158 | newmkfl.puts(line) | |
159 | newmkfl.puts("\t\t@$(RM) *.nc demo/*.nc demo/*~ lib/*~ doc/*~ test/*.nc test/*~ Makefile.orig") | |
160 | when /^all:/ | |
161 | newmkfl.puts(line) | |
162 | newmkfl.puts("") | |
163 | newmkfl.puts("test: all") # insert the "test" target | |
164 | newmkfl.puts("\t\t@cd test && ruby test.rb && echo 'test did not fail :-p (please ignore the warnings)' && cd ..") | |
165 | # when /lib\/netcdf/ | |
166 | # line = line.chomp! + "/" | |
167 | # newmkfl.puts(line) | |
168 | else | |
169 | newmkfl.puts(line) | |
170 | end | |
171 | } | |
172 | newmkfl.close |
0 | require 'narray' | |
1 | require 'numru/netcdfraw' | |
2 | ||
3 | if NArray.const_defined?(:SUPPORT_BIGMEM) && NArray::SUPPORT_BIGMEM | |
4 | unless NumRu::NetCDF::SUPPORT_BIGMEM | |
5 | raise "Ruby-NetCDF was compiled with NArray with big memory supoort " + | |
6 | "(NArray-bigmem). However the NArray loaded is not NArray-bigmem." | |
7 | end | |
8 | else | |
9 | if NumRu::NetCDF::SUPPORT_BIGMEM | |
10 | raise "Ruby-NetCDF was compiled with NArray without big memory support. " + | |
11 | "However the NArray loaded is with the support (NArray-bigmem)." | |
12 | end | |
13 | end | |
14 | ||
15 | module NumRu | |
16 | class NetCDF | |
17 | ||
18 | Max_Try = 100 | |
19 | ||
20 | NCVERSION = NetCDF.libvers | |
21 | ||
22 | if NCVERSION[0..0] >= "4" | |
23 | @@nc4 = true | |
24 | else | |
25 | @@nc4 = false | |
26 | end | |
27 | def NetCDF.nc4? | |
28 | @@nc4 | |
29 | end | |
30 | ||
31 | @@cr_format = 0 | |
32 | ||
33 | def NetCDF.creation_format=(cmode) | |
34 | raise("This method is available only for NetCDF >= 4") unless @@nc4 | |
35 | case cmode | |
36 | when 0, nil, NC_CLASSIC_MODEL, /^CLASSIC$/i # classic netcdf ver 3 fmt | |
37 | @@cr_format = 0 | |
38 | when NC_64BIT_OFFSET, /^64BIT_OFFSET$/i | |
39 | @@cr_format = NC_64BIT_OFFSET | |
40 | when NC_NETCDF4, /^NETCDF4$/i | |
41 | @@cr_format = NC_NETCDF4 | |
42 | when ( NC_NETCDF4 | NC_CLASSIC_MODEL), /^NETCDF4_CLASSIC$/i | |
43 | # NetCDF4 but disabling new data models | |
44 | @@cr_format = NC_NETCDF4 | NC_CLASSIC_MODEL | |
45 | else | |
46 | raise ArgumentError, "Unsupported creation mode: #{cmod.to_s}" | |
47 | end | |
48 | end | |
49 | ||
50 | def NetCDF.creation_format | |
51 | raise("This method is available only for NetCDF >= 4") unless @@nc4 | |
52 | case @@cr_format | |
53 | when 0 | |
54 | "TRADITIONAL" | |
55 | when NC_64BIT_OFFSET | |
56 | "64BIT_OFFSET" | |
57 | when NC_NETCDF4 | |
58 | "NETCDF4" | |
59 | when NC_NETCDF4 | NC_CLASSIC_MODEL | |
60 | "NETCDF4_CLASSIC" | |
61 | end | |
62 | end | |
63 | ||
64 | def NetCDF.open(filename,mode="r",share=false) | |
65 | call_create=false # false-> nc_open; true->nc_create | |
66 | case(mode) | |
67 | when "r","rb" # read only | |
68 | mode=NC_NOWRITE | |
69 | when "w","w+","wb","w+b" # overwrite if exits | |
70 | call_create=true | |
71 | mode=NC_CLOBBER | |
72 | when "a","a+","r+","ab","a+b","r+b" # append if exits | |
73 | if( File.exists?(filename) ) | |
74 | mode=NC_WRITE | |
75 | else | |
76 | call_create=true #(nonexsitent --> create) | |
77 | mode=NC_CLOBBER | |
78 | end | |
79 | else | |
80 | raise NetcdfError, "Mode #{mode} is not supported" | |
81 | end | |
82 | case(share) | |
83 | when false | |
84 | share=0 | |
85 | when true | |
86 | share=NC_SHARE | |
87 | else | |
88 | raise NetcdfError, "We can't use the sharing mode you typed" | |
89 | end | |
90 | omode = mode | share | |
91 | if(!call_create) | |
92 | nc_open(filename,omode) | |
93 | else | |
94 | nc_create(filename,omode) | |
95 | end | |
96 | end | |
97 | ||
98 | class << NetCDF | |
99 | alias new open | |
100 | end | |
101 | ||
102 | ||
103 | def NetCDF.create(filename,noclobber=false,share=false) | |
104 | case(noclobber) | |
105 | when false | |
106 | noclobber=NC_CLOBBER | |
107 | when true | |
108 | noclobber=NC_NOCLOBBER | |
109 | else | |
110 | raise NetcdfError,"noclobber (2nd argument) must be true or false" | |
111 | end | |
112 | case(share) | |
113 | when false | |
114 | share=0 | |
115 | when true | |
116 | share=NC_SHARE | |
117 | else | |
118 | raise NetcdfError,"share (3rd argument) must be true or false" | |
119 | end | |
120 | ||
121 | cmode=noclobber | share | @@cr_format | |
122 | nc_create(filename,cmode) | |
123 | end | |
124 | ||
125 | class << NetCDF | |
126 | def clean_tmpfile(path) | |
127 | proc { | |
128 | print "removing ", path, "..." if $DEBUG | |
129 | if File.exist?(path) | |
130 | File.unlink(path) | |
131 | end | |
132 | print "done\n" if $DEBUG | |
133 | } | |
134 | end | |
135 | protected :clean_tmpfile | |
136 | end | |
137 | ||
138 | def NetCDF.create_tmp(tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'.', | |
139 | share=false) | |
140 | basename = 'temp' | |
141 | if $SAFE > 0 and tmpdir.tainted? | |
142 | tmpdir = '.' | |
143 | end | |
144 | ||
145 | n = 0 | |
146 | while true | |
147 | begin | |
148 | tmpname = sprintf('%s/%s%d_%d.nc', tmpdir, basename, $$, n) | |
149 | unless File.exist?(tmpname) | |
150 | netcdf = NetCDF.create(tmpname, true, share) | |
151 | ObjectSpace.define_finalizer(netcdf, | |
152 | NetCDF.clean_tmpfile(tmpname)) | |
153 | break | |
154 | end | |
155 | rescue | |
156 | raise NetcdfError, "cannot generate tempfile `%s'" % tmpname if n >= Max_Try | |
157 | end | |
158 | n += 1 | |
159 | end | |
160 | netcdf | |
161 | end | |
162 | ||
163 | ||
164 | def put_att(attname,val,atttype=nil) | |
165 | put_attraw(attname,val,atttype) | |
166 | end | |
167 | ||
168 | def def_var_with_dim(name, vartype, shape_ul0, dimnames) | |
169 | # Same as def_var but defines dimensions first if needed. | |
170 | # Use zero in shape to define an unlimited dimension. | |
171 | if (shape_ul0.length != dimnames.length ) then | |
172 | raise ArgumentError, 'lengths of shape and dimnames do not agree' | |
173 | end | |
174 | dims = [] | |
175 | dimnames.each_index{ |i| | |
176 | dim = self.dim( dimnames[i] ) | |
177 | if ( dim != nil ) then | |
178 | # dim exists --> check the length | |
179 | if (shape_ul0[i] != dim.length_ul0 ) then | |
180 | raise ArgumentError, "dimension length do not agree: #{i}th dim: "+\ | |
181 | "#{shape_ul0[i]} and #{dim.length_ul0}" | |
182 | end | |
183 | dims.push(dim) | |
184 | else | |
185 | # dim does not exist --> define it | |
186 | dims.push( def_dim( dimnames[i], shape_ul0[i] ) ) | |
187 | end | |
188 | } | |
189 | def_var(name, vartype, dims) | |
190 | end | |
191 | ||
192 | # Iterators: | |
193 | def each_dim | |
194 | num_dim=ndims() | |
195 | for dimid in 0..num_dim-1 | |
196 | obj_Dim=id2dim(dimid) | |
197 | yield(obj_Dim) | |
198 | end | |
199 | end | |
200 | ||
201 | def each_var | |
202 | num_var=nvars() | |
203 | for varid in 0..num_var-1 | |
204 | obj_Var=id2var(varid) | |
205 | yield(obj_Var) | |
206 | end | |
207 | end | |
208 | ||
209 | def each_att | |
210 | num_att=natts() | |
211 | for attnum in 0..num_att-1 | |
212 | obj_Att=id2att(attnum) | |
213 | yield(obj_Att) | |
214 | end | |
215 | end | |
216 | ||
217 | def dims( names=nil ) # return all if names==nil | |
218 | if names == nil | |
219 | dims = (0..ndims()-1).collect{|dimid| id2dim(dimid)} | |
220 | else | |
221 | raise TypeError, "names is not an array" if ! names.is_a?(Array) | |
222 | dims = names.collect{|name| dim(name)} | |
223 | raise ArgumentError, "One or more dimensions do not exist" if dims.include?(nil) | |
224 | end | |
225 | dims | |
226 | end | |
227 | ||
228 | def vars( names=nil ) # return all if names==nil | |
229 | if names == nil | |
230 | vars = (0..nvars()-1).collect{ |varid| id2var(varid) } | |
231 | else | |
232 | raise TypeError, "names is not an array" if ! names.is_a?(Array) | |
233 | vars = names.collect{|name| var(name)} | |
234 | raise ArgumentError, "One or more variables do not exist" if vars.include?(nil) | |
235 | end | |
236 | vars | |
237 | end | |
238 | ||
239 | def dim_names | |
240 | num_dim=ndims() | |
241 | names=[] | |
242 | for dimid in 0..num_dim-1 | |
243 | obj_Dim=id2dim(dimid) | |
244 | names=names+[obj_Dim.name] | |
245 | end | |
246 | return names | |
247 | end | |
248 | ||
249 | def var_names | |
250 | num_var=nvars() | |
251 | names=[] | |
252 | for varid in 0..num_var-1 | |
253 | obj_Var=id2var(varid) | |
254 | names=names+[obj_Var.name] | |
255 | end | |
256 | return names | |
257 | end | |
258 | ||
259 | def att_names | |
260 | num_att=natts() | |
261 | names=[] | |
262 | for attnum in 0..num_att-1 | |
263 | obj_Att=id2att(attnum) | |
264 | names=names+[obj_Att.name] | |
265 | end | |
266 | return names | |
267 | end | |
268 | ||
269 | def inspect | |
270 | "NetCDF:"+path | |
271 | end | |
272 | ||
273 | end | |
274 | ||
275 | class NetCDFVar | |
276 | ||
277 | class << NetCDFVar | |
278 | def new(file,varname,mode="r",share=false) | |
279 | if(file.is_a?(String)) | |
280 | file = NetCDF.open(file,mode,share) | |
281 | elsif(!file.is_a?(NetCDF)) | |
282 | raise TypeError, "1st arg must be a NetCDF (file object) or a String (path)" | |
283 | end | |
284 | file.var(varname) | |
285 | end | |
286 | ||
287 | alias open new | |
288 | end | |
289 | ||
290 | alias :rank :ndims | |
291 | ||
292 | def each_att | |
293 | num_att=natts() | |
294 | for attnum in 0..num_att-1 | |
295 | obj_Att=id2att(attnum) | |
296 | yield(obj_Att) | |
297 | end | |
298 | end | |
299 | ||
300 | def dim_names | |
301 | ary = Array.new() | |
302 | dims.each{|dim| ary.push(dim.name)} | |
303 | ary | |
304 | end | |
305 | ||
306 | def att_names | |
307 | num_att=natts() | |
308 | names=[] | |
309 | for attnum in 0..num_att-1 | |
310 | obj_Att=id2att(attnum) | |
311 | names=names+[obj_Att.name] | |
312 | end | |
313 | return names | |
314 | end | |
315 | ||
316 | def put_att(attname,val,atttype=nil) | |
317 | put_attraw(attname,val,atttype) | |
318 | end | |
319 | ||
320 | def shape_ul0 | |
321 | sh = [] | |
322 | dims.each{|d| | |
323 | if d.unlimited? then | |
324 | sh.push(0) | |
325 | else | |
326 | sh.push(d.length) | |
327 | end | |
328 | } | |
329 | sh | |
330 | end | |
331 | ||
332 | def shape_current | |
333 | sh = [] | |
334 | dims.each{|d| | |
335 | sh.push(d.length) | |
336 | } | |
337 | sh | |
338 | end | |
339 | ||
340 | # The put and get methods in the NetCDFVar class | |
341 | ||
342 | def pack(na) | |
343 | sf = att('scale_factor') | |
344 | ao = att('add_offset') | |
345 | if ( sf == nil && ao == nil ) then | |
346 | na | |
347 | else | |
348 | na = NArray.to_na(na) if na.is_a?(Array) | |
349 | if sf | |
350 | csf = sf.get | |
351 | raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String) | |
352 | raise NetcdfError, "scale_factor is not unique" if csf.length != 1 | |
353 | raise NetcdfError, "zero scale_factor" if csf[0] == 0 | |
354 | else | |
355 | csf = nil | |
356 | end | |
357 | if ao | |
358 | cao = ao.get | |
359 | raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String) | |
360 | raise NetcdfError, "add_offset is not unique" if cao.length != 1 | |
361 | else | |
362 | cao = nil | |
363 | end | |
364 | if csf and cao | |
365 | packed = (na - cao) / csf | |
366 | elsif csf | |
367 | packed = na / csf | |
368 | elsif cao | |
369 | packed = na - cao | |
370 | end | |
371 | if self.typecode <= NArray::LINT | |
372 | packed = packed.round | |
373 | end | |
374 | packed | |
375 | end | |
376 | end | |
377 | ||
378 | def scaled_put(var,hash=nil) | |
379 | simple_put( pack(var), hash) | |
380 | end | |
381 | ||
382 | @@unpack_type = nil | |
383 | class << NetCDFVar | |
384 | def unpack_type | |
385 | @@unpack_type | |
386 | end | |
387 | def unpack_type=(na_type) | |
388 | if [NArray::BYTE, NArray::SINT, NArray::INT, | |
389 | NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type) | |
390 | @@unpack_type = na_type | |
391 | else | |
392 | raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT" | |
393 | end | |
394 | end | |
395 | ||
396 | end | |
397 | ||
398 | def unpack(na) | |
399 | sf = att('scale_factor') | |
400 | ao = att('add_offset') | |
401 | if ( sf == nil && ao == nil ) then | |
402 | na | |
403 | else | |
404 | if sf | |
405 | csf = sf.get | |
406 | raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String) | |
407 | raise NetcdfError, "scale_factor is not unique" if csf.length != 1 | |
408 | raise NetcdfError, "zero scale_factor" if csf[0] == 0 | |
409 | else | |
410 | csf =nil | |
411 | end | |
412 | if ao | |
413 | cao = ao.get | |
414 | raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String) | |
415 | raise NetcdfError, "add_offset is not unique" if cao.length != 1 | |
416 | else | |
417 | cao = nil | |
418 | end | |
419 | if csf and cao | |
420 | una = na * csf + cao # csf & cao are NArray -> coerced to their types | |
421 | elsif csf | |
422 | una = na * csf | |
423 | elsif cao | |
424 | una = na + cao | |
425 | end | |
426 | una = una.to_type(@@unpack_type) if @@unpack_type | |
427 | una | |
428 | end | |
429 | end | |
430 | ||
431 | def scaled_get(hash=nil) | |
432 | unpack( simple_get(hash) ) | |
433 | end | |
434 | ||
435 | def simple_put(var,hash=nil) | |
436 | if hash==nil | |
437 | if self.vartype == "char" | |
438 | put_var_char(var) | |
439 | elsif self.vartype == "byte" | |
440 | put_var_byte(var) | |
441 | elsif self.vartype == "sint" | |
442 | put_var_sint(var) | |
443 | elsif self.vartype == "int" | |
444 | put_var_int(var) | |
445 | elsif self.vartype == "sfloat" | |
446 | put_var_sfloat(var) | |
447 | elsif self.vartype == "float" | |
448 | put_var_float(var) | |
449 | else | |
450 | raise NetcdfError,"variable type isn't supported in netCDF" | |
451 | end | |
452 | elsif hash.key?("index")==true | |
453 | if self.vartype == "char" | |
454 | put_var1_char(var,hash["index"]) | |
455 | elsif self.vartype=="byte" | |
456 | put_var1_byte(var,hash["index"]) | |
457 | elsif self.vartype=="sint" | |
458 | put_var1_sint(var,hash["index"]) | |
459 | elsif self.vartype == "int" | |
460 | put_var1_int(var,hash["index"]) | |
461 | elsif self.vartype == "sfloat" | |
462 | put_var1_sfloat(var,hash["index"]) | |
463 | elsif self.vartype == "float" | |
464 | put_var1_float(var,hash["index"]) | |
465 | else | |
466 | raise NetcdfError,"variable type isn't supported in netCDF" | |
467 | end | |
468 | elsif hash.key?("start")==true | |
469 | if hash.key?("end")==false && hash.key?("stride")==false | |
470 | if self.vartype == "char" | |
471 | put_vars_char(var,hash["start"],nil,nil) | |
472 | elsif self.vartype=="byte" | |
473 | put_vars_byte(var,hash["start"],nil,nil) | |
474 | elsif self.vartype=="sint" | |
475 | put_vars_sint(var,hash["start"],nil,nil) | |
476 | elsif self.vartype=="int" | |
477 | put_vars_int(var,hash["start"],nil,nil) | |
478 | elsif self.vartype=="sfloat" | |
479 | put_vars_sfloat(var,hash["start"],nil,nil) | |
480 | elsif self.vartype=="float" | |
481 | put_vars_float(var,hash["start"],nil,nil) | |
482 | else | |
483 | raise NetcdfError, "variable type isn't supported in netCDF" | |
484 | end | |
485 | elsif hash.key?("end")==true && hash.key?("stride") == false | |
486 | if self.vartype == "char" | |
487 | put_vars_char(var,hash["start"],hash["end"],nil) | |
488 | elsif self.vartype=="byte" | |
489 | put_vars_byte(var,hash["start"],hash["end"],nil) | |
490 | elsif self.vartype=="sint" | |
491 | put_vars_sint(var,hash["start"],hash["end"],nil) | |
492 | elsif self.vartype=="int" | |
493 | put_vars_int(var,hash["start"],hash["end"],nil) | |
494 | elsif self.vartype == "sfloat" | |
495 | put_vars_sfloat(var,hash["start"],hash["end"],nil) | |
496 | elsif self.vartype =="float" | |
497 | put_vars_float(var,hash["start"],hash["end"],nil) | |
498 | else | |
499 | raise NetcdfError, "variable type isn't supported in netCDF" | |
500 | end | |
501 | elsif hash.key?("end")==false && hash.key?("stride")==true | |
502 | if self.vartype == "char" | |
503 | put_vars_char(var,hash["start"],nil,hash["stride"]) | |
504 | elsif self.vartype=="byte" | |
505 | put_vars_byte(var,hash["start"],nil,hash["stride"]) | |
506 | elsif self.vartype=="sint" | |
507 | put_vars_sint(var,hash["start"],nil,hash["stride"]) | |
508 | elsif self.vartype=="int" | |
509 | put_vars_int(var,hash["start"],nil,hash["stride"]) | |
510 | elsif self.vartype=="sfloat" | |
511 | put_vars_sfloat(var,hash["start"],nil,hash["stride"]) | |
512 | elsif self.vartype=="float" | |
513 | put_vars_float(var,hash["start"],nil,hash["stride"]) | |
514 | else | |
515 | raise NetcdfError, "variable type isn't supported in netCDF" | |
516 | end | |
517 | else hash.key?("end")==true && hash.key?("stride")==true | |
518 | if self.vartype == "char" | |
519 | put_vars_char(var,hash["start"],hash["end"],hash["stride"]) | |
520 | elsif self.vartype=="byte" | |
521 | put_vars_byte(var,hash["start"],hash["end"],hash["stride"]) | |
522 | elsif self.vartype=="sint" | |
523 | put_vars_sint(var,hash["start"],hash["end"],hash["stride"]) | |
524 | elsif self.vartype=="int" | |
525 | put_vars_int(var,hash["start"],hash["end"],hash["stride"]) | |
526 | elsif self.vartype=="sfloat" | |
527 | put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"]) | |
528 | elsif self.vartype=="float" | |
529 | put_vars_float(var,hash["start"],hash["end"],hash["stride"]) | |
530 | else | |
531 | raise NetcdfError, "variable type isn't supported in netCDF" | |
532 | end | |
533 | end | |
534 | else | |
535 | raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed" | |
536 | end | |
537 | end | |
538 | ||
539 | alias put simple_put | |
540 | ||
541 | def simple_get(hash=nil) | |
542 | t_var = self.vartype | |
543 | if hash == nil | |
544 | if t_var == "char" | |
545 | get_var_char | |
546 | elsif t_var == "byte" | |
547 | get_var_byte | |
548 | elsif t_var == "sint" | |
549 | get_var_sint | |
550 | elsif t_var == "int" | |
551 | get_var_int | |
552 | elsif t_var == "sfloat" | |
553 | get_var_sfloat | |
554 | elsif t_var == "float" | |
555 | get_var_float | |
556 | else | |
557 | raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" | |
558 | end | |
559 | elsif hash.key?("index")==true | |
560 | ind = hash["index"] | |
561 | if t_var == "char" | |
562 | get_var1_char(ind) | |
563 | elsif t_var == "byte" | |
564 | get_var1_byte(ind) | |
565 | elsif t_var == "sint" | |
566 | get_var1_sint(ind) | |
567 | elsif t_var == "int" | |
568 | get_var1_int(ind) | |
569 | elsif t_var == "sfloat" | |
570 | get_var1_sfloat(ind) | |
571 | elsif t_var == "float" | |
572 | get_var1_float(ind) | |
573 | else | |
574 | raise NetcdfError,"variable type #{t_var} isn't supported in netCDF" | |
575 | end | |
576 | elsif hash.key?("start")==true | |
577 | h_sta = hash["start"] | |
578 | h_end = hash["end"] # can be nill | |
579 | h_str = hash["stride"] # can be nill | |
580 | if NetCDF.nc4? && h_str && ((xstr=h_str[0]) != 1) | |
581 | # Tentative treatment for the very slow netcdf-4 reading with step. | |
582 | # Reading with step is generally slow with NetCDF 4, but it is | |
583 | # particularly so for the first dimension. | |
584 | # Ref: http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2013/msg00311.html | |
585 | h_str[0] = 1 | |
586 | nc4remedy = true | |
587 | else | |
588 | nc4remedy = false | |
589 | end | |
590 | if t_var == "char" | |
591 | v = get_vars_char(h_sta,h_end,h_str) | |
592 | elsif t_var == "byte" | |
593 | v = get_vars_byte(h_sta,h_end,h_str) | |
594 | elsif t_var == "sint" | |
595 | v = get_vars_sint(h_sta,h_end,h_str) | |
596 | elsif t_var == "int" | |
597 | v = get_vars_int(h_sta,h_end,h_str) | |
598 | elsif t_var == "sfloat" | |
599 | v = get_vars_sfloat(h_sta,h_end,h_str) | |
600 | elsif t_var == "float" | |
601 | v = get_vars_float(h_sta,h_end,h_str) | |
602 | else | |
603 | raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" | |
604 | end | |
605 | if nc4remedy | |
606 | idx = [] | |
607 | (0...v.shape[0]).step(xstr){|k| idx.push(k)} | |
608 | v = v[idx,false] | |
609 | end | |
610 | v | |
611 | else | |
612 | raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed" | |
613 | end | |
614 | end | |
615 | ||
616 | alias get simple_get | |
617 | ||
618 | def __rubber_expansion( args ) | |
619 | if (id = args.index(false)) # substitution into id | |
620 | # false is incuded | |
621 | alen = args.length | |
622 | if args.rindex(false) != id | |
623 | raise ArguemntError,"only one rubber dimension is permitted" | |
624 | elsif alen > rank+1 | |
625 | raise ArgumentError, "too many args" | |
626 | end | |
627 | ar = ( id!=0 ? args[0..id-1] : [] ) | |
628 | args = ar + [true]*(rank-alen+1) + args[id+1..-1] | |
629 | elsif args.length == 0 # to support empty [], []= | |
630 | args = [true]*rank | |
631 | end | |
632 | args | |
633 | end | |
634 | private :__rubber_expansion | |
635 | ||
636 | def [](*a) | |
637 | if a.length == 0 | |
638 | return self.get | |
639 | end | |
640 | a = __rubber_expansion(a) | |
641 | first = Array.new | |
642 | last = Array.new | |
643 | stride = Array.new | |
644 | set_stride = false | |
645 | a.each{|i| | |
646 | if(i.is_a?(Fixnum)) | |
647 | first.push(i) | |
648 | last.push(i) | |
649 | stride.push(1) | |
650 | elsif(i.is_a?(Range)) | |
651 | first.push(i.first) | |
652 | last.push(i.exclude_end? ? i.last-1 : i.last) | |
653 | stride.push(1) | |
654 | elsif(i.is_a?(Hash)) | |
655 | r = (i.to_a[0])[0] | |
656 | s = (i.to_a[0])[1] | |
657 | if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) | |
658 | raise TypeError, "Hash argument must be {a_Range, step}" | |
659 | end | |
660 | first.push(r.first) | |
661 | last.push(r.exclude_end? ? r.last-1 : r.last) | |
662 | stride.push(s) | |
663 | set_stride = true | |
664 | elsif(i.is_a?(TrueClass)) | |
665 | first.push(0) | |
666 | last.push(-1) | |
667 | stride.push(1) | |
668 | elsif( i.is_a?(Array) || i.is_a?(NArray)) | |
669 | a_new = a.dup | |
670 | at = a.index(i) | |
671 | i = NArray.to_na(i) if i.is_a?(Array) | |
672 | for n in 0..i.length-1 | |
673 | a_new[at] = i[n]..i[n] | |
674 | na_tmp = self[*a_new] | |
675 | if n==0 then | |
676 | k = at | |
677 | if at > 0 | |
678 | a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} | |
679 | end | |
680 | shape_tmp = na_tmp.shape | |
681 | shape_tmp[k] = i.length | |
682 | na = na_tmp.class.new(na_tmp.typecode,*shape_tmp) | |
683 | index_tmp = Array.new(shape_tmp.length,true) | |
684 | end | |
685 | index_tmp[k] = n..n | |
686 | na[*index_tmp] = na_tmp | |
687 | end | |
688 | return na | |
689 | else | |
690 | raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" | |
691 | end | |
692 | } | |
693 | ||
694 | if(set_stride) | |
695 | na = self.get({"start"=>first, "end"=>last, "stride"=>stride}) | |
696 | else | |
697 | na = self.get({"start"=>first, "end"=>last}) | |
698 | end | |
699 | shape = na.shape | |
700 | (a.length-1).downto(0){ |i| | |
701 | shape.delete_at(i) if a[i].is_a?(Fixnum) | |
702 | } | |
703 | na.reshape!( *shape ) | |
704 | na | |
705 | end | |
706 | ||
707 | def []=(*a) | |
708 | val = a.pop | |
709 | a = __rubber_expansion(a) | |
710 | first = Array.new | |
711 | last = Array.new | |
712 | stride = Array.new | |
713 | set_stride = false | |
714 | a.each{|i| | |
715 | if(i.is_a?(Fixnum)) | |
716 | first.push(i) | |
717 | last.push(i) | |
718 | stride.push(1) | |
719 | elsif(i.is_a?(Range)) | |
720 | first.push(i.first) | |
721 | last.push(i.exclude_end? ? i.last-1 : i.last) | |
722 | stride.push(1) | |
723 | elsif(i.is_a?(Hash)) | |
724 | r = (i.to_a[0])[0] | |
725 | s = (i.to_a[0])[1] | |
726 | if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) | |
727 | raise ArgumentError, "Hash argument must be {first..last, step}" | |
728 | end | |
729 | first.push(r.first) | |
730 | last.push(r.exclude_end? ? r.last-1 : r.last) | |
731 | stride.push(s) | |
732 | set_stride = true | |
733 | elsif(i.is_a?(TrueClass)) | |
734 | first.push(0) | |
735 | last.push(-1) | |
736 | stride.push(1) | |
737 | elsif(i.is_a?(Array) || i.is_a?(NArray)) | |
738 | a_new = a.dup | |
739 | at = a.index(i) | |
740 | i = NArray.to_na(i) if i.is_a?(Array) | |
741 | val = NArray.to_na(val) if val.is_a?(Array) | |
742 | rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length | |
743 | if val.rank != rank_of_subset | |
744 | raise "rank of the rhs (#{val.rank}) is not equal to the rank "+ | |
745 | "of the subset specified by #{a.inspect} (#{rank_of_subset})" | |
746 | end | |
747 | k = at | |
748 | a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} | |
749 | if i.length != val.shape[k] | |
750 | raise "length of the #{k+1}-th dim of rhs is incorrect "+ | |
751 | "(#{i.length} for #{val.shape[k]})" | |
752 | end | |
753 | index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like | |
754 | for n in 0..i.length-1 | |
755 | a_new[at] = i[n]..i[n] | |
756 | if !val.is_a?(Numeric) then | |
757 | index_tmp[k] = n..n | |
758 | self[*a_new] = val[*index_tmp] | |
759 | else | |
760 | self[*a_new] = val | |
761 | end | |
762 | end | |
763 | return self | |
764 | else | |
765 | raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" | |
766 | end | |
767 | } | |
768 | ||
769 | if(set_stride) | |
770 | self.put(val, {"start"=>first, "end"=>last, "stride"=>stride}) | |
771 | else | |
772 | self.put(val, {"start"=>first, "end"=>last}) | |
773 | end | |
774 | end | |
775 | ||
776 | def inspect | |
777 | 'NetCDFVar:'+file.path+'?var='+name | |
778 | end | |
779 | ||
780 | end | |
781 | ||
782 | class NetCDFAtt | |
783 | ||
784 | def put(val,atttype=nil) | |
785 | putraw(val,atttype) | |
786 | end | |
787 | ||
788 | def inspect | |
789 | 'NetCDFAtt:'+name | |
790 | end | |
791 | end | |
792 | ||
793 | class NetCDFDim | |
794 | def inspect | |
795 | 'NetCDFDim:'+name | |
796 | end | |
797 | ||
798 | def length_ul0 | |
799 | if unlimited? | |
800 | 0 | |
801 | else | |
802 | length | |
803 | end | |
804 | end | |
805 | ||
806 | end | |
807 | end |
0 | require "numru/netcdf" | |
1 | require "narray_miss" | |
2 | ||
3 | module NumRu | |
4 | ||
5 | class NetCDFVar | |
6 | ||
7 | def get_with_miss(*args) | |
8 | __interpret_missing_params if !defined?(@missval) | |
9 | data = simple_get(*args) | |
10 | if @vmin || @vmax | |
11 | if @vmin | |
12 | mask = (data >= @vmin) | |
13 | mask = mask.and(data <= @vmax) if @vmax | |
14 | else | |
15 | mask = (data <= @vmax) | |
16 | end | |
17 | data = NArrayMiss.to_nam(data, mask) | |
18 | elsif @missval # only missing_value is present. | |
19 | mask = (data.ne(@missval)) | |
20 | data = NArrayMiss.to_nam(data, mask) | |
21 | end | |
22 | data | |
23 | end | |
24 | ||
25 | def get_with_miss_and_scaling(*args) | |
26 | __interpret_missing_params if !defined?(@missval) | |
27 | data = simple_get(*args) | |
28 | if @vmin || @vmax | |
29 | if @vmin | |
30 | mask = (data >= @vmin) | |
31 | mask = mask.and(data <= @vmax) if @vmax | |
32 | else | |
33 | mask = (data <= @vmax) | |
34 | end | |
35 | data = NArrayMiss.to_nam(data, mask) | |
36 | elsif @missval # only missing_value is present. | |
37 | mask = (data.ne(@missval)) | |
38 | data = NArrayMiss.to_nam(data, mask) | |
39 | end | |
40 | data = unpack( data ) | |
41 | data | |
42 | end | |
43 | ||
44 | def put_with_miss(data, *args) | |
45 | if data.is_a?( NArrayMiss ) | |
46 | __interpret_missing_params if !defined?(@missval) | |
47 | if @missval | |
48 | simple_put(data.to_na(@missval), *args) | |
49 | else | |
50 | simple_put(data.to_na, *args) | |
51 | end | |
52 | else | |
53 | simple_put(data, *args) | |
54 | end | |
55 | end | |
56 | ||
57 | def put_with_miss_and_scaling(data, *args) | |
58 | if data.is_a?( NArrayMiss ) | |
59 | __interpret_missing_params if !defined?(@missval) | |
60 | if @missval | |
61 | data = pack( data ) | |
62 | data = data.to_na(@missval) | |
63 | else | |
64 | data = pack( data ) | |
65 | data = data.to_na | |
66 | end | |
67 | simple_put(data, *args) | |
68 | else | |
69 | scaled_put(data, *args) | |
70 | end | |
71 | end | |
72 | ||
73 | ######### private ########## | |
74 | ||
75 | def __interpret_missing_params | |
76 | # Interprets the specification of missing data, | |
77 | # either by valid_range, (valid_min and/or valid_max), or missing_value. | |
78 | # (unlike the NetCDF User's guide (NUG), missing_value is interpreted, | |
79 | # but valid_* has a higher precedence.) | |
80 | # Always sets @missval whether missing_value is defined or not, | |
81 | # since it will be used as a fill value for data missing. | |
82 | # | |
83 | @vmin = att('valid_min') | |
84 | @vmin = @vmin.get if @vmin # kept in a NArray(size==1) to consv type | |
85 | @vmax = att('valid_max') | |
86 | @vmax = @vmax.get if @vmax # kept in a NArray(size==1) to consv type | |
87 | vrange = att('valid_range') | |
88 | vrange = vrange.get if vrange | |
89 | if vrange | |
90 | vrange.sort! | |
91 | @vmin = vrange[0..0] # kept in... (same) | |
92 | @vmax = vrange[-1..-1] # kept in... (same) | |
93 | end | |
94 | @missval = att('missing_value') || att('_FillValue') | |
95 | @missval = @missval.get if @missval # kept in... (same) | |
96 | ||
97 | sf = att('scale_factor') | |
98 | ao = att('add_offset') | |
99 | if ( sf || ao ) | |
100 | ## Both NUG & CF conventions requires to specify the valid | |
101 | ## range with respect to the external (i.e. packed) values. | |
102 | ## However, some conventions require specification | |
103 | ## with respect to unpacked values. The following | |
104 | ## is to support such cases as well: | |
105 | thres_tp = [ self.typecode, NArray::LINT ].max | |
106 | @missval = pack(@missval) if @missval && @missval.typecode > thres_tp | |
107 | @vmin = pack(@vmin) if @vmin && @vmin.typecode > thres_tp | |
108 | @vmax = pack(@vmax) if @vmax && @vmax.typecode > thres_tp | |
109 | end | |
110 | ||
111 | if @missval | |
112 | if @vmin && @vmax | |
113 | if @vmin[0] <= @missval[0] && @missval[0] <= @vmax[0] | |
114 | warn "WARNING: missing_value #{@missval[0]} is in the valid range #{@vmin[0]}..#{@vmax[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" | |
115 | end | |
116 | else | |
117 | if @vmin && @missval[0] >= @vmin[0] | |
118 | warn "WARNING: missing_value #{@missval[0]} >= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" | |
119 | elsif @vmax && @missval[0] <= @vmax[0] | |
120 | warn "WARNING: missing_value #{@missval[0]} <= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" | |
121 | end | |
122 | end | |
123 | else | |
124 | realtc = NArray::SFLOAT | |
125 | if @vmin | |
126 | if @vmin[0] >= 0 | |
127 | @missval = ( @vmin.typecode>=realtc ? 0.99*@vmin : @vmin-1 ) | |
128 | else | |
129 | @missval = ( @vmin.typecode>=realtc ? 1.01*@vmin : @vmin-1 ) | |
130 | end | |
131 | elsif @vmax | |
132 | if @vmax[0] >= 0 | |
133 | @missval = ( @vmax.typecode>=realtc ? 1.01*@vmax : @vmax+1 ) | |
134 | else | |
135 | @missval = ( @vmax.typecode>=realtc ? 0.99*@vmax : @vmax+1 ) | |
136 | end | |
137 | end | |
138 | end | |
139 | ||
140 | end | |
141 | ||
142 | private :__interpret_missing_params | |
143 | ||
144 | end | |
145 | ||
146 | end | |
147 | ||
148 | if $0 == __FILE__ | |
149 | include NumRu | |
150 | ||
151 | filename = "tmp.nc" | |
152 | print "creating ",filename,"...\n" | |
153 | file=NetCDF.create(filename) | |
154 | nx = 10 | |
155 | dimx = file.def_dim("x",nx) | |
156 | xf = file.def_var("xf","sfloat",[dimx]) | |
157 | xfn = file.def_var("xfn","sfloat",[dimx]) | |
158 | xf.put_att("valid_range",[-1e12,1e12]) | |
159 | f = 10 ** (2*NArray.sfloat(nx).indgen!) | |
160 | xr = file.def_var("xr","sint",[dimx]) | |
161 | xr.put_att("valid_max",[0.5]) | |
162 | xr.put_att("scale_factor",1e-4) | |
163 | xr.put_att("add_offset",0.5) | |
164 | xr2 = file.def_var("xr2","sint",[dimx]) | |
165 | xr2.put_att("valid_max",NArray.sint(1).fill!(1000)) | |
166 | xr2.put_att("scale_factor",1e-4) | |
167 | xr2.put_att("add_offset",0.5) | |
168 | r = NArray.sfloat(nx).indgen!/nx | |
169 | file.enddef | |
170 | xf.put(f) | |
171 | xfn.put(f) | |
172 | xr.scaled_put(r) | |
173 | file.close | |
174 | ||
175 | file = NetCDF.open(filename,'r+') | |
176 | xf = file.var('xf') | |
177 | xfn = file.var('xfn') | |
178 | p "f0" | |
179 | xf.get.each{|v| print "#{v} "} ; print "\n" | |
180 | p( 'f1', nam = xf.get_with_miss ) | |
181 | def xf.get(*args); get_with_miss(*args); end | |
182 | p( 'f12', xf[2..-3].to_na ) | |
183 | p( 'fn10', xfn.get_with_miss ) | |
184 | p( 'fn11', xfn.get_with_miss_and_scaling ) | |
185 | nam.invalidation([0,1]) | |
186 | p 'f2', nam | |
187 | xf.put_with_miss(nam) | |
188 | p( 'f3', xf.get_with_miss ) | |
189 | xr = file.var('xr') | |
190 | p "r0" | |
191 | xr.simple_get.each{|v| print "#{v} "} ; print "\n" | |
192 | p( 'r1', xr.get_with_miss_and_scaling ) | |
193 | def xr.get(*args); get_with_miss_and_scaling(*args); end | |
194 | def xr.put(*args); put_with_miss_and_scaling(*args); end | |
195 | #xr[0..3] = xr[0..3]*10 | |
196 | p( 'r2', xr.get_with_miss_and_scaling ) | |
197 | p 'r',r | |
198 | xr2.put_with_miss_and_scaling(r) | |
199 | p 'xr2',xr2.get_with_miss_and_scaling | |
200 | file.close | |
201 | print "** ncdump tmp.nc **\n", `ncdump tmp.nc` | |
202 | end |
0 | require 'narray' | |
1 | require 'numru/netcdf/version' | |
2 | require 'numru/netcdfraw' | |
3 | ||
4 | if NArray.const_defined?(:SUPPORT_BIGMEM) && NArray::SUPPORT_BIGMEM | |
5 | unless NumRu::NetCDF::SUPPORT_BIGMEM | |
6 | raise "Ruby-NetCDF was compiled with NArray with big memory supoort " + | |
7 | "(NArray-bigmem). However the NArray loaded is not NArray-bigmem." | |
8 | end | |
9 | else | |
10 | if NumRu::NetCDF::SUPPORT_BIGMEM | |
11 | raise "Ruby-NetCDF was compiled with NArray without big memory support. " + | |
12 | "However the NArray loaded is with the support (NArray-bigmem)." | |
13 | end | |
14 | end | |
15 | ||
16 | module NumRu | |
17 | class NetCDF | |
18 | ||
19 | Max_Try = 100 | |
20 | ||
21 | NCVERSION = NetCDF.libvers | |
22 | ||
23 | if NCVERSION[0..0] >= "4" | |
24 | @@nc4 = true | |
25 | else | |
26 | @@nc4 = false | |
27 | end | |
28 | def NetCDF.nc4? | |
29 | @@nc4 | |
30 | end | |
31 | ||
32 | @@cr_format = 0 | |
33 | ||
34 | def NetCDF.creation_format=(cmode) | |
35 | raise("This method is available only for NetCDF >= 4") unless @@nc4 | |
36 | case cmode | |
37 | when 0, nil, NC_CLASSIC_MODEL, /^CLASSIC$/i, NC_FORMAT_CLASSIC | |
38 | # classic netcdf ver 3 fmt | |
39 | @@cr_format = 0 | |
40 | when NC_64BIT_OFFSET, /^64BIT_OFFSET$/i, NC_FORMAT_64BIT | |
41 | @@cr_format = NC_64BIT_OFFSET | |
42 | when NC_NETCDF4, /^NETCDF4$/i, NC_FORMAT_NETCDF4 | |
43 | @@cr_format = NC_NETCDF4 | |
44 | when ( NC_NETCDF4 | NC_CLASSIC_MODEL), /^NETCDF4_CLASSIC$/i, NC_FORMAT_NETCDF4_CLASSIC | |
45 | # NetCDF4 but disabling new data models | |
46 | @@cr_format = NC_NETCDF4 | NC_CLASSIC_MODEL | |
47 | else | |
48 | raise ArgumentError, "Unsupported creation mode: #{cmod.to_s}" | |
49 | end | |
50 | end | |
51 | ||
52 | def NetCDF.creation_format | |
53 | raise("This method is available only for NetCDF >= 4") unless @@nc4 | |
54 | case @@cr_format | |
55 | when 0 | |
56 | "TRADITIONAL" | |
57 | when NC_64BIT_OFFSET | |
58 | "64BIT_OFFSET" | |
59 | when NC_NETCDF4 | |
60 | "NETCDF4" | |
61 | when (NC_NETCDF4 | NC_CLASSIC_MODEL) | |
62 | "NETCDF4_CLASSIC" | |
63 | end | |
64 | end | |
65 | ||
66 | def NetCDF.open(filename,mode="r",share=false) | |
67 | call_create=false # false-> nc_open; true->nc_create | |
68 | case(mode) | |
69 | when "r","rb" # read only | |
70 | mode=NC_NOWRITE | |
71 | when "w","w+","wb","w+b" # overwrite if exits | |
72 | call_create=true | |
73 | mode=NC_CLOBBER | |
74 | when "a","a+","r+","ab","a+b","r+b" # append if exits | |
75 | if( File.exists?(filename) ) | |
76 | mode=NC_WRITE | |
77 | else | |
78 | call_create=true #(nonexsitent --> create) | |
79 | mode=NC_CLOBBER | |
80 | end | |
81 | else | |
82 | raise NetcdfError, "Mode #{mode} is not supported" | |
83 | end | |
84 | case(share) | |
85 | when false | |
86 | share=0 | |
87 | when true | |
88 | share=NC_SHARE | |
89 | else | |
90 | raise NetcdfError, "We can't use the sharing mode you typed" | |
91 | end | |
92 | omode = mode | share | |
93 | if(!call_create) | |
94 | nc_open(filename,omode) | |
95 | else | |
96 | nc_create(filename,omode) | |
97 | end | |
98 | end | |
99 | ||
100 | class << NetCDF | |
101 | alias new open | |
102 | end | |
103 | ||
104 | ||
105 | def NetCDF.create(filename,noclobber=false,share=false) | |
106 | case(noclobber) | |
107 | when false | |
108 | noclobber=NC_CLOBBER | |
109 | when true | |
110 | noclobber=NC_NOCLOBBER | |
111 | else | |
112 | raise NetcdfError,"noclobber (2nd argument) must be true or false" | |
113 | end | |
114 | case(share) | |
115 | when false | |
116 | share=0 | |
117 | when true | |
118 | share=NC_SHARE | |
119 | else | |
120 | raise NetcdfError,"share (3rd argument) must be true or false" | |
121 | end | |
122 | ||
123 | cmode=noclobber | share | @@cr_format | |
124 | nc_create(filename,cmode) | |
125 | end | |
126 | ||
127 | class << NetCDF | |
128 | def clean_tmpfile(path) | |
129 | proc { | |
130 | print "removing ", path, "..." if $DEBUG | |
131 | if File.exist?(path) | |
132 | File.unlink(path) | |
133 | end | |
134 | print "done\n" if $DEBUG | |
135 | } | |
136 | end | |
137 | protected :clean_tmpfile | |
138 | end | |
139 | ||
140 | def NetCDF.create_tmp(tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'.', | |
141 | share=false) | |
142 | basename = 'temp' | |
143 | if $SAFE > 0 and tmpdir.tainted? | |
144 | tmpdir = '.' | |
145 | end | |
146 | ||
147 | n = 0 | |
148 | while true | |
149 | begin | |
150 | tmpname = sprintf('%s/%s%d_%d.nc', tmpdir, basename, $$, n) | |
151 | unless File.exist?(tmpname) | |
152 | netcdf = NetCDF.create(tmpname, true, share) | |
153 | ObjectSpace.define_finalizer(netcdf, | |
154 | NetCDF.clean_tmpfile(tmpname)) | |
155 | break | |
156 | end | |
157 | rescue | |
158 | raise NetcdfError, "cannot generate tempfile `%s'" % tmpname if n >= Max_Try | |
159 | end | |
160 | n += 1 | |
161 | end | |
162 | netcdf | |
163 | end | |
164 | ||
165 | ||
166 | def put_att(attname,val,atttype=nil) | |
167 | put_attraw(attname,val,atttype) | |
168 | end | |
169 | ||
170 | def def_var_with_dim(name, vartype, shape_ul0, dimnames) | |
171 | # Same as def_var but defines dimensions first if needed. | |
172 | # Use zero in shape to define an unlimited dimension. | |
173 | if (shape_ul0.length != dimnames.length ) then | |
174 | raise ArgumentError, 'lengths of shape and dimnames do not agree' | |
175 | end | |
176 | dims = [] | |
177 | dimnames.each_index{ |i| | |
178 | dim = self.dim( dimnames[i] ) | |
179 | if ( dim != nil ) then | |
180 | # dim exists --> check the length | |
181 | if (shape_ul0[i] != dim.length_ul0 ) then | |
182 | raise ArgumentError, "dimension length do not agree: #{i}th dim: "+\ | |
183 | "#{shape_ul0[i]} and #{dim.length_ul0}" | |
184 | end | |
185 | dims.push(dim) | |
186 | else | |
187 | # dim does not exist --> define it | |
188 | dims.push( def_dim( dimnames[i], shape_ul0[i] ) ) | |
189 | end | |
190 | } | |
191 | def_var(name, vartype, dims) | |
192 | end | |
193 | ||
194 | # Iterators: | |
195 | def each_dim | |
196 | num_dim=ndims() | |
197 | for dimid in 0..num_dim-1 | |
198 | obj_Dim=id2dim(dimid) | |
199 | yield(obj_Dim) | |
200 | end | |
201 | end | |
202 | ||
203 | def each_var | |
204 | num_var=nvars() | |
205 | for varid in 0..num_var-1 | |
206 | obj_Var=id2var(varid) | |
207 | yield(obj_Var) | |
208 | end | |
209 | end | |
210 | ||
211 | def each_att | |
212 | num_att=natts() | |
213 | for attnum in 0..num_att-1 | |
214 | obj_Att=id2att(attnum) | |
215 | yield(obj_Att) | |
216 | end | |
217 | end | |
218 | ||
219 | def dims( names=nil ) # return all if names==nil | |
220 | if names == nil | |
221 | dims = (0..ndims()-1).collect{|dimid| id2dim(dimid)} | |
222 | else | |
223 | raise TypeError, "names is not an array" if ! names.is_a?(Array) | |
224 | dims = names.collect{|name| dim(name)} | |
225 | raise ArgumentError, "One or more dimensions do not exist" if dims.include?(nil) | |
226 | end | |
227 | dims | |
228 | end | |
229 | ||
230 | def vars( names=nil ) # return all if names==nil | |
231 | if names == nil | |
232 | vars = (0..nvars()-1).collect{ |varid| id2var(varid) } | |
233 | else | |
234 | raise TypeError, "names is not an array" if ! names.is_a?(Array) | |
235 | vars = names.collect{|name| var(name)} | |
236 | raise ArgumentError, "One or more variables do not exist" if vars.include?(nil) | |
237 | end | |
238 | vars | |
239 | end | |
240 | ||
241 | def dim_names | |
242 | num_dim=ndims() | |
243 | names=[] | |
244 | for dimid in 0..num_dim-1 | |
245 | obj_Dim=id2dim(dimid) | |
246 | names=names+[obj_Dim.name] | |
247 | end | |
248 | return names | |
249 | end | |
250 | ||
251 | def var_names | |
252 | num_var=nvars() | |
253 | names=[] | |
254 | for varid in 0..num_var-1 | |
255 | obj_Var=id2var(varid) | |
256 | names=names+[obj_Var.name] | |
257 | end | |
258 | return names | |
259 | end | |
260 | ||
261 | def att_names | |
262 | num_att=natts() | |
263 | names=[] | |
264 | for attnum in 0..num_att-1 | |
265 | obj_Att=id2att(attnum) | |
266 | names=names+[obj_Att.name] | |
267 | end | |
268 | return names | |
269 | end | |
270 | ||
271 | def inspect | |
272 | "NetCDF:"+path | |
273 | end | |
274 | ||
275 | end | |
276 | ||
277 | class NetCDFVar | |
278 | ||
279 | class << NetCDFVar | |
280 | def new(file,varname,mode="r",share=false) | |
281 | if(file.is_a?(String)) | |
282 | file = NetCDF.open(file,mode,share) | |
283 | elsif(!file.is_a?(NetCDF)) | |
284 | raise TypeError, "1st arg must be a NetCDF (file object) or a String (path)" | |
285 | end | |
286 | file.var(varname) | |
287 | end | |
288 | ||
289 | alias open new | |
290 | end | |
291 | ||
292 | alias :rank :ndims | |
293 | ||
294 | def each_att | |
295 | num_att=natts() | |
296 | for attnum in 0..num_att-1 | |
297 | obj_Att=id2att(attnum) | |
298 | yield(obj_Att) | |
299 | end | |
300 | end | |
301 | ||
302 | def dim_names | |
303 | ary = Array.new() | |
304 | dims.each{|dim| ary.push(dim.name)} | |
305 | ary | |
306 | end | |
307 | ||
308 | def att_names | |
309 | num_att=natts() | |
310 | names=[] | |
311 | for attnum in 0..num_att-1 | |
312 | obj_Att=id2att(attnum) | |
313 | names=names+[obj_Att.name] | |
314 | end | |
315 | return names | |
316 | end | |
317 | ||
318 | def put_att(attname,val,atttype=nil) | |
319 | put_attraw(attname,val,atttype) | |
320 | end | |
321 | ||
322 | def shape_ul0 | |
323 | sh = [] | |
324 | dims.each{|d| | |
325 | if d.unlimited? then | |
326 | sh.push(0) | |
327 | else | |
328 | sh.push(d.length) | |
329 | end | |
330 | } | |
331 | sh | |
332 | end | |
333 | ||
334 | def shape_current | |
335 | sh = [] | |
336 | dims.each{|d| | |
337 | sh.push(d.length) | |
338 | } | |
339 | sh | |
340 | end | |
341 | ||
342 | # The put and get methods in the NetCDFVar class | |
343 | ||
344 | def pack(na) | |
345 | sf = att('scale_factor') | |
346 | ao = att('add_offset') | |
347 | if ( sf == nil && ao == nil ) then | |
348 | na | |
349 | else | |
350 | na = NArray.to_na(na) if na.is_a?(Array) | |
351 | if sf | |
352 | csf = sf.get | |
353 | raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String) | |
354 | raise NetcdfError, "scale_factor is not unique" if csf.length != 1 | |
355 | raise NetcdfError, "zero scale_factor" if csf[0] == 0 | |
356 | else | |
357 | csf = nil | |
358 | end | |
359 | if ao | |
360 | cao = ao.get | |
361 | raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String) | |
362 | raise NetcdfError, "add_offset is not unique" if cao.length != 1 | |
363 | else | |
364 | cao = nil | |
365 | end | |
366 | if csf and cao | |
367 | packed = (na - cao) / csf | |
368 | elsif csf | |
369 | packed = na / csf | |
370 | elsif cao | |
371 | packed = na - cao | |
372 | end | |
373 | if self.typecode <= NArray::LINT | |
374 | packed = packed.round | |
375 | end | |
376 | packed | |
377 | end | |
378 | end | |
379 | ||
380 | def scaled_put(var,hash=nil) | |
381 | simple_put( pack(var), hash) | |
382 | end | |
383 | ||
384 | @@unpack_type = nil | |
385 | class << NetCDFVar | |
386 | def unpack_type | |
387 | @@unpack_type | |
388 | end | |
389 | def unpack_type=(na_type) | |
390 | if [NArray::BYTE, NArray::SINT, NArray::INT, | |
391 | NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type) | |
392 | @@unpack_type = na_type | |
393 | else | |
394 | raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT" | |
395 | end | |
396 | end | |
397 | ||
398 | end | |
399 | ||
400 | def unpack(na) | |
401 | sf = att('scale_factor') | |
402 | ao = att('add_offset') | |
403 | if ( sf == nil && ao == nil ) then | |
404 | na | |
405 | else | |
406 | if sf | |
407 | csf = sf.get | |
408 | raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String) | |
409 | raise NetcdfError, "scale_factor is not unique" if csf.length != 1 | |
410 | raise NetcdfError, "zero scale_factor" if csf[0] == 0 | |
411 | else | |
412 | csf =nil | |
413 | end | |
414 | if ao | |
415 | cao = ao.get | |
416 | raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String) | |
417 | raise NetcdfError, "add_offset is not unique" if cao.length != 1 | |
418 | else | |
419 | cao = nil | |
420 | end | |
421 | if csf and cao | |
422 | una = na * csf + cao # csf & cao are NArray -> coerced to their types | |
423 | elsif csf | |
424 | una = na * csf | |
425 | elsif cao | |
426 | una = na + cao | |
427 | end | |
428 | una = una.to_type(@@unpack_type) if @@unpack_type | |
429 | una | |
430 | end | |
431 | end | |
432 | ||
433 | def scaled_get(hash=nil) | |
434 | unpack( simple_get(hash) ) | |
435 | end | |
436 | ||
437 | def simple_put(var,hash=nil) | |
438 | if hash==nil | |
439 | if self.vartype == "char" | |
440 | put_var_char(var) | |
441 | elsif self.vartype == "byte" | |
442 | put_var_byte(var) | |
443 | elsif self.vartype == "sint" | |
444 | put_var_sint(var) | |
445 | elsif self.vartype == "int" | |
446 | put_var_int(var) | |
447 | elsif self.vartype == "sfloat" | |
448 | put_var_sfloat(var) | |
449 | elsif self.vartype == "float" | |
450 | put_var_float(var) | |
451 | else | |
452 | raise NetcdfError,"variable type isn't supported in netCDF" | |
453 | end | |
454 | elsif hash.key?("index")==true | |
455 | if self.vartype == "char" | |
456 | put_var1_char(var,hash["index"]) | |
457 | elsif self.vartype=="byte" | |
458 | put_var1_byte(var,hash["index"]) | |
459 | elsif self.vartype=="sint" | |
460 | put_var1_sint(var,hash["index"]) | |
461 | elsif self.vartype == "int" | |
462 | put_var1_int(var,hash["index"]) | |
463 | elsif self.vartype == "sfloat" | |
464 | put_var1_sfloat(var,hash["index"]) | |
465 | elsif self.vartype == "float" | |
466 | put_var1_float(var,hash["index"]) | |
467 | else | |
468 | raise NetcdfError,"variable type isn't supported in netCDF" | |
469 | end | |
470 | elsif hash.key?("start")==true | |
471 | if hash.key?("end")==false && hash.key?("stride")==false | |
472 | if self.vartype == "char" | |
473 | put_vars_char(var,hash["start"],nil,nil) | |
474 | elsif self.vartype=="byte" | |
475 | put_vars_byte(var,hash["start"],nil,nil) | |
476 | elsif self.vartype=="sint" | |
477 | put_vars_sint(var,hash["start"],nil,nil) | |
478 | elsif self.vartype=="int" | |
479 | put_vars_int(var,hash["start"],nil,nil) | |
480 | elsif self.vartype=="sfloat" | |
481 | put_vars_sfloat(var,hash["start"],nil,nil) | |
482 | elsif self.vartype=="float" | |
483 | put_vars_float(var,hash["start"],nil,nil) | |
484 | else | |
485 | raise NetcdfError, "variable type isn't supported in netCDF" | |
486 | end | |
487 | elsif hash.key?("end")==true && hash.key?("stride") == false | |
488 | if self.vartype == "char" | |
489 | put_vars_char(var,hash["start"],hash["end"],nil) | |
490 | elsif self.vartype=="byte" | |
491 | put_vars_byte(var,hash["start"],hash["end"],nil) | |
492 | elsif self.vartype=="sint" | |
493 | put_vars_sint(var,hash["start"],hash["end"],nil) | |
494 | elsif self.vartype=="int" | |
495 | put_vars_int(var,hash["start"],hash["end"],nil) | |
496 | elsif self.vartype == "sfloat" | |
497 | put_vars_sfloat(var,hash["start"],hash["end"],nil) | |
498 | elsif self.vartype =="float" | |
499 | put_vars_float(var,hash["start"],hash["end"],nil) | |
500 | else | |
501 | raise NetcdfError, "variable type isn't supported in netCDF" | |
502 | end | |
503 | elsif hash.key?("end")==false && hash.key?("stride")==true | |
504 | if self.vartype == "char" | |
505 | put_vars_char(var,hash["start"],nil,hash["stride"]) | |
506 | elsif self.vartype=="byte" | |
507 | put_vars_byte(var,hash["start"],nil,hash["stride"]) | |
508 | elsif self.vartype=="sint" | |
509 | put_vars_sint(var,hash["start"],nil,hash["stride"]) | |
510 | elsif self.vartype=="int" | |
511 | put_vars_int(var,hash["start"],nil,hash["stride"]) | |
512 | elsif self.vartype=="sfloat" | |
513 | put_vars_sfloat(var,hash["start"],nil,hash["stride"]) | |
514 | elsif self.vartype=="float" | |
515 | put_vars_float(var,hash["start"],nil,hash["stride"]) | |
516 | else | |
517 | raise NetcdfError, "variable type isn't supported in netCDF" | |
518 | end | |
519 | else hash.key?("end")==true && hash.key?("stride")==true | |
520 | if self.vartype == "char" | |
521 | put_vars_char(var,hash["start"],hash["end"],hash["stride"]) | |
522 | elsif self.vartype=="byte" | |
523 | put_vars_byte(var,hash["start"],hash["end"],hash["stride"]) | |
524 | elsif self.vartype=="sint" | |
525 | put_vars_sint(var,hash["start"],hash["end"],hash["stride"]) | |
526 | elsif self.vartype=="int" | |
527 | put_vars_int(var,hash["start"],hash["end"],hash["stride"]) | |
528 | elsif self.vartype=="sfloat" | |
529 | put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"]) | |
530 | elsif self.vartype=="float" | |
531 | put_vars_float(var,hash["start"],hash["end"],hash["stride"]) | |
532 | else | |
533 | raise NetcdfError, "variable type isn't supported in netCDF" | |
534 | end | |
535 | end | |
536 | else | |
537 | raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed" | |
538 | end | |
539 | end | |
540 | ||
541 | alias put simple_put | |
542 | ||
543 | def simple_get(hash=nil) | |
544 | t_var = self.vartype | |
545 | if hash == nil | |
546 | if t_var == "char" | |
547 | get_var_char | |
548 | elsif t_var == "byte" | |
549 | get_var_byte | |
550 | elsif t_var == "sint" | |
551 | get_var_sint | |
552 | elsif t_var == "int" | |
553 | get_var_int | |
554 | elsif t_var == "sfloat" | |
555 | get_var_sfloat | |
556 | elsif t_var == "float" | |
557 | get_var_float | |
558 | else | |
559 | raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" | |
560 | end | |
561 | elsif hash.key?("index")==true | |
562 | ind = hash["index"] | |
563 | if t_var == "char" | |
564 | get_var1_char(ind) | |
565 | elsif t_var == "byte" | |
566 | get_var1_byte(ind) | |
567 | elsif t_var == "sint" | |
568 | get_var1_sint(ind) | |
569 | elsif t_var == "int" | |
570 | get_var1_int(ind) | |
571 | elsif t_var == "sfloat" | |
572 | get_var1_sfloat(ind) | |
573 | elsif t_var == "float" | |
574 | get_var1_float(ind) | |
575 | else | |
576 | raise NetcdfError,"variable type #{t_var} isn't supported in netCDF" | |
577 | end | |
578 | elsif hash.key?("start")==true | |
579 | h_sta = hash["start"] | |
580 | h_end = hash["end"] # can be nill | |
581 | h_str = hash["stride"] # can be nill | |
582 | if NetCDF.nc4? && h_str && ((xstr=h_str[0]) != 1) | |
583 | # Tentative treatment for the very slow netcdf-4 reading with step. | |
584 | # Reading with step is generally slow with NetCDF 4, but it is | |
585 | # particularly so for the first dimension. | |
586 | # Ref: http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2013/msg00311.html | |
587 | h_str[0] = 1 | |
588 | nc4remedy = true | |
589 | else | |
590 | nc4remedy = false | |
591 | end | |
592 | if t_var == "char" | |
593 | v = get_vars_char(h_sta,h_end,h_str) | |
594 | elsif t_var == "byte" | |
595 | v = get_vars_byte(h_sta,h_end,h_str) | |
596 | elsif t_var == "sint" | |
597 | v = get_vars_sint(h_sta,h_end,h_str) | |
598 | elsif t_var == "int" | |
599 | v = get_vars_int(h_sta,h_end,h_str) | |
600 | elsif t_var == "sfloat" | |
601 | v = get_vars_sfloat(h_sta,h_end,h_str) | |
602 | elsif t_var == "float" | |
603 | v = get_vars_float(h_sta,h_end,h_str) | |
604 | else | |
605 | raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" | |
606 | end | |
607 | if nc4remedy | |
608 | idx = [] | |
609 | (0...v.shape[0]).step(xstr){|k| idx.push(k)} | |
610 | v = v[idx,false] | |
611 | end | |
612 | v | |
613 | else | |
614 | raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed" | |
615 | end | |
616 | end | |
617 | ||
618 | alias get simple_get | |
619 | ||
620 | def __rubber_expansion( args ) | |
621 | if (id = args.index(false)) # substitution into id | |
622 | # false is incuded | |
623 | alen = args.length | |
624 | if args.rindex(false) != id | |
625 | raise ArguemntError,"only one rubber dimension is permitted" | |
626 | elsif alen > rank+1 | |
627 | raise ArgumentError, "too many args" | |
628 | end | |
629 | ar = ( id!=0 ? args[0..id-1] : [] ) | |
630 | args = ar + [true]*(rank-alen+1) + args[id+1..-1] | |
631 | elsif args.length == 0 # to support empty [], []= | |
632 | args = [true]*rank | |
633 | end | |
634 | args | |
635 | end | |
636 | private :__rubber_expansion | |
637 | ||
638 | def [](*a) | |
639 | if a.length == 0 | |
640 | return self.get | |
641 | end | |
642 | a = __rubber_expansion(a) | |
643 | first = Array.new | |
644 | last = Array.new | |
645 | stride = Array.new | |
646 | set_stride = false | |
647 | a.each{|i| | |
648 | if(i.is_a?(Fixnum)) | |
649 | first.push(i) | |
650 | last.push(i) | |
651 | stride.push(1) | |
652 | elsif(i.is_a?(Range)) | |
653 | first.push(i.first) | |
654 | last.push(i.exclude_end? ? i.last-1 : i.last) | |
655 | stride.push(1) | |
656 | elsif(i.is_a?(Hash)) | |
657 | r = (i.to_a[0])[0] | |
658 | s = (i.to_a[0])[1] | |
659 | if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) | |
660 | raise TypeError, "Hash argument must be {a_Range, step}" | |
661 | end | |
662 | first.push(r.first) | |
663 | last.push(r.exclude_end? ? r.last-1 : r.last) | |
664 | stride.push(s) | |
665 | set_stride = true | |
666 | elsif(i.is_a?(TrueClass)) | |
667 | first.push(0) | |
668 | last.push(-1) | |
669 | stride.push(1) | |
670 | elsif( i.is_a?(Array) || i.is_a?(NArray)) | |
671 | a_new = a.dup | |
672 | at = a.index(i) | |
673 | i = NArray.to_na(i) if i.is_a?(Array) | |
674 | for n in 0..i.length-1 | |
675 | a_new[at] = i[n]..i[n] | |
676 | na_tmp = self[*a_new] | |
677 | if n==0 then | |
678 | k = at | |
679 | if at > 0 | |
680 | a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} | |
681 | end | |
682 | shape_tmp = na_tmp.shape | |
683 | shape_tmp[k] = i.length | |
684 | na = na_tmp.class.new(na_tmp.typecode,*shape_tmp) | |
685 | index_tmp = Array.new(shape_tmp.length,true) | |
686 | end | |
687 | index_tmp[k] = n..n | |
688 | na[*index_tmp] = na_tmp | |
689 | end | |
690 | return na | |
691 | else | |
692 | raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" | |
693 | end | |
694 | } | |
695 | ||
696 | if(set_stride) | |
697 | na = self.get({"start"=>first, "end"=>last, "stride"=>stride}) | |
698 | else | |
699 | na = self.get({"start"=>first, "end"=>last}) | |
700 | end | |
701 | shape = na.shape | |
702 | (a.length-1).downto(0){ |i| | |
703 | shape.delete_at(i) if a[i].is_a?(Fixnum) | |
704 | } | |
705 | na.reshape!( *shape ) | |
706 | na | |
707 | end | |
708 | ||
709 | def []=(*a) | |
710 | val = a.pop | |
711 | a = __rubber_expansion(a) | |
712 | first = Array.new | |
713 | last = Array.new | |
714 | stride = Array.new | |
715 | set_stride = false | |
716 | a.each{|i| | |
717 | if(i.is_a?(Fixnum)) | |
718 | first.push(i) | |
719 | last.push(i) | |
720 | stride.push(1) | |
721 | elsif(i.is_a?(Range)) | |
722 | first.push(i.first) | |
723 | last.push(i.exclude_end? ? i.last-1 : i.last) | |
724 | stride.push(1) | |
725 | elsif(i.is_a?(Hash)) | |
726 | r = (i.to_a[0])[0] | |
727 | s = (i.to_a[0])[1] | |
728 | if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) | |
729 | raise ArgumentError, "Hash argument must be {first..last, step}" | |
730 | end | |
731 | first.push(r.first) | |
732 | last.push(r.exclude_end? ? r.last-1 : r.last) | |
733 | stride.push(s) | |
734 | set_stride = true | |
735 | elsif(i.is_a?(TrueClass)) | |
736 | first.push(0) | |
737 | last.push(-1) | |
738 | stride.push(1) | |
739 | elsif(i.is_a?(Array) || i.is_a?(NArray)) | |
740 | a_new = a.dup | |
741 | at = a.index(i) | |
742 | i = NArray.to_na(i) if i.is_a?(Array) | |
743 | val = NArray.to_na(val) if val.is_a?(Array) | |
744 | rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length | |
745 | if val.rank != rank_of_subset | |
746 | raise "rank of the rhs (#{val.rank}) is not equal to the rank "+ | |
747 | "of the subset specified by #{a.inspect} (#{rank_of_subset})" | |
748 | end | |
749 | k = at | |
750 | a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} | |
751 | if i.length != val.shape[k] | |
752 | raise "length of the #{k+1}-th dim of rhs is incorrect "+ | |
753 | "(#{i.length} for #{val.shape[k]})" | |
754 | end | |
755 | index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like | |
756 | for n in 0..i.length-1 | |
757 | a_new[at] = i[n]..i[n] | |
758 | if !val.is_a?(Numeric) then | |
759 | index_tmp[k] = n..n | |
760 | self[*a_new] = val[*index_tmp] | |
761 | else | |
762 | self[*a_new] = val | |
763 | end | |
764 | end | |
765 | return self | |
766 | else | |
767 | raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" | |
768 | end | |
769 | } | |
770 | ||
771 | if(set_stride) | |
772 | self.put(val, {"start"=>first, "end"=>last, "stride"=>stride}) | |
773 | else | |
774 | self.put(val, {"start"=>first, "end"=>last}) | |
775 | end | |
776 | end | |
777 | ||
778 | def inspect | |
779 | 'NetCDFVar:'+file.path+'?var='+name | |
780 | end | |
781 | ||
782 | end | |
783 | ||
784 | class NetCDFAtt | |
785 | ||
786 | def put(val,atttype=nil) | |
787 | putraw(val,atttype) | |
788 | end | |
789 | ||
790 | def inspect | |
791 | 'NetCDFAtt:'+name | |
792 | end | |
793 | end | |
794 | ||
795 | class NetCDFDim | |
796 | def inspect | |
797 | 'NetCDFDim:'+name | |
798 | end | |
799 | ||
800 | def length_ul0 | |
801 | if unlimited? | |
802 | 0 | |
803 | else | |
804 | length | |
805 | end | |
806 | end | |
807 | ||
808 | end | |
809 | end |
0 | require "numru/netcdf" | |
1 | require "narray_miss" | |
2 | ||
3 | module NumRu | |
4 | ||
5 | class NetCDFVar | |
6 | ||
7 | def get_with_miss(*args) | |
8 | __interpret_missing_params if !defined?(@missval) | |
9 | data = simple_get(*args) | |
10 | if @vmin || @vmax | |
11 | if @vmin | |
12 | mask = (data >= @vmin) | |
13 | mask = mask.and(data <= @vmax) if @vmax | |
14 | else | |
15 | mask = (data <= @vmax) | |
16 | end | |
17 | data = NArrayMiss.to_nam(data, mask) | |
18 | elsif @missval # only missing_value is present. | |
19 | mask = (data.ne(@missval)) | |
20 | data = NArrayMiss.to_nam(data, mask) | |
21 | end | |
22 | data | |
23 | end | |
24 | ||
25 | def get_with_miss_and_scaling(*args) | |
26 | __interpret_missing_params if !defined?(@missval) | |
27 | data = simple_get(*args) | |
28 | if @vmin || @vmax | |
29 | if @vmin | |
30 | mask = (data >= @vmin) | |
31 | mask = mask.and(data <= @vmax) if @vmax | |
32 | else | |
33 | mask = (data <= @vmax) | |
34 | end | |
35 | data = NArrayMiss.to_nam(data, mask) | |
36 | elsif @missval # only missing_value is present. | |
37 | mask = (data.ne(@missval)) | |
38 | data = NArrayMiss.to_nam(data, mask) | |
39 | end | |
40 | data = unpack( data ) | |
41 | data | |
42 | end | |
43 | ||
44 | def put_with_miss(data, *args) | |
45 | if data.is_a?( NArrayMiss ) | |
46 | __interpret_missing_params if !defined?(@missval) | |
47 | if @missval | |
48 | simple_put(data.to_na(@missval), *args) | |
49 | else | |
50 | simple_put(data.to_na, *args) | |
51 | end | |
52 | else | |
53 | simple_put(data, *args) | |
54 | end | |
55 | end | |
56 | ||
57 | def put_with_miss_and_scaling(data, *args) | |
58 | if data.is_a?( NArrayMiss ) | |
59 | __interpret_missing_params if !defined?(@missval) | |
60 | if @missval | |
61 | data = pack( data ) | |
62 | data = data.to_na(@missval) | |
63 | else | |
64 | data = pack( data ) | |
65 | data = data.to_na | |
66 | end | |
67 | simple_put(data, *args) | |
68 | else | |
69 | scaled_put(data, *args) | |
70 | end | |
71 | end | |
72 | ||
73 | ######### private ########## | |
74 | ||
75 | def __interpret_missing_params | |
76 | # Interprets the specification of missing data, | |
77 | # either by valid_range, (valid_min and/or valid_max), or missing_value. | |
78 | # (unlike the NetCDF User's guide (NUG), missing_value is interpreted, | |
79 | # but valid_* has a higher precedence.) | |
80 | # Always sets @missval whether missing_value is defined or not, | |
81 | # since it will be used as a fill value for data missing. | |
82 | # | |
83 | @vmin = att('valid_min') | |
84 | @vmin = @vmin.get if @vmin # kept in a NArray(size==1) to consv type | |
85 | @vmax = att('valid_max') | |
86 | @vmax = @vmax.get if @vmax # kept in a NArray(size==1) to consv type | |
87 | vrange = att('valid_range') | |
88 | vrange = vrange.get if vrange | |
89 | if vrange | |
90 | vrange.sort! | |
91 | @vmin = vrange[0..0] # kept in... (same) | |
92 | @vmax = vrange[-1..-1] # kept in... (same) | |
93 | end | |
94 | @missval = att('missing_value') || att('_FillValue') | |
95 | @missval = @missval.get if @missval # kept in... (same) | |
96 | ||
97 | sf = att('scale_factor') | |
98 | ao = att('add_offset') | |
99 | if ( sf || ao ) | |
100 | ## Both NUG & CF conventions requires to specify the valid | |
101 | ## range with respect to the external (i.e. packed) values. | |
102 | ## However, some conventions require specification | |
103 | ## with respect to unpacked values. The following | |
104 | ## is to support such cases as well: | |
105 | thres_tp = [ self.typecode, NArray::LINT ].max | |
106 | @missval = pack(@missval) if @missval && @missval.typecode > thres_tp | |
107 | @vmin = pack(@vmin) if @vmin && @vmin.typecode > thres_tp | |
108 | @vmax = pack(@vmax) if @vmax && @vmax.typecode > thres_tp | |
109 | end | |
110 | ||
111 | if @missval | |
112 | if @vmin && @vmax | |
113 | if @vmin[0] <= @missval[0] && @missval[0] <= @vmax[0] | |
114 | warn "WARNING: missing_value #{@missval[0]} is in the valid range #{@vmin[0]}..#{@vmax[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" | |
115 | end | |
116 | else | |
117 | if @vmin && @missval[0] >= @vmin[0] | |
118 | warn "WARNING: missing_value #{@missval[0]} >= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" | |
119 | elsif @vmax && @missval[0] <= @vmax[0] | |
120 | warn "WARNING: missing_value #{@missval[0]} <= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" | |
121 | end | |
122 | end | |
123 | else | |
124 | realtc = NArray::SFLOAT | |
125 | if @vmin | |
126 | if @vmin[0] >= 0 | |
127 | @missval = ( @vmin.typecode>=realtc ? 0.99*@vmin : @vmin-1 ) | |
128 | else | |
129 | @missval = ( @vmin.typecode>=realtc ? 1.01*@vmin : @vmin-1 ) | |
130 | end | |
131 | elsif @vmax | |
132 | if @vmax[0] >= 0 | |
133 | @missval = ( @vmax.typecode>=realtc ? 1.01*@vmax : @vmax+1 ) | |
134 | else | |
135 | @missval = ( @vmax.typecode>=realtc ? 0.99*@vmax : @vmax+1 ) | |
136 | end | |
137 | end | |
138 | end | |
139 | ||
140 | end | |
141 | ||
142 | private :__interpret_missing_params | |
143 | ||
144 | end | |
145 | ||
146 | end | |
147 | ||
148 | if $0 == __FILE__ | |
149 | include NumRu | |
150 | ||
151 | filename = "tmp.nc" | |
152 | print "creating ",filename,"...\n" | |
153 | file=NetCDF.create(filename) | |
154 | nx = 10 | |
155 | dimx = file.def_dim("x",nx) | |
156 | xf = file.def_var("xf","sfloat",[dimx]) | |
157 | xfn = file.def_var("xfn","sfloat",[dimx]) | |
158 | xf.put_att("valid_range",[-1e12,1e12]) | |
159 | f = 10 ** (2*NArray.sfloat(nx).indgen!) | |
160 | xr = file.def_var("xr","sint",[dimx]) | |
161 | xr.put_att("valid_max",[0.5]) | |
162 | xr.put_att("scale_factor",1e-4) | |
163 | xr.put_att("add_offset",0.5) | |
164 | xr2 = file.def_var("xr2","sint",[dimx]) | |
165 | xr2.put_att("valid_max",NArray.sint(1).fill!(1000)) | |
166 | xr2.put_att("scale_factor",1e-4) | |
167 | xr2.put_att("add_offset",0.5) | |
168 | r = NArray.sfloat(nx).indgen!/nx | |
169 | file.enddef | |
170 | xf.put(f) | |
171 | xfn.put(f) | |
172 | xr.scaled_put(r) | |
173 | file.close | |
174 | ||
175 | file = NetCDF.open(filename,'r+') | |
176 | xf = file.var('xf') | |
177 | xfn = file.var('xfn') | |
178 | p "f0" | |
179 | xf.get.each{|v| print "#{v} "} ; print "\n" | |
180 | p( 'f1', nam = xf.get_with_miss ) | |
181 | def xf.get(*args); get_with_miss(*args); end | |
182 | p( 'f12', xf[2..-3].to_na ) | |
183 | p( 'fn10', xfn.get_with_miss ) | |
184 | p( 'fn11', xfn.get_with_miss_and_scaling ) | |
185 | nam.invalidation([0,1]) | |
186 | p 'f2', nam | |
187 | xf.put_with_miss(nam) | |
188 | p( 'f3', xf.get_with_miss ) | |
189 | xr = file.var('xr') | |
190 | p "r0" | |
191 | xr.simple_get.each{|v| print "#{v} "} ; print "\n" | |
192 | p( 'r1', xr.get_with_miss_and_scaling ) | |
193 | def xr.get(*args); get_with_miss_and_scaling(*args); end | |
194 | def xr.put(*args); put_with_miss_and_scaling(*args); end | |
195 | #xr[0..3] = xr[0..3]*10 | |
196 | p( 'r2', xr.get_with_miss_and_scaling ) | |
197 | p 'r',r | |
198 | xr2.put_with_miss_and_scaling(r) | |
199 | p 'xr2',xr2.get_with_miss_and_scaling | |
200 | file.close | |
201 | print "** ncdump tmp.nc **\n", `ncdump tmp.nc` | |
202 | end |
0 | --- !ruby/object:Gem::Specification | |
1 | name: ruby-netcdf | |
2 | version: !ruby/object:Gem::Version | |
3 | version: 0.7.1.1 | |
4 | platform: ruby | |
5 | authors: | |
6 | - Takeshi Horinouchi | |
7 | - Tsuyoshi Koshiro | |
8 | - Shigenori Otsuka | |
9 | - Seiya Nishizawa | |
10 | - T Sakakima | |
11 | autorequire: | |
12 | bindir: bin | |
13 | cert_chain: [] | |
14 | date: 2015-03-02 00:00:00.000000000 Z | |
15 | dependencies: | |
16 | - !ruby/object:Gem::Dependency | |
17 | name: narray | |
18 | requirement: !ruby/object:Gem::Requirement | |
19 | requirements: | |
20 | - - ! '>=' | |
21 | - !ruby/object:Gem::Version | |
22 | version: '0' | |
23 | type: :runtime | |
24 | prerelease: false | |
25 | version_requirements: !ruby/object:Gem::Requirement | |
26 | requirements: | |
27 | - - ! '>=' | |
28 | - !ruby/object:Gem::Version | |
29 | version: '0' | |
30 | - !ruby/object:Gem::Dependency | |
31 | name: narray_miss | |
32 | requirement: !ruby/object:Gem::Requirement | |
33 | requirements: | |
34 | - - ! '>=' | |
35 | - !ruby/object:Gem::Version | |
36 | version: '0' | |
37 | type: :runtime | |
38 | prerelease: false | |
39 | version_requirements: !ruby/object:Gem::Requirement | |
40 | requirements: | |
41 | - - ! '>=' | |
42 | - !ruby/object:Gem::Version | |
43 | version: '0' | |
44 | description: RubyNetCDF is the Ruby interface to the NetCDF library built on the NArray | |
45 | library, which is an efficient multi-dimensional numeric array class for Ruby. This | |
46 | version works with Ruby2.0. | |
47 | email: | |
48 | - eriko@gfd-dennou.org | |
49 | executables: [] | |
50 | extensions: | |
51 | - extconf.rb | |
52 | extra_rdoc_files: [] | |
53 | files: | |
54 | - .gitignore | |
55 | - .rspec | |
56 | - .travis.yml | |
57 | - ChangeLog | |
58 | - Gemfile | |
59 | - INSTALL | |
60 | - LICENSE.txt | |
61 | - Rakefile | |
62 | - ToDo | |
63 | - bin/console | |
64 | - bin/setup | |
65 | - demo/README | |
66 | - demo/demo1-create-alt.rb | |
67 | - demo/demo1-create.rb | |
68 | - demo/demo2-graphic.rb | |
69 | - demo/demo3-ncepclim.rb | |
70 | - demo/demo4-copy.rb | |
71 | - demo/demo5-netcdf4.rb | |
72 | - doc/README_JP.txt | |
73 | - doc/Ref_man.html | |
74 | - doc/Ref_man.rd | |
75 | - doc/Ref_man_jp.html | |
76 | - doc/Ref_man_jp.rd | |
77 | - doc/to_html | |
78 | - extconf.rb | |
79 | - lib/netcdf.rb | |
80 | - lib/netcdf_miss.rb | |
81 | - lib/version.rb | |
82 | - netcdfraw.c | |
83 | - ruby-netcdf.gemspec | |
84 | - test/aref_aset.rb | |
85 | - test/char_var.rb | |
86 | - test/clone.rb | |
87 | - test/create_tmp.rb | |
88 | - test/def_var_with_dim.rb | |
89 | - test/factor_offset.rb | |
90 | - test/putatt.cdl | |
91 | - test/putatt.rb | |
92 | - test/test.cdl | |
93 | - test/test.rb | |
94 | - test/type.rb | |
95 | homepage: http://www.gfd-dennou.org/arch/ruby/products/ruby-netcdf/ | |
96 | licenses: | |
97 | - GFD Dennou Club | |
98 | metadata: {} | |
99 | post_install_message: | |
100 | rdoc_options: [] | |
101 | require_paths: | |
102 | - lib | |
103 | required_ruby_version: !ruby/object:Gem::Requirement | |
104 | requirements: | |
105 | - - ! '>=' | |
106 | - !ruby/object:Gem::Version | |
107 | version: '1.6' | |
108 | required_rubygems_version: !ruby/object:Gem::Requirement | |
109 | requirements: | |
110 | - - ! '>=' | |
111 | - !ruby/object:Gem::Version | |
112 | version: '0' | |
113 | requirements: [] | |
114 | rubyforge_project: | |
115 | rubygems_version: 2.4.6 | |
116 | signing_key: | |
117 | specification_version: 4 | |
118 | summary: Ruby interface to NetCDF | |
119 | test_files: | |
120 | - demo/README | |
121 | - demo/demo1-create-alt.rb | |
122 | - demo/demo1-create.rb | |
123 | - demo/demo2-graphic.rb | |
124 | - demo/demo3-ncepclim.rb | |
125 | - demo/demo4-copy.rb | |
126 | - demo/demo5-netcdf4.rb | |
127 | - test/aref_aset.rb | |
128 | - test/char_var.rb | |
129 | - test/clone.rb | |
130 | - test/create_tmp.rb | |
131 | - test/def_var_with_dim.rb | |
132 | - test/factor_offset.rb | |
133 | - test/putatt.cdl | |
134 | - test/putatt.rb | |
135 | - test/test.cdl | |
136 | - test/test.rb | |
137 | - test/type.rb |
0 | #include<stdio.h> | |
1 | #include "ruby.h" | |
2 | #include "narray.h" | |
3 | #include<netcdf.h> | |
4 | #include<string.h> | |
5 | ||
6 | /* for compatibility with ruby 1.6 */ | |
7 | #ifndef RSTRING_PTR | |
8 | #define RSTRING_PTR(s) (RSTRING(s)->ptr) | |
9 | #endif | |
10 | #ifndef RSTRING_LEN | |
11 | #define RSTRING_LEN(s) (RSTRING(s)->len) | |
12 | #endif | |
13 | #ifndef RARRAY_PTR | |
14 | #define RARRAY_PTR(a) (RARRAY(a)->ptr) | |
15 | #endif | |
16 | #ifndef RARRAY_LEN | |
17 | #define RARRAY_LEN(a) (RARRAY(a)->len) | |
18 | #endif | |
19 | #ifndef StringValueCStr | |
20 | #define StringValueCStr(s) STR2CSTR(s) | |
21 | #endif | |
22 | #ifndef SafeStringValue | |
23 | #define SafeStringValue(s) Check_SafeStr(s) | |
24 | #endif | |
25 | ||
26 | /* for compatibility for NArray and NArray with big memory patch */ | |
27 | #ifndef NARRAY_BIGMEM | |
28 | typedef int na_shape_t; | |
29 | #endif | |
30 | ||
31 | /* Data to NArray */ | |
32 | ||
33 | /* memcpy(ary->ptr,nc_ptr,na_sizeof[NA_SINT]*ary->total); \ */ | |
34 | ||
35 | #define Cbyte_to_NArray(v, rank, shape, up) \ | |
36 | { \ | |
37 | struct NARRAY *ary; \ | |
38 | v = na_make_object(NA_BYTE, rank, shape, cNArray); \ | |
39 | GetNArray(v,ary); \ | |
40 | up = (unsigned char *)ary->ptr; \ | |
41 | } | |
42 | ||
43 | #define Csint_to_NArray(v, rank, shape, sp) \ | |
44 | { \ | |
45 | struct NARRAY *ary; \ | |
46 | v = na_make_object(NA_SINT, rank, shape, cNArray); \ | |
47 | GetNArray(v, ary); \ | |
48 | sp = (short *)ary->ptr; \ | |
49 | } | |
50 | ||
51 | #define Clint_to_NArray(v, rank, shape, lp) \ | |
52 | { \ | |
53 | struct NARRAY *ary; \ | |
54 | v = na_make_object(NA_LINT, rank, shape, cNArray); \ | |
55 | GetNArray(v, ary); \ | |
56 | lp = (int *)ary->ptr; \ | |
57 | } | |
58 | #define Cfloat_to_NArray(v, rank, shape, fp) \ | |
59 | { \ | |
60 | struct NARRAY *ary; \ | |
61 | v = na_make_object(NA_SFLOAT, rank, shape, cNArray); \ | |
62 | GetNArray(v, ary); \ | |
63 | fp = (float *)ary->ptr; \ | |
64 | } | |
65 | #define Cdouble_to_NArray(v, rank, shape, dp); \ | |
66 | { \ | |
67 | struct NARRAY *ary; \ | |
68 | v = na_make_object(NA_DFLOAT, rank, shape, cNArray); \ | |
69 | GetNArray(v, ary); \ | |
70 | dp = (double *)ary->ptr; \ | |
71 | } | |
72 | ||
73 | /* Array or NArray to pointer and length (with no new allocation) */ | |
74 | ||
75 | #define Array_to_Cfloat_len(obj, ptr, len) \ | |
76 | { \ | |
77 | struct NARRAY *na; \ | |
78 | obj = na_cast_object(obj, NA_SFLOAT); \ | |
79 | GetNArray(obj, na); \ | |
80 | ptr = (float *) NA_PTR(na,0); \ | |
81 | len = na->total; \ | |
82 | } | |
83 | ||
84 | #define Array_to_Cfloat_len_shape(obj, ptr, len, shape) \ | |
85 | { \ | |
86 | struct NARRAY *na; \ | |
87 | obj = na_cast_object(obj, NA_SFLOAT); \ | |
88 | GetNArray(obj, na); \ | |
89 | ptr = (float *) NA_PTR(na,0); \ | |
90 | len = na->total; \ | |
91 | shape = na->shape; \ | |
92 | } | |
93 | ||
94 | #define Array_to_Cdouble_len(obj, ptr, len) \ | |
95 | { \ | |
96 | struct NARRAY *na; \ | |
97 | obj = na_cast_object(obj, NA_DFLOAT); \ | |
98 | GetNArray(obj, na); \ | |
99 | ptr = (double *) NA_PTR(na,0); \ | |
100 | len = na->total; \ | |
101 | } | |
102 | #define Array_to_Cdouble_len_shape(obj, ptr, len, shape) \ | |
103 | { \ | |
104 | struct NARRAY *na; \ | |
105 | obj = na_cast_object(obj, NA_DFLOAT); \ | |
106 | GetNArray(obj, na); \ | |
107 | ptr = (double *) NA_PTR(na,0); \ | |
108 | len = na->total; \ | |
109 | shape = na->shape; \ | |
110 | } | |
111 | ||
112 | #define Array_to_Cbyte_len(obj, ptr, len) \ | |
113 | { \ | |
114 | struct NARRAY *na; \ | |
115 | obj = na_cast_object(obj, NA_BYTE); \ | |
116 | GetNArray(obj, na); \ | |
117 | ptr = (u_int8_t *) NA_PTR(na,0); \ | |
118 | len = na->total; \ | |
119 | } | |
120 | ||
121 | #define Array_to_Cbyte_len_shape(obj, ptr, len, shape) \ | |
122 | { \ | |
123 | struct NARRAY *na; \ | |
124 | obj = na_cast_object(obj, NA_BYTE); \ | |
125 | GetNArray(obj, na); \ | |
126 | ptr = (u_int8_t *) NA_PTR(na,0); \ | |
127 | len = na->total; \ | |
128 | shape = na->shape; \ | |
129 | } | |
130 | ||
131 | #define Array_to_Csint_len(obj, ptr, len) \ | |
132 | { \ | |
133 | struct NARRAY *na; \ | |
134 | obj = na_cast_object(obj, NA_SINT); \ | |
135 | GetNArray(obj, na); \ | |
136 | ptr = (int16_t *) NA_PTR(na,0); \ | |
137 | len = na->total; \ | |
138 | } | |
139 | ||
140 | #define Array_to_Csint_len_shape(obj, ptr, len, shape) \ | |
141 | { \ | |
142 | struct NARRAY *na; \ | |
143 | obj = na_cast_object(obj, NA_SINT); \ | |
144 | GetNArray(obj, na); \ | |
145 | ptr = (int16_t *) NA_PTR(na,0); \ | |
146 | len = na->total; \ | |
147 | shape = na->shape; \ | |
148 | } | |
149 | ||
150 | ||
151 | #define Array_to_Clint_len(obj, ptr, len) \ | |
152 | { \ | |
153 | struct NARRAY *na; \ | |
154 | obj = na_cast_object(obj, NA_LINT); \ | |
155 | GetNArray(obj, na); \ | |
156 | ptr = (int32_t *) NA_PTR(na,0); \ | |
157 | len = na->total; \ | |
158 | } | |
159 | ||
160 | #define Array_to_Clint_len_shape(obj, ptr, len, shape) \ | |
161 | { \ | |
162 | struct NARRAY *na; \ | |
163 | obj = na_cast_object(obj, NA_LINT); \ | |
164 | GetNArray(obj, na); \ | |
165 | ptr = (int32_t *) NA_PTR(na,0); \ | |
166 | len = na->total; \ | |
167 | shape = na->shape; \ | |
168 | } | |
169 | ||
170 | ||
171 | /* Array or NArray to pointer (with no new allocation) */ | |
172 | ||
173 | #define Array_to_Cfloat(obj, ptr) \ | |
174 | { \ | |
175 | struct NARRAY *na; \ | |
176 | obj = na_cast_object(obj, NA_SFLOAT); \ | |
177 | GetNArray(obj, na); \ | |
178 | ptr = (float *) NA_PTR(na,0); \ | |
179 | } | |
180 | #define Array_to_Cdouble(obj, ptr) \ | |
181 | { \ | |
182 | struct NARRAY *na; \ | |
183 | obj = na_cast_object(obj, NA_DFLOAT); \ | |
184 | GetNArray(obj, na); \ | |
185 | ptr = (double *) NA_PTR(na,0); \ | |
186 | } | |
187 | #define Array_to_Cbyte(obj, ptr) \ | |
188 | { \ | |
189 | struct NARRAY *na; \ | |
190 | obj = na_cast_object(obj, NA_BYTE); \ | |
191 | GetNArray(obj, na); \ | |
192 | ptr = (u_int8_t *) NA_PTR(na,0); \ | |
193 | } | |
194 | #define Array_to_Csint(obj, ptr) \ | |
195 | { \ | |
196 | struct NARRAY *na; \ | |
197 | obj = na_cast_object(obj, NA_SINT); \ | |
198 | GetNArray(obj, na); \ | |
199 | ptr = (int16_t *) NA_PTR(na,0); \ | |
200 | } | |
201 | #define Array_to_Clint(obj, ptr) \ | |
202 | { \ | |
203 | struct NARRAY *na; \ | |
204 | obj = na_cast_object(obj, NA_LINT); \ | |
205 | GetNArray(obj, na); \ | |
206 | ptr = (int32_t *) NA_PTR(na,0); \ | |
207 | } | |
208 | ||
209 | #define NC_RAISE(status) rb_raise(err_status2class(status),"%s",(nc_strerror(status))) | |
210 | #define NC_RAISE2(status, str) rb_raise(err_status2class(status),"%s (%s)",nc_strerror(status),(str) ) | |
211 | ||
212 | static VALUE mNumRu = 0; | |
213 | static VALUE cNetCDF; | |
214 | static VALUE cNetCDFDim; | |
215 | static VALUE cNetCDFAtt; | |
216 | static VALUE cNetCDFVar; | |
217 | ||
218 | static VALUE rb_eNetcdfError; | |
219 | static VALUE rb_eNetcdfBadid; | |
220 | static VALUE rb_eNetcdfNfile; | |
221 | static VALUE rb_eNetcdfExist; | |
222 | static VALUE rb_eNetcdfInval; | |
223 | static VALUE rb_eNetcdfPerm; | |
224 | static VALUE rb_eNetcdfNotindefine; | |
225 | static VALUE rb_eNetcdfIndefine; | |
226 | static VALUE rb_eNetcdfInvalcoords; | |
227 | static VALUE rb_eNetcdfMaxdims; | |
228 | static VALUE rb_eNetcdfNameinuse; | |
229 | static VALUE rb_eNetcdfNotatt; | |
230 | static VALUE rb_eNetcdfMaxatts; | |
231 | static VALUE rb_eNetcdfBadtype; | |
232 | static VALUE rb_eNetcdfBaddim; | |
233 | static VALUE rb_eNetcdfUnlimpos; | |
234 | static VALUE rb_eNetcdfMaxvars; | |
235 | static VALUE rb_eNetcdfNotvar; | |
236 | static VALUE rb_eNetcdfGlobal; | |
237 | static VALUE rb_eNetcdfNotnc; | |
238 | static VALUE rb_eNetcdfSts; | |
239 | static VALUE rb_eNetcdfMaxname; | |
240 | static VALUE rb_eNetcdfUnlimit; | |
241 | static VALUE rb_eNetcdfNorecvars; | |
242 | static VALUE rb_eNetcdfChar; | |
243 | static VALUE rb_eNetcdfEdge; | |
244 | static VALUE rb_eNetcdfStride; | |
245 | static VALUE rb_eNetcdfBadname; | |
246 | static VALUE rb_eNetcdfRange; | |
247 | static VALUE rb_eNetcdfNomem; | |
248 | ||
249 | /* Special Error */ | |
250 | /* Global error status */ | |
251 | ||
252 | static VALUE rb_eNetcdfFatal; | |
253 | ||
254 | /* Global options variable. Used to determine behavior of error handler. */ | |
255 | ||
256 | static VALUE rb_eNetcdfEntool; | |
257 | static VALUE rb_eNetcdfExdr; | |
258 | static VALUE rb_eNetcdfSyserr; | |
259 | ||
260 | ||
261 | struct Netcdf{ | |
262 | int ncid; | |
263 | char *name; | |
264 | int closed; | |
265 | }; | |
266 | ||
267 | struct NetCDFDim{ | |
268 | int dimid; | |
269 | int ncid; | |
270 | }; | |
271 | ||
272 | struct NetCDFVar{ | |
273 | int varid; | |
274 | int ncid; | |
275 | VALUE file; | |
276 | }; | |
277 | ||
278 | struct NetCDFAtt{ | |
279 | int varid; | |
280 | int ncid; | |
281 | char *name; | |
282 | }; | |
283 | ||
284 | static struct Netcdf * | |
285 | NetCDF_init(int ncid,char *filename) | |
286 | { | |
287 | struct Netcdf *Netcdffile; | |
288 | Netcdffile=xmalloc(sizeof(struct Netcdf)); | |
289 | Netcdffile->ncid=ncid; | |
290 | Netcdffile->closed=0; | |
291 | Netcdffile->name=xmalloc((strlen(filename)+1)*sizeof(char)); | |
292 | strcpy(Netcdffile->name,filename); | |
293 | return(Netcdffile); | |
294 | } | |
295 | ||
296 | static struct NetCDFDim * | |
297 | NetCDF_dim_init(int ncid,int dimid) | |
298 | { | |
299 | struct NetCDFDim *Netcdf_dim; | |
300 | Netcdf_dim=xmalloc(sizeof(struct NetCDFDim)); | |
301 | Netcdf_dim->dimid=dimid; | |
302 | Netcdf_dim->ncid=ncid; | |
303 | return(Netcdf_dim); | |
304 | } | |
305 | ||
306 | static struct NetCDFVar * | |
307 | NetCDF_var_init(int ncid,int varid,VALUE file) | |
308 | { | |
309 | struct NetCDFVar *Netcdf_var; | |
310 | Netcdf_var=xmalloc(sizeof(struct NetCDFVar)); | |
311 | Netcdf_var->varid=varid; | |
312 | Netcdf_var->ncid=ncid; | |
313 | Netcdf_var->file=file; | |
314 | return(Netcdf_var); | |
315 | } | |
316 | static struct NetCDFAtt * | |
317 | NetCDF_att_init(int ncid,int varid,char *attname) | |
318 | { | |
319 | struct NetCDFAtt *Netcdf_att; | |
320 | Netcdf_att=xmalloc(sizeof(struct NetCDFAtt)); | |
321 | Netcdf_att->ncid=ncid; | |
322 | Netcdf_att->varid=varid; | |
323 | Netcdf_att->name=xmalloc((strlen(attname)+1)*sizeof(char)); | |
324 | strcpy(Netcdf_att->name,attname); | |
325 | return(Netcdf_att); | |
326 | } | |
327 | ||
328 | void | |
329 | Netcdf_att_free(struct NetCDFAtt *Netcdf_att) | |
330 | { | |
331 | free(Netcdf_att->name); | |
332 | free(Netcdf_att); | |
333 | } | |
334 | ||
335 | void | |
336 | NetCDF_var_free(struct NetCDFVar *Netcdf_var) | |
337 | { | |
338 | free(Netcdf_var); | |
339 | } | |
340 | ||
341 | void | |
342 | NetCDF_dim_free(struct NetCDFDim *Netcdf_dim) | |
343 | { | |
344 | free(Netcdf_dim); | |
345 | } | |
346 | ||
347 | void | |
348 | NetCDF_free(struct Netcdf *Netcdffile) | |
349 | { | |
350 | if (!Netcdffile->closed){ | |
351 | nc_close(Netcdffile->ncid); /* no error check -- not to stop during GC */ | |
352 | } | |
353 | free(Netcdffile->name); | |
354 | free(Netcdffile); | |
355 | } | |
356 | ||
357 | static VALUE | |
358 | err_status2class(int status) | |
359 | { | |
360 | if(NC_ISSYSERR(status)){ | |
361 | return(rb_eNetcdfSyserr); | |
362 | } | |
363 | switch(status) | |
364 | { | |
365 | case(NC_EBADID): | |
366 | return(rb_eNetcdfBadid);break; | |
367 | case(NC_ENFILE): | |
368 | return(rb_eNetcdfNfile);break; | |
369 | case(NC_EEXIST): | |
370 | return(rb_eNetcdfExist);break; | |
371 | case(NC_EINVAL): | |
372 | return(rb_eNetcdfInval);break; | |
373 | case(NC_EPERM): | |
374 | return(rb_eNetcdfPerm);break; | |
375 | case(NC_ENOTINDEFINE): | |
376 | return(rb_eNetcdfNotindefine);break; | |
377 | case(NC_EINDEFINE): | |
378 | return(rb_eNetcdfIndefine);break; | |
379 | case(NC_EINVALCOORDS): | |
380 | return(rb_eNetcdfInvalcoords);break; | |
381 | case(NC_EMAXDIMS): | |
382 | return(rb_eNetcdfMaxdims);break; | |
383 | case(NC_ENAMEINUSE): | |
384 | return(rb_eNetcdfNameinuse);break; | |
385 | case(NC_ENOTATT): | |
386 | return(rb_eNetcdfNotatt);break; | |
387 | case(NC_EMAXATTS): | |
388 | return(rb_eNetcdfMaxatts);break; | |
389 | case(NC_EBADTYPE): | |
390 | return(rb_eNetcdfBadtype);break; | |
391 | case(NC_EBADDIM): | |
392 | return(rb_eNetcdfBaddim);break; | |
393 | case(NC_EUNLIMPOS): | |
394 | return(rb_eNetcdfUnlimpos);break; | |
395 | case(NC_EMAXVARS): | |
396 | return(rb_eNetcdfMaxvars);break; | |
397 | case(NC_ENOTVAR): | |
398 | return(rb_eNetcdfNotvar);break; | |
399 | case(NC_EGLOBAL): | |
400 | return(rb_eNetcdfGlobal);break; | |
401 | case(NC_ENOTNC): | |
402 | return(rb_eNetcdfNotnc);break; | |
403 | case(NC_ESTS): | |
404 | return(rb_eNetcdfSts);break; | |
405 | case(NC_EMAXNAME): | |
406 | return(rb_eNetcdfMaxname);break; | |
407 | case(NC_EUNLIMIT): | |
408 | return(rb_eNetcdfUnlimit);break; | |
409 | case(NC_ENORECVARS): | |
410 | return(rb_eNetcdfNorecvars);break; | |
411 | case(NC_ECHAR): | |
412 | return(rb_eNetcdfChar);break; | |
413 | case(NC_EEDGE): | |
414 | return(rb_eNetcdfEdge);break; | |
415 | case(NC_ESTRIDE): | |
416 | return(rb_eNetcdfStride);break; | |
417 | case(NC_EBADNAME): | |
418 | return(rb_eNetcdfBadname);break; | |
419 | case(NC_ERANGE): | |
420 | return(rb_eNetcdfRange);break; | |
421 | case(NC_ENOMEM): | |
422 | return(rb_eNetcdfNomem);break; | |
423 | /* case(NC_ENTOOL): | |
424 | return(rb_eNetcdfEntool);break; */ | |
425 | case(NC_EXDR): | |
426 | return(rb_eNetcdfExdr);break; | |
427 | case(NC_SYSERR): | |
428 | return(rb_eNetcdfSyserr);break; | |
429 | case(NC_FATAL): | |
430 | return(rb_eNetcdfFatal);break; | |
431 | } | |
432 | return rb_eNetcdfError; | |
433 | } | |
434 | ||
435 | static const char* | |
436 | nctype2natype(int nctype){ | |
437 | switch(nctype){ | |
438 | case NC_CHAR: | |
439 | return("char"); | |
440 | case NC_BYTE: | |
441 | return("byte"); | |
442 | case NC_SHORT: | |
443 | return("sint"); | |
444 | case NC_INT: | |
445 | return("int"); | |
446 | case NC_FLOAT: | |
447 | return("sfloat"); | |
448 | case NC_DOUBLE: | |
449 | return("float"); | |
450 | default: | |
451 | rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype); | |
452 | } | |
453 | } | |
454 | ||
455 | static int | |
456 | nctype2natypecode(int nctype){ | |
457 | switch(nctype){ | |
458 | case NC_CHAR: | |
459 | return(NA_BYTE); | |
460 | case NC_BYTE: | |
461 | return(NA_BYTE); | |
462 | case NC_SHORT: | |
463 | return(NA_SINT); | |
464 | case NC_INT: | |
465 | return(NA_LINT); | |
466 | case NC_FLOAT: | |
467 | return(NA_SFLOAT); | |
468 | case NC_DOUBLE: | |
469 | return(NA_DFLOAT); | |
470 | default: | |
471 | rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype); | |
472 | } | |
473 | } | |
474 | ||
475 | static int | |
476 | natype2nctype(char *natype) | |
477 | { | |
478 | if(strcmp(natype,"byte")==0) return(NC_BYTE); | |
479 | else if(strcmp(natype,"char")==0) return(NC_CHAR); | |
480 | else if(strcmp(natype,"text")==0) return(NC_CHAR); /* alias of char */ | |
481 | else if(strcmp(natype,"string")==0) return(NC_CHAR); /* alias of char */ | |
482 | else if(strcmp(natype,"sint")==0) return(NC_SHORT); | |
483 | else if(strcmp(natype,"int")==0) return(NC_INT); | |
484 | else if(strcmp(natype,"sfloat")==0) return(NC_FLOAT); | |
485 | else if(strcmp(natype,"float")==0) return(NC_DOUBLE); | |
486 | else rb_raise(rb_eNetcdfError, "No such NArray type '%s'",natype); | |
487 | } | |
488 | ||
489 | static int | |
490 | natypecode2nctype(int natypecode) | |
491 | { | |
492 | if(natypecode==NA_BYTE) return(NC_BYTE); | |
493 | else if(natypecode==NA_SINT) return(NC_SHORT); | |
494 | else if(natypecode==NA_LINT) return(NC_INT); | |
495 | else if(natypecode==NA_SFLOAT) return(NC_FLOAT); | |
496 | else if(natypecode==NA_DFLOAT) return(NC_DOUBLE); | |
497 | else rb_raise(rb_eNetcdfError, "No such NArray typecode '%d'",natypecode); | |
498 | } | |
499 | ||
500 | static void | |
501 | nc_mark_obj(struct NetCDFVar *netcdf_var) | |
502 | { | |
503 | VALUE ptr; | |
504 | ||
505 | ptr = netcdf_var->file; | |
506 | rb_gc_mark(ptr); | |
507 | } | |
508 | ||
509 | ||
510 | VALUE | |
511 | NetCDF_clone(VALUE file) | |
512 | { | |
513 | VALUE clone; | |
514 | struct Netcdf *nc1, *nc2; | |
515 | ||
516 | Data_Get_Struct(file, struct Netcdf, nc1); | |
517 | nc2 = NetCDF_init(nc1->ncid, nc1->name); | |
518 | clone = Data_Wrap_Struct(cNetCDF, 0, NetCDF_free, nc2); | |
519 | CLONESETUP(clone, file); | |
520 | return clone; | |
521 | } | |
522 | ||
523 | VALUE | |
524 | NetCDF_dim_clone(VALUE dim) | |
525 | { | |
526 | VALUE clone; | |
527 | struct NetCDFDim *nd1, *nd2; | |
528 | ||
529 | Data_Get_Struct(dim, struct NetCDFDim, nd1); | |
530 | nd2 = NetCDF_dim_init(nd1->ncid, nd1->dimid); | |
531 | clone = Data_Wrap_Struct(cNetCDFDim, 0, NetCDF_dim_free, nd2); | |
532 | CLONESETUP(clone, dim); | |
533 | return clone; | |
534 | } | |
535 | ||
536 | VALUE | |
537 | NetCDF_att_clone(VALUE att) | |
538 | { | |
539 | VALUE clone; | |
540 | struct NetCDFAtt *na1, *na2; | |
541 | ||
542 | Data_Get_Struct(att, struct NetCDFAtt, na1); | |
543 | na2 = NetCDF_att_init(na1->ncid, na1->varid, na1->name); | |
544 | clone = Data_Wrap_Struct(cNetCDFAtt, 0, Netcdf_att_free, na2); | |
545 | CLONESETUP(clone, att); | |
546 | return clone; | |
547 | } | |
548 | ||
549 | VALUE | |
550 | NetCDF_var_clone(VALUE var) | |
551 | { | |
552 | VALUE clone; | |
553 | struct NetCDFVar *nv1, *nv2; | |
554 | ||
555 | Data_Get_Struct(var, struct NetCDFVar, nv1); | |
556 | nv2 = NetCDF_var_init(nv1->ncid, nv1->varid, nv1->file); | |
557 | clone = Data_Wrap_Struct(cNetCDFVar, nc_mark_obj, NetCDF_var_free, nv2); | |
558 | CLONESETUP(clone, var); | |
559 | return clone; | |
560 | } | |
561 | ||
562 | VALUE | |
563 | NetCDF_inq_libvers(VALUE mod) | |
564 | { | |
565 | VALUE str; | |
566 | str = rb_str_new2(nc_inq_libvers()); | |
567 | return(str); | |
568 | } | |
569 | ||
570 | VALUE | |
571 | NetCDF_close(file) | |
572 | VALUE file; | |
573 | { | |
574 | int status; | |
575 | int ncid; | |
576 | struct Netcdf *Netcdffile; | |
577 | ||
578 | if (rb_safe_level() >= 3 && !OBJ_TAINTED(file)) { | |
579 | rb_raise(rb_eSecurityError, "Insecure: can't close"); | |
580 | } | |
581 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
582 | ncid=Netcdffile->ncid; | |
583 | if(!Netcdffile->closed){ | |
584 | status = nc_close(ncid); | |
585 | if(status != NC_NOERR) NC_RAISE(status); | |
586 | Netcdffile->closed = 1; | |
587 | } else { | |
588 | rb_warn("file %s is already closed", Netcdffile->name); | |
589 | } | |
590 | return Qnil; | |
591 | } | |
592 | ||
593 | VALUE | |
594 | NetCDF_def_dim(VALUE file,VALUE dim_name,VALUE length) | |
595 | { | |
596 | char* c_dim_name; | |
597 | size_t c_length; | |
598 | int ncid; | |
599 | int dimidp; | |
600 | int status; | |
601 | struct Netcdf *Netcdffile; | |
602 | struct NetCDFDim *Netcdf_dim; | |
603 | VALUE Dimension; | |
604 | ||
605 | rb_secure(3); | |
606 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
607 | ||
608 | Check_Type(dim_name,T_STRING); | |
609 | c_dim_name=RSTRING_PTR(dim_name); | |
610 | c_length=NUM2UINT(length); | |
611 | ncid=Netcdffile->ncid; | |
612 | ||
613 | status = nc_def_dim(ncid,c_dim_name,c_length,&dimidp); | |
614 | if(status !=NC_NOERR) NC_RAISE(status); | |
615 | ||
616 | Netcdf_dim = NetCDF_dim_init(ncid,dimidp); | |
617 | ||
618 | Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
619 | return Dimension; | |
620 | } | |
621 | ||
622 | ||
623 | static VALUE | |
624 | NetCDF_put_att_char(int ncid, char *name,VALUE value,VALUE atttype, int varid) | |
625 | { | |
626 | int status; | |
627 | struct NetCDFAtt *ncatt; | |
628 | ||
629 | /* check atttype (not necessarily needed but it's better to do it) */ | |
630 | if (TYPE(atttype) == T_STRING){ | |
631 | if ( natype2nctype(RSTRING_PTR(atttype)) != NC_CHAR ) { | |
632 | rb_raise(rb_eNetcdfError, | |
633 | "attribute type must be 'char' (or nil) for a String value"); | |
634 | } | |
635 | } else if (TYPE(atttype) != T_NIL) { | |
636 | rb_raise(rb_eNetcdfError, | |
637 | "type specfication must be by a string or nil"); | |
638 | } | |
639 | /* put value */ | |
640 | Check_Type(value,T_STRING); | |
641 | status = nc_put_att_text(ncid, varid, name, | |
642 | RSTRING_LEN(value), RSTRING_PTR(value)); | |
643 | if(status != NC_NOERR) NC_RAISE(status); | |
644 | ||
645 | ncatt = NetCDF_att_init(ncid,varid,name); | |
646 | return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt)); | |
647 | } | |
648 | ||
649 | static VALUE | |
650 | NetCDF_put_att_numeric(int ncid, char *name,VALUE value,VALUE atttype, int varid) | |
651 | { | |
652 | VALUE val; | |
653 | struct NARRAY *na_val; | |
654 | int na_typecode, status, len; | |
655 | char *ptr; | |
656 | struct NetCDFAtt *ncatt; | |
657 | ||
658 | /* check atttype and cast to an appropriate NArray if needed */ | |
659 | ||
660 | if (TYPE(atttype) != T_NIL){ | |
661 | na_typecode = na_get_typecode(atttype); | |
662 | GetNArray( na_cast_object(value, na_typecode), na_val ); | |
663 | } else { | |
664 | if (TYPE(value)==T_ARRAY) { | |
665 | val = RARRAY_PTR(value)[0]; /* to check the 1st elemnt if Array */ | |
666 | } else { | |
667 | val = value; | |
668 | } | |
669 | switch(TYPE(val)){ | |
670 | case T_FIXNUM: | |
671 | case T_BIGNUM: | |
672 | na_typecode = NA_LINT; | |
673 | GetNArray( na_cast_object(value, na_typecode), na_val ); | |
674 | break; | |
675 | case T_FLOAT: | |
676 | na_typecode = NA_DFLOAT; | |
677 | GetNArray( na_cast_object(value, na_typecode), na_val ); | |
678 | break; | |
679 | case T_DATA: | |
680 | if ( IsNArray(value) ){ | |
681 | GetNArray(value,na_val); | |
682 | na_typecode = na_val->type; | |
683 | } else { | |
684 | rb_raise(rb_eNetcdfError,"value has a wrong data type"); | |
685 | } | |
686 | break; | |
687 | default: | |
688 | rb_raise(rb_eNetcdfError, | |
689 | "value (or its first element) has a wrong type"); | |
690 | } | |
691 | } | |
692 | ||
693 | /* put value */ | |
694 | ||
695 | len = na_val->total; | |
696 | ptr = na_val->ptr; | |
697 | switch(na_typecode){ | |
698 | case NA_BYTE: | |
699 | status = nc_put_att_uchar(ncid,varid,name,NC_BYTE,len,(unsigned char *)ptr); | |
700 | break; | |
701 | case NA_SINT: | |
702 | status = nc_put_att_short(ncid,varid,name,NC_SHORT,len,(short *)ptr); | |
703 | break; | |
704 | case NA_LINT: | |
705 | status = nc_put_att_int(ncid,varid,name,NC_INT,len,(int *)ptr); | |
706 | break; | |
707 | case NA_SFLOAT: | |
708 | status = nc_put_att_float(ncid,varid,name,NC_FLOAT,len,(float *)ptr); | |
709 | break; | |
710 | case NA_DFLOAT: | |
711 | status = nc_put_att_double(ncid,varid,name,NC_DOUBLE,len,(double*)ptr); | |
712 | break; | |
713 | default: | |
714 | rb_raise(rb_eNetcdfError, | |
715 | "unsupported type. code = %d",na_typecode); | |
716 | } | |
717 | if(status != NC_NOERR) NC_RAISE(status); | |
718 | ||
719 | ncatt = NetCDF_att_init(ncid,varid,name); | |
720 | return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt)); | |
721 | } | |
722 | ||
723 | static VALUE | |
724 | NetCDF_put_att__(int ncid, char *name, VALUE value, VALUE atttype, int varid) | |
725 | /* | |
726 | * atttype: nil or a String ("string","int",etc). If nil, | |
727 | * the type of attribute is determined from the type of value | |
728 | */ | |
729 | { | |
730 | switch(TYPE(value)){ | |
731 | case T_STRING: | |
732 | return(NetCDF_put_att_char(ncid, name, value, atttype, varid)); | |
733 | default: | |
734 | return(NetCDF_put_att_numeric(ncid, name, value, atttype, varid)); | |
735 | } | |
736 | } | |
737 | ||
738 | VALUE | |
739 | NetCDF_put_att(VALUE file,VALUE att_name,VALUE value,VALUE atttype) | |
740 | /* | |
741 | * atttype: nil or a String ("string","int",etc). If nil, | |
742 | * the type of attribute is determined from the type of value | |
743 | */ | |
744 | { | |
745 | struct Netcdf *ncfile; | |
746 | char *name; | |
747 | ||
748 | rb_secure(3); | |
749 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
750 | Check_Type(att_name,T_STRING); | |
751 | name = RSTRING_PTR(att_name); | |
752 | ||
753 | return( NetCDF_put_att__(ncfile->ncid, name, value, atttype, NC_GLOBAL) ); | |
754 | } | |
755 | ||
756 | VALUE | |
757 | NetCDF_put_att_var(VALUE var,VALUE att_name,VALUE value,VALUE atttype) | |
758 | /* | |
759 | * atttype: nil or a String ("string","int",etc). If nil, | |
760 | * the type of attribute is determined from the type of value | |
761 | */ | |
762 | { | |
763 | struct NetCDFVar *ncvar; | |
764 | char *name; | |
765 | ||
766 | rb_secure(3); | |
767 | Data_Get_Struct(var,struct NetCDFVar,ncvar); | |
768 | Check_Type(att_name,T_STRING); | |
769 | name = RSTRING_PTR(att_name); | |
770 | ||
771 | return( NetCDF_put_att__(ncvar->ncid, name, value, atttype, ncvar->varid)); | |
772 | } | |
773 | ||
774 | ||
775 | VALUE | |
776 | NetCDF_def_var(VALUE file,VALUE var_name,VALUE vartype,VALUE dimensions) | |
777 | { | |
778 | int ncid; | |
779 | char *c_var_name; | |
780 | static int xtype; | |
781 | long c_ndims; | |
782 | int varidp; | |
783 | int dimidp; | |
784 | int i=0; | |
785 | int status; | |
786 | char *c_dim_name; | |
787 | int c_dimids[NC_MAX_DIMS]; | |
788 | struct Netcdf *Netcdffile; | |
789 | struct NetCDFVar *Netcdf_var; | |
790 | struct NetCDFDim *Netcdf_dim; | |
791 | VALUE Var; | |
792 | ||
793 | rb_secure(3); | |
794 | Check_Type(var_name,T_STRING); | |
795 | Check_Type(dimensions,T_ARRAY); | |
796 | ||
797 | c_var_name=RSTRING_PTR(var_name); | |
798 | c_ndims=RARRAY_LEN(dimensions); | |
799 | ||
800 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
801 | ncid=Netcdffile->ncid; | |
802 | ||
803 | if (TYPE(vartype) == T_STRING){ | |
804 | xtype = natype2nctype(RSTRING_PTR(vartype)); | |
805 | } else if (TYPE(vartype) == T_FIXNUM){ | |
806 | xtype = natypecode2nctype(NUM2INT(vartype)); | |
807 | } else { | |
808 | rb_raise(rb_eNetcdfError, | |
809 | "type specfication must be by a string or nil"); | |
810 | } | |
811 | ||
812 | for(i=0;i<c_ndims;i++){ | |
813 | switch(TYPE(RARRAY_PTR(dimensions)[c_ndims-1-i])){ | |
814 | case T_STRING: | |
815 | Check_Type(RARRAY_PTR(dimensions)[c_ndims-1-i],T_STRING); | |
816 | c_dim_name=StringValueCStr(RARRAY_PTR(dimensions)[c_ndims-1-i]); | |
817 | status=nc_inq_dimid(ncid,c_dim_name,&dimidp); | |
818 | if(status != NC_NOERR) NC_RAISE(status); | |
819 | c_dimids[i]=dimidp; | |
820 | break; | |
821 | case T_DATA: | |
822 | Data_Get_Struct(RARRAY_PTR(dimensions)[c_ndims-1-i],struct NetCDFDim,Netcdf_dim); | |
823 | c_dimids[i]=Netcdf_dim->dimid; | |
824 | break; | |
825 | default: | |
826 | rb_raise(rb_eNetcdfError, "No such object of the netCDF dimension class."); | |
827 | } | |
828 | } | |
829 | ||
830 | status = nc_def_var(ncid,c_var_name,xtype,c_ndims,c_dimids,&varidp); | |
831 | if(status != NC_NOERR) NC_RAISE(status); | |
832 | ||
833 | Netcdf_var = NetCDF_var_init(ncid,varidp,file); | |
834 | ||
835 | Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var); | |
836 | return Var; | |
837 | } | |
838 | ||
839 | VALUE | |
840 | NetCDF_dim(VALUE file,VALUE dim_name) | |
841 | { | |
842 | int ncid; | |
843 | char *c_dim_name; | |
844 | int dimidp; | |
845 | int status; | |
846 | struct Netcdf *Netcdffile; | |
847 | struct NetCDFDim *Netcdf_dim; | |
848 | VALUE Dimension; | |
849 | ||
850 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
851 | ncid=Netcdffile->ncid; | |
852 | Check_Type(dim_name,T_STRING); | |
853 | c_dim_name=RSTRING_PTR(dim_name); | |
854 | ||
855 | status = nc_inq_dimid(ncid,c_dim_name,&dimidp); | |
856 | if(status !=NC_NOERR){ | |
857 | if(status == NC_EBADDIM){ | |
858 | return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/ | |
859 | } else{ | |
860 | NC_RAISE(status); | |
861 | } | |
862 | } | |
863 | ||
864 | Netcdf_dim=NetCDF_dim_init(ncid,dimidp); | |
865 | ||
866 | Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
867 | return Dimension; | |
868 | } | |
869 | ||
870 | VALUE | |
871 | NetCDF_var(VALUE file,VALUE var_name) | |
872 | { | |
873 | int ncid; | |
874 | int status; | |
875 | int varidp; | |
876 | char *c_var_name; | |
877 | struct Netcdf *Netcdffile; | |
878 | struct NetCDFVar *Netcdf_var; | |
879 | VALUE Variable; | |
880 | ||
881 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
882 | ncid=Netcdffile->ncid; | |
883 | Check_Type(var_name,T_STRING); | |
884 | c_var_name=RSTRING_PTR(var_name); | |
885 | ||
886 | status=nc_inq_varid(ncid,c_var_name,&varidp); | |
887 | if(status != NC_NOERR){ | |
888 | if(status == NC_ENOTVAR){ | |
889 | return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/ | |
890 | } else{ | |
891 | NC_RAISE(status); | |
892 | } | |
893 | } | |
894 | ||
895 | Netcdf_var = NetCDF_var_init(ncid,varidp,file); | |
896 | Variable = Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var); | |
897 | return Variable; | |
898 | } | |
899 | ||
900 | VALUE | |
901 | NetCDF_att(VALUE file,VALUE att_name) | |
902 | { | |
903 | int ncid; | |
904 | int status; | |
905 | int attnump; | |
906 | char *c_att_name; | |
907 | struct Netcdf *Netcdffile; | |
908 | struct NetCDFAtt *Netcdf_att; | |
909 | VALUE Attribute; | |
910 | ||
911 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
912 | ncid=Netcdffile->ncid; | |
913 | Check_Type(att_name,T_STRING); | |
914 | c_att_name=RSTRING_PTR(att_name); | |
915 | ||
916 | ||
917 | status = nc_inq_attid(ncid,NC_GLOBAL,c_att_name,&attnump); | |
918 | if(status != NC_NOERR){ | |
919 | if(status == NC_ENOTATT){ | |
920 | return(Qnil); | |
921 | } | |
922 | else{ | |
923 | NC_RAISE(status); | |
924 | } | |
925 | } | |
926 | ||
927 | Netcdf_att = NetCDF_att_init(ncid,NC_GLOBAL,c_att_name); | |
928 | ||
929 | Attribute = Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
930 | ||
931 | return Attribute; | |
932 | } | |
933 | VALUE | |
934 | NetCDF_fill(VALUE file,VALUE mode) | |
935 | { | |
936 | int ncid; | |
937 | int status; | |
938 | struct Netcdf *Netcdffile; | |
939 | int old_modep; | |
940 | ||
941 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
942 | ncid = Netcdffile->ncid; | |
943 | if(mode==Qfalse){ | |
944 | status = nc_set_fill(ncid,NC_NOFILL,&old_modep); | |
945 | if(status != NC_NOERR) NC_RAISE(status); | |
946 | } | |
947 | else if(mode == Qtrue){ | |
948 | status = nc_set_fill(ncid,NC_FILL,&old_modep); | |
949 | if(status != NC_NOERR) NC_RAISE(status); | |
950 | } | |
951 | else | |
952 | rb_raise(rb_eNetcdfError,"Usage:self.fill(true) or self.fill(false)"); | |
953 | return Qnil; | |
954 | } | |
955 | ||
956 | VALUE | |
957 | NetCDF_redef(VALUE file) | |
958 | { | |
959 | int ncid; | |
960 | int status; | |
961 | struct Netcdf *Netcdffile; | |
962 | ||
963 | rb_secure(3); | |
964 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
965 | ncid=Netcdffile->ncid; | |
966 | status = nc_redef(ncid); | |
967 | if(status !=NC_NOERR){ | |
968 | if(status == NC_EINDEFINE){ | |
969 | return Qnil; | |
970 | } | |
971 | else{ | |
972 | NC_RAISE(status); | |
973 | } | |
974 | } | |
975 | return Qtrue; | |
976 | } | |
977 | ||
978 | VALUE | |
979 | NetCDF_enddef(VALUE file) | |
980 | { | |
981 | int ncid; | |
982 | int status; | |
983 | struct Netcdf *Netcdffile; | |
984 | ||
985 | rb_secure(3); | |
986 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
987 | ncid=Netcdffile->ncid; | |
988 | status = nc_enddef(ncid); | |
989 | if(status !=NC_NOERR){ | |
990 | if(status == NC_ENOTINDEFINE){ | |
991 | return Qnil; | |
992 | } | |
993 | else{ | |
994 | NC_RAISE(status); | |
995 | } | |
996 | } | |
997 | return Qtrue; | |
998 | } | |
999 | ||
1000 | VALUE | |
1001 | NetCDF_whether_in_define_mode(VALUE file) | |
1002 | { | |
1003 | /* returns true if the NetCDF object is currently in the define mode, | |
1004 | false if in the data mode, and | |
1005 | nil if else (possibly the file is read-only, or some other | |
1006 | error occurred) | |
1007 | */ | |
1008 | int ncid; | |
1009 | int status; | |
1010 | struct Netcdf *Netcdffile; | |
1011 | ||
1012 | rb_secure(3); | |
1013 | Data_Get_Struct(file,struct Netcdf,Netcdffile); | |
1014 | ncid=Netcdffile->ncid; | |
1015 | status = nc_redef(ncid); | |
1016 | if(status == NC_EINDEFINE){ | |
1017 | return Qtrue; | |
1018 | } else if(status == NC_NOERR) { | |
1019 | /* was in the data mode --> recover the data mode and report false */ | |
1020 | status = nc_enddef(ncid); | |
1021 | if(status == NC_NOERR) { | |
1022 | return Qfalse; | |
1023 | } else { | |
1024 | return Qnil; | |
1025 | } | |
1026 | } else { | |
1027 | return Qnil; | |
1028 | } | |
1029 | } | |
1030 | ||
1031 | VALUE | |
1032 | NetCDF_open(VALUE mod,VALUE filename,VALUE omode) | |
1033 | { | |
1034 | int status; | |
1035 | int ncid; | |
1036 | char* c_filename; | |
1037 | int c_omode; | |
1038 | struct Netcdf *ncfile; | |
1039 | VALUE retval; | |
1040 | ||
1041 | Check_Type(filename,T_STRING); | |
1042 | SafeStringValue(filename); | |
1043 | c_filename=RSTRING_PTR(filename); | |
1044 | Check_Type(omode,T_FIXNUM); | |
1045 | c_omode=NUM2INT(omode); | |
1046 | ||
1047 | status = nc_open(c_filename,c_omode,&ncid); | |
1048 | if(status !=NC_NOERR){NC_RAISE2(status,c_filename);} | |
1049 | ||
1050 | ncfile = NetCDF_init(ncid,c_filename); | |
1051 | retval = Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile); | |
1052 | return( retval ); | |
1053 | } | |
1054 | ||
1055 | VALUE | |
1056 | NetCDF_create(VALUE mod,VALUE filename,VALUE cmode) | |
1057 | { | |
1058 | int ncid; | |
1059 | int status; | |
1060 | char* c_filename; | |
1061 | int c_cmode; | |
1062 | struct Netcdf *ncfile; | |
1063 | ||
1064 | Check_Type(filename,T_STRING); | |
1065 | SafeStringValue(filename); | |
1066 | c_filename=RSTRING_PTR(filename); | |
1067 | Check_Type(cmode,T_FIXNUM); | |
1068 | c_cmode=NUM2INT(cmode); | |
1069 | ||
1070 | status = nc_create(c_filename,c_cmode,&ncid); | |
1071 | if(status != NC_NOERR) NC_RAISE2(status, c_filename); | |
1072 | ||
1073 | ncfile = NetCDF_init(ncid,c_filename); | |
1074 | return( Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile) ); | |
1075 | } | |
1076 | ||
1077 | VALUE | |
1078 | NetCDF_ndims(VALUE file) | |
1079 | { | |
1080 | int ncid; | |
1081 | int ndimsp; | |
1082 | VALUE Integer; | |
1083 | int status; | |
1084 | struct Netcdf *ncfile; | |
1085 | ||
1086 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1087 | ncid=ncfile->ncid; | |
1088 | status = nc_inq_ndims(ncid,&ndimsp); | |
1089 | if(status != NC_NOERR) NC_RAISE (status); | |
1090 | Integer = INT2NUM(ndimsp); | |
1091 | return Integer; | |
1092 | } | |
1093 | ||
1094 | VALUE | |
1095 | NetCDF_nvars(VALUE file) | |
1096 | { | |
1097 | int ncid; | |
1098 | int nvarsp; | |
1099 | int status; | |
1100 | VALUE Integer; | |
1101 | struct Netcdf *ncfile; | |
1102 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1103 | ncid=ncfile->ncid; | |
1104 | status = nc_inq_nvars(ncid,&nvarsp); | |
1105 | if(status != NC_NOERR) NC_RAISE (status); | |
1106 | Integer = INT2NUM(nvarsp); | |
1107 | return Integer; | |
1108 | } | |
1109 | ||
1110 | VALUE | |
1111 | NetCDF_natts(VALUE file) | |
1112 | { | |
1113 | int ncid; | |
1114 | int nattsp; | |
1115 | int status; | |
1116 | VALUE Integer; | |
1117 | struct Netcdf *ncfile; | |
1118 | ||
1119 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1120 | ncid=ncfile->ncid; | |
1121 | status=nc_inq_natts(ncid,&nattsp); | |
1122 | if(status != NC_NOERR) NC_RAISE (status); | |
1123 | Integer = INT2NUM(nattsp); | |
1124 | return Integer; | |
1125 | } | |
1126 | ||
1127 | VALUE | |
1128 | NetCDF_unlimited(VALUE file) | |
1129 | { | |
1130 | int ncid; | |
1131 | int unlimdimidp; | |
1132 | int status; | |
1133 | struct Netcdf *ncfile; | |
1134 | struct NetCDFDim *Netcdf_dim; | |
1135 | VALUE Dimension; | |
1136 | ||
1137 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1138 | ncid=ncfile->ncid; | |
1139 | status=nc_inq_unlimdim(ncid,&unlimdimidp); | |
1140 | if(status !=NC_NOERR) NC_RAISE(status); | |
1141 | ||
1142 | Netcdf_dim = NetCDF_dim_init(ncid,unlimdimidp); | |
1143 | ||
1144 | /* If unlimdimidp=-1,No unlimited dimension is defined in the netCDF dataset */ | |
1145 | if(unlimdimidp != -1) | |
1146 | { | |
1147 | Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
1148 | return Dimension; | |
1149 | } | |
1150 | else | |
1151 | { | |
1152 | return Qnil; | |
1153 | } | |
1154 | } | |
1155 | ||
1156 | VALUE | |
1157 | NetCDF_sync(VALUE file) | |
1158 | { | |
1159 | int ncid; | |
1160 | int status; | |
1161 | struct Netcdf *ncfile; | |
1162 | ||
1163 | rb_secure(3); | |
1164 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1165 | ncid=ncfile->ncid; | |
1166 | status = nc_sync(ncid); | |
1167 | if(status !=NC_NOERR) NC_RAISE (status); | |
1168 | return Qnil; | |
1169 | } | |
1170 | ||
1171 | VALUE | |
1172 | NetCDF_path(VALUE file) | |
1173 | { | |
1174 | char *path; | |
1175 | struct Netcdf *ncfile; | |
1176 | ||
1177 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1178 | path=ncfile->name; | |
1179 | return(rb_str_new2(path)); | |
1180 | } | |
1181 | ||
1182 | VALUE | |
1183 | NetCDF_dim_length(VALUE Dim) | |
1184 | { | |
1185 | int ncid; | |
1186 | int status; | |
1187 | int dimid; | |
1188 | size_t lengthp; | |
1189 | struct NetCDFDim *Netcdf_dim; | |
1190 | ||
1191 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1192 | ncid=Netcdf_dim->ncid; | |
1193 | dimid=Netcdf_dim->dimid; | |
1194 | ||
1195 | status = nc_inq_dimlen(ncid,dimid,&lengthp); | |
1196 | if(status != NC_NOERR) NC_RAISE(status); | |
1197 | ||
1198 | return(INT2NUM(lengthp)); | |
1199 | } | |
1200 | ||
1201 | VALUE | |
1202 | NetCDF_dim_name(VALUE Dim,VALUE dimension_newname) | |
1203 | { | |
1204 | int ncid; | |
1205 | int status; | |
1206 | int dimid; | |
1207 | char *c_dim_name; | |
1208 | struct NetCDFDim *Netcdf_dim; | |
1209 | ||
1210 | rb_secure(3); | |
1211 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1212 | ncid=Netcdf_dim->ncid; | |
1213 | dimid=Netcdf_dim->dimid; | |
1214 | Check_Type(dimension_newname,T_STRING); | |
1215 | c_dim_name = StringValueCStr(dimension_newname); | |
1216 | ||
1217 | status = nc_rename_dim(ncid,dimid,c_dim_name); | |
1218 | if(status !=NC_NOERR) NC_RAISE(status); | |
1219 | ||
1220 | return Qnil; | |
1221 | } | |
1222 | ||
1223 | VALUE | |
1224 | NetCDF_dim_inqname(VALUE Dim) | |
1225 | { | |
1226 | int ncid; | |
1227 | int status; | |
1228 | int dimid; | |
1229 | char c_dim_name[NC_MAX_NAME]; | |
1230 | struct NetCDFDim *Netcdf_dim; | |
1231 | VALUE str; | |
1232 | ||
1233 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1234 | ncid=Netcdf_dim->ncid; | |
1235 | dimid=Netcdf_dim->dimid; | |
1236 | ||
1237 | status = nc_inq_dimname(ncid,dimid,c_dim_name); | |
1238 | if(status !=NC_NOERR) NC_RAISE(status); | |
1239 | ||
1240 | str = rb_str_new2(c_dim_name); | |
1241 | OBJ_TAINT(str); | |
1242 | return(str); | |
1243 | } | |
1244 | ||
1245 | VALUE | |
1246 | NetCDF_dim_whether_unlimited(VALUE Dim) | |
1247 | { | |
1248 | int status; | |
1249 | int uldid; | |
1250 | struct NetCDFDim *Netcdf_dim; | |
1251 | ||
1252 | Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim); | |
1253 | status=nc_inq_unlimdim(Netcdf_dim->ncid,&uldid); | |
1254 | if(status !=NC_NOERR) NC_RAISE(status); | |
1255 | if(Netcdf_dim->dimid == uldid){ | |
1256 | return(Qtrue); | |
1257 | } else { | |
1258 | return(Qfalse); | |
1259 | } | |
1260 | } | |
1261 | ||
1262 | VALUE | |
1263 | NetCDF_att_inq_name(VALUE Att) | |
1264 | { | |
1265 | char *c_att_name; | |
1266 | struct NetCDFAtt *Netcdf_att; | |
1267 | VALUE str; | |
1268 | ||
1269 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1270 | c_att_name=Netcdf_att->name; | |
1271 | ||
1272 | str = rb_str_new2(c_att_name); | |
1273 | OBJ_TAINT(str); | |
1274 | return(str); | |
1275 | } | |
1276 | ||
1277 | VALUE | |
1278 | NetCDF_att_rename(VALUE Att,VALUE new_att_name) | |
1279 | { | |
1280 | int ncid; | |
1281 | int status; | |
1282 | int varid; | |
1283 | char *c_att_name; | |
1284 | char *c_new_att_name; | |
1285 | struct NetCDFAtt *Netcdf_att; | |
1286 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1287 | ncid=Netcdf_att->ncid; | |
1288 | varid=Netcdf_att->varid; | |
1289 | ||
1290 | c_att_name=Netcdf_att->name; | |
1291 | ||
1292 | Check_Type(new_att_name,T_STRING); | |
1293 | SafeStringValue(new_att_name); | |
1294 | c_new_att_name=StringValueCStr(new_att_name); | |
1295 | ||
1296 | status = nc_rename_att(ncid,varid,c_att_name,c_new_att_name); | |
1297 | if(status != NC_NOERR) NC_RAISE(status); | |
1298 | ||
1299 | strcpy(Netcdf_att->name,c_new_att_name); | |
1300 | return Qnil; | |
1301 | } | |
1302 | ||
1303 | VALUE | |
1304 | NetCDF_id2dim(VALUE file,VALUE dimid) | |
1305 | { | |
1306 | int ncid; | |
1307 | int c_dimid; | |
1308 | struct Netcdf *ncfile; | |
1309 | struct NetCDFDim *Netcdf_dim; | |
1310 | VALUE Dim; | |
1311 | ||
1312 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1313 | ncid=ncfile->ncid; | |
1314 | Check_Type(dimid,T_FIXNUM); | |
1315 | c_dimid=NUM2INT(dimid); | |
1316 | Netcdf_dim = NetCDF_dim_init(ncid,c_dimid); | |
1317 | Dim=Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
1318 | return(Dim); | |
1319 | } | |
1320 | ||
1321 | VALUE | |
1322 | NetCDF_id2var(VALUE file,VALUE varid) | |
1323 | { | |
1324 | int ncid; | |
1325 | int c_varid; | |
1326 | struct Netcdf *ncfile; | |
1327 | struct NetCDFVar *Netcdf_var; | |
1328 | VALUE Var; | |
1329 | ||
1330 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1331 | ncid=ncfile->ncid; | |
1332 | Check_Type(varid,T_FIXNUM); | |
1333 | c_varid=NUM2INT(varid); | |
1334 | Netcdf_var = NetCDF_var_init(ncid,c_varid,file); | |
1335 | Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var); | |
1336 | return(Var); | |
1337 | } | |
1338 | ||
1339 | ||
1340 | VALUE | |
1341 | NetCDF_id2att(VALUE file,VALUE attnum) | |
1342 | { | |
1343 | int ncid; | |
1344 | int c_attnum; | |
1345 | int status; | |
1346 | struct Netcdf *ncfile; | |
1347 | struct NetCDFAtt *Netcdf_att; | |
1348 | char *c_att_name; | |
1349 | VALUE Att; | |
1350 | c_att_name=ALLOCA_N(char,NC_MAX_NAME); | |
1351 | ||
1352 | Data_Get_Struct(file,struct Netcdf,ncfile); | |
1353 | ncid=ncfile->ncid; | |
1354 | ||
1355 | Check_Type(attnum,T_FIXNUM); | |
1356 | c_attnum=NUM2INT(attnum); | |
1357 | ||
1358 | status = nc_inq_attname(ncid,NC_GLOBAL,c_attnum,c_att_name); | |
1359 | if(status != NC_NOERR) NC_RAISE(status); | |
1360 | ||
1361 | Netcdf_att=NetCDF_att_init(ncid,NC_GLOBAL,c_att_name); | |
1362 | ||
1363 | Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
1364 | return(Att); | |
1365 | ||
1366 | } | |
1367 | ||
1368 | #if NCVER >= 400 | |
1369 | /* USAGE | |
1370 | NetCDFVar#deflate(deflate_level, shuffle=false) | |
1371 | */ | |
1372 | VALUE | |
1373 | NetCDF_var_deflate(int argc, VALUE *argv, VALUE Var) | |
1374 | { | |
1375 | int ncid, varid, status; | |
1376 | struct NetCDFVar *Netcdf_var; | |
1377 | ||
1378 | int shuffle; | |
1379 | /* If non-zero, turn on the shuffle filter. | |
1380 | ||
1381 | http://www.unidata.ucar.edu/software/netcdf/papers/AMS_2008.pdf : | |
1382 | The shuffle algorithm changes the byte order in the data stream; | |
1383 | when used with integers that are all close together, this | |
1384 | results in a better compression ratio. There is no benefit | |
1385 | from using the shuffle filter without also using | |
1386 | compression. | |
1387 | ||
1388 | MEMO by horinouchi: shuffling filter was also effective for float | |
1389 | variables in some test (demo5-netcdf4.rb). | |
1390 | */ | |
1391 | int deflate_level; | |
1392 | int deflate=1; | |
1393 | /* Always set to non-zero: | |
1394 | See https://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar_005fdeflate.html#nc_005fdef_005fvar_005fdeflate | |
1395 | If non-zero, turn on the deflate filter at the | |
1396 | level specified by the deflate_level parameter. | |
1397 | */ | |
1398 | ||
1399 | if (argc>2 || argc<1) rb_raise(rb_eArgError, | |
1400 | "wrong # of arguments (%d). It must be 1 or 2", argc); | |
1401 | ||
1402 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1403 | ncid = Netcdf_var->ncid; | |
1404 | varid = Netcdf_var->varid; | |
1405 | ||
1406 | deflate_level = NUM2INT(argv[0]); | |
1407 | ||
1408 | if (argc==1) { | |
1409 | shuffle = 0; /* default: false */ | |
1410 | } else { | |
1411 | if ( argv[1] == Qnil || argv[1] == Qfalse ) { | |
1412 | shuffle = 0; | |
1413 | } else { | |
1414 | shuffle = 1; | |
1415 | } | |
1416 | } | |
1417 | ||
1418 | status = nc_def_var_deflate(ncid, varid, shuffle, deflate, deflate_level); | |
1419 | if(status != NC_NOERR) NC_RAISE(status); | |
1420 | ||
1421 | return(Var); | |
1422 | } | |
1423 | ||
1424 | VALUE | |
1425 | NetCDF_var_deflate_params(VALUE Var) | |
1426 | { | |
1427 | int ncid, varid, status; | |
1428 | struct NetCDFVar *Netcdf_var; | |
1429 | int shufflep, deflatep, deflate_levelp; | |
1430 | VALUE sh, df, params; | |
1431 | ||
1432 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1433 | ncid = Netcdf_var->ncid; | |
1434 | varid = Netcdf_var->varid; | |
1435 | status = nc_inq_var_deflate(ncid, varid, &shufflep, &deflatep, | |
1436 | &deflate_levelp); | |
1437 | if(status != NC_NOERR) NC_RAISE(status); | |
1438 | if (shufflep==0) {sh=Qfalse;} else {sh=Qtrue;} | |
1439 | if (deflatep==0) {df=Qfalse;} else {df=Qtrue;} | |
1440 | params = rb_ary_new3(3, sh, df, INT2NUM(deflate_levelp) ); | |
1441 | return(params); | |
1442 | } | |
1443 | ||
1444 | VALUE | |
1445 | NetCDF_var_set_endian(VALUE Var, VALUE endian) | |
1446 | { | |
1447 | int ncid, varid, status; | |
1448 | struct NetCDFVar *Netcdf_var; | |
1449 | ||
1450 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1451 | ncid = Netcdf_var->ncid; | |
1452 | varid = Netcdf_var->varid; | |
1453 | status = nc_def_var_endian(ncid, varid, NUM2INT(endian)); | |
1454 | if(status != NC_NOERR) NC_RAISE(status); | |
1455 | return(Var); | |
1456 | } | |
1457 | ||
1458 | VALUE | |
1459 | NetCDF_var_endian(VALUE Var) | |
1460 | { | |
1461 | int ncid, varid, status; | |
1462 | struct NetCDFVar *Netcdf_var; | |
1463 | int endian; | |
1464 | ||
1465 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1466 | ncid = Netcdf_var->ncid; | |
1467 | varid = Netcdf_var->varid; | |
1468 | status = nc_inq_var_endian(ncid, varid, &endian); | |
1469 | if(status != NC_NOERR) NC_RAISE(status); | |
1470 | return(INT2FIX(endian)); | |
1471 | } | |
1472 | ||
1473 | #endif | |
1474 | ||
1475 | VALUE | |
1476 | NetCDF_var_id2att(VALUE Var,VALUE attnum) | |
1477 | { | |
1478 | int ncid; | |
1479 | int c_attnum; | |
1480 | int status; | |
1481 | int c_varid; | |
1482 | struct NetCDFVar *Netcdf_var; | |
1483 | struct NetCDFAtt *Netcdf_att; | |
1484 | char *c_att_name; | |
1485 | VALUE Att; | |
1486 | ||
1487 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1488 | ncid=Netcdf_var->ncid; | |
1489 | c_varid=Netcdf_var->varid; | |
1490 | ||
1491 | Check_Type(attnum,T_FIXNUM); | |
1492 | c_attnum=NUM2INT(attnum); | |
1493 | ||
1494 | c_att_name=ALLOCA_N(char,NC_MAX_NAME); | |
1495 | ||
1496 | status = nc_inq_attname(ncid,c_varid,c_attnum,c_att_name); | |
1497 | if(status != NC_NOERR) NC_RAISE(status); | |
1498 | ||
1499 | Netcdf_att=NetCDF_att_init(ncid,c_varid,c_att_name); | |
1500 | Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
1501 | return(Att); | |
1502 | } | |
1503 | ||
1504 | VALUE | |
1505 | NetCDF_var_dims(VALUE Var) | |
1506 | { | |
1507 | int ncid, *dimids, ndims, varid, i, status; | |
1508 | struct NetCDFVar *Netcdf_var; | |
1509 | struct NetCDFDim *Netcdf_dim; | |
1510 | VALUE Dims; | |
1511 | ||
1512 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1513 | ncid = Netcdf_var->ncid; | |
1514 | varid = Netcdf_var->varid; | |
1515 | status = nc_inq_varndims(ncid,varid,&ndims); | |
1516 | if(status != NC_NOERR) NC_RAISE(status); | |
1517 | dimids=ALLOCA_N(int,ndims); | |
1518 | status = nc_inq_vardimid(ncid,varid,dimids); | |
1519 | if(status != NC_NOERR) NC_RAISE(status); | |
1520 | Dims = rb_ary_new(); | |
1521 | for(i=0;i<ndims;i++){ | |
1522 | Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-i]); | |
1523 | rb_ary_push(Dims, | |
1524 | Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim)); | |
1525 | } | |
1526 | return(Dims); | |
1527 | } | |
1528 | ||
1529 | VALUE | |
1530 | NetCDF_var_dim(VALUE Var, VALUE ith) | |
1531 | { | |
1532 | int ncid, *dimids, ndims, varid, status, c_ith; | |
1533 | struct NetCDFVar *Netcdf_var; | |
1534 | struct NetCDFDim *Netcdf_dim; | |
1535 | VALUE Dim; | |
1536 | ||
1537 | Check_Type(ith,T_FIXNUM); | |
1538 | c_ith=NUM2INT(ith); | |
1539 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1540 | ncid = Netcdf_var->ncid; | |
1541 | varid = Netcdf_var->varid; | |
1542 | status = nc_inq_varndims(ncid,varid,&ndims); | |
1543 | if(status != NC_NOERR) NC_RAISE(status); | |
1544 | if(c_ith < 0 || c_ith >= ndims) { | |
1545 | rb_raise(rb_eNetcdfError, "dimension count less than zero or greater than ndims-1"); | |
1546 | } | |
1547 | dimids=ALLOCA_N(int,ndims); | |
1548 | status = nc_inq_vardimid(ncid,varid,dimids); | |
1549 | if(status != NC_NOERR) NC_RAISE(status); | |
1550 | Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-c_ith]); | |
1551 | Dim = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim); | |
1552 | return(Dim); | |
1553 | } | |
1554 | ||
1555 | VALUE | |
1556 | NetCDF_att_copy(VALUE Att,VALUE Var_or_File) | |
1557 | { | |
1558 | int ncid_in,ncid_out; | |
1559 | int status; | |
1560 | int varid_in,varid_out; | |
1561 | char *att_name; | |
1562 | struct NetCDFAtt *Netcdf_att; | |
1563 | struct NetCDFVar *Netcdf_var; | |
1564 | struct Netcdf *ncfile; | |
1565 | struct NetCDFAtt *Netcdf_att_out; | |
1566 | ||
1567 | rb_secure(3); | |
1568 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1569 | ncid_in=Netcdf_att->ncid; | |
1570 | varid_in=Netcdf_att->varid; | |
1571 | att_name=Netcdf_att->name; | |
1572 | ||
1573 | if( rb_obj_is_kind_of(Var_or_File, cNetCDFVar) ){ | |
1574 | Data_Get_Struct(Var_or_File,struct NetCDFVar, Netcdf_var); | |
1575 | ncid_out=Netcdf_var->ncid; | |
1576 | varid_out=Netcdf_var->varid; | |
1577 | } else if ( rb_obj_is_kind_of(Var_or_File, cNetCDF) ){ | |
1578 | Data_Get_Struct(Var_or_File,struct Netcdf, ncfile); | |
1579 | ncid_out=ncfile->ncid; | |
1580 | varid_out=NC_GLOBAL; | |
1581 | } else { | |
1582 | rb_raise(rb_eNetcdfError,"The argument must be a NetCDFVar or a NetCDF"); | |
1583 | } | |
1584 | ||
1585 | status = nc_copy_att(ncid_in,varid_in,att_name,ncid_out,varid_out); | |
1586 | if(status != NC_NOERR) NC_RAISE(status); | |
1587 | Netcdf_att_out = NetCDF_att_init(ncid_out,varid_out,att_name); | |
1588 | return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att_out)); | |
1589 | } | |
1590 | ||
1591 | VALUE | |
1592 | NetCDF_att_atttype(VALUE Att) | |
1593 | { | |
1594 | int ncid; | |
1595 | int varid; | |
1596 | int status; | |
1597 | char *att_name; | |
1598 | const char *Attname; | |
1599 | struct NetCDFAtt *Netcdf_att; | |
1600 | nc_type xtypep; | |
1601 | ||
1602 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1603 | ncid = Netcdf_att->ncid; | |
1604 | varid = Netcdf_att->varid; | |
1605 | att_name = Netcdf_att->name; | |
1606 | ||
1607 | status = nc_inq_atttype(ncid,varid,att_name,&xtypep); | |
1608 | if(status != NC_NOERR) NC_RAISE(status); | |
1609 | ||
1610 | Attname = nctype2natype(xtypep); | |
1611 | return(rb_str_new2(Attname)); | |
1612 | } | |
1613 | ||
1614 | VALUE | |
1615 | NetCDF_att_typecode(VALUE Att) | |
1616 | { | |
1617 | int ncid; | |
1618 | int varid; | |
1619 | int status; | |
1620 | char *att_name; | |
1621 | struct NetCDFAtt *Netcdf_att; | |
1622 | nc_type xtypep; | |
1623 | ||
1624 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1625 | ncid = Netcdf_att->ncid; | |
1626 | varid = Netcdf_att->varid; | |
1627 | att_name = Netcdf_att->name; | |
1628 | ||
1629 | status = nc_inq_atttype(ncid,varid,att_name,&xtypep); | |
1630 | if(status != NC_NOERR) NC_RAISE(status); | |
1631 | ||
1632 | return(INT2NUM(nctype2natypecode(xtypep))); | |
1633 | } | |
1634 | ||
1635 | VALUE | |
1636 | NetCDF_att_delete(VALUE Att) | |
1637 | { | |
1638 | int ncid; | |
1639 | int status; | |
1640 | int varid; | |
1641 | char *c_att_name; | |
1642 | struct NetCDFAtt *Netcdf_att; | |
1643 | ||
1644 | rb_secure(3); | |
1645 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1646 | ||
1647 | ncid=Netcdf_att->ncid; | |
1648 | varid=Netcdf_att->varid; | |
1649 | c_att_name=Netcdf_att->name; | |
1650 | ||
1651 | status = nc_del_att(ncid,varid,c_att_name); | |
1652 | if(status != NC_NOERR) NC_RAISE(status); | |
1653 | ||
1654 | return Qnil; | |
1655 | } | |
1656 | ||
1657 | VALUE | |
1658 | NetCDF_att_put(VALUE Att,VALUE value,VALUE atttype) | |
1659 | /* | |
1660 | * atttype: nil or a String ("string","int",etc). If nil, | |
1661 | * the type of attribute is determined from the type of value | |
1662 | */ | |
1663 | { | |
1664 | struct NetCDFAtt *ncatt; | |
1665 | ||
1666 | rb_secure(3); | |
1667 | Data_Get_Struct(Att,struct NetCDFAtt,ncatt); | |
1668 | return( NetCDF_put_att__(ncatt->ncid, ncatt->name, value, | |
1669 | atttype, ncatt->varid) ); | |
1670 | } | |
1671 | ||
1672 | VALUE | |
1673 | NetCDF_att_get(VALUE Att) | |
1674 | { | |
1675 | int ncid; | |
1676 | int varid; | |
1677 | char *c_attname; | |
1678 | int status; | |
1679 | struct NetCDFAtt *Netcdf_att; | |
1680 | nc_type xtypep; | |
1681 | size_t lenp; | |
1682 | na_shape_t attlen[1]; /* NArray uses int instead of size_t */ | |
1683 | char *tp; | |
1684 | unsigned char *up; | |
1685 | short *sp; | |
1686 | int *ip; | |
1687 | float *fp; | |
1688 | double *dp; | |
1689 | VALUE NArray; | |
1690 | VALUE str; | |
1691 | ||
1692 | Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att); | |
1693 | ncid = Netcdf_att->ncid; | |
1694 | varid = Netcdf_att->varid; | |
1695 | c_attname = Netcdf_att->name; | |
1696 | ||
1697 | status = nc_inq_atttype(ncid,varid,c_attname,&xtypep); | |
1698 | if(status != NC_NOERR) NC_RAISE(status); | |
1699 | ||
1700 | switch(xtypep){ | |
1701 | case NC_CHAR: | |
1702 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1703 | if(status != NC_NOERR) NC_RAISE(status); | |
1704 | tp = ALLOCA_N(char,lenp+1); | |
1705 | tp[lenp]= '\0'; | |
1706 | status = nc_get_att_text(ncid,varid,c_attname,tp); | |
1707 | if(status != NC_NOERR) NC_RAISE(status); | |
1708 | str = rb_str_new2(tp); | |
1709 | OBJ_TAINT(str); | |
1710 | return(str); | |
1711 | break; | |
1712 | case NC_BYTE: | |
1713 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1714 | if(status != NC_NOERR) NC_RAISE(status); | |
1715 | ||
1716 | attlen[0]=lenp; | |
1717 | Cbyte_to_NArray(NArray,1,attlen,up); | |
1718 | ||
1719 | status = nc_get_att_uchar(ncid,varid,c_attname,up); | |
1720 | if(status != NC_NOERR) NC_RAISE(status); | |
1721 | ||
1722 | OBJ_TAINT(NArray); | |
1723 | return NArray; | |
1724 | break; | |
1725 | case NC_SHORT: | |
1726 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1727 | if(status != NC_NOERR) NC_RAISE(status); | |
1728 | ||
1729 | attlen[0]=lenp; | |
1730 | Csint_to_NArray(NArray,1,attlen,sp); | |
1731 | ||
1732 | status = nc_get_att_short(ncid,varid,c_attname,sp); | |
1733 | if(status != NC_NOERR) NC_RAISE(status); | |
1734 | OBJ_TAINT(NArray); | |
1735 | return NArray; | |
1736 | break; | |
1737 | case NC_INT: | |
1738 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1739 | if(status != NC_NOERR) NC_RAISE(status); | |
1740 | ||
1741 | attlen[0]=lenp; | |
1742 | Clint_to_NArray(NArray,1,attlen,ip); | |
1743 | ||
1744 | status = nc_get_att_int(ncid,varid,c_attname,ip); | |
1745 | if(status != NC_NOERR) NC_RAISE(status); | |
1746 | ||
1747 | OBJ_TAINT(NArray); | |
1748 | return NArray; | |
1749 | break; | |
1750 | case NC_FLOAT: | |
1751 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1752 | if(status != NC_NOERR) NC_RAISE(status); | |
1753 | ||
1754 | attlen[0]=lenp; | |
1755 | Cfloat_to_NArray(NArray,1,attlen,fp); | |
1756 | ||
1757 | status = nc_get_att_float(ncid,varid,c_attname,fp); | |
1758 | if(status != NC_NOERR) NC_RAISE(status); | |
1759 | ||
1760 | OBJ_TAINT(NArray); | |
1761 | return NArray; | |
1762 | break; | |
1763 | case NC_DOUBLE: | |
1764 | status = nc_inq_attlen(ncid,varid,c_attname,&lenp); | |
1765 | if(status != NC_NOERR) NC_RAISE(status); | |
1766 | ||
1767 | attlen[0]=lenp; | |
1768 | Cdouble_to_NArray(NArray,1,attlen,dp); | |
1769 | ||
1770 | status = nc_get_att_double(ncid,varid,c_attname,dp); | |
1771 | if(status != NC_NOERR) NC_RAISE(status); | |
1772 | OBJ_TAINT(NArray); | |
1773 | return NArray; | |
1774 | break; | |
1775 | default: | |
1776 | rb_raise(rb_eNetcdfError,"atttype isn't supported in netCDF"); | |
1777 | } | |
1778 | return Qnil; | |
1779 | } | |
1780 | ||
1781 | ||
1782 | VALUE | |
1783 | NetCDF_var_inq_name(VALUE Var) | |
1784 | { | |
1785 | int ncid; | |
1786 | int status; | |
1787 | int varid; | |
1788 | char c_var_name[NC_MAX_NAME]; | |
1789 | struct NetCDFVar *Netcdf_var; | |
1790 | VALUE Var_name; | |
1791 | ||
1792 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1793 | ||
1794 | ncid=Netcdf_var->ncid; | |
1795 | varid=Netcdf_var->varid; | |
1796 | status = nc_inq_varname(ncid,varid,c_var_name); | |
1797 | if(status != NC_NOERR) NC_RAISE(status); | |
1798 | ||
1799 | Var_name=rb_str_new2(c_var_name); | |
1800 | OBJ_TAINT(Var_name); | |
1801 | return Var_name; | |
1802 | } | |
1803 | ||
1804 | VALUE | |
1805 | NetCDF_var_ndims(VALUE Var) | |
1806 | { | |
1807 | int ncid; | |
1808 | int status; | |
1809 | int varid; | |
1810 | int ndimsp; | |
1811 | struct NetCDFVar *Netcdf_var; | |
1812 | VALUE Var_ndims; | |
1813 | ||
1814 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1815 | ||
1816 | ncid=Netcdf_var->ncid; | |
1817 | varid=Netcdf_var->varid; | |
1818 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
1819 | if(status != NC_NOERR) NC_RAISE(status); | |
1820 | Var_ndims=INT2FIX(ndimsp); | |
1821 | return Var_ndims; | |
1822 | } | |
1823 | ||
1824 | VALUE | |
1825 | NetCDF_var_vartype(VALUE Var) | |
1826 | { | |
1827 | int ncid; | |
1828 | int status; | |
1829 | int varid; | |
1830 | nc_type xtypep; | |
1831 | struct NetCDFVar *Netcdf_var; | |
1832 | const char *Vartype; | |
1833 | ||
1834 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1835 | ||
1836 | ncid=Netcdf_var->ncid; | |
1837 | varid=Netcdf_var->varid; | |
1838 | ||
1839 | status = nc_inq_vartype(ncid,varid,&xtypep); | |
1840 | if(status != NC_NOERR) NC_RAISE(status); | |
1841 | ||
1842 | Vartype=nctype2natype(xtypep); | |
1843 | return(rb_str_new2(Vartype)); | |
1844 | } | |
1845 | ||
1846 | VALUE | |
1847 | NetCDF_var_typecode(VALUE Var) | |
1848 | { | |
1849 | int ncid; | |
1850 | int status; | |
1851 | int varid; | |
1852 | nc_type xtypep; | |
1853 | struct NetCDFVar *Netcdf_var; | |
1854 | ||
1855 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1856 | ||
1857 | ncid=Netcdf_var->ncid; | |
1858 | varid=Netcdf_var->varid; | |
1859 | ||
1860 | status = nc_inq_vartype(ncid,varid,&xtypep); | |
1861 | if(status != NC_NOERR) NC_RAISE(status); | |
1862 | ||
1863 | return(INT2NUM(nctype2natypecode(xtypep))); | |
1864 | } | |
1865 | ||
1866 | ||
1867 | VALUE | |
1868 | NetCDF_var_natts(VALUE Var) | |
1869 | { | |
1870 | int ncid; | |
1871 | int status; | |
1872 | int varid; | |
1873 | int nattsp; | |
1874 | struct NetCDFVar *Netcdf_var; | |
1875 | VALUE Var_natts; | |
1876 | ||
1877 | ||
1878 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1879 | ||
1880 | ncid=Netcdf_var->ncid; | |
1881 | varid=Netcdf_var->varid; | |
1882 | ||
1883 | status= nc_inq_varnatts(ncid,varid,&nattsp); | |
1884 | if(status !=NC_NOERR) NC_RAISE(status); | |
1885 | ||
1886 | Var_natts=INT2FIX(nattsp); | |
1887 | return Var_natts; | |
1888 | } | |
1889 | ||
1890 | VALUE | |
1891 | NetCDF_var_file(VALUE Var) | |
1892 | { | |
1893 | struct NetCDFVar *Netcdf_var; | |
1894 | /* VALUE file; */ | |
1895 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1896 | ||
1897 | return (Netcdf_var->file); | |
1898 | } | |
1899 | ||
1900 | VALUE | |
1901 | NetCDF_var_rename(VALUE Var,VALUE var_new_name) | |
1902 | { | |
1903 | int ncid; | |
1904 | int status; | |
1905 | int varid; | |
1906 | char *c_var_new_name; | |
1907 | struct NetCDFVar *Netcdf_var; | |
1908 | ||
1909 | rb_secure(3); | |
1910 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1911 | ncid=Netcdf_var->ncid; | |
1912 | varid=Netcdf_var->varid; | |
1913 | ||
1914 | Check_Type(var_new_name,T_STRING); | |
1915 | c_var_new_name=StringValueCStr(var_new_name); | |
1916 | ||
1917 | status = nc_rename_var(ncid,varid,c_var_new_name); | |
1918 | if(status !=NC_NOERR) NC_RAISE(status); | |
1919 | ||
1920 | return Qnil; | |
1921 | } | |
1922 | ||
1923 | VALUE | |
1924 | NetCDF_var_att(VALUE Var,VALUE att_name) | |
1925 | { | |
1926 | int ncid; | |
1927 | int status; | |
1928 | int varid; | |
1929 | char *c_att_name; | |
1930 | int c_attnump; | |
1931 | struct NetCDFVar *Netcdf_var; | |
1932 | struct NetCDFAtt *Netcdf_att; | |
1933 | VALUE Att; | |
1934 | ||
1935 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
1936 | ||
1937 | ncid=Netcdf_var->ncid; | |
1938 | varid=Netcdf_var->varid; | |
1939 | ||
1940 | Check_Type(att_name,T_STRING); | |
1941 | c_att_name=StringValueCStr(att_name); | |
1942 | ||
1943 | status = nc_inq_attid(ncid,varid,c_att_name,&c_attnump); | |
1944 | if(status == NC_NOERR){ | |
1945 | Netcdf_att=NetCDF_att_init(ncid,varid,c_att_name); | |
1946 | Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att); | |
1947 | return Att; | |
1948 | } | |
1949 | else if(status == NC_ENOTATT){ | |
1950 | return Qnil; | |
1951 | } | |
1952 | else{ | |
1953 | NC_RAISE(status); | |
1954 | return Qnil; | |
1955 | } | |
1956 | } | |
1957 | ||
1958 | /* Redifinition of the "==" and "eql?" methods */ | |
1959 | ||
1960 | VALUE | |
1961 | NetCDF_eql(VALUE filea,VALUE fileb) | |
1962 | { | |
1963 | struct Netcdf *ncfilea; | |
1964 | struct Netcdf *ncfileb; | |
1965 | ||
1966 | if( rb_obj_is_kind_of(fileb, cNetCDF) ){ | |
1967 | Data_Get_Struct(filea,struct Netcdf,ncfilea); | |
1968 | Data_Get_Struct(fileb,struct Netcdf,ncfileb); | |
1969 | ||
1970 | if(ncfilea->ncid == ncfileb->ncid && | |
1971 | strcmp(ncfilea->name,ncfileb->name)==0){ | |
1972 | return Qtrue; | |
1973 | } else { | |
1974 | return Qfalse; | |
1975 | } | |
1976 | } else { | |
1977 | return Qfalse; | |
1978 | } | |
1979 | } | |
1980 | ||
1981 | VALUE | |
1982 | NetCDF_var_eql(VALUE Vara,VALUE Varb) | |
1983 | { | |
1984 | struct NetCDFVar *Netcdf_vara; | |
1985 | struct NetCDFVar *Netcdf_varb; | |
1986 | ||
1987 | if( rb_obj_is_kind_of(Varb, cNetCDFVar) ){ | |
1988 | Data_Get_Struct(Vara,struct NetCDFVar,Netcdf_vara); | |
1989 | Data_Get_Struct(Varb,struct NetCDFVar,Netcdf_varb); | |
1990 | ||
1991 | if(Netcdf_vara->ncid == Netcdf_varb->ncid && | |
1992 | Netcdf_vara->varid == Netcdf_varb->varid){ | |
1993 | return Qtrue; | |
1994 | } else { | |
1995 | return Qfalse; | |
1996 | } | |
1997 | } else { | |
1998 | return Qfalse; | |
1999 | } | |
2000 | } | |
2001 | ||
2002 | VALUE | |
2003 | NetCDF_dim_eql(VALUE Dima,VALUE Dimb) | |
2004 | { | |
2005 | struct NetCDFDim *Netcdf_dima; | |
2006 | struct NetCDFDim *Netcdf_dimb; | |
2007 | ||
2008 | if( rb_obj_is_kind_of(Dimb, cNetCDFDim) ){ | |
2009 | Data_Get_Struct(Dima,struct NetCDFDim,Netcdf_dima); | |
2010 | Data_Get_Struct(Dimb,struct NetCDFDim,Netcdf_dimb); | |
2011 | ||
2012 | if(Netcdf_dima->ncid == Netcdf_dimb->ncid && | |
2013 | Netcdf_dima->dimid == Netcdf_dimb->dimid){ | |
2014 | return Qtrue; | |
2015 | } else { | |
2016 | return Qfalse; | |
2017 | } | |
2018 | } else { | |
2019 | return Qfalse; | |
2020 | } | |
2021 | } | |
2022 | ||
2023 | VALUE | |
2024 | NetCDF_att_eql(VALUE Atta,VALUE Attb) | |
2025 | { | |
2026 | struct NetCDFAtt *Netcdf_atta; | |
2027 | struct NetCDFAtt *Netcdf_attb; | |
2028 | ||
2029 | if( rb_obj_is_kind_of(Attb, cNetCDFAtt) ){ | |
2030 | Data_Get_Struct(Atta,struct NetCDFAtt,Netcdf_atta); | |
2031 | Data_Get_Struct(Attb,struct NetCDFAtt,Netcdf_attb); | |
2032 | ||
2033 | if(Netcdf_atta->ncid == Netcdf_atta->ncid && | |
2034 | Netcdf_atta->varid == Netcdf_attb->varid && | |
2035 | strcmp(Netcdf_atta->name,Netcdf_attb->name)==0){ | |
2036 | return Qtrue; | |
2037 | } else { | |
2038 | return Qfalse; | |
2039 | } | |
2040 | } else { | |
2041 | return Qfalse; | |
2042 | } | |
2043 | } | |
2044 | ||
2045 | /* Follow methods is to connect "NArray" with "Netcdf" */ | |
2046 | VALUE | |
2047 | NetCDF_get_var_char(VALUE Var) | |
2048 | { | |
2049 | int ncid; | |
2050 | int varid; | |
2051 | int status; | |
2052 | unsigned char *ptr; | |
2053 | struct NetCDFVar *Netcdf_var; | |
2054 | int i=0; | |
2055 | int ndimsp; | |
2056 | int *dimids; | |
2057 | size_t lengthp; | |
2058 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2059 | VALUE NArray; | |
2060 | ||
2061 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2062 | ncid = Netcdf_var->ncid; | |
2063 | varid = Netcdf_var->varid; | |
2064 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2065 | if(status != NC_NOERR) NC_RAISE(status); | |
2066 | dimids = ALLOCA_N(int,ndimsp); | |
2067 | if (ndimsp != 0){ | |
2068 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2069 | for(i=0;i<ndimsp;i++){ | |
2070 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2071 | if(status != NC_NOERR) NC_RAISE(status); | |
2072 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2073 | shape[ndimsp-1-i]=lengthp; | |
2074 | } | |
2075 | } else { | |
2076 | ndimsp = 1; | |
2077 | shape = ALLOCA_N(na_shape_t,1); | |
2078 | shape[0]=1; | |
2079 | } | |
2080 | ||
2081 | Cbyte_to_NArray(NArray,ndimsp,shape,ptr); | |
2082 | ||
2083 | status = nc_get_var_text(ncid,varid,(char *)ptr); | |
2084 | if(status != NC_NOERR) NC_RAISE(status); | |
2085 | ||
2086 | OBJ_TAINT(NArray); | |
2087 | return NArray; | |
2088 | } | |
2089 | ||
2090 | VALUE | |
2091 | NetCDF_get_var_byte(VALUE Var) | |
2092 | { | |
2093 | int ncid; | |
2094 | int varid; | |
2095 | int status; | |
2096 | unsigned char *ptr; | |
2097 | struct NetCDFVar *Netcdf_var; | |
2098 | int i=0; | |
2099 | int ndimsp; | |
2100 | int *dimids; | |
2101 | size_t lengthp; | |
2102 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2103 | VALUE NArray; | |
2104 | ||
2105 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2106 | ncid = Netcdf_var->ncid; | |
2107 | varid = Netcdf_var->varid; | |
2108 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2109 | if(status != NC_NOERR) NC_RAISE(status); | |
2110 | dimids = ALLOCA_N(int,ndimsp); | |
2111 | if (ndimsp != 0){ | |
2112 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2113 | for(i=0;i<ndimsp;i++){ | |
2114 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2115 | if(status != NC_NOERR) NC_RAISE(status); | |
2116 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2117 | shape[ndimsp-1-i]=lengthp; | |
2118 | } | |
2119 | } else { | |
2120 | ndimsp = 1; | |
2121 | shape = ALLOCA_N(na_shape_t,1); | |
2122 | shape[0]=1; | |
2123 | } | |
2124 | ||
2125 | Cbyte_to_NArray(NArray,ndimsp,shape,ptr); | |
2126 | ||
2127 | status = nc_get_var_uchar(ncid,varid,ptr); | |
2128 | if(status != NC_NOERR) NC_RAISE(status); | |
2129 | ||
2130 | OBJ_TAINT(NArray); | |
2131 | return NArray; | |
2132 | } | |
2133 | ||
2134 | VALUE | |
2135 | NetCDF_get_var_sint(VALUE Var) | |
2136 | { | |
2137 | int ncid; | |
2138 | int varid; | |
2139 | int status; | |
2140 | short *ptr; | |
2141 | struct NetCDFVar *Netcdf_var; | |
2142 | int i=0; | |
2143 | int ndimsp; | |
2144 | int *dimids; | |
2145 | size_t lengthp; | |
2146 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2147 | VALUE NArray; | |
2148 | ||
2149 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2150 | ncid = Netcdf_var->ncid; | |
2151 | varid = Netcdf_var->varid; | |
2152 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2153 | if(status != NC_NOERR) NC_RAISE(status); | |
2154 | dimids = ALLOCA_N(int,ndimsp); | |
2155 | if (ndimsp != 0){ | |
2156 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2157 | for(i=0;i<ndimsp;i++){ | |
2158 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2159 | if(status != NC_NOERR) NC_RAISE(status); | |
2160 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2161 | shape[ndimsp-1-i]=lengthp; | |
2162 | } | |
2163 | } else { | |
2164 | ndimsp = 1; | |
2165 | shape = ALLOCA_N(na_shape_t,1); | |
2166 | shape[0]=1; | |
2167 | } | |
2168 | ||
2169 | Csint_to_NArray(NArray,ndimsp,shape,ptr); | |
2170 | ||
2171 | status = nc_get_var_short(ncid,varid,ptr); | |
2172 | if(status != NC_NOERR) NC_RAISE(status); | |
2173 | ||
2174 | OBJ_TAINT(NArray); | |
2175 | return NArray; | |
2176 | } | |
2177 | ||
2178 | VALUE | |
2179 | NetCDF_get_var_int(VALUE Var) | |
2180 | { | |
2181 | int ncid; | |
2182 | int varid; | |
2183 | int status; | |
2184 | int *ptr; | |
2185 | struct NetCDFVar *Netcdf_var; | |
2186 | int i=0; | |
2187 | int ndimsp; | |
2188 | int *dimids; | |
2189 | size_t lengthp; | |
2190 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2191 | VALUE NArray; | |
2192 | ||
2193 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2194 | ncid = Netcdf_var->ncid; | |
2195 | varid = Netcdf_var->varid; | |
2196 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2197 | if(status != NC_NOERR) NC_RAISE(status); | |
2198 | dimids = ALLOCA_N(int,ndimsp); | |
2199 | if (ndimsp != 0){ | |
2200 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2201 | for(i=0;i<ndimsp;i++){ | |
2202 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2203 | if(status != NC_NOERR) NC_RAISE(status); | |
2204 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2205 | shape[ndimsp-1-i]=lengthp; | |
2206 | } | |
2207 | } else { | |
2208 | ndimsp = 1; | |
2209 | shape = ALLOCA_N(na_shape_t,1); | |
2210 | shape[0]=1; | |
2211 | } | |
2212 | ||
2213 | Clint_to_NArray(NArray,ndimsp,shape,ptr); | |
2214 | ||
2215 | status = nc_get_var_int(ncid,varid,ptr); | |
2216 | if(status != NC_NOERR) NC_RAISE(status); | |
2217 | ||
2218 | OBJ_TAINT(NArray); | |
2219 | return NArray; | |
2220 | } | |
2221 | ||
2222 | VALUE | |
2223 | NetCDF_get_var_float(VALUE Var) | |
2224 | { | |
2225 | int ncid; | |
2226 | int varid; | |
2227 | int status; | |
2228 | float *ptr; | |
2229 | struct NetCDFVar *Netcdf_var; | |
2230 | int i=0; | |
2231 | int ndimsp; | |
2232 | int *dimids; | |
2233 | size_t lengthp; | |
2234 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2235 | VALUE NArray; | |
2236 | ||
2237 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2238 | ncid = Netcdf_var->ncid; | |
2239 | varid = Netcdf_var->varid; | |
2240 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2241 | if(status != NC_NOERR) NC_RAISE(status); | |
2242 | dimids = ALLOCA_N(int,ndimsp); | |
2243 | if (ndimsp != 0){ | |
2244 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2245 | for(i=0;i<ndimsp;i++){ | |
2246 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2247 | if(status != NC_NOERR) NC_RAISE(status); | |
2248 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2249 | shape[ndimsp-1-i]=lengthp; | |
2250 | } | |
2251 | } else { | |
2252 | ndimsp = 1; | |
2253 | shape = ALLOCA_N(na_shape_t,1); | |
2254 | shape[0]=1; | |
2255 | } | |
2256 | ||
2257 | Cfloat_to_NArray(NArray,ndimsp,shape,ptr); | |
2258 | ||
2259 | status = nc_get_var_float(ncid,varid,ptr); | |
2260 | if(status != NC_NOERR) NC_RAISE(status); | |
2261 | ||
2262 | OBJ_TAINT(NArray); | |
2263 | return NArray; | |
2264 | } | |
2265 | ||
2266 | VALUE | |
2267 | NetCDF_get_var_double(VALUE Var) | |
2268 | { | |
2269 | int ncid; | |
2270 | int varid; | |
2271 | int status; | |
2272 | double *ptr; | |
2273 | struct NetCDFVar *Netcdf_var; | |
2274 | int i=0; | |
2275 | int ndimsp; | |
2276 | int *dimids; | |
2277 | size_t lengthp; | |
2278 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2279 | VALUE NArray; | |
2280 | ||
2281 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2282 | ncid = Netcdf_var->ncid; | |
2283 | varid = Netcdf_var->varid; | |
2284 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
2285 | if(status != NC_NOERR) NC_RAISE(status); | |
2286 | dimids = ALLOCA_N(int,ndimsp); | |
2287 | if (ndimsp != 0){ | |
2288 | shape = ALLOCA_N(na_shape_t,ndimsp); | |
2289 | for(i=0;i<ndimsp;i++){ | |
2290 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2291 | if(status != NC_NOERR) NC_RAISE(status); | |
2292 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
2293 | shape[ndimsp-1-i]=lengthp; | |
2294 | } | |
2295 | } else { | |
2296 | ndimsp = 1; | |
2297 | shape = ALLOCA_N(na_shape_t,1); | |
2298 | shape[0]=1; | |
2299 | } | |
2300 | ||
2301 | Cdouble_to_NArray(NArray,ndimsp,shape,ptr); | |
2302 | ||
2303 | status = nc_get_var_double(ncid,varid,ptr); | |
2304 | if(status != NC_NOERR) NC_RAISE(status); | |
2305 | ||
2306 | OBJ_TAINT(NArray); | |
2307 | return NArray; | |
2308 | } | |
2309 | ||
2310 | VALUE | |
2311 | NetCDF_get_var1_char(VALUE Var,VALUE start) | |
2312 | { | |
2313 | int ncid; | |
2314 | int varid; | |
2315 | int status; | |
2316 | unsigned char *ptr; | |
2317 | int i; | |
2318 | struct NetCDFVar *Netcdf_var; | |
2319 | na_shape_t l_start; | |
2320 | size_t *c_start; | |
2321 | int ndims; | |
2322 | int dimids[NC_MAX_DIMS]; | |
2323 | size_t dimlen; | |
2324 | na_shape_t *c_count; | |
2325 | VALUE NArray; | |
2326 | ||
2327 | ||
2328 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2329 | ncid = Netcdf_var->ncid; | |
2330 | varid = Netcdf_var->varid; | |
2331 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2332 | if(status != NC_NOERR)NC_RAISE(status); | |
2333 | if(ndims == 0) { | |
2334 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2335 | } | |
2336 | ||
2337 | Check_Type(start,T_ARRAY); | |
2338 | if(RARRAY_LEN(start) < ndims) { | |
2339 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2340 | } | |
2341 | ||
2342 | c_start=ALLOCA_N(size_t,ndims); | |
2343 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2344 | for(i=0;i<ndims;i++){ | |
2345 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2346 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2347 | if(status != NC_NOERR) NC_RAISE(status); | |
2348 | if(l_start < 0) { | |
2349 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2350 | if(status != NC_NOERR) NC_RAISE(status); | |
2351 | l_start += dimlen; | |
2352 | } | |
2353 | c_start[i]=l_start; | |
2354 | ||
2355 | c_count[i]=1; | |
2356 | } | |
2357 | ||
2358 | ||
2359 | ||
2360 | ||
2361 | Cbyte_to_NArray(NArray,ndims,c_count,ptr); | |
2362 | status = nc_get_var1_text(ncid,varid,c_start,(char *)ptr); | |
2363 | if(status != NC_NOERR) NC_RAISE(status); | |
2364 | ||
2365 | OBJ_TAINT(NArray); | |
2366 | return NArray; | |
2367 | ||
2368 | } | |
2369 | ||
2370 | VALUE | |
2371 | NetCDF_get_var1_byte(VALUE Var,VALUE start) | |
2372 | { | |
2373 | int ncid; | |
2374 | int varid; | |
2375 | int status; | |
2376 | unsigned char *ptr; | |
2377 | int i; | |
2378 | struct NetCDFVar *Netcdf_var; | |
2379 | na_shape_t l_start; | |
2380 | size_t *c_start; | |
2381 | int ndims; | |
2382 | int dimids[NC_MAX_DIMS]; | |
2383 | size_t dimlen; | |
2384 | na_shape_t *c_count; | |
2385 | VALUE NArray; | |
2386 | ||
2387 | ||
2388 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2389 | ncid = Netcdf_var->ncid; | |
2390 | varid = Netcdf_var->varid; | |
2391 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2392 | if(status != NC_NOERR)NC_RAISE(status); | |
2393 | if(ndims == 0) { | |
2394 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2395 | } | |
2396 | ||
2397 | Check_Type(start,T_ARRAY); | |
2398 | if(RARRAY_LEN(start) < ndims) { | |
2399 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2400 | } | |
2401 | ||
2402 | c_start=ALLOCA_N(size_t,ndims); | |
2403 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2404 | for(i=0;i<ndims;i++){ | |
2405 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2406 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2407 | if(status != NC_NOERR) NC_RAISE(status); | |
2408 | if(l_start < 0) { | |
2409 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2410 | if(status != NC_NOERR) NC_RAISE(status); | |
2411 | l_start += dimlen; | |
2412 | } | |
2413 | c_start[i]=l_start; | |
2414 | ||
2415 | c_count[i]=1; | |
2416 | } | |
2417 | ||
2418 | ||
2419 | ||
2420 | ||
2421 | Cbyte_to_NArray(NArray,ndims,c_count,ptr); | |
2422 | status = nc_get_var1_uchar(ncid,varid,c_start,ptr); | |
2423 | if(status != NC_NOERR) NC_RAISE(status); | |
2424 | ||
2425 | OBJ_TAINT(NArray); | |
2426 | return NArray; | |
2427 | ||
2428 | } | |
2429 | ||
2430 | VALUE | |
2431 | NetCDF_get_var1_sint(VALUE Var,VALUE start) | |
2432 | { | |
2433 | int ncid; | |
2434 | int varid; | |
2435 | int status; | |
2436 | short *ptr; | |
2437 | int i; | |
2438 | struct NetCDFVar *Netcdf_var; | |
2439 | na_shape_t l_start; | |
2440 | size_t *c_start; | |
2441 | int ndims; | |
2442 | int dimids[NC_MAX_DIMS]; | |
2443 | size_t dimlen; | |
2444 | na_shape_t *c_count; | |
2445 | VALUE NArray; | |
2446 | ||
2447 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2448 | ncid = Netcdf_var->ncid; | |
2449 | varid = Netcdf_var->varid; | |
2450 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2451 | if(status != NC_NOERR) NC_RAISE(status); | |
2452 | if(ndims == 0) { | |
2453 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2454 | } | |
2455 | ||
2456 | Check_Type(start,T_ARRAY); | |
2457 | if(RARRAY_LEN(start) < ndims) { | |
2458 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2459 | } | |
2460 | ||
2461 | c_start=ALLOCA_N(size_t,ndims); | |
2462 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2463 | for(i=0;i<ndims;i++){ | |
2464 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2465 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2466 | if(status != NC_NOERR) NC_RAISE(status); | |
2467 | if(l_start < 0) { | |
2468 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2469 | if(status != NC_NOERR) NC_RAISE(status); | |
2470 | l_start += dimlen; | |
2471 | } | |
2472 | c_start[i]=l_start; | |
2473 | c_count[i]=1; | |
2474 | } | |
2475 | ||
2476 | Csint_to_NArray(NArray,ndims,c_count,ptr); | |
2477 | ||
2478 | status = nc_get_var1_short(ncid,varid,c_start,ptr); | |
2479 | if(status != NC_NOERR) NC_RAISE(status); | |
2480 | ||
2481 | OBJ_TAINT(NArray); | |
2482 | return NArray; | |
2483 | ||
2484 | } | |
2485 | ||
2486 | VALUE | |
2487 | NetCDF_get_var1_int(VALUE Var,VALUE start) | |
2488 | { | |
2489 | int ncid; | |
2490 | int varid; | |
2491 | int status; | |
2492 | int *ptr; | |
2493 | int i; | |
2494 | struct NetCDFVar *Netcdf_var; | |
2495 | na_shape_t l_start; | |
2496 | size_t *c_start; | |
2497 | int ndims; | |
2498 | int dimids[NC_MAX_DIMS]; | |
2499 | size_t dimlen; | |
2500 | na_shape_t *c_count; | |
2501 | VALUE NArray; | |
2502 | ||
2503 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2504 | ncid = Netcdf_var->ncid; | |
2505 | varid = Netcdf_var->varid; | |
2506 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2507 | if(status != NC_NOERR)NC_RAISE(status); | |
2508 | if(ndims == 0) { | |
2509 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2510 | } | |
2511 | ||
2512 | Check_Type(start,T_ARRAY); | |
2513 | if(RARRAY_LEN(start) < ndims) { | |
2514 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2515 | } | |
2516 | ||
2517 | c_start=ALLOCA_N(size_t,ndims); | |
2518 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2519 | for(i=0;i<ndims;i++){ | |
2520 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2521 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2522 | if(status != NC_NOERR) NC_RAISE(status); | |
2523 | if(l_start < 0) { | |
2524 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2525 | if(status != NC_NOERR) NC_RAISE(status); | |
2526 | l_start += dimlen; | |
2527 | } | |
2528 | c_start[i]=l_start; | |
2529 | c_count[i]=1; | |
2530 | } | |
2531 | ||
2532 | Clint_to_NArray(NArray,ndims,c_count,ptr); | |
2533 | ||
2534 | status = nc_get_var1_int(ncid,varid,c_start,ptr); | |
2535 | if(status != NC_NOERR) NC_RAISE(status); | |
2536 | ||
2537 | OBJ_TAINT(NArray); | |
2538 | return NArray; | |
2539 | ||
2540 | } | |
2541 | ||
2542 | VALUE | |
2543 | NetCDF_get_var1_float(VALUE Var,VALUE start) | |
2544 | { | |
2545 | int ncid; | |
2546 | int varid; | |
2547 | int status; | |
2548 | float *ptr; | |
2549 | int i; | |
2550 | struct NetCDFVar *Netcdf_var; | |
2551 | na_shape_t l_start; | |
2552 | size_t *c_start; | |
2553 | int ndims; | |
2554 | int dimids[NC_MAX_DIMS]; | |
2555 | size_t dimlen; | |
2556 | na_shape_t *c_count; | |
2557 | VALUE NArray; | |
2558 | ||
2559 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2560 | ncid = Netcdf_var->ncid; | |
2561 | varid = Netcdf_var->varid; | |
2562 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2563 | if(status != NC_NOERR)NC_RAISE(status); | |
2564 | if(ndims == 0) { | |
2565 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2566 | } | |
2567 | ||
2568 | Check_Type(start,T_ARRAY); | |
2569 | if(RARRAY_LEN(start) < ndims) { | |
2570 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2571 | } | |
2572 | ||
2573 | c_start=ALLOCA_N(size_t,ndims); | |
2574 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2575 | for(i=0;i<ndims;i++){ | |
2576 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2577 | status = nc_inq_vardimid(ncid, varid, dimids); | |
2578 | if(status != NC_NOERR) NC_RAISE(status); | |
2579 | if(l_start < 0) { | |
2580 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2581 | if(status != NC_NOERR) NC_RAISE(status); | |
2582 | l_start += dimlen; | |
2583 | } | |
2584 | c_start[i]=l_start; | |
2585 | c_count[i]=1; | |
2586 | } | |
2587 | ||
2588 | Cfloat_to_NArray(NArray,ndims,c_count,ptr); | |
2589 | ||
2590 | status = nc_get_var1_float(ncid,varid,c_start,ptr); | |
2591 | if(status != NC_NOERR) NC_RAISE(status); | |
2592 | ||
2593 | OBJ_TAINT(NArray); | |
2594 | return NArray; | |
2595 | ||
2596 | } | |
2597 | ||
2598 | VALUE | |
2599 | NetCDF_get_var1_double(VALUE Var,VALUE start) | |
2600 | { | |
2601 | int ncid; | |
2602 | int varid; | |
2603 | int status; | |
2604 | double *ptr; | |
2605 | int i; | |
2606 | struct NetCDFVar *Netcdf_var; | |
2607 | na_shape_t l_start; | |
2608 | size_t *c_start; | |
2609 | int ndims; | |
2610 | int dimids[NC_MAX_DIMS]; | |
2611 | size_t dimlen; | |
2612 | na_shape_t *c_count; | |
2613 | VALUE NArray; | |
2614 | ||
2615 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2616 | ncid = Netcdf_var->ncid; | |
2617 | varid = Netcdf_var->varid; | |
2618 | status = nc_inq_varndims(ncid, varid, &ndims); | |
2619 | if(status != NC_NOERR)NC_RAISE(status); | |
2620 | if(ndims == 0) { | |
2621 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2622 | } | |
2623 | ||
2624 | Check_Type(start,T_ARRAY); | |
2625 | if(RARRAY_LEN(start) < ndims) { | |
2626 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
2627 | } | |
2628 | ||
2629 | c_start=ALLOCA_N(size_t,ndims); | |
2630 | c_count=ALLOCA_N(na_shape_t,ndims); | |
2631 | for(i=0;i<ndims;i++){ | |
2632 | l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2633 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2634 | if(status !=NC_NOERR) NC_RAISE(status); | |
2635 | if(l_start < 0) { | |
2636 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2637 | if(status != NC_NOERR) NC_RAISE(status); | |
2638 | l_start += dimlen; | |
2639 | } | |
2640 | c_start[i]=l_start; | |
2641 | c_count[i]=1; | |
2642 | } | |
2643 | ||
2644 | Cdouble_to_NArray(NArray,ndims,c_count,ptr); | |
2645 | ||
2646 | status = nc_get_var1_double(ncid,varid,c_start,ptr); | |
2647 | if(status != NC_NOERR) NC_RAISE(status); | |
2648 | ||
2649 | OBJ_TAINT(NArray); | |
2650 | return NArray; | |
2651 | ||
2652 | } | |
2653 | ||
2654 | VALUE | |
2655 | NetCDF_get_vars_char(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2656 | { | |
2657 | int ncid; | |
2658 | int varid; | |
2659 | int status; | |
2660 | unsigned char *ptr; | |
2661 | int i; | |
2662 | struct NetCDFVar *Netcdf_var; | |
2663 | na_shape_t l_start, l_end; | |
2664 | size_t *c_start; | |
2665 | size_t *c_count; | |
2666 | ptrdiff_t *c_stride; | |
2667 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2668 | int ndims; | |
2669 | int *dimids; | |
2670 | size_t dimlen; | |
2671 | VALUE NArray; | |
2672 | ||
2673 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2674 | ncid = Netcdf_var->ncid; | |
2675 | varid = Netcdf_var->varid; | |
2676 | ||
2677 | status = nc_inq_varndims(ncid,varid,&ndims); | |
2678 | if(status != NC_NOERR) NC_RAISE(status); | |
2679 | if(ndims == 0) { | |
2680 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2681 | } | |
2682 | ||
2683 | dimids = ALLOCA_N(int,ndims); | |
2684 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2685 | if(status != NC_NOERR) NC_RAISE(status); | |
2686 | ||
2687 | Check_Type(start,T_ARRAY); | |
2688 | if(RARRAY_LEN(start) < ndims){ | |
2689 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
2690 | } | |
2691 | c_start = ALLOCA_N(size_t,ndims); | |
2692 | for(i=0; i<ndims; i++){ | |
2693 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2694 | ||
2695 | if(l_start < 0) { | |
2696 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
2697 | if(status != NC_NOERR) NC_RAISE(status); | |
2698 | l_start += dimlen; | |
2699 | } | |
2700 | c_start[i]=l_start; | |
2701 | } | |
2702 | ||
2703 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
2704 | switch(TYPE(stride)){ | |
2705 | case T_NIL: | |
2706 | for(i=0; i<ndims; i++){ | |
2707 | c_stride[i]=1; | |
2708 | } | |
2709 | break; | |
2710 | default: | |
2711 | Check_Type(stride,T_ARRAY); | |
2712 | if(RARRAY_LEN(stride) < ndims) { | |
2713 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
2714 | } | |
2715 | for(i=0;i<ndims; i++){ | |
2716 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
2717 | if(c_stride[i]==0){ | |
2718 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
2719 | } | |
2720 | } | |
2721 | } | |
2722 | ||
2723 | c_count=ALLOCA_N(size_t,ndims); | |
2724 | switch(TYPE(end)){ | |
2725 | case T_NIL: | |
2726 | for(i=0; i<ndims; i++){ | |
2727 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2728 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
2729 | } | |
2730 | break; | |
2731 | default: | |
2732 | Check_Type(end,T_ARRAY); | |
2733 | if(RARRAY_LEN(end) <ndims) { | |
2734 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
2735 | } | |
2736 | for(i=0; i<ndims; i++){ | |
2737 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
2738 | if(l_end < 0) { | |
2739 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2740 | if(status != NC_NOERR) NC_RAISE(status); | |
2741 | l_end +=dimlen; | |
2742 | } | |
2743 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
2744 | } | |
2745 | } | |
2746 | ||
2747 | ||
2748 | shape = ALLOCA_N(na_shape_t,ndims); | |
2749 | for(i=0;i<ndims;i++){ | |
2750 | shape[ndims-1-i]=c_count[i]; | |
2751 | } | |
2752 | ||
2753 | Cbyte_to_NArray(NArray,ndims,shape,ptr); | |
2754 | ||
2755 | status = nc_get_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr); | |
2756 | if(status != NC_NOERR) NC_RAISE(status); | |
2757 | ||
2758 | OBJ_TAINT(NArray); | |
2759 | return NArray; | |
2760 | } | |
2761 | ||
2762 | VALUE | |
2763 | NetCDF_get_vars_byte(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2764 | { | |
2765 | int ncid; | |
2766 | int varid; | |
2767 | int status; | |
2768 | unsigned char *ptr; | |
2769 | int i; | |
2770 | struct NetCDFVar *Netcdf_var; | |
2771 | na_shape_t l_start, l_end; | |
2772 | size_t *c_start; | |
2773 | size_t *c_count; | |
2774 | ptrdiff_t *c_stride; | |
2775 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2776 | int ndims; | |
2777 | int *dimids; | |
2778 | size_t dimlen; | |
2779 | VALUE NArray; | |
2780 | ||
2781 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2782 | ncid = Netcdf_var->ncid; | |
2783 | varid = Netcdf_var->varid; | |
2784 | ||
2785 | status = nc_inq_varndims(ncid,varid,&ndims); | |
2786 | if(status != NC_NOERR) NC_RAISE(status); | |
2787 | if(ndims == 0) { | |
2788 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2789 | } | |
2790 | ||
2791 | dimids = ALLOCA_N(int,ndims); | |
2792 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2793 | if(status != NC_NOERR) NC_RAISE(status); | |
2794 | ||
2795 | Check_Type(start,T_ARRAY); | |
2796 | if(RARRAY_LEN(start) < ndims){ | |
2797 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
2798 | } | |
2799 | c_start = ALLOCA_N(size_t,ndims); | |
2800 | for(i=0; i<ndims; i++){ | |
2801 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2802 | ||
2803 | if(l_start < 0) { | |
2804 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
2805 | if(status != NC_NOERR) NC_RAISE(status); | |
2806 | l_start += dimlen; | |
2807 | } | |
2808 | c_start[i]=l_start; | |
2809 | } | |
2810 | ||
2811 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
2812 | switch(TYPE(stride)){ | |
2813 | case T_NIL: | |
2814 | for(i=0; i<ndims; i++){ | |
2815 | c_stride[i]=1; | |
2816 | } | |
2817 | break; | |
2818 | default: | |
2819 | Check_Type(stride,T_ARRAY); | |
2820 | if(RARRAY_LEN(stride) < ndims) { | |
2821 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
2822 | } | |
2823 | for(i=0;i<ndims; i++){ | |
2824 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
2825 | if(c_stride[i]==0){ | |
2826 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
2827 | } | |
2828 | } | |
2829 | } | |
2830 | ||
2831 | c_count=ALLOCA_N(size_t,ndims); | |
2832 | switch(TYPE(end)){ | |
2833 | case T_NIL: | |
2834 | for(i=0; i<ndims; i++){ | |
2835 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2836 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
2837 | } | |
2838 | break; | |
2839 | default: | |
2840 | Check_Type(end,T_ARRAY); | |
2841 | if(RARRAY_LEN(end) <ndims) { | |
2842 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
2843 | } | |
2844 | for(i=0; i<ndims; i++){ | |
2845 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
2846 | if(l_end < 0) { | |
2847 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2848 | if(status != NC_NOERR) NC_RAISE(status); | |
2849 | l_end +=dimlen; | |
2850 | } | |
2851 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
2852 | } | |
2853 | } | |
2854 | ||
2855 | ||
2856 | shape = ALLOCA_N(na_shape_t,ndims); | |
2857 | for(i=0;i<ndims;i++){ | |
2858 | shape[ndims-1-i]=c_count[i]; | |
2859 | } | |
2860 | ||
2861 | Cbyte_to_NArray(NArray,ndims,shape,ptr); | |
2862 | ||
2863 | status = nc_get_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr); | |
2864 | if(status != NC_NOERR) NC_RAISE(status); | |
2865 | ||
2866 | OBJ_TAINT(NArray); | |
2867 | return NArray; | |
2868 | } | |
2869 | ||
2870 | VALUE | |
2871 | NetCDF_get_vars_sint(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2872 | { | |
2873 | int ncid; | |
2874 | int varid; | |
2875 | int status; | |
2876 | short *ptr; | |
2877 | int i; | |
2878 | struct NetCDFVar *Netcdf_var; | |
2879 | na_shape_t l_start, l_end; | |
2880 | size_t *c_start; | |
2881 | size_t *c_count; | |
2882 | ptrdiff_t *c_stride; | |
2883 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2884 | int ndims; | |
2885 | int *dimids; | |
2886 | size_t dimlen; | |
2887 | VALUE NArray; | |
2888 | ||
2889 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2890 | ncid = Netcdf_var->ncid; | |
2891 | varid = Netcdf_var->varid; | |
2892 | ||
2893 | status = nc_inq_varndims(ncid,varid,&ndims); | |
2894 | if(status != NC_NOERR) NC_RAISE(status); | |
2895 | if(ndims == 0) { | |
2896 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
2897 | } | |
2898 | ||
2899 | dimids = ALLOCA_N(int,ndims); | |
2900 | status = nc_inq_vardimid(ncid,varid,dimids); | |
2901 | if(status != NC_NOERR) NC_RAISE(status); | |
2902 | ||
2903 | Check_Type(start,T_ARRAY); | |
2904 | if(RARRAY_LEN(start) < ndims){ | |
2905 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
2906 | } | |
2907 | c_start = ALLOCA_N(size_t,ndims); | |
2908 | for(i=0; i<ndims; i++){ | |
2909 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
2910 | ||
2911 | if(l_start < 0) { | |
2912 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
2913 | if(status != NC_NOERR) NC_RAISE(status); | |
2914 | l_start += dimlen; | |
2915 | } | |
2916 | c_start[i]=l_start; | |
2917 | } | |
2918 | ||
2919 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
2920 | switch(TYPE(stride)){ | |
2921 | case T_NIL: | |
2922 | for(i=0; i<ndims; i++){ | |
2923 | c_stride[i]=1; | |
2924 | } | |
2925 | break; | |
2926 | default: | |
2927 | Check_Type(stride,T_ARRAY); | |
2928 | if(RARRAY_LEN(stride) < ndims) { | |
2929 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
2930 | } | |
2931 | for(i=0;i<ndims; i++){ | |
2932 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
2933 | if(c_stride[i]==0){ | |
2934 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
2935 | } | |
2936 | } | |
2937 | } | |
2938 | ||
2939 | c_count=ALLOCA_N(size_t,ndims); | |
2940 | switch(TYPE(end)){ | |
2941 | case T_NIL: | |
2942 | for(i=0; i<ndims; i++){ | |
2943 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2944 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
2945 | } | |
2946 | break; | |
2947 | default: | |
2948 | Check_Type(end,T_ARRAY); | |
2949 | if(RARRAY_LEN(end) <ndims) { | |
2950 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
2951 | } | |
2952 | for(i=0; i<ndims; i++){ | |
2953 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
2954 | if(l_end < 0) { | |
2955 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
2956 | if(status != NC_NOERR) NC_RAISE(status); | |
2957 | l_end +=dimlen; | |
2958 | } | |
2959 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
2960 | } | |
2961 | } | |
2962 | ||
2963 | ||
2964 | shape = ALLOCA_N(na_shape_t,ndims); | |
2965 | for(i=0;i<ndims;i++){ | |
2966 | shape[ndims-1-i]=c_count[i]; | |
2967 | } | |
2968 | ||
2969 | Csint_to_NArray(NArray,ndims,shape,ptr); | |
2970 | ||
2971 | ||
2972 | status = nc_get_vars_short(ncid,varid,c_start,c_count,c_stride,ptr); | |
2973 | if(status != NC_NOERR) NC_RAISE(status); | |
2974 | ||
2975 | OBJ_TAINT(NArray); | |
2976 | return NArray; | |
2977 | } | |
2978 | ||
2979 | VALUE | |
2980 | NetCDF_get_vars_int(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
2981 | { | |
2982 | int ncid; | |
2983 | int varid; | |
2984 | int status; | |
2985 | int *ptr; | |
2986 | int i; | |
2987 | struct NetCDFVar *Netcdf_var; | |
2988 | na_shape_t l_start, l_end; | |
2989 | size_t *c_start; | |
2990 | size_t *c_count; | |
2991 | ptrdiff_t *c_stride; | |
2992 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
2993 | int ndims; | |
2994 | int *dimids; | |
2995 | size_t dimlen; | |
2996 | VALUE NArray; | |
2997 | ||
2998 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
2999 | ncid = Netcdf_var->ncid; | |
3000 | varid = Netcdf_var->varid; | |
3001 | ||
3002 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3003 | if(status != NC_NOERR) NC_RAISE(status); | |
3004 | if(ndims == 0) { | |
3005 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
3006 | } | |
3007 | ||
3008 | dimids = ALLOCA_N(int,ndims); | |
3009 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3010 | if(status != NC_NOERR) NC_RAISE(status); | |
3011 | ||
3012 | Check_Type(start,T_ARRAY); | |
3013 | if(RARRAY_LEN(start) < ndims){ | |
3014 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3015 | } | |
3016 | c_start = ALLOCA_N(size_t,ndims); | |
3017 | for(i=0; i<ndims; i++){ | |
3018 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3019 | ||
3020 | if(l_start < 0) { | |
3021 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3022 | if(status != NC_NOERR) NC_RAISE(status); | |
3023 | l_start += dimlen; | |
3024 | } | |
3025 | c_start[i]=l_start; | |
3026 | } | |
3027 | ||
3028 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3029 | switch(TYPE(stride)){ | |
3030 | case T_NIL: | |
3031 | for(i=0; i<ndims; i++){ | |
3032 | c_stride[i]=1; | |
3033 | } | |
3034 | break; | |
3035 | default: | |
3036 | Check_Type(stride,T_ARRAY); | |
3037 | if(RARRAY_LEN(stride) < ndims) { | |
3038 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
3039 | } | |
3040 | for(i=0;i<ndims; i++){ | |
3041 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3042 | if(c_stride[i]==0){ | |
3043 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
3044 | } | |
3045 | } | |
3046 | } | |
3047 | ||
3048 | c_count=ALLOCA_N(size_t,ndims); | |
3049 | switch(TYPE(end)){ | |
3050 | case T_NIL: | |
3051 | for(i=0; i<ndims; i++){ | |
3052 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3053 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
3054 | } | |
3055 | break; | |
3056 | default: | |
3057 | Check_Type(end,T_ARRAY); | |
3058 | if(RARRAY_LEN(end) <ndims) { | |
3059 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3060 | } | |
3061 | for(i=0; i<ndims; i++){ | |
3062 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3063 | if(l_end < 0) { | |
3064 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3065 | if(status != NC_NOERR) NC_RAISE(status); | |
3066 | l_end +=dimlen; | |
3067 | } | |
3068 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3069 | } | |
3070 | } | |
3071 | ||
3072 | ||
3073 | shape = ALLOCA_N(na_shape_t,ndims); | |
3074 | for(i=0;i<ndims;i++){ | |
3075 | shape[ndims-1-i]=c_count[i]; | |
3076 | } | |
3077 | ||
3078 | Clint_to_NArray(NArray,ndims,shape,ptr); | |
3079 | ||
3080 | ||
3081 | status = nc_get_vars_int(ncid,varid,c_start,c_count,c_stride,ptr); | |
3082 | if(status != NC_NOERR) NC_RAISE(status); | |
3083 | ||
3084 | OBJ_TAINT(NArray); | |
3085 | return NArray; | |
3086 | } | |
3087 | ||
3088 | VALUE | |
3089 | NetCDF_get_vars_float(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
3090 | { | |
3091 | int ncid; | |
3092 | int varid; | |
3093 | int status; | |
3094 | float *ptr; | |
3095 | int i; | |
3096 | struct NetCDFVar *Netcdf_var; | |
3097 | na_shape_t l_start, l_end; | |
3098 | size_t *c_start; | |
3099 | size_t *c_count; | |
3100 | ptrdiff_t *c_stride; | |
3101 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
3102 | int ndims; | |
3103 | int *dimids; | |
3104 | size_t dimlen; | |
3105 | VALUE NArray; | |
3106 | ||
3107 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3108 | ncid = Netcdf_var->ncid; | |
3109 | varid = Netcdf_var->varid; | |
3110 | ||
3111 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3112 | if(status != NC_NOERR) NC_RAISE(status); | |
3113 | if(ndims == 0) { | |
3114 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
3115 | } | |
3116 | ||
3117 | dimids = ALLOCA_N(int,ndims); | |
3118 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3119 | if(status != NC_NOERR) NC_RAISE(status); | |
3120 | ||
3121 | Check_Type(start,T_ARRAY); | |
3122 | if(RARRAY_LEN(start) < ndims){ | |
3123 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3124 | } | |
3125 | c_start = ALLOCA_N(size_t,ndims); | |
3126 | for(i=0; i<ndims; i++){ | |
3127 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3128 | ||
3129 | if(l_start < 0) { | |
3130 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3131 | if(status != NC_NOERR) NC_RAISE(status); | |
3132 | l_start += dimlen; | |
3133 | } | |
3134 | c_start[i]=l_start; | |
3135 | } | |
3136 | ||
3137 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3138 | switch(TYPE(stride)){ | |
3139 | case T_NIL: | |
3140 | for(i=0; i<ndims; i++){ | |
3141 | c_stride[i]=1; | |
3142 | } | |
3143 | break; | |
3144 | default: | |
3145 | Check_Type(stride,T_ARRAY); | |
3146 | if(RARRAY_LEN(stride) < ndims) { | |
3147 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
3148 | } | |
3149 | for(i=0;i<ndims; i++){ | |
3150 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3151 | if(c_stride[i]==0){ | |
3152 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
3153 | } | |
3154 | } | |
3155 | } | |
3156 | ||
3157 | c_count=ALLOCA_N(size_t,ndims); | |
3158 | switch(TYPE(end)){ | |
3159 | case T_NIL: | |
3160 | for(i=0; i<ndims; i++){ | |
3161 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3162 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
3163 | } | |
3164 | break; | |
3165 | default: | |
3166 | Check_Type(end,T_ARRAY); | |
3167 | if(RARRAY_LEN(end) <ndims) { | |
3168 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3169 | } | |
3170 | for(i=0; i<ndims; i++){ | |
3171 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3172 | if(l_end < 0) { | |
3173 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3174 | if(status != NC_NOERR) NC_RAISE(status); | |
3175 | l_end +=dimlen; | |
3176 | } | |
3177 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3178 | } | |
3179 | } | |
3180 | ||
3181 | ||
3182 | shape = ALLOCA_N(na_shape_t,ndims); | |
3183 | for(i=0;i<ndims;i++){ | |
3184 | shape[ndims-1-i]=c_count[i]; | |
3185 | } | |
3186 | ||
3187 | Cfloat_to_NArray(NArray,ndims,shape,ptr); | |
3188 | ||
3189 | ||
3190 | status = nc_get_vars_float(ncid,varid,c_start,c_count,c_stride,ptr); | |
3191 | if(status != NC_NOERR) NC_RAISE(status); | |
3192 | ||
3193 | OBJ_TAINT(NArray); | |
3194 | return NArray; | |
3195 | } | |
3196 | ||
3197 | VALUE | |
3198 | NetCDF_get_vars_double(VALUE Var,VALUE start,VALUE end,VALUE stride) | |
3199 | { | |
3200 | int ncid; | |
3201 | int varid; | |
3202 | int status; | |
3203 | double *ptr; | |
3204 | int i; | |
3205 | struct NetCDFVar *Netcdf_var; | |
3206 | na_shape_t l_start, l_end; | |
3207 | size_t *c_start; | |
3208 | size_t *c_count; | |
3209 | ptrdiff_t *c_stride; | |
3210 | na_shape_t *shape; /* NArray uses int instead of size_t */ | |
3211 | int ndims; | |
3212 | int *dimids; | |
3213 | size_t dimlen; | |
3214 | VALUE NArray; | |
3215 | ||
3216 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3217 | ncid = Netcdf_var->ncid; | |
3218 | varid = Netcdf_var->varid; | |
3219 | ||
3220 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3221 | if(status != NC_NOERR) NC_RAISE(status); | |
3222 | if(ndims == 0) { | |
3223 | rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n"); | |
3224 | } | |
3225 | ||
3226 | dimids = ALLOCA_N(int,ndims); | |
3227 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3228 | if(status != NC_NOERR) NC_RAISE(status); | |
3229 | ||
3230 | Check_Type(start,T_ARRAY); | |
3231 | if(RARRAY_LEN(start) < ndims){ | |
3232 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3233 | } | |
3234 | c_start = ALLOCA_N(size_t,ndims); | |
3235 | for(i=0; i<ndims; i++){ | |
3236 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3237 | ||
3238 | if(l_start < 0) { | |
3239 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3240 | if(status != NC_NOERR) NC_RAISE(status); | |
3241 | l_start += dimlen; | |
3242 | } | |
3243 | c_start[i]=l_start; | |
3244 | } | |
3245 | ||
3246 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3247 | switch(TYPE(stride)){ | |
3248 | case T_NIL: | |
3249 | for(i=0; i<ndims; i++){ | |
3250 | c_stride[i]=1; | |
3251 | } | |
3252 | break; | |
3253 | default: | |
3254 | Check_Type(stride,T_ARRAY); | |
3255 | if(RARRAY_LEN(stride) < ndims) { | |
3256 | rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n"); | |
3257 | } | |
3258 | for(i=0;i<ndims; i++){ | |
3259 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3260 | if(c_stride[i]==0){ | |
3261 | rb_raise(rb_eNetcdfError,"stride cannot be zero\n"); | |
3262 | } | |
3263 | } | |
3264 | } | |
3265 | ||
3266 | c_count=ALLOCA_N(size_t,ndims); | |
3267 | switch(TYPE(end)){ | |
3268 | case T_NIL: | |
3269 | for(i=0; i<ndims; i++){ | |
3270 | nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3271 | c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1; | |
3272 | } | |
3273 | break; | |
3274 | default: | |
3275 | Check_Type(end,T_ARRAY); | |
3276 | if(RARRAY_LEN(end) <ndims) { | |
3277 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3278 | } | |
3279 | for(i=0; i<ndims; i++){ | |
3280 | l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3281 | if(l_end < 0) { | |
3282 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3283 | if(status != NC_NOERR) NC_RAISE(status); | |
3284 | l_end +=dimlen; | |
3285 | } | |
3286 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3287 | } | |
3288 | } | |
3289 | ||
3290 | ||
3291 | shape = ALLOCA_N(na_shape_t,ndims); | |
3292 | for(i=0;i<ndims;i++){ | |
3293 | shape[ndims-1-i]=c_count[i]; | |
3294 | } | |
3295 | ||
3296 | Cdouble_to_NArray(NArray,ndims,shape,ptr); | |
3297 | ||
3298 | status = nc_get_vars_double(ncid,varid,c_start,c_count,c_stride,ptr); | |
3299 | if(status != NC_NOERR) NC_RAISE(status); | |
3300 | ||
3301 | OBJ_TAINT(NArray); | |
3302 | return NArray; | |
3303 | } | |
3304 | ||
3305 | ||
3306 | VALUE | |
3307 | NetCDF_put_var_char(VALUE Var,VALUE NArray) | |
3308 | { | |
3309 | int ncid; | |
3310 | int varid; | |
3311 | int status; | |
3312 | unsigned char *ptr,scalar; | |
3313 | na_shape_t len,i=0; | |
3314 | struct NetCDFVar *Netcdf_var; | |
3315 | na_shape_t nc_tlen=1; | |
3316 | int ndimsp; | |
3317 | int dimids[NC_MAX_DIMS]; | |
3318 | size_t lengthp; | |
3319 | char *var_name; | |
3320 | ||
3321 | rb_secure(3); | |
3322 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3323 | ncid=Netcdf_var->ncid; | |
3324 | varid=Netcdf_var->varid; | |
3325 | ||
3326 | Array_to_Cbyte_len(NArray,ptr,len); | |
3327 | ||
3328 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3329 | if(status != NC_NOERR) NC_RAISE(status); | |
3330 | for(i=0;i<ndimsp;i++){ | |
3331 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3332 | if(status != NC_NOERR) NC_RAISE(status); | |
3333 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3334 | nc_tlen=lengthp*nc_tlen; | |
3335 | } | |
3336 | if(len == 1 && len != nc_tlen){ | |
3337 | scalar = *ptr; | |
3338 | ptr = ALLOCA_N(unsigned char,nc_tlen); | |
3339 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3340 | } else if(len != nc_tlen){ | |
3341 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3342 | status = nc_inq_varname(ncid,varid,var_name); | |
3343 | if(status != NC_NOERR) NC_RAISE(status ); | |
3344 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name); | |
3345 | } | |
3346 | status = nc_put_var_text(ncid,varid,(char *)ptr); | |
3347 | if(status !=NC_NOERR) NC_RAISE(status); | |
3348 | return Qnil; | |
3349 | } | |
3350 | ||
3351 | VALUE | |
3352 | NetCDF_put_var_byte(VALUE Var,VALUE NArray) | |
3353 | { | |
3354 | int ncid; | |
3355 | int varid; | |
3356 | int status; | |
3357 | unsigned char *ptr,scalar; | |
3358 | na_shape_t len,i=0; | |
3359 | struct NetCDFVar *Netcdf_var; | |
3360 | na_shape_t nc_tlen=1; | |
3361 | int ndimsp; | |
3362 | int dimids[NC_MAX_DIMS]; | |
3363 | size_t lengthp; | |
3364 | char *var_name; | |
3365 | ||
3366 | rb_secure(3); | |
3367 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3368 | ncid=Netcdf_var->ncid; | |
3369 | varid=Netcdf_var->varid; | |
3370 | ||
3371 | Array_to_Cbyte_len(NArray,ptr,len); | |
3372 | ||
3373 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3374 | if(status != NC_NOERR) NC_RAISE(status); | |
3375 | for(i=0;i<ndimsp;i++){ | |
3376 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3377 | if(status != NC_NOERR) NC_RAISE(status); | |
3378 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3379 | nc_tlen=lengthp*nc_tlen; | |
3380 | } | |
3381 | if(len == 1 && len != nc_tlen){ | |
3382 | scalar = *ptr; | |
3383 | ptr = ALLOCA_N(unsigned char,nc_tlen); | |
3384 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3385 | } else if(len != nc_tlen){ | |
3386 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3387 | status = nc_inq_varname(ncid,varid,var_name); | |
3388 | if(status != NC_NOERR) NC_RAISE(status ); | |
3389 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name); | |
3390 | } | |
3391 | status = nc_put_var_uchar(ncid,varid,ptr); | |
3392 | if(status !=NC_NOERR) NC_RAISE(status); | |
3393 | return Qnil; | |
3394 | } | |
3395 | ||
3396 | VALUE | |
3397 | NetCDF_put_var_short(VALUE Var,VALUE NArray) | |
3398 | { | |
3399 | int ncid; | |
3400 | int varid; | |
3401 | int status; | |
3402 | short *ptr,scalar; | |
3403 | na_shape_t len,i=0; | |
3404 | struct NetCDFVar *Netcdf_var; | |
3405 | na_shape_t nc_tlen=1; | |
3406 | int ndimsp; | |
3407 | int dimids[NC_MAX_DIMS]; | |
3408 | size_t lengthp; | |
3409 | char *var_name; | |
3410 | ||
3411 | rb_secure(3); | |
3412 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3413 | ncid=Netcdf_var->ncid; | |
3414 | varid=Netcdf_var->varid; | |
3415 | Array_to_Csint_len(NArray,ptr,len); | |
3416 | ||
3417 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3418 | if(status != NC_NOERR) NC_RAISE(status); | |
3419 | for(i=0;i<ndimsp;i++){ | |
3420 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3421 | if(status != NC_NOERR) NC_RAISE(status); | |
3422 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3423 | nc_tlen=lengthp*nc_tlen; | |
3424 | } | |
3425 | if(len == 1 && len != nc_tlen){ | |
3426 | scalar = *ptr; | |
3427 | ptr = ALLOCA_N(short,nc_tlen); | |
3428 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3429 | } else if(len != nc_tlen){ | |
3430 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3431 | status = nc_inq_varname(ncid,varid,var_name); | |
3432 | if(status != NC_NOERR) NC_RAISE(status); | |
3433 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3434 | } | |
3435 | ||
3436 | status = nc_put_var_short(ncid,varid,ptr); | |
3437 | if(status !=NC_NOERR) NC_RAISE(status); | |
3438 | return Qnil; | |
3439 | } | |
3440 | ||
3441 | VALUE | |
3442 | NetCDF_put_var_int(VALUE Var,VALUE NArray) | |
3443 | { | |
3444 | int ncid; | |
3445 | int varid; | |
3446 | int status; | |
3447 | int *ptr,scalar; | |
3448 | na_shape_t len,i=0; | |
3449 | struct NetCDFVar *Netcdf_var; | |
3450 | na_shape_t nc_tlen=1; | |
3451 | int ndimsp; | |
3452 | int dimids[NC_MAX_DIMS]; | |
3453 | size_t lengthp; | |
3454 | char *var_name; | |
3455 | ||
3456 | rb_secure(3); | |
3457 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3458 | ncid=Netcdf_var->ncid; | |
3459 | varid=Netcdf_var->varid; | |
3460 | ||
3461 | Array_to_Clint_len(NArray,ptr,len); | |
3462 | ||
3463 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3464 | if(status != NC_NOERR) NC_RAISE(status); | |
3465 | for(i=0;i<ndimsp;i++){ | |
3466 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3467 | if(status != NC_NOERR) NC_RAISE(status); | |
3468 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3469 | nc_tlen=lengthp*nc_tlen; | |
3470 | } | |
3471 | if(len == 1 && len != nc_tlen){ | |
3472 | scalar = *ptr; | |
3473 | ptr = ALLOCA_N(int,nc_tlen); | |
3474 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3475 | } else if(len != nc_tlen){ | |
3476 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3477 | status = nc_inq_varname(ncid,varid,var_name); | |
3478 | if(status != NC_NOERR) NC_RAISE(status); | |
3479 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3480 | } | |
3481 | ||
3482 | ||
3483 | status = nc_put_var_int(ncid,varid,ptr); | |
3484 | if(status !=NC_NOERR) NC_RAISE(status); | |
3485 | return Qnil; | |
3486 | } | |
3487 | ||
3488 | ||
3489 | VALUE | |
3490 | NetCDF_put_var_float(VALUE Var,VALUE NArray) | |
3491 | { | |
3492 | int ncid; | |
3493 | int varid; | |
3494 | int status; | |
3495 | float *ptr,scalar; | |
3496 | na_shape_t len,i=0; | |
3497 | struct NetCDFVar *Netcdf_var; | |
3498 | na_shape_t nc_tlen=1; | |
3499 | int ndimsp; | |
3500 | int dimids[NC_MAX_DIMS]; | |
3501 | size_t lengthp; | |
3502 | char *var_name; | |
3503 | ||
3504 | ||
3505 | rb_secure(3); | |
3506 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3507 | ncid=Netcdf_var->ncid; | |
3508 | varid=Netcdf_var->varid; | |
3509 | ||
3510 | Array_to_Cfloat_len(NArray,ptr,len); | |
3511 | ||
3512 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3513 | if(status != NC_NOERR) NC_RAISE(status); | |
3514 | for(i=0;i<ndimsp;i++){ | |
3515 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3516 | if(status != NC_NOERR) NC_RAISE(status); | |
3517 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3518 | nc_tlen=lengthp*nc_tlen; | |
3519 | } | |
3520 | if(len == 1 && len != nc_tlen){ | |
3521 | scalar = *ptr; | |
3522 | ptr = ALLOCA_N(float,nc_tlen); | |
3523 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3524 | } else if(len != nc_tlen){ | |
3525 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3526 | status = nc_inq_varname(ncid,varid,var_name); | |
3527 | if(status != NC_NOERR) NC_RAISE(status); | |
3528 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3529 | } | |
3530 | ||
3531 | status = nc_put_var_float(ncid,varid,ptr); | |
3532 | if(status !=NC_NOERR) NC_RAISE(status); | |
3533 | return Qnil; | |
3534 | } | |
3535 | ||
3536 | VALUE | |
3537 | NetCDF_put_var_double(VALUE Var,VALUE NArray) | |
3538 | { | |
3539 | int ncid; | |
3540 | int varid; | |
3541 | int status; | |
3542 | double *ptr,scalar; | |
3543 | na_shape_t len,i=0; | |
3544 | struct NetCDFVar *Netcdf_var; | |
3545 | na_shape_t nc_tlen=1; | |
3546 | int ndimsp; | |
3547 | int dimids[NC_MAX_DIMS]; | |
3548 | size_t lengthp; | |
3549 | char *var_name; | |
3550 | ||
3551 | ||
3552 | rb_secure(3); | |
3553 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3554 | ncid=Netcdf_var->ncid; | |
3555 | varid=Netcdf_var->varid; | |
3556 | ||
3557 | Array_to_Cdouble_len(NArray,ptr,len); | |
3558 | ||
3559 | status = nc_inq_varndims(ncid,varid,&ndimsp); | |
3560 | if(status != NC_NOERR) NC_RAISE(status); | |
3561 | for(i=0;i<ndimsp;i++){ | |
3562 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3563 | if(status != NC_NOERR) NC_RAISE(status); | |
3564 | nc_inq_dimlen(ncid,dimids[i],&lengthp); | |
3565 | nc_tlen=lengthp*nc_tlen; | |
3566 | } | |
3567 | if(len == 1 && len != nc_tlen){ | |
3568 | scalar = *ptr; | |
3569 | ptr = ALLOCA_N(double,nc_tlen); | |
3570 | for(i=0;i<nc_tlen;i++){ptr[i]=scalar;} | |
3571 | } else if(len != nc_tlen){ | |
3572 | var_name=ALLOCA_N(char,NC_MAX_NAME); | |
3573 | status = nc_inq_varname(ncid,varid,var_name); | |
3574 | if(status != NC_NOERR) NC_RAISE(status); | |
3575 | rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name); | |
3576 | } | |
3577 | ||
3578 | status = nc_put_var_double(ncid,varid,ptr); | |
3579 | if(status !=NC_NOERR) NC_RAISE(status); | |
3580 | return Qnil; | |
3581 | } | |
3582 | ||
3583 | VALUE | |
3584 | NetCDF_put_var1_char(VALUE Var,VALUE NArray,VALUE start) | |
3585 | { | |
3586 | int ncid; | |
3587 | int varid; | |
3588 | int status; | |
3589 | unsigned char *ptr; | |
3590 | int i; | |
3591 | struct NetCDFVar *Netcdf_var; | |
3592 | na_shape_t l_start; | |
3593 | size_t *c_start; | |
3594 | int ndims; | |
3595 | int *dimids; | |
3596 | size_t dimlen; | |
3597 | ||
3598 | rb_secure(3); | |
3599 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3600 | ncid=Netcdf_var->ncid; | |
3601 | varid=Netcdf_var->varid; | |
3602 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3603 | if(status != NC_NOERR) NC_RAISE(status); | |
3604 | ||
3605 | ||
3606 | dimids = ALLOCA_N(int,ndims); | |
3607 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3608 | if(status != NC_NOERR) NC_RAISE(status); | |
3609 | ||
3610 | Check_Type(start,T_ARRAY); | |
3611 | if(RARRAY_LEN(start) <ndims) { | |
3612 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3613 | } | |
3614 | ||
3615 | c_start=ALLOCA_N(size_t,ndims); | |
3616 | for(i=0;i<ndims;i++){ | |
3617 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3618 | ||
3619 | if(l_start < 0) { | |
3620 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3621 | if(status != NC_NOERR) NC_RAISE(status); | |
3622 | l_start += dimlen; | |
3623 | } | |
3624 | c_start[i]=l_start; | |
3625 | ||
3626 | } | |
3627 | Array_to_Cbyte(NArray,ptr); | |
3628 | ||
3629 | status = nc_put_var1_text(ncid,varid,c_start,(char *)ptr); | |
3630 | if(status != NC_NOERR) NC_RAISE(status); | |
3631 | return Qnil; | |
3632 | } | |
3633 | ||
3634 | VALUE | |
3635 | NetCDF_put_var1_byte(VALUE Var,VALUE NArray,VALUE start) | |
3636 | { | |
3637 | int ncid; | |
3638 | int varid; | |
3639 | int status; | |
3640 | unsigned char *ptr; | |
3641 | int i; | |
3642 | struct NetCDFVar *Netcdf_var; | |
3643 | na_shape_t l_start; | |
3644 | size_t *c_start; | |
3645 | int ndims; | |
3646 | int *dimids; | |
3647 | size_t dimlen; | |
3648 | ||
3649 | rb_secure(3); | |
3650 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3651 | ncid=Netcdf_var->ncid; | |
3652 | varid=Netcdf_var->varid; | |
3653 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3654 | if(status != NC_NOERR) NC_RAISE(status); | |
3655 | ||
3656 | ||
3657 | dimids = ALLOCA_N(int,ndims); | |
3658 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3659 | if(status != NC_NOERR) NC_RAISE(status); | |
3660 | ||
3661 | Check_Type(start,T_ARRAY); | |
3662 | if(RARRAY_LEN(start) <ndims) { | |
3663 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3664 | } | |
3665 | ||
3666 | c_start=ALLOCA_N(size_t,ndims); | |
3667 | for(i=0;i<ndims;i++){ | |
3668 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3669 | ||
3670 | if(l_start < 0) { | |
3671 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3672 | if(status != NC_NOERR) NC_RAISE(status); | |
3673 | l_start += dimlen; | |
3674 | } | |
3675 | c_start[i]=l_start; | |
3676 | ||
3677 | } | |
3678 | Array_to_Cbyte(NArray,ptr); | |
3679 | ||
3680 | status = nc_put_var1_uchar(ncid,varid,c_start,ptr); | |
3681 | if(status != NC_NOERR) NC_RAISE(status); | |
3682 | return Qnil; | |
3683 | } | |
3684 | ||
3685 | VALUE | |
3686 | NetCDF_put_var1_sint(VALUE Var,VALUE NArray,VALUE start) | |
3687 | { | |
3688 | int ncid; | |
3689 | int varid; | |
3690 | int status; | |
3691 | short *ptr; | |
3692 | int i; | |
3693 | struct NetCDFVar *Netcdf_var; | |
3694 | na_shape_t l_start; | |
3695 | size_t *c_start; | |
3696 | int ndims; | |
3697 | int *dimids; | |
3698 | size_t dimlen; | |
3699 | ||
3700 | rb_secure(3); | |
3701 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3702 | ncid=Netcdf_var->ncid; | |
3703 | varid=Netcdf_var->varid; | |
3704 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3705 | if(status != NC_NOERR) NC_RAISE(status); | |
3706 | ||
3707 | ||
3708 | dimids = ALLOCA_N(int,ndims); | |
3709 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3710 | if(status != NC_NOERR) NC_RAISE(status); | |
3711 | ||
3712 | Check_Type(start,T_ARRAY); | |
3713 | if(RARRAY_LEN(start) <ndims) { | |
3714 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3715 | } | |
3716 | ||
3717 | c_start=ALLOCA_N(size_t,ndims); | |
3718 | for(i=0;i<ndims;i++){ | |
3719 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3720 | ||
3721 | if(l_start < 0) { | |
3722 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3723 | if(status != NC_NOERR) NC_RAISE(status); | |
3724 | l_start += dimlen; | |
3725 | } | |
3726 | c_start[i]=l_start; | |
3727 | ||
3728 | } | |
3729 | Array_to_Csint(NArray,ptr); | |
3730 | ||
3731 | status = nc_put_var1_short(ncid,varid,c_start,ptr); | |
3732 | if(status != NC_NOERR) NC_RAISE(status); | |
3733 | return Qnil; | |
3734 | } | |
3735 | VALUE | |
3736 | NetCDF_put_var1_int(VALUE Var,VALUE NArray,VALUE start) | |
3737 | { | |
3738 | int ncid; | |
3739 | int varid; | |
3740 | int status; | |
3741 | int *ptr; | |
3742 | int i; | |
3743 | struct NetCDFVar *Netcdf_var; | |
3744 | na_shape_t l_start; | |
3745 | size_t *c_start; | |
3746 | int ndims; | |
3747 | int *dimids; | |
3748 | size_t dimlen; | |
3749 | ||
3750 | rb_secure(3); | |
3751 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3752 | ncid=Netcdf_var->ncid; | |
3753 | varid=Netcdf_var->varid; | |
3754 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3755 | if(status != NC_NOERR) NC_RAISE(status); | |
3756 | ||
3757 | ||
3758 | dimids = ALLOCA_N(int,ndims); | |
3759 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3760 | if(status != NC_NOERR) NC_RAISE(status); | |
3761 | ||
3762 | Check_Type(start,T_ARRAY); | |
3763 | if(RARRAY_LEN(start) <ndims) { | |
3764 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3765 | } | |
3766 | ||
3767 | c_start=ALLOCA_N(size_t,ndims); | |
3768 | for(i=0;i<ndims;i++){ | |
3769 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3770 | ||
3771 | if(l_start < 0) { | |
3772 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3773 | if(status != NC_NOERR) NC_RAISE(status); | |
3774 | l_start += dimlen; | |
3775 | } | |
3776 | c_start[i]=l_start; | |
3777 | ||
3778 | } | |
3779 | Array_to_Clint(NArray,ptr); | |
3780 | ||
3781 | status = nc_put_var1_int(ncid,varid,c_start,ptr); | |
3782 | if(status != NC_NOERR) NC_RAISE(status); | |
3783 | return Qnil; | |
3784 | } | |
3785 | ||
3786 | VALUE | |
3787 | NetCDF_put_var1_float(VALUE Var,VALUE NArray,VALUE start) | |
3788 | { | |
3789 | int ncid; | |
3790 | int varid; | |
3791 | int status; | |
3792 | float *ptr; | |
3793 | int i; | |
3794 | struct NetCDFVar *Netcdf_var; | |
3795 | na_shape_t l_start; | |
3796 | size_t *c_start; | |
3797 | int ndims; | |
3798 | int *dimids; | |
3799 | size_t dimlen; | |
3800 | ||
3801 | rb_secure(3); | |
3802 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3803 | ncid=Netcdf_var->ncid; | |
3804 | varid=Netcdf_var->varid; | |
3805 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3806 | if(status != NC_NOERR) NC_RAISE(status); | |
3807 | ||
3808 | ||
3809 | dimids = ALLOCA_N(int,ndims); | |
3810 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3811 | if(status != NC_NOERR) NC_RAISE(status); | |
3812 | ||
3813 | Check_Type(start,T_ARRAY); | |
3814 | if(RARRAY_LEN(start) <ndims) { | |
3815 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3816 | } | |
3817 | ||
3818 | c_start=ALLOCA_N(size_t,ndims); | |
3819 | for(i=0;i<ndims;i++){ | |
3820 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3821 | ||
3822 | if(l_start < 0) { | |
3823 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3824 | if(status != NC_NOERR) NC_RAISE(status); | |
3825 | l_start += dimlen; | |
3826 | } | |
3827 | c_start[i]=l_start; | |
3828 | ||
3829 | } | |
3830 | Array_to_Cfloat(NArray,ptr); | |
3831 | ||
3832 | status = nc_put_var1_float(ncid,varid,c_start,ptr); | |
3833 | if(status != NC_NOERR) NC_RAISE(status); | |
3834 | return Qnil; | |
3835 | } | |
3836 | ||
3837 | VALUE | |
3838 | NetCDF_put_var1_double(VALUE Var,VALUE NArray,VALUE start) | |
3839 | { | |
3840 | int ncid; | |
3841 | int varid; | |
3842 | int status; | |
3843 | double *ptr; | |
3844 | int i; | |
3845 | struct NetCDFVar *Netcdf_var; | |
3846 | na_shape_t l_start; | |
3847 | size_t *c_start; | |
3848 | int ndims; | |
3849 | int *dimids; | |
3850 | size_t dimlen; | |
3851 | ||
3852 | rb_secure(3); | |
3853 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3854 | ncid=Netcdf_var->ncid; | |
3855 | varid=Netcdf_var->varid; | |
3856 | status = nc_inq_varndims(ncid,varid,&ndims); | |
3857 | if(status != NC_NOERR) NC_RAISE(status); | |
3858 | ||
3859 | ||
3860 | dimids = ALLOCA_N(int,ndims); | |
3861 | status = nc_inq_vardimid(ncid,varid,dimids); | |
3862 | if(status != NC_NOERR) NC_RAISE(status); | |
3863 | ||
3864 | Check_Type(start,T_ARRAY); | |
3865 | if(RARRAY_LEN(start) <ndims) { | |
3866 | rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n"); | |
3867 | } | |
3868 | ||
3869 | c_start=ALLOCA_N(size_t,ndims); | |
3870 | for(i=0;i<ndims;i++){ | |
3871 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3872 | ||
3873 | if(l_start < 0) { | |
3874 | status = nc_inq_dimlen(ncid,dimids[i],&dimlen); | |
3875 | if(status != NC_NOERR) NC_RAISE(status); | |
3876 | l_start += dimlen; | |
3877 | } | |
3878 | c_start[i]=l_start; | |
3879 | ||
3880 | } | |
3881 | Array_to_Cdouble(NArray,ptr); | |
3882 | ||
3883 | status = nc_put_var1_double(ncid,varid,c_start,ptr); | |
3884 | if(status != NC_NOERR) NC_RAISE(status); | |
3885 | return Qnil; | |
3886 | } | |
3887 | ||
3888 | ||
3889 | VALUE | |
3890 | NetCDF_put_vars_char(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
3891 | { | |
3892 | int ncid; | |
3893 | int varid; | |
3894 | int status; | |
3895 | unsigned char *ptr,scalar; | |
3896 | na_shape_t len; | |
3897 | int c_count_all=1; | |
3898 | struct NetCDFVar *Netcdf_var; | |
3899 | na_shape_t l_start, l_end; | |
3900 | size_t *c_start; | |
3901 | size_t *c_count; | |
3902 | ptrdiff_t *c_stride; | |
3903 | int ndims,i; | |
3904 | na_shape_t *shape; | |
3905 | int *dimids; | |
3906 | size_t dimlen; | |
3907 | ||
3908 | rb_secure(3); | |
3909 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
3910 | ncid=Netcdf_var->ncid; | |
3911 | varid=Netcdf_var->varid; | |
3912 | status = nc_inq_varndims(ncid, varid, &ndims); | |
3913 | if(status != NC_NOERR) NC_RAISE(status); | |
3914 | ||
3915 | dimids=ALLOCA_N(int,ndims); | |
3916 | status = nc_inq_vardimid(ncid, varid, dimids); | |
3917 | if(status != NC_NOERR) NC_RAISE(status); | |
3918 | ||
3919 | Check_Type(start,T_ARRAY); | |
3920 | if(RARRAY_LEN(start) < ndims) { | |
3921 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
3922 | } | |
3923 | c_start=ALLOCA_N(size_t,ndims); | |
3924 | for(i=0; i<ndims; i++){ | |
3925 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
3926 | ||
3927 | if(l_start < 0) { | |
3928 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3929 | if(status != NC_NOERR) NC_RAISE(status); | |
3930 | l_start += dimlen; | |
3931 | } | |
3932 | c_start[i]=l_start; | |
3933 | } | |
3934 | ||
3935 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
3936 | switch(TYPE(stride)){ | |
3937 | case T_NIL: | |
3938 | for(i=0; i<ndims; i++){ | |
3939 | c_stride[i]=1; | |
3940 | } | |
3941 | break; | |
3942 | default: | |
3943 | Check_Type(stride,T_ARRAY); | |
3944 | if(RARRAY_LEN(stride) < ndims) { | |
3945 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
3946 | } | |
3947 | for(i=0; i<ndims; i++){ | |
3948 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
3949 | if(c_stride[i]==0) { | |
3950 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
3951 | } | |
3952 | } | |
3953 | } | |
3954 | ||
3955 | Array_to_Cbyte_len_shape(NArray,ptr,len,shape); | |
3956 | ||
3957 | c_count=ALLOCA_N(size_t,ndims); | |
3958 | switch(TYPE(end)){ | |
3959 | case T_NIL: | |
3960 | for(i=0; i<ndims; i++){ | |
3961 | c_count[i]=shape[i]; | |
3962 | } | |
3963 | c_count_all=len; | |
3964 | break; | |
3965 | default: | |
3966 | Check_Type(end,T_ARRAY); | |
3967 | if(RARRAY_LEN(end) < ndims) { | |
3968 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
3969 | } | |
3970 | for(i=0; i<ndims; i++){ | |
3971 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
3972 | if(l_end < 0) { | |
3973 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
3974 | if(status != NC_NOERR) NC_RAISE(status); | |
3975 | l_end += dimlen; | |
3976 | } | |
3977 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
3978 | c_count_all=c_count[i]*c_count_all; | |
3979 | } | |
3980 | if(len == 1 && len != c_count_all){ | |
3981 | scalar = *ptr; | |
3982 | ptr = ALLOCA_N(unsigned char,c_count_all); | |
3983 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
3984 | } else if(len != c_count_all) { | |
3985 | rb_raise(rb_eNetcdfError, | |
3986 | "lengh of the array does not agree with that of the subset\n"); | |
3987 | } | |
3988 | } | |
3989 | ||
3990 | status = nc_put_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr); | |
3991 | if(status != NC_NOERR) NC_RAISE(status); | |
3992 | return Qnil; | |
3993 | } | |
3994 | ||
3995 | VALUE | |
3996 | NetCDF_put_vars_byte(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
3997 | { | |
3998 | int ncid; | |
3999 | int varid; | |
4000 | int status; | |
4001 | unsigned char *ptr,scalar; | |
4002 | na_shape_t len; | |
4003 | int c_count_all=1; | |
4004 | struct NetCDFVar *Netcdf_var; | |
4005 | na_shape_t l_start, l_end; | |
4006 | size_t *c_start; | |
4007 | size_t *c_count; | |
4008 | ptrdiff_t *c_stride; | |
4009 | int ndims,i; | |
4010 | na_shape_t *shape; | |
4011 | int *dimids; | |
4012 | size_t dimlen; | |
4013 | ||
4014 | rb_secure(3); | |
4015 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4016 | ncid=Netcdf_var->ncid; | |
4017 | varid=Netcdf_var->varid; | |
4018 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4019 | if(status != NC_NOERR) NC_RAISE(status); | |
4020 | ||
4021 | dimids=ALLOCA_N(int,ndims); | |
4022 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4023 | if(status != NC_NOERR) NC_RAISE(status); | |
4024 | ||
4025 | Check_Type(start,T_ARRAY); | |
4026 | if(RARRAY_LEN(start) < ndims) { | |
4027 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4028 | } | |
4029 | c_start=ALLOCA_N(size_t,ndims); | |
4030 | for(i=0; i<ndims; i++){ | |
4031 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4032 | ||
4033 | if(l_start < 0) { | |
4034 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4035 | if(status != NC_NOERR) NC_RAISE(status); | |
4036 | l_start += dimlen; | |
4037 | } | |
4038 | c_start[i]=l_start; | |
4039 | } | |
4040 | ||
4041 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4042 | switch(TYPE(stride)){ | |
4043 | case T_NIL: | |
4044 | for(i=0; i<ndims; i++){ | |
4045 | c_stride[i]=1; | |
4046 | } | |
4047 | break; | |
4048 | default: | |
4049 | Check_Type(stride,T_ARRAY); | |
4050 | if(RARRAY_LEN(stride) < ndims) { | |
4051 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4052 | } | |
4053 | for(i=0; i<ndims; i++){ | |
4054 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4055 | if(c_stride[i]==0) { | |
4056 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4057 | } | |
4058 | } | |
4059 | } | |
4060 | ||
4061 | Array_to_Cbyte_len_shape(NArray,ptr,len,shape); | |
4062 | ||
4063 | c_count=ALLOCA_N(size_t,ndims); | |
4064 | switch(TYPE(end)){ | |
4065 | case T_NIL: | |
4066 | for(i=0; i<ndims; i++){ | |
4067 | c_count[i]=shape[i]; | |
4068 | } | |
4069 | c_count_all=len; | |
4070 | break; | |
4071 | default: | |
4072 | Check_Type(end,T_ARRAY); | |
4073 | if(RARRAY_LEN(end) < ndims) { | |
4074 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4075 | } | |
4076 | for(i=0; i<ndims; i++){ | |
4077 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4078 | if(l_end < 0) { | |
4079 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4080 | if(status != NC_NOERR) NC_RAISE(status); | |
4081 | l_end += dimlen; | |
4082 | } | |
4083 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4084 | c_count_all=c_count[i]*c_count_all; | |
4085 | } | |
4086 | if(len == 1 && len != c_count_all){ | |
4087 | scalar = *ptr; | |
4088 | ptr = ALLOCA_N(unsigned char,c_count_all); | |
4089 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4090 | } else if(len != c_count_all) { | |
4091 | rb_raise(rb_eNetcdfError, | |
4092 | "lengh of the array does not agree with that of the subset\n"); | |
4093 | } | |
4094 | } | |
4095 | ||
4096 | status = nc_put_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr); | |
4097 | if(status != NC_NOERR) NC_RAISE(status); | |
4098 | return Qnil; | |
4099 | } | |
4100 | ||
4101 | VALUE | |
4102 | NetCDF_put_vars_sint(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4103 | { | |
4104 | int ncid; | |
4105 | int varid; | |
4106 | int status; | |
4107 | short *ptr,scalar; | |
4108 | na_shape_t len; | |
4109 | int c_count_all=1; | |
4110 | struct NetCDFVar *Netcdf_var; | |
4111 | na_shape_t l_start, l_end; | |
4112 | size_t *c_start; | |
4113 | size_t *c_count; | |
4114 | ptrdiff_t *c_stride; | |
4115 | int ndims,i; | |
4116 | na_shape_t *shape; | |
4117 | int *dimids; | |
4118 | size_t dimlen; | |
4119 | ||
4120 | rb_secure(3); | |
4121 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4122 | ncid=Netcdf_var->ncid; | |
4123 | varid=Netcdf_var->varid; | |
4124 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4125 | if(status != NC_NOERR) NC_RAISE(status); | |
4126 | ||
4127 | dimids=ALLOCA_N(int,ndims); | |
4128 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4129 | if(status != NC_NOERR) NC_RAISE(status); | |
4130 | ||
4131 | Check_Type(start,T_ARRAY); | |
4132 | if(RARRAY_LEN(start) < ndims) { | |
4133 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4134 | } | |
4135 | c_start=ALLOCA_N(size_t,ndims); | |
4136 | for(i=0; i<ndims; i++){ | |
4137 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4138 | ||
4139 | if(l_start < 0) { | |
4140 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4141 | if(status != NC_NOERR) NC_RAISE(status); | |
4142 | l_start += dimlen; | |
4143 | } | |
4144 | c_start[i]=l_start; | |
4145 | } | |
4146 | ||
4147 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4148 | switch(TYPE(stride)){ | |
4149 | case T_NIL: | |
4150 | for(i=0; i<ndims; i++){ | |
4151 | c_stride[i]=1; | |
4152 | } | |
4153 | break; | |
4154 | default: | |
4155 | Check_Type(stride,T_ARRAY); | |
4156 | if(RARRAY_LEN(stride) < ndims) { | |
4157 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4158 | } | |
4159 | for(i=0; i<ndims; i++){ | |
4160 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4161 | if(c_stride[i]==0) { | |
4162 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4163 | } | |
4164 | } | |
4165 | } | |
4166 | ||
4167 | Array_to_Csint_len_shape(NArray,ptr,len,shape); | |
4168 | ||
4169 | c_count=ALLOCA_N(size_t,ndims); | |
4170 | switch(TYPE(end)){ | |
4171 | case T_NIL: | |
4172 | for(i=0; i<ndims; i++){ | |
4173 | c_count[i]=shape[i]; | |
4174 | } | |
4175 | c_count_all=len; | |
4176 | break; | |
4177 | default: | |
4178 | Check_Type(end,T_ARRAY); | |
4179 | if(RARRAY_LEN(end) < ndims) { | |
4180 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4181 | } | |
4182 | for(i=0; i<ndims; i++){ | |
4183 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4184 | if(l_end < 0) { | |
4185 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4186 | if(status != NC_NOERR) NC_RAISE(status); | |
4187 | l_end += dimlen; | |
4188 | } | |
4189 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4190 | c_count_all=c_count[i]*c_count_all; | |
4191 | } | |
4192 | if(len == 1 && len != c_count_all){ | |
4193 | scalar = *ptr; | |
4194 | ptr = ALLOCA_N(short,c_count_all); | |
4195 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4196 | } else if(len != c_count_all) { | |
4197 | rb_raise(rb_eNetcdfError, | |
4198 | "lengh of the array does not agree with that of the subset\n"); | |
4199 | } | |
4200 | } | |
4201 | ||
4202 | status = nc_put_vars_short(ncid,varid,c_start,c_count,c_stride,ptr); | |
4203 | if(status != NC_NOERR) NC_RAISE(status); | |
4204 | return Qnil; | |
4205 | } | |
4206 | ||
4207 | ||
4208 | VALUE | |
4209 | NetCDF_put_vars_int(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4210 | { | |
4211 | int ncid; | |
4212 | int varid; | |
4213 | int status; | |
4214 | int *ptr,scalar; | |
4215 | na_shape_t len; | |
4216 | int c_count_all=1; | |
4217 | struct NetCDFVar *Netcdf_var; | |
4218 | na_shape_t l_start, l_end; | |
4219 | size_t *c_start; | |
4220 | size_t *c_count; | |
4221 | ptrdiff_t *c_stride; | |
4222 | int ndims,i; | |
4223 | na_shape_t *shape; | |
4224 | int *dimids; | |
4225 | size_t dimlen; | |
4226 | ||
4227 | rb_secure(3); | |
4228 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4229 | ncid=Netcdf_var->ncid; | |
4230 | varid=Netcdf_var->varid; | |
4231 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4232 | if(status != NC_NOERR) NC_RAISE(status); | |
4233 | ||
4234 | dimids=ALLOCA_N(int,ndims); | |
4235 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4236 | if(status != NC_NOERR) NC_RAISE(status); | |
4237 | ||
4238 | Check_Type(start,T_ARRAY); | |
4239 | if(RARRAY_LEN(start) < ndims) { | |
4240 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4241 | } | |
4242 | c_start=ALLOCA_N(size_t,ndims); | |
4243 | for(i=0; i<ndims; i++){ | |
4244 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4245 | ||
4246 | if(l_start < 0) { | |
4247 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4248 | if(status != NC_NOERR) NC_RAISE(status); | |
4249 | l_start += dimlen; | |
4250 | } | |
4251 | c_start[i]=l_start; | |
4252 | } | |
4253 | ||
4254 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4255 | switch(TYPE(stride)){ | |
4256 | case T_NIL: | |
4257 | for(i=0; i<ndims; i++){ | |
4258 | c_stride[i]=1; | |
4259 | } | |
4260 | break; | |
4261 | default: | |
4262 | Check_Type(stride,T_ARRAY); | |
4263 | if(RARRAY_LEN(stride) < ndims) { | |
4264 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4265 | } | |
4266 | for(i=0; i<ndims; i++){ | |
4267 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4268 | if(c_stride[i]==0) { | |
4269 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4270 | } | |
4271 | } | |
4272 | } | |
4273 | ||
4274 | Array_to_Clint_len_shape(NArray,ptr,len,shape); | |
4275 | ||
4276 | c_count=ALLOCA_N(size_t,ndims); | |
4277 | switch(TYPE(end)){ | |
4278 | case T_NIL: | |
4279 | for(i=0; i<ndims; i++){ | |
4280 | c_count[i]=shape[i]; | |
4281 | } | |
4282 | c_count_all=len; | |
4283 | break; | |
4284 | default: | |
4285 | Check_Type(end,T_ARRAY); | |
4286 | if(RARRAY_LEN(end) < ndims) { | |
4287 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4288 | } | |
4289 | for(i=0; i<ndims; i++){ | |
4290 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4291 | if(l_end < 0) { | |
4292 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4293 | if(status != NC_NOERR) NC_RAISE(status); | |
4294 | l_end += dimlen; | |
4295 | } | |
4296 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4297 | c_count_all=c_count[i]*c_count_all; | |
4298 | } | |
4299 | if(len == 1 && len != c_count_all){ | |
4300 | scalar = *ptr; | |
4301 | ptr = ALLOCA_N(int,c_count_all); | |
4302 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4303 | } else if(len != c_count_all) { | |
4304 | rb_raise(rb_eNetcdfError, | |
4305 | "length of the array does not agree with that of the subset\n"); | |
4306 | } | |
4307 | } | |
4308 | ||
4309 | status = nc_put_vars_int(ncid,varid,c_start,c_count,c_stride,ptr); | |
4310 | if(status != NC_NOERR) NC_RAISE(status); | |
4311 | return Qnil; | |
4312 | } | |
4313 | ||
4314 | ||
4315 | VALUE | |
4316 | NetCDF_put_vars_float(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4317 | { | |
4318 | int ncid; | |
4319 | int varid; | |
4320 | int status; | |
4321 | float *ptr,scalar; | |
4322 | na_shape_t len; | |
4323 | int c_count_all=1; | |
4324 | struct NetCDFVar *Netcdf_var; | |
4325 | na_shape_t l_start, l_end; | |
4326 | size_t *c_start; | |
4327 | size_t *c_count; | |
4328 | ptrdiff_t *c_stride; | |
4329 | int ndims,i; | |
4330 | na_shape_t *shape; | |
4331 | int *dimids; | |
4332 | size_t dimlen; | |
4333 | ||
4334 | rb_secure(3); | |
4335 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4336 | ncid=Netcdf_var->ncid; | |
4337 | varid=Netcdf_var->varid; | |
4338 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4339 | if(status != NC_NOERR) NC_RAISE(status); | |
4340 | ||
4341 | dimids=ALLOCA_N(int,ndims); | |
4342 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4343 | if(status != NC_NOERR) NC_RAISE(status); | |
4344 | ||
4345 | Check_Type(start,T_ARRAY); | |
4346 | if(RARRAY_LEN(start) < ndims) { | |
4347 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4348 | } | |
4349 | c_start=ALLOCA_N(size_t,ndims); | |
4350 | for(i=0; i<ndims; i++){ | |
4351 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4352 | ||
4353 | if(l_start < 0) { | |
4354 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4355 | if(status != NC_NOERR) NC_RAISE(status); | |
4356 | l_start += dimlen; | |
4357 | } | |
4358 | c_start[i]=l_start; | |
4359 | } | |
4360 | ||
4361 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4362 | switch(TYPE(stride)){ | |
4363 | case T_NIL: | |
4364 | for(i=0; i<ndims; i++){ | |
4365 | c_stride[i]=1; | |
4366 | } | |
4367 | break; | |
4368 | default: | |
4369 | Check_Type(stride,T_ARRAY); | |
4370 | if(RARRAY_LEN(stride) < ndims) { | |
4371 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4372 | } | |
4373 | for(i=0; i<ndims; i++){ | |
4374 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4375 | if(c_stride[i]==0) { | |
4376 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4377 | } | |
4378 | } | |
4379 | } | |
4380 | ||
4381 | Array_to_Cfloat_len_shape(NArray,ptr,len,shape); | |
4382 | ||
4383 | c_count=ALLOCA_N(size_t,ndims); | |
4384 | switch(TYPE(end)){ | |
4385 | case T_NIL: | |
4386 | for(i=0; i<ndims; i++){ | |
4387 | c_count[i]=shape[i]; | |
4388 | } | |
4389 | c_count_all=len; | |
4390 | break; | |
4391 | default: | |
4392 | Check_Type(end,T_ARRAY); | |
4393 | if(RARRAY_LEN(end) < ndims) { | |
4394 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4395 | } | |
4396 | for(i=0; i<ndims; i++){ | |
4397 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4398 | if(l_end < 0) { | |
4399 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4400 | if(status != NC_NOERR) NC_RAISE(status); | |
4401 | l_end += dimlen; | |
4402 | } | |
4403 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4404 | c_count_all=c_count[i]*c_count_all; | |
4405 | } | |
4406 | if(len == 1 && len != c_count_all){ | |
4407 | scalar = *ptr; | |
4408 | ptr = ALLOCA_N(float,c_count_all); | |
4409 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4410 | } else if(len != c_count_all) { | |
4411 | rb_raise(rb_eNetcdfError, | |
4412 | "lengh of the array does not agree with that of the subset\n"); | |
4413 | } | |
4414 | } | |
4415 | ||
4416 | status = nc_put_vars_float(ncid,varid,c_start,c_count,c_stride,ptr); | |
4417 | if(status != NC_NOERR) NC_RAISE(status); | |
4418 | return Qnil; | |
4419 | } | |
4420 | ||
4421 | ||
4422 | VALUE | |
4423 | NetCDF_put_vars_double(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride) | |
4424 | { | |
4425 | int ncid; | |
4426 | int varid; | |
4427 | int status; | |
4428 | double *ptr,scalar; | |
4429 | na_shape_t len; | |
4430 | int c_count_all=1; | |
4431 | struct NetCDFVar *Netcdf_var; | |
4432 | na_shape_t l_start, l_end; | |
4433 | size_t *c_start; | |
4434 | size_t *c_count; | |
4435 | ptrdiff_t *c_stride; | |
4436 | int ndims,i; | |
4437 | na_shape_t *shape; | |
4438 | int *dimids; | |
4439 | size_t dimlen; | |
4440 | ||
4441 | rb_secure(3); | |
4442 | Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var); | |
4443 | ncid=Netcdf_var->ncid; | |
4444 | varid=Netcdf_var->varid; | |
4445 | status = nc_inq_varndims(ncid, varid, &ndims); | |
4446 | if(status != NC_NOERR) NC_RAISE(status); | |
4447 | ||
4448 | dimids=ALLOCA_N(int,ndims); | |
4449 | status = nc_inq_vardimid(ncid, varid, dimids); | |
4450 | if(status != NC_NOERR) NC_RAISE(status); | |
4451 | ||
4452 | Check_Type(start,T_ARRAY); | |
4453 | if(RARRAY_LEN(start) < ndims) { | |
4454 | rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n"); | |
4455 | } | |
4456 | c_start=ALLOCA_N(size_t,ndims); | |
4457 | for(i=0; i<ndims; i++){ | |
4458 | l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]); | |
4459 | ||
4460 | if(l_start < 0) { | |
4461 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4462 | if(status != NC_NOERR) NC_RAISE(status); | |
4463 | l_start += dimlen; | |
4464 | } | |
4465 | c_start[i]=l_start; | |
4466 | } | |
4467 | ||
4468 | c_stride=ALLOCA_N(ptrdiff_t,ndims); | |
4469 | switch(TYPE(stride)){ | |
4470 | case T_NIL: | |
4471 | for(i=0; i<ndims; i++){ | |
4472 | c_stride[i]=1; | |
4473 | } | |
4474 | break; | |
4475 | default: | |
4476 | Check_Type(stride,T_ARRAY); | |
4477 | if(RARRAY_LEN(stride) < ndims) { | |
4478 | rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n"); | |
4479 | } | |
4480 | for(i=0; i<ndims; i++){ | |
4481 | c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]); | |
4482 | if(c_stride[i]==0) { | |
4483 | rb_raise(rb_eNetcdfError, "stride cannot be zero\n"); | |
4484 | } | |
4485 | } | |
4486 | } | |
4487 | ||
4488 | Array_to_Cdouble_len_shape(NArray,ptr,len,shape); | |
4489 | ||
4490 | c_count=ALLOCA_N(size_t,ndims); | |
4491 | switch(TYPE(end)){ | |
4492 | case T_NIL: | |
4493 | for(i=0; i<ndims; i++){ | |
4494 | c_count[i]=shape[i]; | |
4495 | } | |
4496 | c_count_all=len; | |
4497 | break; | |
4498 | default: | |
4499 | Check_Type(end,T_ARRAY); | |
4500 | if(RARRAY_LEN(end) < ndims) { | |
4501 | rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n"); | |
4502 | } | |
4503 | for(i=0; i<ndims; i++){ | |
4504 | l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]); | |
4505 | if(l_end < 0) { | |
4506 | status = nc_inq_dimlen(ncid, dimids[i], &dimlen); | |
4507 | if(status != NC_NOERR) NC_RAISE(status); | |
4508 | l_end += dimlen; | |
4509 | } | |
4510 | c_count[i]=(l_end-c_start[i])/c_stride[i]+1; | |
4511 | c_count_all=c_count[i]*c_count_all; | |
4512 | } | |
4513 | if(len == 1 && len != c_count_all){ | |
4514 | scalar = *ptr; | |
4515 | ptr = ALLOCA_N(double,c_count_all); | |
4516 | for(i=0;i<c_count_all;i++){ptr[i]=scalar;} | |
4517 | } else if(len != c_count_all) { | |
4518 | rb_raise(rb_eNetcdfError, | |
4519 | "lengh of the array does not agree with that of the subset\n"); | |
4520 | } | |
4521 | } | |
4522 | ||
4523 | status = nc_put_vars_double(ncid,varid,c_start,c_count,c_stride,ptr); | |
4524 | if(status != NC_NOERR) NC_RAISE(status); | |
4525 | return Qnil; | |
4526 | } | |
4527 | ||
4528 | void | |
4529 | Init_netcdfraw(void) | |
4530 | { | |
4531 | mNumRu = rb_define_module("NumRu"); | |
4532 | ||
4533 | /* Difinitions of the classes */ | |
4534 | cNetCDF = rb_define_class_under(mNumRu, "NetCDF", rb_cObject); | |
4535 | cNetCDFDim = rb_define_class_under(mNumRu, "NetCDFDim", rb_cObject); | |
4536 | cNetCDFAtt = rb_define_class_under(mNumRu, "NetCDFAtt", rb_cObject); | |
4537 | cNetCDFVar = rb_define_class_under(mNumRu, "NetCDFVar", rb_cObject); | |
4538 | ||
4539 | rb_eNetcdfError = rb_define_class("NetcdfError",rb_eStandardError); | |
4540 | rb_eNetcdfBadid = rb_define_class("NetcdfBadid",rb_eNetcdfError); | |
4541 | rb_eNetcdfNfile = rb_define_class("NetcdfNfile",rb_eNetcdfError); | |
4542 | rb_eNetcdfExist = rb_define_class("NetcdfExist",rb_eNetcdfError); | |
4543 | rb_eNetcdfInval = rb_define_class("NetcdfInval",rb_eNetcdfError); | |
4544 | rb_eNetcdfPerm = rb_define_class("NetcdfPerm",rb_eNetcdfError); | |
4545 | rb_eNetcdfNotindefine = rb_define_class("NetcdfNotindefine",rb_eNetcdfError); | |
4546 | rb_eNetcdfIndefine = rb_define_class("NetcdfIndefine",rb_eNetcdfError); | |
4547 | rb_eNetcdfInvalcoords = rb_define_class("NetcdfInvalcoords",rb_eNetcdfError); | |
4548 | rb_eNetcdfMaxdims = rb_define_class("NetcdfMaxdims",rb_eNetcdfError); | |
4549 | rb_eNetcdfNameinuse = rb_define_class("NetcdfNameinuse",rb_eNetcdfError); | |
4550 | rb_eNetcdfNotatt = rb_define_class("NetcdfNotatt",rb_eNetcdfError); | |
4551 | rb_eNetcdfMaxatts = rb_define_class("NetcdfMaxatts",rb_eNetcdfError); | |
4552 | rb_eNetcdfBadtype = rb_define_class("NetcdfBadtype",rb_eNetcdfError); | |
4553 | rb_eNetcdfBaddim = rb_define_class("NetcdfBaddim",rb_eNetcdfError); | |
4554 | rb_eNetcdfUnlimpos = rb_define_class("NetcdFUnlimpos",rb_eNetcdfError); | |
4555 | rb_eNetcdfMaxvars = rb_define_class("NetcdfMaxvars",rb_eNetcdfError); | |
4556 | rb_eNetcdfNotvar = rb_define_class("NetcdfNotvar",rb_eNetcdfError); | |
4557 | rb_eNetcdfGlobal = rb_define_class("NetcdfGlobal",rb_eNetcdfError); | |
4558 | rb_eNetcdfNotnc = rb_define_class("NetcdfNotnc",rb_eNetcdfError); | |
4559 | rb_eNetcdfSts = rb_define_class("NetcdfSts",rb_eNetcdfError); | |
4560 | rb_eNetcdfMaxname = rb_define_class("NetcdfMaxname",rb_eNetcdfError); | |
4561 | rb_eNetcdfUnlimit = rb_define_class("NetcdfUnlimit",rb_eNetcdfError); | |
4562 | rb_eNetcdfNorecvars = rb_define_class("NetcdfNorecvars",rb_eNetcdfError); | |
4563 | rb_eNetcdfChar = rb_define_class("NetcdfChar",rb_eNetcdfError); | |
4564 | rb_eNetcdfEdge = rb_define_class("NetcdfEdge",rb_eNetcdfError); | |
4565 | rb_eNetcdfStride = rb_define_class("NetcdfStride",rb_eNetcdfError); | |
4566 | rb_eNetcdfBadname = rb_define_class("NetcdfBadname",rb_eNetcdfError); | |
4567 | /* N.B. following must match value in ncx.h */ | |
4568 | rb_eNetcdfRange = rb_define_class("NetcdfRange",rb_eNetcdfError); | |
4569 | rb_eNetcdfNomem = rb_define_class("NetcdfNomem",rb_eNetcdfError); | |
4570 | /* Global error status */ | |
4571 | rb_eNetcdfEntool = rb_define_class("NetcdfEntool",rb_eNetcdfError); | |
4572 | rb_eNetcdfExdr = rb_define_class("NetcdfExdr",rb_eNetcdfError); | |
4573 | rb_eNetcdfSyserr = rb_define_class("NetcdfSyserr",rb_eNetcdfError); | |
4574 | /* Global options variable. Used to determine behavior of error handler. */ | |
4575 | rb_eNetcdfFatal = rb_define_class("NetcdfFatal",rb_eNetcdfError); | |
4576 | ||
4577 | /* Class Constants Definition */ | |
4578 | rb_define_const(cNetCDF, "NC_NOWRITE", INT2FIX(NC_NOWRITE)); | |
4579 | rb_define_const(cNetCDF, "NC_WRITE", INT2FIX(NC_WRITE)); | |
4580 | rb_define_const(cNetCDF, "NC_SHARE", INT2FIX(NC_SHARE)); | |
4581 | rb_define_const(cNetCDF, "NC_CLOBBER", INT2FIX(NC_CLOBBER)); | |
4582 | rb_define_const(cNetCDF, "NC_NOCLOBBER", INT2FIX(NC_NOCLOBBER)); | |
4583 | #if NCVER >= 400 | |
4584 | rb_define_const(cNetCDF, "NC_64BIT_OFFSET", INT2FIX(NC_64BIT_OFFSET)); | |
4585 | /* NC_64BIT_OFFSET supports large files in the class data format */ | |
4586 | rb_define_const(cNetCDF, "NC_NETCDF4", INT2FIX(NC_NETCDF4)); | |
4587 | rb_define_const(cNetCDF, "NC_CLASSIC_MODEL", INT2FIX(NC_CLASSIC_MODEL)); | |
4588 | /* for use as ( NC_NETCDF4 | NC_CLASSIC_MODEL ) to ensure the classic | |
4589 | data model in NetCDF4 by disabling new features like groups */ | |
4590 | rb_define_const(cNetCDF, "NC_ENDIAN_NATIVE", INT2FIX(NC_ENDIAN_NATIVE)); | |
4591 | rb_define_const(cNetCDF, "NC_ENDIAN_LITTLE", INT2FIX(NC_ENDIAN_LITTLE)); | |
4592 | rb_define_const(cNetCDF, "NC_ENDIAN_BIG", INT2FIX(NC_ENDIAN_BIG)); | |
4593 | #endif | |
4594 | ||
4595 | #ifdef NARRAY_BIGMEM | |
4596 | rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qtrue); | |
4597 | #else | |
4598 | rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qfalse); | |
4599 | #endif | |
4600 | ||
4601 | /* Difinitions of the ruby methods */ | |
4602 | /* The methods of the NetCDF class */ | |
4603 | rb_define_singleton_method(cNetCDF,"libvers",NetCDF_inq_libvers,0); | |
4604 | rb_define_singleton_method(cNetCDF,"nc_open",NetCDF_open,2); | |
4605 | rb_define_method(cNetCDF,"clone",NetCDF_clone,0); | |
4606 | rb_define_method(cNetCDF,"close",NetCDF_close,0); | |
4607 | /* rb_define_singleton_method(cNetCDF,"new",NetCDF_open,2); */ | |
4608 | rb_define_singleton_method(cNetCDF,"nc_create",NetCDF_create,2); | |
4609 | rb_define_method(cNetCDF,"def_dim",NetCDF_def_dim,2); | |
4610 | rb_define_method(cNetCDF,"def_var",NetCDF_def_var,3); | |
4611 | rb_define_method(cNetCDF,"put_attraw",NetCDF_put_att,3); | |
4612 | rb_define_method(cNetCDF,"redef",NetCDF_redef,0); | |
4613 | rb_define_method(cNetCDF,"enddef",NetCDF_enddef,0); | |
4614 | rb_define_method(cNetCDF,"define_mode?",NetCDF_whether_in_define_mode,0); | |
4615 | rb_define_method(cNetCDF,"fill",NetCDF_fill,1); | |
4616 | rb_define_method(cNetCDF,"ndims",NetCDF_ndims,0); | |
4617 | rb_define_method(cNetCDF,"nvars",NetCDF_nvars,0); | |
4618 | rb_define_method(cNetCDF,"natts",NetCDF_natts,0); | |
4619 | rb_define_method(cNetCDF,"sync",NetCDF_sync,0); | |
4620 | rb_define_method(cNetCDF,"path",NetCDF_path,0); | |
4621 | rb_define_method(cNetCDF,"dim",NetCDF_dim,1); | |
4622 | rb_define_method(cNetCDF,"var",NetCDF_var,1); | |
4623 | rb_define_method(cNetCDF,"att",NetCDF_att,1); | |
4624 | rb_define_method(cNetCDF,"unlimited",NetCDF_unlimited,0); | |
4625 | rb_define_private_method(cNetCDF,"id2var",NetCDF_id2var,1); | |
4626 | rb_define_private_method(cNetCDF,"id2dim",NetCDF_id2dim,1); | |
4627 | rb_define_private_method(cNetCDF,"id2att",NetCDF_id2att,1); | |
4628 | rb_define_method(cNetCDF,"==",NetCDF_eql,1); | |
4629 | /* rb_define_method(cNetCDF,"eql?",NetCDF_eql,1); */ | |
4630 | ||
4631 | /* The methods of the NetCDFDim class */ | |
4632 | rb_define_method(cNetCDFDim,"clone",NetCDF_dim_clone,0); | |
4633 | rb_define_method(cNetCDFDim,"length",NetCDF_dim_length,0); | |
4634 | rb_define_method(cNetCDFDim,"name=",NetCDF_dim_name,1); | |
4635 | rb_define_method(cNetCDFDim,"name",NetCDF_dim_inqname,0); | |
4636 | rb_define_method(cNetCDFDim,"unlimited?",NetCDF_dim_whether_unlimited,0); | |
4637 | rb_define_method(cNetCDFDim,"==",NetCDF_dim_eql,1); | |
4638 | /* rb_define_method(cNetCDFDim,"eql?",NetCDF_dim_eql,1); */ | |
4639 | ||
4640 | /* The methods of the NetCDFAtt class */ | |
4641 | rb_define_method(cNetCDFAtt,"clone",NetCDF_att_clone,0); | |
4642 | rb_define_method(cNetCDFAtt,"name",NetCDF_att_inq_name,0); | |
4643 | rb_define_method(cNetCDFAtt,"name=",NetCDF_att_rename,1); | |
4644 | rb_define_method(cNetCDFAtt,"delete",NetCDF_att_delete,0); | |
4645 | rb_define_method(cNetCDFAtt,"copy",NetCDF_att_copy,1); | |
4646 | rb_define_method(cNetCDFAtt,"atttype",NetCDF_att_atttype,0); | |
4647 | rb_define_method(cNetCDFAtt,"typecode",NetCDF_att_typecode,0); | |
4648 | rb_define_method(cNetCDFAtt,"==",NetCDF_att_eql,1); | |
4649 | /* rb_define_method(cNetCDFAtt,"eql?",NetCDF_att_eql,1); */ | |
4650 | rb_define_method(cNetCDFAtt,"putraw",NetCDF_att_put,2); | |
4651 | rb_define_method(cNetCDFAtt,"get",NetCDF_att_get,0); | |
4652 | ||
4653 | /* The methods of the NetCDFVar class */ | |
4654 | #if NCVER >= 400 | |
4655 | rb_define_method(cNetCDFVar,"deflate",NetCDF_var_deflate,-1); | |
4656 | rb_define_method(cNetCDFVar,"deflate_params",NetCDF_var_deflate_params,0); | |
4657 | rb_define_method(cNetCDFVar,"endian=",NetCDF_var_set_endian,1); | |
4658 | rb_define_method(cNetCDFVar,"endian",NetCDF_var_endian,0); | |
4659 | #endif | |
4660 | rb_define_method(cNetCDFVar,"clone",NetCDF_var_clone,0); | |
4661 | rb_define_method(cNetCDFVar,"name",NetCDF_var_inq_name,0); | |
4662 | rb_define_method(cNetCDFVar,"ndims",NetCDF_var_ndims,0); | |
4663 | rb_define_method(cNetCDFVar,"vartype",NetCDF_var_vartype,0); | |
4664 | rb_define_method(cNetCDFVar,"typecode",NetCDF_var_typecode,0); | |
4665 | rb_define_method(cNetCDFVar,"ntype",NetCDF_var_vartype,0); | |
4666 | rb_define_method(cNetCDFVar,"natts",NetCDF_var_natts,0); | |
4667 | rb_define_method(cNetCDFVar,"file",NetCDF_var_file,0); | |
4668 | rb_define_method(cNetCDFVar,"name=",NetCDF_var_rename,1); | |
4669 | rb_define_method(cNetCDFVar,"att",NetCDF_var_att,1); | |
4670 | rb_define_method(cNetCDFVar,"put_attraw",NetCDF_put_att_var,3); | |
4671 | rb_define_method(cNetCDFVar,"dims",NetCDF_var_dims,0); | |
4672 | rb_define_method(cNetCDFVar,"dim",NetCDF_var_dim,1); | |
4673 | /*rb_define_private_method(cNetCDFVar,"id2dim",NetCDF_var_id2dim,1); */ | |
4674 | rb_define_private_method(cNetCDFVar,"id2att",NetCDF_var_id2att,1); | |
4675 | rb_define_method(cNetCDFVar,"==",NetCDF_var_eql,1); | |
4676 | /* rb_define_method(cNetCDFVar,"eql?",NetCDF_var_eql,1); */ | |
4677 | ||
4678 | /* The "get*" or "put*" methods in the NetCDFVar class */ | |
4679 | rb_define_method(cNetCDFVar,"put_var_char",NetCDF_put_var_char,1); | |
4680 | rb_define_method(cNetCDFVar,"put_var_byte",NetCDF_put_var_byte,1); | |
4681 | rb_define_method(cNetCDFVar,"put_var_sint",NetCDF_put_var_short,1); | |
4682 | rb_define_method(cNetCDFVar,"put_var_int",NetCDF_put_var_int,1); | |
4683 | rb_define_method(cNetCDFVar,"put_var_sfloat",NetCDF_put_var_float,1); | |
4684 | rb_define_method(cNetCDFVar,"put_var_float",NetCDF_put_var_double,1); | |
4685 | ||
4686 | rb_define_method(cNetCDFVar,"put_vars_char",NetCDF_put_vars_char,4); | |
4687 | rb_define_method(cNetCDFVar,"put_vars_byte",NetCDF_put_vars_byte,4); | |
4688 | rb_define_method(cNetCDFVar,"put_vars_sint",NetCDF_put_vars_sint,4); | |
4689 | rb_define_method(cNetCDFVar,"put_vars_int",NetCDF_put_vars_int,4); | |
4690 | rb_define_method(cNetCDFVar,"put_vars_sfloat",NetCDF_put_vars_float,4); | |
4691 | rb_define_method(cNetCDFVar,"put_vars_float",NetCDF_put_vars_double,4); | |
4692 | ||
4693 | rb_define_method(cNetCDFVar,"put_var1_char",NetCDF_put_var1_char,2); | |
4694 | rb_define_method(cNetCDFVar,"put_var1_byte",NetCDF_put_var1_byte,2); | |
4695 | rb_define_method(cNetCDFVar,"put_var1_sint",NetCDF_put_var1_sint,2); | |
4696 | rb_define_method(cNetCDFVar,"put_var1_int",NetCDF_put_var1_int,2); | |
4697 | rb_define_method(cNetCDFVar,"put_var1_sfloat",NetCDF_put_var1_float,2); | |
4698 | rb_define_method(cNetCDFVar,"put_var1_float",NetCDF_put_var1_double,2); | |
4699 | ||
4700 | rb_define_method(cNetCDFVar,"get_var_char",NetCDF_get_var_char,0); | |
4701 | rb_define_method(cNetCDFVar,"get_var_byte",NetCDF_get_var_byte,0); | |
4702 | rb_define_method(cNetCDFVar,"get_var_sint",NetCDF_get_var_sint,0); | |
4703 | rb_define_method(cNetCDFVar,"get_var_int",NetCDF_get_var_int,0); | |
4704 | rb_define_method(cNetCDFVar,"get_var_sfloat",NetCDF_get_var_float,0); | |
4705 | rb_define_method(cNetCDFVar,"get_var_float",NetCDF_get_var_double,0); | |
4706 | ||
4707 | rb_define_method(cNetCDFVar,"get_vars_char",NetCDF_get_vars_char,3); | |
4708 | rb_define_method(cNetCDFVar,"get_vars_byte",NetCDF_get_vars_byte,3); | |
4709 | rb_define_method(cNetCDFVar,"get_vars_sint",NetCDF_get_vars_sint,3); | |
4710 | rb_define_method(cNetCDFVar,"get_vars_int",NetCDF_get_vars_int,3); | |
4711 | rb_define_method(cNetCDFVar,"get_vars_sfloat",NetCDF_get_vars_float,3); | |
4712 | rb_define_method(cNetCDFVar,"get_vars_float",NetCDF_get_vars_double,3); | |
4713 | ||
4714 | rb_define_method(cNetCDFVar,"get_var1_char",NetCDF_get_var1_char,1); | |
4715 | rb_define_method(cNetCDFVar,"get_var1_byte",NetCDF_get_var1_byte,1); | |
4716 | rb_define_method(cNetCDFVar,"get_var1_sint",NetCDF_get_var1_sint,1); | |
4717 | rb_define_method(cNetCDFVar,"get_var1_int",NetCDF_get_var1_int,1); | |
4718 | rb_define_method(cNetCDFVar,"get_var1_sfloat",NetCDF_get_var1_float,1); | |
4719 | rb_define_method(cNetCDFVar,"get_var1_float",NetCDF_get_var1_double,1); | |
4720 | } |
0 | # coding: utf-8 | |
1 | lib = File.expand_path('../lib', __FILE__) | |
2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |
3 | require 'numru/netcdf/version' | |
4 | ||
5 | Gem::Specification.new do |spec| | |
6 | spec.name = "ruby-netcdf-bigmem" | |
7 | spec.version = NumRu::NetCDF::VERSION | |
8 | spec.authors = ["Takeshi Horinouchi", "Tsuyoshi Koshiro",\ | |
9 | "Shigenori Otsuka", "Seiya Nishizawa", "T Sakakima"] | |
10 | spec.email = ['eriko@gfd-dennou.org'] | |
11 | ||
12 | spec.summary = %q{Ruby interface to NetCDF} | |
13 | spec.description = %q{RubyNetCDF is the Ruby interface to the NetCDF library built on the NArray library, which is an efficient multi-dimensional numeric array class for Ruby. This version works with Ruby2.0.} | |
14 | ||
15 | spec.homepage = 'http://www.gfd-dennou.org/arch/ruby/products/ruby-netcdf/' | |
16 | spec.licenses = ["BSD-2-Clause"] | |
17 | ||
18 | spec.files = `git ls-files -z`.split("\x0") | |
19 | spec.test_files = spec.files.grep(%r{^(test|demo)/}) | |
20 | spec.require_paths = ["ext","lib"] | |
21 | spec.extensions << "ext/numru/extconf.rb" | |
22 | ||
23 | spec.required_ruby_version = Gem::Requirement.new(">= 1.8") | |
24 | spec.add_runtime_dependency(%q<narray-bigmem>, [">= 0"]) | |
25 | spec.add_runtime_dependency(%q<narray_miss-bigmem>, [">= 0"]) | |
26 | ||
27 | end |
0 | 0 | # coding: utf-8 |
1 | 1 | lib = File.expand_path('../lib', __FILE__) |
2 | 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) |
3 | require 'version' | |
3 | require 'numru/netcdf/version' | |
4 | 4 | |
5 | 5 | Gem::Specification.new do |spec| |
6 | 6 | spec.name = "ruby-netcdf" |
7 | spec.version = Ruby::Netcdf::VERSION | |
7 | spec.version = NumRu::NetCDF::VERSION | |
8 | 8 | spec.authors = ["Takeshi Horinouchi", "Tsuyoshi Koshiro",\ |
9 | 9 | "Shigenori Otsuka", "Seiya Nishizawa", "T Sakakima"] |
10 | 10 | spec.email = ['eriko@gfd-dennou.org'] |
11 | ||
12 | #if spec.respond_to?(:metadata) | |
13 | # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server." | |
14 | #end | |
15 | 11 | |
16 | 12 | spec.summary = %q{Ruby interface to NetCDF} |
17 | 13 | spec.description = %q{RubyNetCDF is the Ruby interface to the NetCDF library built on the NArray library, which is an efficient multi-dimensional numeric array class for Ruby. This version works with Ruby2.0.} |
18 | 14 | |
19 | 15 | spec.homepage = 'http://www.gfd-dennou.org/arch/ruby/products/ruby-netcdf/' |
20 | spec.licenses = ["GFD Dennou Club"] | |
16 | spec.licenses = ["BSD-2-Clause"] | |
21 | 17 | |
22 | 18 | spec.files = `git ls-files -z`.split("\x0") |
23 | 19 | spec.test_files = spec.files.grep(%r{^(test|demo)/}) |
24 | #spec.bindir = "exe" | |
25 | #spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } | |
26 | spec.require_paths = ["lib"] | |
20 | spec.require_paths = ["ext","lib"] | |
21 | spec.extensions << "ext/numru/extconf.rb" | |
27 | 22 | |
28 | spec.required_ruby_version = Gem::Requirement.new(">= 1.6") | |
23 | spec.required_ruby_version = Gem::Requirement.new(">= 1.8") | |
29 | 24 | spec.add_runtime_dependency(%q<narray>, [">= 0"]) |
30 | 25 | spec.add_runtime_dependency(%q<narray_miss>, [">= 0"]) |
31 | 26 | |
32 | spec.extensions << "extconf.rb" | |
33 | 27 | end |