ruby-netcdf 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
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
+