program converting_to_netcdf c written by Dan Truman c updated 4/94 *sh* c This program provides a model for converting a data set to netCDF. c The basic strategy used in this program is to open an existing netCDF c file, query the file for the ID's of the variables it contains, and c then write the data to those variables. c The output netCDF file must be created **before** this program is run. c The simplest way to do this is to cd to your scratch directory and c % cp $FER_DIR/doc/converting_to_netcdf.basic converting_to_netcdf.cdl c and then edit converting_to_netcdf.cdl (an ASCII file) to describe YOUR data c set. If your data set requires unequally spaced axes, climatological time c axes, staggered grids, etc. then converting_to_netcdf.supplement may be c a better starting point then the "basic" file used above. c After you edit converting_to_netcdf.cdl then create the netCDF file with c the command c % ncgen -o converting_to_netcdf.cdf converting_to_netcdf.cdl c Now we will read in **your** data (gridded oceanic temperature and c salt in this example) and write it out into the netCDF file c converting_to_netcdf.cdf. Note that the axis coordinates can be written c out exactly the same methodology - including time step values (as below). ************************************************************************* c An alternative to modifying this program is to use the command: c ncgen -f converting_to_netcdf.cdl c This will create a large source code to which select lines can c be added to write out your data. ************************************************************************* c To compile and link converting_to_netcdf.f, use: c f77 -o converting_to_netcdf converting_to_netcdf.f -lnetcdf ************************************************************************* c include file necessary for netCDF include 'netcdf.inc' ! may be found in $FER_DIR/fmt/cmn ************************************************************************* c parameters relevant to the data being read in c THESE NORMALLY MATCH THE DIMENSIONS IN THE CDL FILE c (except nt which may be "unlimited") integer imt, jmt, km, nt, lnew, inlun parameter (imt=160, jmt=100, km=27, nt=5) c imt is longitude, jmt latitude, km depth, and nt number of time steps ************************************************************************* c variable declaration real temp(imt,jmt,km),salt(imt,jmt,km),time_step integer cdfid, rcode c ** cdfid = id number for the netCDF file my_data.cdf c ** rcode = error id number integer tid, sid, timeaxid c ** tid = variable id number for temperature c ** sid = variable id number for salt c ** timeaxid = variable id for the time axis integer itime c ** itime = index for do loop ************************************************************************* c dimension corner and step for defining size of gridded data integer corner(4) integer step(4) c corner and step are used to define the size of the gridded data c to be written out. Since temp and salt are four dimensional arrays, c corner and step must be four dimensions as well. In each output c to my_data.cdf within the do loop, the entire array of data (160 long. c pts, 100 lat. pts., 27 depth pts.) will be written for one time step. c Corner tells netCDF where to start, and step indicates how many steps c in each dimension to take. data corner/1, 1, 1, -1/ ! -1 is arbitrary; the time value ! of corner will be initialized ! within the do loop. data step/imt, jmt, km, 1/ ! NOT /1, km, jmt, imt/ c ***NOTE*** Since Fortran and C access data differently, the order of c the variables in the Fortran code must be opposite that in the cdl c file. In Fortran, the first variable varies fastest while in C, the c last variables varies fastest. ************************************************************************** c initialize cdfid by using ncopn cdfid = ncopn('converting_to_netcdf.cdf', ncwrite, rcode) if (rcode.ne.ncnoerr) stop 'error with ncopn' ************************************************************************** c get variable id's by using ncvid c THE VARIABLE NAMES MUST MATCH THE CDL FILE (case sensitive) tid = ncvid(cdfid, 'temp', rcode) if (rcode.ne.ncnoerr) stop 'error with tid' sid = ncvid(cdfid, 'salt', rcode) if (rcode.ne.ncnoerr) stop 'error with sid' timeaxid = ncvid(cdfid, 'time', rcode) if (rcode.ne.ncnoerr) stop 'error with timeaxid' ************************************************************************** c this is a good place to open youy data file ! OPEN (FILE=my_data.dat,STATUS='OLD') ************************************************************************** c begin do loop. Each step will read in one time step of data c and then write it out to my_data.cdf. do 10 itime = 1, nt corner(4) = itime ! initialize time step in corner time_step = float(itime) ! or you may read this from your file * insert your data reading routine here ! CALL READ_MY_DATA(temp,salt) ! you write this write (6,*) 'writing time step: ',itime, time_step ! diagnostic output call ncvpt(cdfid,tid,corner,step,temp(1,1,1),rcode) ! write data to if (rcode.ne.ncnoerr) stop 'error with t-put' call ncvpt(cdfid,sid,corner,step,salt(1,1,1),rcode) ! my_data.cdf with if (rcode.ne.ncnoerr) stop 'error with s-put' call ncvpt1(cdfid,timeaxid,itime,time_step,rcode) ! ncvpt if (rcode.ne.ncnoerr) stop 'error with timax-put' c ncvpt1 writes a single data point to the specified location within c timeaxid. The itime argument in ncvpt1 specifies the location within c time to write. The float(itime) argument is the value to be written; c float(itime) is used (rather than simply itime) so the type matches the c type of time declared in the CDL file. 10 continue ************************************************************************** c close my_data.cdf using ncclos call ncclos(cdfid, rcode) if (rcode.ne.ncnoerr) stop 'error with ncclos' ************************************************************************** stop end