c -------------------- c meridional_section.f c -------------------- program converting_to_netcdf c ---------------------------- 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 c update for your location include '/usr/local/netcdf/netcdf-3.5.0/include/netcdf.inc' c 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=360, jmt=1, km=26, nt=240) c imt is longitude, jmt latitude, km depth, and nt number of time steps ************************************************************************* c variable declaration real datain(imt) real temp(imt,jmt,km), u(imt,jmt,km), v(imt,jmt,km) real w(imt,jmt,km),salinity(imt,jmt,km) real sum_temp(imt,jmt,km,12) real sum_u(imt,jmt,km,12) real sum_v(imt,jmt,km,12) real sum_w(imt,jmt,km,12) real sum_salinity(imt,jmt,km,12) real tmp1,tmp2,tmp3 real miss integer cdfid, rcode, index c netcdf field ids integer tempid,uid,vid, timeaxid integer wid, salinityid integer itime,i,j,k,l ************************************************************************* c dimension corner and step for defining size of gridded data integer corner1(4) integer step1(4) integer corner2(3) integer step2(3) 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 corner1/1, 1, 1, -1/ data corner2/1, 1, -1/ data step1/imt, jmt, km, 1/ data step2/imt, jmt, 1/ real dayofdat(12) data dayofdat / 14, 45, 74, 105, 135, 166, & 196, 227, 258, 288, 319, 349 / 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('make_cdf_merid_sec_0N_clim_01.cdf', & ncwrite, rcode) if (rcode.ne.ncnoerr) stop 'error with ncopn' ************************************************************************** miss = -9.99e12 c get variable id's by using ncvid c THE VARIABLE NAMES MUST MATCH THE CDL FILE (case sensitive) tempid = ncvid(cdfid, 'temp', rcode) if (rcode.ne.ncnoerr) stop 'error with tempid' uid = ncvid(cdfid, 'u', rcode) if (rcode.ne.ncnoerr) stop 'error with uid' vid = ncvid(cdfid, 'v', rcode) if (rcode.ne.ncnoerr) stop 'error with vid' wid = ncvid(cdfid, 'w', rcode) if (rcode.ne.ncnoerr) stop 'error with wid' salinityid = ncvid(cdfid, 'salinity', rcode) if (rcode.ne.ncnoerr) stop 'error with salinityid' timeaxid = ncvid(cdfid, 'time', rcode) if (rcode.ne.ncnoerr) stop 'error with timeaxid' ************************************************************************** c this is a good place to open your data file open(unit=32, * file= * 'make_cdf_meridional_sec_0N_temp.dat', * status='old',form='unformatted') open(unit=33, * file= * 'make_cdf_meridional_sec_0N_u.dat', * status='old',form='unformatted') open(unit=34, * file= * 'make_cdf_meridional_sec_0N_v.dat', * status='old',form='unformatted') open(unit=35, * file= * 'make_cdf_meridional_sec_0N_w.dat', * status='old',form='unformatted') open(unit=36, * file= * 'make_cdf_meridional_sec_0N_salinity.dat', * status='old',form='unformatted') ************************************************************************** c begin do loop. Each step will read in one time step of data c and then write it out to my_data.cdf. c zero the climatology fields do l=1,12 do i=1,imt do j=1,jmt do k=1,km sum_temp(i,j,k,l) = 0.0 sum_u(i,j,k,l) = 0.0 sum_v(i,j,k,l) = 0.0 sum_w(i,j,k,l) = 0.0 sum_salinity(i,j,k,l) = 0.0 end do end do end do end do index = 0 do itime = 1, nt write(6,*) itime index = index +1 if(index .eq. 13)then index = 1 end if c read data do k=1,km read(32) datain do i=1, imt if(datain(i) .lt. -1.0e30)then sum_temp(i,1,k,index) = miss else sum_temp(i,1,k,index) = sum_temp(i,1,k,index) & + datain(i) end if end do end do do k=1,km read(33) datain do i=1, imt if(datain(i) .lt. -1.0e30)then sum_u(i,1,k,index) = miss else sum_u(i,1,k,index) = sum_u(i,1,k,index) & + datain(i)/100.0 end if end do end do do k=1,km read(34) datain do i=1, imt if(datain(i) .lt. -1.0e30)then sum_v(i,1,k,index) = miss else sum_v(i,1,k,index) = sum_v(i,1,k,index) & + datain(i)/100.0 end if end do end do do k=1,km read(35) datain do i=1, imt if(datain(i) .lt. -1.0e30)then sum_w(i,1,k,index) = miss else sum_w(i,1,k,index) = sum_w(i,1,k,index) & + datain(i)/100.0 end if end do end do do k=1,km read(36) datain do i=1, imt if(datain(i) .lt. -1.0e30)then sum_salinity(i,1,k,index) = miss else sum_salinity(i,1,k,index) = & sum_salinity(i,1,k,index) & + datain(i) end if end do end do end do c compute number of years tmp1 = float(nt)/12.0 write(6,*) 'the number of years is ', tmp1 do l=1,12 do i=1,imt do j=1,jmt do k=1,km if(sum_temp(i,j,k,l) .ne. miss)then sum_temp(i,j,k,l) = sum_temp(i,j,k,l)/tmp1 end if if(sum_u(i,j,k,l) .ne. miss)then sum_u(i,j,k,l) = sum_u(i,j,k,l)/tmp1 end if if(sum_v(i,j,k,l) .ne. miss)then sum_v(i,j,k,l) = sum_v(i,j,k,l)/tmp1 end if if(sum_w(i,j,k,l) .ne. miss)then sum_w(i,j,k,l) = sum_w(i,j,k,l)/tmp1 end if if(sum_salinity(i,j,k,l) .ne. miss)then sum_salinity(i,j,k,l) = sum_salinity(i,j,k,l)/tmp1 end if end do end do end do end do close(32) close(33) close(34) close(35) close(36) ************************************************************************** c begin do loop. Each step will read in one time step of data c and then write it out to my_data.cdf. write(6,*) 'Data writing routine' index = 0 do itime = 1, 12 time_step = dayofdat(itime) index = index +1 if(index .eq. 13)then index = 1 end if c initialize time step in corner corner2(3) = itime corner1(4) = itime do i=1,imt do j=1,jmt do k=1,km temp(i,j,k) = sum_temp(i,j,k,itime) end do end do end do do i=1,imt do j=1,jmt do k=1,km u(i,j,k) = sum_u(i,j,k,itime) end do end do end do do i=1,imt do j=1,jmt do k=1,km v(i,j,k) = sum_v(i,j,k,itime) end do end do end do do i=1,imt do j=1,jmt do k=1,km w(i,j,k) = sum_w(i,j,k,itime) end do end do end do do i=1,imt do j=1,jmt do k=1,km salinity(i,j,k) = sum_salinity(i,j,k,itime) end do end do end do c writing the data to the netCDF file write (6,*) 'writing time step: ',itime, time_step write (6,*) 'writing temp' call ncvpt(cdfid,tempid,corner1,step1,temp(1,1,1),rcode) if (rcode.ne.ncnoerr) stop 'error with sst-put' write (6,*) 'writing u' call ncvpt(cdfid,uid,corner1,step1,u(1,1,1),rcode) if (rcode.ne.ncnoerr) stop 'error with u-put' write (6,*) 'writing v' call ncvpt(cdfid,vid,corner1,step1,v(1,1,1),rcode) if (rcode.ne.ncnoerr) stop 'error with v-put' write (6,*) 'writing w' call ncvpt(cdfid,wid,corner1,step1,w(1,1,1),rcode) if (rcode.ne.ncnoerr) stop 'error with w-put' write (6,*) 'writing salinity' call ncvpt(cdfid,salinityid,corner1,step1,salinity(1,1,1),rcode) if (rcode.ne.ncnoerr) stop 'error with salinity-put' call ncvpt1(cdfid,timeaxid,itime,time_step,rcode) if (rcode.ne.ncnoerr) stop 'error with timax-put' end do ************************************************************************** c close my_data.cdf using ncclos call ncclos(cdfid, rcode) if (rcode.ne.ncnoerr) stop 'error with ncclos' ************************************************************************** stop end