ruby-netcdf 0.6.5
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +389 -0
- data/INSTALL +62 -0
- data/LICENSE.txt +59 -0
- data/Rakefile +40 -0
- data/ToDo +1 -0
- data/demo/README +14 -0
- data/demo/demo1-create-alt.rb +35 -0
- data/demo/demo1-create.rb +35 -0
- data/demo/demo2-graphic.rb +67 -0
- data/demo/demo3-ncepclim.rb +178 -0
- data/demo/demo4-copy.rb +32 -0
- data/doc/README_JP.txt +152 -0
- data/doc/Ref_man.html +1482 -0
- data/doc/Ref_man.rd +1312 -0
- data/doc/Ref_man_jp.html +1445 -0
- data/doc/Ref_man_jp.rd +1276 -0
- data/doc/to_html +7 -0
- data/extconf.rb +137 -0
- data/extconf.rb.orig +124 -0
- data/extconf.rb.rej +16 -0
- data/lib/netcdf.rb +791 -0
- data/lib/netcdf_miss.rb +203 -0
- data/netcdfraw.c +4613 -0
- data/test/aref_aset.rb +37 -0
- data/test/char_var.rb +25 -0
- data/test/clone.rb +54 -0
- data/test/create_tmp.rb +15 -0
- data/test/def_var_with_dim.rb +14 -0
- data/test/factor_offset.rb +53 -0
- data/test/putatt.cdl +23 -0
- data/test/putatt.rb +56 -0
- data/test/test.cdl +31 -0
- data/test/test.rb +192 -0
- data/test/type.rb +13 -0
- metadata +140 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
Ruby/NetCDF is copyrighted free software by Takeshi Horinouchi and the
|
2
|
+
GFD Dennou Club.
|
3
|
+
You can redistribute it and/or modify it under either the terms of the
|
4
|
+
GPL, or the conditions below, which is idential to Ruby's license
|
5
|
+
(http://www.ruby-lang.org/en/LICENSE.txt):
|
6
|
+
|
7
|
+
1. You may make and give away verbatim copies of the source form of the
|
8
|
+
software without restriction, provided that you duplicate all of the
|
9
|
+
original copyright notices and associated disclaimers.
|
10
|
+
|
11
|
+
2. You may modify your copy of the software in any way, provided that
|
12
|
+
you do at least ONE of the following:
|
13
|
+
|
14
|
+
a) place your modifications in the Public Domain or otherwise
|
15
|
+
make them Freely Available, such as by posting said
|
16
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
17
|
+
the author to include your modifications in the software.
|
18
|
+
|
19
|
+
b) use the modified software only within your corporation or
|
20
|
+
organization.
|
21
|
+
|
22
|
+
c) rename any non-standard executables so the names do not conflict
|
23
|
+
with standard executables, which must also be provided.
|
24
|
+
|
25
|
+
d) make other distribution arrangements with the author.
|
26
|
+
|
27
|
+
3. You may distribute the software in object code or executable
|
28
|
+
form, provided that you do at least ONE of the following:
|
29
|
+
|
30
|
+
a) distribute the executables and library files of the software,
|
31
|
+
together with instructions (in the manual page or equivalent)
|
32
|
+
on where to get the original distribution.
|
33
|
+
|
34
|
+
b) accompany the distribution with the machine-readable source of
|
35
|
+
the software.
|
36
|
+
|
37
|
+
c) give non-standard executables non-standard names, with
|
38
|
+
instructions on where to get the original software distribution.
|
39
|
+
|
40
|
+
d) make other distribution arrangements with the author.
|
41
|
+
|
42
|
+
4. You may modify and include the part of the software into any other
|
43
|
+
software (possibly commercial). But some files in the distribution
|
44
|
+
are not written by the author, so that they are not under this terms.
|
45
|
+
|
46
|
+
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
47
|
+
files under the ./missing directory. See each file for the copying
|
48
|
+
condition.
|
49
|
+
|
50
|
+
5. The scripts and library files supplied as input to or produced as
|
51
|
+
output from the software do not automatically fall under the
|
52
|
+
copyright of the software, but belong to whomever generated them,
|
53
|
+
and may be sold commercially, and may be aggregated with this
|
54
|
+
software.
|
55
|
+
|
56
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
57
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
58
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
59
|
+
PURPOSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rake/gempackagetask'
|
2
|
+
|
3
|
+
NAME = 'ruby-netcdf'
|
4
|
+
VER = '0.6.5'
|
5
|
+
|
6
|
+
PKG_FILES = FileList[
|
7
|
+
'**',
|
8
|
+
'lib/**/*',
|
9
|
+
'demo/**/*',
|
10
|
+
'doc/**/*',
|
11
|
+
'test/**/*'
|
12
|
+
]
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = NAME
|
16
|
+
s.version = VER
|
17
|
+
s.authors = ['T. Horinouchi','T. Sakakima',\
|
18
|
+
'GFD Dennou Club' ]
|
19
|
+
s.email = 'eriko@gfd-dennou.org'
|
20
|
+
s.homepage = 'http://www.gfd-dennou.org/arch/ruby/products/ruby-netcdf/'
|
21
|
+
s.licenses = ["GFD Dennou Club"]
|
22
|
+
s.platform = Gem::Platform::RUBY
|
23
|
+
s.summary = 'Ruby interface to NetCDF'
|
24
|
+
s.description = '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.'
|
25
|
+
s.files = PKG_FILES.to_a
|
26
|
+
s.require_paths = ['lib']
|
27
|
+
s.test_files = Dir.glob("test/*")
|
28
|
+
s.has_rdoc = true
|
29
|
+
s.required_ruby_version = Gem::Requirement.new(">= 1.6")
|
30
|
+
s.add_runtime_dependency(%q<narray>, [">= 0"])
|
31
|
+
s.add_runtime_dependency(%q<narray_miss>, [">= 0"])
|
32
|
+
#s.extra_rdoc_files = ['README']
|
33
|
+
|
34
|
+
s.extensions << "extconf.rb"
|
35
|
+
end
|
36
|
+
|
37
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
38
|
+
pkg.gem_spec = spec
|
39
|
+
pkg.need_tar = true
|
40
|
+
end
|
data/demo/README
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
* demo1-create.rb a basic test of file creation.
|
3
|
+
creates a file and prints its contents.
|
4
|
+
* demo1-create-alt.rb an alternative way to write demo1-create.rb
|
5
|
+
* demo2-graphic.rb creates a file and close it. Then reopens and
|
6
|
+
visualize it using AdvancedDCL
|
7
|
+
(AdvancedDCL at http://www.gfd-dennou.org/arch/ruby/
|
8
|
+
must have been installed)
|
9
|
+
|
10
|
+
* demo3-ncepclim.rb plots arbitrary 2D slices the 4D distribution of
|
11
|
+
global temperature climatology from
|
12
|
+
the NCEP reanalysis data. The data (8MB) is downloaded
|
13
|
+
by anonymous ftp if not found in the user's
|
14
|
+
run-time directory and he or she wants it.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "numru/netcdf"
|
2
|
+
include NumRu
|
3
|
+
|
4
|
+
file = NetCDF.create("test.nc")
|
5
|
+
nx, ny = 10, 5
|
6
|
+
file.def_dim("x",nx)
|
7
|
+
file.def_dim("y",ny)
|
8
|
+
file.def_dim("t",0)
|
9
|
+
require "date"
|
10
|
+
file.put_att("history","created by #{$0} #{Date.today}")
|
11
|
+
|
12
|
+
x = file.def_var("x","sfloat",["x"])
|
13
|
+
y = file.def_var("y","sfloat",["y"])
|
14
|
+
t = file.def_var("t","sfloat",["t"])
|
15
|
+
v1 = file.def_var("v1","sfloat",["x","y"])
|
16
|
+
v1.put_att("long_name","test 1")
|
17
|
+
v1.put_att("units","1")
|
18
|
+
v2 = file.def_var("v2","sfloat",["x","y","t"])
|
19
|
+
v2.put_att("long_name","test 2")
|
20
|
+
v2.put_att("units","1")
|
21
|
+
file.enddef
|
22
|
+
|
23
|
+
x.put( NArray.float(nx).indgen! )
|
24
|
+
y.put( NArray.float(ny).indgen! )
|
25
|
+
|
26
|
+
z = NArray.float(nx,ny).indgen!*0.1
|
27
|
+
v1.put(z)
|
28
|
+
v1.put( NArray.float(nx).add!(20), "start"=>[0,2],"end"=>[-1,2])
|
29
|
+
v2.put(z, "start"=>[0,0,0],"end"=>[-1,-1,0])
|
30
|
+
t.put( 0, "index"=>[0])
|
31
|
+
v2.put(-z, "start"=>[0,0,1],"end"=>[-1,-1,1])
|
32
|
+
t.put( 1, "index"=>[1])
|
33
|
+
|
34
|
+
file.close
|
35
|
+
print `ncdump test.nc`
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "numru/netcdf"
|
2
|
+
include NumRu
|
3
|
+
|
4
|
+
file = NetCDF.create("test.nc")
|
5
|
+
nx, ny = 10, 5
|
6
|
+
xdim = file.def_dim("x",nx)
|
7
|
+
ydim = file.def_dim("y",ny)
|
8
|
+
tdim = file.def_dim("t",0)
|
9
|
+
require "date"
|
10
|
+
file.put_att("history","created by #{$0} #{Date.today}")
|
11
|
+
|
12
|
+
x = file.def_var("x","sfloat",[xdim])
|
13
|
+
y = file.def_var("y","sfloat",[ydim])
|
14
|
+
t = file.def_var("t","sfloat",[tdim])
|
15
|
+
v1 = file.def_var("v1","sfloat",[xdim,ydim])
|
16
|
+
v1.put_att("long_name","test 1")
|
17
|
+
v1.put_att("units","1")
|
18
|
+
v2 = file.def_var("v2","sfloat",[xdim,ydim,tdim])
|
19
|
+
v2.put_att("long_name","test 2")
|
20
|
+
v2.put_att("units","1")
|
21
|
+
file.enddef
|
22
|
+
|
23
|
+
x.put( NArray.float(nx).indgen! )
|
24
|
+
y.put( NArray.float(ny).indgen! )
|
25
|
+
|
26
|
+
z = NArray.float(nx,ny).indgen!*0.1
|
27
|
+
v1.put(z)
|
28
|
+
v1.put( NArray.float(nx).add!(20), "start"=>[0,2],"end"=>[-1,2])
|
29
|
+
v2.put(z, "start"=>[0,0,0],"end"=>[-1,-1,0])
|
30
|
+
t.put( 0, "index"=>[0])
|
31
|
+
v2.put(-z, "start"=>[0,0,1],"end"=>[-1,-1,1])
|
32
|
+
t.put( 1, "index"=>[1])
|
33
|
+
|
34
|
+
file.close
|
35
|
+
print `ncdump test.nc`
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "numru/dcl"
|
2
|
+
require "numru/netcdf"
|
3
|
+
include NumRu
|
4
|
+
include NMath
|
5
|
+
|
6
|
+
## < create a sample netcdf file >
|
7
|
+
def write_file
|
8
|
+
|
9
|
+
file = NetCDF.create("test.nc")
|
10
|
+
nx, ny = 21, 21
|
11
|
+
xdim = file.def_dim("x",nx)
|
12
|
+
ydim = file.def_dim("y",ny)
|
13
|
+
|
14
|
+
x = file.def_var("x","sfloat",["x"])
|
15
|
+
y = file.def_var("y","sfloat",["y"])
|
16
|
+
var = file.def_var("var","float",["x","y"])
|
17
|
+
var.put_att("long_name","test variable")
|
18
|
+
file.enddef
|
19
|
+
|
20
|
+
vx = NArray.float(nx).indgen! * (2*(Math::PI)*1.5/(nx-1))
|
21
|
+
vy = NArray.float(ny).indgen! * (2*(Math::PI)*1.0/(ny-1))
|
22
|
+
x.put( vx )
|
23
|
+
y.put( vy )
|
24
|
+
|
25
|
+
sx = sin( vx )
|
26
|
+
sy = sin( vy )
|
27
|
+
z = NArray.float(nx,ny)
|
28
|
+
for j in 0..ny-1
|
29
|
+
z[true,j] = sx * sy[j] + 0.00001
|
30
|
+
end
|
31
|
+
|
32
|
+
var.put(z)
|
33
|
+
|
34
|
+
file.close
|
35
|
+
print `ncdump -h test.nc`
|
36
|
+
end
|
37
|
+
|
38
|
+
## < read the file and plot >
|
39
|
+
def draw_graph
|
40
|
+
|
41
|
+
file = NetCDF.open("test.nc")
|
42
|
+
vx = file.var("x")
|
43
|
+
vy = file.var("y")
|
44
|
+
vz = file.var("var")
|
45
|
+
x = vx.get
|
46
|
+
y = vy.get
|
47
|
+
z = vz.get
|
48
|
+
file.close
|
49
|
+
|
50
|
+
#DCL.swlset('ldump',1)
|
51
|
+
DCL.gropn(1)
|
52
|
+
DCL.grfrm
|
53
|
+
DCL.usspnt(x, y)
|
54
|
+
DCL.uspfit
|
55
|
+
DCL.usdaxs
|
56
|
+
DCL.sglset("lsoftf",false)
|
57
|
+
DCL.uegtlb(z, -20) # set the number of levels
|
58
|
+
DCL.uelset("ltone",true)
|
59
|
+
DCL.uetone(z)
|
60
|
+
DCL.udcntz(z)
|
61
|
+
DCL.grcls
|
62
|
+
end
|
63
|
+
|
64
|
+
###(main)###
|
65
|
+
write_file
|
66
|
+
draw_graph
|
67
|
+
###(main)###
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# Plot global climatological temperature distribution
|
2
|
+
# from the NCEP reanalysis data.
|
3
|
+
# The data is downloaded if not found and the users wants.
|
4
|
+
|
5
|
+
######################################
|
6
|
+
### local functions ###
|
7
|
+
def nearest_index(na,val)
|
8
|
+
# returns the element of na nearest to val
|
9
|
+
# na is assumed to be 1d and monotonic
|
10
|
+
|
11
|
+
if(na[0] > na[-1]) then
|
12
|
+
reversed = true
|
13
|
+
na = na[-1..0]
|
14
|
+
else
|
15
|
+
reversed = false
|
16
|
+
end
|
17
|
+
|
18
|
+
w = (na.lt(val)).where
|
19
|
+
idx = [ (w.length==0 ? 0 : w.max), na.length-2 ].min
|
20
|
+
if ( na[idx+1]-val < val-na[idx] ) then
|
21
|
+
idx = idx+1
|
22
|
+
end
|
23
|
+
|
24
|
+
if reversed then
|
25
|
+
na = na[-1..0]
|
26
|
+
idx = na.length-1-idx
|
27
|
+
end
|
28
|
+
|
29
|
+
idx
|
30
|
+
end
|
31
|
+
#####################################
|
32
|
+
### main part ###
|
33
|
+
require "numru/dcl"
|
34
|
+
require "numru/netcdf"
|
35
|
+
include NumRu
|
36
|
+
|
37
|
+
filename = "air.mon.ltm.nc"
|
38
|
+
|
39
|
+
# < download if not found and the users wants >
|
40
|
+
|
41
|
+
if !(Dir.glob(filename)[0]) then
|
42
|
+
# file not found ==> download by ftp if the user wants
|
43
|
+
host = "ftp.cdc.noaa.gov"
|
44
|
+
path = "/Datasets/ncep.reanalysis.derived/pressure/"+filename
|
45
|
+
print "\n*** question ***\n",
|
46
|
+
" File "+filename+" is not in the current directory.\n",
|
47
|
+
" Would you like to download (ftp) it from "+host+"?\n",
|
48
|
+
" (y, n)> "
|
49
|
+
ans = gets
|
50
|
+
if ans =~ /^y/ then
|
51
|
+
print " What is your email address? (needed for anonymous ftp) > "
|
52
|
+
email = gets.chop!
|
53
|
+
require "net/ftp"
|
54
|
+
print " connecting...\n"
|
55
|
+
ftp = Net::FTP.open(host, "anonymous", email, nil)
|
56
|
+
size = ftp.size(path)
|
57
|
+
print " Size of the file is #{(size/1000)} kb. Would you really like to download?\n (y, n)> "
|
58
|
+
ans = gets
|
59
|
+
if ans =~ /^y/ then
|
60
|
+
print " now downloading...\n"
|
61
|
+
ftp.getbinaryfile(path, filename)
|
62
|
+
else
|
63
|
+
print " exit\n"
|
64
|
+
exit
|
65
|
+
end
|
66
|
+
else
|
67
|
+
print " exit\n"
|
68
|
+
exit
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# < open the file and read axes >
|
73
|
+
|
74
|
+
file = NetCDF.open(filename)
|
75
|
+
var = file.var("air") # temperature
|
76
|
+
|
77
|
+
lon = file.var("lon")
|
78
|
+
lat = file.var("lat")
|
79
|
+
level = file.var("level")
|
80
|
+
time = file.var("time") # in hours
|
81
|
+
t = (time.get/720).round + 1 # --> in months
|
82
|
+
axes = [ lon, lat, level, time ]
|
83
|
+
axvals = [ lon.get, lat.get, level.get, t ]
|
84
|
+
axunits = [ lon.att("units").get.gsub("_",""),
|
85
|
+
lat.att("units").get.gsub("_",""),
|
86
|
+
level.att("units").get.gsub("_",""),
|
87
|
+
"months" ]
|
88
|
+
# < graphics >
|
89
|
+
|
90
|
+
#DCL.sglset('lbuff',false)
|
91
|
+
DCL.swlset('lwait',false)
|
92
|
+
DCL.gropn(1)
|
93
|
+
|
94
|
+
first = true
|
95
|
+
while true do
|
96
|
+
begin
|
97
|
+
|
98
|
+
## / select a 2D slice /
|
99
|
+
|
100
|
+
if (first) then
|
101
|
+
print <<-EOS
|
102
|
+
** select a slice **
|
103
|
+
List desired grid numbers of lonigutede, latitude, level, time
|
104
|
+
(set only two of them)
|
105
|
+
|
106
|
+
Example:
|
107
|
+
, , 850, 1
|
108
|
+
-- horizontal slice at 850hPa and January
|
109
|
+
135, , , 2
|
110
|
+
-- vertical slice at 135E and Feburary
|
111
|
+
EOS
|
112
|
+
DCL.grfrm
|
113
|
+
else
|
114
|
+
DCL.grfrm
|
115
|
+
print "Input next slice (C-d to quit)\n"
|
116
|
+
end
|
117
|
+
print "> "
|
118
|
+
slice = gets.chop!.split(",")
|
119
|
+
if slice.length!=4 then
|
120
|
+
raise("Slice must be 4 comma-split numerics")
|
121
|
+
end
|
122
|
+
slice.collect!{|e| # "collect!" replaces elements
|
123
|
+
if e =~ /^ *$/ then
|
124
|
+
nil
|
125
|
+
else
|
126
|
+
e.to_f
|
127
|
+
end
|
128
|
+
}
|
129
|
+
|
130
|
+
iax = []
|
131
|
+
start=[] ; last=[]
|
132
|
+
slice.each_index{|i|
|
133
|
+
if slice[i] == nil then
|
134
|
+
iax.push(i)
|
135
|
+
start.push(0) ; last.push(-1) # from the beginning to the end
|
136
|
+
else
|
137
|
+
idx = nearest_index( axvals[i], slice[i] )
|
138
|
+
start.push( idx ) ; last.push( idx )
|
139
|
+
end
|
140
|
+
}
|
141
|
+
|
142
|
+
if iax.length != 2 then
|
143
|
+
raise("Specify a 2D slice")
|
144
|
+
else
|
145
|
+
x = axvals[iax[0]]
|
146
|
+
iax[0]==2 ? xr=[x.max, x.min] : xr=[x.min, x.max]
|
147
|
+
xttl = axes[iax[0]].att("long_name").get
|
148
|
+
xunits = axunits[iax[0]]
|
149
|
+
y = axvals[iax[1]]
|
150
|
+
iax[1]==2 ? yr=[y.max, y.min] : yr=[y.min, y.max]
|
151
|
+
yttl = axes[iax[1]].att("long_name").get
|
152
|
+
yunits = axunits[iax[1]]
|
153
|
+
end
|
154
|
+
|
155
|
+
## / read the slice and plot /
|
156
|
+
|
157
|
+
v = var.get("start"=>start, "end"=>last)
|
158
|
+
shp=v.shape; shp.delete(1); v.reshape!(*shp) # delete dims of length==1
|
159
|
+
|
160
|
+
#Fig.inclpoint(x, y)
|
161
|
+
DCL.grswnd( xr[0], xr[1], yr[0], yr[1] )
|
162
|
+
DCL.grsvpt(0.2,0.9,0.2,0.9)
|
163
|
+
DCL.grstrf
|
164
|
+
DCL.ussttl(xttl," ",yttl," ")
|
165
|
+
DCL.usdaxs
|
166
|
+
DCL.uwsgxa(x)
|
167
|
+
DCL.uwsgya(y)
|
168
|
+
DCL.uelset("ltone",true)
|
169
|
+
DCL.uetone(v)
|
170
|
+
DCL.udcntz(v)
|
171
|
+
|
172
|
+
first = false
|
173
|
+
rescue
|
174
|
+
print "*Error* ", $!,"\n" # show the error message in ($!)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
DCL.grcls
|
data/demo/demo4-copy.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
=demo4-copy.rb
|
4
|
+
|
5
|
+
Make a copy of a NetCDF file
|
6
|
+
|
7
|
+
==Usage
|
8
|
+
|
9
|
+
% ruby demo4-copy.rb filename_from filename_to
|
10
|
+
|
11
|
+
=end
|
12
|
+
|
13
|
+
def usage
|
14
|
+
"\n\nUSAGE:\n% ruby #{$0} filename_from filename_to\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
require "numru/netcdf"
|
18
|
+
include NumRu
|
19
|
+
raise usage if ARGV.length != 2
|
20
|
+
filename_from, filename_to = ARGV
|
21
|
+
from = NetCDF.open(filename_from)
|
22
|
+
to = NetCDF.create(filename_to)
|
23
|
+
from.each_dim{|dim| to.def_dim( dim.name, dim.length_ul0 )}
|
24
|
+
from.each_att{|att| to.put_att( att.name, att.get )} ## global attributes
|
25
|
+
from.each_var{|var|
|
26
|
+
newvar = to.def_var( var.name, var.ntype, var.dim_names )
|
27
|
+
var.each_att{|att| newvar.put_att( att.name, att.get )}
|
28
|
+
}
|
29
|
+
to.enddef
|
30
|
+
from.each_var{|var| to.var(var.name).put(var.get)}
|
31
|
+
to.close
|
32
|
+
|