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

[netCDF #NUC-119714]: struggling with writing data to nc file



> Thanks for this very fast feedback! I will check out the details tomorrow 
> morning but wanted to say that the F90 code is actually working properly, 
> producing a nc file that I can read and plot with for example ferret. Working 
> despite the bug???

Yes, it's possible that the dimension ID and variable ID are equal, just by 
coincidence, since they are both small integers.  That may also be the case 
for the F77 version.

But your program should not rely on that coincidence, it should use a separate
Fortran variable for the netCDF time dimension ID and the time variable ID.

--Russ

> Laurens Ganzeveld
> =======================================================================
> Dr. ir. Laurens Ganzeveld
> Assistant professor
> Department of Environmental Sciences, Chair group Earth System Sciences
> Wageningen University and Research Centre
> Lumen, room D.001, Droevendaalsesteeg 4, 6708 PB, Wageningen, Netherlands
> Phone: (+31) 317-486651 / 613066079, Fax: (+31) 317-419000,
> Being in in Colombia: +57 310 2979313
> E-mail: address@hidden
>  
> Affiliate of Universidad de Los Andes, Depart de Biología, Bogota, Colombia
> Affiliate of Max Planck Institute for Chemistry, Depart. of Atmospheric 
> Chemistry, Mainz, Germany,
> =======================================================================
> 
> 
> -----Original Message-----
> From: Unidata netCDF Support [mailto:address@hidden]
> Sent: woensdag 9 oktober 2013 17:50
> To: Ganzeveld, Laurens
> Cc: address@hidden
> Subject: [netCDF #NUC-119714]: struggling with writing data to nc file
> 
> Hi Laurens,
> 
> > I hope that you are actually working at the moment and not affected by
> > the government shutdown; I am already struggling now for some weeks
> > with a simple script to read and write data to netcdf in a F77 model
> > code. I am able to read-in and then write some manipulated data in F90
> > version but the F77 version gives problems with the writing; I have
> > copied below the F90 version of the write_nc routine I used and that
> > works with my installation of the netcdf software (3.6.2) on my
> > Suse11.2 linux system. I have also copied a version of the F77
> > subroutine that doesn't work; I am basically looking for the F77
> > equivalent of some of the calls of the various nc functions where the
> > help page has helped a lot but not to solve this remaining problem.
> > Your feedback would be highly appreciated,
> 
> I see a bug in your F90 write_nc that may be a source of the problem:
> you should not be using the same variable, tid, for both the dimension ID of 
> the time dimension and the variable ID of the time variable.
> These are two different objects, and may have two different IDs.  Or they may 
> have the same ID in the F90 version, by coincidence, but have different 
> values in your F77 program.
> 
> You specify a netCDF coordinate variable by giving it the same name as a 
> dimension, but that's just a convention, and does not have any effect on what 
> ID is assigned to the variable.  Dimension IDs are just assigned in the order 
> dimensions are defined, and similarly for variables.  So if the first 
> dimension defined has the name "time", but the corresponding "time" variable 
> is the third variable defined, then the "time" dimension will have dimension 
> ID 1, but the time variable will have variable ID 3.  This is the way it 
> works in both the F90 and
> F77 netCDF APIs.
> 
> There is also a problem with the call to NF_PUT_VAR_DOUBLE(), which can only 
> be used to write *all* the values of a variable.  If instead you only want to 
> write the values for a single time step, as in the
> F90 subroutine, you will need to instead use the function 
> NF_PUT_VARA_DOUBLE(), for which you need to specify START and COUNT 
> arguments, as in:
> 
> NF_PUT_VARA_DOUBLE(INTEGER NCID, INTEGER VARID, INTEGER START(*), INTEGER 
> COUNT(*), DOUBLE DVALS(*))
> 
> > Thanks, Laurens Ganzeveld
> >
> > F90:
> >
> > The subroutine is called in a timeloop over 12 months writing out the
> > global emission field (emis3D), at a resolution of 1x1 degree for each
> > month to a new netcdf file:
> >
> > SUBROUTINE write_nc_file
> >
> > ! write timestep
> > CALL nf(nf90_inquire_dimension(ncid, tid, len=timestep)) timestep =
> > timestep + 1
> >
> > print *,'write_nc: timestepping ',timestep read (*,*)
> >
> > CALL nf(nf90_put_var(ncid, tid, time, (/timestep/) ))
> 
> For the above, use the varid for the time variable instead of tid.
> 
> > ! syntax: nf90_put_var(ncid, varid, values, start, cnt) ! start: start
> > in netcdf variable ! cnt: number of netcdf variable points ! values:
> > starting point of the fortran variable start1d = (/ 1, timestep /)
> > start2d = (/ 1, 1, timestep /) start3d = (/ 1, 1, 1, timestep /)
> >
> > CALL nf(nf90_put_var(ncid, emis3Did, emis3D, start3d, cnt3d)) ! emis.
> >
> > END SUBROUTINE write_nc_file
> >
> >
> > F77:
> > Ncid, tid, emisid are all properly defined as well as the parameter
> > emis
> >
> > SUBROUTINE write_nc_file(ii,time,ncid,tid,emisid,emis)
> >
> > integer :: ii,timestep,status,ncid,tid,dimtid,timelen,nrecs,
> > & emisid,start2d(3),cnt2d(3),j,k
> > real :: time,emis(180,360)
> >
> > character*(20) recnam
> >
> > ! write timestep
> > timestep = ii
> > print *,'timestep',timestep,time
> >
> > CALL nf(nf_put_var_double(ncid, tid, time, (/timestep/) )) read (*,*)
> 
> There are 3 things wrong with that call to nf_put_var_double: it uses a 
> dimension id instead of a variable id, it has too many arguments, and even if 
> the extra last argument is omitted, it writes too many values.
> 
> That call writes *all* the values of the time variable, not just the one 
> value for the current timestep.  So if time is the unlimited dimension (i.e. 
> record dimension), and it currently has length 10, then that 
> nf_put_var_double() call tries to write time(1), time(2), ..., time(10).
> 
> Note this warning in the documentation:
> 
> Take care when using the simplest forms of this interface with
> record variables (variables that use the NF_UNLIMITED dimension)
> when you don't specify how many records are to be written. If you
> try to write all the values of a record variable into a netCDF file
> that has no record data yet (hence has 0 records), nothing will be
> written. Similarly, if you try to write all the values of a record
> variable from an array but there are more records in the file than
> you assume, more in-memory data will be accessed than you expect,
> which may cause a segmentation violation. To avoid such problems,
> it is better to use the NF_PUT_VARA_type interfaces for variables
> that use the NF_UNLIMITED dimension. See NF_PUT_VARA_ type.
> 
> So you probably instead want to use something like:
> 
> CALL nf(nf_put_vara_double(ncid, tvarid, (/ ii /) , (/ 1 /), time(timestep) ))
> 
> to write the one value, time(timestep), as the new value of the time variable.
> 
> > ! syntax: nf90_put_var(ncid, varid, values, start, cnt) ! start: start
> > in netcdf variable ! cnt: number of netcdf variable points ! values:
> > starting point of the fortran variable start2d = (/ 1, 1, timestep /)
> > cnt2d = (/ 180, 360, 1 /)
> >
> > ! write 2d data
> >
> > CALL nf(nf_put_var_real(ncid, emisid, emis, start2d, cnt2d)) ! emis .
> 
> Here, you also want to follow the documentation for the order of arguments 
> and use the nf_put_vara_real() function instead, something
> like:
> 
> CALL nf_put_vara_real(ncid, emisid, start2d, cnt2d, emis)
> 
> assuming "emis" is a 2D variable of the new emissivities.
> 
> --Russ
> 
> Russ Rew                                         UCAR Unidata Program
> address@hidden                      http://www.unidata.ucar.edu
> 
> 
> 
> Ticket Details
> ===================
> Ticket ID: NUC-119714
> Department: Support netCDF
> Priority: Normal
> Status: Closed
> 
> 
> 

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



Ticket Details
===================
Ticket ID: NUC-119714
Department: Support netCDF
Priority: Normal
Status: Closed