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

[netCDF #YLU-405033]: dealing with missing values while writing netCDF in FORTRAN V 3.6.1



Avirup,

> Thanks for answering my questions regarding netCDF. I tried to use
> '_FillValue' using the following codes:
> 
> call check(nf90_put_att(ncid,Varid4,'_FillValue', -9999.00))
> 
> Then I read that netCDF file in fortran and R again. But the output array
> contains missing values as -9999.000. I was expecting them to be NaN. I
> looked at the manual for fortran 90. But didn't find any help regarding to
> this subject. Could you plesae help by answering these question:
> 1. Is there way i fill/declare the missing values with some real number and
> then read them as NaN (as we can do in R)

No, that's not supported directly by the netCDF API.  You can define
the value of a variable's _FillValue attribute to be NaN and it will
be read as NaN.  For example, here's some Fortran-90 code that does
that: 

program filltest
  use netcdf
 ...
  real :: fillval, zero
  zero = 0.0
 ...
  call check( nf90_def_var(ncid, "data", NF90_REAL, dimids, varid) )
 ...
  fillval = zero / zero
  call check( nf90_put_att(ncid, varid, "_FillValue", fillval) )
 ...

Now any data not written or written with the value in fillval can be
read as a NaN.

I've attached a full F90 example program modified from an example that
writes incomplete data, with some fill values.  Running the ncdump on
the result shows the unwritten values as '_', which shows they were
read as NaNs.

--Russ


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



Ticket Details
===================
Ticket ID: YLU-405033
Department: Support netCDF
Priority: Normal
Status: Closed
!     This is part of the netCDF package.
!     Copyright 2006 University Corporation for Atmospheric Research/Unidata.
!     See COPYRIGHT file for conditions of use.

!     This is a very simple example which writes a 2D array of
!     sample data. To handle this in netCDF we create two shared
!     dimensions, "x" and "y", and a netCDF variable, called "data".

!     This example demonstrates the netCDF Fortran 90 API. This is part
!     of the netCDF tutorial, which can be found at:
!     http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
      
!     Full documentation of the netCDF Fortran 90 API can be found at:
!     http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-f90

!     $Id: filltest.f90,v 1.11 2010/04/06 19:32:08 ed Exp $

program filltest
  use netcdf
  implicit none

  ! This is the name of the data file we will create.
  character (len = *), parameter :: FILE_NAME = "filltest.nc"

  ! We are writing 2D data, a 12 x 6 grid. 
  integer, parameter :: NDIMS = 2
  integer, parameter :: NX = 6, NY = 12

  ! When we create netCDF files, variables and dimensions, we get back
  ! an ID for each one.
  integer :: ncid, varid, dimids(NDIMS)
  integer :: x_dimid, y_dimid
  
  ! This is the data array we will write. It will just be filled with
  ! a progression of integers for this example.
  real, dimension(:,:), allocatable :: data_out

  ! Loop indexes, and error handling.
  integer :: x, y
  real :: fillval, zero
  zero = 0.0

  ! Allocate memory for data.
  allocate(data_out(NY-1, NX-1))

  ! Create some pretend data. If this wasn't an example program, we
  ! would have some real data to write, for example, model output.
  do x = 1, NX-1
     do y = 1, NY-1
        data_out(y, x) = (x - 1) * NY + (y - 1)
     end do
  end do

  ! Always check the return code of every netCDF function call. In
  ! this example program, wrapping netCDF calls with "call check()"
  ! makes sure that any return which is not equal to nf90_noerr (0)
  ! will print a netCDF error message and exit.

  ! Create the netCDF file. The nf90_clobber parameter tells netCDF to
  ! overwrite this file, if it already exists.
  call check( nf90_create(FILE_NAME, NF90_CLOBBER, ncid) )

  ! Define the dimensions. NetCDF will hand back an ID for each. 
  call check( nf90_def_dim(ncid, "x", NX, x_dimid) )
  call check( nf90_def_dim(ncid, "y", NY, y_dimid) )

  ! The dimids array is used to pass the IDs of the dimensions of
  ! the variables. Note that in fortran arrays are stored in
  ! column-major format.
  dimids =  (/ y_dimid, x_dimid /)

  ! Define the variable. The type of the variable in this case is
  ! NF90_INT (4-byte integer).
  call check( nf90_def_var(ncid, "data", NF90_REAL, dimids, varid) )

  fillval = zero/ zero
  call check( nf90_put_att(ncid, varid, "_FillValue", fillval) )

  ! End define mode. This tells netCDF we are done defining metadata.
  call check( nf90_enddef(ncid) )

  ! Write the pretend data to the file. Although netCDF supports
  ! reading and writing subsets of data, in this case we write all the
  ! data in one operation.
  call check( nf90_put_var(ncid, varid, data_out) )

  ! Close the file. This frees up any internal netCDF resources
  ! associated with the file, and flushes any buffers.
  call check( nf90_close(ncid) )

  print *, "*** SUCCESS writing example ", FILE_NAME

contains
  subroutine check(status)
    integer, intent ( in) :: status
    
    if(status /= nf90_noerr) then 
      print *, trim(nf90_strerror(status))
      stop 2
    end if
  end subroutine check  
end program filltest

NOTE: All email exchanges with Unidata User Support are recorded in the Unidata inquiry tracking system and then made publicly available through the web. If you do not want to have your interactions made available in this way, you must let us know in each email you send to us.