text:
!
! CloudCoeff_netCDF_IO
!
! Module containing routines to read and write CloudCoeff netCDF
! format files.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 10-Apr-2007
!                       paul.vandelst@ssec.wisc.edu
!

MODULE CloudCoeff_netCDF_IO

  ! -----------------
  ! Environment setup
  ! -----------------
  ! Module use
  USE Type_Kinds       , ONLY: Double
  USE Message_Handler  , ONLY: SUCCESS, FAILURE, INFORMATION, Display_Message
  USE File_Utility     , ONLY: File_Exists
  USE String_Utility   , ONLY: StrClean
  USE CloudCoeff_Define, ONLY: CloudCoeff_type         , &
                               CloudCoeff_Associated   , &
                               CloudCoeff_Destroy      , &
                               CloudCoeff_Create       , &
                               CloudCoeff_Inspect      , &
                               CloudCoeff_ValidRelease , &
                               CloudCoeff_Info

  USE netcdf
  ! Disable implicit typing
  IMPLICIT NONE

  ! ------------
  ! Visibilities
  ! ------------
  ! Everything private by default
  PRIVATE
  ! Procedures
  PUBLIC :: CloudCoeff_netCDF_InquireFile
  PUBLIC :: CloudCoeff_netCDF_ReadFile
  PUBLIC :: CloudCoeff_netCDF_WriteFile
  !PUBLIC :: CloudCoeff_netCDF_IOVersion

  ! -----------------
  ! Module parameters
  ! -----------------
  ! Default msg string length
  INTEGER, PARAMETER :: ML = 1024
  ! Literal constants
  REAL(Double), PARAMETER :: ZERO = 0.0_Double

  ! Global attribute names. Case sensitive
  CHARACTER(*), PARAMETER :: RELEASE_GATTNAME = 'Release'
  CHARACTER(*), PARAMETER :: VERSION_GATTNAME = 'Version'
  CHARACTER(*), PARAMETER :: TITLE_GATTNAME   = 'Title'
  CHARACTER(*), PARAMETER :: HISTORY_GATTNAME = 'History'
  CHARACTER(*), PARAMETER :: COMMENT_GATTNAME = 'Comment'

  ! Dimension names
  CHARACTER(*), PARAMETER :: MW_FREQ_DIMNAME     = 'n_MW_Frequencies'
  CHARACTER(*), PARAMETER :: MW_REFF_DIMNAME     = 'n_MW_Radii'
  CHARACTER(*), PARAMETER :: IR_FREQ_DIMNAME     = 'n_IR_Frequencies'
  CHARACTER(*), PARAMETER :: IR_REFF_DIMNAME     = 'n_IR_Radii'
  CHARACTER(*), PARAMETER :: TEMPERATURE_DIMNAME = 'n_Temperatures'
  CHARACTER(*), PARAMETER :: DENSITY_DIMNAME     = 'n_Densities'
  CHARACTER(*), PARAMETER :: IR_DENSITY_DIMNAME  = 'n_IR_Densities'
  CHARACTER(*), PARAMETER :: LEGENDRE_DIMNAME    = 'n_Legendre_Terms'
  CHARACTER(*), PARAMETER :: PHASE_DIMNAME       = 'n_Phase_Elements'

  ! Variable names
  CHARACTER(*), PARAMETER :: FREQUENCY_MW_VARNAME = 'Frequency_MW'
  CHARACTER(*), PARAMETER :: FREQUENCY_IR_VARNAME = 'Frequency_IR'
  CHARACTER(*), PARAMETER :: REFF_MW_VARNAME      = 'Reff_MW'
  CHARACTER(*), PARAMETER :: REFF_IR_VARNAME      = 'Reff_IR'
  CHARACTER(*), PARAMETER :: TEMPERATURE_VARNAME  = 'Temperature'
  CHARACTER(*), PARAMETER :: DENSITY_VARNAME      = 'Density'

  CHARACTER(*), PARAMETER :: KE_L_MW_VARNAME     = 'ke_L_MW'
  CHARACTER(*), PARAMETER :: W_L_MW_VARNAME      = 'w_L_MW'
  CHARACTER(*), PARAMETER :: G_L_MW_VARNAME      = 'g_L_MW'
  CHARACTER(*), PARAMETER :: PCOEFF_L_MW_VARNAME = 'pcoeff_L_MW'

  CHARACTER(*), PARAMETER :: KE_S_MW_VARNAME     = 'ke_S_MW'
  CHARACTER(*), PARAMETER :: W_S_MW_VARNAME      = 'w_S_MW'
  CHARACTER(*), PARAMETER :: G_S_MW_VARNAME      = 'g_S_MW'
  CHARACTER(*), PARAMETER :: PCOEFF_S_MW_VARNAME = 'pcoeff_S_MW'

  CHARACTER(*), PARAMETER :: KE_IR_VARNAME       = 'ke_IR'
  CHARACTER(*), PARAMETER :: W_IR_VARNAME        = 'w_IR'
  CHARACTER(*), PARAMETER :: G_IR_VARNAME        = 'g_IR'
  CHARACTER(*), PARAMETER :: PCOEFF_IR_VARNAME   = 'pcoeff_IR'

  ! Variable long name attribute.
  CHARACTER(*), PARAMETER :: LONGNAME_ATTNAME = 'long_name'

  CHARACTER(*), PARAMETER :: FREQUENCY_MW_LONGNAME = 'Frequency'
  CHARACTER(*), PARAMETER :: FREQUENCY_IR_LONGNAME = 'Frequency'
  CHARACTER(*), PARAMETER :: REFF_MW_LONGNAME      = 'Effective radius'
  CHARACTER(*), PARAMETER :: REFF_IR_LONGNAME      = 'Effective radius'
  CHARACTER(*), PARAMETER :: TEMPERATURE_LONGNAME  = 'Temperature'
  CHARACTER(*), PARAMETER :: DENSITY_LONGNAME      = 'Density'

  CHARACTER(*), PARAMETER :: KE_L_MW_LONGNAME     = 'Microwave ke(L)'
  CHARACTER(*), PARAMETER :: W_L_MW_LONGNAME      = 'Microwave w(L)'
  CHARACTER(*), PARAMETER :: G_L_MW_LONGNAME      = 'Microwave g(L)'
  CHARACTER(*), PARAMETER :: PCOEFF_L_MW_LONGNAME = 'Microwave pcoeff(L)'

  CHARACTER(*), PARAMETER :: KE_S_MW_LONGNAME     = 'Microwave ke(S)'
  CHARACTER(*), PARAMETER :: W_S_MW_LONGNAME      = 'Microwave w(S)'
  CHARACTER(*), PARAMETER :: G_S_MW_LONGNAME      = 'Microwave g(S)'
  CHARACTER(*), PARAMETER :: PCOEFF_S_MW_LONGNAME = 'Microwave pcoeff(S)'

  CHARACTER(*), PARAMETER :: KE_IR_LONGNAME       = 'Infrared ke'
  CHARACTER(*), PARAMETER :: W_IR_LONGNAME        = 'Infrared w'
  CHARACTER(*), PARAMETER :: G_IR_LONGNAME        = 'Infrared g'
  CHARACTER(*), PARAMETER :: PCOEFF_IR_LONGNAME   = 'Infrared pcoeff'

  ! Variable description attribute.
  CHARACTER(*), PARAMETER :: DESCRIPTION_ATTNAME = 'description'

  CHARACTER(*), PARAMETER :: FREQUENCY_MW_DESCRIPTION = 'Microwave frequency LUT dimension vector'
  CHARACTER(*), PARAMETER :: FREQUENCY_IR_DESCRIPTION = 'Infrared frequency LUT dimension vector'
  CHARACTER(*), PARAMETER :: REFF_MW_DESCRIPTION      = 'Microwave effective radius LUT dimension vector'
  CHARACTER(*), PARAMETER :: REFF_IR_DESCRIPTION      = 'Infrared effective radius LUT dimension vector'
  CHARACTER(*), PARAMETER :: TEMPERATURE_DESCRIPTION  = 'Temperature LUT dimension vector'
  CHARACTER(*), PARAMETER :: DENSITY_DESCRIPTION      = 'Density LUT dimension vector'

  CHARACTER(*), PARAMETER :: KE_L_MW_DESCRIPTION     = 'Mass extinction coefficient for liquid phase microwave scatterers'
  CHARACTER(*), PARAMETER :: W_L_MW_DESCRIPTION      = 'Single scatter albedo for liquid phase microwave scatterers'
  CHARACTER(*), PARAMETER :: G_L_MW_DESCRIPTION      = 'Asymmetry parameter for liquid phase microwave scatterers'
  CHARACTER(*), PARAMETER :: PCOEFF_L_MW_DESCRIPTION = 'Phase coefficients for liquid phase microwave scatterers'

  CHARACTER(*), PARAMETER :: KE_S_MW_DESCRIPTION     = 'Mass extinction coefficient for solid phase microwave scatterers'
  CHARACTER(*), PARAMETER :: W_S_MW_DESCRIPTION      = 'Single scatter albedo for solid phase microwave scatterers'
  CHARACTER(*), PARAMETER :: G_S_MW_DESCRIPTION      = 'Asymmetry parameter for solid phase microwave scatterers'
  CHARACTER(*), PARAMETER :: PCOEFF_S_MW_DESCRIPTION = 'Phase coefficients for solid phase microwave scatterers'

  CHARACTER(*), PARAMETER :: KE_IR_DESCRIPTION       = 'Mass extinction coefficient for infrared scatterers'
  CHARACTER(*), PARAMETER :: W_IR_DESCRIPTION        = 'Single scatter albedo for infrared scatterers'
  CHARACTER(*), PARAMETER :: G_IR_DESCRIPTION        = 'Asymmetry parameter for infrared scatterers'
  CHARACTER(*), PARAMETER :: PCOEFF_IR_DESCRIPTION   = 'Phase coefficients for infrared scatterers'

  ! Variable units attribute.
  CHARACTER(*), PARAMETER :: UNITS_ATTNAME = 'units'

  CHARACTER(*), PARAMETER :: RELEASE_UNITS = 'N/A'
  CHARACTER(*), PARAMETER :: VERSION_UNITS = 'N/A'

  CHARACTER(*), PARAMETER :: FREQUENCY_MW_UNITS = 'GigaHertz (GHz)'
  CHARACTER(*), PARAMETER :: FREQUENCY_IR_UNITS = 'Inverse centimetres (cm^-1)'
  CHARACTER(*), PARAMETER :: REFF_MW_UNITS      = 'Microns (um)'
  CHARACTER(*), PARAMETER :: REFF_IR_UNITS      = 'Microns (um)'
  CHARACTER(*), PARAMETER :: TEMPERATURE_UNITS  = 'Kelvin (K)'
  CHARACTER(*), PARAMETER :: DENSITY_UNITS      = 'Kilograms per cubic metre (kg.m^-3)'

  CHARACTER(*), PARAMETER :: KE_L_MW_UNITS     = 'Metres squared per kilogram (m^2.kg^-1)'
  CHARACTER(*), PARAMETER :: W_L_MW_UNITS      = 'N/A'
  CHARACTER(*), PARAMETER :: G_L_MW_UNITS      = 'N/A'
  CHARACTER(*), PARAMETER :: PCOEFF_L_MW_UNITS = 'N/A'

  CHARACTER(*), PARAMETER :: KE_S_MW_UNITS     = 'Metres squared per kilogram (m^2.kg^-1)'
  CHARACTER(*), PARAMETER :: W_S_MW_UNITS      = 'N/A'
  CHARACTER(*), PARAMETER :: G_S_MW_UNITS      = 'N/A'
  CHARACTER(*), PARAMETER :: PCOEFF_S_MW_UNITS = 'N/A'

  CHARACTER(*), PARAMETER :: KE_IR_UNITS       = 'Metres squared per kilogram (m^2.kg^-1)'
  CHARACTER(*), PARAMETER :: W_IR_UNITS        = 'N/A'
  CHARACTER(*), PARAMETER :: G_IR_UNITS        = 'N/A'
  CHARACTER(*), PARAMETER :: PCOEFF_IR_UNITS   = 'N/A'

  ! Variable _FillValue attribute.
  CHARACTER(*), PARAMETER :: FILLVALUE_ATTNAME = '_FillValue'

  REAL(Double), PARAMETER :: FREQUENCY_MW_FILLVALUE = ZERO
  REAL(Double), PARAMETER :: FREQUENCY_IR_FILLVALUE = ZERO
  REAL(Double), PARAMETER :: REFF_MW_FILLVALUE      = ZERO
  REAL(Double), PARAMETER :: REFF_IR_FILLVALUE      = ZERO
  REAL(Double), PARAMETER :: TEMPERATURE_FILLVALUE  = ZERO
  REAL(Double), PARAMETER :: DENSITY_FILLVALUE      = ZERO

  REAL(Double), PARAMETER :: KE_L_MW_FILLVALUE     = ZERO
  REAL(Double), PARAMETER :: W_L_MW_FILLVALUE      = ZERO
  REAL(Double), PARAMETER :: G_L_MW_FILLVALUE      = ZERO
  REAL(Double), PARAMETER :: PCOEFF_L_MW_FILLVALUE = ZERO

  REAL(Double), PARAMETER :: KE_S_MW_FILLVALUE     = ZERO
  REAL(Double), PARAMETER :: W_S_MW_FILLVALUE      = ZERO
  REAL(Double), PARAMETER :: G_S_MW_FILLVALUE      = ZERO
  REAL(Double), PARAMETER :: PCOEFF_S_MW_FILLVALUE = ZERO

  REAL(Double), PARAMETER :: KE_IR_FILLVALUE       = ZERO
  REAL(Double), PARAMETER :: W_IR_FILLVALUE        = ZERO
  REAL(Double), PARAMETER :: G_IR_FILLVALUE        = ZERO
  REAL(Double), PARAMETER :: PCOEFF_IR_FILLVALUE   = ZERO

  ! Variable types
  INTEGER, PARAMETER :: FREQUENCY_MW_TYPE = NF90_DOUBLE
  INTEGER, PARAMETER :: FREQUENCY_IR_TYPE = NF90_DOUBLE
  INTEGER, PARAMETER :: REFF_MW_TYPE      = NF90_DOUBLE
  INTEGER, PARAMETER :: REFF_IR_TYPE      = NF90_DOUBLE
  INTEGER, PARAMETER :: TEMPERATURE_TYPE  = NF90_DOUBLE
  INTEGER, PARAMETER :: DENSITY_TYPE      = NF90_DOUBLE

  INTEGER, PARAMETER :: KE_L_MW_TYPE     = NF90_DOUBLE
  INTEGER, PARAMETER :: W_L_MW_TYPE      = NF90_DOUBLE
  INTEGER, PARAMETER :: G_L_MW_TYPE      = NF90_DOUBLE
  INTEGER, PARAMETER :: PCOEFF_L_MW_TYPE = NF90_DOUBLE

  INTEGER, PARAMETER :: KE_S_MW_TYPE     = NF90_DOUBLE
  INTEGER, PARAMETER :: W_S_MW_TYPE      = NF90_DOUBLE
  INTEGER, PARAMETER :: G_S_MW_TYPE      = NF90_DOUBLE
  INTEGER, PARAMETER :: PCOEFF_S_MW_TYPE = NF90_DOUBLE

  INTEGER, PARAMETER :: KE_IR_TYPE       = NF90_DOUBLE
  INTEGER, PARAMETER :: W_IR_TYPE        = NF90_DOUBLE
  INTEGER, PARAMETER :: G_IR_TYPE        = NF90_DOUBLE
  INTEGER, PARAMETER :: PCOEFF_IR_TYPE   = NF90_DOUBLE

CONTAINS

!################################################################################
!################################################################################
!##                                                                            ##
!##                         ## PUBLIC MODULE ROUTINES ##                       ##
!##                                                                            ##
!################################################################################
!################################################################################

!------------------------------------------------------------------------------
!:sdoc+:
!
! NAME:
!       CloudCoeff_netCDF_InquireFile
!
! PURPOSE:
!       Function to inquire CloudCoeff object netCDF format files.
!
! CALLING SEQUENCE:
!       Error_Status = CloudCoeff_netCDF_InquireFile( &
!                        Filename, &
!                        n_MW_Frequencies = n_MW_Frequencies , &
!                        n_MW_Radii       = n_MW_Radii       , &
!                        n_IR_Frequencies = n_IR_Frequencies , &
!                        n_IR_Radii       = n_IR_Radii       , &
!                        n_Temperatures   = n_Temperatures   , &
!                        n_Densities      = n_Densities      , &
!                        n_Legendre_Terms = n_Legendre_Terms , &
!                        n_Phase_Elements = n_Phase_Elements , &
!                        Release          = Release          , &
!                        Version          = Version          , &
!                        Title            = Title            , &
!                        History          = History          , &
!                        Comment          = Comment            )
!
! INPUTS:
!       Filename:           Character string specifying the name of the
!                           CloudCoeff data file to inquire.
!                           UNITS:      N/A
!                           TYPE:       CHARACTER(*)
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(IN)
!
! OPTIONAL OUTPUTS:
!       n_MW_Frequencies:   The number of microwave frequencies in
!                           the look-up table (LUT).
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_MW_Radii:         The number of discrete effective radii
!                           for MW scatterers in the LUT.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_IR_Frequencies:   The number of infrared frequencies in
!                           the LUT.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_IR_Radii:         The number of discrete effective radii
!                           for IR scatterers in the LUT.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_Temperatures:     The number of discrete layer temperatures
!                           in the LUT.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_Densities:        The number of fixed densities for snow, graupel,
!                           and hail/ice in the LUT. Must be > 0.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_Legendre_Terms:   The maximum number of Legendre polynomial
!                           terms in the LUT.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       n_Phase_Elements:   The maximum number of phase elements in the LUT.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       Release:            The release number of the CloudCoeff file.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       Version:            The version number of the CloudCoeff file.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       Title:              Character string written into the TITLE global
!                           attribute field of the CloudCoeff file.
!                           UNITS:      N/A
!                           TYPE:       CHARACTER(*)
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       History:            Character string written into the HISTORY global
!                           attribute field of the CloudCoeff file.
!                           UNITS:      N/A
!                           TYPE:       CHARACTER(*)
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       Comment:            Character string written into the COMMENT global
!                           attribute field of the CloudCoeff file.
!                           UNITS:      N/A
!                           TYPE:       CHARACTER(*)
!                           DIMENSION:  Scalar
!                           ATTRIBUTES: INTENT(OUT), OPTIONAL
!
! FUNCTION RESULT:
!       Error_Status:       The return value is an integer defining the error
!                           status. The error codes are defined in the
!                           Message_Handler module.
!                           If == SUCCESS the file inquiry was successful
!                              == FAILURE an error occurred.
!                           UNITS:      N/A
!                           TYPE:       INTEGER
!                           DIMENSION:  Scalar
!
!:sdoc-:
!------------------------------------------------------------------------------

  FUNCTION CloudCoeff_netCDF_InquireFile( &
    Filename        , &  ! Input
    n_MW_Frequencies, &  ! Optional output
    n_MW_Radii      , &  ! Optional output
    n_IR_Frequencies, &  ! Optional output
    n_IR_Radii      , &  ! Optional output
    n_Temperatures  , &  ! Optional output
    n_Densities     , &  ! Optional output
    n_Legendre_Terms, &  ! Optional output
    n_Phase_Elements, &  ! Optional output
    Release         , &  ! Optional output
    Version         , &  ! Optional output
    Title           , &  ! Optional output
    History         , &  ! Optional output
    Comment         ) &  ! Optional output
  RESULT( err_stat )
    ! Arguments
    CHARACTER(*),           INTENT(IN)  :: Filename
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_MW_Frequencies
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_MW_Radii
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_IR_Frequencies
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_IR_Radii
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_Temperatures
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_Densities
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_Legendre_Terms
    INTEGER,      OPTIONAL, INTENT(OUT) :: n_Phase_Elements
    INTEGER,      OPTIONAL, INTENT(OUT) :: Release
    INTEGER,      OPTIONAL, INTENT(OUT) :: Version
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: Title
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: History
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: Comment
    ! Function result
    INTEGER :: err_stat
    ! Function parameters
    CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CloudCoeff_InquireFile(netCDF)'
    ! Function variables
    CHARACTER(ML) :: msg
    LOGICAL :: Close_File
    INTEGER :: NF90_Status
    INTEGER :: FileId
    INTEGER :: DimId
    TYPE(CloudCoeff_type) :: CloudCoeff

    ! Set up
    err_stat = SUCCESS
    Close_File = .FALSE.

    ! Open the file
    NF90_Status = NF90_OPEN( Filename,NF90_NOWRITE,FileId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error opening '//TRIM(Filename)//' for read access - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...Close the file if any error from here on
    Close_File = .TRUE.

    ! Get the dimensions
    ! ...n_MW_Frequencies dimension
    NF90_Status = NF90_INQ_DIMID( FileId,MW_FREQ_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//MW_FREQ_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_MW_Frequencies )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//MW_FREQ_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_MW_Radii dimension
    NF90_Status = NF90_INQ_DIMID( FileId,MW_REFF_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//MW_REFF_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_MW_Radii )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//MW_REFF_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_IR_Frequencies dimension
    NF90_Status = NF90_INQ_DIMID( FileId,IR_FREQ_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//IR_FREQ_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_IR_Frequencies )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//IR_FREQ_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_IR_Radii dimension
    NF90_Status = NF90_INQ_DIMID( FileId,IR_REFF_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//IR_REFF_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_IR_Radii )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//IR_REFF_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_Temperatures dimension
    NF90_Status = NF90_INQ_DIMID( FileId,TEMPERATURE_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//TEMPERATURE_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_Temperatures )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//TEMPERATURE_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_Densities dimension
    NF90_Status = NF90_INQ_DIMID( FileId,DENSITY_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//DENSITY_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_Densities )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//DENSITY_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_Legendre_Terms dimension
    NF90_Status = NF90_INQ_DIMID( FileId,LEGENDRE_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//LEGENDRE_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_Legendre_Terms )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//LEGENDRE_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    ! ...n_Phase_Elements dimension
    NF90_Status = NF90_INQ_DIMID( FileId,PHASE_DIMNAME,DimId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring dimension ID for '//PHASE_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_INQUIRE_DIMENSION( FileId,DimId,Len=CloudCoeff%n_Phase_Elements )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading dimension value for '//PHASE_DIMNAME//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF

    ! Get the global attributes
    err_stat = ReadGAtts( Filename, &
                          FileId  , &
                          Release = CloudCoeff%Release, &
                          Version = CloudCoeff%Version, &
                          Title   = Title  , &
                          History = History, &
                          Comment = Comment  )
    IF ( err_stat /= SUCCESS ) THEN
      msg = 'Error reading global attributes from '//TRIM(Filename)
      CALL Inquire_Cleanup(); RETURN
    END IF

    ! Close the file
    NF90_Status = NF90_CLOSE( FileId )
    Close_File = .FALSE.
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error closing input file - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Inquire_Cleanup(); RETURN
    END IF

    ! Set the return values
    IF ( PRESENT(n_MW_Frequencies) ) n_MW_Frequencies = CloudCoeff%n_MW_Frequencies
    IF ( PRESENT(n_MW_Radii      ) ) n_MW_Radii       = CloudCoeff%n_MW_Radii
    IF ( PRESENT(n_IR_Frequencies) ) n_IR_Frequencies = CloudCoeff%n_IR_Frequencies
    IF ( PRESENT(n_IR_Radii      ) ) n_IR_Radii       = CloudCoeff%n_IR_Radii
    IF ( PRESENT(n_Temperatures  ) ) n_Temperatures   = CloudCoeff%n_Temperatures
    IF ( PRESENT(n_Densities     ) ) n_Densities      = CloudCoeff%n_Densities
    IF ( PRESENT(n_Legendre_Terms) ) n_Legendre_Terms = CloudCoeff%n_Legendre_Terms-1  ! Indexed from 0, so subtract 1.
    IF ( PRESENT(n_Phase_Elements) ) n_Phase_Elements = CloudCoeff%n_Phase_Elements
    IF ( PRESENT(Release         ) ) Release          = CloudCoeff%Release
    IF ( PRESENT(Version         ) ) Version          = CloudCoeff%Version

  CONTAINS

    SUBROUTINE Inquire_CleanUp()
      IF ( Close_File ) THEN
        NF90_Status = NF90_CLOSE( FileId )
        IF ( NF90_Status /= NF90_NOERR ) &
          msg = TRIM(msg)//'; Error closing input file during error cleanup.'
      END IF
      err_stat = FAILURE
      CALL Display_Message( ROUTINE_NAME,msg,err_stat )
    END SUBROUTINE Inquire_CleanUp

  END FUNCTION CloudCoeff_netCDF_InquireFile

!------------------------------------------------------------------------------
!:sdoc+:
!
! NAME:
!       CloudCoeff_netCDF_WriteFile
!
! PURPOSE:
!       Function to write CloudCoeff object files in netCDF format.
!
! CALLING SEQUENCE:
!       Error_Status = CloudCoeff_netCDF_WriteFile( &
!                        Filename  , &
!                        CloudCoeff, &
!                        Quiet   = Quiet  , &
!                        Title   = Title  , &
!                        History = History, &
!                        Comment = Comment  )
!
! INPUTS:
!       Filename:       Character string specifying the name of the
!                       CloudCoeff data file to write.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN)
!
!       CloudCoeff:     Object containing the cloud coefficient data.
!                       UNITS:      N/A
!                       TYPE:       TYPE(CloudCoeff_type)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN)
!
! OPTIONAL INPUTS:
!       Quiet:          Set this logical argument to suppress INFORMATION
!                       messages being printed to stdout
!                       If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
!                          == .TRUE.,  INFORMATION messages are SUPPRESSED.
!                       If not specified, default is .FALSE.
!                       UNITS:      N/A
!                       TYPE:       LOGICAL
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN), OPTIONAL
!
!       Title:          Character string written into the TITLE global
!                       attribute field of the CloudCoeff file.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN), OPTIONAL
!
!       History:        Character string written into the HISTORY global
!                       attribute field of the CloudCoeff file.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN), OPTIONAL
!
!       Comment:        Character string written into the COMMENT global
!                       attribute field of the CloudCoeff file.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN), OPTIONAL
!
! FUNCTION RESULT:
!       Error_Status:   The return value is an integer defining the error status.
!                       The error codes are defined in the Message_Handler module.
!                       If == SUCCESS the data write was successful
!                          == FAILURE an unrecoverable error occurred.
!                       UNITS:      N/A
!                       TYPE:       INTEGER
!                       DIMENSION:  Scalar
!
!:sdoc-:
!------------------------------------------------------------------------------

  FUNCTION CloudCoeff_netCDF_WriteFile( &
    Filename  , &  ! Input
    CloudCoeff, &  ! Input
    Quiet     , &  ! Optional input
    Title     , &  ! Optional input
    History   , &  ! Optional input
    Comment   ) &  ! Optional input
  RESULT( err_stat )
    ! Arguments
    CHARACTER(*),           INTENT(IN) :: Filename
    TYPE(CloudCoeff_type),  INTENT(IN) :: CloudCoeff
    LOGICAL,      OPTIONAL, INTENT(IN) :: Quiet
    CHARACTER(*), OPTIONAL, INTENT(IN) :: Title
    CHARACTER(*), OPTIONAL, INTENT(IN) :: History
    CHARACTER(*), OPTIONAL, INTENT(IN) :: Comment
    ! Function result
    INTEGER :: err_stat
    ! Local parameters
    CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CloudCoeff_WriteFile(netCDF)'
    ! Local variables
    CHARACTER(ML) :: msg
    LOGICAL :: Close_File
    LOGICAL :: Noisy
    INTEGER :: NF90_Status
    INTEGER :: FileId
    INTEGER :: VarId

    ! Set up
    err_stat = SUCCESS
    Close_File = .FALSE.
    ! ...Check structure pointer association status
    IF ( .NOT. CloudCoeff_Associated( CloudCoeff ) ) THEN
      msg = 'CloudCoeff structure is empty. Nothing to do!'
      CALL Write_CleanUp(); RETURN
    END IF
    ! ...Check if release is valid
    IF ( .NOT. CloudCoeff_ValidRelease( CloudCoeff ) ) THEN
      msg = 'CloudCoeff Release check failed.'
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Check Quiet argument
    Noisy = .TRUE.
    IF ( PRESENT(Quiet) ) Noisy = .NOT. Quiet

    ! Create the output file
    err_stat = CreateFile( &
                 Filename                    , &  ! Input
                 CloudCoeff%n_MW_Frequencies , &  ! Input
                 CloudCoeff%n_MW_Radii       , &  ! Input
                 CloudCoeff%n_IR_Frequencies , &  ! Input
                 CloudCoeff%n_IR_Radii       , &  ! Input
                 CloudCoeff%n_Temperatures   , &  ! Input
                 CloudCoeff%n_Densities      , &  ! Input
                 CloudCoeff%n_Legendre_Terms , &  ! Input
                 CloudCoeff%n_Phase_Elements , &  ! Input
                 FileId                      , &  ! Output
                 Version = CloudCoeff%Version, &  ! Optional input
                 Title   = Title             , &  ! Optional input
                 History = History           , &  ! Optional input
                 Comment = Comment             )  ! Optional input
    IF ( err_stat /= SUCCESS ) THEN
      msg = 'Error creating output file '//TRIM(Filename)
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Close the file if any error from here on
    Close_File = .TRUE.

    ! Write the data items
    ! ...Frequency_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,FREQUENCY_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//FREQUENCY_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%Frequency_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//FREQUENCY_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Frequency_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,FREQUENCY_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//FREQUENCY_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%Frequency_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//FREQUENCY_IR_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Reff_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,REFF_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//REFF_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%Reff_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//REFF_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Reff_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,REFF_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//REFF_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%Reff_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//REFF_IR_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Temperature variable
    NF90_Status = NF90_INQ_VARID( FileId,TEMPERATURE_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//TEMPERATURE_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%Temperature )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//TEMPERATURE_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...Density variable
    NF90_Status = NF90_INQ_VARID( FileId,DENSITY_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//DENSITY_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%Density )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//DENSITY_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...ke_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,KE_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//KE_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%ke_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//KE_L_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...w_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,W_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//W_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%w_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//W_L_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...g_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,G_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//G_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%g_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//G_L_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...pcoeff_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,PCOEFF_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//PCOEFF_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%pcoeff_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//PCOEFF_L_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...ke_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,KE_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//KE_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%ke_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//KE_S_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...w_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,W_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//W_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%w_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//W_S_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...g_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,G_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//G_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%g_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//G_S_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...pcoeff_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,PCOEFF_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//PCOEFF_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%pcoeff_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//PCOEFF_S_MW_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...ke_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,KE_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//KE_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%ke_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//KE_IR_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...w_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,W_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//W_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%w_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//W_IR_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...g_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,G_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//G_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%g_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//G_IR_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    ! ...pcoeff_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,PCOEFF_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//PCOEFF_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_PUT_VAR( FileId,VarID,CloudCoeff%pcoeff_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error writing '//PCOEFF_IR_VARNAME//' to '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF

    ! Close the file
    NF90_Status = NF90_CLOSE( FileId )
    Close_File = .FALSE.
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error closing output file - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Write_Cleanup(); RETURN
    END IF

    ! Output an info message
    IF ( Noisy ) THEN
      CALL CloudCoeff_Info( CloudCoeff, msg )
      CALL Display_Message( ROUTINE_NAME, 'FILE: '//TRIM(Filename)//'; '//TRIM(msg), INFORMATION )
    END IF

  CONTAINS

    SUBROUTINE Write_CleanUp()
      IF ( Close_File ) THEN
        NF90_Status = NF90_CLOSE( FileId )
        IF ( NF90_Status /= NF90_NOERR ) &
          msg = TRIM(msg)//'; Error closing output file during error cleanup - '//&
                TRIM(NF90_STRERROR( NF90_Status ))
      END IF
      err_stat = FAILURE
      CALL Display_Message( ROUTINE_NAME,msg,err_stat )
    END SUBROUTINE Write_CleanUp

  END FUNCTION CloudCoeff_netCDF_WriteFile

!------------------------------------------------------------------------------
!:sdoc+:
!
! NAME:
!       CloudCoeff_netCDF_ReadFile
!
! PURPOSE:
!       Function to read CloudCoeff object files in netCDF format.
!
! CALLING SEQUENCE:
!       Error_Status = CloudCoeff_netCDF_ReadFile( &
!                        Filename         , &
!                        CloudCoeff       , &
!                        Quiet   = Quiet  , &
!                        Title   = Title  , &
!                        History = History, &
!                        Comment = Comment  )
!
! INPUTS:
!       Filename:       Character string specifying the name of the
!                       CloudCoeff data file to read.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN)
!
! OUTPUTS:
!       CloudCoeff:     CloudCoeff object containing the cloud coefficient data.
!                       UNITS:      N/A
!                       TYPE:       TYPE(CloudCoeff_type)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(OUT)
!
! OPTIONAL INPUTS:
!       Quiet:          Set this logical argument to suppress INFORMATION
!                       messages being printed to stdout
!                       If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
!                          == .TRUE.,  INFORMATION messages are SUPPRESSED.
!                       If not specified, default is .FALSE.
!                       UNITS:      N/A
!                       TYPE:       LOGICAL
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(IN), OPTIONAL
!
! OPTIONAL OUTPUTS:
!       Title:          Character string written into the TITLE global
!                       attribute field of the CloudCoeff file.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       History:        Character string written into the HISTORY global
!                       attribute field of the CloudCoeff file.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(OUT), OPTIONAL
!
!       Comment:        Character string written into the COMMENT global
!                       attribute field of the CloudCoeff file.
!                       UNITS:      N/A
!                       TYPE:       CHARACTER(*)
!                       DIMENSION:  Scalar
!                       ATTRIBUTES: INTENT(OUT), OPTIONAL
!
! FUNCTION RESULT:
!       Error_Status:   The return value is an integer defining the error status.
!                       The error codes are defined in the Message_Handler module.
!                       If == SUCCESS the data read was successful
!                          == FAILURE an unrecoverable error occurred.
!                       UNITS:      N/A
!                       TYPE:       INTEGER
!                       DIMENSION:  Scalar
!
!:sdoc-:
!------------------------------------------------------------------------------

  FUNCTION CloudCoeff_netCDF_ReadFile( &
    Filename  , &  ! Input
    CloudCoeff, &  ! Output
    Quiet     , &  ! Optional input
    Title     , &  ! Optional output
    History   , &  ! Optional output
    Comment   ) &  ! Optional output
  RESULT( err_stat )
    ! Arguments
    CHARACTER(*),           INTENT(IN)  :: Filename
    TYPE(CloudCoeff_type),  INTENT(OUT) :: CloudCoeff
    LOGICAL,      OPTIONAL, INTENT(IN)  :: Quiet
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: Title
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: History
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: Comment
    ! Function result
    INTEGER :: err_stat
    ! Function parameters
    CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CloudCoeff_ReadFile(netCDF)'
    ! Function variables
    CHARACTER(ML) :: msg
    LOGICAL :: Close_File
    LOGICAL :: Noisy
    INTEGER :: NF90_Status
    INTEGER :: FileId
    INTEGER :: n_MW_Frequencies
    INTEGER :: n_MW_Radii
    INTEGER :: n_IR_Frequencies
    INTEGER :: n_IR_Radii
    INTEGER :: n_Temperatures
    INTEGER :: n_Densities
    INTEGER :: n_Legendre_Terms
    INTEGER :: n_Phase_Elements
    INTEGER :: VarId

    ! Set up
    err_stat = SUCCESS
    Close_File = .FALSE.
    ! ...Check that the file exists
    IF ( .NOT. File_Exists(Filename) ) THEN
      msg = 'File '//TRIM(Filename)//' not found.'
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Check Quiet argument
    Noisy = .TRUE.
    IF ( PRESENT(Quiet) ) Noisy = .NOT. Quiet

    ! Inquire the file to get the dimensions
    err_stat = CloudCoeff_netCDF_InquireFile( &
                 Filename, &
                 n_MW_Frequencies = n_MW_Frequencies, &
                 n_MW_Radii       = n_MW_Radii      , &
                 n_IR_Frequencies = n_IR_Frequencies, &
                 n_IR_Radii       = n_IR_Radii      , &
                 n_Temperatures   = n_Temperatures  , &
                 n_Densities      = n_Densities     , &
                 n_Legendre_Terms = n_Legendre_Terms, &
                 n_Phase_Elements = n_Phase_Elements  )
    IF ( err_stat /= SUCCESS ) THEN
      msg = 'Error obtaining CloudCoeff dimensions from '//TRIM(Filename)
      CALL Read_Cleanup(); RETURN
    END IF

    ! Allocate the output structure
    CALL CloudCoeff_Create( &
           CloudCoeff, &
           n_MW_Frequencies, &
           n_MW_Radii      , &
           n_IR_Frequencies, &
           n_IR_Radii      , &
           n_Temperatures  , &
           n_Densities     , &
           n_Legendre_Terms, &
           n_Phase_Elements  )
    IF ( .NOT. CloudCoeff_Associated(CloudCoeff) ) THEN
      msg = 'Error allocating output CloudCoeff'
      CALL Read_Cleanup(); RETURN
    END IF

    ! Open the file for reading
    NF90_Status = NF90_OPEN( Filename,NF90_NOWRITE,FileId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error opening '//TRIM(Filename)//' for read access - '//&
            TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Close the file if any error from here on
    Close_File = .TRUE.

    ! Read the global attributes
    err_stat = ReadGAtts( Filename, &
                          FileID  , &
                          Release = CloudCoeff%Release, &
                          Version = CloudCoeff%Version, &
                          Title   = Title             , &
                          History = History           , &
                          Comment = Comment             )
    IF ( err_stat /= SUCCESS ) THEN
      msg = 'Error reading global attribute from '//TRIM(Filename)
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Check if release is valid
    IF ( .NOT. CloudCoeff_ValidRelease( CloudCoeff ) ) THEN
      msg = 'CloudCoeff Release check failed.'
      CALL Read_Cleanup(); RETURN
    END IF

    ! Read the CloudCoeff data
    ! ...Frequency_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,FREQUENCY_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//FREQUENCY_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%Frequency_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//FREQUENCY_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Frequency_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,FREQUENCY_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//FREQUENCY_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%Frequency_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//FREQUENCY_IR_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Reff_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,REFF_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//REFF_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%Reff_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//REFF_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Reff_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,REFF_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//REFF_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%Reff_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//REFF_IR_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Temperature variable
    NF90_Status = NF90_INQ_VARID( FileId,TEMPERATURE_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//TEMPERATURE_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%Temperature )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//TEMPERATURE_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...Density variable
    NF90_Status = NF90_INQ_VARID( FileId,DENSITY_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//DENSITY_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%Density )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//DENSITY_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...ke_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,KE_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//KE_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%ke_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//KE_L_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...w_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,W_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//W_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%w_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//W_L_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...g_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,G_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//G_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%g_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//G_L_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...pcoeff_L_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,PCOEFF_L_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//PCOEFF_L_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%pcoeff_L_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//PCOEFF_L_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...ke_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,KE_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//KE_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%ke_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//KE_S_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...w_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,W_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//W_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%w_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//W_S_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...g_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,G_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//G_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%g_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//G_S_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...pcoeff_S_MW variable
    NF90_Status = NF90_INQ_VARID( FileId,PCOEFF_S_MW_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//PCOEFF_S_MW_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%pcoeff_S_MW )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//PCOEFF_S_MW_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...ke_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,KE_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//KE_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%ke_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//KE_IR_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...w_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,W_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//W_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%w_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//W_IR_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...g_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,G_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//G_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%g_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//G_IR_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    ! ...pcoeff_IR variable
    NF90_Status = NF90_INQ_VARID( FileId,PCOEFF_IR_VARNAME,VarId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error inquiring '//TRIM(Filename)//' for '//PCOEFF_IR_VARNAME//&
            ' variable ID - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF
    NF90_Status = NF90_GET_VAR( FileId,VarID,CloudCoeff%pcoeff_IR )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error reading '//PCOEFF_IR_VARNAME//' from '//TRIM(Filename)//&
            ' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF

    ! Close the file
    NF90_Status = NF90_CLOSE( FileId ); Close_File = .FALSE.
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error closing output file - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Read_Cleanup(); RETURN
    END IF

    ! Output an info message
    IF ( Noisy ) THEN
      CALL CloudCoeff_Info( CloudCoeff, msg )
      CALL Display_Message( ROUTINE_NAME, 'FILE: '//TRIM(Filename)//'; '//TRIM(msg), INFORMATION )
    END IF

  CONTAINS

    SUBROUTINE Read_CleanUp()
      IF ( Close_File ) THEN
        NF90_Status = NF90_CLOSE( FileId )
        IF ( NF90_Status /= NF90_NOERR ) &
          msg = TRIM(msg)//'; Error closing input file during error cleanup- '//&
                TRIM(NF90_STRERROR( NF90_Status ))
      END IF
      CALL CloudCoeff_Destroy( CloudCoeff )
      err_stat = FAILURE
      CALL Display_Message( ROUTINE_NAME,msg,err_stat )
    END SUBROUTINE Read_CleanUp

  END FUNCTION CloudCoeff_netCDF_ReadFile

!--------------------------------------------------------------------------------
!:sdoc+:
!
! NAME:
!       CloudCoeff_netCDF_IOVersion
!
! PURPOSE:
!       Subroutine to return the module version information.
!
! CALLING SEQUENCE:
!       CALL CloudCoeff_netCDF_IOVersion( Id )
!
! OUTPUT ARGUMENTS:
!       Id:            Character string containing the version Id information
!                      for the module.
!                      UNITS:      N/A
!                      TYPE:       CHARACTER(*)
!                      DIMENSION:  Scalar
!                      ATTRIBUTES: INTENT(OUT)
!
!:sdoc-:
!--------------------------------------------------------------------------------

!  SUBROUTINE CloudCoeff_netCDF_IOVersion( Id )
!    CHARACTER(*), INTENT(OUT) :: Id
!    Id = MODULE_VERSION_ID
!  END SUBROUTINE CloudCoeff_netCDF_IOVersion

!##################################################################################
!##################################################################################
!##                                                                              ##
!##                          ## PRIVATE MODULE ROUTINES ##                       ##
!##                                                                              ##
!##################################################################################
!##################################################################################

  ! Function to write the global attributes to a CloudCoeff data file.

  FUNCTION WriteGAtts( &
    Filename, &  ! Input
    FileId  , &  ! Input
    Version , &  ! Optional input
    Title   , &  ! Optional input
    History , &  ! Optional input
    Comment ) &  ! Optional input
  RESULT( err_stat )
    ! Arguments
    CHARACTER(*),           INTENT(IN) :: Filename
    INTEGER     ,           INTENT(IN) :: FileId
    INTEGER     , OPTIONAL, INTENT(IN) :: Version
    CHARACTER(*), OPTIONAL, INTENT(IN) :: Title
    CHARACTER(*), OPTIONAL, INTENT(IN) :: History
    CHARACTER(*), OPTIONAL, INTENT(IN) :: Comment
    ! Function result
    INTEGER :: err_stat
    ! Local parameters
    CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CloudCoeff_WriteGAtts(netCDF)'
    CHARACTER(*), PARAMETER :: WRITE_MODULE_HISTORY_GATTNAME   = 'write_module_history'
    CHARACTER(*), PARAMETER :: CREATION_DATE_AND_TIME_GATTNAME = 'creation_date_and_time'
    ! Local variables
    CHARACTER(ML) :: msg
    CHARACTER(ML) :: GAttName
    CHARACTER(8)  :: cdate
    CHARACTER(10) :: ctime
    CHARACTER(5)  :: czone
    INTEGER :: Ver
    INTEGER :: NF90_Status
    TYPE(CloudCoeff_type) :: CloudCoeff

    ! Set up
    err_stat = SUCCESS
    msg = ' '

    ! Mandatory global attributes
    ! ...Software ID
    !GAttName = WRITE_MODULE_HISTORY_GATTNAME
    !NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName),MODULE_VERSION_ID )
    !IF ( NF90_Status /= NF90_NOERR ) THEN
    !  CALL WriteGAtts_Cleanup(); RETURN
    !END IF
    ! ...Creation date
    CALL DATE_AND_TIME( cdate, ctime, czone )
    GAttName = CREATION_DATE_AND_TIME_GATTNAME
    NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName), &
                                cdate(1:4)//'/'//cdate(5:6)//'/'//cdate(7:8)//', '// &
                                ctime(1:2)//':'//ctime(3:4)//':'//ctime(5:6)//' '// &
                                czone//'UTC' )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      CALL WriteGAtts_Cleanup(); RETURN
    END IF
    ! ...The Release
    GAttName = RELEASE_GATTNAME
    NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName),CloudCoeff%Release )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      CALL WriteGAtts_Cleanup(); RETURN
    END IF

    ! Optional global attributes
    ! ...The Version
    IF ( PRESENT(Version) ) THEN
      Ver = Version
    ELSE
      Ver = CloudCoeff%Version
    END IF
    GAttName = VERSION_GATTNAME
    NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName),Ver )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      CALL WriteGAtts_Cleanup(); RETURN
    END IF
    ! ...The title
    IF ( PRESENT(title) ) THEN
      GAttName = TITLE_GATTNAME
      NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName),title )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL WriteGAtts_Cleanup(); RETURN
      END IF
    END IF
    ! ...The history
    IF ( PRESENT(history) ) THEN
      GAttName = HISTORY_GATTNAME
      NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName),history )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL WriteGAtts_Cleanup(); RETURN
      END IF
    END IF
    ! ...The comment
    IF ( PRESENT(comment) ) THEN
      GAttName = COMMENT_GATTNAME
      NF90_Status = NF90_PUT_ATT( FileId,NF90_GLOBAL,TRIM(GAttName),comment )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL WriteGAtts_Cleanup(); RETURN
      END IF
    END IF

 CONTAINS

    SUBROUTINE WriteGAtts_CleanUp()
      NF90_Status = NF90_CLOSE( FileId )
      IF ( NF90_Status /= NF90_NOERR ) &
        msg = '; Error closing input file during error cleanup - '//&
              TRIM(NF90_STRERROR( NF90_Status ) )
      err_stat = FAILURE
      CALL Display_Message( ROUTINE_NAME, &
                            'Error writing '//TRIM(GAttName)//' attribute to '//&
                            TRIM(Filename)//' - '// &
                            TRIM(NF90_STRERROR( NF90_Status ) )//TRIM(msg), &
                            err_stat )
    END SUBROUTINE WriteGAtts_CleanUp

  END FUNCTION WriteGAtts

  ! Function to read the global attributes from a CloudCoeff data file.

  FUNCTION ReadGAtts( &
    Filename, &  ! Input
    FileId  , &  ! Input
    Release , &  ! Optional output
    Version , &  ! Optional output
    Title   , &  ! Optional output
    History , &  ! Optional output
    Comment ) &  ! Optional output
  RESULT( err_stat )
    ! Arguments
    CHARACTER(*),           INTENT(IN)  :: Filename
    INTEGER     ,           INTENT(IN)  :: FileId
    INTEGER     , OPTIONAL, INTENT(OUT) :: Release
    INTEGER     , OPTIONAL, INTENT(OUT) :: Version
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: Title
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: History
    CHARACTER(*), OPTIONAL, INTENT(OUT) :: Comment
    ! Function result
    INTEGER :: err_stat
    ! Local parameters
    CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CloudCoeff_ReadGAtts(netCDF)'
    ! Local variables
    CHARACTER(ML)   :: msg
    CHARACTER(256)  :: GAttName
    CHARACTER(5000) :: GAttString
    INTEGER :: NF90_Status

    ! Set up
    err_stat = SUCCESS

    ! The global attributes
    ! ...The Release
    IF ( PRESENT(Release) ) THEN
      GAttName = RELEASE_GATTNAME
      NF90_Status = NF90_GET_ATT( FileID,NF90_GLOBAL,TRIM(GAttName),Release )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL ReadGAtts_Cleanup(); RETURN
      END IF
    END IF
    ! ...The Version
    IF ( PRESENT(Version) ) THEN
      GAttName = VERSION_GATTNAME
      NF90_Status = NF90_GET_ATT( FileID,NF90_GLOBAL,TRIM(GAttName),Version )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL ReadGAtts_Cleanup(); RETURN
      END IF
    END IF
    ! ...The title
    IF ( PRESENT(title) ) THEN
      GAttName = TITLE_GATTNAME; GAttString = ''
      NF90_Status = NF90_GET_ATT( FileID,NF90_GLOBAL,TRIM(GAttName),GAttString )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL ReadGAtts_Cleanup(); RETURN
      END IF
      CALL StrClean( GAttString )
      title = GAttString(1:MIN(LEN(title), LEN_TRIM(GAttString)))
    END IF
    ! ...The history
    IF ( PRESENT(history) ) THEN
      GAttName = HISTORY_GATTNAME; GAttString = ''
      NF90_Status = NF90_GET_ATT( FileID,NF90_GLOBAL,TRIM(GAttName),GAttString )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL ReadGAtts_Cleanup(); RETURN
      END IF
      CALL StrClean( GAttString )
      history = GAttString(1:MIN(LEN(history), LEN_TRIM(GAttString)))
    END IF
    ! ...The comment
    IF ( PRESENT(comment) ) THEN
      GAttName = COMMENT_GATTNAME; GAttString = ''
      NF90_Status = NF90_GET_ATT( FileID,NF90_GLOBAL,TRIM(GAttName),GAttString )
      IF ( NF90_Status /= NF90_NOERR ) THEN
        CALL ReadGAtts_Cleanup(); RETURN
      END IF
      CALL StrClean( GAttString )
      comment = GAttString(1:MIN(LEN(comment), LEN_TRIM(GAttString)))
    END IF

  CONTAINS

    SUBROUTINE ReadGAtts_CleanUp()
      err_stat = FAILURE
      msg = 'Error reading '//TRIM(GAttName)//' attribute from '//TRIM(Filename)//' - '// &
            TRIM(NF90_STRERROR( NF90_Status ) )
      CALL Display_Message( ROUTINE_NAME, msg, err_stat )
    END SUBROUTINE ReadGAtts_CleanUp

  END FUNCTION ReadGAtts

  ! Function to create a CloudCoeff file for writing

  FUNCTION CreateFile( &
    Filename        , &  ! Input
    n_MW_Frequencies, &  ! Input
    n_MW_Radii      , &  ! Input
    n_IR_Frequencies, &  ! Input
    n_IR_Radii      , &  ! Input
    n_Temperatures  , &  ! Input
    n_Densities     , &  ! Input
    n_Legendre_Terms, &  ! Input
    n_Phase_Elements, &  ! Input
    FileId          , &  ! Output
    Version         , &  ! Optional input
    Title           , &  ! Optional input
    History         , &  ! Optional input
    Comment         ) &  ! Optional input
  RESULT( err_stat )
    ! Arguments
    CHARACTER(*),           INTENT(IN)  :: Filename
    INTEGER     ,           INTENT(IN)  :: n_MW_Frequencies
    INTEGER     ,           INTENT(IN)  :: n_MW_Radii
    INTEGER     ,           INTENT(IN)  :: n_IR_Frequencies
    INTEGER     ,           INTENT(IN)  :: n_IR_Radii
    INTEGER     ,           INTENT(IN)  :: n_Temperatures
    INTEGER     ,           INTENT(IN)  :: n_Densities
    INTEGER     ,           INTENT(IN)  :: n_Legendre_Terms
    INTEGER     ,           INTENT(IN)  :: n_Phase_Elements
    INTEGER     ,           INTENT(OUT) :: FileId
    INTEGER     , OPTIONAL, INTENT(IN)  :: Version
    CHARACTER(*), OPTIONAL, INTENT(IN)  :: Title
    CHARACTER(*), OPTIONAL, INTENT(IN)  :: History
    CHARACTER(*), OPTIONAL, INTENT(IN)  :: Comment
    ! Function result
    INTEGER :: err_stat
    ! Local parameters
    CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CloudCoeff_CreateFile(netCDF)'
    ! Local variables
    CHARACTER(ML) :: msg
    LOGICAL :: Close_File
    INTEGER :: NF90_Status
    INTEGER :: n_MW_Frequencies_DimID
    INTEGER :: n_MW_Radii_DimID
    INTEGER :: n_IR_Frequencies_DimID
    INTEGER :: n_IR_Radii_DimID
    INTEGER :: n_Temperatures_DimID
    INTEGER :: n_Densities_DimID
    INTEGER :: n_IR_Densities_DimID
    INTEGER :: n_Legendre_Terms_DimID
    INTEGER :: n_Phase_Elements_DimID
    INTEGER :: varID
    INTEGER :: Put_Status(4)

    ! Setup
    err_stat = SUCCESS
    Close_File = .FALSE.

    ! Create the data file
    NF90_Status = NF90_CREATE( Filename,NF90_CLOBBER,FileId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error creating '//TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Close the file if any error from here on
    Close_File = .TRUE.

    ! Define the dimensions
    ! ...Number of microwave frequencies
    NF90_Status = NF90_DEF_DIM( FileID,MW_FREQ_DIMNAME,n_MW_Frequencies,n_MW_Frequencies_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//MW_FREQ_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of radii for microwave data
    NF90_Status = NF90_DEF_DIM( FileID,MW_REFF_DIMNAME,n_MW_Radii,n_MW_Radii_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//MW_REFF_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of infrared frequencies
    NF90_Status = NF90_DEF_DIM( FileID,IR_FREQ_DIMNAME,n_IR_Frequencies,n_IR_Frequencies_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//IR_FREQ_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of radii for infrared data
    NF90_Status = NF90_DEF_DIM( FileID,IR_REFF_DIMNAME,n_IR_Radii,n_IR_Radii_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//IR_REFF_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of temperatures
    NF90_Status = NF90_DEF_DIM( FileID,TEMPERATURE_DIMNAME,n_Temperatures,n_Temperatures_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//TEMPERATURE_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of densities for microwave data
    NF90_Status = NF90_DEF_DIM( FileID,DENSITY_DIMNAME,n_Densities,n_Densities_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//DENSITY_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of densities for infrared data
    ! ...Array indexing starts at 0, so +1
    NF90_Status = NF90_DEF_DIM( FileID,IR_DENSITY_DIMNAME,n_Densities+1,n_IR_Densities_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//IR_DENSITY_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of Legendre terms
    ! ...Array indexing starts at 0, so +1
    NF90_Status = NF90_DEF_DIM( FileID,LEGENDRE_DIMNAME,n_Legendre_Terms+1,n_Legendre_Terms_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//LEGENDRE_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Number of phase elements
    NF90_Status = NF90_DEF_DIM( FileID,PHASE_DIMNAME,n_Phase_Elements,n_Phase_Elements_DimID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//PHASE_DIMNAME//' dimension in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF

    ! Write the global attributes
    err_stat = WriteGAtts( Filename, &
                           FileId  , &
                           Version = Version, &
                           Title   = Title  , &
                           History = History, &
                           Comment = Comment  )
    IF ( err_stat /= SUCCESS ) THEN
      msg = 'Error writing global attribute to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF

    ! Define the variables
    ! ...Frequency_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      FREQUENCY_MW_VARNAME, &
      FREQUENCY_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//FREQUENCY_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,FREQUENCY_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,FREQUENCY_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,FREQUENCY_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,FREQUENCY_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//FREQUENCY_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Frequency_IR variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      FREQUENCY_IR_VARNAME, &
      FREQUENCY_IR_TYPE, &
      dimIDs=(/n_IR_Frequencies_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//FREQUENCY_IR_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,FREQUENCY_IR_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,FREQUENCY_IR_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,FREQUENCY_IR_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,FREQUENCY_IR_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//FREQUENCY_IR_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Reff_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      REFF_MW_VARNAME, &
      REFF_MW_TYPE, &
      dimIDs=(/n_MW_Radii_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//REFF_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,REFF_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,REFF_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,REFF_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,REFF_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//REFF_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Reff_IR variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      REFF_IR_VARNAME, &
      REFF_IR_TYPE, &
      dimIDs=(/n_IR_Radii_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//REFF_IR_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,REFF_IR_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,REFF_IR_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,REFF_IR_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,REFF_IR_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//REFF_IR_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Temperature variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      TEMPERATURE_VARNAME, &
      TEMPERATURE_TYPE, &
      dimIDs=(/n_Temperatures_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//TEMPERATURE_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,TEMPERATURE_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,TEMPERATURE_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,TEMPERATURE_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,TEMPERATURE_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//TEMPERATURE_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...Density variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      DENSITY_VARNAME, &
      DENSITY_TYPE, &
      dimIDs=(/n_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//DENSITY_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,DENSITY_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,DENSITY_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,DENSITY_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,DENSITY_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//DENSITY_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...ke_L_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      KE_L_MW_VARNAME, &
      KE_L_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Temperatures_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//KE_L_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,KE_L_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,KE_L_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,KE_L_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,KE_L_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//KE_L_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...w_L_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      W_L_MW_VARNAME, &
      W_L_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Temperatures_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//W_L_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,W_L_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,W_L_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,W_L_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,W_L_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//W_L_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...g_L_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      G_L_MW_VARNAME, &
      G_L_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Temperatures_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//G_L_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,G_L_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,G_L_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,G_L_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,G_L_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//G_L_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...pcoeff_L_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      PCOEFF_L_MW_VARNAME, &
      PCOEFF_L_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Temperatures_DimID, &
               n_Legendre_Terms_DimID, n_Phase_Elements_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//PCOEFF_L_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,PCOEFF_L_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,PCOEFF_L_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,PCOEFF_L_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,PCOEFF_L_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//PCOEFF_L_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...ke_S_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      KE_S_MW_VARNAME, &
      KE_S_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//KE_S_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,KE_S_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,KE_S_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,KE_S_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,KE_S_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//KE_S_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...w_S_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      W_S_MW_VARNAME, &
      W_S_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//W_S_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,W_S_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,W_S_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,W_S_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,W_S_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//W_S_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...g_S_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      G_S_MW_VARNAME, &
      G_S_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//G_S_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,G_S_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,G_S_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,G_S_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,G_S_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//G_S_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...pcoeff_S_MW variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      PCOEFF_S_MW_VARNAME, &
      PCOEFF_S_MW_TYPE, &
      dimIDs=(/n_MW_Frequencies_DimID, n_MW_Radii_DimID, n_Densities_DimID, &
               n_Legendre_Terms_DimID, n_Phase_Elements_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//PCOEFF_S_MW_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,PCOEFF_S_MW_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,PCOEFF_S_MW_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,PCOEFF_S_MW_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,PCOEFF_S_MW_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//PCOEFF_S_MW_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...ke_IR variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      KE_IR_VARNAME, &
      KE_IR_TYPE, &
      dimIDs=(/n_IR_Frequencies_DimID, n_IR_Radii_DimID, n_IR_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//KE_IR_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,KE_IR_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,KE_IR_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,KE_IR_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,KE_IR_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//KE_IR_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...w_IR variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      W_IR_VARNAME, &
      W_IR_TYPE, &
      dimIDs=(/n_IR_Frequencies_DimID, n_IR_Radii_DimID, n_IR_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//W_IR_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,W_IR_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,W_IR_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,W_IR_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,W_IR_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//W_IR_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...g_IR variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      G_IR_VARNAME, &
      G_IR_TYPE, &
      dimIDs=(/n_IR_Frequencies_DimID, n_IR_Radii_DimID, n_IR_Densities_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//G_IR_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,G_IR_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,G_IR_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,G_IR_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,G_IR_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//G_IR_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF
    ! ...pcoeff_IR variable
    NF90_Status = NF90_DEF_VAR( FileID, &
      PCOEFF_IR_VARNAME, &
      PCOEFF_IR_TYPE, &
      dimIDs=(/n_IR_Frequencies_DimID, n_IR_Radii_DimID, n_IR_Densities_DimID, &
               n_Legendre_Terms_DimID/), &
      varID=VarID )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error defining '//PCOEFF_IR_VARNAME//' variable in '//&
            TRIM(Filename)//' - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF
    Put_Status(1) = NF90_PUT_ATT( FileID,VarID,LONGNAME_ATTNAME   ,PCOEFF_IR_LONGNAME    )
    Put_Status(2) = NF90_PUT_ATT( FileID,VarID,DESCRIPTION_ATTNAME,PCOEFF_IR_DESCRIPTION )
    Put_Status(3) = NF90_PUT_ATT( FileID,VarID,UNITS_ATTNAME      ,PCOEFF_IR_UNITS       )
    Put_Status(4) = NF90_PUT_ATT( FileID,VarID,FILLVALUE_ATTNAME  ,PCOEFF_IR_FILLVALUE   )
    IF ( ANY(Put_Status /= NF90_NOERR) ) THEN
      msg = 'Error writing '//PCOEFF_IR_VARNAME//' variable attributes to '//TRIM(Filename)
      CALL Create_Cleanup(); RETURN
    END IF

    ! Take netCDF file out of define mode
    NF90_Status = NF90_ENDDEF( FileId )
    IF ( NF90_Status /= NF90_NOERR ) THEN
      msg = 'Error taking file '//TRIM(Filename)// &
            ' out of define mode - '//TRIM(NF90_STRERROR( NF90_Status ))
      CALL Create_Cleanup(); RETURN
    END IF

  CONTAINS

    SUBROUTINE Create_CleanUp()
      IF ( Close_File ) THEN
        NF90_Status = NF90_CLOSE( FileID )
        IF ( NF90_Status /= NF90_NOERR ) &
          msg = TRIM(msg)//'; Error closing input file during error cleanup - '//&
                TRIM(NF90_STRERROR( NF90_Status ))
      END IF
      err_stat = FAILURE
      CALL Display_Message( ROUTINE_NAME,msg,err_stat )
    END SUBROUTINE Create_CleanUp

  END FUNCTION CreateFile

END MODULE CloudCoeff_netCDF_IO

max_stars_repo_name: hsbadr/crtm

max_issues_repo_name: hsbadr/crtm

max_forks_repo_name: hsbadr/crtm


text:
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!       NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS      !
!-----------------------------------------------------------------------
!
! !ROUTINE: indexxs - indexed heap-sorting of a list of strings
!
! !INTERFACE:
    subroutine indexxs(n,str,indx)
      implicit none
      integer, intent(in)	:: n		! number of strings
      character(len=*), intent(in) :: str(n)	! a list of strings
      integer, intent(out)	:: indx(n)	! a sorted index
!   end subroutine ihpsrt_str

! !DESCRIPTION:
!
! !EXAMPLES:
!
! !BUGS:
!
! !SEE ALSO:
!
! !SYSTEM ROUTINES:
!
! !FILES USED:
!
! !REVISION HISTORY:
! 	10Jan96 - J. Guo	- programmed and added the prolog
!_______________________________________________________________________

!   ..Locals
  integer i,j,l,ir,indxt
  character(len=len(str))	:: tStr

!-----------------------------------------------------------------------

  do i=1,n			! initialize the indices
    indx(i)=i
  end do
  if(n.le.1) return

  l = n/2 + 1
  ir = n

  do
    if( l.gt.1 ) then
      l = l - 1
      indxt = indx(l)
      tStr = str(indxt)

    else
      indxt = indx(ir)
      tStr = str(indxt)
      indx(ir) = indx(1)
      ir = ir - 1

      if( ir.eq.1 ) then
        indx(1) = indxt
        return			! <== the exit
      endif
    endif

    i = l
    j = l + l

    do while( j.le.ir )
      if( j.lt.ir ) then
	if ( str(indx(j)).lt.str(indx(j+1)) ) j = j + 1
      endif

      if( tStr.lt.str(indx(j)) ) then
        indx(i) = indx(j)
        i = j
        j = j + j

      else
        j = ir + 1

      endif

    end do

    indx(i) = indxt

  end do
!
end
!.

max_stars_repo_name: GEOS-ESM/AeroApps

max_forks_repo_name: GEOS-ESM/AeroApps


text:
Ariela Haro: Ariela has a B.A. in Sociology and a minor in Music from UC Davis. She plans to pursue a Ph.D in Music History and become a Mozart specialist.

While in Davis, she hosted a hit radio show on KDRT called Arielas Appassionata. The show was so good that it replayed four times! It is also played spontaneously throughout the week. Arielas Appassionata was the only classical show in Davis, although apparently an opera show is in the planning stages.. Ariela also volunteered at http://www.capradio.org KXPR, the classical station in Sacramento.

In May, 2007, she moved to wiki:Madison with her partner, Users/KarlMogel Karl J. Mogel.

Fan Club
Users/KarlMogel
Users/StevenDaubert
Users/AlexandraKollantai

20070303 01:58:25 nbsp Thanks to your encouragement I finally read Bitch magazine. Thats some great stuff! Truly enlightening. Im interested in know your take on my idea of the family: mainly that kids should be reared by the state, not their families. and that every child is everyones child. Users/AlexandraKollantai

20070622 01:53:52 nbsp ariela! i need your help! how did goddess religions come about? and what matriarchal societies (human and nonhuman) can you name? thanks for the letter. im bad with missives, but i intend on responding. hope all is well! Users/JessicaRockwell

20071025 21:33:46 nbsp foo, i want to see the blog. holla! Users/JessicaRockwell

ext: f

max_stars_repo_name: voflo/Search

max_issues_repo_name: voflo/Search

max_forks_repo_name: voflo/Search