! DART software - Copyright UCAR. This open source software is provided
! by UCAR, "as is", without charge, subject to all terms of use at
! http://www.image.ucar.edu/DAReS/DART/DART_download
!
! $Id$

!----------------------------------------------------------------------
! WARNING!!  The file obs_kind_mod.f90 is AUTOGENERATED by the
! 'preprocess' program.  Any changes made to this file will be
! overwritten when it is regenerated.  To make permanent changes
! in the code, edit DEFAULT_obs_kind_mod.F90, or edit the
! observation specific obs_def_xxx_mod.f90 files.
!----------------------------------------------------------------------

module obs_kind_mod

use        types_mod, only : obstypelength
use    utilities_mod, only : register_module, error_handler, E_ERR, E_WARN,  &
                             logfileunit, find_namelist_in_file,             &
                             check_namelist_read, do_output, ascii_file_format

implicit none
private

public :: get_name_for_type_of_obs,       &
          assimilate_this_type_of_obs,    &
          evaluate_this_type_of_obs,      &
          get_quantity_for_type_of_obs,   &
          get_index_for_type_of_obs,      &
          write_type_of_obs_table,        &
          read_type_of_obs_table,         &
          get_type_of_obs_from_menu,      &
          map_type_of_obs_table,          &
          use_ext_prior_this_type_of_obs, &
          get_name_for_quantity,          &
          get_index_for_quantity

! Added by nsc to try to limit the number of global vars exported from
! this program.  i do not like this terminology, but since we are still
! using kind where we mean type, raw kind is as good a solution as anything.
! when i get permission to change public interfaces (next significant public
! release of the code), all kinds will become types, and raw_kind will become
! plain kind.  or i'll dump type/kind altogether and go to specific/generic
! or some other pair without this long history.
public :: get_num_types_of_obs, get_num_quantities

!----------------------------------------------------------------------------
! Note: this list is currently maintained by hand; new kinds must be added
! to the DEFAULT_obs_kind_mod.F90 file and then the preprocess program must
! be rerun to generate a obs_kind_mod.f90 file for use by the rest of the
! DART system.  Future versions of the preprocess program will be able to
! generate this table automatically.

!>@todo FIXME: replace this list with a formatted comment
!>and have an input to preprocess have a kinds type include list.
!>it can default to 'all' but it could be grouped by atmosphere,
!>ocean, land, chemistry, etc?  if you ignore duplicates, these
!>could be overlapping groups of any resolution you want.
!
! Definition and public access to the observation types/kinds
! Unique index values associated with each observation type and
! kind strings are defined here.

integer, parameter, public :: &
    QTY_STATE_VARIABLE              = 0, &
    QTY_U_WIND_COMPONENT            = 1, &
    QTY_V_WIND_COMPONENT            = 2, &
    QTY_SURFACE_PRESSURE            = 3, &
    QTY_TEMPERATURE                 = 4, &
    QTY_SPECIFIC_HUMIDITY           = 5, &
    QTY_PRESSURE                    = 6, &
    QTY_VERTICAL_VELOCITY           = 7, &
    QTY_RAINWATER_MIXING_RATIO      = 8, &
    QTY_DEWPOINT                    = 9, &
    QTY_DENSITY                     = 10, &
    QTY_VELOCITY                    = 11, &
    QTY_RADAR_REFLECTIVITY          = 12, &
    QTY_1D_INTEGRAL                 = 13, &
    QTY_GRAUPEL_MIXING_RATIO        = 14, &
    QTY_SNOW_MIXING_RATIO           = 15, &
    QTY_GPSRO                       = 16, &
    QTY_CLOUD_LIQUID_WATER          = 17, &
    QTY_CLOUD_ICE                   = 18, &
    QTY_CONDENSATIONAL_HEATING      = 19, &
    QTY_VAPOR_MIXING_RATIO          = 20, &
    QTY_ICE_NUMBER_CONCENTRATION    = 21, &
    QTY_GEOPOTENTIAL_HEIGHT         = 22, &
    QTY_POTENTIAL_TEMPERATURE       = 23, &
    QTY_SOIL_MOISTURE               = 24, &
    QTY_SURFACE_ELEVATION           = 25

! kinds for Gravity Wave Drag (CAM - kevin)
integer, parameter, public :: &
    QTY_GRAV_WAVE_DRAG_EFFIC        = 26, &
    QTY_GRAV_WAVE_STRESS_FRACTION   = 27

! kinds for simple advection model
integer, parameter, public :: &
    QTY_TRACER_SOURCE               = 28, &
    QTY_TRACER_CONCENTRATION        = 29, &
    QTY_MEAN_SOURCE                 = 30, &
    QTY_SOURCE_PHASE                = 31

! kind for power-weighted precipitation fall speed
! and a few other kinds that were missing from the
! collection of fractions and mixing ratio definitions.
! (CONCENTRATION -> CONCENTR because the max len of
! these strings is still 32 chars.)

! WARNING: the current models use
! QTY_CLOUD_LIQUID_WATER and QTY_CLOUD_ICE
! for mixing ratios.  because current models are
! using them, we can't make them consistent with
! the rest of the names - but in the next release
! we will be changing over to using mixing-ratio
! in the names and removing the old ones.
integer, parameter, public :: &
    QTY_POWER_WEIGHTED_FALL_SPEED   = 32, &
    QTY_CLOUDWATER_MIXING_RATIO     = 33, &
    QTY_ICE_MIXING_RATIO            = 34, &
    QTY_DROPLET_NUMBER_CONCENTR     = 35, &
    QTY_SNOW_NUMBER_CONCENTR        = 36, &
    QTY_RAIN_NUMBER_CONCENTR        = 37, &
    QTY_GRAUPEL_NUMBER_CONCENTR     = 38, &
    QTY_CLOUD_FRACTION              = 39, &
    QTY_ICE_FRACTION                = 40, &
    QTY_RELATIVE_HUMIDITY           = 41

! kinds for TIEgcm
integer, parameter, public :: &
    QTY_ELECTRON_DENSITY            = 42

! kinds for generic parameters that aren't going to be
! directly observed but are going to be adjusted by the
! assimilation.
integer, parameter, public :: &
    QTY_1D_PARAMETER                = 43, &
    QTY_2D_PARAMETER                = 44, &
    QTY_3D_PARAMETER                = 45

! kinds for CHAMP upper atmosphere computations
integer, parameter, public :: &
    QTY_ATOMIC_OXYGEN_MIXING_RATIO  = 46, &
    QTY_MOLEC_OXYGEN_MIXING_RATIO   = 47

! kinds for tendencies
integer, parameter, public :: &
    QTY_ALTIMETER_TENDENCY          = 48

! kind for precip water; contrast with
! total precip water (also in this file), 
! which is the total column integrated value. 
integer, parameter, public :: &
    QTY_PRECIPITABLE_WATER          = 49

! kinds for the MITgcm, POP ocean model
integer, parameter, public :: &
    QTY_SALINITY                    = 50, &
    QTY_U_CURRENT_COMPONENT         = 51, &
    QTY_V_CURRENT_COMPONENT         = 52, &
    QTY_SEA_SURFACE_HEIGHT          = 53, &
    QTY_DRY_LAND                    = 54, &
    QTY_SEA_SURFACE_PRESSURE        = 55, &
    QTY_W_CURRENT_COMPONENT         = 56

! proposed new kinds for COSMIC GPS/RO obs
! (currently unused)
integer, parameter, public :: &
    QTY_OCCULTATION_REFRACTIVITY    = 57, &
    QTY_OCCULTATION_EXCESSPHASE     = 58

! kind for the other way of measuring elevation
! contrast this with geopotential height
integer, parameter, public :: &
    QTY_GEOMETRIC_HEIGHT            = 59

! kinds for satellite radiances (jason o.)
integer, parameter, public :: &
    QTY_INFRARED_RADIANCE           = 60, &
    QTY_INFRARED_BRIGHT_TEMP        = 61, &
    QTY_LANDMASK                    = 62

! kind for unstructured grids
integer, parameter, public :: &
    QTY_EDGE_NORMAL_SPEED           = 63

! kind for cloud liquid water path
! see also kinds 363, 364
integer, parameter, public :: &
    QTY_CLW_PATH                    = 64

! kind for wind power
integer, parameter, public :: &
    QTY_WIND_TURBINE_POWER          = 65

! kinds for surface fields
integer, parameter, public :: &
    QTY_2M_SPECIFIC_HUMIDITY        = 66, &
    QTY_2M_TEMPERATURE              = 67, &
    QTY_10M_U_WIND_COMPONENT        = 68, &
    QTY_10M_V_WIND_COMPONENT        = 69

! kinds for planetary remote sensing (wglawson, c.lee)
integer, parameter, public :: &
    QTY_SKIN_TEMPERATURE            = 70, &
    QTY_NADIR_RADIANCE              = 71, &
    QTY_TRACER_1_MIXING_RATIO       = 72, &  ! for active dust aerosols
    QTY_TRACER_2_MIXING_RATIO       = 73, &  ! for active dust aerosols
    ! Is QTY_TRACER_MIXING_RATIO necessary with QTY_TRACER_CONCENTRATION
    !   (= 29) available from the simple advection model?
    QTY_SOIL_TEMPERATURE            = 74, &  ! missing from WRF model_mod (?)
    QTY_SOIL_LIQUID_WATER           = 75     ! missing from WRF model_mod (?)

! kinds for NCOMMAS  (Lou W., Ted M.)
integer, parameter, public :: &
    QTY_VERTICAL_VORTICITY          = 76

! more kinds for planetary remote sensing (c.lee)
integer, parameter, public :: &
    QTY_SURFACE_ALBEDO              = 77, &
    QTY_SURFACE_EMISSIVITY          = 78, &
    QTY_DUST_OPACITY_7MB            = 79, &
    QTY_THC                         = 80

! kinds for vortex tracking (WRF - yongsheng)
integer, parameter, public :: &
    QTY_VORTEX_LON                  = 81, &
    QTY_VORTEX_LAT                  = 82, &
    QTY_VORTEX_PMIN                 = 83, &
    QTY_VORTEX_WMAX                 = 84

! kinds for COAMPS (Tim Whitcomb)
integer, parameter, public :: &
    QTY_EXNER_FUNCTION              = 85, &
    QTY_TURBULENT_KINETIC_ENERGY    = 86, &
    QTY_TOTAL_PRECIPITABLE_WATER    = 87, & ! accumulated value - total water in a column
    QTY_VERTLEVEL                   = 88, &
    QTY_MICROWAVE_BRIGHT_TEMP       = 89

! kinds for NAAPS (Walter R. Sessions)
integer, parameter, public :: &
    QTY_INTEGRATED_SULFATE          = 90, &
    QTY_INTEGRATED_DUST             = 91, &
    QTY_INTEGRATED_SMOKE            = 92, &
    QTY_INTEGRATED_SEASALT          = 93, &
    QTY_INTEGRATED_AOD              = 94, &
    QTY_SO2                         = 95, &
    QTY_SULFATE                     = 96, &
    QTY_DUST                        = 97, &
    QTY_SMOKE                       = 98, &
    QTY_SEASALT                     = 99

! kinds for ZVD (advanced microphysics)
integer, parameter, public ::&
    QTY_HAIL_MIXING_RATIO           = 100, &
    QTY_HAIL_NUMBER_CONCENTR        = 101, &
    QTY_GRAUPEL_VOLUME              = 102, &
    QTY_HAIL_VOLUME                 = 103, &
    QTY_DIFFERENTIAL_REFLECTIVITY   = 104, &
    QTY_SPECIFIC_DIFFERENTIAL_PHASE = 105, &
    QTY_FLASH_RATE_2D               = 106

! kinds for CLM - Community Land Model (Tim Hoar)
! There will be lots of these ... perhaps leave some space ...
integer, parameter, public :: &
    QTY_SNOW_THICKNESS              = 107, &
    QTY_SNOW_WATER                  = 108, &
    QTY_SNOWCOVER_FRAC              = 109, &
    QTY_LIQUID_WATER                = 110, &
    QTY_ICE                         = 111, &
    QTY_CARBON                      = 112, &
    QTY_SOIL_CARBON                 = 113, &
    QTY_ROOT_CARBON                 = 114, &
    QTY_STEM_CARBON                 = 115, &
    QTY_LEAF_CARBON                 = 116, &
    QTY_LEAF_AREA_INDEX             = 117, &
    QTY_NET_CARBON_FLUX             = 118, &
    QTY_LATENT_HEAT_FLUX            = 119, &
    QTY_SENSIBLE_HEAT_FLUX          = 120, &
    QTY_RADIATION                   = 121, &
    QTY_NET_CARBON_PRODUCTION       = 122, &
    QTY_NITROGEN                    = 123, &
    QTY_SOIL_NITROGEN               = 124, &
    QTY_ROOT_NITROGEN               = 125, &
    QTY_STEM_NITROGEN               = 126, &
    QTY_LEAF_NITROGEN               = 127, &
    QTY_WATER_TABLE_DEPTH           = 128, &
    QTY_FPAR                        = 129, &
    QTY_TOTAL_WATER_STORAGE         = 130, &
    QTY_SNOW_TEMPERATURE            = 131, &
    QTY_SURFACE_RUNOFF              = 132, &
    QTY_UNDER_RUNOFF                = 133, &
    QTY_AQUIFER_WATER               = 134

! kinds for NOAH  (Tim Hoar)
integer, parameter, public :: &
    QTY_NEUTRON_INTENSITY           = 140, &
    QTY_CANOPY_WATER                = 141, &
    QTY_GROUND_HEAT_FLUX            = 142

! more kinds for TIEGCM Alex Chartier 
integer, parameter, public :: &
    QTY_VERTICAL_TEC                = 143, &
    QTY_O_N2_COLUMN_DENSITY_RATIO   = 144

!! For now we have agreed to reserve kind numbers 151 to 250
!! for chemistry types, specifically for WRF-Chem/DART, but
!! possibly of interest to other models with Chemistry species.
!! DO NOT USE numbers between 151-250 without talking to me, please?  (nancy)

! these chemistry kinds match the numbers Arthur Mizzi is using
integer, parameter, public :: &
    QTY_O3                          = 151, &
    QTY_CO                          = 153, &
    QTY_NO                          = 155, &
    QTY_NO2                         = 156

! more chemistry kinds (Jerome Barre)  (through 249)
integer, parameter, public :: &
    QTY_CO01                        = 161, &
    QTY_CO02                        = 162, &
    QTY_CO03                        = 163 

integer, parameter, public :: &
    QTY_SFCO                        = 170, &
    QTY_SFCO01                      = 171, &
    QTY_SFCO02                      = 172, &
    QTY_SFCO03                      = 173, &
    QTY_STATE_VAR_POWER             = 174


integer, parameter, public :: &
    QTY_AOD                         = 200, &
    QTY_CB1                         = 201, &
    QTY_CB2                         = 202, &
    QTY_OC1                         = 203, &
    QTY_OC2                         = 204, &
    QTY_CB102                       = 205, &
    QTY_CB202                       = 206, &
    QTY_OC102                       = 207, &
    QTY_OC202                       = 208

integer, parameter, public :: &

    QTY_SFCB1                       = 221, &
    QTY_SFCB2                       = 222, &
    QTY_SFOC1                       = 223, &
    QTY_SFOC2                       = 224, &
    QTY_SFCB102                     = 225, &
    QTY_SFCB202                     = 226, &
    QTY_SFOC102                     = 227, &
    QTY_SFOC202                     = 228

integer, parameter, public :: &
    QTY_CO2                         = 247, &
    QTY_NH3                         = 248, &
    QTY_CH4                         = 249

! kinds for GITM (Alexey Morozov)
integer, parameter, public :: &
  QTY_TEMPERATURE_ELECTRON          = 251, &
  QTY_TEMPERATURE_ION               = 252, &
  QTY_DENSITY_NEUTRAL_O3P           = 253, &
  QTY_DENSITY_NEUTRAL_O2            = 254, &
  QTY_DENSITY_NEUTRAL_N2            = 255, &
  QTY_DENSITY_NEUTRAL_N4S           = 256, &
  QTY_DENSITY_NEUTRAL_NO            = 257, &
  QTY_DENSITY_NEUTRAL_N2D           = 258, &
  QTY_DENSITY_NEUTRAL_N2P           = 259, &
  QTY_DENSITY_NEUTRAL_H             = 260, &
  QTY_DENSITY_NEUTRAL_HE            = 261, &
  QTY_DENSITY_NEUTRAL_CO2           = 262, &
  QTY_DENSITY_NEUTRAL_O1D           = 263, &
  QTY_DENSITY_ION_O4SP              = 264, &
  QTY_DENSITY_ION_O2P               = 265, &
  QTY_DENSITY_ION_N2P               = 266, &
  QTY_DENSITY_ION_NP                = 267, &
  QTY_DENSITY_ION_NOP               = 268, &
  QTY_DENSITY_ION_O2DP              = 269, &
  QTY_DENSITY_ION_O2PP              = 270, &
  QTY_DENSITY_ION_HP                = 271, &
  QTY_DENSITY_ION_HEP               = 272, &
  QTY_DENSITY_ION_E                 = 273, &
  QTY_VELOCITY_U                    = 274, &
  QTY_VELOCITY_V                    = 275, &
  QTY_VELOCITY_W                    = 276, &
  QTY_VELOCITY_U_ION                = 277, &
  QTY_VELOCITY_V_ION                = 278, &
  QTY_VELOCITY_W_ION                = 279, &
  QTY_VELOCITY_VERTICAL_O3P         = 280, &
  QTY_VELOCITY_VERTICAL_O2          = 281, &
  QTY_VELOCITY_VERTICAL_N2          = 282, &
  QTY_VELOCITY_VERTICAL_N4S         = 283, &
  QTY_VELOCITY_VERTICAL_NO          = 284, &
  QTY_GND_GPS_VTEC                  = 285, &
  QTY_DENSITY_ION_OP                = 286, &
  QTY_TOTAL_ELECTRON_COUNT          = 287

!! WRF_Hydro specific observations/states
integer, parameter, public :: &
  QTY_STREAM_FLOW                   = 290, &
  QTY_SURFACE_HEAD                  = 291, &
  QTY_DEEP_GROUNDWATER_LEVEL        = 292, &
  QTY_STREAM_HEIGHT                 = 293, &
  QTY_GROUND_SURF_TEMPERATURE       = 294, &
  QTY_CANOPY_TEMPERATURE            = 295, &
  QTY_BUCKET_MULTIPLIER             = 296, &
  QTY_RUNOFF_MULTIPLIER             = 297
 
! more land kinds
integer, parameter, public :: &
  QTY_BRIGHTNESS_TEMPERATURE        = 300, &
  QTY_VEGETATION_TEMPERATURE        = 301, &
  QTY_CANOPY_HEIGHT                 = 302, &
  QTY_FPAR_DIRECT                   = 303, &
  QTY_FPAR_DIFFUSE                  = 304, &
  QTY_FPAR_SUNLIT_DIRECT            = 305, &
  QTY_FPAR_SUNLIT_DIFFUSE           = 306, &
  QTY_FPAR_SHADED_DIRECT            = 307, &
  QTY_FPAR_SHADED_DIFFUSE           = 308, &
  QTY_FPSN                          = 309, &
  QTY_FSIF                          = 310

! kinds for CICE added by C. Bitz
integer, parameter, public :: &
  QTY_SEAICE_AGREG_CONCENTR         = 311, &  ! aggregate over categories
  QTY_SEAICE_AGREG_VOLUME           = 312, &
  QTY_SEAICE_AGREG_SNOWVOLUME       = 313, &
  QTY_SEAICE_AGREG_THICKNESS        = 314, &
  QTY_SEAICE_AGREG_SNOWDEPTH        = 315, &
  QTY_U_SEAICE_COMPONENT            = 316, &
  QTY_V_SEAICE_COMPONENT            = 317, &
  QTY_SEAICE_ALBEDODIRVIZ           = 318, &
  QTY_SEAICE_ALBEDODIRNIR           = 319, &
  QTY_SEAICE_ALBEDOINDVIZ           = 320, &
  QTY_SEAICE_ALBEDOINDNIR           = 321, &
  QTY_SEAICE_CONCENTR               = 322, &  ! for each category
  QTY_SEAICE_VOLUME                 = 323, &
  QTY_SEAICE_SNOWVOLUME             = 324, &
  QTY_SEAICE_SURFACETEMP            = 325, &
  QTY_SEAICE_FIRSTYEARAREA          = 326, &
  QTY_SEAICE_ICEAGE                 = 327, &
  QTY_SEAICE_LEVELAREA              = 328, &
  QTY_SEAICE_LEVELVOLUME            = 329, &
  QTY_SEAICE_MELTPONDAREA           = 330, &
  QTY_SEAICE_MELTPONDDEPTH          = 331, &
  QTY_SEAICE_MELTPONDLID            = 332, &
  QTY_SEAICE_MELTPONDSNOW           = 333, &
  QTY_SEAICE_SALINITY001            = 334, &   ! 00X refers to layer (ugh)
  QTY_SEAICE_SALINITY002            = 335, &
  QTY_SEAICE_SALINITY003            = 336, &
  QTY_SEAICE_SALINITY004            = 337, &
  QTY_SEAICE_SALINITY005            = 338, &
  QTY_SEAICE_SALINITY006            = 339, &
  QTY_SEAICE_SALINITY007            = 340, &
  QTY_SEAICE_SALINITY008            = 341, &
  QTY_SEAICE_ICEENTHALPY001         = 342, &
  QTY_SEAICE_ICEENTHALPY002         = 343, &
  QTY_SEAICE_ICEENTHALPY003         = 344, &
  QTY_SEAICE_ICEENTHALPY004         = 345, &
  QTY_SEAICE_ICEENTHALPY005         = 346, &
  QTY_SEAICE_ICEENTHALPY006         = 347, &
  QTY_SEAICE_ICEENTHALPY007         = 348, &
  QTY_SEAICE_ICEENTHALPY008         = 349, &
  QTY_SEAICE_SNOWENTHALPY001        = 350, &
  QTY_SEAICE_SNOWENTHALPY002        = 351, &
  QTY_SEAICE_SNOWENTHALPY003        = 352, &
  QTY_SOM_TEMPERATURE               = 353, &
  QTY_SEAICE_FY                     = 354, &
  QTY_SEAICE_AGREG_FY               = 355, &
  QTY_SEAICE_AGREG_SURFACETEMP      = 356, &
  QTY_SEAICE_AGREG_FREEBOARD        = 357, &
  QTY_SEAICE_CATEGORY               = 358

integer, parameter, public :: &
  QTY_SEA_SURFACE_ANOMALY           = 360

integer, parameter, public :: &
  QTY_LARGE_SCALE_STATE             = 361, &
  QTY_SMALL_SCALE_STATE             = 362

! see also CLW_PATH at 64
integer, parameter, public :: &
  QTY_CWP_PATH                      = 363, &
  QTY_CWP_PATH_ZERO                 = 364

! WACCM
integer, parameter, public :: &
  QTY_ION_O_MIXING_RATIO            = 365, &
  QTY_ATOMIC_H_MIXING_RATIO         = 366

! max_defined_quantities is private to this module.  see comment below near the max_obs_specific
! declaration for more info about publics and private values.

integer, parameter :: max_defined_quantities = 366

!----------------------------------------------------------------------------
! This list is autogenerated by the 'preprocess' program.  To add new
! observation types (e.g. AIRS_U_WIND_COMPONENT), edit the obs_def_x_mod.f90
! files and also add (or remove) them from the 'input_files' variable of
! the &preprocess_nml namelist in the model-specific work/input.nml file.

! Unique index values associated with each observation type string are
! are defined here. The total number of obs_types is also set in public
! parameter max_defined_types_of_obs.

! DART PREPROCESS INTEGER DECLARATION INSERTED HERE


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

! version controlled file description for error handling, do not edit
character(len=*), parameter :: source   = &
   "$URL$"
character(len=*), parameter :: revision = "$Revision$"
character(len=*), parameter :: revdate  = "$Date$"

logical, save :: module_initialized = .false.

!! max_defined_types_of_obs is really max_obs_types, and is generated by preprocess.

!! PRIVATE ONLY TO THIS MODULE.  max_defined_types_of_obs is really max_obs_types,
!! but since the original variable name is public it can't change without
!! being non-backwards compatible.  for now, punt on both type and kind
!! and start trying to use specific and generic (ok, which do map to type
!! and kind, respectively).  using intermediate names might make the transition
!! less painful.  right now, many(most) of the subroutine names or args
!! which are public are using 'kind' where it needs to be 'type'.
integer, parameter :: max_obs_specific = max_defined_types_of_obs

character(len=512) :: msg_string, msg_string1

integer :: num_kind_assimilate, num_kind_evaluate 
integer :: num_kind_use_precomputed_FOs

! Map from values of kind in obs_def to the fixed values in the list above.
! Initially, these are undefined and have values -1.
! For the first index 1, the value is the index in the input obs_sequence file.
! The first index 2 is the value of the corresponding index in this kind module.
integer :: map(2, max_obs_specific) = -1

! An observation kind type links together all the information required.
! An integer index that is also associated with the parameter above,
! A character string that has the same string as the parameter above,
! an integer that indicates what kind of variable type this is (for
! instance a radiosonde u wind component is a u wind component, but so
! is a 10 meter u wind component), and two logicals that indicate
! whether observations of this kind are to be assimilated, evaluated,
! or neither. Name lengths are limited to 32 characters by compiler
! restrictions on the length of parameter identifiers.
type obs_type_type
   integer              :: index
   character(len=obstypelength) :: name
   integer              :: generic_kind
   logical              :: assimilate
   logical              :: evaluate
   logical              :: use_precomputed_FO
end type obs_type_type

! An obs_type_type is defined by the preprocessor to store the association
! between obs_types, associated integer identifiers, the underlying kind,
! and whether observations of this type should be assimilate or evaluated.
type(obs_type_type) :: obs_type_info(max_obs_specific)

type obs_kind_type
   integer              :: index
   character(len=obstypelength) :: name
end type obs_kind_type

! An obs_kind_name_type is defined by the preprocess program to store
! the association between obs_kind index numbers and string names.
! raw is index 0, so this needs to match.  revisit the direct indexing
! since we have an index in the table -- redundant info?
type(obs_kind_type) :: obs_kind_names(0:max_defined_quantities)

! Namelist array to turn on any requested observation types
character(len=obstypelength) :: assimilate_these_obs_types(500) = 'null'
character(len=obstypelength) :: evaluate_these_obs_types(500) = 'null'
character(len=obstypelength) :: use_precomputed_FOs_these_obs_types(500) = 'null' 


namelist /obs_kind_nml/ assimilate_these_obs_types, evaluate_these_obs_types, &
                        use_precomputed_FOs_these_obs_types

contains

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

  subroutine initialize_module

integer :: iunit, io, i, j
character(len = 169) :: err_string

call register_module(source, revision, revdate)
module_initialized = .true.

! Read the namelist entry
call find_namelist_in_file("input.nml", "obs_kind_nml", iunit)
read(iunit, nml = obs_kind_nml, iostat = io)
call check_namelist_read(iunit, io, "obs_kind_nml")


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

! This list is autogenerated by the 'preprocess' program.  To add types
! or kinds, edit the obs_def_xxx_mod.f90 files, and then add/remove them
! from the 'input_files' variable of the &preprocess_nml namelist
! in the model-specific work/input.nml file.

! Table which associates the string type name with the index type value
! and the kind.  Default for all obs is to not assimilate or evaluate.

! DART PREPROCESS OBS_QTY_INFO INSERTED HERE

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

! this *should* be autogenerated; the next version of preprocess has code
! to do that.  but for now, hard code this table.  ugly.

do i = 0, max_defined_quantities
   obs_kind_names(i) = obs_kind_type(i, 'UNKNOWN')
enddo

obs_kind_names( 0) = obs_kind_type(QTY_STATE_VARIABLE, 'QTY_STATE_VARIABLE')
obs_kind_names( 1) = obs_kind_type(QTY_U_WIND_COMPONENT, 'QTY_U_WIND_COMPONENT')
obs_kind_names( 2) = obs_kind_type(QTY_V_WIND_COMPONENT, 'QTY_V_WIND_COMPONENT')
obs_kind_names( 3) = obs_kind_type(QTY_SURFACE_PRESSURE, 'QTY_SURFACE_PRESSURE')
obs_kind_names( 4) = obs_kind_type(QTY_TEMPERATURE, 'QTY_TEMPERATURE')
obs_kind_names( 5) = obs_kind_type(QTY_SPECIFIC_HUMIDITY, 'QTY_SPECIFIC_HUMIDITY')
obs_kind_names( 6) = obs_kind_type(QTY_PRESSURE, 'QTY_PRESSURE')
obs_kind_names( 7) = obs_kind_type(QTY_VERTICAL_VELOCITY, 'QTY_VERTICAL_VELOCITY')
obs_kind_names( 8) = obs_kind_type(QTY_RAINWATER_MIXING_RATIO, 'QTY_RAINWATER_MIXING_RATIO')
obs_kind_names( 9) = obs_kind_type(QTY_DEWPOINT, 'QTY_DEWPOINT')
obs_kind_names(10) = obs_kind_type(QTY_DENSITY, 'QTY_DENSITY')
obs_kind_names(11) = obs_kind_type(QTY_VELOCITY, 'QTY_VELOCITY')
obs_kind_names(12) = obs_kind_type(QTY_RADAR_REFLECTIVITY, 'QTY_RADAR_REFLECTIVITY')
obs_kind_names(13) = obs_kind_type(QTY_1D_INTEGRAL, 'QTY_1D_INTEGRAL')
obs_kind_names(14) = obs_kind_type(QTY_GRAUPEL_MIXING_RATIO, 'QTY_GRAUPEL_MIXING_RATIO')
obs_kind_names(15) = obs_kind_type(QTY_SNOW_MIXING_RATIO, 'QTY_SNOW_MIXING_RATIO')
obs_kind_names(16) = obs_kind_type(QTY_GPSRO, 'QTY_GPSRO')
obs_kind_names(17) = obs_kind_type(QTY_CLOUD_LIQUID_WATER, 'QTY_CLOUD_LIQUID_WATER')
obs_kind_names(18) = obs_kind_type(QTY_CLOUD_ICE, 'QTY_CLOUD_ICE')
obs_kind_names(19) = obs_kind_type(QTY_CONDENSATIONAL_HEATING, 'QTY_CONDENSATIONAL_HEATING')
obs_kind_names(20) = obs_kind_type(QTY_VAPOR_MIXING_RATIO, 'QTY_VAPOR_MIXING_RATIO')
obs_kind_names(21) = obs_kind_type(QTY_ICE_NUMBER_CONCENTRATION, 'QTY_ICE_NUMBER_CONCENTRATION')
obs_kind_names(22) = obs_kind_type(QTY_GEOPOTENTIAL_HEIGHT, 'QTY_GEOPOTENTIAL_HEIGHT')
obs_kind_names(23) = obs_kind_type(QTY_POTENTIAL_TEMPERATURE, 'QTY_POTENTIAL_TEMPERATURE')
obs_kind_names(24) = obs_kind_type(QTY_SOIL_MOISTURE, 'QTY_SOIL_MOISTURE')
obs_kind_names(25) = obs_kind_type(QTY_SURFACE_ELEVATION, 'QTY_SURFACE_ELEVATION')
obs_kind_names(26) = obs_kind_type(QTY_GRAV_WAVE_DRAG_EFFIC, 'QTY_GRAV_WAVE_DRAG_EFFIC')
obs_kind_names(27) = obs_kind_type(QTY_GRAV_WAVE_STRESS_FRACTION, 'QTY_GRAV_WAVE_STRESS_FRACTION')
obs_kind_names(28) = obs_kind_type(QTY_TRACER_SOURCE, 'QTY_TRACER_SOURCE')
obs_kind_names(29) = obs_kind_type(QTY_TRACER_CONCENTRATION, 'QTY_TRACER_CONCENTRATION')
obs_kind_names(30) = obs_kind_type(QTY_MEAN_SOURCE, 'QTY_MEAN_SOURCE')
obs_kind_names(31) = obs_kind_type(QTY_SOURCE_PHASE, 'QTY_SOURCE_PHASE')
obs_kind_names(32) = obs_kind_type(QTY_POWER_WEIGHTED_FALL_SPEED, 'QTY_POWER_WEIGHTED_FALL_SPEED')
obs_kind_names(33) = obs_kind_type(QTY_CLOUDWATER_MIXING_RATIO, 'QTY_CLOUDWATER_MIXING_RATIO')
obs_kind_names(34) = obs_kind_type(QTY_ICE_MIXING_RATIO, 'QTY_ICE_MIXING_RATIO')
obs_kind_names(35) = obs_kind_type(QTY_DROPLET_NUMBER_CONCENTR, 'QTY_DROPLET_NUMBER_CONCENTR')
obs_kind_names(36) = obs_kind_type(QTY_SNOW_NUMBER_CONCENTR, 'QTY_SNOW_NUMBER_CONCENTR')
obs_kind_names(37) = obs_kind_type(QTY_RAIN_NUMBER_CONCENTR, 'QTY_RAIN_NUMBER_CONCENTR')
obs_kind_names(38) = obs_kind_type(QTY_GRAUPEL_NUMBER_CONCENTR, 'QTY_GRAUPEL_NUMBER_CONCENTR')
obs_kind_names(39) = obs_kind_type(QTY_CLOUD_FRACTION, 'QTY_CLOUD_FRACTION')
obs_kind_names(40) = obs_kind_type(QTY_ICE_FRACTION, 'QTY_ICE_FRACTION')
obs_kind_names(41) = obs_kind_type(QTY_RELATIVE_HUMIDITY, 'QTY_RELATIVE_HUMIDITY')
obs_kind_names(42) = obs_kind_type(QTY_ELECTRON_DENSITY, 'QTY_ELECTRON_DENSITY')
obs_kind_names(43) = obs_kind_type(QTY_1D_PARAMETER, 'QTY_1D_PARAMETER')
obs_kind_names(44) = obs_kind_type(QTY_2D_PARAMETER, 'QTY_2D_PARAMETER')
obs_kind_names(45) = obs_kind_type(QTY_3D_PARAMETER, 'QTY_3D_PARAMETER')
obs_kind_names(46) = obs_kind_type(QTY_ATOMIC_OXYGEN_MIXING_RATIO, 'QTY_ATOMIC_OXYGEN_MIXING_RATIO')
obs_kind_names(47) = obs_kind_type(QTY_MOLEC_OXYGEN_MIXING_RATIO, 'QTY_MOLEC_OXYGEN_MIXING_RATIO')
obs_kind_names(48) = obs_kind_type(QTY_ALTIMETER_TENDENCY, 'QTY_ALTIMETER_TENDENCY')
obs_kind_names(49) = obs_kind_type(QTY_PRECIPITABLE_WATER, 'QTY_PRECIPITABLE_WATER')
obs_kind_names(50) = obs_kind_type(QTY_SALINITY, 'QTY_SALINITY')
obs_kind_names(51) = obs_kind_type(QTY_U_CURRENT_COMPONENT, 'QTY_U_CURRENT_COMPONENT')
obs_kind_names(52) = obs_kind_type(QTY_V_CURRENT_COMPONENT, 'QTY_V_CURRENT_COMPONENT')
obs_kind_names(53) = obs_kind_type(QTY_SEA_SURFACE_HEIGHT, 'QTY_SEA_SURFACE_HEIGHT')
obs_kind_names(54) = obs_kind_type(QTY_DRY_LAND, 'QTY_DRY_LAND')
obs_kind_names(55) = obs_kind_type(QTY_SEA_SURFACE_PRESSURE, 'QTY_SEA_SURFACE_PRESSURE')
obs_kind_names(56) = obs_kind_type(QTY_W_CURRENT_COMPONENT, 'QTY_W_CURRENT_COMPONENT')
obs_kind_names(57) = obs_kind_type(QTY_OCCULTATION_REFRACTIVITY, 'QTY_OCCULTATION_REFRACTIVITY')
obs_kind_names(58) = obs_kind_type(QTY_OCCULTATION_EXCESSPHASE, 'QTY_OCCULTATION_EXCESSPHASE')
obs_kind_names(59) = obs_kind_type(QTY_GEOMETRIC_HEIGHT, 'QTY_GEOMETRIC_HEIGHT')
obs_kind_names(60) = obs_kind_type(QTY_INFRARED_RADIANCE, 'QTY_INFRARED_RADIANCE')
obs_kind_names(61) = obs_kind_type(QTY_INFRARED_BRIGHT_TEMP, 'QTY_INFRARED_BRIGHT_TEMP')
obs_kind_names(62) = obs_kind_type(QTY_LANDMASK, 'QTY_LANDMASK')
obs_kind_names(63) = obs_kind_type(QTY_EDGE_NORMAL_SPEED, 'QTY_EDGE_NORMAL_SPEED')
obs_kind_names(64) = obs_kind_type(QTY_CLW_PATH, 'QTY_CLW_PATH')
obs_kind_names(65) = obs_kind_type(QTY_WIND_TURBINE_POWER, 'QTY_WIND_TURBINE_POWER')
obs_kind_names(66) = obs_kind_type(QTY_2M_SPECIFIC_HUMIDITY, 'QTY_2M_SPECIFIC_HUMIDITY')
obs_kind_names(67) = obs_kind_type(QTY_2M_TEMPERATURE, 'QTY_2M_TEMPERATURE')
obs_kind_names(68) = obs_kind_type(QTY_10M_U_WIND_COMPONENT, 'QTY_10M_U_WIND_COMPONENT')
obs_kind_names(69) = obs_kind_type(QTY_10M_V_WIND_COMPONENT, 'QTY_10M_V_WIND_COMPONENT')
obs_kind_names(70) = obs_kind_type(QTY_SKIN_TEMPERATURE, 'QTY_SKIN_TEMPERATURE')
obs_kind_names(71) = obs_kind_type(QTY_NADIR_RADIANCE, 'QTY_NADIR_RADIANCE')
obs_kind_names(72) = obs_kind_type(QTY_TRACER_1_MIXING_RATIO, 'QTY_TRACER_1_MIXING_RATIO')
obs_kind_names(73) = obs_kind_type(QTY_TRACER_2_MIXING_RATIO, 'QTY_TRACER_2_MIXING_RATIO')
obs_kind_names(74) = obs_kind_type(QTY_SOIL_TEMPERATURE, 'QTY_SOIL_TEMPERATURE')
obs_kind_names(75) = obs_kind_type(QTY_SOIL_LIQUID_WATER, 'QTY_SOIL_LIQUID_WATER')
obs_kind_names(76) = obs_kind_type(QTY_VERTICAL_VORTICITY, 'QTY_VERTICAL_VORTICITY')
obs_kind_names(77) = obs_kind_type(QTY_SURFACE_ALBEDO, 'QTY_SURFACE_ALBEDO')
obs_kind_names(78) = obs_kind_type(QTY_SURFACE_EMISSIVITY, 'QTY_SURFACE_EMISSIVITY')
obs_kind_names(79) = obs_kind_type(QTY_DUST_OPACITY_7MB, 'QTY_DUST_OPACITY_7MB')
obs_kind_names(80) = obs_kind_type(QTY_THC, 'QTY_THC')
obs_kind_names(81) = obs_kind_type(QTY_VORTEX_LON, 'QTY_VORTEX_LON')
obs_kind_names(82) = obs_kind_type(QTY_VORTEX_LAT, 'QTY_VORTEX_LAT')
obs_kind_names(83) = obs_kind_type(QTY_VORTEX_PMIN, 'QTY_VORTEX_PMIN')
obs_kind_names(84) = obs_kind_type(QTY_VORTEX_WMAX, 'QTY_VORTEX_WMAX')
obs_kind_names(85) = obs_kind_type(QTY_EXNER_FUNCTION, 'QTY_EXNER_FUNCTION')
obs_kind_names(86) = obs_kind_type(QTY_TURBULENT_KINETIC_ENERGY, 'QTY_TURBULENT_KINETIC_ENERGY')
obs_kind_names(87) = obs_kind_type(QTY_TOTAL_PRECIPITABLE_WATER, 'QTY_TOTAL_PRECIPITABLE_WATER')
obs_kind_names(88) = obs_kind_type(QTY_VERTLEVEL, 'QTY_VERTLEVEL')
obs_kind_names(89) = obs_kind_type(QTY_MICROWAVE_BRIGHT_TEMP, 'QTY_MICROWAVE_BRIGHT_TEMP')
obs_kind_names(90) = obs_kind_type(QTY_INTEGRATED_SULFATE, 'QTY_INTEGRATED_SULFATE')
obs_kind_names(91) = obs_kind_type(QTY_INTEGRATED_DUST, 'QTY_INTEGRATED_DUST')
obs_kind_names(92) = obs_kind_type(QTY_INTEGRATED_SMOKE, 'QTY_INTEGRATED_SMOKE')
obs_kind_names(93) = obs_kind_type(QTY_INTEGRATED_SEASALT, 'QTY_INTEGRATED_SEASALT')
obs_kind_names(94) = obs_kind_type(QTY_INTEGRATED_AOD, 'QTY_INTEGRATED_AOD')
obs_kind_names(95) = obs_kind_type(QTY_SO2, 'QTY_SO2')
obs_kind_names(96) = obs_kind_type(QTY_SULFATE, 'QTY_SULFATE')
obs_kind_names(97) = obs_kind_type(QTY_DUST, 'QTY_DUST')
obs_kind_names(98) = obs_kind_type(QTY_SMOKE, 'QTY_SMOKE')
obs_kind_names(99) = obs_kind_type(QTY_SEASALT, 'QTY_SEASALT')
obs_kind_names(100) = obs_kind_type(QTY_HAIL_MIXING_RATIO, 'QTY_HAIL_MIXING_RATIO')
obs_kind_names(101) = obs_kind_type(QTY_HAIL_NUMBER_CONCENTR, 'QTY_HAIL_NUMBER_CONCENTR')
obs_kind_names(102) = obs_kind_type(QTY_GRAUPEL_VOLUME, 'QTY_GRAUPEL_VOLUME')
obs_kind_names(103) = obs_kind_type(QTY_HAIL_VOLUME, 'QTY_HAIL_VOLUME')
obs_kind_names(104) = obs_kind_type(QTY_DIFFERENTIAL_REFLECTIVITY, 'QTY_DIFFERENTIAL_REFLECTIVITY')
obs_kind_names(105) = obs_kind_type(QTY_SPECIFIC_DIFFERENTIAL_PHASE, 'QTY_SPECIFIC_DIFFERENTIAL_PHASE')
obs_kind_names(106) = obs_kind_type(QTY_FLASH_RATE_2D, 'QTY_FLASH_RATE_2D')

obs_kind_names(107) = obs_kind_type(QTY_SNOW_THICKNESS        ,'QTY_SNOW_THICKNESS')
obs_kind_names(108) = obs_kind_type(QTY_SNOW_WATER            ,'QTY_SNOW_WATER')
obs_kind_names(109) = obs_kind_type(QTY_SNOWCOVER_FRAC        ,'QTY_SNOWCOVER_FRAC')
obs_kind_names(110) = obs_kind_type(QTY_LIQUID_WATER          ,'QTY_LIQUID_WATER')
obs_kind_names(111) = obs_kind_type(QTY_ICE                   ,'QTY_ICE')
obs_kind_names(112) = obs_kind_type(QTY_CARBON                ,'QTY_CARBON')
obs_kind_names(113) = obs_kind_type(QTY_SOIL_CARBON           ,'QTY_SOIL_CARBON')
obs_kind_names(114) = obs_kind_type(QTY_ROOT_CARBON           ,'QTY_ROOT_CARBON')
obs_kind_names(115) = obs_kind_type(QTY_STEM_CARBON           ,'QTY_STEM_CARBON')
obs_kind_names(116) = obs_kind_type(QTY_LEAF_CARBON           ,'QTY_LEAF_CARBON')
obs_kind_names(117) = obs_kind_type(QTY_LEAF_AREA_INDEX       ,'QTY_LEAF_AREA_INDEX')
obs_kind_names(118) = obs_kind_type(QTY_NET_CARBON_FLUX       ,'QTY_NET_CARBON_FLUX')
obs_kind_names(119) = obs_kind_type(QTY_LATENT_HEAT_FLUX      ,'QTY_LATENT_HEAT_FLUX')
obs_kind_names(120) = obs_kind_type(QTY_SENSIBLE_HEAT_FLUX    ,'QTY_SENSIBLE_HEAT_FLUX')
obs_kind_names(121) = obs_kind_type(QTY_RADIATION             ,'QTY_RADIATION')
obs_kind_names(122) = obs_kind_type(QTY_NET_CARBON_PRODUCTION ,'QTY_NET_CARBON_PRODUCTION')
obs_kind_names(123) = obs_kind_type(QTY_NITROGEN              ,'QTY_NITROGEN')
obs_kind_names(124) = obs_kind_type(QTY_SOIL_NITROGEN         ,'QTY_SOIL_NITROGEN')
obs_kind_names(125) = obs_kind_type(QTY_ROOT_NITROGEN         ,'QTY_ROOT_NITROGEN')
obs_kind_names(126) = obs_kind_type(QTY_STEM_NITROGEN         ,'QTY_STEM_NITROGEN')
obs_kind_names(127) = obs_kind_type(QTY_LEAF_NITROGEN         ,'QTY_LEAF_NITROGEN')
obs_kind_names(128) = obs_kind_type(QTY_WATER_TABLE_DEPTH     ,'QTY_WATER_TABLE_DEPTH')
obs_kind_names(129) = obs_kind_type(QTY_FPAR                  ,'QTY_FPAR')
obs_kind_names(130) = obs_kind_type(QTY_TOTAL_WATER_STORAGE   ,'QTY_TOTAL_WATER_STORAGE')
obs_kind_names(131) = obs_kind_type(QTY_SNOW_TEMPERATURE      ,'QTY_SNOW_TEMPERATURE')
obs_kind_names(132) = obs_kind_type(QTY_SURFACE_RUNOFF        ,'QTY_SURFACE_RUNOFF')
obs_kind_names(133) = obs_kind_type(QTY_UNDER_RUNOFF          ,'QTY_UNDER_RUNOFF')
obs_kind_names(134) = obs_kind_type(QTY_AQUIFER_WATER         ,'QTY_AQUIFER_WATER')

obs_kind_names(140) = obs_kind_type(QTY_NEUTRON_INTENSITY     ,'QTY_NEUTRON_INTENSITY')
obs_kind_names(141) = obs_kind_type(QTY_CANOPY_WATER          ,'QTY_CANOPY_WATER')
obs_kind_names(142) = obs_kind_type(QTY_GROUND_HEAT_FLUX      ,'QTY_GROUND_HEAT_FLUX')
obs_kind_names(143) = obs_kind_type(QTY_VERTICAL_TEC          ,'QTY_VERTICAL_TEC')
obs_kind_names(144) = obs_kind_type(QTY_O_N2_COLUMN_DENSITY_RATIO, 'QTY_O_N2_COLUMN_DENSITY_RATIO')

obs_kind_names(151) = obs_kind_type(QTY_O3,             'QTY_O3')
obs_kind_names(153) = obs_kind_type(QTY_CO,             'QTY_CO')
obs_kind_names(155) = obs_kind_type(QTY_NO,             'QTY_NO')
obs_kind_names(156) = obs_kind_type(QTY_NO2,            'QTY_NO2')

obs_kind_names(161) = obs_kind_type(QTY_CO01,           'QTY_CO01')
obs_kind_names(162) = obs_kind_type(QTY_CO02,           'QTY_CO02')
obs_kind_names(163) = obs_kind_type(QTY_CO03,           'QTY_CO03')

obs_kind_names(170) = obs_kind_type(QTY_SFCO,           'QTY_SFCO')
obs_kind_names(171) = obs_kind_type(QTY_SFCO01,         'QTY_SFCO01')
obs_kind_names(172) = obs_kind_type(QTY_SFCO02,         'QTY_SFCO02')
obs_kind_names(173) = obs_kind_type(QTY_SFCO03,         'QTY_SFCO03')
obs_kind_names(174) = obs_kind_type(QTY_STATE_VAR_POWER,'QTY_STATE_VAR_POWER')

obs_kind_names(200) = obs_kind_type(QTY_AOD,            'QTY_AOD')
obs_kind_names(201) = obs_kind_type(QTY_CB1,            'QTY_CB1')
obs_kind_names(202) = obs_kind_type(QTY_CB2,            'QTY_CB2')
obs_kind_names(203) = obs_kind_type(QTY_OC1,            'QTY_OC1')
obs_kind_names(204) = obs_kind_type(QTY_OC2,            'QTY_OC2')
obs_kind_names(205) = obs_kind_type(QTY_CB1,            'QTY_CB102')
obs_kind_names(206) = obs_kind_type(QTY_CB2,            'QTY_CB202')
obs_kind_names(207) = obs_kind_type(QTY_OC1,            'QTY_OC102')
obs_kind_names(208) = obs_kind_type(QTY_OC2,            'QTY_OC202')

obs_kind_names(221) = obs_kind_type(QTY_SFCB1,          'QTY_SFCB1')
obs_kind_names(222) = obs_kind_type(QTY_SFCB2,          'QTY_SFCB2')
obs_kind_names(223) = obs_kind_type(QTY_SFOC1,          'QTY_SFOC1')
obs_kind_names(224) = obs_kind_type(QTY_SFOC2,          'QTY_SFOC2')
obs_kind_names(225) = obs_kind_type(QTY_SFCB1,          'QTY_SFCB102')
obs_kind_names(226) = obs_kind_type(QTY_SFCB2,          'QTY_SFCB202')
obs_kind_names(227) = obs_kind_type(QTY_SFOC1,          'QTY_SFOC102')
obs_kind_names(228) = obs_kind_type(QTY_SFOC2,          'QTY_SFOC202')

obs_kind_names(247) = obs_kind_type(QTY_CO2,            'QTY_CO2')
obs_kind_names(248) = obs_kind_type(QTY_NH3,            'QTY_NH3')
obs_kind_names(249) = obs_kind_type(QTY_CH4,            'QTY_CH4')

obs_kind_names(251) = obs_kind_type(QTY_TEMPERATURE_ELECTRON  ,'QTY_TEMPERATURE_ELECTRON')
obs_kind_names(252) = obs_kind_type(QTY_TEMPERATURE_ION       ,'QTY_TEMPERATURE_ION')
obs_kind_names(253) = obs_kind_type(QTY_DENSITY_NEUTRAL_O3P   ,'QTY_DENSITY_NEUTRAL_O3P')
obs_kind_names(254) = obs_kind_type(QTY_DENSITY_NEUTRAL_O2    ,'QTY_DENSITY_NEUTRAL_O2')
obs_kind_names(255) = obs_kind_type(QTY_DENSITY_NEUTRAL_N2    ,'QTY_DENSITY_NEUTRAL_N2')
obs_kind_names(256) = obs_kind_type(QTY_DENSITY_NEUTRAL_N4S   ,'QTY_DENSITY_NEUTRAL_N4S')
obs_kind_names(257) = obs_kind_type(QTY_DENSITY_NEUTRAL_NO    ,'QTY_DENSITY_NEUTRAL_NO')
obs_kind_names(258) = obs_kind_type(QTY_DENSITY_NEUTRAL_N2D   ,'QTY_DENSITY_NEUTRAL_N2D')
obs_kind_names(259) = obs_kind_type(QTY_DENSITY_NEUTRAL_N2P   ,'QTY_DENSITY_NEUTRAL_N2P')
obs_kind_names(260) = obs_kind_type(QTY_DENSITY_NEUTRAL_H     ,'QTY_DENSITY_NEUTRAL_H')
obs_kind_names(261) = obs_kind_type(QTY_DENSITY_NEUTRAL_HE    ,'QTY_DENSITY_NEUTRAL_HE')
obs_kind_names(262) = obs_kind_type(QTY_DENSITY_NEUTRAL_CO2   ,'QTY_DENSITY_NEUTRAL_CO2')
obs_kind_names(263) = obs_kind_type(QTY_DENSITY_NEUTRAL_O1D   ,'QTY_DENSITY_NEUTRAL_O1D')
obs_kind_names(264) = obs_kind_type(QTY_DENSITY_ION_O4SP      ,'QTY_DENSITY_ION_O4SP')
obs_kind_names(265) = obs_kind_type(QTY_DENSITY_ION_O2P       ,'QTY_DENSITY_ION_O2P')
obs_kind_names(266) = obs_kind_type(QTY_DENSITY_ION_N2P       ,'QTY_DENSITY_ION_N2P')
obs_kind_names(267) = obs_kind_type(QTY_DENSITY_ION_NP        ,'QTY_DENSITY_ION_NP')
obs_kind_names(268) = obs_kind_type(QTY_DENSITY_ION_NOP       ,'QTY_DENSITY_ION_NOP')
obs_kind_names(269) = obs_kind_type(QTY_DENSITY_ION_O2DP      ,'QTY_DENSITY_ION_O2DP')
obs_kind_names(270) = obs_kind_type(QTY_DENSITY_ION_O2PP      ,'QTY_DENSITY_ION_O2PP')
obs_kind_names(271) = obs_kind_type(QTY_DENSITY_ION_HP        ,'QTY_DENSITY_ION_HP')
obs_kind_names(272) = obs_kind_type(QTY_DENSITY_ION_HEP       ,'QTY_DENSITY_ION_HEP')
obs_kind_names(273) = obs_kind_type(QTY_DENSITY_ION_E         ,'QTY_DENSITY_ION_E')
obs_kind_names(274) = obs_kind_type(QTY_VELOCITY_U            ,'QTY_VELOCITY_U')
obs_kind_names(275) = obs_kind_type(QTY_VELOCITY_V            ,'QTY_VELOCITY_V')
obs_kind_names(276) = obs_kind_type(QTY_VELOCITY_W            ,'QTY_VELOCITY_W')
obs_kind_names(277) = obs_kind_type(QTY_VELOCITY_U_ION        ,'QTY_VELOCITY_U_ION')
obs_kind_names(278) = obs_kind_type(QTY_VELOCITY_V_ION        ,'QTY_VELOCITY_V_ION')
obs_kind_names(279) = obs_kind_type(QTY_VELOCITY_W_ION        ,'QTY_VELOCITY_W_ION')
obs_kind_names(280) = obs_kind_type(QTY_VELOCITY_VERTICAL_O3P ,'QTY_VELOCITY_VERTICAL_O3P')
obs_kind_names(281) = obs_kind_type(QTY_VELOCITY_VERTICAL_O2  ,'QTY_VELOCITY_VERTICAL_O2')
obs_kind_names(282) = obs_kind_type(QTY_VELOCITY_VERTICAL_N2  ,'QTY_VELOCITY_VERTICAL_N2')
obs_kind_names(283) = obs_kind_type(QTY_VELOCITY_VERTICAL_N4S ,'QTY_VELOCITY_VERTICAL_N4S')
obs_kind_names(284) = obs_kind_type(QTY_VELOCITY_VERTICAL_NO  ,'QTY_VELOCITY_VERTICAL_NO')
obs_kind_names(285) = obs_kind_type(QTY_GND_GPS_VTEC          ,'QTY_GND_GPS_VTEC')
obs_kind_names(286) = obs_kind_type(QTY_DENSITY_ION_OP        ,'QTY_DENSITY_ION_OP')
obs_kind_names(287) = obs_kind_type(QTY_TOTAL_ELECTRON_COUNT  ,'QTY_TOTAL_ELECTRON_COUNT')

obs_kind_names(290) = obs_kind_type(QTY_STREAM_FLOW             ,'QTY_STREAM_FLOW')
obs_kind_names(291) = obs_kind_type(QTY_SURFACE_HEAD            ,'QTY_SURFACE_HEAD')
obs_kind_names(292) = obs_kind_type(QTY_DEEP_GROUNDWATER_LEVEL  ,'QTY_DEEP_GROUNDWATER_LEVEL')
obs_kind_names(293) = obs_kind_type(QTY_STREAM_HEIGHT           ,'QTY_STREAM_HEIGHT')
obs_kind_names(294) = obs_kind_type(QTY_GROUND_SURF_TEMPERATURE ,'QTY_GROUND_SURF_TEMPERATURE')
obs_kind_names(295) = obs_kind_type(QTY_CANOPY_TEMPERATURE      ,'QTY_CANOPY_TEMPERATURE')
obs_kind_names(296) = obs_kind_type(QTY_BUCKET_MULTIPLIER       ,'QTY_BUCKET_MULTIPLIER')
obs_kind_names(297) = obs_kind_type(QTY_RUNOFF_MULTIPLIER       ,'QTY_RUNOFF_MULTIPLIER')

obs_kind_names(300) = obs_kind_type(QTY_BRIGHTNESS_TEMPERATURE,'QTY_BRIGHTNESS_TEMPERATURE')
obs_kind_names(301) = obs_kind_type(QTY_VEGETATION_TEMPERATURE,'QTY_VEGETATION_TEMPERATURE')
obs_kind_names(302) = obs_kind_type(QTY_CANOPY_HEIGHT         ,'QTY_CANOPY_HEIGHT')
obs_kind_names(303) = obs_kind_type(QTY_FPAR_DIRECT           ,'QTY_FPAR_DIRECT')
obs_kind_names(304) = obs_kind_type(QTY_FPAR_DIFFUSE          ,'QTY_FPAR_DIFFUSE')
obs_kind_names(305) = obs_kind_type(QTY_FPAR_SUNLIT_DIRECT    ,'QTY_FPAR_SUNLIT_DIRECT')
obs_kind_names(306) = obs_kind_type(QTY_FPAR_SUNLIT_DIFFUSE   ,'QTY_FPAR_SUNLIT_DIFFUSE')
obs_kind_names(307) = obs_kind_type(QTY_FPAR_SHADED_DIRECT    ,'QTY_FPAR_SHADED_DIRECT')
obs_kind_names(308) = obs_kind_type(QTY_FPAR_SHADED_DIFFUSE   ,'QTY_FPAR_SHADED_DIFFUSE')
obs_kind_names(309) = obs_kind_type(QTY_FPSN                  ,'QTY_FPSN')
obs_kind_names(310) = obs_kind_type(QTY_FSIF                  ,'QTY_FSIF')

obs_kind_names(311) = obs_kind_type(QTY_SEAICE_AGREG_CONCENTR ,'QTY_SEAICE_AGREG_CONCENTR')
obs_kind_names(312) = obs_kind_type(QTY_SEAICE_AGREG_VOLUME   ,'QTY_SEAICE_AGREG_VOLUME')
obs_kind_names(313) = obs_kind_type(QTY_SEAICE_AGREG_SNOWVOLUME,'QTY_SEAICE_AGREG_SNOWVOLUME')
obs_kind_names(314) = obs_kind_type(QTY_SEAICE_AGREG_THICKNESS,'QTY_SEAICE_AGREG_THICKNESS')
obs_kind_names(315) = obs_kind_type(QTY_SEAICE_AGREG_SNOWDEPTH,'QTY_SEAICE_AGREG_SNOWDEPTH')
obs_kind_names(316) = obs_kind_type(QTY_U_SEAICE_COMPONENT    ,'QTY_U_SEAICE_COMPONENT')
obs_kind_names(317) = obs_kind_type(QTY_V_SEAICE_COMPONENT    ,'QTY_V_SEAICE_COMPONENT')
obs_kind_names(318) = obs_kind_type(QTY_SEAICE_ALBEDODIRVIZ   ,'QTY_SEAICE_ALBEDODIRVIZ')
obs_kind_names(319) = obs_kind_type(QTY_SEAICE_ALBEDODIRNIR   ,'QTY_SEAICE_ALBEDODIRNIR')
obs_kind_names(320) = obs_kind_type(QTY_SEAICE_ALBEDOINDVIZ   ,'QTY_SEAICE_ALBEDOINDVIZ')
obs_kind_names(321) = obs_kind_type(QTY_SEAICE_ALBEDOINDNIR   ,'QTY_SEAICE_ALBEDOINDNIR')
obs_kind_names(322) = obs_kind_type(QTY_SEAICE_CONCENTR       ,'QTY_SEAICE_CONCENTR')
obs_kind_names(323) = obs_kind_type(QTY_SEAICE_VOLUME         ,'QTY_SEAICE_VOLUME')
obs_kind_names(324) = obs_kind_type(QTY_SEAICE_SNOWVOLUME     ,'QTY_SEAICE_SNOWVOLUME')
obs_kind_names(325) = obs_kind_type(QTY_SEAICE_SURFACETEMP    ,'QTY_SEAICE_SURFACETEMP')
obs_kind_names(326) = obs_kind_type(QTY_SEAICE_FIRSTYEARAREA  ,'QTY_SEAICE_FIRSTYEARAREA')
obs_kind_names(327) = obs_kind_type(QTY_SEAICE_ICEAGE         ,'QTY_SEAICE_ICEAGE')
obs_kind_names(328) = obs_kind_type(QTY_SEAICE_LEVELAREA      ,'QTY_SEAICE_LEVELAREA')
obs_kind_names(329) = obs_kind_type(QTY_SEAICE_LEVELVOLUME    ,'QTY_SEAICE_LEVELVOLUME')
obs_kind_names(330) = obs_kind_type(QTY_SEAICE_MELTPONDAREA   ,'QTY_SEAICE_MELTPONDAREA')
obs_kind_names(331) = obs_kind_type(QTY_SEAICE_MELTPONDDEPTH  ,'QTY_SEAICE_MELTPONDDEPTH')
obs_kind_names(332) = obs_kind_type(QTY_SEAICE_MELTPONDLID    ,'QTY_SEAICE_MELTPONDLID')
obs_kind_names(333) = obs_kind_type(QTY_SEAICE_MELTPONDSNOW   ,'QTY_SEAICE_MELTPONDSNOW')
obs_kind_names(334) = obs_kind_type(QTY_SEAICE_SALINITY001    ,'QTY_SEAICE_SALINITY001')
obs_kind_names(335) = obs_kind_type(QTY_SEAICE_SALINITY002    ,'QTY_SEAICE_SALINITY002')
obs_kind_names(336) = obs_kind_type(QTY_SEAICE_SALINITY003    ,'QTY_SEAICE_SALINITY003')
obs_kind_names(337) = obs_kind_type(QTY_SEAICE_SALINITY004    ,'QTY_SEAICE_SALINITY004')
obs_kind_names(338) = obs_kind_type(QTY_SEAICE_SALINITY005    ,'QTY_SEAICE_SALINITY005')
obs_kind_names(339) = obs_kind_type(QTY_SEAICE_SALINITY006    ,'QTY_SEAICE_SALINITY006')
obs_kind_names(340) = obs_kind_type(QTY_SEAICE_SALINITY007    ,'QTY_SEAICE_SALINITY007')
obs_kind_names(341) = obs_kind_type(QTY_SEAICE_SALINITY008    ,'QTY_SEAICE_SALINITY008')
obs_kind_names(342) = obs_kind_type(QTY_SEAICE_ICEENTHALPY001 ,'QTY_SEAICE_ICEENTHALPY001')
obs_kind_names(343) = obs_kind_type(QTY_SEAICE_ICEENTHALPY002 ,'QTY_SEAICE_ICEENTHALPY002')
obs_kind_names(344) = obs_kind_type(QTY_SEAICE_ICEENTHALPY003 ,'QTY_SEAICE_ICEENTHALPY003')
obs_kind_names(345) = obs_kind_type(QTY_SEAICE_ICEENTHALPY004 ,'QTY_SEAICE_ICEENTHALPY004')
obs_kind_names(346) = obs_kind_type(QTY_SEAICE_ICEENTHALPY005 ,'QTY_SEAICE_ICEENTHALPY005')
obs_kind_names(347) = obs_kind_type(QTY_SEAICE_ICEENTHALPY006 ,'QTY_SEAICE_ICEENTHALPY006')
obs_kind_names(348) = obs_kind_type(QTY_SEAICE_ICEENTHALPY007 ,'QTY_SEAICE_ICEENTHALPY007')
obs_kind_names(349) = obs_kind_type(QTY_SEAICE_ICEENTHALPY008 ,'QTY_SEAICE_ICEENTHALPY008')
obs_kind_names(350) = obs_kind_type(QTY_SEAICE_SNOWENTHALPY001,'QTY_SEAICE_SNOWENTHALPY001')
obs_kind_names(351) = obs_kind_type(QTY_SEAICE_SNOWENTHALPY002,'QTY_SEAICE_SNOWENTHALPY002')
obs_kind_names(352) = obs_kind_type(QTY_SEAICE_SNOWENTHALPY003,'QTY_SEAICE_SNOWENTHALPY003')
obs_kind_names(353) = obs_kind_type(QTY_SOM_TEMPERATURE,       'QTY_SOM_TEMPERATURE')
obs_kind_names(354) = obs_kind_type(QTY_SEAICE_FY,             'QTY_SEAICE_FY')
obs_kind_names(355) = obs_kind_type(QTY_SEAICE_AGREG_FY,       'QTY_SEAICE_AGREG_FY')
obs_kind_names(356) = obs_kind_type(QTY_SEAICE_AGREG_SURFACETEMP,'QTY_SEAICE_AGREG_SURFACETEMP')
obs_kind_names(357) = obs_kind_type(QTY_SEAICE_AGREG_FREEBOARD,'QTY_SEAICE_AGREG_FREEBOARD')
obs_kind_names(358) = obs_kind_type(QTY_SEAICE_CATEGORY,       'QTY_SEAICE_CATEGORY')

obs_kind_names(360) = obs_kind_type(QTY_SEA_SURFACE_ANOMALY,   'QTY_SEA_SURFACE_ANOMALY')
obs_kind_names(361) = obs_kind_type(QTY_LARGE_SCALE_STATE,     'QTY_LARGE_SCALE_STATE')
obs_kind_names(362) = obs_kind_type(QTY_SMALL_SCALE_STATE,     'QTY_SMALL_SCALE_STATE')
obs_kind_names(363) = obs_kind_type(QTY_CWP_PATH,              'QTY_CWP_PATH')
obs_kind_names(364) = obs_kind_type(QTY_CWP_PATH_ZERO,         'QTY_CWP_PATH_ZERO')
obs_kind_names(365) = obs_kind_type(QTY_ION_O_MIXING_RATIO,    'QTY_ION_O_MIXING_RATIO')
obs_kind_names(366) = obs_kind_type(QTY_ATOMIC_H_MIXING_RATIO, 'QTY_ATOMIC_H_MIXING_RATIO')

! count here, then output below

num_kind_assimilate = 0
do i = 1, max_obs_specific
   if(assimilate_these_obs_types(i) == 'null' .or. len_trim(assimilate_these_obs_types(i)) == 0 ) exit
   num_kind_assimilate = i
end do

num_kind_evaluate = 0
do i = 1, max_obs_specific
   if(evaluate_these_obs_types(i) == 'null' .or. len_trim(evaluate_these_obs_types(i)) == 0) exit
   num_kind_evaluate = i
end do

! Special case when all obs_types should use precomputed_FOs
if( any(use_precomputed_FOs_these_obs_types .eq. 'all') ) then
   num_kind_use_precomputed_FOs = num_kind_assimilate + num_kind_evaluate
   j = 1
   if ( num_kind_assimilate > 0 ) then
      use_precomputed_FOs_these_obs_types(j:num_kind_assimilate) = assimilate_these_obs_types(1:num_kind_assimilate)
      j = j + num_kind_assimilate
   endif
   if ( num_kind_evaluate > 0 ) use_precomputed_FOs_these_obs_types(j:num_kind_use_precomputed_FOs) = evaluate_these_obs_types(1:num_kind_evaluate)
else
   num_kind_use_precomputed_FOs = 0
   do i = 1, max_obs_specific
      if(use_precomputed_FOs_these_obs_types(i) == 'null' .or.  len_trim(use_precomputed_FOs_these_obs_types(i)) == 0) exit
      num_kind_use_precomputed_FOs = i
   end do
endif

if (do_output() .and. (num_kind_assimilate          > 0 .or. &
                       num_kind_evaluate            > 0 .or.  &
                       num_kind_use_precomputed_FOs > 0 )) then  

   write(*, *)
   write(*, *) '--------------------------------------------------------'
   write(*, *) '-------------- ASSIMILATE_THESE_OBS_TYPES --------------'
   write(logfileunit, *)
   write(logfileunit, *) 'Assimilate_these_obs_types:'

   if (num_kind_assimilate < 1) then
         write(logfileunit, *) '   none'
         write(     *     , *) '   none'
   else
      do i = 1, num_kind_assimilate
         write(logfileunit, *) '   '//trim(assimilate_these_obs_types(i))
         write(     *     , *) '   '//trim(assimilate_these_obs_types(i))
      enddo
   endif

   write(*, *) '--------------------------------------------------------'
   write(*, *) '-------------- EVALUATE_THESE_OBS_TYPES   --------------'
   write(logfileunit, *) 'Evaluate_these_obs_types:'

   if (num_kind_evaluate <1) then
         write(logfileunit, *) '   none'
         write(     *     , *) '   none'
   else
      do i = 1, num_kind_evaluate
         write(logfileunit, *) '   '//trim(evaluate_these_obs_types(i))
         write(     *     , *) '   '//trim(evaluate_these_obs_types(i))
      enddo
   endif

   write(*, *) '--------------------------------------------------------'
   write(*, *) '---------- USE_PRECOMPUTED_FO_OBS_TYPES   --------------'
   write(logfileunit, *) 'Use the precomputed Prior Forward Operators for these obs types:'

   if (num_kind_use_precomputed_FOs <1) then
         write(logfileunit, *) '   none'
         write(     *     , *) '   none'
   else
      do i = 1, num_kind_use_precomputed_FOs
         write(logfileunit, *) trim(use_precomputed_FOs_these_obs_types(i))
         write(     *     , *) trim(use_precomputed_FOs_these_obs_types(i))
      enddo
   endif

   write(*, *) '--------------------------------------------------------'
   write(*, *)
   write(logfileunit, *)

endif


! Figure out which kinds are being used, look for errors
! Start by loading up kinds to assimilate
if (num_kind_assimilate > 0) then
   do i = 1, num_kind_assimilate
      ! Search for the matching string
      do j = 1, max_obs_specific
         if(assimilate_these_obs_types(i) == obs_type_info(j)%name) then
            obs_type_info(j)%assimilate = .true.
            goto 44
         endif
      end do
      ! Falling off the end is an error
      write(err_string, *) '"',trim(assimilate_these_obs_types(i)), &
         '" from obs_kind_nml is not a legal observation kind to assimilate'
      call error_handler(E_ERR, 'initialize_module', err_string, source, revision, revdate)
      44 continue
   end do
endif

! Now look for kinds to evaluate
if (num_kind_evaluate > 0) then
   do i = 1, num_kind_evaluate
      ! Search for the matching string
      do j = 1, max_obs_specific
         if(evaluate_these_obs_types(i) == obs_type_info(j)%name) then
            obs_type_info(j)%evaluate = .true.
            goto 55
         endif
      end do
      ! Falling off the end is an error
      write(err_string, *) '"',trim(evaluate_these_obs_types(i)), &
         '" from obs_kind_nml is not a legal observation kind to evaluate'
      call error_handler(E_ERR, 'initialize_module', err_string, source, revision, revdate)
      55 continue
   end do
endif

if (num_kind_use_precomputed_FOs > 0) then
   do i = 1, num_kind_use_precomputed_FOs
      ! Search for the matching string
      do j = 1, max_obs_specific
         if(use_precomputed_FOs_these_obs_types(i) == obs_type_info(j)%name) then
            obs_type_info(j)%use_precomputed_FO = .true.
            goto 66
         endif
      end do
      ! Falling off the end is an error
      write(err_string, *) '"',trim(use_precomputed_FOs_these_obs_types(i)), &
         '" from obs_kind_nml is not a legal observation type'
      call error_handler(E_ERR, 'initialize_module', err_string, source, revision, revdate)
      66 continue
   end do
endif

! Make it an error to ask to assimilate AND evaluate the same obs kind
do i = 1, max_obs_specific
   if(obs_type_info(i)%evaluate .and. obs_type_info(i)%assimilate) then
      write(err_string, *) 'Illegal to evaluate and assimilate same kind ', &
         trim(obs_type_info(i)%name)
      call error_handler(E_ERR, 'initialize_module', err_string, source, revision, revdate)
   endif
end do

end subroutine initialize_module

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

function map_type_of_obs_table(obs_def_index)

! Argument is the index from the obs_def; needs to be mapped to the appropriate
! Integer storage index
integer, intent(in) :: obs_def_index
integer             :: map_type_of_obs_table

character(len = 169) :: err_string
integer :: i

if ( .not. module_initialized ) call initialize_module

! Need to search through the first map column to find this obs_def_index value
! Then return the index into table in this module from corresponding row in
! second column.
do i = 1, max_obs_specific
   if(map(1, i) == obs_def_index) then
      map_type_of_obs_table = map(2, i)
      return
   endif
end do

! Error, didn't find this obs_def_index in the map
write(err_string, *) 'Could not find obs_def_index ', obs_def_index, &
   ' in obs_kind map'
call error_handler(E_ERR, 'map_def_index', err_string, &
   source, revision, revdate)

end function map_type_of_obs_table

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

function get_name_for_type_of_obs(obs_type_ind)

! Returns observation type name

integer, intent(in) :: obs_type_ind
character(len=obstypelength) :: get_name_for_type_of_obs

if ( .not. module_initialized ) call initialize_module

if (obs_type_ind < 1 .or. obs_type_ind > max_obs_specific) then
   write(msg_string,'(A,I6,A,I6)') 'specific type number ', obs_type_ind, &
                                   ' must be between 1 and ', max_obs_specific
   call error_handler(E_ERR, 'get_obs_kind_name', msg_string, &
                      source, revision, revdate)
endif

get_name_for_type_of_obs = obs_type_info(obs_type_ind)%name

end function get_name_for_type_of_obs

!----------------------------------------------------------------------------
! Added by TRW to handle matching RAW variable types to their strings
! as well as the derived types - this will make the restart file
! handling more readable.

function get_name_for_quantity(obs_kind_ind)

! Returns observation kind name

integer, intent(in) :: obs_kind_ind
character(len=obstypelength) :: get_name_for_quantity

if (.not. module_initialized) call initialize_module

if (obs_kind_ind < 0 .or. obs_kind_ind > max_defined_quantities) then
   write(msg_string,'(A,I6,A,I6)') 'generic kind number ', obs_kind_ind, &
                                   ' must be between 0 and ', max_defined_quantities
   call error_handler(E_ERR, 'get_raw_obs_kind_name', msg_string, &
                      source, revision, revdate)
endif

get_name_for_quantity = obs_kind_names(obs_kind_ind)%name

end function get_name_for_quantity
!----------------------------------------------------------------------------

function get_index_for_type_of_obs(obs_type_name)

! Returns the integer index corresponding to an observation type string name
! Returns a -1 if this string is not in list

character(len = *), intent(in)  :: obs_type_name
integer                         :: get_index_for_type_of_obs

integer :: i
character(len=len(obs_type_name)) :: string1

if ( .not. module_initialized ) call initialize_module

string1 = adjustl(obs_type_name)

do i = 1, max_obs_specific
   if(trim(string1) == trim(obs_type_info(i)%name) ) then
      get_index_for_type_of_obs = i
      return
   endif
end do

get_index_for_type_of_obs = -1

end function get_index_for_type_of_obs

!----------------------------------------------------------------------------
! Added by TRW to handle matching RAW variable types to their strings
! as well as the derived types - this will make the restart file
! handling more readable.

function get_index_for_quantity(obs_kind_name)

! Returns the integer index corresponding to an observation kind string name
! Returns a -1 if this string is not in list

character(len=*), intent(in)  :: obs_kind_name
integer                       :: get_index_for_quantity

integer :: i
character(len=len(obs_kind_name)) :: string1

if (.not. module_initialized) call initialize_module

string1 = adjustl(obs_kind_name)

do i = 0, max_defined_quantities
   if(trim(string1) == trim(obs_kind_names(i)%name)) then
      get_index_for_quantity = i
      return
   end if
end do

get_index_for_quantity = -1

end function get_index_for_quantity

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

function get_num_types_of_obs()

! Accessor function to return observation *type* count

integer :: get_num_types_of_obs

if ( .not. module_initialized ) call initialize_module

get_num_types_of_obs = max_obs_specific

end function get_num_types_of_obs

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

function get_num_quantities()

! Accessor function to return observation *kind* count

integer :: get_num_quantities

if (.not. module_initialized) call initialize_module

get_num_quantities = max_defined_quantities

end function get_num_quantities

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

function assimilate_this_type_of_obs(obs_type_ind)

! Returns true if this obs_type is being assimilated

logical             :: assimilate_this_type_of_obs
integer, intent(in) :: obs_type_ind

if ( .not. module_initialized ) call initialize_module

assimilate_this_type_of_obs = obs_type_info(obs_type_ind)%assimilate

end function assimilate_this_type_of_obs

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

function evaluate_this_type_of_obs(obs_type_ind)

! Returns true if this obs_type is being assimilated

logical             :: evaluate_this_type_of_obs
integer, intent(in) :: obs_type_ind

if ( .not. module_initialized ) call initialize_module

evaluate_this_type_of_obs = obs_type_info(obs_type_ind)%evaluate

end function evaluate_this_type_of_obs

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

function use_ext_prior_this_type_of_obs(obs_type_ind)

! Returns true if this obs_type should use externally computed priors

logical             :: use_ext_prior_this_type_of_obs
integer, intent(in) :: obs_type_ind

if ( .not. module_initialized ) call initialize_module

use_ext_prior_this_type_of_obs = obs_type_info(obs_type_ind)%use_precomputed_FO

end function use_ext_prior_this_type_of_obs

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

function get_quantity_for_type_of_obs(obs_type_ind)

! Returns the associated generic kind associated with the
! specific type of this observation

integer, intent(in) :: obs_type_ind
integer             :: get_quantity_for_type_of_obs

if ( .not. module_initialized ) call initialize_module

get_quantity_for_type_of_obs = obs_type_info(obs_type_ind)%generic_kind

end function get_quantity_for_type_of_obs

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

subroutine write_type_of_obs_table(ifile, fform, use_list)

! Writes out the observation kind strings and corresponding integer
! indices as a header for an obs_sequence file.

integer, intent(in)                    :: ifile
character(len=*), intent(in), optional :: fform
integer,          intent(in), optional :: use_list(:)

integer :: i, ntypes
logical :: is_ascii, restrict

if ( .not. module_initialized ) call initialize_module

is_ascii = ascii_file_format(fform)

! Write the 20 character identifier to indicate the start of a kind table.
! To maintain complete backwards compatibility with the original read
! code this string must start in column 1.
! you cannot use: write(ifile, *) 'string'  because the output string
! will start in col 2.  the string either has to be part of the format
! argument to write(), or you have to use a separate format statement.
if (is_ascii) then
   write(ifile,  "('obs_kind_definitions')")   ! see note above!
else
   write(ifile)    'obs_kind_definitions'
endif

! If this routine is called with a list of which types are actually
! being used, restrict the table of contents to only those.
! Otherwise, write all known types.
if (present(use_list)) then
   ! make sure the list is the right length
   if (size(use_list) /= max_obs_specific) then
      call error_handler(E_ERR, 'write_obs_kind', &
         'use_list(:) must be the same length as number of types', &
         source, revision, revdate)
   endif

   ntypes = count(use_list(:) > 0)
   restrict = .true.
else
   ntypes = max_obs_specific
   restrict = .false.
endif

if (is_ascii) then
   write(ifile, *) ntypes
else
   write(ifile)    ntypes
endif

do i = 1, max_obs_specific
   if (restrict) then
       if (use_list(i) == 0) cycle
   endif

   if (is_ascii) then
      write(ifile, *) obs_type_info(i)%index, obs_type_info(i)%name
   else
      write(ifile)    obs_type_info(i)%index, obs_type_info(i)%name
   endif
end do

end subroutine write_type_of_obs_table

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


subroutine read_type_of_obs_table(ifile, pre_I_format, fform)

! Reads the observation kind strings and corresponding integer
! indices as a header for an obs_sequence file. 

integer,                    intent(in) :: ifile
logical,                    intent(in) :: pre_I_format
character(len=*), intent(in), optional :: fform

character(len=20)  :: header
character(len=obstypelength) :: o_name
integer            :: i, num_def_kinds, o_index, list_index, rc
logical            :: is_ascii

if ( .not. module_initialized ) call initialize_module

! pre_I_format has been deprecated.  
if(pre_I_format) then
   call error_handler(E_ERR, 'read_obs_kind: ', 'pre_I_format no longer supported', &
                      source, revision, revdate)
endif

is_ascii = ascii_file_format(fform)

! Read the 20 character identifier which identifies the start
! of the obstype number/name table for this sequence file.
if (is_ascii) then
   read(ifile, *, iostat=rc) header
else
   read(ifile,    iostat=rc) header
endif

if(rc /= 0 .or. header /= 'obs_kind_definitions') then
   write(msg_string,  *) 'Did not find expected "obs_kind_definitions" string at start of obs_seq file '
   write(msg_string1, *) 'Bad file format, corrupted file, or wrong-endian binary file'
   call error_handler(E_ERR, 'read_obs_kind', msg_string, &
      source, revision, revdate, text2=msg_string1)
endif

! Loop through the list to read the integer indices and strings
! For all the defined observation types
! Set up the map from kinds in the obs_sequence file to those
! in the data structure in this module.
if (is_ascii) then
   read(ifile, *) num_def_kinds
else
   read(ifile)    num_def_kinds
endif

do i = 1, num_def_kinds
   if (is_ascii) then
      read(ifile, *) o_index, o_name
   else
      read(ifile)    o_index, o_name
   endif

   ! What is the integer associated with this o_name in this module?
   list_index = get_index_for_type_of_obs(o_name)
   ! Check for error
   if(list_index == -1) then
      write(msg_string, *) 'Did not find observation kind "', o_name, &
         '" in obs_kind_mod list'
      call error_handler(E_ERR, 'read_obs_kind', msg_string, &
         source, revision, revdate)
   endif
   map(1, i) = o_index
   map(2, i) = list_index
end do

end subroutine read_type_of_obs_table

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

function get_type_of_obs_from_menu()

integer :: get_type_of_obs_from_menu

integer :: i, ierr
character(len=obstypelength) :: in

if ( .not. module_initialized ) call initialize_module

! Should only do kinds that have been selected by preprocessor, so those
! are ones that are being evaluated or assimilated.
21 continue
write(*, *) '     ', 'Input -1 * state variable index for identity observations'
write(*, *) '     ', 'OR input the name of the observation kind from table below:'
write(*, *) '     ', 'OR input the integer index, BUT see documentation...'
do i = 1, max_obs_specific
   if(assimilate_this_type_of_obs(i) .or. evaluate_this_type_of_obs(i)) &
      write(*, *) '     ',  obs_type_info(i)%index, trim(obs_type_info(i)%name)
end do

! Read the input as a string, convert to integers as appropriate
read(*, '(A)') in

! If string is a positive or negative number, convert it to integer
read(in, *, IOSTAT = ierr) get_type_of_obs_from_menu
if(ierr /= 0) then
   get_type_of_obs_from_menu = get_index_for_type_of_obs(in)
   ! If string isn't found, need to reprompt
   if(get_type_of_obs_from_menu == -1) then
      write(*, *) trim(in) // ' is not a supported kind: Please try again.'
      goto 21
   endif
else
   ! Make sure that number entered isn't 0 or too larg
   if(get_type_of_obs_from_menu == 0 .or. get_type_of_obs_from_menu > max_obs_specific) then
      write(*, *) get_type_of_obs_from_menu, 'is not a legal entry: Please try again.'
      goto 21
   endif
endif

! Make sure

end function get_type_of_obs_from_menu

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

end module obs_kind_mod

! <next few lines under version control, do not edit>
! $URL$
! $Id$
! $Revision$
! $Date$
