[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,

I don't exactly understand your question.

I thought you were asking for a way to write a subset of
the elements in a netCDF array.  The netCDF array is on disk,
so writing only a subset of its elements will always leave
unwritten values in the disk array.

If instead you intended to write an entire netCDF array using a
subset of the elements of an in-memory array, that's a different
problem, with a different solution.  That problem is less common,
because typically memory is more limited than disk space, so
usually users want to write an smaller in-memory array into a
larger netCDF variable on disk, which is what I thought you meant
by subset.

Below is code that creates a smaller 3 x 2 x 5 netCDF variable on
disk and writes a subset of a 3 x 4 x 5 in-memory array into it.
I hope I've finally understood what you wanted :-).

The code below results in writing all the data in a 3 x 2 x 5
variable, which ncdump displays as:

netcdf subset_3D {
dimensions:
        x = 3 ;
        y = 2 ;
        z = 5 ;
variables:
        int data(x, y, z) ;
data:

 data =
  111, 112, 113, 114, 115,
  121, 122, 123, 124, 125,
  211, 212, 213, 214, 215,
  221, 222, 223, 224, 225,
  311, 312, 313, 314, 315,
  321, 322, 323, 324, 325 ;
}

--Russ

C     Example that writes a subset of a 3D memory array into a netCDF
C     variable that is the same shape as the subset.

      program subset_3D
      implicit none
      include 'netcdf.inc'

      character*(*) FILE_NAME
      parameter (FILE_NAME='subset_3D.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 array to be written
      integer data_out(NZ, NY, NX)

      do x = 1, NX
         do y = 1, NY
            do z = 1, NZ
               data_out(z, y, x) = z+10*y+100*x
            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", 2, 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)

C ... Output 3 x 2 x 5 subset of memory array into smaller netCDF variable
      start(1) = 1
      start(2) = 1
      start(3) = 1
      count(1) = 5
      count(2) = 2
      count(3) = 3
      stride(1) = 1
      stride(2) = 1
      stride(3) = 1
C Distance between successive elements along axes in memory of data_out array
      map(1) =     1
      map(2) =   5*1
      map(3) = 4*5*1

      ret = nf_put_varm_int(ncid, varid, start, count, stride,
     *                      map, data_out)

      if (ret .ne. nf_noerr) call handle_err(ret)

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

      print *,'*** SUCCESS writing example file ', FILE_NAME
      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