Blame | Last modification | View Log | Download | RSS feed
module netcdf_tools
USE netcdf
implicit none
INTRINSIC :: TRIM, ADJUSTL, NINT, SIZE
interface read_file
module procedure read_file_1d
module procedure read_file_2d
module procedure read_file_3d
module procedure read_file_4d
end interface
contains
SUBROUTINE inquire_file(fname, &
x_name, y_name, z_name,t_name, &
nx, ny, nz, nt)
IMPLICIT NONE
! I/O
CHARACTER(LEN=*), INTENT(IN) :: fname ! filename
CHARACTER(LEN=*), INTENT(IN) :: x_name ! name of dimension in file dimension
CHARACTER(LEN=*), INTENT(IN) :: y_name ! name of dimension in file dimension
CHARACTER(LEN=*), INTENT(IN) :: z_name ! name of dimension in file dimension
CHARACTER(LEN=*), INTENT(IN) :: t_name ! name of dimension in file dimension
INTEGER, INTENT(OUT) :: nx ! file dimension lenght
INTEGER, INTENT(OUT) :: ny ! file dimension length
INTEGER, INTENT(OUT) :: nz ! file dimension length
INTEGER, INTENT(OUT) :: nt ! file dimension length
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'inquire_file'
INTEGER,SAVE :: ncid ! netCDF-ID
INTEGER :: dimid, varid
LOGICAL :: file_exists ! checking existence of file
INTEGER, DIMENSION(:), ALLOCATABLE :: date_file
CHARACTER(LEN=30) :: name_dim ! line
INQUIRE(FILE=TRIM(fname), EXIST=file_exists)
IF (.not.file_exists) THEN
WRITE(*,*) 'File ',TRIM(fname),' does NOT exist! skipping....'
STOP
ENDIF
! OPEN FILE
CALL NFERR( status, &
nf90_open(TRIM(fname), NF90_NOWRITE, ncid) &
,1)
! latitude dimension check
CALL NFERR( status, &
nf90_inq_dimid(ncid, x_name, dimid ) &
,2)
CALL NFERR( status, &
nf90_Inquire_Dimension(ncid, dimid, name_dim, nx ) &
,3)
! longitude dimension check
CALL NFERR( status, &
nf90_inq_dimid(ncid, y_name, dimid ) &
,4)
CALL NFERR( status, &
nf90_Inquire_Dimension(ncid, dimid, name_dim, ny ) &
,5)
! vertical dimension check
CALL NFERR( status, &
nf90_inq_dimid(ncid, z_name, dimid ) &
,6)
CALL NFERR( status, &
nf90_Inquire_Dimension(ncid, dimid, name_dim, nz ) &
,7)
! time dimension check
CALL NFERR( status, &
nf90_inq_dimid(ncid, t_name, dimid ) &
,8)
CALL NFERR( status, &
nf90_Inquire_Dimension(ncid, dimid, name_dim, nt ) &
,9)
!CLOSE FILE
CALL NFERR( status, &
nf90_close(ncid) &
,14)
! RETURN
status = 0
END SUBROUTINE inquire_file
! ------------------------------------------------------------------
! ------------------------------------------------------------------------
SUBROUTINE read_file_1D(fname, varname, data_file)
IMPLICIT NONE
! I/O
CHARACTER(LEN=*), INTENT(IN) :: fname ! filename
CHARACTER(LEN=*), INTENT(IN) :: varname ! variable name
REAL, DIMENSION(:), INTENT(OUT):: data_file ! INTENT(OUT)
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'read_file_1d'
INTEGER,SAVE :: ncid ! netCDF-ID
INTEGER :: dimid, varid
! OPEN FILE
CALL NFERR( status, &
nf90_open(TRIM(fname), NF90_NOWRITE, ncid) &
,21)
CALL NFERR( status, &
nf90_inq_varid(ncid, TRIM(varname), varid ) &
,22)
IF (status.ne.0) then
write(*,*) "variable not found in NetCDF file, skipping"
STOP
ENDIF
CALL NFERR( status, &
nf90_get_var(ncid, varid, data_file ) &
,23)
!CLOSE FILE
CALL NFERR( status, &
nf90_close(ncid) &
,24)
! RETURN
status = 0
END SUBROUTINE read_file_1D
! ------------------------------------------------------------------------
! ------------------------------------------------------------------------
SUBROUTINE read_file_2D(fname, varname, data_file)
IMPLICIT NONE
! I/O
CHARACTER(LEN=*), INTENT(IN) :: fname ! filename
CHARACTER(LEN=*), INTENT(IN) :: varname ! variable name
REAL, DIMENSION(:,:), INTENT(OUT):: data_file ! INTENT(OUT)
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'read_file_2d'
INTEGER,SAVE :: ncid ! netCDF-ID
INTEGER :: dimid, varid
! OPEN FILE
CALL NFERR( status, &
nf90_open(TRIM(fname), NF90_NOWRITE, ncid) &
,21)
CALL NFERR( status, &
nf90_inq_varid(ncid, TRIM(varname), varid ) &
,22)
IF (status.ne.0) then
write(*,*) "variable not found in NetCDF file, skipping"
STOP
ENDIF
CALL NFERR( status, &
nf90_get_var(ncid, varid, data_file ) &
,23)
!CLOSE FILE
CALL NFERR( status, &
nf90_close(ncid) &
,24)
! RETURN
status = 0
END SUBROUTINE read_file_2D
! ------------------------------------------------------------------------
! ------------------------------------------------------------------------
SUBROUTINE read_file_3D(fname, varname, data_file)
IMPLICIT NONE
! I/O
CHARACTER(LEN=*), INTENT(IN) :: fname ! filename
CHARACTER(LEN=*), INTENT(IN) :: varname ! variable name
REAL, DIMENSION(:,:,:), INTENT(OUT):: data_file ! INTENT(OUT)
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'read_file_3d'
INTEGER,SAVE :: ncid ! netCDF-ID
INTEGER :: dimid, varid
! OPEN FILE
CALL NFERR( status, &
nf90_open(TRIM(fname), NF90_NOWRITE, ncid) &
,21)
CALL NFERR( status, &
nf90_inq_varid(ncid, TRIM(varname), varid ) &
,22)
IF (status.ne.0) then
write(*,*) "variable not found in NetCDF file, skipping"
STOP
ENDIF
CALL NFERR( status, &
nf90_get_var(ncid, varid, data_file ) &
,23)
!CLOSE FILE
CALL NFERR( status, &
nf90_close(ncid) &
,24)
! RETURN
status = 0
END SUBROUTINE read_file_3D
! ------------------------------------------------------------------------
! ------------------------------------------------------------------------
SUBROUTINE read_file_4D(fname, varname, data_file)
IMPLICIT NONE
! I/O
CHARACTER(LEN=*), INTENT(IN) :: fname ! filename
CHARACTER(LEN=*), INTENT(IN) :: varname ! variable name
REAL, DIMENSION(:,:,:,:), INTENT(OUT):: data_file ! INTENT(OUT)
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'read_file_4d'
INTEGER,SAVE :: ncid ! netCDF-ID
INTEGER :: dimid, varid
! OPEN FILE
CALL NFERR( status, &
nf90_open(TRIM(fname), NF90_NOWRITE, ncid) &
,21)
CALL NFERR( status, &
nf90_inq_varid(ncid, TRIM(varname), varid ) &
,22)
IF (status.ne.0) then
write(*,*) "variable not found in NetCDF file, skipping"
STOP
ENDIF
CALL NFERR( status, &
nf90_get_var(ncid, varid, data_file ) &
,23)
!CLOSE FILE
CALL NFERR( status, &
nf90_close(ncid) &
,24)
! RETURN
status = 0
END SUBROUTINE read_file_4D
! ------------------------------------------------------------------------
! ------------------------------------------------------------------------
SUBROUTINE read_att(fname, varname, attname, str)
IMPLICIT NONE
! I/O
CHARACTER(LEN=*), INTENT(IN) :: fname ! filename
CHARACTER(LEN=*), INTENT(IN) :: varname ! variable name
CHARACTER(LEN=*), INTENT(IN) :: attname ! attribute name
CHARACTER(LEN=*), INTENT(OUT) :: str ! date string
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'read_startdate'
INTEGER,SAVE :: ncid ! netCDF-ID
INTEGER :: dimid, varid
! OPEN FILE
CALL NFERR( status, &
nf90_open(TRIM(fname), NF90_NOWRITE, ncid) &
,21)
CALL NFERR( status, &
nf90_inq_varid(ncid, TRIM(varname), varid ) &
,22)
IF (status.ne.0) then
write(*,*) "variable not found in NetCDF file, skipping"
STOP
ENDIF
CALL NFERR( status, &
nf90_get_att(ncid, varid, TRIM(attname), str ) &
,23)
!CLOSE FILE
CALL NFERR( status, &
nf90_close(ncid) &
,24)
! RETURN
status = 0
END SUBROUTINE read_att
! ------------------------------------------------------------------------
! ------------------------------------------------------------------------
SUBROUTINE nc_dump(fname, x_data, y_data,z_data,t_data, &
x_units,y_units, z_units,t_units, aps, ak, bk, &
label,fold, sfold, mfold, dfold, tp, dp, pmin, pmax)
USE netcdf
IMPLICIT NONE
CHARACTER(LEN=*), INTENT(IN) :: fname
REAL, DIMENSION(:), INTENT(IN) :: x_data, y_data,z_data,t_data
CHARACTER(LEN=*), INTENT(IN) :: x_units,y_units, z_units,t_units
REAL, DIMENSION(:,:,:), INTENT(IN) :: aps
REAL, DIMENSION(:), INTENT(IN) :: ak,bk
REAL, DIMENSION(:,:,:,:), INTENT(IN) :: label
REAL, DIMENSION(:,:,:), INTENT(IN) :: fold
REAL, DIMENSION(:,:,:), INTENT(IN) :: sfold
REAL, DIMENSION(:,:,:), INTENT(IN) :: mfold
REAL, DIMENSION(:,:,:), INTENT(IN) :: dfold
REAL, DIMENSION(:,:,:), INTENT(IN) :: dp
REAL, DIMENSION(:,:,:), INTENT(IN) :: tp
REAL, DIMENSION(:,:,:), INTENT(IN) :: pmin
REAL, DIMENSION(:,:,:), INTENT(IN) :: pmax
! LOCAL
INTEGER :: status
CHARACTER(LEN=*), PARAMETER :: substr = 'nc_dump'
INTEGER :: ncid ! netCDF-ID
INTEGER :: nlon,nlat,nlev,ntime
INTEGER :: dimid_lat, dimid_lon, dimid_lev, dimid_ilev, dimid_time
INTEGER :: varid_lat, varid_lon, varid_lev, varid_ilev, varid_time
INTEGER :: varid_aps, varid_hyam, varid_hybm, varid_label
INTEGER :: varid_fold, varid_sfold, varid_mfold, varid_dfold, varid_tp, varid_dp
INTEGER :: varid_pmin, varid_pmax
!
CHARACTER(LEN=8) :: date
CHARACTER(LEN=10) :: time
CHARACTER(LEN=5) :: zone
nlon = SIZE(x_data)
nlat = SIZE(y_data)
nlev = SIZE(z_data)
ntime = SIZE(t_data)
! CREATE NEW FILE
CALL NFERR(status, &
nf90_create(TRIM(fname), NF90_CLOBBER, ncid) &
,51)
! ADD GLOBALE ATTRIBUTES
! - VERSION
CALL NFERR(status, &
nf90_put_att(ncid, NF90_GLOBAL, 'contact:', &
'Andrea Pozzer, MPIC, Mainz') &
,52)
! - DATE AND TIME
CALL DATE_AND_TIME(date, time, zone)
CALL NFERR(status, &
nf90_put_att(ncid, NF90_GLOBAL, 'date', date) &
,53)
CALL NFERR(status, &
nf90_put_att(ncid, NF90_GLOBAL, 'time', TRIM(time)//TRIM(zone)) &
,54)
! DEFINE DIMENSIONS
CALL NFERR(status, &
nf90_def_dim(ncid, 'lon', nlon, dimid_lon) &
,56)
CALL NFERR(status, &
nf90_def_dim(ncid, 'lat', nlat, dimid_lat) &
,57)
CALL NFERR(status, &
nf90_def_dim(ncid, 'lev', nlev, dimid_lev) &
,58)
CALL NFERR(status, &
nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid_time) &
,59)
! DEFINE COORDINATE VARIABLES WITH ATTRIBUTES
CALL NFERR(status, &
nf90_def_var(ncid, 'lon', NF90_FLOAT, (/ dimid_lon /), varid_lon) &
,60)
CALL NFERR(status, &
nf90_put_att(ncid, varid_lon, 'long_name', 'longitude') &
,61)
CALL NFERR(status, &
nf90_put_att(ncid, varid_lon, 'units', x_units) &
,62)
CALL NFERR(status, &
nf90_def_var(ncid, 'lat', NF90_FLOAT, (/ dimid_lat /), varid_lat) &
,63)
CALL NFERR(status, &
nf90_put_att(ncid, varid_lat, 'long_name', 'latitude') &
,63)
CALL NFERR(status, &
nf90_put_att(ncid, varid_lat, 'units', y_units) &
,64)
CALL NFERR(status, &
nf90_def_var(ncid, 'lev', NF90_FLOAT, (/ dimid_lev /), varid_lev) &
,65)
CALL NFERR(status, &
nf90_put_att(ncid, varid_lev, 'long_name', 'level index') &
,66)
CALL NFERR(status, &
nf90_put_att(ncid, varid_lev, 'units', z_units) &
,67)
CALL NFERR(status, &
nf90_def_var(ncid, 'time', NF90_FLOAT, (/ dimid_time /), varid_time) &
,68)
CALL NFERR(status, &
nf90_put_att(ncid, varid_time, 'long_name', 'time') &
,69)
CALL NFERR(status, &
nf90_put_att(ncid, varid_time, 'units', t_units) &
,70)
! DEFINE VARIABLES
! - aps
CALL NFERR(status, &
nf90_def_var(ncid, 'APS', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_aps) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_aps, 'long_name' &
,'Surface Pressure') &
,79)
! - ak
CALL NFERR(status, &
nf90_def_var(ncid, 'hyam', NF90_FLOAT &
, (/ dimid_lev /), varid_hyam) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_hyam, 'long_name' &
,'"hybrid A coefficient at layer midpoints') &
,79)
! - bk
CALL NFERR(status, &
nf90_def_var(ncid, 'hybm', NF90_FLOAT &
, (/ dimid_lev /), varid_hybm) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_hybm, 'long_name' &
,'hybrid B coefficient at layer midpoints') &
,79)
! - label
CALL NFERR(status, &
nf90_def_var(ncid, 'label', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_lev, dimid_time /), varid_label) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_label, 'long_name' &
,'TR=1,ST=2,ST.CUTOFF=3,TR.TR.CUTOFF=4,PV.BLOB=5') &
,79)
! - fold
CALL NFERR(status, &
nf90_def_var(ncid, 'fold', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_fold) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_fold, 'long_name' &
, 'Tropopause folding: 1=YES, 2=NO') &
,79)
! - sfold
CALL NFERR(status, &
nf90_def_var(ncid, 'sfold', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_sfold) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_sfold, 'long_name' &
, 'Shallow tropopause folding (50< >200 hPa) : 1=YES, 2=NO') &
,79)
! - mfold
CALL NFERR(status, &
nf90_def_var(ncid, 'mfold', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_mfold) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_mfold, 'long_name' &
, 'Medium Tropopause folding (200< >350 hPa): 1=YES, 2=NO') &
,79)
! - dfold
CALL NFERR(status, &
nf90_def_var(ncid, 'dfold', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_dfold) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_dfold, 'long_name' &
, 'Deep Tropopause folding (>=350 hPa): 1=YES, 2=NO') &
,79)
! - tropopause
CALL NFERR(status, &
nf90_def_var(ncid, 'tp', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_tp) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_tp, 'long_name' &
, 'Tropopause') &
,79)
CALL NFERR(status, &
nf90_put_att(ncid, varid_tp, 'units' &
, 'hPa') &
,79)
! - folding extension
CALL NFERR(status, &
nf90_def_var(ncid, 'dp', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_dp) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_dp, 'long_name' &
, 'vertical extend of folding') &
,79)
CALL NFERR(status, &
nf90_put_att(ncid, varid_dp, 'units' &
, 'hPa') &
,79)
CALL NFERR(status, &
nf90_def_var(ncid, 'pmin', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_pmin) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_pmin, 'long_name' &
, 'vertical extend of folding') &
,79)
CALL NFERR(status, &
nf90_put_att(ncid, varid_pmin, 'units' &
, 'hPa') &
,79)
CALL NFERR(status, &
nf90_def_var(ncid, 'pmax', NF90_FLOAT &
, (/ dimid_lon, dimid_lat, dimid_time /), varid_pmax) &
,78)
CALL NFERR(status, &
nf90_put_att(ncid, varid_pmax, 'long_name' &
, 'vertical extend of folding') &
,79)
CALL NFERR(status, &
nf90_put_att(ncid, varid_pmax, 'units' &
, 'hPa') &
,79)
! SWITCH MODUS
CALL NFERR(status, &
nf90_enddef(ncid) &
,82)
! SAVE COORDINATE VARIBLES
CALL NFERR(status, &
nf90_put_var(ncid, varid_lon, x_data) &
,83)
CALL NFERR(status, &
nf90_put_var(ncid, varid_lat, y_data) &
,84)
CALL NFERR(status, &
nf90_put_var(ncid, varid_lev, z_data) &
,85)
CALL NFERR(status, &
nf90_put_var(ncid, varid_time, t_data) &
,86)
CALL NFERR(status, &
nf90_put_var(ncid, varid_aps, aps) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_hyam, ak) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_hybm, bk) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_label, label) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_fold, fold) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_sfold, sfold) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_mfold, mfold) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_dfold, dfold) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_tp, tp) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_dp, dp) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_pmin, pmin) &
,89)
CALL NFERR(status, &
nf90_put_var(ncid, varid_pmax, pmax) &
,89)
! CLOSE FILE
CALL NFERR(status, &
nf90_close(ncid) &
,90)
END SUBROUTINE nc_dump
! ------------------------------------------------------------------
SUBROUTINE NFERR(status,command,pos)
IMPLICIT NONE
! I/O
INTEGER, INTENT(OUT) :: status
INTEGER, INTENT(IN) :: command
INTEGER, INTENT(IN) :: pos
status=command
IF (status /= NF90_NOERR) THEN
WRITE(*,*) 'netCDF ERROR at position: ', pos
WRITE(*,*) 'netCDF ERROR status : ',status
WRITE(*,*) 'netCDF ERROR : ',nf90_strerror(status)
END IF
END SUBROUTINE NFERR
! ------------------------------------------------------------------
end module netcdf_tools