[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[netCDF #KJN-301947]: Writing a Subset of a 3-D Array to a NetCDF File



Ben,

Oops, I had made a simple typo in my test program, and fixing it
made everything work as documented.  But at least now I have an
F77 example demonstrating the vars and varm interfaces do what is
intended.

I'm not entirely happy with the clarity of this example, so if you
find it can be improved in studying it, please let us know.  Good
examples are often better than reference documentation for seeing
how things work.

C     Example that writes a 3D array of sample data, then rewrites a
C     subset of that data, to show that elements not in the subset are
C     not overwritten.

      program put3d
      implicit none
      include 'netcdf.inc'

      character*(*) FILE_NAME
      parameter (FILE_NAME='put3d.nc')

      integer NDIMS
      parameter (NDIMS=3)
      integer NX, NY, NZ
      parameter (NX = 3, NY = 4, NZ = 5)
      integer ncid, varid, dimids(NDIMS)
      integer x_dimid, y_dimid, z_dimid
      integer x, y, z, i, ret
      integer start(NDIMS), count(NDIMS), stride(NDIMS), map(NDIMS)

C     Data arrays of different shapes to be written
      integer data_out(NZ, NY, NX)
      integer slab(NZ, NY)
      integer slab2(2*NY*NX)
      integer slab3(3, 2, NX)

      do x = 1, NX
         do y = 1, NY
            do z = 1, NZ
               data_out(z, y, x) = 7
            end do
         end do
      end do

      ret = nf_create(FILE_NAME, NF_CLOBBER, ncid)
      if (ret .ne. nf_noerr) call handle_err(ret)

      ret = nf_def_dim(ncid, "x", NX, x_dimid)
      if (ret .ne. nf_noerr) call handle_err(ret)
      ret = nf_def_dim(ncid, "y", NY, y_dimid)
      if (ret .ne. nf_noerr) call handle_err(ret)
      ret = nf_def_dim(ncid, "z", NZ, z_dimid)
      if (ret .ne. nf_noerr) call handle_err(ret)

      dimids(1) = z_dimid
      dimids(2) = y_dimid
      dimids(3) = x_dimid

      ret = nf_def_var(ncid, "data", NF_INT, NDIMS, dimids, varid)
      if (ret .ne. nf_noerr) call handle_err(ret)

      ret = nf_enddef(ncid)
      if (ret .ne. nf_noerr) call handle_err(ret)

      ret = nf_put_var_int(ncid, varid, data_out)
      if (ret .ne. nf_noerr) call handle_err(ret)

C  Now
C
C  data =
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7,
C   7, 7, 7, 7, 7 ;

C Use nf_put_vara_int to write same variable, one 2D slab at a time as all 6's
      start(1) = 1
      start(2) = 1
      count(1) = NZ
      count(2) = NY
C 4 by 5 slab of data to be written
      do y = 1, NY
         do z = 1, NZ
            slab(z, y) = 6
         end do
      end do

      do x = 1, NX
         start(3) = x
         count(3) = 1
         ret = nf_put_vara_int(ncid, varid, start, count, slab)
         if (ret .ne. nf_noerr) call handle_err(ret)
      end do

C Now
C
C  data =
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6,
C   6, 6, 6, 6, 6 ;

C Use strided put to overwrite first and last columns with 3's
      start(1) = 1
      start(2) = 1
      start(3) = 1
      count(1) = 2
      count(2) = NY
      count(3) = NX
C only write every fourth value along z dimension
      stride(1) = 4
      stride(2) = 1
      stride(3) = 1
      i = 1
      do x = 1, NX
         do y = 1, NY
            do z = 1, 2
               slab2(i) = 3
               i = i+1
            end do
         end do
      end do
      ret = nf_put_vars_int(ncid, varid, start, count, stride, slab2)

C Now
C
C  data =
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3,
C   3, 6, 6, 6, 3 ;

C Use mapped put to overwrite middle 6 elements of each Y-Z slab with
C 2's
      start(1) = 2
      start(2) = 2
      start(3) = 1
      count(1) = 3
      count(2) = 2
      count(3) = NX
C Just use default strides in this example
      stride(1) = 1
      stride(2) = 1
      stride(3) = 1
C Distance between successive elements along axes in memory of slab3 array
      map(1) = 1
      map(2) = 2
      map(3) = 6

      do x = 1, NX
         do y = 1, 2
            do z = 1, 3
               slab3(z, y, x) = 2
            end do
         end do
      end do
      ret = nf_put_varm_int(ncid, varid, start, count, stride,
     *                      map, slab3)

C Now
C
C  data =
C   3, 6, 6, 6, 3,
C   3, 2, 2, 2, 3,
C   3, 2, 2, 2, 3,
C   3, 6, 6, 6, 3,
C
C   3, 6, 6, 6, 3,
C   3, 2, 2, 2, 3,
C   3, 2, 2, 2, 3,
C   3, 6, 6, 6, 3,
C
C   3, 6, 6, 6, 3,
C   3, 2, 2, 2, 3,
C   3, 2, 2, 2, 3,
C   3, 6, 6, 6, 3 ;

      ret = nf_close(ncid)
      if (ret .ne. nf_noerr) call handle_err(ret)

      print *,'*** SUCCESS writing example file put3d.nc!'
      end

      subroutine handle_err(errcode)
      implicit none
      include 'netcdf.inc'
      integer errcode

      print *, 'Error: ', nf_strerror(errcode)
      stop 2
      end

Russ Rew                                         UCAR Unidata Program
address@hidden                     http://www.unidata.ucar.edu



Ticket Details
===================
Ticket ID: KJN-301947
Department: Support netCDF
Priority: Normal
Status: Closed