Subroutine to write to netcdf file (4 dimensions)

subroutine D4_write_nc(FILE_NAME,outvar11,outvar22,NLONS,NLATS,NLVLS,NRECS,lons,lats,lvls,time)
use netcdf
implicit none

! This is the name of the data file we will create.
character (len = *) :: FILE_NAME
integer :: ncid

! We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
! timesteps of data.
integer,parameter :: NDIMS = 4
integer,parameter :: NDUM = 1
integer :: NLVLS , NLATS, NLONS , NRECS
character (len = *), parameter :: LVL_NAME = “level”
character (len = *), parameter :: LAT_NAME = “latitude”
character (len = *), parameter :: LON_NAME = “longitude”
character (len = *), parameter :: REC_NAME = “time”
character (len = *), parameter :: DUM_NAME = “dummy”
integer :: lvl_dimid, lon_dimid, lat_dimid, rec_dimid
integer :: dum_dimid

! The start and count arrays will tell the netCDF library where to
! write our data.
integer :: start(NDIMS), count(NDIMS)

! These program variables hold the latitudes and longitudes.
real :: lats(NLATS), lons(NLONS), lvls(NLVLS), time(NRECS)
real,parameter :: DUM(1)=1.0
integer :: lon_varid, lat_varid, lvl_varid, rec_varid
integer :: dum_varid

! We will create two netCDF variables, one each for outvar22erature and
! pressure fields.
character (len = *), parameter :: OUTVAR11_NAME=”aod_tfrac”
character (len = *), parameter :: OUTVAR22_NAME=”ext_tfrac”
integer :: outvar11_varid, outvar22_varid
integer :: dimids(NDIMS)

! We recommend that each variable carry a “units” attribute.
character (len = *), parameter :: UNITS = “units”
character (len = *), parameter :: OUTVAR11_UNITS = “UL”
character (len = *), parameter :: OUTVAR22_UNITS = “1/Km”
character (len = *), parameter :: LAT_UNITS = “degrees_north”
character (len = *), parameter :: LON_UNITS = “degrees_east”

! Program variables to hold the data we will write out. We will only
! need enough space to hold one timestep of data; one record.
! real :: outvar11_out(NLONS, NLATS, NLVLS)
! real :: outvar22_out(NLONS, NLATS, NLVLS)
real :: outvar11(NLONS, NLATS, NLVLS,NRECS)
real :: outvar22(NLONS, NLATS, NLVLS,NRECS)
real :: outvar11o(NLONS, NLATS, NLVLS)
real :: outvar22o(NLONS, NLATS, NLVLS)

! Use these to construct some latitude and longitude data for this
! example.

! Loop indices
integer :: lvl, lat, lon, rec, i,retval

! Create the file.
call check( nf90_create(FILE_NAME, nf90_clobber, ncid) )

! Define the dimensions. The record dimension is defined to have
! unlimited length – it can grow as needed. In this example it is
! the time dimension.
call check( nf90_def_dim(ncid, LVL_NAME, NLVLS, lvl_dimid) )
call check( nf90_def_dim(ncid, LAT_NAME, NLATS, lat_dimid) )
call check( nf90_def_dim(ncid, LON_NAME, NLONS, lon_dimid) )
call check( nf90_def_dim(ncid, REC_NAME,NF90_UNLIMITED, &
rec_dimid ) )
! call check( nf90_def_dim(ncid, DUM_NAME, NF90_UNLIMITED, &
! dum_dimid) )

! Define the coordinate variables. We will only define coordinate
! variables for lat and lon. Ordinarily we would need to provide
! an array of dimension IDs for each variable’s dimensions, but
! since coordinate variables only have one dimension, we can
! simply provide the address of that dimension ID (lat_dimid) and
! similarly for (lon_dimid).
call check( nf90_def_var(ncid, LAT_NAME, NF90_real, lat_dimid, &
lat_varid) )
call check( nf90_def_var(ncid, LON_NAME, NF90_real, lon_dimid, &
lon_varid) )
call check( nf90_def_var(ncid, LVL_NAME, NF90_real, lvl_dimid, &
lvl_varid) )
call check( nf90_def_var(ncid, REC_NAME, NF90_real, rec_dimid, &
rec_varid) )
! call check( nf90_def_var(ncid, DUM_NAME, NF90_real, dum_dimid, &
! dum_varid) )

! Assign units attributes to coordinate variables.
call check( nf90_put_att(ncid, lat_varid, UNITS, LAT_UNITS) )
call check( nf90_put_att(ncid, lon_varid, UNITS, LON_UNITS) )

! The dimids array is used to pass the dimids of the dimensions of
! the netCDF variables. Both of the netCDF variables we are creating
! share the same four dimensions. In Fortran, the unlimited
! dimension must come last on the list of dimids.
dimids = (/ lon_dimid, lat_dimid, lvl_dimid,rec_dimid/)

! Define the netCDF variables for the pressure and outvar22erature data.
call check( nf90_def_var(ncid, OUTVAR11_NAME, NF90_real, dimids, &
outvar11_varid) )
call check( nf90_def_var(ncid, OUTVAR22_NAME, NF90_real, dimids, &
outvar22_varid) )

! Assign units attributes to the netCDF variables.
call check( nf90_put_att(ncid, outvar11_varid, UNITS, OUTVAR11_UNIT&
&S) )
call check( nf90_put_att(ncid, outvar22_varid, UNITS, OUTVAR22_UNIT&
&S) )

! End define mode.
call check( nf90_enddef(ncid) )

! Write the coordinate variable data. This will put the latitudes
! and longitudes of our data grid into the netCDF file.
call check( nf90_put_var(ncid, lat_varid, lats) )
call check( nf90_put_var(ncid, lon_varid, lons) )
call check( nf90_put_var(ncid, lvl_varid, lvls) )
call check( nf90_put_var(ncid, rec_varid, time) )
! call check( nf90_put_var(ncid, dum_varid, dum) )

! These settings tell netcdf to write one timestep of data. (The
! setting of start(4) inside the loop below tells netCDF which
! timestep to write.)
count = (/ NLONS, NLATS, NLVLS, 1 /)
start = (/ 1, 1, 1, 1 /)

! Write the pretend data. This will write our surface pressure and
! surface outvar22erature data. The arrays only hold one timestep worth
! of data. We will just rewrite the same data for each timestep. In
! a real :: application, the data would change between timesteps.
do rec = 1, NRECS
start(4) = rec
outvar11o(:,:,:)=outvar11(:,:,:,rec)
outvar22o(:,:,:)=outvar22(:,:,:,rec)
call check( nf90_put_var(ncid, outvar11_varid, outvar11o, start = &
start, count = count) )
call check( nf90_put_var(ncid, outvar22_varid, outvar22o, &
start =start,count = count) )
end do

! Close the file. This causes netCDF to flush all buffers and make
! sure your data are really written to disk.
call check( nf90_close(ncid) )

print *,”*** SUCCESS writing example file “, FILE_NAME, “!”
end subroutine D4_write_ncsubroutine D4_write_nc(FILE_NAME,outvar11,outvar22,NLONS,NLATS,NLVLS,NRECS,lons,lats,lvls,time)
use netcdf
implicit none

! This is the name of the data file we will create.
character (len = *) :: FILE_NAME
integer :: ncid

! We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
! timesteps of data.
integer,parameter :: NDIMS = 4
integer,parameter :: NDUM = 1
integer :: NLVLS , NLATS, NLONS , NRECS
character (len = *), parameter :: LVL_NAME = “level”
character (len = *), parameter :: LAT_NAME = “latitude”
character (len = *), parameter :: LON_NAME = “longitude”
character (len = *), parameter :: REC_NAME = “time”
character (len = *), parameter :: DUM_NAME = “dummy”
integer :: lvl_dimid, lon_dimid, lat_dimid, rec_dimid
integer :: dum_dimid

! The start and count arrays will tell the netCDF library where to
! write our data.
integer :: start(NDIMS), count(NDIMS)

! These program variables hold the latitudes and longitudes.
real :: lats(NLATS), lons(NLONS), lvls(NLVLS), time(NRECS)
real,parameter :: DUM(1)=1.0
integer :: lon_varid, lat_varid, lvl_varid, rec_varid
integer :: dum_varid

! We will create two netCDF variables, one each for outvar22erature and
! pressure fields.
character (len = *), parameter :: OUTVAR11_NAME=”aod_tfrac”
character (len = *), parameter :: OUTVAR22_NAME=”ext_tfrac”
integer :: outvar11_varid, outvar22_varid
integer :: dimids(NDIMS)

! We recommend that each variable carry a “units” attribute.
character (len = *), parameter :: UNITS = “units”
character (len = *), parameter :: OUTVAR11_UNITS = “UL”
character (len = *), parameter :: OUTVAR22_UNITS = “1/Km”
character (len = *), parameter :: LAT_UNITS = “degrees_north”
character (len = *), parameter :: LON_UNITS = “degrees_east”

! Program variables to hold the data we will write out. We will only
! need enough space to hold one timestep of data; one record.
! real :: outvar11_out(NLONS, NLATS, NLVLS)
! real :: outvar22_out(NLONS, NLATS, NLVLS)
real :: outvar11(NLONS, NLATS, NLVLS,NRECS)
real :: outvar22(NLONS, NLATS, NLVLS,NRECS)
real :: outvar11o(NLONS, NLATS, NLVLS)
real :: outvar22o(NLONS, NLATS, NLVLS)

! Use these to construct some latitude and longitude data for this
! example.

! Loop indices
integer :: lvl, lat, lon, rec, i,retval

! Create the file.
call check( nf90_create(FILE_NAME, nf90_clobber, ncid) )

! Define the dimensions. The record dimension is defined to have
! unlimited length – it can grow as needed. In this example it is
! the time dimension.
call check( nf90_def_dim(ncid, LVL_NAME, NLVLS, lvl_dimid) )
call check( nf90_def_dim(ncid, LAT_NAME, NLATS, lat_dimid) )
call check( nf90_def_dim(ncid, LON_NAME, NLONS, lon_dimid) )
call check( nf90_def_dim(ncid, REC_NAME,NF90_UNLIMITED, &
rec_dimid ) )
! call check( nf90_def_dim(ncid, DUM_NAME, NF90_UNLIMITED, &
! dum_dimid) )

! Define the coordinate variables. We will only define coordinate
! variables for lat and lon. Ordinarily we would need to provide
! an array of dimension IDs for each variable’s dimensions, but
! since coordinate variables only have one dimension, we can
! simply provide the address of that dimension ID (lat_dimid) and
! similarly for (lon_dimid).
call check( nf90_def_var(ncid, LAT_NAME, NF90_real, lat_dimid, &
lat_varid) )
call check( nf90_def_var(ncid, LON_NAME, NF90_real, lon_dimid, &
lon_varid) )
call check( nf90_def_var(ncid, LVL_NAME, NF90_real, lvl_dimid, &
lvl_varid) )
call check( nf90_def_var(ncid, REC_NAME, NF90_real, rec_dimid, &
rec_varid) )
! call check( nf90_def_var(ncid, DUM_NAME, NF90_real, dum_dimid, &
! dum_varid) )

! Assign units attributes to coordinate variables.
call check( nf90_put_att(ncid, lat_varid, UNITS, LAT_UNITS) )
call check( nf90_put_att(ncid, lon_varid, UNITS, LON_UNITS) )

! The dimids array is used to pass the dimids of the dimensions of
! the netCDF variables. Both of the netCDF variables we are creating
! share the same four dimensions. In Fortran, the unlimited
! dimension must come last on the list of dimids.
dimids = (/ lon_dimid, lat_dimid, lvl_dimid,rec_dimid/)

! Define the netCDF variables for the pressure and outvar22erature data.
call check( nf90_def_var(ncid, OUTVAR11_NAME, NF90_real, dimids, &
outvar11_varid) )
call check( nf90_def_var(ncid, OUTVAR22_NAME, NF90_real, dimids, &
outvar22_varid) )

! Assign units attributes to the netCDF variables.
call check( nf90_put_att(ncid, outvar11_varid, UNITS, OUTVAR11_UNIT&
&S) )
call check( nf90_put_att(ncid, outvar22_varid, UNITS, OUTVAR22_UNIT&
&S) )

! End define mode.
call check( nf90_enddef(ncid) )

! Write the coordinate variable data. This will put the latitudes
! and longitudes of our data grid into the netCDF file.
call check( nf90_put_var(ncid, lat_varid, lats) )
call check( nf90_put_var(ncid, lon_varid, lons) )
call check( nf90_put_var(ncid, lvl_varid, lvls) )
call check( nf90_put_var(ncid, rec_varid, time) )
! call check( nf90_put_var(ncid, dum_varid, dum) )

! These settings tell netcdf to write one timestep of data. (The
! setting of start(4) inside the loop below tells netCDF which
! timestep to write.)
count = (/ NLONS, NLATS, NLVLS, 1 /)
start = (/ 1, 1, 1, 1 /)

! Write the pretend data. This will write our surface pressure and
! surface outvar22erature data. The arrays only hold one timestep worth
! of data. We will just rewrite the same data for each timestep. In
! a real :: application, the data would change between timesteps.
do rec = 1, NRECS
start(4) = rec
outvar11o(:,:,:)=outvar11(:,:,:,rec)
outvar22o(:,:,:)=outvar22(:,:,:,rec)
call check( nf90_put_var(ncid, outvar11_varid, outvar11o, start = &
start, count = count) )
call check( nf90_put_var(ncid, outvar22_varid, outvar22o, &
start =start,count = count) )
end do

! Close the file. This causes netCDF to flush all buffers and make
! sure your data are really written to disk.
call check( nf90_close(ncid) )

print *,”*** SUCCESS writing example file “, FILE_NAME, “!”
end subroutine D4_write_nc

contains
subroutine check(status)
integer, intent ( in) :: status

if(status /= nf90_noerr) then
print *, trim(nf90_strerror(status))
stop “Stopped”
end if
end subroutine check
end subroutine D4_write_nc

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s