ruby-netcdf 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/ToDo ADDED
@@ -0,0 +1 @@
1
+ * none currently
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
@@ -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
+