[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[netCDF #DXD-376053]: [netcdfgroup] Very strange problem with Fortran
- Subject: [netCDF #DXD-376053]: [netcdfgroup] Very strange problem with Fortran
- Date: Fri, 27 Jun 2008 13:02:33 -0600
Ian,
First, if you are willing to just use the default type-specific fill
value for a variable, it's not necessary to explicitly define the
_FillValue attribute, and not defining it makes sure it is of the
right type for the variable. So you only need to define the
time:_FillValue attribute if you want to use a particular non-default
value for missing times.
Second, if time is supposed to be a coordinate variable, it should not
have missing values. This is not a requirement enforced by the
library, just a "best practice", as listed here:
http://www.unidata.ucar.edu/software/netcdf/docs/BestPractices.html#Coordinate%20Systems
A coordinate variable is a one-dimensional variable with the same
name as a dimension, which names the coordinate values of the
dimension. It must not have any missing data (for example, no
_FillValue or missing_value attributes) and must be strictly
monotonic (values increasing or decreasing).
Third, I tried using NF_FILL_DOUBLE as a fill value for a time
coordinate associated with the unlimited dimension, and it worked
fine. I've attached an example program, mostly generated by ncgen -f,
that demonstrates this.
Finally, in response to your last question, the fill value type has to
match the type of the variable that the fill value is associated with.
In your case that's the double precision time variable, not the
single-precision data variable, right?
I hope this helps. I still haven't figure out why the error isn't
generated when the attribute is defined rather than when the data is
written, but I hope you can just delete the attribute definition for
the time _FillValue, since it shouldn't have such an attribute or the
default value is adequate.
--Russ
Russ Rew UCAR Unidata Program
address@hidden http://www.unidata.ucar.edu
Ticket Details
===================
Ticket ID: DXD-376053
Department: Support netCDF
Priority: Normal
Status: Closed
program fgennc
include 'netcdf.inc'
* error status return
integer iret
* netCDF id
integer ncid
* dimension ids
integer lat_dim
integer lon_dim
integer time_dim
* dimension lengths
integer lat_len
integer lon_len
integer time_len
parameter (lat_len = 2)
parameter (lon_len = 3)
parameter (time_len = NF_UNLIMITED)
* variable ids
integer lat_id
integer lon_id
integer time_id
integer rh_id
* rank (number of dimensions) for each variable
integer lat_rank
integer lon_rank
integer time_rank
integer rh_rank
parameter (lat_rank = 1)
parameter (lon_rank = 1)
parameter (time_rank = 1)
parameter (rh_rank = 3)
* variable shapes
integer lat_dims(lat_rank)
integer lon_dims(lon_rank)
integer time_dims(time_rank)
integer rh_dims(rh_rank)
* data variables
real lat(lat_len)
real lon(lon_len)
* attribute vectors
double precision doubleval(1)
* enter define mode
iret = nf_create('ih.nc', NF_CLOBBER, ncid)
call check_err(iret)
* define dimensions
iret = nf_def_dim(ncid, 'lat', 2, lat_dim)
call check_err(iret)
iret = nf_def_dim(ncid, 'lon', 3, lon_dim)
call check_err(iret)
iret = nf_def_dim(ncid, 'time', NF_UNLIMITED, time_dim)
call check_err(iret)
* define variables
lat_dims(1) = lat_dim
iret = nf_def_var(ncid, 'lat', NF_REAL, lat_rank, lat_dims, lat_id
1)
call check_err(iret)
lon_dims(1) = lon_dim
iret = nf_def_var(ncid, 'lon', NF_REAL, lon_rank, lon_dims, lon_id
1)
call check_err(iret)
time_dims(1) = time_dim
iret = nf_def_var(ncid, 'time', NF_DOUBLE, time_rank, time_dims, t
1ime_id)
call check_err(iret)
rh_dims(3) = time_dim
rh_dims(2) = lat_dim
rh_dims(1) = lon_dim
iret = nf_def_var(ncid, 'rh', NF_REAL, rh_rank, rh_dims, rh_id)
call check_err(iret)
* assign attributes
doubleval(1) = 0
* iret = nf_put_att_double(ncid, time_id, '_FillValue', NF_DOUBLE, 1
* 1, doubleval)
call check_err(iret)
* print *, "about to define fill value attribute"
* This causes error later when time value written
* iret = nf_put_att_real(ncid, time_id, '_FillValue', NF_REAL, 1
* 1, 0.0)
* This works OK
* iret = nf_put_att_double(ncid, time_id, '_FillValue', NF_DOUBLE, 1
* 1, 0.0d0)
iret = nf_put_att_double(ncid, time_id, '_FillValue', NF_DOUBLE, 1
1, NF_FILL_DOUBLE)
call check_err(iret)
* leave define mode
iret = nf_enddef(ncid)
call check_err(iret)
* Write record variables
call writerecs(ncid,time_id,rh_id)
iret = nf_close(ncid)
call check_err(iret)
end
subroutine writerecs(ncid,time_id,rh_id)
* netCDF id
integer ncid
* variable ids
integer time_id
integer rh_id
include 'netcdf.inc'
* error status return
integer iret
* netCDF dimension sizes for dimensions used with record variables
integer lat_len
parameter (lat_len = 2)
integer lon_len
parameter (lon_len = 3)
* rank (number of dimensions) for each variable
integer time_rank
integer rh_rank
parameter (time_rank = 1)
parameter (rh_rank = 3)
* starts and counts for array sections of record variables
integer time_start(time_rank), time_count(time_rank)
integer rh_start(rh_rank), rh_count(rh_rank)
* data variables
integer time_nr
parameter (time_nr = 2)
double precision time(time_nr)
integer rh_nr
parameter (rh_nr = 2)
real rh(lon_len, lat_len, rh_nr)
data time /2., 3./
data rh /4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15/
* store time
time_start(1) = 1
time_count(1) = time_nr
iret = nf_put_vara_double(ncid, time_id, time_start, time_count, t
1ime)
call check_err(iret)
* iret = nf_put_var1_double(ncid, time_id, 1, 2.0d0)
* print *, "about to put time value 1"
* iret = nf_put_var1_double(ncid, time_id, 1, time(1))
* print *, "iret = ", iret
* call check_err(iret)
* print *, "about to put time value 2"
* iret = nf_put_var1_double(ncid, time_id, 2, time(2))
* print *, "iret = ", iret
* call check_err(iret)
* store rh
rh_start(1) = 1
rh_start(2) = 1
rh_start(3) = 1
rh_count(1) = lon_len
rh_count(2) = lat_len
rh_count(3) = rh_nr
iret = nf_put_vara_real(ncid, rh_id, rh_start, rh_count, rh)
call check_err(iret)
end
subroutine check_err(iret)
integer iret
include 'netcdf.inc'
if (iret .ne. NF_NOERR) then
print *, nf_strerror(iret)
stop
endif
end