!---------------------------------------------------------------------- ! NEMO system team, System and Interface for oceanic RElocable Nesting !---------------------------------------------------------------------- ! ! MODULE: iom ! ! DESCRIPTION: !> @brief Input/Output manager : Library to read input files !> !> @details !> to open file:
!> @code !> CALL iom_open(td_file) !> @endcode !> - td_file is file structure !> !> to create file:
!> @code !> CALL iom_create(td_file) !> @endcode !> - td_file is file structure !> !> to write in file:
!> @code !> CALL iom_write_file(td_file) !> @endcode !> !> to close file:
!> @code !> CALL iom_close(tl_file) !> @endcode !> !> to read one dimension in file:
!> @code !> tl_dim = iom_read_dim(tl_file, id_dimid) !> @endcode !> or
!> @code !> tl_dim = iom_read_dim(tl_file, cd_name) !> @endcode !> - id_dimid is dimension id !> - cd_name is dimension name !> !> to read variable or global attribute in file:
!> @code !> tl_att = iom_read_att(tl_file, id_varid, id_attid) !> @endcode !> or !> @code !> tl_att = iom_read_att(tl_file, id_varid, cd_attname) !> @endcode !> or !> @code !> tl_att = iom_read_att(tl_file, cd_varname, id_attid) !> @endcode !> or !> @code !> tl_att = iom_read_att(tl_file, cd_varname, cd_attname) !> @endcode !> - id_varid is variable id !> - id_attid is attribute id !> - cd_attname is attribute name !> - cd_varname is variable name or standard name !> !> to read one variable in file:
!> @code !> tl_var = iom_read_var(td_file, id_varid, [id_start, id_count]) !> @endcode !> or !> @code !> tl_var = iom_read_var(td_file, cd_name, [id_start, [id_count,]]) !> @endcode !> - id_varid is variabale id !> - cd_name is variabale name or standard name. !> - id_start is a integer(4) 1D array of index from which the data !> values will be read [optional] !> - id_count is a integer(4) 1D array of the number of indices selected !> along each dimension [optional] !> !> @author !> J.Paul ! REVISION HISTORY: !> @date November, 2013 - Initial Version !> !> @todo !> - see lbc_lnk !> - see goup netcdf4 !> !> @note Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) !---------------------------------------------------------------------- MODULE iom USE netcdf ! nf90 library USE global ! global parameter USE kind ! F90 kind parameter USE fct ! basic useful function USE logger ! log file manager USE dim ! dimension manager USE att ! attribute manager USE var ! variable manager USE file ! file manager USE iom_cdf ! netcdf I/O manager USE iom_rstdimg ! restart dimg I/O manager IMPLICIT NONE ! NOTE_avoid_public_variables_if_possible ! function and subroutine PUBLIC :: iom_open !< open or create file, fill file structure PUBLIC :: iom_create !< create file, fill file structure PUBLIC :: iom_close !< close file PUBLIC :: iom_read_dim !< read one dimension in an opened file PUBLIC :: iom_read_att !< read one attribute in an opened file PUBLIC :: iom_read_var !< read one variable in an opened file PUBLIC :: iom_write_file !< write file structure contents in an opened file ! read variable or global attribute in an opened file PRIVATE :: iom__read_att_varname_id ! given variable name or standard name and attribute id. PRIVATE :: iom__read_att_varid_id ! given variable id and attribute id. PRIVATE :: iom__read_att_varname_name ! given variable name or standard name, and attribute name. PRIVATE :: iom__read_att_varid_name ! given variable id and attribute name. PRIVATE :: iom__read_dim_id ! read one dimension in an opened file, given dimension id. PRIVATE :: iom__read_dim_name ! read one dimension in an opened netcdf file, given dimension name. PRIVATE :: iom__read_var_id ! read variable value in an opened file, given variable id. PRIVATE :: iom__read_var_name ! read variable value in an opened file, given variable name or standard name. INTERFACE iom_read_var MODULE PROCEDURE iom__read_var_id MODULE PROCEDURE iom__read_var_name END INTERFACE iom_read_var INTERFACE iom_read_dim MODULE PROCEDURE iom__read_dim_id MODULE PROCEDURE iom__read_dim_name END INTERFACE iom_read_dim INTERFACE iom_read_att !< read variable or global attribute in an opened file MODULE PROCEDURE iom__read_att_varname_id !< given variable name or standard name and attribute id. MODULE PROCEDURE iom__read_att_varid_id !< given variable id and attribute id. MODULE PROCEDURE iom__read_att_varname_name !< given variable name or standard name, and attribute name. MODULE PROCEDURE iom__read_att_varid_name !< given variable id and attribute name. END INTERFACE iom_read_att CONTAINS !------------------------------------------------------------------- !> @brief This function open a file in read or write mode !> @details !> If try to open a file in write mode that did not exist, create it.
!> !> If file exist, get information about: !> - the number of variables !> - the number of dimensions !> - the number of global attributes !> - the ID of the unlimited dimension !> - the file format !> and finally read dimensions. !> !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[inout] td_file file structure !------------------------------------------------------------------- SUBROUTINE iom_open(td_file) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(INOUT) :: td_file !---------------------------------------------------------------- ! add suffix to file name td_file%c_name = file_add_suffix( TRIM(td_file%c_name), & & TRIM(td_file%c_type) ) ! check type SELECT CASE(TRIM(ADJUSTL(fct_lower(td_file%c_type)))) CASE('cdf') CALL iom_cdf_open(td_file) CASE('dimg') CALL iom_rstdimg_open(td_file) CASE DEFAULT CALL logger_error("IOM OPEN: unknow type : "//TRIM(td_file%c_name)) END SELECT END SUBROUTINE iom_open !------------------------------------------------------------------- !> @brief This function create a file. !> !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[inout] td_file file structure !------------------------------------------------------------------- SUBROUTINE iom_create(td_file) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(INOUT) :: td_file ! local variable LOGICAL :: ll_exist !---------------------------------------------------------------- INQUIRE(FILE=TRIM(td_file%c_name), EXIST=ll_exist ) IF( ll_exist )THEN CALL logger_fatal("IOM CREATE: can not create file "//& & TRIM(td_file%c_name)//". file exist already.") ENDIF ! forced to open in write mode td_file%l_wrt=.TRUE. ! check type SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') CALL iom_cdf_open(td_file) CASE('dimg') CALL iom_rstdimg_open(td_file) CASE DEFAULT CALL logger_error( "IOM CREATE: can't create file "//& & TRIM(td_file%c_name)//": type unknown " ) END SELECT END SUBROUTINE iom_create !------------------------------------------------------------------- !> @brief This subroutine close file !> !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[inout] td_file file structure !------------------------------------------------------------------- SUBROUTINE iom_close(td_file) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(INOUT) :: td_file !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') CALL iom_cdf_close(td_file) CASE('dimg') CALL iom_rstdimg_close(td_file) CASE DEFAULT CALL logger_error( "IOM CLOSE: can't close file "//& & TRIM(td_file%c_name)//": type unknown " ) END SELECT END SUBROUTINE iom_close !------------------------------------------------------------------- !> @brief This function read attribute (of variable or global) in an opened !> file, given variable name or standard name and attribute id. !> @details !> - to get global attribute use 'GLOBAL' as variable name. ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] cd_varname variable name. use 'GLOBAL' to read global !> attribute in a file !> @param[in] id_attid attribute id !> @return attribute structure !------------------------------------------------------------------- TYPE(TATT) FUNCTION iom__read_att_varname_id( td_file, cd_varname, & & id_attid) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file CHARACTER(LEN=lc), INTENT(IN) :: cd_varname INTEGER(i4), INTENT(IN) :: id_attid ! local variable INTEGER(i4) :: il_varid !---------------------------------------------------------------- ! get variable id IF( TRIM(fct_upper(cd_varname)) == 'GLOBAL' )THEN il_varid=NF90_GLOBAL ELSE il_varid=var_get_id(td_file%t_var(:), cd_varname) ENDIF IF( il_varid /= 0 .OR. TRIM(fct_upper(cd_varname)) == 'GLOBAL' )THEN ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_att_varname_id=iom_read_att( td_file, il_varid, & & id_attid) CASE('dimg') CALL logger_warn( " IOM READ ATT: can't read attribute "//& & "in dimg file : "//TRIM(td_file%c_name) ) CASE DEFAULT CALL logger_error( " IOM READ ATT: can't read attribute "//& & " in file "//TRIM(td_file%c_name)//" : type unknown " ) END SELECT ENDIF END FUNCTION iom__read_att_varname_id !------------------------------------------------------------------- !> @brief This function read attribute (of variable or global) in an opened !> file, given variable id and attribute id. !> !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] id_varid variable id. use NF90_GLOBAL to read global !> attribute in a file !> @param[in] id_attid attribute id !> @return attribute structure !------------------------------------------------------------------- TYPE(TATT) FUNCTION iom__read_att_varid_id( td_file, id_varid, & & id_attid) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file INTEGER(i4), INTENT(IN) :: id_varid INTEGER(i4), INTENT(IN) :: id_attid !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_att_varid_id=iom_cdf_read_att( td_file, id_varid, & & id_attid) CASE('dimg') CALL logger_warn( " IOM READ ATT: can't read attribute in dimg file "//& & TRIM(td_file%c_name) ) CASE DEFAULT CALL logger_error( " IOM READ ATT: can't read attribute in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END FUNCTION iom__read_att_varid_id !------------------------------------------------------------------- !> @brief This function read attribute (of variable or global) in an opened !> file, given variable name or standard name, and attribute name. !> @details !> - to get global attribute use 'GLOBAL' as variable name. ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] cd_varname variable name or standard name. use 'GLOBAL' to read global !> attribute in a file !> @param[in] cd_attname attribute name !> @return attribute structure !------------------------------------------------------------------- TYPE(TATT) FUNCTION iom__read_att_varname_name( td_file, cd_varname, & & cd_attname) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file CHARACTER(LEN=*), INTENT(IN) :: cd_varname CHARACTER(LEN=*), INTENT(IN) :: cd_attname ! local variable INTEGER(i4) :: il_varid !---------------------------------------------------------------- ! get variable id IF( TRIM(fct_upper(cd_varname)) == 'GLOBAL' )THEN il_varid=NF90_GLOBAL ELSE il_varid=var_get_id(td_file%t_var(:), cd_varname) ENDIF IF( il_varid /= 0 .OR. TRIM(fct_upper(cd_varname)) == 'GLOBAL' )THEN ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_att_varname_name=iom_cdf_read_att( td_file, il_varid, & & cd_attname) CASE('dimg') CALL logger_warn( " IOM READ ATT: can't read attribute "//& & "in dimg file :"//TRIM(td_file%c_name) ) CASE DEFAULT CALL logger_error( " IOM READ ATT: can't read attribute in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT ENDIF END FUNCTION iom__read_att_varname_name !------------------------------------------------------------------- !> @brief This function read attribute (of variable or global) in an opened !> file, given variable id and attribute name. ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] id_varid variable id. use NF90_GLOBAL to read global !> attribute in a file !> @param[in] cd_attname attribute name !> @return attribute structure !------------------------------------------------------------------- TYPE(TATT) FUNCTION iom__read_att_varid_name( td_file, id_varid, & & cd_attname) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file INTEGER(i4), INTENT(IN) :: id_varid CHARACTER(LEN=*), INTENT(IN) :: cd_attname !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_att_varid_name=iom_cdf_read_att( td_file, id_varid, & & cd_attname) CASE('dimg') CALL logger_warn( " IOM READ ATT: can't read attribute in dimg file :"& & //TRIM(td_file%c_name) ) CASE DEFAULT CALL logger_error( " IOM READ ATT: can't read attribute in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END FUNCTION iom__read_att_varid_name !------------------------------------------------------------------- !> @brief This function read one dimension in an opened file, !> given dimension id. ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] id_dimid dimension id !> @return dimension structure !------------------------------------------------------------------- TYPE(TDIM) FUNCTION iom__read_dim_id(td_file, id_dimid) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file INTEGER(i4), INTENT(IN) :: id_dimid !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_dim_id=iom_cdf_read_dim(td_file, id_dimid) CASE('dimg') iom__read_dim_id=iom_rstdimg_read_dim(td_file, id_dimid) CASE DEFAULT CALL logger_error( " IOM READ DIM: can't read dimension in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END FUNCTION iom__read_dim_id !------------------------------------------------------------------- !> @brief This function read one dimension in an opened netcdf file, !> given dimension name. ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] cd_name dimension name !> @return dimension structure !------------------------------------------------------------------- TYPE(TDIM) FUNCTION iom__read_dim_name(td_file, cd_name) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file CHARACTER(LEN=*), INTENT(IN) :: cd_name !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_dim_name=iom_cdf_read_dim(td_file, cd_name) CASE('dimg') iom__read_dim_name=iom_rstdimg_read_dim(td_file, cd_name) CASE DEFAULT CALL logger_error( " IOM READ DIM: can't read dimension in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END FUNCTION iom__read_dim_name !------------------------------------------------------------------- !> @brief This function read variable value in an opened !> file, given variable id. !> @details !> start indices and number of indices selected along each dimension !> could be specify in a 4 dimension array (/'x','y','z','t'/) ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] id_varid variable id !> @param[in] id_start index in the variable from which the data values !> will be read !> @param[in] id_count number of indices selected along each dimension !> @return variable structure !------------------------------------------------------------------- TYPE(TVAR) FUNCTION iom__read_var_id( td_file, id_varid,& & id_start, id_count) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(IN) :: td_file INTEGER(i4), INTENT(IN) :: id_varid INTEGER(i4), DIMENSION(ip_maxdim), INTENT(IN), OPTIONAL :: id_start INTEGER(i4), DIMENSION(ip_maxdim), INTENT(IN), OPTIONAL :: id_count !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_var_id=iom_cdf_read_var(td_file, id_varid, & & id_start, id_count) CASE('dimg') iom__read_var_id=iom_rstdimg_read_var(td_file, id_varid, & & id_start, id_count) CASE DEFAULT CALL logger_error( " IOM READ VAR: can't read variable in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END FUNCTION iom__read_var_id !------------------------------------------------------------------- !> @brief This function read variable value in an opened !> file, given variable name or standard name. !> @details !> start indices and number of indices selected along each dimension !> could be specify in a 4 dimension array (/'x','y','z','t'/) !> !> look first for variable name. If it doesn't !> exist in file, look for variable standard name.
! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !> @param[in] cd_name variable name or standard name !> @param[in] id_start index in the variable from which the data values !> will be read !> @param[in] id_count number of indices selected along each dimension !> @return variable structure !------------------------------------------------------------------- TYPE(TVAR) FUNCTION iom__read_var_name(td_file, cd_name, & & id_start, id_count ) IMPLICIT NONE ! Argument TYPE(TFILE) , INTENT(IN) :: td_file CHARACTER(LEN=*) , INTENT(IN) :: cd_name INTEGER(i4) , DIMENSION(:), INTENT(IN), OPTIONAL :: id_start INTEGER(i4) , DIMENSION(:), INTENT(IN), OPTIONAL :: id_count !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') iom__read_var_name=iom_cdf_read_var(td_file, cd_name, & & id_start, id_count ) CASE('dimg') iom__read_var_name=iom_rstdimg_read_var(td_file, cd_name, & & id_start, id_count ) CASE DEFAULT CALL logger_error( " IOM READ VAR: can't read variable in file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END FUNCTION iom__read_var_name !------------------------------------------------------------------- !> @brief This subroutine write file structure in an opened file. ! !> @author J.Paul !> - November, 2013- Initial Version ! !> @param[in] td_file file structure !------------------------------------------------------------------- SUBROUTINE iom_write_file(td_file) IMPLICIT NONE ! Argument TYPE(TFILE), INTENT(INOUT) :: td_file !---------------------------------------------------------------- ! open file SELECT CASE(TRIM(td_file%c_type)) CASE('cdf') CALL iom_cdf_write_file(td_file) CASE('dimg') CALL iom_rstdimg_write_file(td_file) CASE DEFAULT CALL logger_error( " IOM WRITE: can't write file "//& & TRIM(td_file%c_name)//" : type unknown " ) END SELECT END SUBROUTINE iom_write_file END MODULE iom