Created: August in 2003
The last revision: August 2006
This page was transrated by OCN automatically.
GPhys is the class to deal with data of the physical quantity. To assume here becomes latticed from additional information about the price of the physical quantity in the several information and each point and also its physical quantity about the grid point by the physical quantity of scatter-ized continuum. We assume that it's explained gradually for details, and GPhys is convenient at such time.
The file format which can handle GPhys is 3 of NetCDF, GrADS,grib for the moment. Support of grib will be one GPhys 0.4.0. I'd like to increase the supported form in the future.
I'll touch the 2nd simulation by this tutorial and concentrate visualization in handling of the data which becomes a file already in the center. The one which exists in a local host basically is handled, but data also indicates an example of the all easy Thurber and client who access the data which exists in a remote host.
At below GPhys. Drawing library of a NI accessory An example using GGraph comes out much. But. GGraph? Thoroughly. GPhys. It's in the position as one of the use examples which are so, GPhys. It isn't the mandatory component which is so. Therefore even if there are no GGraph and RubyDCL of the subcontractor for itself, GPhys moves (It's used by the shape that I tell here to have written it with require "numru/gphys" in that case.) Independently, the user of GPhys can develop his drawing library with GGraph. For example gave of a graphical user interface isn't using GGraph.
The sample program in this tutorial was executed and checked in GPhys-0.4.0, using the new function by which the part is GPhys-0.5.0, when, it was checked in 0.5.0 (A related one was a part of GDir and was specified in the body). Many programs also move in 0.3.5.
I have here for a reference manual of GPhys:.
It's made in only partial way up to now, but a manual of drawing library GGraph mentioned later is maintained.
Since putting it in several OS, it can be installed automatically including a dependence library. Refer to a "installing, guide" section of a Dennou Ruby home page.
Hereinafter we assume that the version of GPhys is 0.3.0. GPhys is written only in Ruby, so installation is just copied in a suitable pass. Below does that:.
% tar xvzf gphys-0.4.0.tar.gz % cd gphys-0.4.0 % ruby install.rb |
But, there is something to have to install variously in front of it. Please refer to a GPhys home page for more information. A necessary one is NArray, NArrayMiss,RubyNetCDF, RubyDCL. There is also something which needs RubyFFTW3 in the function of FFT. Like mentioning above if it isn't visualized, there may be no RubyDCL.
A NetCDF file as T.jan.nc is included in a distribution package of GPhys for tests, so that will be used (in the subdirectory as testdata). The same one can also be downloaded from here. The contents are the climate value of January of the temperature of the whole ball by a NCEP re-analysis. We assume that this file is copied in a directory for work and the following menu is carried out there.
First, I'll see the outline of this file. Command ncdump of a NetCDF accessory is used.
% ncdump -c T.jan.nc
netcdf. T.jan {
dimensions:
lon = 36 ;
lat = 19 ;
level = 9 ;
variables:
float lon (lon) ;
lon:units = " degrees_east" ;
lon:long_name = " Longitude" ;
lon:actual_range = 0.f, 357.5f ;
float lat (lat) ;
lat:units = " degrees_north" ;
lat:actual_range = 90.f, -90.f ;
lat:long_name = " Latitude" ;
float level (level) ;
level:units = " millibar" ;
level:long_name = "Level" ;
level:positive = "down" ;
level:GRIB_id = 100s ;
level:GRIB_name = "hPa" ;
level:actual_range = 10.f, 1000.f ;
float T(level, lat, lon) ;
T:long_name = "Monthly Mean Air temperature" ;
T:actual_range = -72.66724f, -24.35f ;
T:units = "degC" ;
T:add_offset = 0.f ;
T:scale_factor = 1.f ;
T:missing_value = -9.96921e+36f ;
..snip..
data:
lon = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150,
160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290,
300, 310, 320, 330, 340, 350 ;
lat = 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, -10, -20, -30, -40, -50, -60,
-70, -80, -90 ;
level = 1000, 850, 600, 400, 250, 150, 70, 30, 10 ;
}
|
Original one NCEP. The data is level. 2.5 times of resolution. I make it rough here and have reserved the data size. Data has been also killed in vertical direction. The temperature T. The HA longitude. A parallel. By three-dimensional data of the pressure. But, it's a longitudinal axis "It turns around fast." It's a style of a C language, so dimensional indication of ncdump is , T (level, lat, lon), but the dimension is placed on the reverse by order of lon, lat, level by multidimensional data of Ruby (This is a style of NArray and a multidimensional data library of all RubyNetCDF and GPhys, etc. is based. Therefore, as Fortran, it's how to place, an arrangement subscript is added to a Array class in Ruby, and it always starts from a zero.) The longitude, latitude and high grid point value are stocked in one dimension variable lon, lat, level with the same name as a dimensional name.
Even the GrADS form has prepared something of the same contents basically with NetCDF data above-mentioned. This is also included in a distribution package of GPhys. In case of GrADS, I split up into a control file of a text format and a binary data file. Like mentioning later it's the one of a control file to use it for a bootstrap for reading. It's necessary to download a data file in the same directory, but that may forget the file name.
Even the (grib ver.1) form has prepared something of the same contents basically with NetCDF data above-mentioned. This is also included in a distribution package of GPhys. It's GPhys after 0.4.0 to correspond to the grib form. grib ver.2 isn't being supported. grib 2 isn't used so much for the moment as a practical problem, and much software doesn't correspond.
I'll write a figure right away. Graphic library GGraph for GPhys visualization is included in a GPhys distribution package, so that will be used. GGraph is a module and offers the drawing method as the module function. For example the method on which a contour figure is written (the module function) is GGraph::contour. Further GPhys and GGraph have put it in a module as NumRu and have protected name space like other computer Ruby libraries. Therefore a full name will be NumRu::GPhys,NumRu::GGraph.
In the two-dimensional drawing method in GGraph (contour, tone), it chose the first grid point automatically for the 3th, 4th, .. dimensions, if the data has more than three dimensions. therefore the following program indicates the temperature of the 3rd dimension of first grid point = undermost layer (1000hPa) (A line number is put for convenience of the explanation. It isn't included actually.).
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.nc', 'T') 4: DCL.gropn(1) 5: DCL.sgpset('lcntl', false) ; DCL.uzfact(0.7) 6: GGraph.contour( gphys ) 7: DCL.grcls |
It's executed as follows.
% ruby contour1000mb_1.rb
|
Then the next figure is shown to a screen.
contour1000mb_1.rb execution result
The 1st and 2nd lines of the above program is the spell called each time. The first require "numru/ggraph" loads all necessary libraries. Next include NumRu doesn't have to do, but GGraph or DCL have to call all full names, that is NumRu::GGraph or NumRu::DCL in that case.
The 3rd line gphys = GPhys::IO.open('T.jan.nc', ' T') create GPhys object corresponding the variable T in the file T.jan.nc, and give the variable name of gphys to the object. The GPhys::IO.open recognize type of the file automatically, and through the process to a corresponding lower level module. This time, the file is NetCDF, GPhys::NetCDF_IO.open is called. The module GPhys::NetCDF_IO interprete NetCDF file. As users do not specify exprefitly, it interprete following the convention of NetCDF User's guide: variables for axes are interpreted following the rule that dimension name = variable name, and thier references are kept in the GPhys object (here variable gphys). Interpretation of missing value is also done, and the object has information of the missing value if attribute of valid_range or missing_value exists. Specifically it return NArrayMiss, which is NArray with handling missing value, when we get values (mentioned below).
The 4th line DCL.gropn(1) is graphic equipment initialization of DCL. An argument is shown to 1 in case of and terminal screen. The 5th line isn't usually necessary, but interpretation of a control character is restrained here and the size of the character put on the coordinate axis is set to 0.7 times (DCL.uzfact(0.7))
It's drawing increasingly by the 6th line. GGraph.contour(gphys) does contour line indication of data of the GPhys object by which it was given to an argument. As shown in being above-mentioned the first point is chosen automatically about the after 3rd dimension, so it'll be a plot of horizontal distribution in 1000 mb. I find out that 1000 mb was chosen from indication of level=1000 milibar indicated outside the limits in the upper right on a figure. GGraph.contour does the interpretation which are coordinate axes automatically (I pay attention to x axis's and y axis's being written right.) so that it may be showed by a drawing. It's because Anders Kjor is included in the unit of the indicated x and y axis, that control character interpretation was restrained by the 5th line actually.
The 7th line is a complete process of DCL.
When removing the 5th line which isn't always necessary above, it can visualize it from opening of a file by 6 lines and process to complete it altogether. The way to customize a figure will be described later. It's important for a program not to become long suddenly in the case.
I'll draw a polygonal line by the same way. The 6 lines of GGraph.contour(gphys) in the upper program should be changed to GGraph.line (gphys) But, in this case it is not interesting because the first grid point (that is North Pole) is selected as the second dimension (latitude). So let's draw vertical profile around Japan. The method cut of GPhys cut subset of data in real space. There are two ways to specify the dimension to cut, specify all dimension values one by one, and those of some dimension by dimension name. The following 2 lines will return completely the same result.
gp_jpn = gphys.cut(135,35,true) gp_jpn = gphys.cut('lon'=>135,'lat'=>35) |
Designation method of an argument in in case of is NArray at first, [], it's like the method. Not true, but the "rubber dimension" by false should be used as follows therefore to answer to data of optional number of dimension (rank) with the name more than two dimensions like a designated case. The rubber dimension is equivalent to true in arbitrary number (designation of the total range).
gp_jpn = gphys.cut(135,35,false) |
(It's a by-talk, but, by a language as yorick, the rubber dimension?. if, it can be expressed. In other words, (135,35..) Etc.. To this, the appearance is easy to understand, in Ruby. It isn't possible to make. become independent, so it can't be used.)
Then, I'll draw a figure.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.nc', 'T') 4: DCL.gropn(1) 5: DCL.sgpset('lcntl', false); DCL.uzfact(0.7) 6: GGraph.line(gphys.cut(135,35,false)) 7: DCL.grcls |
A result will be so:.
You indicate "lon=130.0 degrees_east", "lat=40.0 degress_north" outside the upper right limits. The grid point that cut is closest, I come to choose, when designating a center exactly, the one with the smaller grid point number is chosen. The longitude is stocked in the east-> west and latitude in the north-> south, so such parallel and longitude are chosen.
Now, when the pressure which is a vertical coordinate comes to the transverse, somehow I don't think it's vertical profile. So a transverse will be replaced with vertical axis, and it indicates pressure axis by the logarithm scale. Also I'll make sure that the information on the upper right outside the limits won't break in full display (DCL.sgpset('lfull',true)).
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open ('T.jan.nc', 'T') 4: DCL.gropn (1) 5: DCL.sgpset ('isub', 96) # control character of subscription: '_' --> '`' 6: DCL.sgpset ('lfull',true); DCL.uzfact (0.6) 7: GGraph.set_fig ('itr'=> 2, 'viewport'=> [0.250.70.150.6]) 8: GGraph.line (gphys.cut (135,35,false) and true, 'exchange'=>true) 9: DCL.grcls |
By an upper program To make the vertical axis a logarithm scaling. By the 6th line, GGraph.fig The option which is so itr. O is set (GGraph manual referring). In this case. When a control code is invalidated. Ravel who can arrive at an axis becomes too good-looking, so DCL.sgpset('lcntl'. false) The one of ,5 line, not it's so and to invalidate DCL.sgpset('isub'. The letter which is 96) and indicates with a bottom, '_' empty '`' I did NI change. And also. In response to full display. viewport. O is being changed (for the default value, [0.20.80.20.8]). GGraph.fig HA is the method as which the limit of the new figure is defined. The 2nd argument of GGraph.line is called at true. It's possible to omit the 2nd argument and true is the default value. The 7th line is calling GGraph.line, but an option of GGraph.line is the 3rd argument (after a while), so true of the 2nd argument is set positively (It's easy to make a mistake, so, if the 2nd argument is besides true/false, I notify the user by an exception.) And 'exchange'=>true is designated as an option. By this, default though, a coordinate, I come to write a vertical line and data on a transverse. It'll be explained later again about an option.
file can get an object in the class where the pass expressed in a character string or NumRu::NetCDF represents a file directly in GPhys::IO.open (file, varname). The kind of pass in case of and file is distinguished between automatically. The rule is as follows.
The next program just changed only the file name to T.jan.ctl from T.jan.nc by 3 line of contour1000mb_1.rb above-mentioned. All except for that can completely draw data of the GrADS form by the same program.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.ctl', 'T') 4: DCL.gropn(1) 5: DCL.sgpset('lcntl', false); DCL.uzfact(0.7) 6: GGraph.contour(gphys) 7: DCL.grcls |
Equally, the next program draws data of a grib file. GPhys more than 0.4.0 is necessary for execution.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.grib', 'TMP') 4: DCL.gropn(1) 5: DCL.sgpset('lcntl', false); DCL.uzfact(0.7) 6: GGraph.contour(gphys) 7: DCL.grcls |
At the top A variable name, former. ' T' I don't go out. ' TMP' I pay attention to become. A variable doesn't have the name during grib filing. There is just a number decided according to the kind of variables. Since putting it in GPhys::Grib_IO, the name used for its number in wgrib is assigned. That's 'TMP' about the temperature. But, the name of the plural which is also different in the same variable is used in wgrib, so the variable name in GPhys::Grib_IO isn't always parallel with actual output of the wgrib command. Refer to the next about then how to do.
When it's a NetCDF file, it's checked by the ncdump command by a command line as mentioned above. When it's a GrADS file, a control file is a text, so that should be seen. When using GPhys, but I don't depend on the kind of files, and it's checked by the same way.
1: require "numru/gphys" 2: p NumRu::GPhys::IO.var_names('T.jan.grib') 3: p NumRu::GPhys::IO.var_names('T.jan.ctl') 4: p NumRu::GPhys::IO.var_names('T.jan.nc') |
A result is as follows.
% ruby inspect_varnames.rb
["TMP"]
["T"]
["lon", "lat", "level", "T"]
|
A grib file finds out that "TMP", GrADS, NetCDF file has a variable as "T". A variable name as other "lon","lat", "level" also goes out by a NetCDF file, in NetCDF, this, a coordinate variable can also open in GPhys::IO.open as the GPhys object which makes itself a coordinate variable. To make the program a file in only this purpose will seem but troublesome. Next interactive directions are introduced.
The command as irb of standard attachment is the one like
shell which interprets and executes a program of ruby by the line unit
in an interactive session in Ruby. There is also something else as irb
- shell to carry out on emacs. A cut and paste did the result which did
a variable name check above-mentioned in irb in below.
irb (main): 001:0> etc. is a prompt of irb, and it's output of an execution result of each line below the "=>".
% irb. irb (main):001:0>require "numru/gphys" => true irb (main):002:0>include NumRu => Object irb (main):003:0>GPhys::IO.var_names('T.jan.grib') => ["TMP"] irb (main):004:0>GPhys::IO.var_names('T.jan.ctl') => ["T"] irb (main):005:0>GPhys::IO.var_names('T.jan.nc') => ["lon", "lat", "level", "T"] |
Input of the 1st line is different from the former require "numru/ggraph" and is require "numru/gphs". When it's done this way, only the GPhys body is read, and graphic library GGraph isn't read. (Even when a figure isn't written of course, require "numru/ggraph", may, to this, a start-up would be for a short while earlier.)
irb indicates an execution result of the command in p by default, so it's different from a program above-mentioned and p isn't worn positively.
It's troublesome that require "numru/gphys",include NumRu calls "spell" each time at the time of session starting of irb, so using a startup file, I hope that it automates.
A writer gets a way of 2. Both concrete instances are saturated with below.
When it's used, but GPhys doesn't use , GGraph.
% cat ~/.irbrc require "numru/gphys"include NumRu% irb. irb (main): 001:0>GPhys::IO.var_names('T.jan.grib') => ["TMP"] irb (main): 002:0>GPhys::IO.var_names('T.jan.ctl') => ["T"] irb (main): 003:0>GPhys::IO.var_names('T.jan.nc') => ["lon", "lat", "level", "T"] |
The example when GGraph also uses it.
% cat ~/.irbrc
require "numru/ggraph"
include NumRu
include GGraph
DCL.swpset('iwidth',700) # image width
DCL.swpset('iheight',700) # image height
DCL.swpset('lwait',false) # don't wait mouse click to show the next page
DCL.gropn(1)
DCL.sgpset('isub',96) # control character of subscription: '_' --> '`'
DCL.sgpset('lfprop',true) # to use the propotional font
|
Thus require "numru/gphys", when doing drawing as well as include NumRu, I hope that you'll execute the order called in common. Further the default size of the screen is made 700 x 700 at the top, and such as changing it to ofthe control code to lose the wait when drawing it, make sure that the next page will be indicated without mouse clicks and express a done lucky subscript_vanity ', it's being done. When even establishing a startup file, 2 lines are just input after a irb start as follows, and a figure can be taken out. Further html arranges for it and, the Japanese quotation mark is made the em.
% irb. *** MESSAGE (SWDOPN) *** GRPH1 : STARTED / IWS = 1. irb (main):001:0>gphys = GPhys::IO.open ('T.jan.nc', 'T') => <GPhys grid=<3D grid <axis pos=<'lon' in 'T.jan.nc' sfloat[36]>> <axis pos=<'lat' in 'T.jan.nc' sfloat[19]>> <axis pos=<'level' in 'T.jan.nc' sfloat[9]>>> data=<'T' in 'T.jan.nc' sfloat[36, 19, 9]>> irb(main):002:0>contour(gphys.mean (0)) => nil |
The point of view of the output which is as a result of gphys = GPhys::IO.open ('T.jan.nc', 'T') here will be explained later. 2 lines of mean in input of an eye (0) is an average about the first dimension (the= longitude). Refer to here for more information.
irb session execution result above-mentioned
I'll the code carried out be written on a file of the name which isn't recognized as a startup file of irb as follows and it be started by Elias. Following alias? I hope that you write in cshrc.
% alias irb_ggraph 'irb -r ~/.irbrc_ggraph' % cat ~/.irbrc_ggraph.rb require "numru/ggraph" include NumRu include GGraph DCL.swpset('iwidth',700) # image width DCL.swpset('iheight',700) # image height DCL.swpset('lwait',false) # don't wait mouse click to show the next page DCL.gropn(1) DCL.sgpset('isub',96) # control character of subscription: '_' --> '`' DCL.sgpset('lfprop',true) # to use the propotional font |
% irb_ggraph *** MESSAGE (SWDOPN) *** GRPH1 : STARTED / IWS = 1. irb (main):001:0>gphys = GPhys::IO.open('T.jan.nc', 'T') => <GPhys grid=<3D grid <axis pos=<'lon' in 'T.jan.nc' sfloat[36]>> <axis pos=<'lat' in 'T.jan.nc' sfloat[19]>> <axis pos=<'level' in 'T.jan.nc' sfloat[9]>>> data=<'T' in 'T.jan.nc' sfloat[36, 19, 9]>> irb(main):002:0>contour(gphys.mean(0)) => nil |
A writer uses this way habitually.
Without writing a figure, the way to check the contents of the data easily is explained. I'll use dialogue shell irb in Ruby introduced at the top. We assume that a startup file isn't used for a generality as a tutorial. When using it, first a few lines should be omitted suitably. A cut and paste made the screen of kterm below, but html arranges for it and the Japanese quotation mark is made the em.
% irb irb(main):001:0>require "numru/gphys" => true irb(main):002:0>include NumRu => Object irb(main):003:0>T <-It's put in with T here, and a tab is input twice (There is also a case to which the file name doesn't go out like the bottom.), T.jan.ctl T.jan.dat T.jan.grib T.jan.nc ToDo irb(main):003:0>GPhys::IO.var_names('T.jan.nc') # for GPhys >= 0.4.0 => ["lon", "lat", "level", "T"] irb(main):004:0>gphys = GPhys::IO.open('T.jan.nc', 'T') => <GPhys grid=<3D grid <axis pos=<'lon' in 'T.jan.nc' sfloat[36]>> <axis pos=<'lat' in 'T.jan.nc' sfloat[19]>> <axis pos=<'level' in 'T.jan.nc' sfloat[9]>>> data=<'T' in 'T.jan.nc' sfloat[36, 19, 9]>> irb(main):005:0> |
irb. The result which carried out each HA line. The leaving indication function It outputs in standard output using p. Indication by p may not always be clean, but it's convenient. 12 lines of input of an eye (001,002) is an usual spell. By 3 line T. After NI continues. TAB. It'll input a key twice. By many cases. A list of the file names which start from T should be indicated. This is probably. irb. It isn't its own function. Keystroke is controlled. Because it's the function of the library as readline. There is also a case it won't be so. Input of the actual 3 line which continues and becomes redo (The 2nd time of 003) HA. GPhys. 0.4.0. The function which was so and was supported Using GPhys::IO.var_names, one during filing GPhys-ization, a possible variable name is indicated. And 4 lines of GPhys object is made about variable 'T' by input of an eye (gphys = GPhys::NetCDF_IO.open ('T.jan.nc', 'T')). The one by which the result was indicated in p is migrating to 4 lines. It's a little indistinct, but it's data T of three dimensions in lon, lat, level, and you can realize that each is stocked in file T.jan.nc. A numeric type and length of each dimension are also indicated. How to place the dimension is like Fortran and the dimension which "turns around fastest" comes first (Refer here.)
Then, I'll execute the next program.
1: require "numru/gphys" 2: include NumRu 3: p gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 4: p 'name = '+gphys.name, 'rank:',gphys.rank, 'shape:', gphys.shape 5: print ' [1st dim] name:', gphys.coord(0).name. 6: ' long_name:',gphys.coord(0).get_att('long_name'). 7: ' units:',gphys.coord(0).get_att('units'). 8: " min,max:# {gphys.coord(0).min} and# {gphys.coord(0).max}, \n" 9: prs = gphys.coord(2).val. 10: t_jpn = gphys.cut(135,35,true).val. 11: print "\n# {gphys.coord(0).name} \t# {gphys.name}\ n" 12: for i in 0...prs.length do 13: print prs[i], "\t", t_jpn[i], "\n" 14: end |
irb isn't used this time, so p has to call positively (3 line etc). An execution result is indicated below.
% ruby inspect.rb
<GPhys grid=<3D grid <axis pos=<'lon' in 'T.jan.nc' sfloat[36]>>
<axis pos=<'lat' in 'T.jan.nc' sfloat[19]>>
<axis pos=<'level' in 'T.jan.nc' sfloat[9]>>>
data=<'T'in 'T.jan.nc' sfloat[36, 19, 9]>>
"name = T"
"rank:"
3
"shape:"
[36, 19, 9]
[1st dim] name:lon long_name:Longitude units:degrees_east min,max:0.0 degrees_east,350.0 degrees_east
lon T
1000.0 -5.50255870819092
850.0 -13.0088624954224
600.0 -23.8766059875488
400.0 -41.1900672912598
250.0 -52.6089935302734
150.0 -51.7955780029297
70.0 -55.255916595459
30.0 -51.0108757019043
10.0 -43.6157722473145
|
I'll explain 4 line after a while of a program.
4 line:
p 'name = '+gphys.name, 'rank:',gphys.rank, 'shape:', gphys.shape
The name of HA GPhys OBUEJEKUTO (name), number of dimension (rank) and the length of each dimension (shape) are indicated.
5-8 line:
print ' [1st dim] name:', gphys.coord (0) .name, ' long_name:',gphys.coord (0) .get_att ('long_name'), ' units:',gphys.coord (0) .get_att ('units')," \n"
An order of HA no continuation. 第. 567. Because the line ends by a comma. Because it's clear, need of continuation is interpreted so. gphys.coord (idim) HA. The dimension of the idim turn eye (I count from 0.) The data in which the coordinate value which is so is stocked is returned (, further. GPhys also arranges and manages information about each dimension besides the coordinate value. Information about each dimension? gphys.axis (idim) It's so and it's obtained. The coordinate value is to that. pos. The thing to which the method is applied also gives it to us. In other words. gphys.axis (idim). pos. HA gphys.coord (idim) The same result is returned. Any more explanation isn't done for easiness here). The coordinate value? VArray. (=Virtual Array) I say so. An object in a class with the same function is returned basically with multi-dimentional array. VArray. HA. As well as a multidimensional numerical data. It's possible to have the name and the "attribute" of optional 個. The attribute is the set of the optional name (character string) and value. The specification of the price? NetCDF. It's similar (one-dimensional arrangement of a figure or character string). VArray. The data body which is so? Even NArray is good and the variable I'm doing NetCDF filing of is also fine. I'm the latter here. Data isn't read until I need in this case. It won't be to press a memory immediately to come near and open a huge data file. That output is compared with 5-8 line of a program, gphys.coord (0). name, the name, gphys.coord (0). get_att ('long_name'), attribute long_name, gphys.coord (0). max would find out that the maximum of the coordinate value is returned. When I try to read the attribute which doesn't exist, a return value will be nil (An exception doesn't occur.)
Then 9 line (prs = gphys.coord (2). val) (is counted from a zero), and, the 2nd dimension, or the price of the pressure (variable name level) is read. Method val in VArray returns the price of the data in NArray. Therefore reading of variable value from a file occurs (here, for the first time) here.
After an eye (t_jpn = gphys.cut (135,35,true). val) chose 10 lines of 1 vertical profile around Japan from well, data is read. It's explained at the next join about the specification of the data reading.
An eye indicates 11 lines of respective name (name), and the price of the pressure and the temperature by each grid point is extracted by 12-14 line.
Class GDir which represents a directory in the file system for GPhys was introduced from GPhys-0.5.0. It's like Dir of Ruby inclusion, the biggest difference?
It's a fact. Or "ls" makes the "cd" a file of NetCDF, and can do a variable. Further, when HDF and NetCDF-4 support the form for which the directory structure can be taken during filing in the future, it's expected to make sure that that can also be made a GDir object.
It starts to be the next in the main difference in the other than above.
Refer to a online manual of Gdir for more information.
GDir is suitable for dialogue use using irb. When it's used, when I prepare in a startup file, it's convenient, but directions in raw irb are indicated in order to use it only by copy and paste here.
% pwd /hogehoge/TUTORIAL % irb irb(main):001:0> require "numru/gphys" => true irb(main):002:0> include NumRu => Object irb(main):003:0> GDir.top => "/" # default top directory irb(main):004:0> GDir.top = Dir.pwd # The top directory is changed to the present directory, => "/hogehoge/TUTORIAL" irb(main):005:0> GDir.pwd => "/" irb(main)006:0> GDir.ls Directories: 'T.jan.ctl/' 'T.jan.grib/' 'T.jan.nc/' 'testdir/' Text files?: 'ToDo' irb(main):007:0> GDir.ls_l # It's indicated more conversantly, Directories: 423 Sep 16 2003 T.jan.ctl/ # file size, the time of a renewal date and the name 13167 Mar 10 13:03 T.jan.grib/ 26664 Aug 28 2003 T.jan.nc/ 512 Jul 21 13:13 testdir/ Text files?: 206 Mar 23 2004 ToDo => nil irb(main):008:0> GDir.cd 'T.jan.nc' => /T.jan.nc/ irb(main):009:0> GDir.ls Data: 'lon' 'lat' 'level' 'T' => nil irb(main):010:0> GDir.ls_l #. More conversantly, Data: lon. [lon=36] ' Longitude' (degrees_east) lat. [lat=19] ' Latitude' (degrees_north) level. [level=9] 'Level' (millibar) T [lon=36,lat=19,level=9] 'Temperature' (degC) => nil irb(main):022:0> temp = GDir.data 'T' => <GPhys grid=<3D grid <axis pos=<'lon' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[36]>> <axis pos=<'lat' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[19]>> <axis pos=<'level' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[9]>>> data=<'T' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[36, 19, 9]>> |
Thus it's possible to search to handle it as a directory including a file for a desired variable from the data set put in order hierarchically and open as a GPhys object.
A current directory (It was class variable of GDir.) chisel of GDir was used by an upper example, so a GDir object didn't appear positively. The example which handles a GDir object is indicated this time.
% irb irb(main):001:0> require "numru/gphys" => true irb(main):002:0> include NumRu => Object irb(main):003:0> GDir.top = Dir.pwd # The top directory is changed to the present directory, => "/hogehoge/TUTORIAL" irb(main):004:0> dir = GDir.cwd # A current directory is acquired, => / irb(main):005:0> dir.class => NumRu::GDir # dir is a GDir object: irb(main)006:0> dir.ls Directories: 'T.jan.ctl/' 'T.jan.grib/' 'T.jan.nc/' 'testdir/' Text files?: 'ToDo' => nil irb(main):007:0> dir2 = dir.dir ('T.jan.grib/') => /T.jan.grib/ irb(main):008:0> dir2.ls_l Data: TMP [lon=36,lat=19,level=9] 'Temperature' (K) => nil irb(main):009:0> temp = dir2.data('TMP') => <GPhys grid=<3D grid <axis pos=<'lon' in 'TMP' 36>> <axis pos=<'lat' in 'TMP' 19>> <axis pos=<'level' in 'TMP' 9>>> data=<'TMP' in '/hogehoge/TUTORIAL/T.jan.grib' [36, 19, 9]>> |
A condition of a top directory and a sub-directory were opened as a GDir object for a current directory of GDir and (variable name dir2) and data in it were opened as a GPhys object by this example.
File for above-mentioned irb reading. I'll can add setting about GDir to irbrc_ggraph and use irb like shell. "Like shell", when driving in with ls and ls_l, a directory and a variable are listed, and a directory is changed in cd, and a GPhys variable can be opened easily, and (The command name is made open.) it's said that they do.
% alias irb_ggraph 'irb -r ~/.irbrc_ggraph' % cat ~/.irbrc_ggraph.rb print "Start interactive GGraph session\n" require "numru/ggraph" include NumRu include GGraph #<< GDir Setting>> GDir.top='/' GDir.cd(Dir.pwd) def cwd; GDir.cwd; end # returns the current working directory of GDir def pwd; GDir.pwd; end # prints the current working directory of GDir def ls(path=nil); GDir.cwd.ls(path); end # listing def ls_l(path=nil); GDir.cwd.ls_l(path); end # verbose listing alias dir ls_l def cd(path); GDir.cd(path); end def open_all_data; GDir.cwd.open_all_data; end # --> Hash of GPhys objs in cwd def data(path); GDir.cwd.data(path); end # --> GPhysalias open data #<< Graphic Setting>> DCL.swpset('iwidth',700) # window width DCL.swpset('iheight',700) # window height ###DCL.swpset ('ldump',true) # dump image files DCL.swpset('lwait',false) # don't wait mouse click to show the next page ###DCL.swpset('lalt',true) # background plot DCL.sgscmn(10) (# change colomap see below) ###DCL.sgscmn(5) # change colomap (see below) DCL.gropn(1) DCL.sgpset('lfprop',true) #. to. use. the. propotional. font DCL.sgpset('lcorner',false) # don't show the corner mark DCL.sgpset('isub', 96) # control character of subscription: '_' --> '`' DCL.glpset('lmiss',true) # handle data missing =begin color map number 1: dcl_original 2: black-orange-yellow-white 3: black-blue-cyan-white 4: blue-cyan-white-yellow-red 5: gray_scale 6: pastel_rainbow 7: black-rainbow-black 8: white_yellow_red 9: white_blue_black 10: short_green_original 11: black-rainbow-white 12: pink-ra =end |
Then, it'll draw data using this. The command name is irb_ggraph by alias at the top.
% irb_ggraph Start interactive GGraph session *** MESSAGE (SWDOPN) *** GRPH1 : STARTED / IWS = 1. irb(main):001:0> ls Directories: 'T.jan.ctl/' 'T.jan.grib/' 'T.jan.nc/' 'testdir/' Text files?: 'ToDo' => nil irb(main):002:0> cd 'T.jan.nc/' => /hogehoge/TUTORIAL/T.jan.nc/ irb(main):003:0> ls. Data: 'lon' 'lat' 'level' 'T' => nil irb(main):004:0> temp = open 'T' => <GPhys grid=<3D grid <axis pos=<'lon' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[36]>> <axis pos=<'lat' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[19]>> <axis pos=<'level' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[9]>>> data=<'T' in '/hogehoge/TUTORIAL/T.jan.nc' sfloat[36, 19, 9]>> irb(main):005:0> tone temp => nil |
Illustration of data and an analysis can be done while looking for a directory like shell this.
Execution result of the session above-mentioned
It was stated that method cut is able to cut GPhys down at the top. In the data short straight-bladed knife method of GPhys, cut and, [,], there are 2 kinds. cut, a physical coordinate, it's designated, and, it's cut down, [,], for, a grid point of data is cut down based on an index (subscript as= arrangement). The respective specifications are indicated by an example first.
require "numru/gphys" include NumRu gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') print "gphys: rank=# {gphys.rank} shape=# {gphys.shape.inspect}, \n" gp135 = gphys.cut('lon'=>0..90) # An axis of the name as lon, up to 0-90 times, print "gp135: rank=# {gp135.rank} shape=# {gp135.shape.inspect}, \n" gprg1 = gphys.cut(100.0..150.0, 30..50, 850) # The 12th dimension of is an area, and the 3rd dimension is the price, print "gprg1 rank=# {gprg1.rank} shape=#{gprg1.shape.inspect}" " 0th dim: # {gprg1.coord (0). Min}. . # {gprg1.coord(0). max}, \n" gprg2 = gphys[0..3, -3..-1, 0] # It's like the top, but by an arrangement subscript, designation print "gprg2 rank=# {gprg2.rank} shape=# {gprg2.shape.inspect}", " 0th dim: # {gprg2.coord (0). Min} .. # {gprg2.coord (0). max} \n" p gprg2 # leaving indication |
Execution results in below:.
% ruby -Ke kiridashi.rb
gphys: rank=3 shape=[36, 19, 9]
gp135: rank=3 shape=[10, 19, 9]
gprg1 rank=2 shape=[6, 3] 0th dim: 100.0 degrees_east .. 150.0 degrees_east
gprg2 rank=2 shape=[4, 3] 0th dim: 0.0 degrees_east .. 30.0 degrees_east
<GPhys grid=<2D grid <axis pos=<'lon' shape=[4] subset of a NumRu::VArrayNetCDF>>
<axis pos=<'lat' shape=[3] subset of a NumRu::VArrayNetCDF>>>
data=<'T' shape=[4, 3] subset of a NumRu::VArrayNetCDF>>
|
The one from the last line Leaving indication by p (p gprg2) The result which is so? ' lon'. ' lat'. ' T' The data which is so, both are "subset. of. Please show that it's a NumRu::VArrayNetCDF". I'm here. (Just like arranging a NetCDF variable, VArrayNetCDF is a class like the socket to show it.). Well, "short straight-bladed knife" in GPhys just defines all references to which the reach to the original data was limited. When defining more GPhys objects about the data I'm doing NetCDF filing of like this example, VArrayNetCDF which becomes a saucer has only a reference to a NetCDF variable as the internal data. Therefore, kiridashi.rb above-mentioned, as much as it was carried out, for, the price of the variable isn't read (The investigation attribute is read as the need arises.) Reading of the price isn't performed until purpose of visualization needs actually.
The case of GGraph.contour(gphys) in the first example of visualization, then a two-dimensional subset (lowest data) is cut down first almost, and only data necessary to illustration is read after that. Original data, several, 100 MB of four dimensions, even if it's data, it's no problem.
Now, because a short straight-bladed knife is a reference, if writing the price in gprg2 above-mentioned, change will be reflected by a NetCDF file in gphys and Omoto. But a file is opened in Read - only by default, so I don't need the worry to which the file is changed carelessly. Actually, the first argument of GPhys::NetCDF_IO.open is going to understand a NetCDF object or a character string. If and it's a character string, a NetCDF object of read - only is opened and used inside.
When I'd like to permit writing in, it's necessary to give the NetCDF object which opened as writing in possible beforehand as follows to GPhys::NetCDF_IO.open.
file = NetCDF.open('T.jan.nc', 'a') # the mode 'a' permits edit of a file gphys = GPhys::NetCDF_IO.open(file, 'T') |
Arguments of NetCDF.open are the file name and an input/output mode (It's possible to omit.) The input/output mode is same as the specification of the built-in File class in Ruby (And that's same as the specification of the C language.) But, NetCDF needs the purpose 'b' which is always binary, KU, the reading is possible by every mode again.
GPhys. Data is cut down and. It's possible to get the average and do mathematics calculation and statistical operation. Because calculation about data is unnecessary to a short straight-bladed knife. A GPhys object just maintained a reference to the variable I'm doing NetCDF filing of, such as I get the average, when it is, it'll be calculated with the reading of the actual data. Data leaves the file already and is maintained on the memory. Since putting it in GPhys, but data on the memory is also dealt with just equally with the data in the file. Therefore the user doesn't have to classify both of them. But, it's better to try to calculate after a necessary part is cut down so that a memory isn't pressed when dealing with huge data.
It's known immediately never data is in the file or whether class GPhys is in NArray indeed. VArray of a GPhys follower (= Virtual Array) absorbs this difference. For example above-mentioned VArrayNetCDF is a sub-class in VArray. (Correspondence to the unsupported format will depend, and is main work to make VArray which deals.)
Now, a lower program indicates vertical profile of the whole ball average temperature. Be careful about almost no source's changing with line_2.rb.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.nc', 'T') 4: DCL.gropn(1) 5: DCL.sgpset('isub', 96) 6: DCL.sgpset('lfull',true) 7: DCL.uzfact(0.6) 8: GGraph.set_fig('itr'=> 2, 'viewport'=> [0.250.70.150.6]) 9: GGraph.line(gphys.mean(0,1), true, 'exchange'=>true) 10: DCL.grcls |
A figure of the result is the bottom. I pay attention to information's on the upper right outside the limits changing to the one which shows an average.
I'm getting the average of the 12th dimension in mean (01) here. The dimension is also counted from 0 like an array element. Method mean in GPhys does a arithmetic mean equivalent in the weight of each grid point. The directions are same as method mean in NArray (And there is a method of sum, max, min, stddev equally.)
Now, because data makes the sample discrete by 90N-90S, and a thing is an included reason, in fact an average is the top integrated by trapezium rules and Simpson formulas, etc., and it's natural to divide it by the length. It's possible to balance in method average at such real space:.
9: GGraph.line(gphys.average(1).average(0), true, 'exchange'=>true) |
Such. The method operated in real space? It's 2, average and integrate up to now. Integration algorithm of default is a trapezium rule together, (, when it changes, but algorithm interprets only a user's guide of , NetCDF by the character of the grid, I know and don't get the character of the grid actually, so well). it's necessary to do these every each dimension, so it's being called average (1) .average (0) again. I pay attention to being not the average which considered that the longitudinal space of the grid point around the pole is also still short in this case. it's expected to make sure that you can establish the coordinate system for which spherical coordinates was necessary in the future and make them interpret.
VArray, GPhys recognizes the unit of the physical quantity.
The unit is designated by attribute "units", and <ahref="http://ruby.gfd-dennou.org/products/numru-units" target=_top>NumRu::Units carries out the operation. When I choose as this for example multiply by VAray and GPhys, you multiply by the unit. I do (for example, km and conversion between m, degree_C and K) after the summation of the data and the difference with the unit with the difference for the fixed number double and/ or the offset will do the conversion which adds the 2nd item to the unit of the initial term later.
A class of the numerical value with the unit as NumRu::UNumeric using this (scalar) is defined in the package of GPhys. GPhys, VArray, UNumeric can carry out 2 item operation freely. (In a class of a result, of GPhys, VArray, UNumeric, it's added in turn. For example, an operation result of UNumric and GPhys is GPhys.)
1: require "numru/gphys" 1: include NumRu 2: temp = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 3: p (temp.data.get_att('units')) 4: p ( (temp * temp).data.get_att('units')) 5: p ( (temp * temp).units.to_s) 6: 7: R = UNumeric [287.04, 'J.K-1.kg-1'] # Gas const of dry air 8: p ( (R * temp).data.get_att('units')) # Bad, because temperature should be in K 9: zeroK = UNumeric[0.0, 'K'] 10: tempK = zeroK + temp 11: p ( (R * tempK).data.get_att('units')) |
Execution results in below:.
% ruby op_units.rb
" degC"
"degC2"
"degC2"
"J.K^(-1.0). degC.kg-1"
"J.kg-1"
|
I find out that unit "degC" of the temperature is squared and becomes "degC2" as the result by which the 4th line is (temp * temp). 7 lines of several gaseous fixed R = 287.04 [J.kg-1.K-1] is prepared by an eye, and you multiply 8 lines by the temperature by an eye. The unit of the result was" J.K^ (-1.0). degC.kg-1". K and degC have not canceled it, so it's a little indistinct, but really to hang on a gas constant and be significant when I think, would usually remember that it's absolute temperature (probably). So, using the unit's which is as a result of the addition being added to the first item by , 9,10 line, I change to Kelvin:.
zeroK = UNumeric [0.0, 'K'] tempK = zeroK + temp
The unit of (11 line) and the result which hangs R on this result has gone out with "J.kg-1".
It's possible to extract the whole of a GPhys object in a file while keeping own description. A NetCDF file is read by the next example and the small group which limited territory is extracted in a NetCDF file. A coordinate variable corresponds to extracted territory, and is also cut down right.
1: require "numru/gphys" 2: include NumRu 3: gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 4: outfile = NetCDF.create('tmp.nc') 5: GPhys::NetCDF_IO.write(outfile, gphys.cut('level'=>1000..250).mean(0)) 6: GPhys::NetCDF_IO.write(outfile, gphys.cut('level'=>1000..250).mean(0,1).rename('T00')) 7: outfile.close |
% ruby ncwrite1.rb % ncdump -c tmp.nc netcdf tmp { dimensions: lat = 19 ; level = 5 ; variables: float lat(lat) ; lat:units = "degrees_north" ; lat:actual_range = 90.f, -90.f; lat:long_name = "Latitude" ; float level(level) ; ...(snip)... float T(level, lat) ; ...(snip)... float T00(level) ; ...(snip)... // global attributes: :history = "2004-03-19 19:40:17 JST horinout> NumRu::GPhys::NetCDF_IO.write T" ; data: lat = 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, -10, -20, -30, -40, -50, -60, -70, -80, -90 ; level = 1000, 850, 600, 400, 250 ; } |
第 of a source 56. Like a line. GPhys::NetCDF_IO.write Repeatedly, O can write more than one variables on one file. But, only one variable of the same name can be written by the restrictions of NetCDF, so I'm changing the name of the data written on the 2nd with 'T00' here. When not changing the name, the name of the two data is same, so an exception occurs. On the other hand, coordinate variable in case of is often shared in more than one GPhys, so when there is something homonymous of existence, the dimension and the size (shape) are checked, and when it's identical, it's regarded as the same one and writing in is omitted. When being not identical, an exception occurs. A coordinate variable as level is shared by an upper example.
A style change in a file can be performed easily by a thing through GPhys.
1: require "numru/gphys" 2: include NumRu 3: 4: usage = "\nUSAGE:\n % #{$0} in_file out_file\n" 5: ifpath = ARGV.shift || raise (usage) 6: ofpath = ARGV.shift || raise (usage) 7: 8: raise "File # {ofpath} present. Delete it if needed." if File.exist? (ofpath) 9: case ofpath 10: when /\.nc$/ 11: ofile = NetCDF.create (ofpath) 12: when /\.grib$/ 13: ofile = Grib.create (ofpath) 14: else 15: raise "unsupported file type judged by suffix): "+ofpath 16: end 17: 18: GPhys::IO.var_names_except_coordinates (ifpath). each do |varname| 19: GPhys::IO.write (ofile, GPhys::IO.open (ifpath, varname)) 20: end 21: 22: ofile.close |
The style of the file in a change destination has been decided according to the suffix (is it .nc? grib) by this program. The style of the input file is distinguished between automatically, so you have to do nothing in particular. Still, 19 lines are input by an eye, it's extracted in a file after all variables which are being filed are read for the memory once, so it isn't suitable for handling of huge data. A handling method of huge data is mentioned later. Further for the bug, the above program can't convert it to a grib file in GPhys 0.4.0. I need after 0.4.1 which will be released from now on.
Example (But, the 3rd one can't normally be carried out in GPhys 0.4.0.):
% ruby convert.rb T.jan.grib tmp1.nc % ruby convert.rb T.jan.ctl tmp2.nc % ruby convert.rb T.jan.nc tmp.grib % ls tmp* tmp.grib tmp1.nc tmp2.nc |
Confirmation of the filing which could be done:
% ncdump -h tmp1.nc
netcdf tmp1 {
dimensions:
lon = 36 ;
lat = 19 ;
level = 9 ;
variables:
float lon (lon) ;
lon:long_name = " longitude" ;
lon:units = " degrees_east" ;
lon:short_name = "lon" ;
float lat(lat) ;
lat:long_name = "latitude" ;
lat:units = "degrees_north" ;
lat:short_name = "lat" ;
long level(level) ;
level:long_name = "isobaric level" ;
level:units = "hPa" ;
double TMP(level, lat, lon) ;
TMP:time = "0000-01-01 00:00:0.0" ;
TMP:long_name = "Temperature" ;
TMP:units = "K" ;
TMP:standard_name = "air_temperature" ;
// global attributes:
:history = "2005-03-21 18:06:19 JST horinout> NumRu::GPhys::NetCDF_IO.write TMP" ;
}
|
% wgrib tmp.grib
1:0:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=1000:TR=1:P1=0:P2=0:TimeU=0:1000 mb:anl:NAve=0
2:1463:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=850:TR=1:P1=0:P2=0:TimeU=0:850 mb:anl:NAve=0
3:2926:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=600:TR=1:P1=0:P2=0:TimeU=0:600 mb:anl:NAve=0
4:4389:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=400:TR=1:P1=0:P2=0:TimeU=0:400 mb:anl:NAve=0
5:5852:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=250:TR=1:P1=0:P2=0:TimeU=0:250 mb:anl:NAve=0
6:7315:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=150:TR=1:P1=0:P2=0:TimeU=0:150 mb:anl:NAve=0
7:8778:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=70:TR=1:P1=0:P2=0:TimeU=0:70 mb:anl:NAve=0
8:10241:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=30:TR=1:P1=0:P2=0:TimeU=0:30 mb:anl:NAve=0
9:11704:d=00010100:TMP:kpds5=11:kpds6=100:kpds7=10:TR=1:P1=0:P2=0:TimeU=0:10 mb:anl:NAve=0
|
(by Seiya Saizawa and 改: Horinouchi)
When extracting a NetCDF file from one, you can write that GPhys is used easily.
I'm not reading a file by the following program and compose a GPhys object from one including coordinate information, and that's output in a NetCDF file. A program doesn't have to deal with the method of RubyNetCDF directly by going through a GPhys object once, and becomes easy.
require "numru/gphys" include NumRu nlon = 36 nlat = 18 lon_a = VArray.new(NArray.sfloat(nlon).indgen(0,360.0/nlon), {"long_name"=>"longitude", "units"=>"degrees_east"}, "lon") lon = Axis.new.set_pos(lon_a) lat_a = VArray.new(NArray.sfloat(nlat).indgen 0,180/nlat), {"long_name"=>"latitude", "units"=>"degrees_north"}, "lat") lat = Axis.new.set_pos(lat_a) data = VArray.new(NArray.sfloat(nlon,nlat).indgen, {"long_name"=>"temperature", "units"=>"K"}, "T") gphys = GPhys.new(Grid.new(lon,lat). data) file = NetCDF.create("tmp.nc") GPhys::NetCDF_IO.write(file,gphys) file.close |
I'll check the contents of file tmp.nc which can execute and make the program above-mentioned:.
% ruby ncwrite2.rb % ncdump -c tmp.nc netcdf tmp { dimensions: lon = 36 ; lat = 18 ; variables: float lon(lon) ; lon:long_name = "longitude" ; lon:units = "degrees_east" ; float lat(lat) ; lat:long_name = "latitude" ; lat:units = "degrees_north" ; float T(lat, lon) ; T:long_name = "temperature" ; T:units = "K" ; // global attributes: :history = "2004-04-19 12:02:36 JST horinout> NumRu::GPhys::NetCDF_IO.write T" ; data: lon = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350 ; lat = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170; } |
The, first, for, design policy of GPhys which says "Unless I need, data isn't read." For example, [,], and, reading of a file doesn't occur by subset cutting by cut. Could you see the following example?
% irb irb(main):001:0> require "numru/gphys" => true irb(main):002:0> include NumRu => Object irb(main):003:0> gphys = GPhys::IO.open ('T.jan.nc','T') => <GPhys grid=<3D grid <axis pos=<'lon' in 'T.jan.nc' sfloat[36]>> <axis pos=<'lat' in 'T.jan.nc' sfloat[19]>> <axis pos=<'level' in 'T.jan.nc' sfloat[9]>>> data=<'T' in 'T.jan.nc' sfloat[36, 19, 9]>> irb(main):004:0>sub = gphys.cut ('lon'=>0,'lat'=>10..60) => <GPhys grid=<2D grid <axis pos=<'lat' shape=[6] subset of a NumRu::VArrayNetCDF>> <axis pos=<'level' shape=[9] subset of a NumRu::VArrayNetCDF>>> data=<'T' shape=[6, 9] subset of a NumRu::VArrayNetCDF>> |
sub. = In the indication which is as a result of gphys.cut ('lon'=>0,'lat'=>10..60). ' lat'. ' T' NITSUI, since, subset. It's indicated with of a NumRu::VArrayNetCDF. It's because when doing subset making of this in VArray, a new object copies and doesn't maintain the price, but a reference to an original object and representation method of a subset are maintained. A short straight-bladed knife of the data even an example of visualization above-mentioned visualizes, [,], and, it's that to do in cut, the data read from a file is used for taking pictures. If therefore just just illustrating, a GPhys object may be made dealing with the whole of huge data.
Continuation of the above irb session:
irb(main):005:0> csub = sub.copy
=> <GPhys grid=<2D grid <axis pos=<'lat' sfloat[6] val=[60.0,50.0,40.0,30.0,...]>>
<axis pos=<'level' sfloat[9] val=[1000.0,850.0,600.0,400.0,...]>>>
data=<'T' sfloat[6, 9] val=[4.25522947311401,4.68513584136963,9.936279296875,14.2176637649536,...]>>
|
Now, the policy "data doesn't read" unless I needed, was explained at the top, but they often come to the "need". When carrying out an operation like gphys.mean (0) and gphys3 = gphys1 + gphys2, for example it's so. When reading and extracting a file as it was told at a join of a change in the file format later, reading occurs once.
1: require "numru/gphys" 2: include NumRu 3: 4: gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 5: 6: #< all at once > 7: print "Case 1: all at once\n" 8: p gphys.mean(0,1).val 9: 10: #< iterate over the last dimension > 11: print "\nCase 2: iterated\n" 12: nz = gphys.axis(2).length 13: for i in 0...nz 14: p gphys[false,i].mean(0,1).val 15: end |
% ruby iterate_over_dim_1.rb
Case 1: all at onceNArrayMiss.sfloat (9): [5.058, -0.5645, -14.03, -32.75,
-49.6, -57.47, -61.5, -53.99, -42.25]
Case 2: iterated 5.05842492176078-0.564510100069102-14.0251893160636-32.7455883360746-49.5988384046053-57.4673908077485-61.4999143366228-53.9931640625-42.247435809576.
|
But the result the occasion set to one side and the occasion using ITERETA give isn't same as a Ruby object by an upper example. Because the latter is more than one zero dimensions while the former is one of one-dimensional data.
ITERETA which supports to divide calculation to huge data into GPhys and do is mounted. That's used as follows.
1: require "numru/gphys" 2: include NumRu 3: gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 4: 5: < # all at once>. 6: ofile1 = NetCDF.create('tmp1.nc') 7: gp10 = gphys*10 8: GPhys::NetCDF_IO.write(ofile1, gp10) 9: ofile1.close 10: 11: #< iterate over the last dimension > 12: ofile2 = NetCDF.create('tmp2.nc') 13: GPhys::NetCDF_IO.each_along_dims_write(gphys, ofile2, -1) do |sub| 14: sub10 = sub*10 15: [sub10] 16: end 17: ofile2.close |
In the first half After the price of the data is done 10 times. It'll be obvious to extract in a file as "tmp1.nc". The second half may be incomprehensible. Well, the same calculation is completely done, and, "tmp2.nc" It's extracted in the file which says so. But, in the case. I turn a loop about the last dimension. GPhys::NetCDF_IO.each_along_dims_write The GPhys object designated by an argument of HA the 1st is divided along the dimension designated by the 3rd argument and it's made an argument in a block, and (by an upper example, variable sub) and a return value in a block ( [sub10] which is 15 lines of eye at the top) are written in the file designated by the 2nd argument. The data I'd like to write on a file isn't always one, so the return value is made arrangement of a GPhys object. Because a return value should be the whole subset in the case, after restoring the whole right, I write notes. This last point is important, and therefore a result becomes same as the case when split application wasn't performed like an example in the first half.
The length of the last dimension will be 1 in sub at the top. When saying roughly, the following loop is being carried out.
for i in 0...gphys.shape [-1] sub = gphys[false, i..i] # doesn't put out the last dimension and makes it length 1 by i..i. ... end |
Since putting it in the return value in a block for the whole restoration, the partitioned dimension isn't supposed to go off.
Further, arrangement with more than one GPhys objects is also fine for the first argument of GPhys::NetCDF_IO.each_along_dims_write by one GPhys object. I also increase in the number of an argument in a block according to the number of the GPhys object of input. Later, it'll be possible to designate the dimension under the name, not the number. Next, the example:
GPhys::NetCDF_IO.each_along_dims_write( [gp1,gp2,gp3], ofile2, 'level') do |sub1, sub2, sub3| ... |
gp1, gp2, gp3 is divided along common axis 'level' here. Everything has an axis as 'level' of course, and when it isn't equivalent in its length, it'll be an error.
An output file, more than one, it's possible to designate it and separate the destination. The dimension used for division again, more than one, it's possible to designate it:.
GPhys::NetCDF_IO.each_along_dims_write(gp, [ofile1, ofile2], 'lat', 'level') do |sub| .... [res1, res2] end |
res1 is written by ofile2 on ofile1, res2 here. When the number of the return value is bigger than the number of files, more than one object enters a (it was designated, last) output file together.
GPhys::NetCDF_IO.each_along_dims_write extracts a result in a NetCDF file. In the future, I'll plan also to make the method as GPhys::each_along_dims which isn't extracted in a file. The input data is huge for this, but when saying that it's small, the result of the processing will be useful. (If the result was also huge, it couldn't help be taken out in a file, so that was mounted first.)
A subset of the data GPhys is, it's the whole, but it's melted, I explained already that you're able to handle it. When one of data is divided into more than one file actually contrary to that, it's possible to handle it. But, this function is mounted only about NetCDF at present.
For example we'll assume that data of the temperature of the daily mean splits with T.2001.nc,T.2002.nc, T.2003.nc every year. The moment I'll get the average of this data for 3 years and get the average from November in 2001 to February in 2002, (The person on a weather relation is good?) The necessity to attach these files first is ARU by a usual application program, well, wax. But it should be done as follows in GPhys.
gphys = GPhys::IO.open( ['T.2001.nc','T.2002.nc','T.2002.nc'],'T') |
Or.
gphys = GPhys::IO.open(/T. (\d\d\d\d). nc/, 'T') |
The former is informing GPhys::IO.open that it's to put a file in one-dimensional arrangement and is one-dimensional division. Two-dimensional division uses two-dimensional arrangement. The latter designates a file by a regular expression. It's necessary to put the pattern which changes by a file in parentheses here. When a parenthesis is one, it's meant that it's one-dimensional division.
Then, up to now, if, I'll give a demonstration of reading of a division file using the same data. First first a file will be divided, and that's read and a figure is drawn once more.
1: require "numru/ggraph" 2: include NumRu 3: gp = GPhys::IO.open ('T.jan.nc', 'T') 4: 5: # < (create test files: divide into 4 files 2 by 2)>. 6: 7: GPhys::IO.write(f=NetCDF.create('tmp00.nc'), gp[0..17,0..9, {0..6,6}]) 8: f.close 9: GPhys::IO.write(f=NetCDF.create('tmp01.nc'), gp[0..17,10..-1, {0..6,6}]) 10: f.close 11: GPhys::IO.write(f=NetCDF.create('tmp10.nc'), gp[18..-1,0..9, {0..6,6}]) 12: f.close 13: GPhys::IO.write(f=NetCDF.create('tmp11.nc'), gp[18..-1,10..-1, {0..6,6}]) 14: f.close 15: 16: # < open two-dimentionally divided data>. 17: 18: files = /tmp (\d) (\d). nc/ 19: p gpcompo = GPhys::IO.open(files, 'T') 20: 21: # < test graphics>. 22: 23: DCL.gropn(1) 24: DCL.sgpset('lcntl', false); DCL.uzfact (0.7) 25: DCL.sldiv('y',2,1) 26: GGraph.contour(gpcompo) 27: GGraph.contour(gpcompo[false,1]) 28: DCL.grcls 29: 30: #< clean up>. 31: 32: File.unlink('tmp00.nc') 33: File.unlink('tmp01.nc') 34: File.unlink('tmp10.nc') 35: File.unlink('tmp11.nc') |
2 divides data respectively about the longitude and a parallel at the top, and it's put in 4 files as tmp00.nc, tmp01.nc, tmp10.nc, tmp11.nc. That, using a regular expression, /tmp (\d) (\d). It's designated by the shape as the nc/ and GPhys object gpcompo is opened. When the result is illustrated, distribution of temperature of whole ball is indicated like the bottom. It's still lowest about the 3rd dimension (the pressure) and, only the 7th layer is cut down from the bottom. I pay attention to 2nd on a lower figure becoming a figure of 70 mb. Made file tmp??nc is put out at the end of a program.
multiple_files.rb execution result
I return to a topic of visualization again.
Above-mentioned. Use of a irb startup file for GGraph? It isn't necessary to limit to only irb. It's usually possible to employ the processing which is also at the time of GGraph use in a program as gathered one like the bottom. But, when the contents of the startup file are rewritten, the execution contents change, so I don't recommend to use it for the program kept lengthily. Because setting which will be different from dialogue processing in program execution later would be sometimes desirable, (For example it won't be usually better to change the parameter 'lwait' of DCL.) it would be better to prepare a startup file apart from one for irb actually.
1: require File.expand_path("~/.irbrc_ggraph.rb") # one for irb is diverted. 2: gphys = GPhys::IO.open('T.jan.nc', 'T') 3: GGraph.contour(gphys) 4: DCL.grcls |
It's being used to develop File.expand_path as a home directory here.
I'll make sure that a message outside the upper right limits ("lon=130.0 degrees_east") won't be indicated in the polygonal line written at the top for now. When doing that, Anders Kjor isn't included in the indicated character any more, so you don't have to restrain control character interpretation:.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.nc', 'T') 4: DCL.gropn(1) 5: DCL.uzfact(0.7) 6: GGraph.set_fig('itr'=> 2) 7: GGraph.line(gphys.cut(135,35,false), true, 'exchange'=>true, 'annot'=>false) 8: DCL.grcls |
The option 'annotate' was made false here. An option name can omit the back by right truncation (Abbreviation which agrees with more than 2 option name of course can't be done.)
Several options of the drawing method had come out up to now, but maybe it was confused at a form such as 'exchange'=>true, so it's explained. It can be put in the upper program.
GGraph.line(gphys.cut(135,35,false), true, 'exchange'=>true, 'annot'=>false) |
HA.
GGraph.line(gphys.cut(135,35,false), true, {'exchange'=>true, 'annot'=>false}) |
The abbreviation which is so (The grammatical top of Ruby is so.) And.
{'exchange'=>true, 'annot'=>false} |
A definition of HA and association arrangement (Hash) is meant. One which lines key => value at the end of an argument it means that is regarded as a definition of association arrangement. The association arrangement false assigns true to character string 'exchange' and to which is assigned to character string 'annot' is made with an upper example. When I break apart like the bottom separately, it would be easy to understand.
hash = {'exchange'=>true, 'annot'=>false} GGraph.line(gphys.cut(135,35,false), true, hash) |
GGraph.line(gphys.cut(135,35,false). true, 'exchange'=>true, 'annot'=>false) |
Since putting it in association arrangement Hash, "key" has to be perfect matching, but it's devised so that I may finish by right truncation in GGraph. They're KeywordOpt included in a Misc library, not the GPhys body and KeywordOptAutoHelp which is the sub-class to support that. A Misc library collected expensive libraries of the public who supports Ruby programming in general.
It's on a GGraph manual, but the default value of the option of each method is also checked as follows. I'll use dialogue shell irb in Ruby here. irb (main) :001:0> etc. is a prompt of irb below. The line where I have no prompts is output by irb.
% irb irb(main):001:0> require "numru/ggraph" => true irb(main):002:0> include NumRu => Object irb(main):003:0> GGraph.line(nil, true, 'help'=>true) << Description of options>> option. name. default. value. #. description: "title" nil. #. Title. of. the. figure(if nil. internally. #. determined) "annotate" true. #. if. false. do. not. put. texts. on. the. right. #. margin. even. when. newframe==true "exchange" false. #. whether. to. exchange. x and y axes "index" 1 # line/mark index "type" 1 # line type "label" nil. #. if. a String is given, it's shown as the label "max" nil # maximam data value "min" nil # minimam data value "help" false # show help message if true Current values={"annotate"=>true, "help"=>true, "title"=>nil, "type"=>1, "max"=>nil, "exchange"=>false, "index"=>1, "min"=>nil, "label"=>nil} NumRu::Misc::HelpMessagingException: ** help messaging done ** from /usr/local/lib/ruby/site_ruby/1.8/numru/misc/keywordopt.rb:343:in `interpret' from /usr/local/lib/ruby/site_ruby/1.8/numru/ggraph.rb:2389:in `line' from (irb):3 irb(main):004:0> |
After driving 2 lines you promise first (require "numru/ggraph" and include NumRu) in at the top, option 'help'=>true is designated, and GGraph.line is being carried out. Then the message indicated by one under it is indicated. Execution is stopped at this time, and it isn't drawn, so a dummy is fine for data. nil is being given at the top (the 1st argument of GGraph.line).
Then continuously, it'll indicate an option of the other drawing methods.
irb(main):004:0> GGraph.contour(nil, true, 'help'=>true)
<< Description of options>>
option. name. default. value. #. description:
"title" nil. #. Title. of. the. figure(if nil. internally. determined)
"annotate" true. #. if. false. do. not. put. texts. on. the. right.
#. margin. even. when. newframe==true
"transpose" false. #. if. true. exchange. x and y axes
"min" nil. #. minimum. contour. value.
"max" nil. #. maximum. contour. value.
"nlev" nil. #. number. of. levels.
"interval" nil. #. contour. interval.
"nozero" nil. #. delete. zero. contour.
"coloring" false. #. set. color. contours. with. ud_coloring
"clr_min" 13 # (if coloring) minimum color id
"clr_max" 100 # (if coloring) maximum color id
"help" false. #. show. help. message. if. true.
"levels" nil. #. contour. levels. (Array/NArray of. Numeric)
"index" nil. #. (if levels) line. index (es) (Array/NArray of.
#. integers. Integer. or. nil)
"line_type" nil. #. (if levels) line. type (s) (Array/NArray of.
#. integers. Integer. or. nil)
"label" nil. #. (if levels) contour. label (s) (Array/NArray of.
#. String. String. true. false. nil). nil. is.
#. recommended.
"label_height" nil. #. (if levels) label. height (s) (Array/NArray
#. of. Numeric. Numeric. or. nil). nil is recommended.
Current values={"label_height"=>nil. " annotate"=>true. "help"=>true, "title"=>nil, "coloring"=>false, "transpose"=>false, "max"=>nil, "nlev"=>nil, "line_type"=>nil, "min"=>nil, "clr_max"=>100, "index"=>nil, "levels"=>nil, "interval"=>nil, "nozero"=>nil, "label"=>nil, "clr_min"=>13}
NumRu::Misc::HelpMessagingException: ** help messaging done **
from /usr/local/lib/ruby/site_ruby/1.6/numru/misc/keywordopt.rb:343:in `interpret'
from /usr/local/lib/ruby/site_ruby/1.6/numru/ggraph.rb:1350:in `contour'
from (irb):4
irb(main):005:0>
|
An execution stop is performed by giving an exception as NumRu::Misc::HelpMessagingException so that it may be showed by this results. When using irb, when an exception rises, control returns to the user and the next prompt is indicated. When making the program a file, when an exception usually rises, execution stops. When not wanting to make them stop, you should protect at begin - rescure - end join like the bottom.
require "numru/ggraph" include NumRu begin print "\n** optoions of GGraph.line **\n" GGraph.line(nil, true, 'help'=>true) rescue end begin print "\n** optoions of GGraph.contour **\n" GGraph.contour(nil, true, 'help'=>true) rescue end |
So an execution result is omitted like a case of irb. Other methods on which a help option can be put are GGraph.fig, GGraph.axes, GGraph.mark,GGraph.tone.
I'll execute the next program.
1: require "numru/ggraph" 1: include NumRu 2: gphys = GPhys::IO.open('T.jan.nc', 'T') 3: 4 #< Opening of DCL and setting> 5: DCL.gropn(1) 6: DCL.sldiv('y',2,2) # In 2x2, screen split and the 'y'=yoko: upper left-> upper right-> lower left. 7: DCL.sgpset('lcntl', false) # doesn't interpret a control character. 8: DCL.sgpset('lfull',true) # full display 9: DCL.uzfact(0.75) # The character string size of the coordinate axis, 0.75 times 10: DCL.sgpset('lfprop',true) # uses a proportional font. 11: 12: #< Drawing by GGraph> 13: GGraph.set_fig('viewport'=> [0.150.750.150.6]) # set_*:, much effective setting 14: # The 1st of 15: GGraph.contour(gphys) 16: GGraph.tone(gphys, false, 'ltone'=>false) # In less than zero, shading 17: # The 2nd of 18: GGraph.next_fig('itr'=>2) # It's effective setting only next to the next_*:. 19: GGraph.contour(gphys.average(0), true, 'color'=>true) # iridescent contour 20: # The 3rd of 21: GGraph.set_axes('xunits'=>'','yunits'=>'') # the unit of the empty character string--> axis isn't written. 22: GGraph.tone gphys.cut true,true,70)) # Default of tone is color indication. 23: GGraph.contour(gphys.cut(true,true,70), false) # 2nd argument false -> stack describing 24: # The 4th of 25: GGraph.set_linear_contour_options('min'=>0, 'nlev'=>20) 26: # Default change in contour. next where only next time is effective_linear.. 27: GGraph.contour(gphys.average(0)) 28: 29: #< end> 30: DCL.grcls |
When it's carried out, 4 of contour and figure of the painting should be indicated like the bottom. It's written during programming, so explanation in each line won't be that necessary. Only the part is explained here. The price will be shading to the range of less than zero by 'ltone'=>false by the 16th line. An option of tone library UEPACK in DCL is just as it is for this. But, while 'ltone' == false is default in UEPACK, 'ltone' == true is made default in GGraph.
And also. I add that I concern in general. In GGraph It's generally drawn, the method hogehoge. NI vs., with the selling point of. set which changes the default value of the option_hogehoge But it exists. . The method as next_hogehoge is too long, and to make it an option or is prepared for the person to whom it itself doesn't prefer using an option, and I have an influence on only next hogehoge (as that a result gives an option to hogehoge it means that). I correct and in case of contour, splits up into (set|next) of self-reading level generation_linear_contour_options and (set|next) which designates the level positively_contour_levels. About tone which does painting/shading, like.
contour101.rb execution result
When option coloring is set in contour, color contour is generated. The color assigned to the minimum value of contour and the greatest by an option in that case can be designated (clr_min and clr_max).
contour/tone level? I have to do the specific level specification explained by the next clause. It's generated at equal intervals. In the case. Perfect trusting can also be done and. (1) the minimum value (min). (2) the maximum (max) (3) space (interval) or the number (nlev). It's possible to designate and control optional 個 over 3 parameters where it's so. When both of the space and the number are designated. The latter is ignored. Last generation? DCL.udgcl [ab] Because it's entrusted to DCL.uegtl [ab]. It was designated, it's biggest/, the minimum value is changed to the good price of the cut. Of course. A parameter of (UD|UE) PACK in icycle is also interpreted. When option ltone is made false to do shading in tone, level generation is just just stopped, so if parameter ltone in UEPACK is true actually, the color tone will be indicated as expected (And, anyway this incomprehensible name is adopted just as it is because I draw attention I say.) There is an option from which the price takes zero contour only contour (nozero).
GGraph.coloar_bar indicates a color bar about just before tone drawing (It's possible not to use a just before one and to designate the level and the pattern positively, it wouldn't be used so much.) A drawing example of a color bar is indicated in the bottom. I'd find out that it can be designated colorfully.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.nc', 'T') 4: 5: #< Opening of DCL and setting> 6: DCL.gropn(1) 7: DCL.sldiv('y',2,2) # In 2x2, screen split and the 'y'=yoko: upper left-> upper right-> lower left. 8: DCL.sgpset ('isub', 96)# issue--> The control character change : '_' which indicates '`' 9: DCL.sgpset('lfull',true) # full display 10: DCL.uzfact(0.75) # The character string size of the coordinate axis, 0.75 times 11: DCL.sgpset('lfprop',true) # uses a proportional font. 12: 13: # Drawing by < GGraph> 14: GGraph.set_fig('viewport'=> [0.150.70.20.6]) # set_*:, much effective setting 15: # The 1st of 16: GGraph.tone(gphys.cut(true,true,850)) 17: GGraph.contour(gphys.cut(true,true,850), false) 18: GGraph.color_bar # color bar (The default is lengthwise.) 19: The 2nd of 20: # 21: GGraph.next_fig ('viewport'=> [0.20.750.20.6]) 22: GGraph.tone (gphys.cut (true,true,850)) 23: GGraph.contour (gphys.cut (true,true,850) and false) 24: GGraph.color_bar ('left'=>true,'labelintv'=>1) On the# left side, indication and any labels (every 1 of* ) 25: The 3rd of 26: # 27: GGraph.next_fig ('itr'=>2) 28: GGraph.tone (gphys.mean (0) and true, 'int'=>4) 29: GGraph.color_bar ('vlength'=>0.5,"landscape"=>true,'tickintv'=>0) In 30: # length designation and the width, without indication and tick mark, (special case in 0 in case of) 31: The 4th of 32: # 33: GGraph.next_fig ('itr'=>2) 34: rmiss = DCL.glpget ('rmiss') 35: GGraph.tone( gphys.mean (0) and true, 'levels'=> 36: [rmiss,-70,-60,-50,-40,-30,-20,-10,0,10,20,rmiss]) 37: GGraph.color_bar ("voff"=>0.04) # is separated in the side slightly extra. 38: # +- infinity will be the triangle in GrADS a look. 39: 40: #< end> 41: DCL.grcls |
There is a map projection function in DCL. It's wrapped in the shape that that is easy to use and it's offered in GGraph. A projection is designated by the coordinate change number. First, please read explanation of a map projection in DCL before map projection practice in GGraph.
The map projection DCL supports is the following.
The number | Projection | Positive product | Shiyokaku | Positive calcarate |
10. | Equidistant cylindrical projection | X | X | Meridian |
11. | Meru mosquito Tor projection | X | Circle | X |
12. | Mollweide projection | Circle | X | X |
13. | Hammer projection | Circle | X | X |
14. | Eckert 6th projection | Circle | X | X |
15. | Kitada elliptical projection | Circle | X | X |
The number | Projection | Positive product | Shiyokaku | Positive calcarate |
20. | Positive calcarate conic projection | X | X | Meridian |
21. | Lambert Masashi product conic projection | Circle | X | X |
22. | Lambert Shiyokaku conic projection | X | Circle | X |
23. | Bonne projection | Circle | X | X |
The number | Projection | Positive product | Shiyokaku | Positive calcarate |
30. | Orthographic chart way | X | X | X |
31. | Polar stereographic projection | X | Circle | X |
32. | Zenithal projection | X | X | Azimuth line |
33. | Lambert's azimuthal equal-area projection | Circle | X | X |
In GGraph, to each, "It's arranged to come.", a default setting has been prepared. It'll be an easy program first and draw it by several projections.
1: itr = ARGV [0]? ARGV [0]. to_i : 10 2: 3: require "numru/ggraph" 4: include NumRu 5: gphys = GPhys::IO.open('T.jan.nc', 'T') 6: DCL.gropn(1) 7: DCL.sgpset('lcntl', false) 8: DCL.sgpset('lclip', true) 9: DCL.uzfact(0.7) 10: DCL.sgpset('lfull',true) 11: GGraph.set_fig 'itr'=>itr, 'viewport'=> [0.150.850.10.6] 12: GGraph.set_map 'coast_world'=>true 13: GGraph.tone(gphys) 14: DCL.grcls |
% ruby map_proj1.rb 10 % ruby map_proj1.rb 20 % ruby map_proj1.rb 30 |
The respective results are indicated.
ruby map_proj1.rb 10 execution result |
|
ruby map_proj1.rb 20 execution result |
ruby map_proj1.rb 30 execution result |
It's drawn by the whole screen by polar stereographic projection (number 31) in case of and default (by a definition area, to infinity). To put drawing in a viewport.
DCL.sgpset('lclip', true) |
Equidistant cylindrical projection (number 10) is a so-called latitude longitudinal coordinate. It's possible to write a coordinate axis for linear-linear orthogonal coordinate (number 10) in this case. Option 'map_axes' is designated in true in method contour, tone, line in GGraph.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::IO.open('T.jan.nc', 'T') 4: DCL.gropn(1) 5: DCL.sgpset('lcntl', false) 6: DCL.sgpset('lclip', true) 7: DCL.uzfact(0.7) 8: DCL.sgpset('lfull',true) 9: GGraph.set_fig 'itr'=>10, 'viewport'=> [0.150.850.10.6] 10: GGraph.set_map 'coast_japan'=>true 11: GGraph.tone(gphys.cut('lon'=>120..150,'lat'=>20..50), true, 'map_axes'=>true) 12: DCL.grcls |
map_axes_itr10.rb execution result
There is an option on a map projection relation in GGraph::fig and GGraph::map. A map related option of GGraph::fig, the following:
A main option of GGraph::map, the following:
For more information, it's indicated in option help like the bottom.
>>require "numru/ggraph" => true >>NumRu::GGraph.fig nil, nil, 'help'=>true << Description of options>> option name default value # description: "new_frame" true # whether to define a new frame by DCL.grfrm # (otherwise, DCL.grfig is called) "itr" 1 # coordinate transformation number "viewport" [0.2 or 0.8 or 0.2 or 0.8] # [vxmin, vxmax, vymin, vymax] "window" nil # (for itr.<10,> 50) [uxmin, uxmax, uymin, uymax]. # each element allowd nil (only for itr<5,> 50) "xreverse" "positive:down,units:hPa" # (for itr<10,> 50) Assign. # (max value to UXMIN and min value to UXMAX if # condition is satisfied nil:never, true:always, # String: when an attibute has the value specified # ("key:value,key:value,..") "yreverse" "positive:down,units:hPa" # (for itr<10,> 50) Assign. #. max. value. to. UYMIN. and. Min value. to. UYMAX. if. #. condition. is. satisfied. (nil:never. true:always. #. String: when. an. attibute. has. the. value. specified. #. ("key:value,key:value,..") "similar" nil. #. 3-element float. array. for. similar. #. transformation. in. a rectangular curvilinear #. coordinate. which. is. fed. in. #. DCL:grssim: [simfac,vxoff,vyoff]. where. simfac. #. and. [vxoff,vyoff] represent. scaling. factor. and. #. origin. shift. respectively. "map_axis" nil. #. (for all. map. projections) 3-element float. #. array. to. be. fed. in. DCL::umscnt: [uxc. uxy. rot]. #. where. [uxc. uyc] represents. the. tangential. point. #. (Or. the. pole. at. top. side. for. cylindrical. #. projections). and. rot. represents. the. rotation. #. angle. If. nil. internally. determined. (units: #. degrees) "map_radius" nil. #. (for itr>=20: conical/azimuhal map. # projections) raidus around the tangential point. # (units: degrees) "map_fit" nil # (Only for itr=10(cylindrical) and 11 # (Mercator)) true: fit the plot to the data window # (overrides map_window and map_axis); false: do # not fit (then map_window and map_axis are used); # nil: true if itr==10, false if itr==11 "map_window" [-180, 180, -75, 75] # (for itr<20: cylindrical # map projections) lon-lat window [lon_min, # lon_max, lat_min, lat_max ] to draw the map # (units: degres) "help" false # show help message if true Current values={"map_window"=>[-180, 180, -75, 75], "help"=>true, "similar"=>nil, "map_axis"=>nil, "window"=>nil, "new_frame"=>true, "itr"=>1, "map_fit"=>nil, "yreverse"=>"positive:down,units:hPa", "viewport"=>[0.2, 0.8, 0.2, 0.8], "xreverse"=>"positive:down,units:hPa", "map_radius"=>nil} NumRu::Misc::HelpMessagingException: ** help messaging done ** from /usr/local/lib/ruby/site_ruby/1.8/numru/misc/keywordopt.rb:386:in `interpret' from /usr/local/lib/ruby/site_ruby/1.8/numru/ggraph.rb:2261:in `fig' from (irb):5 > >NumRu::GGraph.map 'help'=>true << Description of options>> option. name. default. value. #. description: "lim" true. #. draw. map. lim. (t or f) "grid" true. #. draw. map. grid. (t or f) "vpt_boundary" false. #. draw. viewport. boundaries. (f. t or. #. 1,2,3.., representing. the. line. width) "wwd_boundary" false. #. draw. worksation. window. boundaries. (f. t. #. or. 1,2,3.., representing. the. line. width) "fill" false. #. fill. the. map. if. coast_world or. coast_japan is. #. true. (t or f) "coast_world" false. #. draw. world. coast. lines. (t or f) "border_world" false. #. draw. nation. borders. (t or f) "plate_world" false. #. draw. plate. boundaries. (t or f) "state_usa" false. #. draw. state. boundaries. of. US. (t or f) "coast_japan" false. #. draw. japanese. coast. lines. (t or f) "pref_japan" false. #. draw. japanese. prefecture. boundaries. (t or. #. f) "dgridmj" nil. #. the. interval. between. the. major. lines. of. #. latitudes. and. longitudes. If. nil. internally. #. determined. (units: degrees) (this is. a UMPACK #. parameter. which. is. nullified. when. uminit. or. #. grfrm. is. called) "dgridmn" nil. #. the. interval. between. the. minor. lines. of. #. latitudes. and. longitudes. If. nil. internally. #. determined. (units: degrees) (this is. a UMPACK #. parameter. which. is. nullified. when. uminit. or. #. grfrm. is. called) "help" false. #. show. help. message. if. true. Current. values={"dgridmn"=>nil. "help"=>true, "border_world"=>false, "lim"=>true, "wwd_boundary"=>false, "fill"=>false, "coast_japan"=>false, "dgridmj"=>nil, "vpt_boundary"=>false, "coast_world"=>false, "plate_world"=>false, "grid"=>true, "state_usa"=>false, "pref_japan"=>false} NumRu::Misc::HelpMessagingException: ** help messaging done ** from /usr/local/lib/ruby/site_ruby/1.8/numru/misc/keywordopt.rb:386:in `interpret' from /usr/local/lib/ruby/site_ruby/1.8/numru/ggraph.rb:2546:in `map' from (irb):6 |
When I make this sample program run, 5 lower figures are obtained. When there is a part they seem to use the function I want where, please consult.
The 1st |
The 2nd |
The 3rd |
The 4th |
The 5th |
The height is so low that the pressure is big for certain, so then it's convenient, to designate nothing, well something for is it because it's operated opaquely some? Well, I have written on an original NetCDF file that I should do that, so it's until that's interpreted. When indication by ncdump in T.jan.nc is seen, there is a positive attribute only in variable level, and the price is "down". There is no this on a NetCDF user guide, but it's the average attribute by many conventions (Refer to gtool4NetCDF agreement.)
Then, how should data without the positive attributes be done? I also consider that and am made, so GGraph is OK. Specifically, the default value of the parameter of method fig should be changed.
I'll execute a program in the following only 2 lines first. (Even if it isn't made a file intentionally, irb is enough.)
require "numru/ggraph" NumRu::GGraph.fig(nil, true, 'help'=>true) |
Then the menu of the option is indicated as follows.
% ruby fig_help.rb
<< Description of options>>
option name default value # description:
"new_frame" true # whether to define a new frame by DCL.grfrm
# (otherwise, DCL.grfig is called)
"itr" 1 # coordinate transformation number
"viewport" [0.2 or 0.8 or 0.2 or 0.8] # [vxmin, vxmax, vymin, vymax]
"window" nil # (for itr.<10,> 50) [uxmin, uxmax, uymin, uymax].
# each element allowd nil (only for itr<5,> 50)
" xreverse" "positive:down,units:hPa" # (for itr<10,> 50) Assign.
# (max value to UXMIN and min value to UXMAX if
# conditionis satisfied nil:never, true:always,
# String: when an attibute has the value specified # ("key:value,key:value,..")
"yreverse" "positive:down,units:hPa"
# (for itr<10,> 50) Assign.
#. max. value. to. UYMIN. and. Min value. to. UYMAX. if.
#. condition. is. satisfied. (nil:never. true:always.
#. String: when. an. attibute. has. the. value. specified.
#. ("key:value,key:value,..")
" similar" nil. #. 3-element float. array. for. similar.
#. transformation. in. a rectangular curvilinear
#. coordinate. which. is. fed. in.
#. DCL:grssim: [simfac,vxoff,vyoff]. where. simfac.
#. and. [vxoff,vyoff] represent. scaling. factor. and.
#. origin. shift. respectively.
" map_axis" nil. #. (for all. map. projections) 3-element float.
#. array. to. be. fed. in. DCL::umscnt: [uxc. uxy. rot].
#. where. [uxc, uyc] represents the tangential point
# (or the pole at top side for cylindrical
# projections) and and rot represents the rotation # angle. If nil, internally determined. (units: # degrees)
"map_radius" nil # (for itr>=20: conical/azimuhal map # projections) raidus around the tangential point. # (units: degrees)
"map_lat_range" nil # (for itr<20: cylindrical map projections)
# latitudinal range to draw the map. By default
# (nil), the map is drawn between 75E and 75S.
# (units: degres)
"help" false # show help message if true
Current values={"help"=>true, "similar"=>nil, "map_axis"=>nil, "window"=>nil, "new_frame"=>true, "itr"=>1, "map_lat_range"=>nil, "yreverse"=>"positive:down,units:hPa", "viewport"=>[0.2, 0.8, 0.2, 0.8], "xreverse"=>"positive:down,units:hPa", "map_radius"=>nil}
/usr/local/lib/ruby/site_ruby/1.8/numru/misc/keywordopt.rb:343:in `interpret': ** help messaging done ** (NumRu::Misc::HelpMessagingException)
from /usr/local/lib/ruby/site_ruby/1.8/numru/ggraph.rb:2083:in `fig'
from fig_help.rb:2
|
The coordinate value of the end at the top and the bottom of the left and right on a figure (uxmin. uxmax. uymin. uymax) is an option. window. Because it's so and decided. When I'd like to replace left and right of a coordinate axis/the top and the bottom. It's Kazunori to establish this positively. But. Then when I'd like to write various figures, it's inconvenient. So. window. Without setting O. I'll change a regulation of an automatic judgement. It's option xreverse, yreverse to do that. Upper output shows that the default value becomes "positive:down,units:hPa" together. When or attribute units exists in attribute positive exists, and whether its price is "down", and its price is "hPa", this means that the left and right or the top and the bottom is made reverse. The pressure was being given special treatment as expected actually by caring, but the unit of level is milibar, not hPa by the data used this time, so I don't have that because of that.
The default value, for example, when changing it to "units:mb,units:hPa,units:milibar", attribute units will be the setting which turns one of "mb", "hPa" and "milibar" over in in case of:.
GGraph.set_fig("xrev"=>"units:mb,units:hPa,units:milibar", "yrev"=>"units:mb,units:hPa,units:milibar") |
On the other hand, when I'd like not to regard the pressure as special and to fight only by postive purely, it should be made "positive:down". When setting nil in xreverse, yreverse, further turning isn't always performed, and when making it true, it's always turned over. When window is designated positively of course even if I go, I follow that.
It's possible to designate the level of contour and the tone (painting) positively by arrangement in GGraph.
The tone is designated by the level and the pattern number. The pattern number designates the color and the tone pattern at the same time. Refer to a manual of <ahref="http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/" target=_top>RubyDCL (the "outline" of GRPH1) for its specification. When (establishing the tone by GGraph.set_tone_levels or using in after continuing way) in GGraph, it's designated by option 'levels' of GGraph.tone and 'patterns' (its place limit). (When the latter is used in the still present mounting, GGraph.set_tone_levels before that becomes invalid, if I meet, it's expected to revise.)
Then a method is indicated by an example.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 4: 5: #< Opening of DCL and setting> 6: DCL.gropn(1) 7: DCL.sldiv 'y',2,2) # In 2x2, screen split and the 'y'=yoko: upper left-> upper right-> lower left. 8: DCL.sgpset('lcntl', false) # doesn't interpret a control character. 9: DCL.sgpset('lfull',true) # full display 10: DCL.sgpset('lfprop',true) uses a# proportional font. 11: 12: #< Drawing by GGraph> 13: GGraph.set_fig('viewport'=> [0.150.820.150.6]) 14: # The 1st of 15: GGraph.set_tone_levels( 'levels'=> [-20,-15,-10,-5,0], 16: 'patterns'=> [10,999,209,993,099,940,999]) 17: GGraph.tone(gphys) 18: # The 2nd of 19: GGraph.tone( gphys, true, 'lev'=> [-20,0,20], # the level and the pattern are designated positively. 20: 'pat'=> [20,999,409,997,099,980,999] # The way where ) is bang, 1 of many-> is to a+-infinite. 21: GGraph.contour(gphys, false, 'lev'=> [-20,0,20], 'index'=>3) # Until reference. 22: # The 3rd of 23: GGraph.tone( gphys, true, 'lev'=> [-20,0,20]. 24: 'pat'=> [409,997,099,980,999] ) # Even a+ infinite expands the level and the same number->. 25: # The 4th of 26: GGraph.tone( gphys, true, 'lev'=> [-20,0,20]. 27: 'pat'=> [4,099,970,999] ) # The way where is bang applies during few->. 28: #< end> 29: DCL.grcls |
15 lines are explained more than an eye. By 15-16 line The level of the tone and the pattern number are established. GGraph.set_tone_levels Then. ' levels' TO ' Both parameters of patterns' are designated by arrangement. To mix with in case of GGraph.tone and after-mentioned contour and the form, I'm taking the form of an option. Both of them can't be omitted (It isn't an option it means that actually.) If the level is established, I also have to designate the color at the same time. 17 line? The 1st figure is drawn with just before setting. By 19-20 line The level and the pattern. GGraph.tone It's designated positively as the option which is so. The 2nd is being drawn. There are 1 elements a lot more than the level for the designated pattern. In that case. -An infinite levels [0], levels [1] and .., levels [-1] , + infinite Time, it's applied. As I stated that the back with an option name can be omitted already. contour was piled up and written and made sure that the tone level was still easy to understand. It's mentioned later about level setting of contour. 23-24 line draws the 3rd. It's equivalent in the number of elements of the level and the pattern, but levels [0], levels [1], .., levels [-1] and between the+ infinite are applied in this case. The one which is the pattern by 4th of 26-27 line, there are few 1 elements, so one between levels applies. A relation of the number of elements of the level and the pattern, an exception generates in case of besides these.
The way to designate contour level positively by arrangement is explained. One in case of contour? The thicknesses which are a line in 1 and 1 There are various parameters. I also have to decide those. GGraph. Then. As far as the user's flight is considered, and it's possible, you can omit or simplify it. When designating setting of the level as the in case of established in GGraph.set_contour_levels (When it's used in after continuing way.) by an option of GGraph.contour like tone in case of, there are 2 ways of (its place limit). A designated parameter is always 'index', 'line_type','label', 'label_height' by an option as well as necessary 'levels'. (These are a parameter of DCL.udsclv. GGraph conforms to a regulation as follows, and decides about omitted one, and calls DCL.udsclv.)
Then I'll execute the following program.
1: require "numru/ggraph" 2: include NumRu 3: gphys = GPhys::NetCDF_IO.open('T.jan.nc', 'T') 4: 5: #< Opening of DCL and setting> 6: DCL.gropn(1) 7: DCL.sldiv('y',2,2) # In 2x2, screen split and the 'y'=yoko: upper left-> upper right-> lower left. 8: DCL.sgpset('lcntl', false) # doesn't interpret a control character. 9: DCL.sgpset('lfull',true) # full display 10: DCL.sgpset('lfprop',true) # uses a proportional font. 11: 12: #< Drawing by GGraph> 13: GGraph.set_fig('viewport'=> [0.150.820.150.6]) 14: levels = 5* (NArray.float(7).indgen!) # NArray: [0,5,10...] 15: mj = DCL.udpget('indxmj') 16: mn = DCL.udpget('indxmn') 17: # The 1st of 18: GGraph.set_contour_levels('levels'=>levels, 'index'=>mj) # Contour setting 19: GGraph.contour(gphys) 20: # The 2nd of 21: GGraph.contour( gphys, true, 'lev'=>levels, 22: 'index'=> [mj,mn], 'line_type'=> [1222]) 23: # The 3rd of 24: GGraph.contour( gphys, true, 'lev'=>levels, 25: 'index'=>mn, 'label'=>true ) 26: # The 4th of 27: GGraph.contour( gphys, true, 'lev'=>levels, 28: 'index'=>mn, 'label'=> ['A','B','C','D'], 29: 'label_height'=> [0.0150.020.0250.03]) 30: #< end> 31: DCL.grcls |
By 14 line The contents. [0510...] One-dimensional arrangement of NArray where it's so is being generated. indgen!, the contents [012..] Please, it's often used in NArray by the changed method. It's whether the thickness of the line (index) is equal to parameter 'indxmj' of UDPACK by default, and it's judged whether a label is written in contour (for defaults, 3). 18 lines of that's designated as option 'index' by an eye, so there is 19 lines of label which indicates contour level value in contour written by an eye. When scalar is designated by an option of 'index', its price is applied to all contours.
The 2nd of figure after a while? contour. The levels are designated positively by the option which is so, and it's being drawn. By the 2nd index. HA. [mj. mn] It's granted by arrangement. In that case. [mj. mn. mj. mn,...] It's interpreted as the repeat which says so. About other options, like. You understand that line_type is [1222], so [1,2,2,2, 1,2,2,2..] label is designated with true by the 3rd figure, so a label is written in all contours. A character string of a label is designated positively by the 4th (label generates and writes the character string in which true expresses contour level inside, when a character string was given, that's used.) The size of the character string is established each by label_height by the 4th. But I'd want to change ordinariness uniformly. I recommend not to use label_height and to change parameter RSIZEL in UDPACK in that case.
contour201.rb execution result
I'd want to be absorbed in a layout by a figure for making a fair copy taken out in a contribution thesis. GGraph tends to utilize a strong layout function of DCL.
require "numru/ggraph" include NumRu gphys = GPhys::NetCDF_IO.open('T.jan.nc','T') DCL.uzfact DCL.gropn(1) DCL.sgpset('lcntl', false) # doesn't interpret a control character DCL.sgpset('lfull',true)# full display DCL.sgpset('lcorner',false) # doesn't write coner mark DCL.uzfact(0.35) # The character string size of the coordinate axis, fixed number double DCL.sgpset('lfprop',true) # proportional font DCL.udpset ('lmsg',false)# contour interval nondisplay vpt = NArray [0.05, 0.45, 0.05, 0.25] # viewport size (2:1) vpt00 = (vpt + ([0.050 ]* 2 + [0.32]* 2)).to_a # It's shifted in x and the y-direction, and becomes Array vpt01 = (vpt + ([0.474 ]* 2 + [0.32]* 2)).to_a # It's shifted in x and the y-direction, and becomes Array vpt10 = (vpt + ([0.050 ]* 2 + [0.10]* 2)).to_a # It's shifted in x and the y-direction, and becomes Array vpt11 = (vpt + ([0.474 ]* 2 + [0.10]* 2)).to_a # I shift in x and the y-direction and become Array. GGraph.set_fig('viewport'=>vpt00) GGraph.set_axes('xunits'=>'','yunits'=>'','xtitle'=>'') DCL.uzpset('labelxb',false) GGraph.contour(gphys.cut (true,true,1000), true, 'annot'=>false, 'titl'=>'') DCL.uzpset('pad1',0.2); DCL.uxsttl('t','1000hPa',-1); DCL.uzpset('pad1',0.7) GGraph.set_fig('viewport'=>vpt01, 'new_frame'=>false) GGraph.set_axes('ytitle'=>'') DCL.uzpset('labelyl',false) GGraph.contour(gphys.cut(true,true,250), true, 'annot'=>false, 'titl'=>'') DCL.uzpset('pad1',0.2); DCL.uxsttl('t','250hPa',-1); DCL.uzpset('pad1',0.7) GGraph.set_fig('viewport'=>vpt10, 'new_frame'=>false) GGraph.set_axes('ytitle'=>nil,'xtitle'=>nil) DCL.uzpset('labelyl',true); DCL.uzpset('labelxb',true) GGraph.contour(gphys.cut(true,true,70). true, 'annot'=>false, 'titl'=>'') DCL.uzpset('pad1',0.2); DCL.uxsttl('t','70 hPa',-1); DCL.uzpset('pad1',0.7) GGraph.set_fig('viewport'=>vpt11, 'new_frame'=>false) GGraph.set_axes('ytitle'=>'') DCL.uzpset('labelyl',false) GGraph.contour(gphys.cut(true,true,10), true, 'annot'=>false, 'titl'=>'') DCL.uzpset('pad1',0.2); DCL.uxsttl('t','10hPa',-1); DCL.uzpset('pad1',0.7) DCL::sgtxzv(0.5, vpt00[3]+ 0.028, 'January Monthly Mean Temperature', 1.15*DCL.uzpget('rsizec2'), 003) DCL.grcls print "\n** PRESSURE LEVELS ** " ; p gphys.coord(2).val. |
GGraph trusts coordinate axis drawing to USPACK in DCL (DCL.usxaxs,DCL.usyaxs is called.) How should it be done then to put a date axis and control a coordinate axis smaller using U [XY] PACK? I don't make GGraph write the response for the moment, it's written by itself. Method axes which writes a spindle in GGraph can control a drawn axis by option 'xside', 'yside' as follows. If only the bottom draws an X axis, for example it's 'xside'=>'b'. An original value of default, 'xside'=>'tb','yside'=>'lr'.
require "numru/ggraph" include NumRu gphys = GPhys::IO.open('T.jan.nc','T') DCL.gropn(1) DCL.sgpset('lfull',true); DCL.uzfact(0.6) GGraph.set_fig('itr'=> 2, 'viewport'=> [0.250.70.150.6]) GGraph.set_axes('xside'=>'b','yside'=>'l') GGraph.line(gphys.mean(0,1), true, 'exchange'=>true, 'annot'=>false) DCL.grcls |
A coordinate axis should be written on the place which wasn't written using GGraph from later for UCPACK.
GPhys is made so that it may be useful for structure making to access the data put in the remote server as well as the file on the local disk. A remote object offer by cgi as OPeNDAP/DODS and the example for which a dispersion object library in Ruby as dRuby is used are indicated at below.
The making volume of "client using dRuby and James Grover Thurber", the 1 and making volume It's remote in its 2, mechanism is explained using the easy example on which an offered GPhys object was fixed. When I'd like to use mechanism at any rate, I skip, and I hope that you advance towards the leaving volume using GDir. It's remote in a directory tree using GDir, it's explained about GPhys built-in library gphys to access- remote.
OPeNDAP/DODS is remote data offer service by a CGI. It's a numerical data of the physical quantity which fitted into the file by which the data with which I deal is NetCDF and is used by various servers. An oceanographer has begun to develop it at first, and I have the station data which are buoys by (DODS=Distributed Ocean Data Sytem) and grid point data in mind, and it has been developed. The file format of the plural is being supported with to abstract a data structure by the meaning like GPhys in penetrating way.
OPeNDAP/DODS is object-ized like GPhys which consists of the coordinate value and grid point value by the data structure called "Grid" (class). When it's the NetCDF file which got on OPeNDAP/DODS server, a coordinate variable is interpreted and a Grid object is formed automatically.
A NetCDF client library corresponding to OPeNDAP/DODS is offered, and when this is used, it's to give Uniform Resource Locator of OPeNDAP/DODS instead of the file name of NetCDF, and it's possible to read directly without downloading remote data. The file on the server side doesn't have to be NetCDF in the case, but it's necessary to have NetCDF-like data structure. Much of station data and HDF data isn't based on this.
When a NetCDF client corresponding to OPeNDAP/DODS is installed, when compiling, Ruby where I'm a subcontractor of GPhys/NetCDF is the setting with which that's linked. Even a binary package for Vine and Debian is so. You can just give OPeNDAP/DODS URL as the file name and read and write like a NetCDF file locally in this case.
Then I'll access data. The Meteorological Agency forecast data on the computer club data server is used here. It's possible to browse a directory (holder) like a usual html server in OPeNDAP/DODS: Data of <ahref="http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/" target=_top> these days for 1 week. I'll access information on a data file of air pressure face data of the latest forecast data of Asia area model RSM. The one which html-ized header information on the NetCDF file put in should be indicated. I find out that a variable name has temp.
Then, it'll visualize this. It'll be carried out interactively using irbrc introduced by "use of a startup file (2) Use of-- GDir"_ggraph.
% irb_ggraph --simple-prompt Start interactive GGraph session *** MESSAGE (SWDOPN) *** GRPH1 : STARTED / IWS = 1. >>GPhys::IO.var_names('http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc') => ["lon", "lat", "p", "time", "ref_time", "z", "u", "v", "temp", "rh", "omega"] >>temp = GPhys::IO.open('http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc', 'temp') => <GPhys grid=<4D grid. <axis pos=<'lon' in. ' http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc' sfloat [60], >> <axis pos=<'lat' in. ' http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc' sfloat[75]>> <axis pos=<'p' in 'http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc' sfloat[16]>> <axis pos=<'time' in 'http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc' sfloat[18]>>> data=<'temp' in 'http://davis-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/jmadata/gpv/latest/gpv/latest/RSM_P_latest.nc' sfloat[60, 75, 16, 18]>> >>set_fig 'itr'=>10 => {"itr"=>1}, >>set_map 'coast_japan'=>true => {"coast_japan"=>false}, >>tone temp => nil >>contour temp, false => nil |
Above, a figure like the bottom breaks off.
Attention: Here is transferred, and I hope that you advance towards the leaving volume using GDir to use it quickly.
dRuby. The library where I made sure that you can expand a method calling of HA , Ruby and do a method calling over a network. Standards are attached to Ruby 1.8. It should be even downloaded and installed to Ruby 1.6. When dRuby is used, you can access an object on the process like access to a local object remotely. Even if a communication partner is different in moving mechanical OS, it's no problem. Even if it's called ..., it's how useful or I may not come tightly, so it's indicated by an example.
1: require "drb/drb" 2: require "numru/gphys" 3: include NumRu 4: gp = GPhys::IO.open("T.jan.nc","T") 5: DRb.start_service(nil, gp) 6: puts 'URI: '+DRb.uri 7: puts ' [return] to exit' 8: gets |
1 line? dRuby. The load which is so. 2-4 line is familiar. Here File T.jan.nc Medium variable I compose a GPhys object from T. Variable gp. NI is assigned. From the next. Increasingly. dRuby. The appearance which is so. 5 lines were made an eye destination. GPhys. An object, as "front-end", dRuby. Service has been started. Then when having accessed, a different process will be a reference to this GPhys object to return it at first. The 1st argument of DRb.start_service is made nil, so the port used for communication is decided automatically (It's possible to designate a port.) 6 lines of URI for access including the portnumber (Uniform Resource Locator) is indicated by an eye. I enter 8 lines in input waiting in gets of an eye so as not to make a process end. When pressing a new paragraph key, it ends, so it indicates' [return] to exit' by , 7 line. Then, first, this server, dispatch it would like.
% ruby druby_serv1.rb
URI: druby://horihost:45461
[return] to exit
|
A protocol is druby in indicated URI, and the host name means that horihost and assigned portnumber are 45461. The host name is a machine dependent of course and, (It was generated automatically, so.) portnumber is execution, a degree, it can change.
Next the client's easy example connected to this server is indicated.
1: require "drb/drb" 2: DRb.start_service 3: uri = ARGV.shift || raise ("Usage: % # {$0} uri") 4: gp = DRbObject.new(nil, uri) 5: p gp.class 6: p gp.name 7: p gp.rank 8: p gp.shape 9: print gp.coord(2).name,"\n" |
Before explaining a program, it'll indicate the result when carrying this out. URI of a server went out with druby://horihost:45461 a short while ago, so to access that, as follows, dispatch.
% ruby druby_cli1.rb druby://horihost:45461
DRb::DRbObject
"T"
3
[36, 19, 9]
level
|
Now. A source and an execution result are explained. 1 line of a source is same as a server. By 2 line DRb.start_service is being called. In case of without arguments? Without front-end objects. From other processes. This is fine as the client who doesn't receive the connection which is so. By 3 line When carrying out, the argument to which it was given is being read. || Below? When there were no arguments, an exception is given and execution is stopped. By an upper example, an argument? druby://horihost:45461 So. This, as a character string, variable uri. NI is substituted. By 4 line DRbObject.new(nil. By uri). This. uri. NI vs., it's done and a connection is established. As a result. An object for references to a front-end object in a server is made. Variable gp. NI is substituted. Therefore. Here gp? Temperature data (GPhys where a server opened An object) will be represented. In 5 line after a while To this front-end. Various messages are sent. The result is output in standard output. I'll compare output with a source. By 5 line I inquire of gp a class. The method class. HA is disposed of locally. I show that it's a remote object of dRuby. (class where DRb::DRbObject is indicated An object of all HA lasts, so there are no methods by which ). 6 line after a while DRb::DRbObject also has of course is name in DRb::DRbObject, so the result is sent to the server and carried out, and corresponds with a client. It becomes clear that the name is three-dimensional data of "T" in this way. Be still careful about not loading a GPhys library by a client program. When the one a client needs is only a reference to a GPhys object, it isn't necessary.
1: require "numru/gphys" 2: include NumRu 3: gp = GPhys::IO.open("T.jan.nc","T") 4: p gp.class 5: p gp.name 6: p gp.rank 7: p gp.shape 8: print gp.coord(2).name,"\n" |
The execution result is as follows. It's just similar but output class name was GPhys.
% ruby druby_self-contained1.rb
NumRu::GPhys
"T"
3
[36, 19, 9]
level
|
1: require "drb/drb" 2: require "numru/ggraph" 3: include NumRu 4: 5: class NArray 6: def self._load(o); to_na(*Marshal::load(o).ntoh; end 7: def _dump(limit); Marshal::dump( [hton.to_s, typecode, *shape]); end 8: end 9: 10: gp = GPhys::IO.open("T.jan.nc","T") 11: DRb.start_service(nil, gp) 12: puts 'URI: '+DRb.uri 13: puts ' [return] to exit' 14: gets |
Now, I'm a client. Here, like, NArray is expanded.
1: require "drb/drb" 2: require "numru/ggraph" 3: include NumRu 4: 5: class NArray 6: def self._load(o); to_na(*Marshal::load(o)).ntoh; end 7: end 8: 9: DRb.start_service 10: uri = ARGV.shift || raise ("Usage: % # {$0} uri") 11: gp = DRbObject.new(nil, uri) 12: DCL.gropn(1) 13: DCL.sldiv('y',2,1) 14: DCL.sgpset('lcntl',false) 15: DCL.uzfact(0.7) 16: GGraph.set_fig('viewport'=> [0.150.750.20.8]) 17: GGraph.contour(gp.cut('level'=>100)) 18: GGraph.next_fig('itr'=>2) 19: GGraph.contour(gp.mean(0)) 20: DCL.grcls |
The server side:
% ruby druby_serv2.rb
URI: druby://horihost:45469
[return] to exit
|
The client side:
% ruby druby_cli2.rb druby://horihost:45469
*** MESSAGE (SWDOPN) *** GRPH1 : STARTED / IWS = 1.
*** WARNING (STSWTR) *** WORKSTATION VIEWPORT WAS MODIFIED.
*** MESSAGE (SWPCLS) *** GRPH1 : PAGE = 1 COMPLETED.
*** MESSAGE (SWDCLS) *** GRPH1 : TERMINATED.
|
druby_cli2.rb execution result
After acquiring a front object of a server once by a client like the example a short while ago, as there is data locally, it's being handled.
require "numru/ggraph" include NumRu gp = GPhys::IO.open ("T.jan.nc","T") DCL.gropn(1) DCL.sldiv('y',2,1) DCL.sgpset('lcntl',false) DCL.uzfact(0.7) GGraph.set_fig('viewport'=>[0.150.750.20.8]) GGraph.contour(gp.cut('level'=>100)) GGraph.next_fig('itr'=>2) GGraph.contour(gp.mean(0).copy) DCL.grcls |
The library where dRuby developed as another package is used and a package of the command as <ahref="http://ruby.gfd-dennou.org/products/gphys-remote/">gphys-remote were taken in GPhys more than GPhys-0.5.0. The whole directory tree below the starting point which is the case that a front-end object of dRuby makes GDir a server of gphys - remote and is suitable, remote, I make it accessible (It's read - only.) On the other hand, a dRuby client edition of a startup file for irb to use GDir introduced at the top is prepared, so you can access remote data putting it in the local file system, and like using GDir to use this. Therefore a remote file system can be browsed like a ftp and an analysis of data and visualization can be performed. Further, it's possible to connect gave to gphys-remote server.
When GPhys - remote is installed, command gdir_server and gdir_client are installed. The former is a server program for a GDir remote offer, and the latter is the client program to access the former. The contents of command gdir_client are just.
irb -r numru/gdir_connect_ftp-like |
It is. In other words," numru/gdir_connect_ftp-like" require, at the top, irb, dispatch as something it's substance. When I'd like to read a different startup file for visualization, it's by a command line.
% irb -r ~/.irbrc_ggraph -r numru/gdir_connect_ftp-like
|
I hope that you make it NADO.
Then first I'll start a server. The data included in a GPhys distribution package will be used, so in the top directory which developed that, cd, there is made a starting point of service as a root directory of a server:.
% cd gphys-0.5.0 % gdir_server . -a all URI: druby://horihost:45954 [return] to exit |
The first argument of gdir_server (Here".") is designation of a root directory. The one designated in-a is the host who permits a connection. Access from all hosts is permitted by an upper example only by a local host, so the default isn't desirable. Because-a option can be designated repeatedly.
% gdir_server . -a '192.168.1.*'-a localhost
|
Indication of gdir_server execution result above-mentioned shows that Uniform Resource Locator of a server was druby://horihost:45954. Portnumber 45954 is the space port assigned automatically. It's done as follows to designate a port and the host name positively.
% gdir_server . 12345 % gdir_server . localhost:12345 |
Next I'll connect to this server using ,gdir_client (or, irb -r numru/gphys_connect_ftp-like). Uniform Resource Locator of a server can be visited first, so it's input. When making the back help, you'd be able to use it.
% gdir_client ** A GPhys service client. To conetct, type in server's URI (return) (format: druby://host:port) . Type in help to see usage. URI>>druby://horihost:45954 *************************************************************** * WELCOME! * * You logged in druby://tsudalx3:45954 * with /usr/local/lib/ruby/site_ruby/1.8/numru/gdir_connect_ftp-like.rb: * an irb-based ftp-like client of a gphys service (such as gdir_server.rb). * * This client is to be started as * * % irb --noinspect -r "numru/gphys_connect_ftp-like" * * if you're running on a interactive ruby shell such as irb. * quit and start again like this. *************************************************************** Type in helpfor available methods irb(main):001:0> help. = irb start-up program numru/gdir_connect_ftp-like (A ftp-like client of GPhys directory services e.g., gdir_server.rb). Connection is based on dRuby. == Usage At command line, % irb --noinspect -r numru/gphys_connect_ftp-like then type in the URI of the server. == Available Methods Native methods: help help_more ls dir pwd cd (path) open (name) readtext (name) start_dcl (iws=1, iwidth=500, iheight=500, uzfact=1.0) All GGraph methods: contour (gphys) line (gphys) etc.etc. Type in help_moreFor more info. => nil irb(main):002:0> help_more == Methods---help Show. a help message ---help_more Show. a further help message ---ls List. the. directory.---dir---ls_l Like. ls. but. with. a long descriptive format ---pwd Prints the path of the current directory.---open (name) (opens a GPhys, where name is a variable name in the current directory shown by ls without trailing "/").---readtext (name) (prints the contents of the text file in the current directory shown by ls with remarks as such).---start_dcl (iws=1, iwidth=500, iheight=500, uzfact=1.0) To start RubyDCL (Calls DCL.gropn (iws)). Call this before using GGraph module functions such as contour.---contour---line GGraph methods => nil irb(main):003:0> ls Directories: 'bin/' 'doc/' 'lib/' 'sample/' 'test/' 'testdata/' Text files?: 'ChangeLog' 'README' 'TODO_ep_flux' => nil irb(main):004:0> ;cd 'testdata' /testdata/ => nil irb(main):005:0> ls Directories: 'T.jan.ctl/' 'T.jan.grib/' 'T.jan.nc/' 'T.jan.packed.withmiss.nc/' => nil irb(main):006:0> cd 'T.jan.ctl/' /testdata/T.jan.ctl/ => nil irb(main):007:0> ls. Data: 'T' => nil irb(main):008:0> gphys = open 'T' => #<drb::drbobject:0x40a092ac @uri="druby://horihost:45954" ,="" @ref="541737212"> irb(main):009:0> start_dcl(1, 700, 700) *** MESSAGE (SWDOPN) *** GRPH1 : STARTED / IWS = 1. => nil irb(main):010:0> contour gphys *** WARNING (STSWTR) *** WORKSTATION VIEWPORT WAS MODIFIED. => nil irb(main):011:0> contour gphys.mean(0) *** MESSAGE (SWPCLS) *** GRPH1 : PAGE = 1 COMPLETED. => nil |
A figure like the bottom is indicated with this. I'd find out that it can be used like using GDir to local data. But, since it's data only for the drawn two-dimensional aspect to put it in the first drawing and communicate also putting it in the next drawing, average operation about the longitude is performed on the server side. Therefore the communication amount is small both.
Execution result of the upper irb session (1) |
Execution result of the upper irb session (2) |
% irb -r ~/.irbrc_ggraph -r numru/gdir_connect_ftp-like
|
I hope that you make it NADO.
You can communicate with dRuby at a port of the optional number. But the place where communication with outside is permitted at more than 1000th port Japan and the general user can use today will be rare. I hope that you use port forwarding by ssh (Tunneling) in that case. It's only to a machine with an account that ssh can be used. But it can't be recommended from a security face generally to free and use dRuby widely just as it is, so anyway, it would be better to limit access to the user with an account.
Port forwarding of ssh is performed as follows.
% ssh -L 12300:localhost:12300 remotehost |
% ssh -R 12300:localhost:12300 remotehost |
Actual server start-up and access are performed as follows.
localhost% ssh -L 12300:localhost:12300 user@remotehost Password: ******** Login message. remotehost% cd .... # Where it is, remotehost% gdir_server . localhost:12300 # Server start-up |
I start a GDir server remotely and access from a local host this:.
localhost% gdir_client ** A GPhys service client. To conetct, type in server's URI (return) (format: druby://host:port) . Type in help to see usage. URI>>druby://localhost:12300 *************************************************************** * WELCOME! * * You logged in druby://localhost:12300 ..snip. |
Port forwarding to a remote host has been established from a local host in window 1 first, so local communication to number 12300 is forwarded to a remote host. gdir_server is waiting at the 12300th port of a remote host, so to communicate it can be connected with this.
remotehost% ssh -R 12300:localhost:12300 user@localhost
Password: ******** login
message.
|
remotehost% gdir_server . localhost:12300 # Server start-up
|
localhost% gdir_client ** A GPhys service client. To conetct, type in server's URI (return) (format: druby://host:port) . Type in help to see usage. URI>>druby://localhost:12300 *************************************************************** * WELCOME! * * You logged in druby://localhost:12300 . Abbreviation. |
remotehost% ssh -R 12300:localhost:12300 user@thirdhost
Password: ******** login
message.
|
localhost% ssh -L 12300:localhost:12300 user@thirdhost
Password: ******** login
message.
|
remotehost% gdir_server . localhost:12300 # Server start-up
|
localhost% gdir_client ** A GPhys service client. To conetct, type in server's URI (return) (format: druby://host:port) . Type in help to see usage. URI>>druby://localhost:12300 *************************************************************** * WELCOME! * * You logged in druby://localhost:12300 . Abbreviation. |
A measure is needed so that an object necessary to a remote process may be collected in trash gathering of Ruby (GC) in dRuby. 20 minutes are set using TimerIdConv of a dRuby accessory and something to say in gdir_server so as not to be collected. When saying conversely, the object from which 20 minutes have passed is collected as trash on the server side, and there is a possibility that you can't access. This time will be an option in the future, and I'd like to make sure that it can be designated.
The security of a dRuby server is difficult to guarantee. A server shouldn't be exhibited to the public widely. I'll make the server keeping starting it and end it suitably.
When forwarding data, dRuby changes an object to a part-time work line by a built-in library in Ruby as Marshal. Ruby 1.6-> was Ruby 1.8, and the format of Marshal was changed, so unfortunately, communication is limited to 1.6 comrades or 1.8 comrades.
All NArray-ized data is read from a file at present in gdir_server, and is made the target of network transmission. On the other hand when a circuit is thin, it's effective to make it the setting which doesn't go out of the server side until some degrees will be small size. When a part of a method definition of NArray in gdir_server is rewritten like the bottom, the data length doesn't forward 40000 (not part-time work, but the number) to the above mentioned data any more, so I come to stay at the server side.
class NArray DUMP_SIZE_LIMIT = 40000 def self._load(o); to_na(*Marshal::load(o)).ntoh; end def _dump(limit) if size<= DUMP_SIZE_LIMIT Marshal::dump([hton.to_s, typecode, *shape]) else raise "size of the NArray (#{size}) is too large to dump "+ "(limit: #{DUMP_SIZE_LIMIT})" end end end |
Please wait a moment, this--section will plan to make it from now on.
When Ruby on Rails is used, the search in which I cooperated with a data base can make a possible data offer server. An example can't be taken out yet, so a hurrying person, excuse me, without help, please. It's possible very often, and Ruby on Rails tends to use it.
Copyright (C) 2003 GFD Dennou Club. All Rights Reserved.