GPhys tutorial

Takeshi Horinouchi.

Created: August in 2003

The last revision: August 2006

This page was transrated by OCN automatically.


Contents


First.

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 version of used GPhys


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.


Document


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.



Link


Installation


Installation of a package

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.

Installation from a source

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.



The data used in this tutorial

NetCDF data

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.


GrADS data


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.

grib data


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.


Let's visualize


Fastest drawing (Contour)


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.).

contour1000mb_1.rb
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.


Fastest drawing (polygonal line)


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.


line_1.rb
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:.


line_1.rb execution result

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)).


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)  # 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


line_2.rb execution result

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.


The various file formats


It's possible to deal with a file of the NetCDF, GrADS, grib form in the same way in GPhys. But, extraction by the GrADS form isn't supported for the moment.

Distinction of the file format


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.

  1. A suffix, 'nc', 'ctl', 'grib': supposes NetCDF, GrADS, grib respectively.
  2. Besides that. The first one of a file is read and distinguished.

It's possible to designate and read the file format positively. GPhys::NetCDF_IO.open, GPhys::GrADS_IO.open, GPhys::Grib_IO.open is used respectively.

GrADS,grib file drawing example


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.

contour1000mb_grd.rb
 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.

contour1000mb_grib.rb
 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.

How to check it the variable name which is being filed


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.

inspect_varnames.rb
 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.


Dialogue use using irb (1)


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.

Use of a startup file (1)


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.

.irbrc use example (way 1)


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


., the example for which irbrc isn't used (way 2)


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

In this way, irb for sessions of GGraph is set under the name as irb_ggraph. You can draw at 2 lines as follows as expected.
% 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.


The contents of GPhys are checked.


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.


inspect.rb
 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.



A directory is browsed, use of-- GDir


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 use example (1)


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.

GDir use example (2)


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.


Dialogue use using irb (2)


Use of a startup file (2) Use of-- GDir


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



Basis of a data manipulation


I'll put a basis of a data manipulation in GPhys in order here. When dealing with huge data, attention about the data reading which should be minded is also described.

Short straight-bladed knife


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.


kiridashi.rb
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.

About an average and other calculation.


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.


line_3.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.


line_3.rb execution result


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.



The unit of the physical quantity


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.)


op_units.rb
 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".



Data is extracted in a file.


When GPhys is used, own describing file can be extracted easily. (After it's processed as the need arises.) I deal with the instance output in a file after NetCDF reads own describing data as GPhys already first almost. The style change in a file is also easy as it'll be indicated later. The data which follows and is own describing, and, the example which is extracted from one in a file after composing a GPhys object, is indicated. The file format extracted up to now has not supported extraction of GrADS yet only at NetCDF or grib.

Extraction of GPhys data


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.

ncwrite1.rb
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.

Change in the file format


A style change in a file can be performed easily by a thing through GPhys.

convert.rb
 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

An extraction-- GPhys object of non-GPhys data is made with one.


(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.

ncwrite2.rb
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;
}
Axis Class and GPhys Class object are made after VArray Class object of a variable is made once.


Handling of huge data


The number of complete changes, several, more than 100 MB, when dealing with data, when it's read together, a memory of a computer would be pressed. There are several devices to avoid that in GPhys.

Subset in GPhys and cloning


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.


Further of the price, when I'd like to read and make a copy, the copy method should be used. This makes so-called deep clone where a new object doesn't include a reference to an old object (An object tree is copied wholly.) Refer to the next.


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,...]>>

The part of the price is indicated this time. Data is read, and is maintained on the memory as a NArray object.


Auto partition ITERETA for huge data


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.


It's considered to decide not to press a memory by reading a little in such case. For example, as follows, (This is non-automation example. Next an automation example is indicated.)


iterate_over_dim_1.rb
 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.


iterate_over_dim_2.rb
 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 division file, virtually, bundle


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.

multiple_files.rb
 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


GGraph is managed (its 1).


I return to a topic of visualization again.

Utilization of a reading file


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.

contour1000mb_2.rb
 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.

Drawing option


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:.


line_4.rb
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.)


line_4.rb execution result

Mechanism of an option of the drawing method


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)
In other words, association arrangement is being just given to the 3rd argument of GGraph.line and a key word argument (the argument distinguished under the name, not order) isn't used. A key word argument doesn't exist in grammar of Ruby, but it's using association arrangement.
GGraph.line(gphys.cut(135,35,false). true, 'exchange'=>true, 'annot'=>false)
Be so, it's said that they can express and a key word argument can be used substantially.


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.

I know the default value of the option.


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.


help_ggraph.rb
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.



GGraph is managed (its 2).


The drawing method of GGraph has various options so that it may be understood by help message indication above-mentioned. Designation by an option is finite then, but it can be established much effectively after that by changing the default value. An example is indicated below.

contour/tone (level auto-generation)


I'll execute the next program.

contour101.rb
 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).


Color bar


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.


color_bar.rb
 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

color_bar.rb execution result


Map projection


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.


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.


map_proj1.rb
 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
This program gets the map projection number as the first argument. Cylinder projection, a conic projection and an azimuthal projection will be represented, and equidistant cylindrical projection (10), a positive calcarate conic projection (20) and a orthographic chart way (30) are tried.
% 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


About several special projections.

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)
O is designated.


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.


map_axes_itr10.rb
 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


Map projection related option


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

Further sample

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


That the one with the big price comes to the left/bottom only for pressure axis?


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.)


fig_help.rb
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.