C ================================================ C C //////////////////////////////////////////////// C C ================================================ C program netCDF_rw implicit none include 'netcdf.inc' C |---------------------------------------------------------| C | This programme demonstrates several uses of the NetCDF- | C | libraries via the NetCDF-FORTRAN interface: | C | | C | Making an inquire call (get info), reading an .nc file, | C | defining dimensions and variables, assigning attribites | C | to variables, creating and writing in an .nc file | C | | C | It gets data from an .nc file and writes it into a | C | newly defined .nc file. | C | | C | --------------------------------------------------------| C | NOTE: Make sure the netcdf libraries are installed and | C | the paths to bin,lib and include files are set | C | correctly (for example in .bashrc,.cshrc or in the | C | compile command using -I/inc/path and -L/lib/path) and | C | libraries are included with -lnetcdff | C | | C | --------------------------------------------------------| C | This programme was tested with the netcdf-4.1.3 package | C | configured with '--disable-netcdf-4 --disable-dap' and | C | compiled with gfortran. As an example dataset, the NOAA | C | monthly mean SST's were used. | C | (Available on www.esrl.noaa.gov) | C | | C | General information on netcdf: www.unidata.ucar.edu | C | Specific questions about this script: | C | sebastian.mutz@uni-tuebingen.de | C |---------------------------------------------------------| C ------------------------------------------------ C C ---- VARIABLES and PARAMETERS ------------------ C C ------------------------------------------------ C character path*34,infile*40,outfile*40 integer x,y,t ! file specifics integer nx,ny,nt,ndim parameter(nx=360,ny=180,nt=361,ndim=3) ! dataset variables real xvar(nx),yvar(ny),tvar(nt) ! dimension variables real cvar(nx,ny,nt) ! data ! variable names and attributes (optional but recommended) character*(*)x_dname,y_dname,t_dname ! dimension names parameter(x_dname='lon',y_dname='lat',t_dname='time') character*(*)x_name,y_name,t_name,cvar_name ! variable names parameter(x_name='longitude',y_name='latitude',t_name='time', $ cvar_name='sst') character*(*)att ! attribute name parameter(att='units') character*(*)x_att,y_att,t_att,cvar_att ! variable attributes parameter(x_att='degrees east',y_att='degrees north', $ t_att='days since 1800-1-1 00:00:00',cvar_att='degC') ! netcdf 'communication' variables integer cvar_id,x_id,y_id,t_id ! variable IDs integer x_did,y_did,t_did,dimid(ndim) ! dimension IDs integer state,ncid ! return value and file ID integer nrecs,recid,dim,var,gatt,unlim ! for inquire call character*(nf_max_name) recname path='/home/sebastian/research/TIP/data/' ! path to dataset infile='editable_sst.mnmean.nc' ! dataset name C ------------------------------------------------- C C ==== INSTRUCTIONS =============================== C C ------------------------------------------------- C C ==== Inquire call =============================== C print* print*, 'Info on ', infile print*, '====================================' ! opening file state = nf_open(path//infile,nf_nowrite,ncid) if (state .ne. nf_noerr) call handle_err(state) ! inquire call state = nf_inq(ncid,dim,var,gatt,unlim) if (state .ne. nf_noerr) call handle_err(state) ! counting dimension variables and values for each do x=1,dim state = nf_inq_dim(ncid,x,recname,nrecs) if (state .ne. nf_noerr) call handle_err(state) print '(a13,i2,a4,a6,a8,i4)', 1 ' Dimension ',x,' : ',recname,'Count: ',nrecs enddo print*, ' > netCDF file checked' print* C ==== Read existing netCDF file ================== C print*, 'Reading file ', infile print*, '====================================' state = nf_inq_varid(ncid,'lon',x_id) state=nf_get_var_real(ncid,x_id,xvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (1) Longitudes read' state = nf_inq_varid(ncid,'lat',y_id) state=nf_get_var_real(ncid,y_id,yvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (2) Latitudes read' state = nf_inq_varid(ncid,'time',t_id) state=nf_get_var_real(ncid,t_id,tvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (3) Times read' state = nf_inq_varid(ncid,'sst',cvar_id) state=nf_get_var_real(ncid,cvar_id,cvar) if (state.ne.nf_noerr) call handle_err(state) print*, ' (4) Data variable read' print*, ' > Read complete' print* C ==== Creating and writing in new file =========== C outfile='mod.'//infile print*, 'Writing in ', outfile print*, '====================================' ! create file state = nf_create(path//outfile,nf_clobber,ncid) if (state .ne. nf_noerr) call handle_err(state) ! define dimensions print*, ' > Define dimensions' state = nf_def_dim(ncid,x_dname,nx,x_did) if (state .ne. nf_noerr) call handle_err(state) print*, ' (1) Longitude dimension defined' state = nf_def_dim(ncid,y_dname,ny,y_did) if (state .ne. nf_noerr) call handle_err(state) print*, ' (2) Latitude dimension defined' state = nf_def_dim(ncid,t_dname,nt,t_did) if (state .ne. nf_noerr) call handle_err(state) print*, ' (3) Time dimension defined' print* ! define variables print*, ' > Define variables' state = nf_def_var(ncid,x_name,nf_real,1,x_did,x_id) if (state .ne. nf_noerr) call handle_err(state) print*, ' (1) Longitude variable defined' state = nf_def_var(ncid,y_name,nf_real,1,y_did,y_id) if (state .ne. nf_noerr) call handle_err(state) print*, ' (2) Latitude variable defined' state = nf_def_var(ncid,t_name,nf_real,1,t_did,t_id) if (state .ne. nf_noerr) call handle_err(state) print*, ' (3) Time variable defined' ! dimension IDs for data variable dimid(1)=x_did dimid(2)=y_did dimid(3)=t_did ! define data as type real, with ndim dimensions (with ndim dimension IDs) state = nf_def_var(ncid,cvar_name,nf_real,ndim,dimid,cvar_id) if (state .ne. nf_noerr) call handle_err(state) print*, ' (4) Data variable defined' print* ! assign attributes to variables print*, ' > Assign attributes to variables' state = nf_put_att_text(ncid,x_id,att,len(x_att),x_att) if (state .ne. nf_noerr) call handle_err(state) print*, ' (1) Longitude attribute added' state = nf_put_att_text(ncid,y_id,att,len(y_att),y_att) if (state .ne. nf_noerr) call handle_err(state) print*, ' (2) Latitude attribute added' state = nf_put_att_text(ncid,t_id,att,len(t_att),t_att) if (state .ne. nf_noerr) call handle_err(state) print*, ' (3) Time attribute added' state = nf_put_att_text(ncid,cvar_id,att,len(cvar_att),cvar_att) if (state .ne. nf_noerr) call handle_err(state) print*, ' (4) Data attribute added' print* ! note:len specifies string length, can also type in manually ! end define mode state = nf_enddef(ncid) if (state .ne. nf_noerr) call handle_err(state) ! put variables in file print*, ' > Write variables in file' state = nf_put_var_real(ncid,x_id,xvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (1) Longitude added to file' state = nf_put_var_real(ncid,y_id,yvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (2) Latitude added to file' state = nf_put_var_real(ncid,t_id,tvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (3) Time added to file' state = nf_put_var_real(ncid,cvar_id,cvar) if (state .ne. nf_noerr) call handle_err(state) print*, ' (4) Data variable added to file' print* ! close file state = nf_close(ncid) if (state.ne.nf_noerr) call handle_err(state) print*, ' > File closed: ', path//outfile end C ================================================== C C ////////////////////////////////////////////////// C C ================================================== C subroutine handle_err(errcode) implicit none include 'netcdf.inc' integer errcode print *, 'Error: ', nf_strerror(errcode) stop end