*....................................................................



      subroutine ODS_NCCreate ( id, filename, ods_type,  1,28
     .                                        first_jday, ierr )

      implicit NONE

!-------------------------------------------------------------------------
!         NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS      !
!-------------------------------------------------------------------------
!
! !ROUTINE:          ODS\_NCCreate
! 
! !DESCRIPTION:      
!     Creates an ODS file and initializes the pointers
!     specifying the location and size of data blocks that
!     are partitioned according to julian day and synoptic
!     hour.  Most of this routine is dedicated to calling
!     NetCDF interface routines to determine the structure
!     of the ODS file.  This structure is described in
!     terms of the network common data form language (CDL)
!     and in the header as produced with the NetCDF interface
!     to HDF utility ncdump (see Appendix C of da Silva and
!     Redder, 1996 ).  For further information regarding
!     NetCDF routines and CDL see Rew et al. (1993).
!
! !REFERENCE: 
!
!     Rew, Russ, Glenn Davis and Steve Emmerson, 1993:
!        NetCDF User's Guide, Unidata Program Center,
!        University Corporation for Atmospheric Research,
!        National Science Foundation, Boulder, CO.
!
!
! !INTERFACE:
!     call ODS_NCCreate  ( id, filename, ods_type, 
!                                        first_jday, ierr )
!
! !INPUT PARAMETERS:
      character * (*)  filename             ! name of ODS file
      character * (*)  ods_type             ! = 'pre_anal', if only
                                            !    repacked obs are to be
                                            !    stored.
                                            ! = 'post_anal', if
                                            !    data from assimilation
                                            !    is to be stored
      integer          first_jday           ! first julian day
!
! !OUTPUT PARAMETERS: 
      integer          id                   ! ODS file handle
      integer          ierr                 ! error code
!
! !SEE ALSO:
!     ODS_NCOpen  ( opens  the ODS file )
!     ODS_Close   ( closes the ODS file )!
!     ODS_Julian()  convert the "calendar" date to the Julian day

! !FILES USED:
!     netcdf.inc, a header file, for defining NetCDF library 
!            parameters
!     ods_hdf.h, a header file, for defining hardwired constants
!            and defining global variables and setting up data
!            structures
!     ods_stdio.h, a header file, for defining standard input/output
!            unit numbers
!
! !LIBRARIES ACCESSED:
!     NetCDF
!
! !REVISION HISTORY:
!     3 Sept 1996  Redder   Origional version
!    19 Aug  1997  Redder   Removed the ODS variable for the
!                           modification flag
!    17 Sept 1997  Redder   Modified code in order store the
!                           QC flag as a 4-byte integer
!    13 Apr  1998  Redder   Changed variable name "level" to
!                          "lev"; removed the variables, qc_flag,
!                           julian and km, added the variables,
!                           qcexcl, qchist, xm; modified the
!                           variable, time; hanged variable names,
!                           kt_max and kx_max, to nkt and nkx;
!                           modified code to handle the version
!                           tag with greater flexibility.  These
!                           changes were made to create ODS
!                           version 2.00
!     22 Apr 1998  Redder   Changed the offset and valid range of
!                           the NetCDF variable, time, to allow for  
!                           for negative values.  Time values can
!                           be negative when, for example, the
!                           sample time is 21Z of the synptic time
!                           0Z of the first Julian day on file.
!     16 Jun 1998  Redder   Modified scale factor for the variables
!                           lat and lon
!     07 Jul 1998  Redder   Made minor corrections to the strings
!                           for the NetCDF global attributes,
!                           data_info and title.
!     11 Mar 1999  Redder   Made changes to store ODS observation
!                           attribute, ks (data sounding index), as
!                           a 4-byte instead of 2-byte integer. 
!                           The maximum acceptable value was
!                           increased from ~64,000 to ~1 billion.
!     15 Mar 1999  Redder   Added global attribute, type.
!     16 Feb 2000  Todling  Rename stdio.h to ods_stdio.h
!     16 Feb 2000  RT/CR    Added xvec observation attribute
!     04 Mar 2002  Redder   Changed the lower limit of the time attribute
!                           attribute by -60 min (to allow the raob launch
!                           time to be stored)
!     16 Sep 2002  Redder   Minor correction in name of attribute syn_beg
!     20 Jul 2005  RT/CR    Changed TimeMin to accommodate 10-day time window
!
!-------------------------------------------------------------------------

      include 'netcdf.inc'
      include 'ods_hdf.h'
      include 'ods_stdio.h'

*     dimension ids for ...
*     ---------------------
      integer     nbatchesdim ! number of batches of
                              !   observations stored in file
      integer     batchlendim ! length of each batch of
                              !   observations stored in file
      integer     nktdim      ! list of kt names and units
      integer     nkxdim      ! list of kx names
      integer     nqcxdim     ! meaning of each possible value of the
                              !   quality control exclusion mark
      integer     ndaysdim    ! numbers of days
      integer     nsyndim     ! number of synoptic times
      integer     strlendim   ! string length of kt and kx
                              !   names and units

*     scatch space for variable shapes (i.e. dimension )
*     --------------------------------------------------
      integer  dims   ( MAXNCDIM )

*     scratch space for attributes
*     ----------------------------
      integer   intval    (2)
      real      floatval  (2)
      character charstr * ( max_strlen )

*     functions referenced
*     --------------------
      integer     ODS_CalDat  ! Determine calender date in YYYYMMDD
                              !   format
      character * ( max_strlen )
     .            ODS_Case    ! Sets the case for a string
                              !   of characters
      integer     ODS_Handle  ! Obtains the ODS file handle id
      character * ( max_strlen )
     .            ODS_ParmC   ! Sets string  NetCDF file parameters
      integer     ODS_ParmI   ! Sets integer NetCDF file parameters
      real        ODS_ParmR   ! Sets floating point NetCDF file
                              !   parameters
      integer     ODS_StrSize ! Returns the character string length
                              !   excluding trailing blanks
      character * ( max_strlen )
     .            ODS_VerTag  ! Returns the character string length
                              !   excluding trailing blanks

*     Other variables
*     ---------------
      integer  NameSz         ! number of characters in filename
      integer  DimSz          ! temporary storage for NetCDF
                              !   dimension size
      integer  nc_id          ! temporary storage for NetCDF
                              !   file id
      integer  varid          ! temporary storage for NetCDF
                              !   variable id
      integer  charstrsz      ! string length for character
                              !   string attribute
      integer  type_strlen    ! string length for ODS type
                              !   attribute
      integer  version_strlen ! string length for version
                              !   attribute
      character * ( 20 )      ! temporary storage for the input
     .         ods__type      !   parameter, ods_type
      integer  nkt            ! temporary storage for the
                              !   dimension, nkt
      integer  nkx            ! temporary storage for the
                              !   dimension, nkx
      integer  nqcx           ! temporary storage for the
                              !   dimension, nqcx
      integer  ndayz          ! temporary storage for the
                              !   dimension, ndays
      integer  n_syn          ! temporary storage for the
                              !   dimension, nsyn
      integer  ierr_temp      ! temporary storage for the
                              !   returned error code
      integer  lstr           ! string length
      integer  TimeMin        ! minimum sample time

*.............................................................

*     Set ierr code to valid 
*     ----------------------
      ierr    = NCNoErr

*     Get the number of an used file handle
*     -------------------------------------
      id      = ODS_Handle ( filename, ierr )
      if ( ierr .ne. NCNoErr ) return

*     ensure that any character element in the string
*     parameter, ods_type, are in lower case
*     -----------------------------------------------
      ods__type = ODS_Case ( ods_type, 'lower' )

*     Give full name to ods file type.
*     If ods type is not valid, return
*     --------------------------------
      if      ( ods__type ( :8 ) .eq. 'pre_anal'  ) then
         ods__type = 'pre_analysis'

      else if ( ods__type ( :9 ) .eq. 'post_anal' ) then
         ods__type = 'post_analysis'

      else
         write ( stderr, * )
         write ( stderr, * )
     .    ' ODS_NCCreate: not a valid ods type: ',
     .                    ods__type
         ierr = NCEInVal
         return

      end if 

*     Set error message flag to ON    ( i.e. prints error mesages )
*     and the fatal error flag to OFF ( i.e. errors are not fatal )
*     -------------------------------------------------------------
      call ncpopt ( NCVERBOS )          ! verbose mode

*     Enter define mode and use NetCDF routines to set the
*     structure and contents of the ODS/HDF file in terms of
*     the CDL
*     ------------------------------------------------------
      nc_id             = nccre ( filename, NCCLOB, ierr )
      if ( ierr .ne. NCNoErr ) return

*     Store important file information in common
*     ------------------------------------------
      ncid      ( id )  = nc_id
      IOMode    ( id )  = NCWRITE
      filenames ( id )  = filename

*     From this point on, if an error is detected then perform
*     clean up operations before exiting this routine
*     --------------------------------------------------------

*     define NetCDF dimensions
*     ------------------------

*     nbatches - number of batches
*     ----------------------------
      nbatchesdim = ncddef  ( nc_id, 'nbatches', NCUNLIM,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     batchlen - size of each batch
*     -----------------------------
      DimSz       = ODS_ParmI      ( 'batchlen', Dbatchlen, ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      batchlendim = ncddef  ( nc_id, 'batchlen', DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     nkt - maximum value for the data type index
*     -------------------------------------------
      DimSz        = ODS_ParmI     ( 'nkt',      Dnkt,      ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nktdim       = ncddef ( nc_id, 'nkt',      DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nkt          = DimSz ! store this value for later access

*     nkx - maximum value for the data source index
*     ---------------------------------------------
      DimSz        = ODS_ParmI     ( 'nkx',      Dnkx,      ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nkxdim       = ncddef ( nc_id, 'nkx',      DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nkx          = DimSz ! store this value for later access

*     nqcx - maximum number of possible values for the
*            quality control exclusion mark (qcexcl)
*     ------------------------------------------------
      DimSz        = ODS_ParmI     ( 'nqcx',     Dnqcx,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nqcxdim      = ncddef ( nc_id, 'nqcx',     DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nqcx         = DimSz ! store this value for later access

*     ndays - maximum number of days stored in file
*     ---------------------------------------------
      DimSz        = ODS_ParmI     ( 'ndays',    Dndays,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      ndaysdim     = ncddef ( nc_id, 'ndays',    DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      ndayz        = DimSz ! store this value for later access

*     nsyn - number of synoptic times per day
*     ---------------------------------------
      DimSz        = ODS_ParmI     ( 'nsyn',     Dnsyn,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      nsyndim      = ncddef ( nc_id, 'nsyn',     DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      n_syn        = DimSz ! store this value for later access

*     strlen - the size of the string in each list entry
*     --------------------------------------------------
      DimSz        = ODS_ParmI     ( 'strlen',   Dstrlen,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      strlendim    = ncddef ( nc_id, 'strlen',   DimSz,     ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     Define NetDCF variables and their attributes for text
*     describing data types and souces currently available.
*     -----------------------------------------------------
*
*     note: Comments that begin with "*** attribute" refer
*           to NetCDF attributes
*     ----------------------------------------------------


*     kt_names for each GEOS/DAS data type index number
*     -------------------------------------------------
      dims  ( 1 ) = strlendim
      dims  ( 2 ) = nktdim
      varid       = ncvdef (  nc_id, 'kt_names',  NCCHAR,  2,
     .                        dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid, 'name',     NCCHAR,  27,
     .             'Name of GEOS/DAS data types',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     kt_units - unit for each GEOS/DAS data type index number
*     --------------------------------------------------------
      dims  ( 1 ) = strlendim
      dims  ( 2 ) = nktdim
      varid       = ncvdef (  nc_id, 'kt_units',  NCCHAR,  2,
     .                        dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,    varid, 'name',      NCCHAR,  33,
     .             'Units for each GEOS/DAS data type',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     kx_names - name for each GEOS/DAS data source index number
*     ----------------------------------------------------------
      dims  ( 1 ) = strlendim
      dims  ( 2 ) = nkxdim
      varid       = ncvdef (  nc_id, 'kx_names',  NCCHAR,  2,
     .                        dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,    varid, 'name',      NCCHAR,  29,
     .             'Name of GEOS/DAS data sources',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     kx_meta - kx specific metadata information
*     ------------------------------------------
      dims  ( 1 ) = strlendim
      dims  ( 2 ) = nkxdim
      varid       = ncvdef (  nc_id, 'kx_meta',   NCCHAR,  2,
     .                        dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,    varid, 'name',      NCCHAR,  32,
     .             'kx specific metadata information',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     qcx_names - meaning of each possible value of the
*                 quality control exclusion mark
*     -------------------------------------------------
      dims  ( 1 ) = strlendim
      dims  ( 2 ) = nqcxdim
      varid       = ncvdef (  nc_id, 'qcx_names', NCCHAR,  2,
     .                        dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      charstr     =  'Meaning of each possible value of '
     .            // 'the quality control exclusion mark'
      charstrsz   = ODS_StrSize ( charstr )
      call ncaptc ( nc_id,    varid, 'name',      NCCHAR,
     .              charstrsz,
     .              charstr ( : charstrsz ),
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     end of text describing data types and souces
*     --------------------------------------------

*     For every NetCDF variable defined below with the
*     NetCDF dimension nbatches, the data will be read
*     and/or written in batches. That is each batch
*     contains a subset of the values to be processed.
*     The maximum size of each subset is dbatchlen as
*     defined in the header file, ods_hdf.h or possibly a
*     user specified number.  (through the use of the
*     routines, ODS_SetParmI and ODS_ParmI ) The values
*     are being processed in this manner in order to
*     prevent the execution of the NetCDF library routines
*     from being prohibitively slow, especially when
*     read/writing in HDF format.  However, the number of
*     values that can be stored in the file remains
*     unlimited since the NetCDF dimension nbatches will
*     be set to unlimited.
*     ---------------------------------------------------

*     Define NetDCF variables and their attributes for
*     space-time coordinates including ...
*     ------------------------------------------------
*
*     note: Comments that begin with "*** attribute" refer
*           to NetCDF attributes
*     ----------------------------------------------------

*     latitude
*     --------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'lat',       NCSHORT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,   8,
     .             'Latitude',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - units are degrees north
*     ---------------------------------------
      call ncaptc ( nc_id,     varid,  'units',        NCCHAR,  13,
     .             'degrees north',
     .              ierr)
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range is from -90 to 90
*     ---------------------------------------------
      floatval    ( 1 ) = -90
      floatval    ( 2 ) =  90
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'valid_range',  NCFLOAT,  2,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - scale factor selected to maximize resolution
*                     when stored as a two byte integer
*     ------------------------------------------------------------
c      floatval    ( 1 ) =  90.0 / ( 2.0 ** 15 - 1.0 )
      floatval    ( 1 ) =  1.0 / 100.0
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'scale_factor', NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801


*     longitude
*     ---------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'lon',       NCSHORT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,   9,
     .             'Longitude',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - units are degree east
*     -------------------------------------
      call ncaptc ( nc_id,     varid,  'units',        NCCHAR,  12,
     .             'degrees east',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801


*     *** attribute - value at 90 degrees east is 90.0
*     ------------------------------------------------
      floatval    ( 1 ) =   90
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'value_at_90E', NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - value at 90 degrees west is -90.0
*     -------------------------------------------------
      floatval    ( 1 ) =  -90
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'value_at_90W', NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range is from -180 to 180 degrees
*     -------------------------------------------------------
      floatval    ( 1 ) = -180
      floatval    ( 2 ) =  180
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'valid_range',  NCFLOAT,  2,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - scale factor selected to maximize resolution
*                     when stored as a two byte integer
*     ------------------------------------------------------------
c      floatval    ( 1 ) =  180.0 / ( 2.0 ** 15 - 1.0 )
      floatval    ( 1 ) =  1.0 / 100.0d0
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'scale_factor', NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     level
*     -----
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'lev',       NCFLOAT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  25,
     .             'Pressure level or channel',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - units are hPa or none
*                    (for satellite channel numbers ) 
*     -----------------------------------------------
      call ncaptc ( nc_id,     varid,  'units',        NCCHAR,  11,
     .             'hPa or none',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801


*     time - minutes since 0:00 GMT of first julian day on file
*     ---------------------------------------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'time',      NCSHORT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  50,
     .        'minutes since 0:00 GMT of first julian day on file',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - units in minutes since first julian day on
*                     file ( in COARDS; e.g. 1992-10-8 00:00:00.0 )
*     -------------------------------------------------------------
      intval ( 1 )      =  ODS_CalDat ( first_jday )
      intval ( 2 )      =  0
      call ODS_COARDS ( intval ( 1 ), intval ( 2 ), charstr, ierr )
      charstr           = 'minutes since ' // charstr
      charstrsz         =  ODS_StrSize ( charstr )
      call ncaptc ( nc_id,     varid,  'units',        NCCHAR,
     .              charstrsz,
     .              charstr ( : charstrsz ),
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - add offset which is selected to double
*                     the range without exceeding the limits
*                     of a two byte integer
*     --------------------------------------------------------
c      TimeMin           =  -1440 / ( 2 * n_syn ) - 60
!     TimeMin           =  -1440 / n_syn - 60
      TimeMin           =  -14400
      intval      ( 1 ) =  2 ** 15 - 1 + TimeMin
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'add_offset',   NCLONG,   1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range as determined by the limits
*                     of a two byte integer
*     -------------------------------------------------------
      intval      ( 1 ) =  TimeMin
      intval      ( 2 ) =  2 ** 16 - 2 + TimeMin
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'valid_range',  NCLONG,   2,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     end of space-time coordinates
*     -----------------------------

*     Define NetDCF variables and their attributes for
*     data types and sources including ...
*     ------------------------------------------------
*
*     note: Comments that begin with "*** attribute" refer
*           to NetCDF attributes
*     ----------------------------------------------------

*     kt - GEOS/DAS data type
*     -----------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'kt',        NCBYTE,   2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  15,
     .             'Data type index',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - add offset set to 1
*     -----------------------------------
      intval      ( 1 ) =  1
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'add_offset',   NCLONG,   1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

c      intval      ( 1 ) =  2
c      call ODS_NCAPTI
c     .            ( nc_id,     varid,  'scale_factor', NCLONG,  1,
c     .              intval,    ierr )
c      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range that depends on the dimension nkt
*     -------------------------------------------------------------
      intval      ( 1 ) =  1
      intval      ( 2 ) =  nkt
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'valid_range',  NCLONG,   2,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     kx - GEOS/DAS data source
*     -------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'kx',        NCSHORT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,   17,
     .             'Data source index',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - add offset which is selected to double
*                     the range without exceeding the limits
*                     of a two byte integer
*     --------------------------------------------------------
      intval      ( 1 ) =  2 ** 15
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'add_offset',   NCLONG,   1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range that depends on the dimension nkx
*     -------------------------------------------------------------
      intval      ( 1 ) =  1
      intval      ( 2 ) =  nkx
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'valid_range',  NCLONG,   2,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     ks - GEOS/DAS sounding index
*     ----------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'ks',        NCLONG,   2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  14,
     .             'Sounding index',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - add offset which is selected to double
*                     the range without exceeding the limits
*                     of a two byte integer
*     --------------------------------------------------------
      intval      ( 1 ) =  0
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'add_offset',   NCLONG,   1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range as determined by the limits
*                     of a two byte integer
*     -------------------------------------------------------
      intval      ( 1 ) =  1
      intval      ( 2 ) =  2 ** 30
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'valid_range',  NCLONG,   2,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     xm - GEOS/DAS metadata index
*     ----------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'xm',        NCFLOAT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,   8,
     .             'Metadata',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - missing value set to DAO standard
*     -------------------------------------------------
      floatval    ( 1 ) =  missing_ob
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'missing_value',NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801


*     end of data types and sources
*     -----------------------------

*     Define NetDCF variables and their attributes for
*     observations values
*     ------------------------------------------------
*
*     note: Comments that begin with "*** attribute" refer
*           to NetCDF attributes
*     ----------------------------------------------------

*     obs - observation
*     -----------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'obs',       NCFLOAT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  17,
     .             'Observation value',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - missing value set to DAO standard
*                   ( see header file, ods_hdf.h )
*     -------------------------------------------------
      floatval    ( 1 ) =  missing_ob
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'missing_value',NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     Define the variables, omf and oma, only if the 
*     the ods type is set to 'post_nal'
*     ----------------------------------------------
      if ( ods__type ( 1:9 ) .eq. 'post_anal' ) then

*     omf - observation minus forecast
*     --------------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'omf',       NCFLOAT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  29,
     .             'Observation minus 6h forecast',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - missing value set to DAO standard
*                   ( see header file, ods_hdf.h )
*     -------------------------------------------------
      floatval    ( 1 ) =  missing_ob
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'missing_value',NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     oma - observation minus analysis
*     --------------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'oma',       NCFLOAT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  26,
     .             'Observation minus analysis',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - missing value set to DAO standard
*                   ( see header file, ods_hdf.h )
*     -------------------------------------------------
      floatval    ( 1 ) =  missing_ob
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'missing_value',NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801


*     xvec - PSAS CG solution vector
*     ------------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'xvec',      NCFLOAT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  23,
     .             'PSAS CG solution vector',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - missing value set to DAO standard
*                   ( see header file, ods_hdf.h )
*     -------------------------------------------------
      floatval    ( 1 ) =  missing_ob
      call ODS_NCAPTR
     .            ( nc_id,     varid,  'missing_value',NCFLOAT,  1,
     .              floatval,  ierr )
      if ( ierr .ne. NCNoErr ) go to 801


      end if
*     ------

*     Define NetDCF variables and their attributes for
*     quality control flags including ...
*     ------------------------------------------------
*
*     note: Comments that begin with "*** attribute" refer
*           to NetCDF attributes
*     ----------------------------------------------------

*     qcexcl - quality control exclusion mark
*     ---------------------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'qcexcl',    NCBYTE,   2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  30,
     .             'Quality control exclusion mark',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range as determined by the limits
*                     of a one byte integer
*     -------------------------------------------------------
      intval      ( 1 ) =  0
      intval      ( 2 ) =  2 ** 8 - 1
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'valid_range',  NCLONG,   2,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801


*     qchist - quality control history mark
*     -------------------------------------
      dims        ( 1 ) = batchlendim
      dims        ( 2 ) = nbatchesdim
      varid             = ncvdef ( nc_id, 'qchist',    NCSHORT,  2,
     .                             dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  28,
     .             'Quality control history mark',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - add offset which is selected to double
*                     the range without exceeding the limits
*                     of a one byte integer
*     ------------------------------------------------------
      intval      ( 1 ) =  2 ** 15 - 1
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'add_offset',    NCLONG,  1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range as determined by the limits
*                     of a one byte integer
*     -------------------------------------------------------
      intval      ( 1 ) =  0
      intval      ( 2 ) =  2 ** 16 - 2
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'valid_range',   NCLONG,  2,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     modification flag
*     -----------------
c      dims        ( 1 ) = batchlendim
c      dims        ( 2 ) = nbatchesdim
c      varid             = ncvdef ( nc_id, 'mod_flag',  NCBYTE,  2,
c     .                             dims,   ierr )
c      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
c      call ncaptc ( nc_id,     varid,  'name',         NCCHAR, 17,
c     .             'Modification flag',
c     .              ierr )
c      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - add offset which is selected to double
*                     the range without exceeding the limits
*                     of a two byte integer
*    -------------------------------------------------------
c      intval      ( 1 ) =  0
c      call ODS_NCAPTI
c     .            ( nc_id,     varid,  'add_offset',   NCLONG,  1,
c     .              intval,    ierr )
c      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - valid range as determined by the limits
*                     of a one byte integer
*     -------------------------------------------------------
c      intval      ( 1 ) =  0
c      intval      ( 2 ) =  255
c      call ODS_NCAPTI
c     .            ( nc_id,     varid,  'valid_range',  NCLONG,  2,
c     .              intval,    ierr )
c      if ( ierr .ne. NCNoErr ) go to 801


*     end of quality control flags
*     ----------------------------

*     Define NetDCF variables and their attributes for
*     Tables of pointers including ...
*     ------------------------------------------------
*
*     note: Comments that begin with "*** attribute" refer
*           to NetCDF attributes
*     ----------------------------------------------------

*     days
*     ----
      dims         ( 1 ) = ndaysdim
      varid              = ncvdef ( nc_id, 'days',     NCLONG,   1,
     .                              dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     syn_beg
*     -------
      dims         ( 1 ) = nsyndim
      dims         ( 2 ) = ndaysdim
      varid              = ncvdef ( nc_id, 'syn_beg',  NCLONG,   2,
     .                              dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  39,
     .             'Beginning of synoptic hour for each day',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - reference date which must be identical 
*                     to the same attribute for the variable,
*                     julian.  Thus, the date can be identified
*                     by using either one of two parameter names.
*     -----------------------------------------------------------
      charstr            =  ODS_ParmC ( 'julian:reference_date',
     .                                   Dref_date, ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      charstr            =  ODS_ParmC ( 'syn_beg:reference_date',
     .                                   charstr,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      charstrsz          =  index ( charstr, ' ' ) - 1
      if ( charstrsz .le. 0 ) charstrsz = len ( charstr )
      call ncaptc ( nc_id,     varid,           'reference_date', 
     .              NCCHAR,
     .              charstrsz,
     .              charstr ( 1 : charstrsz ),
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - the julian day at the reference date 
*                     which must be identical to the same
*                     attribute for the variable, julian.
*                     Thus, this attribute can be identified
*                     by using either one of two parameter
*                     names.
*     ---------------------------------------------------
      intval       ( 1 ) =  ODS_ParmI
     .                       (  'julian:value_at_reference_date',
     .                          Dref_jday, ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      intval       ( 1 ) =  ODS_ParmI
     .                       ( 'syn_beg:value_at_reference_date',
     .                          intval,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      call ODS_NCAPTI 
     .            ( nc_id,     varid,  'value_at_reference_date', 
     .              NCLONG,    1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - julian day corresponding to the first
*                     block of data in the file
*     -----------------------------------------------------
      intval       ( 1 ) = first_jday
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'first_julian_day',
     .              NCLONG,    1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - julian day corresponding to the last
*                     block of data written to file
*     ----------------------------------------------------
      intval      ( 1 )  =  first_jday - 1
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'latest_julian_day',
     .              NCLONG,    1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - synoptic hour corresponding to the
*                     last block of data written to file
*     --------------------------------------------------
      intval      ( 1 )  =  0
      call ODS_NCAPTI
     .            ( nc_id,     varid,  'latest_synoptic_hour',  
     .               NCLONG,   1,
     .              intval,    ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     syn_len
*     -------
      dims       (  1 )  = nsyndim
      dims       (  2 )  = ndaysdim
      varid              = ncvdef ( nc_id, 'syn_len',   NCLONG,  2,
     .                              dims,   ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     *** attribute - name
*     --------------------
      call ncaptc ( nc_id,     varid,  'name',         NCCHAR,  36,
     .             'Number of observations for syn. time',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     end of pointers
*     ---------------

*     end of definitions of NetCDF variables and their attributes
*     -----------------------------------------------------------

*     define NetCDF global attributes for ...
*     ---------------------------------------

*     source of this ODS data file
*     ----------------------------
      call ncaptc ( nc_id,  NCGLOBAL,  'source',       NCCHAR,  62,
     .             'Global Modeling and Assimilation Office, Code 910.3, NASA/GSFC',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     title of the data file
*     ----------------------
      call ncaptc ( nc_id,  NCGLOBAL,  'title',        NCCHAR,  45,
     .             'GEOS DAS Observational Data Stream (ODS) File',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     ODS type
*     --------
      type_strlen = ODS_StrSize ( ods__type )
      call ncaptc ( nc_id,  NCGLOBAL,  'type',         NCCHAR,
     .              type_strlen,
     .              ods__type ( 1:type_strlen ),
     .              ierr ) 
      if ( ierr .ne. NCNoErr ) go to 801

*     ODS version number
*     ------------------
      charstr        = ODS_VerTag ( 0, ierr )
      if ( ierr .ne. NCNoErr ) go to 801
      version_strlen = ODS_StrSize ( charstr )
      call ncaptc ( nc_id,  NCGLOBAL,  'version',      NCCHAR,
     .              version_strlen,
     .              charstr ( 1:version_strlen ),
     .              ierr ) 
      if ( ierr .ne. NCNoErr ) go to 801

*     email address
*     -------------
      call ncaptc ( nc_id,  NCGLOBAL,  'data_info',    NCCHAR,  31,
     .             'Contact data@gmao.gsfc.nasa.gov',
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     history tag
*     -----------
      history               = ' '
      call ncaptc ( nc_id,  NCGLOBAL,  'history',      NCCHAR,
     .              max_strlen,
     .              history,
     .              ierr )
      if ( ierr .ne. NCNoErr ) go to 801

*     end of global attributes
*     ------------------------

*     leave define mode
*     -----------------
      call ncendf ( nc_id, ierr)
      if ( ierr .ne. NCNoErr ) go to 801

*     Intialize pointers ( stored in common )
*     ---------------------------------------
      call ODS_ReSetP ( id, ierr )
      if ( ierr .ne. NCNoErr ) go to 802

*     Leave file open for writing
*     ---------------------------

      return
*     ------

*     Clean up by deleting the file and
*     setting io mode to CLOSED
*     ---------------------------------
 801  continue
      call ncabor ( nc_id, ierr_temp )
      IOMode ( id ) = CLOSED

      return
*     ------

*     Clean up by closing the file and
*     setting io mode to CLOSED
*     --------------------------------
 802  continue
      call ncclos ( nc_id, ierr_temp )
      IOMode ( id ) = CLOSED

      return
*     ------

      end