SimpleSDS
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:Simplified NetCDF and HDF APIs with better error reporting
Simple SDS
==========

The Simple SDS project attempts to make
[NetCDF](http://www.unidata.ucar.edu/software/netcdf/) (and
eventually, [HDF](http://www.hdfgroup.org/)) easier to code for
atmospheric science code.  The major component is a set of Fortran 90
modules that wrap NetCDF routines to add better error reporting and
automatically stop the program on error.  The module also has
convenience routines to help you write
[CF-compliant](http://cf-pcmdi.llnl.gov/) files.

A secondary component of this project is a tool, nc2code, which will
examine arbitrary NetCDF files and generate code to read them in one
of several languages.  Incidentally, it uses a high level C wrapper to
examine a NetCDf file which may prove useful if you are writing NetCDF
handling code in C.


Improved Error Handling and Reporting
=====================================

A major aim of Simple SDS is to improve the error reporting and
handling of the NetCDF library.  Normally you will need to check every
NetCDF function's status return code to see if an error occurred.  Example:

    call check( nf90_inq_dimid(ncid, "some_dim", dimid) )
    .
    .
    .
    subroutine check(status)
      .
      .
      .

If the call results in an error, you can get a description like
"NetCDF: Not a valid ID" using nf90_strerror(status), but this has no
context and leaves something to be desired.  The Simple SDS module
keeps track of enough information to report the file, action attempted
and other relevant information when reporting an error.  Example:

Source code:

     some_dimid = snc_get_dimid(file, "some_dim")

Resulting error in terminal:

     NetCDF: Not a valid ID
       While: getting id for dimension 'some_dim' in nonexistent_file.nc

With a little extra work, it can also report the source file and line
number in your code that resulted in a NetCDF error:

    test/snc_with_file_line.F90 line   13: NetCDF: Not a valid ID
       While: getting id for dimension 'some_dim' in nonexistent_file.nc

To do this properly requires the C preprocessor and some Makefile
magic.  See below for more.

In any event, when a Simple SDS routine encounters an error, it is
reported and +stop+ is called to halt the program.  Because you call
Simple SDS routines directly, there is no extra code to check the
error status.


Using Simple SDS
================

To use the Simple SDS NetCDF Fortran module, download this code to
your computer, edit the Makefile if needed and get the code built.
You may want to run the tests in the test/ directory.  Next, copy the
simple_netcdf.F90 file into an appropriate place in your source tree.
Then write or rewrite your NetCDF library calls with the replacement
functions in the Simple SDS module.

You may want to use the macros in simple_netcdf.inc to automatically
add src_file=/src_line= arguments to Simple SDS function and
subroutine calls.  These optional arguments let the library report
where in your code an error came from.  If this sounds useful to you,
there are additional steps you will need to take to use it in your
program.  First you will need to add the simple_netcdf.inc header file to each of the source files that call Simple SDS routines:

    #include "simple_netcdf.inc"

This defines C Preprocessor macros that automatically add

    src_file = __FILE__, src_line = __LINE__

arguments to Simple SDS routines.  The C Preprocessor (for __FILE__
and __LINE__ macros) has proven tricky to get to work with Fortran
source code.  The Makefile here shows one solution:

    .F90.o:
    	$(CPP) $(FFLAGS) -w $< $*.f90
    	$(F90) $(FFLAGS) -c $*.f90 -o $@ || (rm $*.f90; false)
    	rm $*.f90

This takes source files with one of the standard pre-processed
extensions .F90 (commonly .F, .F90, .F95, .F03, .FOR, .FPP), runs it
through the C PreProcessor writing the output to the non-preprocessed
extension .f90, compiles the .f90 file, then makes sure the .f90 file
gets deleted and the proper success/failure exit code is seen by make
with some shell code.  Not overly difficult, but it requires that if
you have a file with the .F90 extension, there must not also be a file
of that name with the .f90 extension, which further assumes a
case-sensitive filesystem.


Examples
========

Often, you'd just like to read a variable in from a NetCDF file and that's it.  Well, there's a function for that!

    ! optional
    #include "simple_netcdf.inc"

    use SimpleNetCDF
    implicit none

    real*4, pointer :: var(:,:,:)

    call snc_open_var("some.nc", "varname", var)

If you'd also like the units for that variable, that's a simple shortcut:

    call snc_open_var("some.nc", "varname", var, units = units)

What if you need just one timestep's worth of the variable?  That's another shortcut:

    real*4, pointer :: var2(:,:)

    call snc_open_var("same.nc", "varname", var2, timestep = 2)

Note that this is a new variable with 2 instead of 3 dimensions, because one of the dimensions for the full variable is time.

What if we want to do a little more?  There are more function calls, but it's still fairly simple and has good error reporting:

    ! optional
    #include "simple_netcdf.inc"

    use SimpleNetCDF
    implicit none

    type(SNCFile) :: file
    type(SNCVar) :: t_var, u_var
    real*4, pointer :: t(:,:), u(:,:)
    character(32) :: units

    file = snc_open("some.nc")

    t_var = snc_inq_var(file, "t", units) ! units is optional here
    call snc_read(file, t_var, t)

    t_var = snc_inq_var(file, "u")        ! see? optional
    call snc_read(file, u_var, u)

    call snc_close(file)

Writing is always more work, but making a CF-compliant NetCDF file is not as bad as it could be:

    use SimpleNetCDF
    implicit none

    character(*) :: filename
    type(SNCFile) :: file
    type(SNCVar) :: var
    integer, parameter :: N_LAT = 3, N_LON = 4, N_LEVELS = 2, N_TIME = 2
    real*4 :: lat(N_LAT), lon(N_LON), time(N_TIME)
    real*4 :: d(N_LON, N_LAT, N_LEVELS, N_TIME)
    character(10), parameter :: t_unit = "seconds"
    character(60) :: time_units
    
    write(time_units, "A,' since ',I4.4,'-',I2.2,'-',I2.2)") &
        t_unit, year, month, day

    file = snc_cf_grid_create(filename, N_LON, N_LAT, &
        time_units, SNC_STANDARD_CAL, &
        ! optional
        title = "What Kind Of Data", source = "MyShinyProgram 1.0", &
        ! optional, helps with debugging
        src_file = __FILE__, src_line = __LINE__)

    call snc_cf_grid_vertical(file, N_LEVELS, "levels", "Levels", "hPa", "down", &
        src_file = __FILE__, src_line = __LINE__)

    var = snc_cf_def_var(file, "co2", "CO2 flux", SNC_FLOAT, "kg m-2 s-1", &
        ! optional
        missing_value = -999.0, &
        src_file = __FILE__, src_line = __LINE__)

    call snc_enddef(file)

    call snc_cf_write_coords(file, lon, lat, levels, time)
    call snc_write(file, var, d)

    call snc_close(file)


For more details, see the files in the examples/ directory.

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。