Newer
Older
integer :: inb_procio_r_save
INTEGER(KIND=CDFINT) :: ioldmode
INTEGER(KIND=CDFINT) :: istatus
INTEGER(KIND=CDFINT) :: ivar_id
integer(kind=CDFINT) :: ilen
INTEGER(KIND=LFIINT) :: ilu,iresp
logical :: gok
CALL PRINT_MSG(NVERB_DEBUG,'IO','OPEN_FILES','called')
KNFILES_OUT = 0

WAUTELET Philippe
committed
!
! Infiles
!
IF (runmode == MODECDF2CDF .OR. runmode == MODECDF2LFI) THEN
!
! NetCDF
!

WAUTELET Philippe
committed
CALL IO_FILE_ADD2LIST(INFILES(1)%TFILE,HINFILE,'MNH','READ',HFORMAT='NETCDF4')

WAUTELET Philippe
committed
CALL IO_FILE_OPEN(INFILES(1)%TFILE)
nbvar_infile = INFILES(1)%TFILE%NNCNAR

WAUTELET Philippe
committed
!Open fallback file if provided
if ( options( OPTFALLBACK )%set ) then
inb_procio_r_save = NB_PROCIO_R
NB_PROCIO_R = 1
CALL IO_FILE_ADD2LIST(INFILES(2)%TFILE,options( OPTFALLBACK )%cvalue,'UNKNOWN','READ',HFORMAT='NETCDF4')
CALL IO_FILE_OPEN(INFILES(2)%TFILE)

WAUTELET Philippe
committed
NB_PROCIO_R = inb_procio_r_save
end if

WAUTELET Philippe
committed
ELSE
!
! LFI
!

WAUTELET Philippe
committed
CALL IO_FILE_ADD2LIST(INFILES(1)%TFILE,HINFILE,'MNH','READ', &

WAUTELET Philippe
committed
HFORMAT='LFI',KLFIVERB=0)

WAUTELET Philippe
committed
CALL IO_FILE_OPEN(INFILES(1)%TFILE)
ilu = INFILES(1)%TFILE%NLFIFLU
nbvar_infile = INFILES(1)%TFILE%NLFININAR

WAUTELET Philippe
committed
IF (options(OPTLIST)%set) THEN
CALL LFILAF(iresp,ilu,lfalse)

WAUTELET Philippe
committed
CALL IO_FILE_CLOSE(INFILES(1)%TFILE)

WAUTELET Philippe
committed
END IF

WAUTELET Philippe
committed
!Open fallback file if provided
if ( options( OPTFALLBACK )%set ) then
inb_procio_r_save = NB_PROCIO_R
NB_PROCIO_R = 1
CALL IO_FILE_ADD2LIST(INFILES(2)%TFILE,options( OPTFALLBACK )%cvalue,'UNKNOWN','READ', &
HFORMAT='LFI',KLFIVERB=0)
CALL IO_FILE_OPEN(INFILES(2)%TFILE)

WAUTELET Philippe
committed
NB_PROCIO_R = inb_procio_r_save
end if

WAUTELET Philippe
committed
END IF
!

WAUTELET Philippe
committed
!Read problem dimensions and some grid variables (needed to determine domain size and also by IO_FILE_OPEN to create netCDF files)

WAUTELET Philippe
committed
JPHEXT = 1
CALL IO_Field_read(INFILES(1)%TFILE,'JPHEXT',JPHEXT,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'JPHEXT',JPHEXT,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'JPHEXT not found')

WAUTELET Philippe
committed
JPHEXT_ll = JPHEXT
JPVEXT_ll = JPVEXT

WAUTELET Philippe
committed
!
ALLOCATE(NIMAX_ll,NJMAX_ll,NKMAX)
CALL IO_Field_read(INFILES(1)%TFILE,'IMAX',NIMAX_ll,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'IMAX',NIMAX_ll,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'IMAX not found')
CALL IO_Field_read(INFILES(1)%TFILE,'JMAX',NJMAX_ll,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'JMAX',NJMAX_ll,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'JMAX not found')

WAUTELET Philippe
committed
CALL IO_Field_read(INFILES(1)%TFILE,'KMAX',NKMAX,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'KMAX',NKMAX,IRESP2)

WAUTELET Philippe
committed
IF (IRESP2/=0) NKMAX = 0

WAUTELET Philippe
committed
!
CALL IO_Field_read(INFILES(1)%TFILE,'PROGRAM',CPROGRAM_ORIG,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'PROGRAM',CPROGRAM_ORIG,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'PROGRAM not found')

WAUTELET Philippe
committed
!
ALLOCATE(CSTORAGE_TYPE)
CALL IO_Field_read(INFILES(1)%TFILE,'STORAGE_TYPE',CSTORAGE_TYPE,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'STORAGE_TYPE',CSTORAGE_TYPE,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'STORAGE_TYPE not found')

WAUTELET Philippe
committed
!

WAUTELET Philippe
committed
ALLOCATE(XXHAT(NIMAX_ll+2*JPHEXT))
CALL IO_Field_read(INFILES(1)%TFILE,'XHAT',XXHAT,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'XHAT',XXHAT,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'XHAT not found')

WAUTELET Philippe
committed
ALLOCATE(XYHAT(NJMAX_ll+2*JPHEXT))
CALL IO_Field_read(INFILES(1)%TFILE,'YHAT',XYHAT,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'YHAT',XYHAT,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'YHAT not found')
CALL IO_Field_read(INFILES(1)%TFILE,'CARTESIAN',LCARTESIAN,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'CARTESIAN',LCARTESIAN,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'CARTESIAN not found')
CALL IO_Field_read(INFILES(1)%TFILE,'LAT0',XLAT0,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'LAT0',XLAT0,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LAT0 not found')
CALL IO_Field_read(INFILES(1)%TFILE,'LON0',XLON0,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'LON0',XLON0,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LON0 not found')
CALL IO_Field_read(INFILES(1)%TFILE,'BETA',XBETA,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'BETA',XBETA,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'BETA not found')

WAUTELET Philippe
committed
IF (.NOT.LCARTESIAN) THEN
CALL IO_Field_read(INFILES(1)%TFILE,'RPK', XRPK, IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'RPK', XRPK,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'RPK not found')
CALL IO_Field_read(INFILES(1)%TFILE,'LATORI',XLATORI,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'LATORI',XLATORI,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LATORI not found')
CALL IO_Field_read(INFILES(1)%TFILE,'LONORI',XLONORI,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'LONORI',XLONORI,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'LONORI not found')

WAUTELET Philippe
committed
ENDIF
!
IF (TRIM(CPROGRAM_ORIG)/='PGD' .AND. TRIM(CPROGRAM_ORIG)/='NESPGD' .AND. TRIM(CPROGRAM_ORIG)/='ZOOMPG' &
.AND. .NOT.(TRIM(CPROGRAM_ORIG)=='REAL' .AND. CSTORAGE_TYPE=='SU') ) THEN !condition to detect PREP_SURFEX
ALLOCATE(XZHAT(NKMAX+2*JPVEXT))
CALL IO_Field_read(INFILES(1)%TFILE,'ZHAT',XZHAT,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'ZHAT',XZHAT,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'ZHAT not found')

WAUTELET Philippe
committed
ALLOCATE(LSLEVE)
CALL IO_Field_read(INFILES(1)%TFILE,'SLEVE',LSLEVE,IRESP2)

WAUTELET Philippe
committed
!If not found in main file, try the fallback one
if ( options( OPTFALLBACK )%set .and. iresp2 /= 0 ) CALL IO_Field_read(INFILES(2)%TFILE,'SLEVE',LSLEVE,IRESP2)

WAUTELET Philippe
committed
if ( iresp2 /= 0 ) call Print_msg( NVERB_ERROR, 'IO', 'OPEN_FILES', 'SLEVE not found')

WAUTELET Philippe
committed
ALLOCATE(TDTMOD)

WAUTELET Philippe
committed
CALL IO_Field_read(INFILES(1)%TFILE,'DTMOD',TDTMOD,IRESP2)

WAUTELET Philippe
committed
IF(IRESP2/=0) DEALLOCATE(TDTMOD)

WAUTELET Philippe
committed

WAUTELET Philippe
committed
ALLOCATE(TDTCUR)

WAUTELET Philippe
committed
CALL IO_Field_read(INFILES(1)%TFILE,'DTCUR',TDTCUR,IRESP2)

WAUTELET Philippe
committed
IF(IRESP2/=0) DEALLOCATE(TDTCUR)

WAUTELET Philippe
committed
!If time values were not found, try to get it from the time coordinate
if ( .not. associated( tdtcur ) .and. infiles(1)%tfile%cformat == 'NETCDF4' ) then
gok = .false.
istatus = NF90_INQ_VARID( infiles(1)%tfile%nncid, 'time', ivar_id )
if ( istatus == NF90_NOERR ) then
allocate( tdtcur )
istatus = NF90_GET_VAR( infiles(1)%tfile%nncid, ivar_id, tdtcur%xtime )

WAUTELET Philippe
committed
if ( istatus == NF90_NOERR ) then
istatus = NF90_INQUIRE_ATTRIBUTE( infiles(1)%tfile%nncid, ivar_id, 'units', len = ilen )
if ( istatus == NF90_NOERR ) then
allocate( character(len = ilen ) :: yunits )
istatus = NF90_GET_ATT( infiles(1)%tfile%nncid, ivar_id, 'units', yunits )
! Extract date from yunits
idx = INDEX( yunits, 'since ' )
Read( yunits(idx+6 :idx+9 ) , '( I4.4 )' ) tdtcur%nyear
Read( yunits(idx+11:idx+12 ), '( I2.2 )' ) tdtcur%nmonth
Read( yunits(idx+14:idx+15 ), '( I2.2 )' ) tdtcur%nday

WAUTELET Philippe
committed
if ( .not. associated( tdtmod ) ) then
allocate( tdtmod )
tdtmod = tdtcur

WAUTELET Philippe
committed
end if
gok = .true.
end if
end if
end if
if ( .not. gok ) deallocate( tdtcur )
end if

WAUTELET Philippe
committed
END IF

WAUTELET Philippe
committed
! Outfiles
!
IF (runmode == MODELFI2CDF .OR. runmode == MODECDF2CDF) THEN

WAUTELET Philippe
committed
!

WAUTELET Philippe
committed
! NetCDF

WAUTELET Philippe
committed
!

WAUTELET Philippe
committed
IF (.NOT.options(OPTSPLIT)%set) THEN
KNFILES_OUT = KNFILES_OUT + 1

WAUTELET Philippe
committed
idx = KNFILES_OUT

WAUTELET Philippe
committed
if ( options(OPTDIR)%set ) then
CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,HOUTFILE,'MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='NETCDF4',OOLD=.TRUE., hdirname = options(OPTDIR)%cvalue )
else
CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,HOUTFILE,'MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='NETCDF4',OOLD=.TRUE.)
end if

WAUTELET Philippe
committed
CALL IO_FILE_OPEN(outfiles(idx)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)

WAUTELET Philippe
committed
IF (options(OPTCOMPRESS)%set) THEN
outfiles(idx)%tfile%LNCCOMPRESS = .TRUE.
outfiles(idx)%tfile%NNCCOMPRESS_LEVEL = options(OPTCOMPRESS)%ivalue

WAUTELET Philippe
committed
END IF

WAUTELET Philippe
committed
IF (options(OPTREDUCE)%set) THEN
outfiles(idx)%tfile%LNCREDUCE_FLOAT_PRECISION = .TRUE.

WAUTELET Philippe
committed
END IF
istatus = NF90_SET_FILL(outfiles(idx)%TFILE%NNCID,NF90_NOFILL,ioldmode)
if ( istatus /= NF90_NOERR ) call IO_Err_handle_nc4( istatus, 'OPEN_FILES', 'NF90_SET_FILL', '' )

WAUTELET Philippe
committed
!
! LFI
!
KNFILES_OUT = KNFILES_OUT + 1
idx = KNFILES_OUT

WAUTELET Philippe
committed
if ( options(OPTDIR)%set ) then
CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,houtfile,'MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='LFI',KLFIVERB=0,OOLD=.TRUE., hdirname = options(OPTDIR)%cvalue )
else
CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,houtfile,'MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='LFI',KLFIVERB=0,OOLD=.TRUE.)
end if

WAUTELET Philippe
committed
LIOCDF4 = .FALSE. !Necessary to open correctly the LFI file

WAUTELET Philippe
committed
CALL IO_FILE_OPEN(outfiles(idx)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)

WAUTELET Philippe
committed
LIOCDF4 = .TRUE.
END IF
!
! Create a dummy netCDF file necessary to manage correctly the netCDF dims
IF (runmode == MODECDF2LFI) THEN
KNFILES_OUT = KNFILES_OUT + 1
idx = KNFILES_OUT

WAUTELET Philippe
committed
if ( options(OPTDIR)%set ) then
CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,'dummy_file','MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='NETCDF4',OOLD=.TRUE., hdirname = options(OPTDIR)%cvalue )
else
CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,'dummy_file','MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='NETCDF4',OOLD=.TRUE.)
end if

WAUTELET Philippe
committed
CALL IO_FILE_OPEN(outfiles(idx)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)

WAUTELET Philippe
committed
END IF
PRINT *,'--> Converted to file: ', TRIM(houtfile)

WAUTELET Philippe
committed
SUBROUTINE OPEN_SPLIT_NCFILES_OUT(outfiles,KNFILES_OUT,houtfile,nbvar,options)

WAUTELET Philippe
committed
USE MODE_IO_FILE, ONLY: IO_FILE_OPEN

WAUTELET Philippe
committed
USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST
TYPE(TFILE_ELT),DIMENSION(:), INTENT(INOUT) :: outfiles
INTEGER, INTENT(OUT) :: KNFILES_OUT

WAUTELET Philippe
committed
CHARACTER(LEN=*), INTENT(IN) :: houtfile
INTEGER, INTENT(IN) :: nbvar

WAUTELET Philippe
committed
TYPE(option),DIMENSION(:), INTENT(IN) :: options

WAUTELET Philippe
committed
CHARACTER(LEN=:),ALLOCATABLE :: filename
CHARACTER(LEN=:),ALLOCATABLE :: YLIST
CHARACTER(LEN=NMNHNAMELGTMAX),DIMENSION(nbvar) :: YVARS
INTEGER :: ji
INTEGER :: idx1, idx2
INTEGER(KIND=CDFINT) :: status
INTEGER(KIND=CDFINT) :: ioldmode
CALL PRINT_MSG(NVERB_DEBUG,'IO','OPEN_SPLIT_NCFILES_OUT','called')
KNFILES_OUT = nbvar
YLIST = TRIM(options(OPTVAR)%cvalue)
DO ji = 1,nbvar-1
idx1 = INDEX(YLIST,',')
idx2 = INDEX(YLIST,'=')
IF (idx1/=0) THEN
IF (idx2/=0 .AND. idx2<idx1) THEN
YVARS(ji) = YLIST(1:idx2-1)
ELSE
YVARS(ji) = YLIST(1:idx1-1)
END IF
YLIST = YLIST(idx1+1:)
ELSE
CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_SPLIT_NCFILES_OUT','problem separating variable names')
END IF

WAUTELET Philippe
committed
END DO
idx2 = INDEX(YLIST,'=')
IF (idx2>0) THEN
YVARS(nbvar) = YLIST(1:idx2-1)
ELSE
YVARS(nbvar) = YLIST
END IF

WAUTELET Philippe
committed
DO ji = 1,nbvar
filename = trim(houtfile)//'.'//TRIM(YVARS(ji))

WAUTELET Philippe
committed
if ( options(OPTDIR)%set ) then
CALL IO_FILE_ADD2LIST(outfiles(ji)%TFILE,filename,'MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='NETCDF4', hdirname = options(OPTDIR)%cvalue )
else
CALL IO_FILE_ADD2LIST(outfiles(ji)%TFILE,filename,'MNH','WRITE', &

WAUTELET Philippe
committed
HFORMAT='NETCDF4')
end if

WAUTELET Philippe
committed
CALL IO_FILE_OPEN(outfiles(ji)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)

WAUTELET Philippe
committed
IF (options(OPTCOMPRESS)%set) THEN
outfiles(ji)%tfile%LNCCOMPRESS = .TRUE.
outfiles(ji)%tfile%NNCCOMPRESS_LEVEL = options(OPTCOMPRESS)%ivalue

WAUTELET Philippe
committed
END IF
IF (options(OPTREDUCE)%set) THEN
outfiles(ji)%tfile%LNCREDUCE_FLOAT_PRECISION = .TRUE.

WAUTELET Philippe
committed
END IF

WAUTELET Philippe
committed
status = NF90_SET_FILL(outfiles(ji)%TFILE%NNCID,NF90_NOFILL,ioldmode)

WAUTELET Philippe
committed
if ( status /= NF90_NOERR ) call IO_Err_handle_nc4( status, 'OPEN_SPLIT_NCFILES_OUT', 'NF90_SET_FILL', '' )

WAUTELET Philippe
committed
END DO
SUBROUTINE CLOSE_FILES(filelist,KNFILES)

WAUTELET Philippe
committed
USE MODE_IO_FILE, ONLY: IO_FILE_CLOSE

WAUTELET Philippe
committed
TYPE(TFILE_ELT),DIMENSION(:),INTENT(INOUT) :: filelist
INTEGER, INTENT(IN) :: KNFILES
INTEGER :: ji
CALL PRINT_MSG(NVERB_DEBUG,'IO','CLOSE_FILES','called')
DO ji=1,KNFILES

WAUTELET Philippe
committed
IF (filelist(ji)%TFILE%LOPENED) CALL IO_FILE_CLOSE(filelist(ji)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)

WAUTELET Philippe
committed
END DO

WAUTELET Philippe
committed

WAUTELET Philippe
committed
SUBROUTINE IO_Metadata_get_nc4(TPFILE,KVAR_ID,TPREC)
USE MODD_DIM_n, ONLY: NKMAX
USE MODD_PARAMETERS, ONLY: JPVEXT
TYPE(TFILEDATA), INTENT(IN) :: TPFILE
INTEGER(KIND=CDFINT), INTENT(IN) :: KVAR_ID
TYPE(workfield), INTENT(INOUT) :: TPREC
character(len=:), allocatable :: YSPLIT
character(len=:), allocatable :: YTIMEDEP
integer :: iblocks
INTEGER :: ILENG
INTEGER :: JDIM
INTEGER(KIND=CDFINT) :: ISTATUS
INTEGER(KIND=CDFINT) :: IFILE_ID
INTEGER(KIND=CDFINT) :: IVAR_ID
INTEGER(KIND=CDFINT),DIMENSION(NF90_MAX_VAR_DIMS) :: IDIMS_ID
LOGICAL :: GSPLIT_AT_ENTRY

WAUTELET Philippe
committed
CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Metadata_get_nc4','called')
!Necessary to know if we already are in a split file for determining correct number of dimensions
GSPLIT_AT_ENTRY = TPREC%LSPLIT
IFILE_ID = TPFILE%NNCID
iblocks = -1
ISTATUS = NF90_INQUIRE_VARIABLE(IFILE_ID, KVAR_ID, NDIMS = TPREC%NDIMS_FILE, &
XTYPE = TPREC%NTYPE_FILE, DIMIDS = IDIMS_ID)

WAUTELET Philippe
committed
if ( istatus /= NF90_NOERR ) call IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQUIRE_VARIABLE', '' )
!split_variable and other attributes were added in MesoNH > 5.4.2
ISTATUS = NF90_INQUIRE_ATTRIBUTE(IFILE_ID, KVAR_ID, 'split_variable', LEN=ILENG)
IF (ISTATUS == NF90_NOERR) THEN
IF (GSPLIT_AT_ENTRY) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_Metadata_get_nc4','split variable delcaration inside a split file')
ALLOCATE(CHARACTER(LEN=ILENG) :: YSPLIT)
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'split_variable', YSPLIT)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'split_variable' )
IF ( YSPLIT == 'yes' ) then
TPREC%LSPLIT = .true.
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'ndims', TPREC%NDIMS_FILE)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'ndims' )
IF ( TPREC%NDIMS_FILE/=3 ) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_Metadata_get_nc4', &
'split variable with ndims/=3 not supported')
ISTATUS = NF90_INQUIRE_ATTRIBUTE(IFILE_ID, KVAR_ID, 'time_dependent', LEN=ILENG)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQUIRE_ATTRIBUTE', &
'time_dependent' )
ALLOCATE(CHARACTER(LEN=ILENG) :: YTIMEDEP)
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'time_dependent', YTIMEDEP)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'time_dependent' )
IF ( YTIMEDEP == 'yes' ) then
TPREC%TFIELD%LTIMEDEP = .TRUE.
ELSE IF ( YTIMEDEP == 'no' ) THEN
TPREC%TFIELD%LTIMEDEP = .FALSE.
ELSE
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Metadata_get_nc4','unknown value '//trim(YTIMEDEP)// &
' for time_dependent attribute' )
END IF
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'split_nblocks', iblocks)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'split_nblocks' )
!PW: todo:check tfiles_ioz exist
IFILE_ID = TPFILE%TFILES_IOZ(1)%TFILE%NNCID
istatus = NF90_INQ_VARID(IFILE_ID,trim(TPREC%NAME)//'0001',ivar_id)
IF (ISTATUS /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQ_VARID', &
trim(TPREC%NAME)//'0001' )
ISTATUS = NF90_INQUIRE_VARIABLE(IFILE_ID, IVAR_ID, DIMIDS = IDIMS_ID)
IF (ISTATUS /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQUIRE_VARIABLE',&
trim(TPREC%NAME)//'0001' )
DEALLOCATE(YTIMEDEP)
ELSE IF ( YSPLIT /= 'no' ) THEN
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Metadata_get_nc4','unknown value '//trim(YSPLIT)//' for split_variable attribute' )
END IF
DEALLOCATE(YSPLIT)
END IF
ISTATUS = NF90_GET_ATT(IFILE_ID,KVAR_ID,'grid',TPREC%NGRID_FILE)
!On MesoNH versions < 5.4.0, the grid number was stored in 'GRID' instead of 'grid'
IF (ISTATUS /= NF90_NOERR) ISTATUS = NF90_GET_ATT(IFILE_ID,KVAR_ID,'GRID',TPREC%NGRID_FILE)
IF (ISTATUS /= NF90_NOERR) TPREC%NGRID_FILE = 0
ISTATUS = NF90_GET_ATT(IFILE_ID,KVAR_ID,'units',TPREC%CUNITS_FILE)
IF (ISTATUS /= NF90_NOERR) TPREC%CUNITS_FILE = ''
!split_variable and other attributes were added in MesoNH > 5.4.2
ISTATUS = NF90_INQUIRE_ATTRIBUTE(IFILE_ID, KVAR_ID, 'split_variable', LEN=ILENG)
IF (ISTATUS == NF90_NOERR) THEN
IF (GSPLIT_AT_ENTRY) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_Metadata_get_nc4','split variable declaration inside a split file')
ALLOCATE(CHARACTER(LEN=ILENG) :: YSPLIT)
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'split_variable', YSPLIT)
IF (istatus /= NF90_NOERR) call IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'split_variable' )
IF ( YSPLIT == 'yes' ) then
TPREC%LSPLIT = .true.
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'ndims', TPREC%NDIMS_FILE)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'ndims' )
IF ( TPREC%NDIMS_FILE/=3 ) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_Metadata_get_nc4', &
'split variable with ndims/=3 not supported')
ISTATUS = NF90_INQUIRE_ATTRIBUTE(IFILE_ID, KVAR_ID, 'time_dependent', LEN=ILENG)
IF (istatus /= NF90_NOERR) &
CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQUIRE_ATTRIBUTE', 'time_dependent' )
ALLOCATE(CHARACTER(LEN=ILENG) :: YTIMEDEP)
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'time_dependent', YTIMEDEP)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'time_dependent' )
IF ( YTIMEDEP == 'yes' ) then
TPREC%TFIELD%LTIMEDEP = .TRUE.
ELSE IF ( YTIMEDEP == 'no' ) THEN
TPREC%TFIELD%LTIMEDEP = .FALSE.
ELSE
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Metadata_get_nc4','unknown value '//trim(YTIMEDEP)// &
' for time_dependent attribute' )
END IF
ISTATUS = NF90_GET_ATT(IFILE_ID, KVAR_ID, 'split_nblocks', iblocks)
IF (istatus /= NF90_NOERR) CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_GET_ATT', 'split_nblocks' )
!PW: todo:check tfiles_ioz exist
IFILE_ID = TPFILE%TFILES_IOZ(1)%TFILE%NNCID
istatus = NF90_INQ_VARID(IFILE_ID,trim(TPREC%NAME)//'0001',ivar_id)
IF (ISTATUS /= NF90_NOERR) &
CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQ_VARID', trim(TPREC%NAME)//'0001' )
ISTATUS = NF90_INQUIRE_VARIABLE(IFILE_ID, IVAR_ID, DIMIDS = IDIMS_ID)
IF (ISTATUS /= NF90_NOERR) &
CALL IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQUIRE_VARIABLE', trim(TPREC%NAME)//'0001' )
DEALLOCATE(YTIMEDEP)
ELSE IF ( YSPLIT /= 'no' ) THEN
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Metadata_get_nc4','unknown value '//trim(YSPLIT)//' for split_variable attribute' )
END IF
DEALLOCATE(YSPLIT)
END IF
ISTATUS = NF90_GET_ATT(IFILE_ID,KVAR_ID,'grid',TPREC%NGRID_FILE)
!On MesoNH versions < 5.4.0, the grid number was stored in 'GRID' instead of 'grid'
IF (ISTATUS /= NF90_NOERR) ISTATUS = NF90_GET_ATT(IFILE_ID,KVAR_ID,'GRID',TPREC%NGRID_FILE)
IF (ISTATUS /= NF90_NOERR) TPREC%NGRID_FILE = 0
ISTATUS = NF90_GET_ATT(IFILE_ID,KVAR_ID,'units',TPREC%CUNITS_FILE)
IF (ISTATUS /= NF90_NOERR) TPREC%CUNITS_FILE = ''
IF (.NOT.TPREC%LSPLIT) THEN
ALLOCATE(TPREC%NDIMSIZES_FILE(TPREC%NDIMS_FILE))
ALLOCATE(TPREC%CDIMNAMES_FILE(TPREC%NDIMS_FILE))
ELSE
IF ( GSPLIT_AT_ENTRY ) THEN
ALLOCATE(TPREC%NDIMSIZES_FILE(TPREC%NDIMS_FILE+1))
ALLOCATE(TPREC%CDIMNAMES_FILE(TPREC%NDIMS_FILE+1))
ELSE
IF (TPREC%TFIELD%LTIMEDEP) THEN
ALLOCATE(TPREC%NDIMSIZES_FILE(TPREC%NDIMS_FILE+1))
ALLOCATE(TPREC%CDIMNAMES_FILE(TPREC%NDIMS_FILE+1))
ELSE
ALLOCATE(TPREC%NDIMSIZES_FILE(TPREC%NDIMS_FILE))
ALLOCATE(TPREC%CDIMNAMES_FILE(TPREC%NDIMS_FILE))
END IF
END IF
END IF
IF (TPREC%NDIMS_FILE == 0) THEN
! Scalar variable
ILENG = 1
ELSE
! Fill dimensions info
ILENG = 1
DO JDIM=1,TPREC%NDIMS_FILE
ISTATUS = NF90_INQUIRE_DIMENSION(IFILE_ID,IDIMS_ID(JDIM), &
len = TPREC%NDIMSIZES_FILE(JDIM), &
name = TPREC%CDIMNAMES_FILE(JDIM) )

WAUTELET Philippe
committed
if ( istatus /= NF90_NOERR ) call IO_Err_handle_nc4( istatus, 'IO_Metadata_get_nc4', 'NF90_INQUIRE_DIMENSION', '' )
ILENG = ILENG*TPREC%NDIMSIZES_FILE(JDIM)
END DO
IF (TPREC%NDIMS_FILE>0) THEN
IF (TPREC%CDIMNAMES_FILE(TPREC%NDIMS_FILE)=='time') THEN
TPREC%TFIELD%LTIMEDEP = .TRUE.
ELSE
TPREC%TFIELD%LTIMEDEP = .FALSE.
END IF
ELSE
TPREC%TFIELD%LTIMEDEP = .FALSE.
END IF
IF (TPREC%LSPLIT) THEN
IF( (.NOT.TPREC%TFIELD%LTIMEDEP .AND. TPREC%NDIMS_FILE/=2) &
.OR. ( TPREC%TFIELD%LTIMEDEP .AND. TPREC%NDIMS_FILE/=3) ) &
CALL PRINT_MSG(NVERB_FATAL,'IO','IO_Metadata_get_nc4',trim(TPREC%NAME)//': split variables can only be 3D')
!Split variables are Z-split
!Move time dimension to last (4th) position
IF (TPREC%TFIELD%LTIMEDEP) THEN
TPREC%NDIMSIZES_FILE(4) = TPREC%NDIMSIZES_FILE(3)
TPREC%CDIMNAMES_FILE(4) = TPREC%CDIMNAMES_FILE(3)
END IF
!Add vertical/3rd dimension
SELECT CASE(TPREC%NGRID_FILE)
CASE (1, 2, 3, 5)
TPREC%CDIMNAMES_FILE(3) = 'level'
CASE (4, 6, 7, 8)
TPREC%CDIMNAMES_FILE(3) = 'level_w'
CASE DEFAULT
TPREC%CDIMNAMES_FILE(3) = 'unknown'
END SELECT
IF (iblocks == -1 ) then
TPREC%NDIMSIZES_FILE(3) = NKMAX+2*JPVEXT
else
if (TPREC%NGRID_FILE/=0 .and. iblocks/=NKMAX+2*JPVEXT) THEN
!If size is not as expected, reset its name
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Metadata_get_nc4',trim(TPREC%NAME)//': strange nblocks size')
TPREC%CDIMNAMES_FILE(3) = 'unknown'
end if
TPREC%NDIMSIZES_FILE(3) = iblocks
end if
ILENG = ILENG * TPREC%NDIMSIZES_FILE(3)
END IF
END IF
TPREC%NSIZE = ILENG

WAUTELET Philippe
committed
END SUBROUTINE IO_Metadata_get_nc4

WAUTELET Philippe
committed
SUBROUTINE IO_Dims_fill_nc4(TPFILE,TPREC,KRESP)
USE MODD_IO, ONLY: TFILEDATA
use mode_io_tools_nc4, only: IO_Dim_find_create_nc4, IO_Dim_find_byname_nc4

WAUTELET Philippe
committed

WAUTELET Philippe
committed
TYPE(TFILEDATA),INTENT(INOUT) :: TPFILE

WAUTELET Philippe
committed
TYPE(workfield),INTENT(INOUT) :: TPREC
INTEGER, INTENT(OUT) :: KRESP
integer :: iidx

WAUTELET Philippe
committed
INTEGER :: JJ

WAUTELET Philippe
committed
CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Dims_fill_nc4','called')

WAUTELET Philippe
committed
KRESP = 0

WAUTELET Philippe
committed
IF (TPREC%NDIMS_FILE<TPREC%TFIELD%NDIMS) THEN

WAUTELET Philippe
committed
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Dims_fill_nc4','less dimensions than expected for '//TRIM(TPREC%TFIELD%CMNHNAME)// &

WAUTELET Philippe
committed
' => ignored')
TPREC%tbw = .FALSE.
TPREC%tbr = .FALSE.
TPREC%found = .FALSE.
RETURN
END IF

WAUTELET Philippe
committed
ALLOCATE(TPREC%TDIMS(TPREC%TFIELD%NDIMS))
DO JJ=1,TPREC%TFIELD%NDIMS
!DO JJ=1,TPREC%NDIMS_FILE !NDIMS_FILE can be bigger than NDIMS due to time dimension (it can be ignored here)

WAUTELET Philippe
committed
CALL IO_Dim_find_byname_nc4(TPFILE,TPREC%CDIMNAMES_FILE(JJ),TPREC%TDIMS(JJ),KRESP)

WAUTELET Philippe
committed
!If dimension not found => create it
IF (KRESP/=0) THEN
call IO_Dim_find_create_nc4( tpfile, tprec%ndimsizes_file(jj), iidx )
tprec%tdims(jj) = tpfile%tncdims%tdims(iidx)

WAUTELET Philippe
committed
KRESP = 0
END IF
IF (TRIM(TPREC%TDIMS(JJ)%cname)/='time' .AND. &
TPREC%TDIMS(JJ)%nlen /= TPREC%NDIMSIZES_FILE(JJ)) THEN

WAUTELET Philippe
committed
CALL PRINT_MSG(NVERB_WARNING,'IO','IO_Dims_fill_nc4','problem with dimensions for '//TPREC%TFIELD%CMNHNAME)

WAUTELET Philippe
committed
KRESP = -3
EXIT
END IF
END DO

WAUTELET Philippe
committed
END SUBROUTINE IO_Dims_fill_nc4

WAUTELET Philippe
committed