!----------------------------------------------------------------------
! NEMO system team, System and Interface for oceanic RElocable Nesting
!----------------------------------------------------------------------
!
! MODULE: att
!
! DESCRIPTION:
!> @brief
!> This module manage attribute of variable or file.
!
!> @details
!> define type TATT:
!> TYPE(TATT) :: tl_att
!>
!> the attribute value inside attribute structure will be
!> character or real(8) 1D table.
!> However the attribute value could be initialised with:
!> - character
!> - scalar (real(4), real(8), integer(4) or integer(8))
!> - table 1D (real(4), real(8), integer(4) or integer(8))
!>
!> to initialise an attribute structure :
!> tl_att=att_init('attname',value)
!> tl_att=att_init('attname',tab_value)
!>
!> to print attribute information of one attribute structure:
!> CALL att_print(td_att)
!>
!> to get character length or the number of value store in attribute
!> - tl_att\%i_len
!>
!> to get attribute value:
!> - tl_att\%c_value (for character attribute)
!> - tl_att\%d_value(i) (otherwise)
!>
!> to get the type number (based on NETCDF type constants) of the
!> attribute:
!> - tl_att\%i_type
!>
!> to get attribute id (affected when attributes will be added to
!> variable or file):
!> - tl_att\%i_id
!>
!> @author
!> J.Paul
! REVISION HISTORY:
!> @date Nov, 2013 - Initial Version
!
!> @note Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
!> @todo
!----------------------------------------------------------------------
MODULE att
USE netcdf ! nf90 library
USE global ! global variable
USE kind ! F90 kind parameter
USE logger ! log file manager
USE fct ! basic useful function
IMPLICIT NONE
PRIVATE
! NOTE_avoid_public_variables_if_possible
! type and variable
PUBLIC :: TATT ! attribute structure
! function and subroutine
PUBLIC :: ASSIGNMENT(=) ! copy attribute structure
PUBLIC :: att_init ! initialize attribute structure
PUBLIC :: att_print ! print attribute structure
PUBLIC :: att_get_id ! get attribute id in table of attribute structure
PUBLIC :: att_clean ! clean attribute strcuture
PRIVATE :: att__init_c ! initialise an attribute structure with character value
PRIVATE :: att__init_dp ! initialise an attribute structure with table of real(8) value
PRIVATE :: att__init_dp_0d ! initialise an attribute structure with real(8) value
PRIVATE :: att__init_sp ! initialise an attribute structure with table of real(4) value
PRIVATE :: att__init_sp_0d ! initialise an attribute structure with real(4) value
PRIVATE :: att__init_i1 ! initialise an attribute structure with table of integer(1) value
PRIVATE :: att__init_i1_0d ! initialise an attribute structure with integer(1) value
PRIVATE :: att__init_i2 ! initialise an attribute structure with table of integer(2) value
PRIVATE :: att__init_i2_0d ! initialise an attribute structure with integer(2) value
PRIVATE :: att__init_i4 ! initialise an attribute structure with table of integer(4) value
PRIVATE :: att__init_i4_0d ! initialise an attribute structure with integer(4) value
PRIVATE :: att__init_i8 ! initialise an attribute structure with table of integer(8) value
PRIVATE :: att__init_i8_0d ! initialise an attribute structure with integer(8) value
PRIVATE :: att__copy_unit ! copy attribute structure
PRIVATE :: att__copy_tab ! copy attribute structure
!> @struct TATT
TYPE TATT
!CHARACTER(LEN=lc) :: c_name = 'unknown' !< attribute name
CHARACTER(LEN=lc) :: c_name = '' !< attribute name
INTEGER(i4) :: i_id = 0 !< attribute id
INTEGER(i4) :: i_type = 0 !< attribute type
INTEGER(i4) :: i_len = 0 !< number of value store in attribute
CHARACTER(LEN=lc) :: c_value = "none" !< attribute value if type CHAR
REAL(dp), DIMENSION(:), POINTER :: d_value => NULL() !< attribute value if type SHORT,INT,FLOAT or DOUBLE
END TYPE TATT
INTERFACE att_init
MODULE PROCEDURE att__init_c
MODULE PROCEDURE att__init_dp
MODULE PROCEDURE att__init_dp_0d
MODULE PROCEDURE att__init_sp
MODULE PROCEDURE att__init_sp_0d
MODULE PROCEDURE att__init_i1
MODULE PROCEDURE att__init_i1_0d
MODULE PROCEDURE att__init_i2
MODULE PROCEDURE att__init_i2_0d
MODULE PROCEDURE att__init_i4
MODULE PROCEDURE att__init_i4_0d
MODULE PROCEDURE att__init_i8
MODULE PROCEDURE att__init_i8_0d
END INTERFACE att_init
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE att__copy_unit ! copy attribute structure
MODULE PROCEDURE att__copy_tab ! copy attribute structure
END INTERFACE
CONTAINS
!-------------------------------------------------------------------
!> @brief
!> This function copy attribute structure in another attribute
!> structure
!> @details
!> attribute value are copied in a temporary table, so input and output
!> attribute structure value do not point on the same "memory cell", and so
!> on are independant.
!>
!> @warning to avoid infinite loop, do not use any function inside
!> this subroutine
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[out] td_att1 : attribute structure
!> @param[in] td_att2 : attribute structure
!-------------------------------------------------------------------
! @code
SUBROUTINE att__copy_tab( td_att1, td_att2 )
IMPLICIT NONE
! Argument
TYPE(TATT), DIMENSION(:) , INTENT(IN) :: td_att2
TYPE(TATT), DIMENSION(SIZE(td_att2(:))),INTENT(OUT) :: td_att1
! local variable
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
DO ji=1,SIZE(td_att2(:))
td_att1(ji)=td_att2(ji)
ENDDO
END SUBROUTINE att__copy_tab
! @endcode
!-------------------------------------------------------------------
!> @brief
!> This function copy attribute structure in another attribute
!> structure
!> @details
!> attribute value are copied in a temporary table, so input and output
!> attribute structure value do not point on the same "memory cell", and so
!> on are independant.
!>
!> @warning to avoid infinite loop, do not use any function inside
!> this subroutine
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[out] td_att1 : attribute structure
!> @param[in] td_att2 : attribute structure
!-------------------------------------------------------------------
! @code
SUBROUTINE att__copy_unit( td_att1, td_att2 )
IMPLICIT NONE
! Argument
TYPE(TATT), INTENT(OUT) :: td_att1
TYPE(TATT), INTENT(IN) :: td_att2
! local variable
REAL(dp), DIMENSION(:), ALLOCATABLE :: dl_value
!----------------------------------------------------------------
CALL logger_trace("COPY: attribute "//TRIM(td_att2%c_name) )
! copy attribute variable
td_att1%c_name = TRIM(td_att2%c_name)
td_att1%i_id = td_att2%i_id
td_att1%i_type = td_att2%i_type
td_att1%i_len = td_att2%i_len
td_att1%c_value = TRIM(td_att2%c_value)
! copy attribute pointer in an independant variable
IF( ASSOCIATED(td_att1%d_value) ) DEALLOCATE(td_att1%d_value)
IF( ASSOCIATED(td_att2%d_value) )THEN
ALLOCATE( dl_value(td_att2%i_len) )
dl_value(:) = td_att2%d_value(:)
ALLOCATE( td_att1%d_value(td_att1%i_len) )
td_att1%d_value(:) = dl_value(:)
DEALLOCATE( dl_value )
ENDIF
END SUBROUTINE att__copy_unit
! @endcode
!-------------------------------------------------------------------
!> @brief This function get attribute id, in a table of attribute structure,
!> given attribute name
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] td_att : attribute structure
!> @param[in] cd_name : attribute name
!> @return attribute id
!-------------------------------------------------------------------
! @code
INTEGER(i4) FUNCTION att_get_id( td_att, cd_name )
IMPLICIT NONE
! Argument
TYPE(TATT), DIMENSION(:), INTENT(IN) :: td_att
CHARACTER(LEN=*), INTENT(IN) :: cd_name
! local variable
INTEGER(i4) :: il_size
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
att_get_id=0
il_size=SIZE(td_att(:))
DO ji=1,il_size
IF( TRIM(td_att(ji)%c_name) == TRIM(cd_name) )THEN
att_get_id=ji
EXIT
ENDIF
ENDDO
END FUNCTION att_get_id
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with character
!> value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] cd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_c( cd_name, cd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
CHARACTER(LEN=*), INTENT(IN) :: cd_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_c)
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cd_value)) )
att__init_c%c_name=TRIM(ADJUSTL(cd_name))
att__init_c%i_type=NF90_CHAR
att__init_c%c_value=TRIM(ADJUSTL(cd_value))
att__init_c%i_len=LEN( TRIM(ADJUSTL(cd_value)) )
END FUNCTION att__init_c
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with table
!> of real(8) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] dd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_dp( cd_name, dd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
REAL(dp), DIMENSION(:), INTENT(IN) :: dd_value
! local value
INTEGER(i4) :: il_len
CHARACTER(LEN=lc) :: cl_value
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_dp)
! table size
il_len=size(dd_value(:))
cl_value="(/"
DO ji=1,il_len-1
cl_value=TRIM(cl_value)//TRIM(fct_str(dd_value(ji)))//","
ENDDO
cl_value=TRIM(cl_value)//TRIM(fct_str(dd_value(il_len)))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_dp%c_name=TRIM(ADJUSTL(cd_name))
att__init_dp%i_type=NF90_DOUBLE
IF( ASSOCIATED(att__init_dp%d_value) )THEN
DEALLOCATE(att__init_dp%d_value)
ENDIF
ALLOCATE(att__init_dp%d_value(il_len))
att__init_dp%d_value(:)=dd_value(:)
att__init_dp%i_len=il_len
END FUNCTION att__init_dp
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with
!> real(8) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] dd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_dp_0d( cd_name, dd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
REAL(dp), INTENT(IN) :: dd_value
! local value
CHARACTER(LEN=lc) :: cl_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_dp_0d)
cl_value="(/"//TRIM(fct_str(dd_value))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_dp_0d%c_name=TRIM(ADJUSTL(cd_name))
att__init_dp_0d%i_type=NF90_DOUBLE
IF( ASSOCIATED(att__init_dp_0d%d_value) )THEN
DEALLOCATE(att__init_dp_0d%d_value)
ENDIF
ALLOCATE(att__init_dp_0d%d_value(1))
att__init_dp_0d%d_value(1)=dd_value
att__init_dp_0d%i_len=1
END FUNCTION att__init_dp_0d
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with table
!> of real(4) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] rd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_sp( cd_name, rd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
REAL(sp), DIMENSION(:), INTENT(IN) :: rd_value
! local value
INTEGER(i4) :: il_len
CHARACTER(LEN=lc) :: cl_value
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_sp)
! table size
il_len=size(rd_value(:))
cl_value="(/"
DO ji=1,il_len-1
cl_value=TRIM(cl_value)//TRIM(fct_str(rd_value(ji)))//","
ENDDO
cl_value=TRIM(cl_value)//TRIM(fct_str(rd_value(il_len)))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_sp%c_name=TRIM(ADJUSTL(cd_name))
att__init_sp%i_type=NF90_FLOAT
IF( ASSOCIATED(att__init_sp%d_value) )THEN
DEALLOCATE(att__init_sp%d_value)
ENDIF
ALLOCATE(att__init_sp%d_value(il_len))
att__init_sp%d_value(:)=REAL(rd_value(:),dp)
att__init_sp%i_len=il_len
END FUNCTION att__init_sp
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with
!> real(4) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] rd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_sp_0d( cd_name, rd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
REAL(sp), INTENT(IN) :: rd_value
! local value
CHARACTER(LEN=lc) :: cl_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_sp_0d)
cl_value="(/"//TRIM(fct_str(rd_value))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_sp_0d%c_name=TRIM(ADJUSTL(cd_name))
att__init_sp_0d%i_type=NF90_FLOAT
IF( ASSOCIATED(att__init_sp_0d%d_value) )THEN
DEALLOCATE(att__init_sp_0d%d_value)
ENDIF
ALLOCATE(att__init_sp_0d%d_value(1))
att__init_sp_0d%d_value(1)=REAL(rd_value,dp)
att__init_sp_0d%i_len=1
END FUNCTION att__init_sp_0d
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with table
!> of integer(1) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] bd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i1( cd_name, bd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i1), DIMENSION(:), INTENT(IN) :: bd_value
! local value
INTEGER(i4) :: il_len
CHARACTER(LEN=lc) :: cl_value
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i1)
! table size
il_len=size(bd_value(:))
cl_value="(/"
DO ji=1,il_len-1
cl_value=TRIM(cl_value)//TRIM(fct_str(bd_value(ji)))//","
ENDDO
cl_value=TRIM(cl_value)//TRIM(fct_str(bd_value(il_len)))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i1%c_name=TRIM(ADJUSTL(cd_name))
att__init_i1%i_type=NF90_BYTE
IF( ASSOCIATED(att__init_i1%d_value) )THEN
DEALLOCATE(att__init_i1%d_value)
ENDIF
ALLOCATE(att__init_i1%d_value(il_len))
att__init_i1%d_value(:)=REAL(bd_value(:),dp)
att__init_i1%i_len=il_len
END FUNCTION att__init_i1
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with
!> integer(1) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] bd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i1_0d( cd_name, bd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i1), INTENT(IN) :: bd_value
!local value
CHARACTER(LEN=lc) :: cl_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i1_0d)
cl_value="(/"//TRIM(fct_str(bd_value))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attibute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i1_0d%c_name=TRIM(ADJUSTL(cd_name))
att__init_i1_0d%i_type=NF90_BYTE
IF( ASSOCIATED(att__init_i1_0d%d_value) )THEN
DEALLOCATE(att__init_i1_0d%d_value)
ENDIF
ALLOCATE(att__init_i1_0d%d_value(1))
att__init_i1_0d%d_value(1)=REAL(bd_value,dp)
att__init_i1_0d%i_len=1
END FUNCTION att__init_i1_0d
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with table
!> of integer(2) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] sd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i2( cd_name, sd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i2), DIMENSION(:), INTENT(IN) :: sd_value
! local value
INTEGER(i4) :: il_len
CHARACTER(LEN=lc) :: cl_value
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i2)
! table size
il_len=size(sd_value(:))
cl_value="(/"
DO ji=1,il_len-1
cl_value=TRIM(cl_value)//TRIM(fct_str(sd_value(ji)))//","
ENDDO
cl_value=TRIM(cl_value)//TRIM(fct_str(sd_value(il_len)))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i2%c_name=TRIM(ADJUSTL(cd_name))
att__init_i2%i_type=NF90_SHORT
IF( ASSOCIATED(att__init_i2%d_value) )THEN
DEALLOCATE(att__init_i2%d_value)
ENDIF
ALLOCATE(att__init_i2%d_value(il_len))
att__init_i2%d_value(:)=REAL(sd_value(:),dp)
att__init_i2%i_len=il_len
END FUNCTION att__init_i2
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with
!> integer(2) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] sd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i2_0d( cd_name, sd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i2), INTENT(IN) :: sd_value
!local value
CHARACTER(LEN=lc) :: cl_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i2_0d)
cl_value="(/"//TRIM(fct_str(sd_value))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attibute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i2_0d%c_name=TRIM(ADJUSTL(cd_name))
att__init_i2_0d%i_type=NF90_SHORT
IF( ASSOCIATED(att__init_i2_0d%d_value) )THEN
DEALLOCATE(att__init_i2_0d%d_value)
ENDIF
ALLOCATE(att__init_i2_0d%d_value(1))
att__init_i2_0d%d_value(1)=REAL(sd_value,dp)
att__init_i2_0d%i_len=1
END FUNCTION att__init_i2_0d
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with table
!> of integer(4) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] id_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i4( cd_name, id_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i4), DIMENSION(:), INTENT(IN) :: id_value
! local value
INTEGER(i4) :: il_len
CHARACTER(LEN=lc) :: cl_value
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i4)
! table size
il_len=size(id_value(:))
cl_value="(/"
DO ji=1,il_len-1
cl_value=TRIM(cl_value)//TRIM(fct_str(id_value(ji)))//","
ENDDO
cl_value=TRIM(cl_value)//TRIM(fct_str(id_value(il_len)))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attribute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i4%c_name=TRIM(ADJUSTL(cd_name))
att__init_i4%i_type=NF90_INT
IF( ASSOCIATED(att__init_i4%d_value) )THEN
DEALLOCATE(att__init_i4%d_value)
ENDIF
ALLOCATE(att__init_i4%d_value(il_len))
att__init_i4%d_value(:)=REAL(id_value(:),dp)
att__init_i4%i_len=il_len
END FUNCTION att__init_i4
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with
!> integer(4) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] id_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i4_0d( cd_name, id_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i4), INTENT(IN) :: id_value
!local value
CHARACTER(LEN=lc) :: cl_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i4_0d)
cl_value="(/"//TRIM(fct_str(id_value))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attibute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i4_0d%c_name=TRIM(ADJUSTL(cd_name))
att__init_i4_0d%i_type=NF90_INT
IF( ASSOCIATED(att__init_i4_0d%d_value) )THEN
DEALLOCATE(att__init_i4_0d%d_value)
ENDIF
ALLOCATE(att__init_i4_0d%d_value(1))
att__init_i4_0d%d_value(1)=REAL(id_value,dp)
att__init_i4_0d%i_len=1
END FUNCTION att__init_i4_0d
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with table
!> of integer(8) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] kd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i8( cd_name, kd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i8), DIMENSION(:), INTENT(IN) :: kd_value
! local value
INTEGER(i4) :: il_len
CHARACTER(LEN=lc) :: cl_value
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i8)
! table size
il_len=size(kd_value(:))
cl_value="(/"
DO ji=1,il_len
cl_value=TRIM(cl_value)//TRIM(fct_str(kd_value(ji)))//","
ENDDO
cl_value=TRIM(cl_value)//TRIM(fct_str(kd_value(il_len)))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attibute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i8%c_name=TRIM(ADJUSTL(cd_name))
att__init_i8%i_type=NF90_INT
IF( ASSOCIATED(att__init_i8%d_value) )THEN
DEALLOCATE(att__init_i8%d_value)
ENDIF
ALLOCATE(att__init_i8%d_value(il_len))
att__init_i8%d_value(:)=REAL(kd_value(:),dp)
att__init_i8%i_len=il_len
END FUNCTION att__init_i8
!> @endcode
!-------------------------------------------------------------------
!> @brief This function initialise an attribute structure with
!> integer(8) value
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] cd_name : attribute name
!> @param[in] kd_value: attribute value
!> @return attribute structure
!-------------------------------------------------------------------
!> @code
TYPE(TATT) FUNCTION att__init_i8_0d( cd_name, kd_value )
IMPLICIT NONE
! Argument
CHARACTER(LEN=*), INTENT(IN) :: cd_name
INTEGER(i8), INTENT(IN) :: kd_value
! local value
CHARACTER(LEN=lc) :: cl_value
!----------------------------------------------------------------
! clean attribute
CALL att_clean(att__init_i8_0d)
cl_value="(/"//TRIM(fct_str(kd_value))//"/)"
CALL logger_info( &
& " ATT INIT: attribute name: "//TRIM(ADJUSTL(cd_name))//&
& " attibute value "//TRIM(ADJUSTL(cl_value)) )
att__init_i8_0d%c_name=TRIM(ADJUSTL(cd_name))
att__init_i8_0d%i_type=NF90_INT
IF( ASSOCIATED(att__init_i8_0d%d_value) )THEN
DEALLOCATE(att__init_i8_0d%d_value)
ENDIF
ALLOCATE(att__init_i8_0d%d_value(1))
att__init_i8_0d%d_value(1)=REAL(kd_value,dp)
att__init_i8_0d%i_len=1
END FUNCTION att__init_i8_0d
!> @endcode
!-------------------------------------------------------------------
!> @brief This subroutine print attribute information
!>
!> @author J.Paul
!> - Nov, 2013- Initial Version
!
!> @param[in] td_att : attribute structure
!-------------------------------------------------------------------
!> @code
SUBROUTINE att_print(td_att)
IMPLICIT NONE
! Argument
TYPE(TATT), INTENT(IN) :: td_att
! local vairbale
CHARACTER(LEN=lc) :: cl_type
CHARACTER(LEN=lc) :: cl_value
CHARACTER(LEN=lc) :: cl_tmp
! loop indices
INTEGER(i4) :: ji
!----------------------------------------------------------------
SELECT CASE( td_att%i_type )
CASE(NF90_CHAR)
cl_type='CHAR'
CASE(NF90_BYTE)
cl_type='BYTE'
CASE(NF90_SHORT)
cl_type='SHORT'
CASE(NF90_INT)
cl_type='INT'
CASE(NF90_FLOAT)
cl_type='FLOAT'
CASE(NF90_DOUBLE)
cl_type='DOUBLE'
CASE DEFAULT
cl_type=''
!cl_type='unknown'
END SELECT
SELECT CASE( td_att%i_type )
CASE(NF90_CHAR)
cl_value=td_att%c_value
CASE(NF90_BYTE, NF90_SHORT, NF90_INT, NF90_FLOAT, NF90_DOUBLE)
IF( td_att%i_len > 1 )THEN
cl_tmp=','
cl_value='(/'
DO ji=1,td_att%i_len-1
cl_value=TRIM(cl_value)//&
& TRIM(fct_str(td_att%d_value(ji)))//TRIM(cl_tmp)
ENDDO
cl_value=TRIM(cl_value)//&
& TRIM(fct_str(td_att%d_value(td_att%i_len)))//'/)'
ELSE
cl_value='(/'//TRIM(fct_str(td_att%d_value(1)))//'/)'
ENDIF
CASE DEFAULT
cl_value="none"
END SELECT
WRITE(*,'((3x,a,a),(/6x,a,i2.2),(a,a),(a,a))')&
& " attribute : ",TRIM(ADJUSTL(td_att%c_name)), &
& " id : ",td_att%i_id, &
& " type : ",TRIM(ADJUSTL(cl_type)), &
& " value : ",TRIM(ADJUSTL(cl_value))
END SUBROUTINE att_print
!> @endcode
!-------------------------------------------------------------------
!> @brief
!> This subroutine clean attribute strcuture.
!
!> @author J.Paul
!> @date Nov, 2013
!
!> @param[inout] td_att : attribute strcuture
!-------------------------------------------------------------------
!> @code
SUBROUTINE att_clean( td_att )
IMPLICIT NONE
! Argument
TYPE(TATT), INTENT(INOUT) :: td_att
! local variable
TYPE(TATT) :: tl_att ! empty attribute structure
!----------------------------------------------------------------
CALL logger_info( &
& " CLEAN: reset attribute "//TRIM(td_att%c_name) )
IF( ASSOCIATED(td_att%d_value) )THEN
! clean value
DEALLOCATE(td_att%d_value)
ENDIF
! replace by empty structure
td_att=tl_att
END SUBROUTINE att_clean
!> @endcode
END MODULE att