[Dart-dev] [4677] DART/trunk/obs_def: revamped a while ago but never committed; i cleaned it up more with help

nancy at ucar.edu nancy at ucar.edu
Thu Jan 27 10:45:50 MST 2011


Revision: 4677
Author:   nancy
Date:     2011-01-27 10:45:50 -0700 (Thu, 27 Jan 2011)
Log Message:
-----------
revamped a while ago but never committed; i cleaned it up more with help
from tim.  it should now be in shape to use as a good example of how to 
write an obs_def for observations with additional metadata. also updated
the documentation to match.  the original version of this file wrote all
the metadata for all 1d integral obs when it read or wrote the first obs
of this type; i removed that code and now each obs writes its own metadata
embedded in each observation.  if we do want to support global metadata
we should make a new section and interface routine that is called only
once per file when it's reading the header info.  or as tim suggests,
just go to netcdf 4 for the obs_seq file format.  anyway - i could find
no obs_seq files committed to the repository that used the old format
so there should be no problems.  the tutorial uses this file but it
goes through the interactive routine to generate obs_seq files on the
fly and doesn't rely on any files in the repository.

Modified Paths:
--------------
    DART/trunk/obs_def/obs_def_1d_state_mod.f90
    DART/trunk/obs_def/obs_def_1d_state_mod.html

-------------- next part --------------
Modified: DART/trunk/obs_def/obs_def_1d_state_mod.f90
===================================================================
--- DART/trunk/obs_def/obs_def_1d_state_mod.f90	2011-01-26 22:11:06 UTC (rev 4676)
+++ DART/trunk/obs_def/obs_def_1d_state_mod.f90	2011-01-27 17:45:50 UTC (rev 4677)
@@ -41,28 +41,38 @@
 ! $Revision$
 ! $Date$
 
-use        types_mod, only : r8
-use    utilities_mod, only : register_module, error_handler, E_ERR, E_MSG, &
-                             ascii_file_format
+! This code currently does not require a namelist, but to add one search for
+! the string 'NML' and comment in the code lines in the 4 marked sections.
+
+use        types_mod, only : r8, missing_r8
+use    utilities_mod, only : register_module, error_handler,               &
+                             E_ERR, E_MSG, ascii_file_format !,            & 
+                             ! find_namelist_in_file, check_namelist_read, &
+                             ! nmlfileunit, do_nml_file, do_nml_term
+                             !! Routines only needed for namelist support. NML1
 use     location_mod, only : location_type, set_location, get_location 
 use  assim_model_mod, only : interpolate
 use   cov_cutoff_mod, only : comp_cov_factor
 
 implicit none
 
-public :: write_1d_integral, read_1d_integral, interactive_1d_integral, &
-          get_expected_1d_integral
+! These are the required interfaces for an obs_def module.  
+public :: write_1d_integral, read_1d_integral, &
+          interactive_1d_integral, get_expected_1d_integral
 
 ! Storage for the special information required for observations of this type
-integer, parameter                      :: max_1d_integral_obs = 100
-integer                                 :: num_1d_integral_obs = 0
-real(r8)                                :: half_width(max_1d_integral_obs)
-integer, dimension(max_1d_integral_obs) :: num_points, localization_type
+integer               :: num_1d_integral_obs = 0     ! current count of obs
+integer               :: max_1d_integral_obs = 1000  ! allocation size limit
+real(r8), allocatable :: half_width(:)         ! metadata storage
+integer,  allocatable :: num_points(:)         ! ditto
+integer,  allocatable :: localization_type(:)  ! ditto
 
-! For now, read in all info on first read call, write all info on first write call
-logical :: already_read = .false., already_written = .false.
 
-! version controlled file description for error handling, do not edit
+! Set to .true. to get debugging output
+logical :: debug = .false.
+
+
+! Version controlled file description for error handling, do not edit
 character(len=128), parameter :: &
    source   = "$URL$", &
    revision = "$Revision$", &
@@ -70,217 +80,282 @@
 
 logical, save :: module_initialized = .false.
 
+!! To enable the namelist, comment this in.  NML2
+!namelist /one_d_integral_nml/  debug, max_1d_integral_obs
+
 contains
 
 !----------------------------------------------------------------------
 
-  subroutine initialize_module
-!----------------------------------------------------------------------------
-! subroutine initialize_module
+subroutine initialize_module
 
+! Anything in this routine is executed exactly once.  It could be used
+! to read in a namelist, precompute values needed later, etc. 
+! Currently this routine logs the version information and allocates
+! space for the metadata arrays.
+
+!! Only needed if you've commented in the namelist code.  NML3
+!integer :: iunit, io
+
+! Execute the code here just once
+if (module_initialized) return
+
+! Logs version information to file.
 call register_module(source, revision, revdate)
+
+! To enable a namelist (e.g to set max number of obs, or to turn
+! on the debug messages at run time, or whatever) search for 'NML'
+! and comment in the 4 code sections marked with that string.  NML4
+!
+!! Read the namelist input
+!call find_namelist_in_file("input.nml", "one_d_integral_nml", iunit)
+!read(iunit, nml = one_d_integral_nml, iostat = io)
+!call check_namelist_read(iunit, io, "one_d_integral_nml")
+!
+!! Record the namelist values used for the run 
+!if (do_nml_file()) write(nmlfileunit, nml=one_d_integral_nml)
+!if (do_nml_term()) write(     *     , nml=one_d_integral_nml)
+
+! Allocate space for the metadata
+allocate(half_width(max_1d_integral_obs),  &
+         num_points(max_1d_integral_obs),  &
+         localization_type(max_1d_integral_obs))
+
 module_initialized = .true.
+if(debug) print*, 'module initialized'
 
 end subroutine initialize_module
 
+!----------------------------------------------------------------------------
 
+subroutine write_1d_integral(igrkey, ifile, fform)
+ integer,          intent(in)           :: igrkey, ifile
+ character(len=*), intent(in), optional :: fform
 
- subroutine write_1d_integral(key, ifile, fileformat)
-!----------------------------------------------------------------------------
-!subroutine write_1d_integral(key, ifile, fileformat)
+! Write out the additional data associated with this observation.
+! The obs is identified by the incoming 'key' argument.
 
-integer, intent(in)             :: key, ifile
-character(len=32), intent(in)   :: fileformat
-
-integer :: i
 logical :: is_ascii
 
 if ( .not. module_initialized ) call initialize_module
 
-is_ascii = ascii_file_format(fileformat)
+! Make sure key value is within valid range -- it will be used as an index below.
+call check_valid_key(igrkey, 'GIVEN', 'write_1d_integral')
 
-! Philosophy, dump ALL information about this special obs_type at once???
-! For now, this means you can only write ONCE (that's all we're doing 3 June 05)
-! Toggle the flag to control this writing
-if(.not. already_written) then
-   already_written = .true.   
-   ! Write out the number of 1d_integral obs descriptions
-   if (is_ascii) then
-      write(ifile, *) num_1d_integral_obs
-   else
-      write(ifile)    num_1d_integral_obs
-   endif
+is_ascii = ascii_file_format(fform)
+if(debug) print*, 'write_1d_integral: ascii format = ', is_ascii
 
-   ! Write out the half_width, num_points, and localization_type for each  
-   do i = 1, num_1d_integral_obs
-      if (is_ascii) then
-         write(ifile, *) half_width(i), num_points(i), localization_type(i) 
-      else
-         write(ifile)    half_width(i), num_points(i), localization_type(i) 
-      endif
-   end do
-endif
+! Write out the half_width, num_points, and localization_type for each  
+! observation embedded in the observation.  The old key is written out
+! for tracking/debug use if needed.
 
-! Write out the obs_def key for this observation
 if (is_ascii) then
-   write(ifile, *) key
+   write(ifile, *) half_width(igrkey), num_points(igrkey), localization_type(igrkey)
+   write(ifile, *) igrkey
 else
-   write(ifile)    key
+   write(ifile)    half_width(igrkey), num_points(igrkey), localization_type(igrkey)
+   write(ifile)    igrkey
 endif
+if(debug) print*, 'writing out metadata for 1D integral obs ', igrkey
+if(debug) print*, 'metadata values are: ', half_width(igrkey), num_points(igrkey), localization_type(igrkey)
 
 end subroutine write_1d_integral
 
+!----------------------------------------------------------------------
 
+subroutine read_1d_integral(igrkey, ifile, fform)
+ integer,          intent(out)          :: igrkey
+ integer,          intent(in)           :: ifile
+ character(len=*), intent(in), optional :: fform
 
- subroutine read_1d_integral(key, ifile, fileformat)
-!----------------------------------------------------------------------
-!subroutine read_1d_integral(key, ifile, fileformat)
+! Read in the additional data associated with this observation.
+! The key value in the file will be read and then discarded, and a new key
+! will be generated based on the next available index in the metadata arrays.
+! Notice that key is intent(out) here, not (in) as in some other routines.
 
-integer, intent(out)            :: key
-integer, intent(in)             :: ifile
-character(len=32), intent(in)   :: fileformat
+logical            :: is_ascii
+integer            :: ignored_igrkey
 
-integer :: i
-logical :: is_ascii
-
 if ( .not. module_initialized ) call initialize_module
 
-is_ascii = ascii_file_format(fileformat)
+! Increment the counter so all key values are unique
+num_1d_integral_obs = num_1d_integral_obs + 1
 
-! Philosophy, read ALL information about this special obs_type at once???
-! For now, this means you can only read ONCE (that's all we're doing 3 June 05)
-! Toggle the flag to control this reading
-if(.not. already_read) then
-   already_read = .true.   
-   ! Read the number of 1d_integral obs descriptions
-   if (is_ascii) then
-      read(ifile, *) num_1d_integral_obs
-   else
-      read(ifile)    num_1d_integral_obs
-   endif
-   
-   ! Read the half_width, num_points, and localization_type for each  
-   do i = 1, num_1d_integral_obs
-      if (is_ascii) then
-         read(ifile, *) half_width(i), num_points(i), localization_type(i) 
-      else
-         read(ifile)    half_width(i), num_points(i), localization_type(i) 
-      endif
-   end do
-endif
+! Set the return value for the key, and use it as the index below
+igrkey = num_1d_integral_obs
 
-! Read in the key for this particular observation
+! Make sure key is within valid range
+call check_valid_key(igrkey, 'GENERATED', 'read_1d_integral')
+
+is_ascii = ascii_file_format(fform)
+if(debug) print*, 'read_1d_integral: ascii format = ', is_ascii
+
+! Read in the additional metadata for this observation, and discard the old key.
 if (is_ascii) then
-   read(ifile, *) key
+   read(ifile, *) half_width(igrkey), num_points(igrkey), localization_type(igrkey) 
+   read(ifile, *) ignored_igrkey
 else
-   read(ifile)    key
+   read(ifile)    half_width(igrkey), num_points(igrkey), localization_type(igrkey) 
+   read(ifile)    ignored_igrkey
 endif
+if(debug) print*, 'read in metadata for 1D integral obs ', igrkey
+if(debug) print*, 'metadata values are: ', half_width(igrkey), num_points(igrkey), localization_type(igrkey)
 
+if(debug) print *, 'ignoring old key', ignored_igrkey
+if(debug) print *, 'return key set to ', igrkey
+
 end subroutine read_1d_integral
 
+!----------------------------------------------------------------------
 
+subroutine interactive_1d_integral(igrkey)
+ integer, intent(out) :: igrkey
 
- subroutine interactive_1d_integral(key)
-!----------------------------------------------------------------------
-!subroutine interactive_1d_integral(key)
-!
-! Initializes the specialized part of a 1d_integral observation
-! Passes back up the key for this one
+! Initializes the specialized part of a 1d_integral observation.
+! A new key will be generated based on the next available index
+! in the metadata arrays.
 
-integer, intent(out) :: key
 
-character(len=129) :: msgstring
-
 if ( .not. module_initialized ) call initialize_module
 
-! Make sure there's enough space, if not die for now (clean later)
-if(num_1d_integral_obs >= max_1d_integral_obs) then
-   ! PUT IN ERROR HANDLER CALL
-   write(msgstring, *)'Not enough space for a 1d_integral_obs.'
-   call error_handler(E_MSG,'interactive_1d_integral',msgstring,source,revision,revdate)
-   write(msgstring, *)'Can only have max_1d_integral_obs (currently ',max_1d_integral_obs,')'
-   call error_handler(E_ERR,'interactive_1d_integral',msgstring,source,revision,revdate)
-endif
-
-! Increment the index
+! Increment the counter so all key values are unique
 num_1d_integral_obs = num_1d_integral_obs + 1
-key = num_1d_integral_obs
 
-! Otherwise, prompt for input for the three required beasts
+! Set the return value for the key, and use it as the index below
+igrkey = num_1d_integral_obs
+
+! Make sure key is within valid range
+call check_valid_key(igrkey, 'GENERATED', 'interactive_1d_integral')
+
+! Prompt for input for the three required metadata items
 write(*, *) 'Creating an interactive_1d_integral observation'
+
 write(*, *) 'Input half width of integral '
-read(*, *) half_width(num_1d_integral_obs)
-write(*, *) 'Input the number of evaluation points (??? recommended) '
-read(*, *) num_points(num_1d_integral_obs)
+ read(*, *) half_width(igrkey)
+
+write(*, *) 'Input the number of evaluation points (5-20 recommended) '
+ read(*, *) num_points(igrkey)
+
 write(*, *) 'Input localization type: 1=Gaspari-Cohn; 2=Boxcar; 3=Ramped Boxcar'
-read(*, *) localization_type(num_1d_integral_obs)
+ read(*, *) localization_type(igrkey)
 
+if(debug) print *, 'return key set to ', igrkey
+
 end subroutine interactive_1d_integral
 
+!----------------------------------------------------------------------
 
+subroutine get_expected_1d_integral(state, location, igrkey, val, istatus)
+ real(r8),            intent(in)  :: state(:)
+ type(location_type), intent(in)  :: location
+ integer,             intent(in)  :: igrkey
+ real(r8),            intent(out) :: val
+ integer,             intent(out) :: istatus
 
- subroutine get_expected_1d_integral(state, location, key, val, istatus)
-!----------------------------------------------------------------------
-!subroutine get_expected_1d_integral(state, location, key, val, istatus)
+! The forward operator interface for this type of observation.  It is
+! called with a state vector, a location, and a key to identify which
+! observation is being processed.  The return 'val' is the expected
+! observation value, and istatus is the return code.  0 is ok, 
+! > 0 signals an error, and < 0 values are reserved for system use.
+! The call to 'interpolate()' below calls the forward operator in 
+! whatever model this code has been compiled with.
 
-real(r8), intent(in)            :: state(:)
-type(location_type), intent(in) :: location
-integer, intent(in)             :: key
-real(r8), intent(out)           :: val
-integer, intent(out)            :: istatus
-
-integer :: i
-real(r8) :: range, loc, bottom, dx, x, sum, dist, weight, weight_sum
 type(location_type) :: location2
+integer             :: i
+real(r8)            :: range, loc, bottom, dx, x, sum, dist, weight, weight_sum
 
 if ( .not. module_initialized ) call initialize_module
 
+! Make sure key is within valid range
+call check_valid_key(igrkey, 'GIVEN', 'get_expected_1d_integral')
+
 ! Figure out the total range of the integrated funtion (1 is max)
-range = 4.0_r8 * half_width(key)
+range = 4.0_r8 * half_width(igrkey)
 if(range > 1.0_r8) range = 1.0_r8
-!write(*, *) 'range is ', range
+if(debug) print*, 'range is ', range
 
 ! Get the location value
 loc = get_location(location)
-!write(*, *) 'loc base is ', loc
+if(debug) print*, 'loc base is ', loc
 
 ! Compute the bottom and top of the range
 bottom = loc - range / 2.0_r8
 if(bottom < 0.0_r8) bottom = bottom + 1.0_r8
-!write(*, *) 'bottom is ', bottom
+if(debug) print*, 'bottom is ', bottom
 
 ! Next figure out where to put all the points
-dx = range / (num_points(key) - 1)
-!write(*, *) 'dx is ', dx
+dx = range / (num_points(igrkey) - 1)
+if(debug) print*, 'dx is ', dx
 
 ! Loop to compute the value at each point, then multiply by localization
 ! to get weighted integral
 sum = 0.0_r8
 weight_sum = 0.0_r8
-do i = 1, num_points(key)
+do i = 1, num_points(igrkey)
    x = bottom + (i - 1) * dx
    if(x > 1.0_r8) x = x - 1.0_r8
-!write(*, *) 'location for int ', i, 'is ', x
+if(debug) print*, 'location for int ', i, 'is ', x
    location2 = set_location(x)
    call interpolate(state, location2, 1, val, istatus)
+if(debug) print*, 'model forward operator for ', i, ' returns ', val
+   if (istatus /= 0) then
+if(debug) print*, 'forward operator returned error, returning'
+      val = missing_r8
+      return 
+   endif
    dist = abs(loc - x)
    if(dist > 0.5_r8) dist = 1.0_r8 - dist
-!write(*, *) 'dist ', i, dist
-   weight = comp_cov_factor(dist, half_width(key), &
-      localization_override = localization_type(key))
-!write(*, *) 'weight ', i, weight
+if(debug) print*, 'dist ', i, dist
+   weight = comp_cov_factor(dist, half_width(igrkey), &
+      localization_override = localization_type(igrkey))
+if(debug) print*, 'weight ', i, weight
    sum = sum + weight * val
    weight_sum = weight_sum + weight
 end do
 
 val = sum / weight_sum
 
-!write(*, *) 'get_expected_1d_integral key is ', key
-!write(*, *) half_width(key), num_points(key), localization_type(key)
+if(debug) print*, 'get_expected_1d_integral key is ', igrkey
+if(debug) print*, 'metadata values are: ', half_width(igrkey), num_points(igrkey), localization_type(igrkey)
+if(debug) print*, 'return value for forward operator is ', val
+if(debug) print*, 'return status (0 good; >0 error; <0 reserved for system use) is ', istatus
 
 end subroutine get_expected_1d_integral
 
 !----------------------------------------------------------------------
 
+subroutine check_valid_key(igrkey, what, fromwhere)
+ integer, intent(in)          :: igrkey
+ character(len=*), intent(in) :: what, fromwhere
+
+! Internal subroutine that verifies that we haven't incremented the key value
+! past the size of the allocated space, or that a routine hasn't been called
+! with a out-of-range key (which would indicate an internal error of some kind).
+! If an error is found, an fatal message is printed and this routine doesn't return.
+! The 'what' argument is either 'GIVEN' for a key value that's passed in from
+! another routine; or 'GENERATED' for one we have just made and are planning to
+! return to the caller.  The 'fromwhere' argument is the name of the calling 
+! subroutine so the error message can report where it was called from.
+
+character(len=128) :: msgstring
+
+if (igrkey <= 0 .or. igrkey > max_1d_integral_obs) then
+   if (what == 'GENERATED' .and. igrkey > max_1d_integral_obs) then
+      ! generating a new key and ran out of space
+      write(msgstring, *)'Out of space, max_1d_integral_obs limit ',max_1d_integral_obs
+      call error_handler(E_ERR,trim(fromwhere),msgstring,source,revision,revdate, &
+                         text2='Increase value of max_1d_integral_obs in obs_def_1d_state_mod')
+   else
+      ! called with a bad key or a negative key generated somehow. "shouldn't happen".
+      write(msgstring, *)'Key is ',igrkey,' must be between 1 and ',max_1d_integral_obs
+      call error_handler(E_ERR,trim(fromwhere),msgstring,source,revision,revdate, &
+                         text2='Internal error: Invalid key value in RAW_STATE_1D_INTEGRAL obs')
+   endif
+endif
+
+end subroutine
+
+!----------------------------------------------------------------------
+
 end module obs_def_1d_state_mod
 ! END DART PREPROCESS MODULE CODE

Modified: DART/trunk/obs_def/obs_def_1d_state_mod.html
===================================================================
--- DART/trunk/obs_def/obs_def_1d_state_mod.html	2011-01-26 22:11:06 UTC (rev 4676)
+++ DART/trunk/obs_def/obs_def_1d_state_mod.html	2011-01-27 17:45:50 UTC (rev 4677)
@@ -4,68 +4,94 @@
 <HEAD>
 <TITLE>module obs_def_1d_state_mod</TITLE>
 <link rel="stylesheet" type="text/css" href="../doc/html/doc.css">
+<link rel="shortcut icon" href="../doc/html/dart.ico" />
 </HEAD>
 <BODY>
 <A NAME="TOP"></A>
 
-<center>
+<H1>MODULE <em class=program>obs_def_1d_state_mod</em></H1>
+
+<table border=0 summary="" cellpadding=5>
+<tr>
+    <td valign=middle>
+    <img src="../doc/html/Dartboard9.png" alt="DART project logo" height=70 />
+    </td>
+    <td>
+       <P>Jump to <a href="../index.html">DART Documentation Main Index</a><br />
+          <small><small>version information for this file: <br />
+          <!-- version tag follows, do not edit -->
+          $Id$</small></small>
+       </P></td>
+</tr>
+</table>
+
 <A HREF="#Interface">INTERFACES</A> /
 <A HREF="#Namelist">NAMELIST</A> /
+<A HREF="#Modules">MODULES</A> /
 <A HREF="#FilesUsed">FILES</A> /
 <A HREF="#References">REFERENCES</A> /
 <A HREF="#Errors">ERRORS</A> /
 <A HREF="#FuturePlans">PLANS</A> /
-<A HREF="#PrivateComponents">PRIVATE COMPONENTS</A> /
 <A HREF="#Legalese">TERMS OF USE</A>
+
 </center>
 
-<H1>MODULE obs_def_1d_state_mod</H1>
-<!-- version tag follows, do not edit --><P>$Id$</P>
 
+<H2>Overview</H2>
 <P>
-Beginning with the I-release of DART, a more flexible, powerful (and complicated)
-mechanism for incorporating new types of observations is part of DART. The
+There is a flexible mechanism built into the DART framework
+for defining, at compile time, the list of observation types
+to be supported by the executables.  This can be changed at
+any time by adding or removing items from a namelist and 
+rebuilding the programs.  The
 special obs_def module being described here is used by the program 
 <em class="unix">preprocess</em>
-to insert appropriate code sections into a DEFAULT_obs_def module and a 
-DEFAULT_obs_kind module to generate the 
+to insert appropriate code sections into a 
+<a href="DEFAULT_obs_def_mod.html">DEFAULT_obs_def module</a>
+and a 
+<a href="../obs_kind/DEFAULT_obs_kind_mod.html">DEFAULT_obs_kind module</a>
+to generate
 <em class="file">obs_def_mod.f90</em> and 
 <em class="file">obs_kind_mod.f90</em>
 that are used by 
 <em class="unix">filter</em> and other DART programs.
 This module is intended to provide a prototype for those
 developing more complicated specialized observation definition modules.
-<br><br>
-This is an extended format Fortran90 module that provides the definition
+<br /><br />
+This is an extended format Fortran 90 module that provides the definition
 for observation types designed for use with idealized low-order models
 that use the 1D location module and can be thought of as having a state
 vector that is equally spaced on a 1D cyclic domain. The two observation types
 are: a straight linear interpolation to a point on a [0,1] domain called
-a RAW_STATE_VARIABLE; an area-weighted 'integral' of the state variable
+a RAW_STATE_VARIABLE; and an area-weighted 'integral' of the state variable
 over some part of the cyclic 1D domain. The second type can be used to
 do idealized studies related to remote sensing observations that are
 best thought of as weighted integrals of some quantity over a finite volume.
-<br><br>
+<br /><br />
 The second observation type is referred to as a RAW_STATE_1D_INTEGRAL. It
-has an associated half_width and localization type (see cov_cutoff module)
+has an associated half_width and localization type (see the
+<a href="../cov_cutoff/cov_cutoff_mod.html">cov_cutoff module</a>
+documentation)
 and a number of points at which to compute the associated integral by 
 quadrature. The location of the observation defines the center of mass of
 the integral. The integral is centered around the location and extends
 outward on each side to 2*half_width. The weight associated with the
 integral is defined by the weight of the localization function (for
-instance Gaspari Cohn) selected by the localization in the cov_cutoff
-module. The number of points are used to equally divide the range for
+instance Gaspari Cohn) using the same localization options as
+defined by the cov_cutoff module. 
+The number of points are used to equally divide the range for
 computing the integral by quadrature.
-<br><br>
+<br /><br />
 This module was partly motivated to provide a prototype for those
 developing more complicated specialized observation definition modules.
-Special observation modules like this contain Fortran90 code PLUS additional
+Special observation modules like this contain Fortran 90 code PLUS additional
 specially formatted commented code that is used to guide the preprocess program
 in constructing the obs_def_mod.f90 and obs_kind_mod.f90. These specially
 formatted comments are most conveniently placed at the beginning of the module
 and comprise seven sections, each beginning and ending with a special F90
-comment line that must be included VERBATIM. The seven sections and their
-specific instances for the 1d_raw_state_mod are:
+comment line that must be included VERBATIM. 
+<br /><br />
+The seven sections and their specific instances for the 1d_raw_state_mod are:
 </P>
 
 <OL>
@@ -74,11 +100,11 @@
 generic kinds (see obs_kind module). The header line is followed by lines
 that have the observation type name (an all caps Fortran 90 identifier) and
 their associated generic kind identifier from the obs_kind module.
-If there is no special processing needed for an observation type,
-and no additional data needed beyond the standard contents of an observation,
-then a third word on the line, the <em class="unix">COMMON_CODE</em> will
+If there is no special processing needed for an observation type
+and no additional data needed beyond the standard contents of an observation
+then a third word on the line, <em class="unix">COMMON_CODE</em>, will
 instruct the preprocess program to automatically generate all stubs and
-code needed for this type.  For observation types needing any special code
+code needed for this type.  For observation types needing special code
 or additional data, this word should not be specified and the user must
 supply the code manually.
 <pre>
@@ -87,85 +113,88 @@
 ! RAW_STATE_1D_INTEGRAL, KIND_1D_INTEGRAL 
 ! END DART PREPROCESS KIND LIST 
 </pre>
-<br><br>
+<br /><br />
 </li>
 
 <li>
 A list of all the use statements that the completed obs_def_mod.f90
 must have in order to use the public interfaces provided by this special
-obs_def module.  This is optional if there are no external interfaces.
+obs_def module.  This section is optional if there are no external interfaces.
 <pre>
 ! BEGIN DART PREPROCESS USE OF SPECIAL OBS_DEF MODULE 
 !   use obs_def_1d_state_mod, only : write_1d_integral, read_1d_integral, 
 !                                    interactive_1d_integral, get_expected_1d_integral 
 ! END DART PREPROCESS USE OF SPECIAL OBS_DEF MODULE 
 </pre>
-<br><br>
+<br /><br />
 </li>
 
 <li>
 Case statement entries for each observation type defined by this special
 obs_def module stating how to compute the forward observation operator.
-Not required if COMMON_CODE was specified, otherwise
-there must be a case statement entry for each
-type of observation.
+Not permitted if COMMON_CODE was specified (because the case statement
+will be automatically generated), otherwise there must be a case 
+statement entry for each type of observation.
 <pre>
 ! BEGIN DART PREPROCESS GET_EXPECTED_OBS_FROM_DEF
 !         case(RAW_STATE_1D_INTEGRAL) 
 !            call get_expected_1d_integral(state, location, obs_def%key, obs_val, istatus) 
 ! END DART PREPROCESS GET_EXPECTED_OBS_FROM_DEF 
 </pre>
-<br><br>
+<br /><br />
 </li>
 
 <li>
 Case statement entries for each observation type defined by this special
 obs_def module stating how to read any extra required information from an
 obs sequence file.  
-Not required if COMMON_CODE was specified, otherwise
-there must be a case statement entry for each
-type of observation defined even if no special action is required
-(just put in a continue.) 
+Not permitted if COMMON_CODE was specified (because the case statement
+will be automatically generated), otherwise there must be a case 
+statement entry for each type of observation defined even if no 
+special action is required. (In that case put a 'continue' statement
+as the body of the case instead of a subroutine call.)
 <pre>
 ! BEGIN DART PREPROCESS READ_OBS_DEF 
 !      case(RAW_STATE_1D_INTEGRAL) 
-!         call read_1d_integral(obs_def%key, ifile, fileformat) 
+!         call read_1d_integral(obs_def%key, ifile, fform) 
 ! END DART PREPROCESS READ_OBS_DEF 
 </pre>
-<br><br>
+<br /><br />
 </li>
 
 <li>
 Case statement entries for each observation type defined by this special
 obs_def module stating how to write any extra required information to an
 obs sequence file.
-Not required if COMMON_CODE was specified, otherwise
-there must be a case statement entry for each
-type of observation defined even if no special action is required
-(just put in a continue.) 
+Not permitted if COMMON_CODE was specified (because the case statement
+will be automatically generated), otherwise there must be a case 
+statement entry for each type of observation defined even if no 
+special action is required. (In that case put a 'continue' statement
+as the body of the case instead of a subroutine call.)
 <pre>
 ! BEGIN DART PREPROCESS WRITE_OBS_DEF 
 !      case(RAW_STATE_1D_INTEGRAL) 
-!         call write_1d_integral(obs_def%key, ifile, fileformat) 
+!         call write_1d_integral(obs_def%key, ifile, fform) 
 ! END DART PREPROCESS WRITE_OBS_DEF 
 </pre>
-<br><br>
+<br /><br />
 </li>
 
 <li>
 Case statement entries for each observation type defined by this special
 obs_def module stating how to interactively create any extra required information.
-Not required if COMMON_CODE was specified, otherwise
-there must be a case statement entry for each
-type of observation defined even if no special action is required
-(just put in a continue.) 
+Not permitted if COMMON_CODE was specified (because the case statement
+will be automatically generated), otherwise there must be a case 
+statement entry for each type of observation defined even if no 
+special action is required. (In that case put a 'continue' statement
+as the body of the case instead of a subroutine call.)
 <pre>
 ! BEGIN DART PREPROCESS INTERACTIVE_OBS_DEF 
 !      case(RAW_STATE_1D_INTEGRAL) 
 !         call interactive_1d_integral(obs_def%key) 
 ! END DART PREPROCESS INTERACTIVE_OBS_DEF 
 </pre>
-<br><br>
+<br /><br />
 </li>
 
 <li>
@@ -182,7 +211,7 @@
 end module obs_def_1d_state_mod
 ! END DART PREPROCESS MODULE CODE
 </pre>
-<br><br>
+<br /><br />
 </li>
 </ol>
 
@@ -190,7 +219,7 @@
 
 <!--==================================================================-->
 
-<A NAME="OtherModulesUsed"></A>
+<A NAME="Modules"></A>
 <HR>
 <H2>OTHER MODULES USED</H2>
 <PRE>
@@ -225,13 +254,13 @@
 <!--============= DESCRIPTION OF A SUBROUTINE =======================-->
 
 <A NAME="write_1d_integral"></A>
-<br>
+<br />
 <div class=routine>
-<em class=call> call write_1d_integral(key, ifile, fileformat) </em>
+<em class=call> call write_1d_integral(igrkey, ifile, fform) </em>
 <pre>
-integer,           intent(in) :: <em class=code>key</em>
-integer,           intent(in) :: <em class=code>ifile</em>
-character(len=32), intent(in) :: <em class=code>fileformat</em>
+integer,          intent(in) :: <em class=code>igrkey</em>
+integer,          intent(in) :: <em class=code>ifile</em>
+character(len=*), intent(in) :: <em class=code>fform</em>
 </pre>
 </div>
 
@@ -240,37 +269,39 @@
 
 <P>
 Writes out the extra information for observation with unique identifier
-key for a 1d_integral observation kind. This information includes a header
-which identifies the total numbe of 1d_integral observations in the whole
-sequence (this is only written on the first call) followed by the half-width,
-localization type and number of quadrature points for
-this observation,
+key for a 1d_integral observation kind.  This includes the half-width,
+localization type and number of quadrature points for this observation.
 </P>
 
 <TABLE width=100% border=0 summary="" cellpadding=3>
-<TR><TD valign=top><em class=code>key&nbsp;&nbsp;</em></TD>
-    <TD>Unique integer key associated with the observation being 
-        processed.</TD></TR>
+<TR><TD valign=top><em class=code>igrkey&nbsp;&nbsp;</em></TD>
+    <TD>Unique integer key associated with the 1d integral
+        observation being processed.  This is not the same as
+        the key that all types of observations have and uniquely
+        distinguishes all observations from each other; this 
+        is a key that is only set and retrieved by this code
+        for 1d integral observations.  It is stored in the obs_def
+        derived type, not in the main obs_type definition.</TD></TR>
 <TR><TD valign=top><em class=code>ifile&nbsp;&nbsp;</em></TD>
     <TD>Unit number on which observation sequence file is open</TD></TR>
-<TR><TD valign=top><em class=code>fileformat&nbsp;&nbsp;</em></TD>
+<TR><TD valign=top><em class=code>fform&nbsp;&nbsp;</em></TD>
     <TD>String noting whether file is opened for 'formatted' 
         or 'unformatted' IO.</TD></TR>
 </TABLE>
 
 </div>
-<br>
+<br />
 
 <!--============= DESCRIPTION OF A SUBROUTINE =======================-->
 
 <A NAME="read_1d_integral"></A>
-<br>
+<br />
 <div class=routine>
-<em class=call> call read_1d_integral(key, ifile, fileformat) </em>
+<em class=call> call read_1d_integral(igrkey, ifile, fform) </em>
 <pre>
-integer,           intent(out) :: <em class=code>key</em>
-integer,           intent(in)  :: <em class=code>ifile</em>
-character(len=32), intent(in)  :: <em class=code>fileformat</em>
+integer,          intent(out) :: <em class=code>igrkey</em>
+integer,          intent(in)  :: <em class=code>ifile</em>
+character(len=*), intent(in)  :: <em class=code>fform</em>
 </pre>
 </div>
 
@@ -279,35 +310,37 @@
 
 <P>
 Reads the extra information for observation with unique identifier
-key for a 1d_integral observation kind. This information includes a header
-which identifies the total numbe of 1d_integral observations in the whole
-sequence (this is only read on the first call) followed by the half-width,
-localization type and number of quadrature points for
-this observation,
+key for a 1d_integral observation kind. This information includes the
+half-width, localization type and number of quadrature points for
+this observation.
+The key that is returned is uniquely associated with the definition
+that has been created and is used by this module to keep track
+of the associated parameters for this observation.
 </P>
+</P>
 
 <TABLE width=100% border=0 summary="" cellpadding=3>
-<TR><TD valign=top><em class=code>key&nbsp;&nbsp;</em></TD>
+<TR><TD valign=top><em class=code>igrkey&nbsp;&nbsp;</em></TD>
     <TD>Unique integer key associated with the observation being 
        processed.</TD></TR>
 <TR><TD valign=top><em class=code>ifile&nbsp;&nbsp;</em></TD>
     <TD>Unit number on which observation sequence file is open</TD></TR>
-<TR><TD valign=top><em class=code>fileformat&nbsp;&nbsp;</em></TD>
+<TR><TD valign=top><em class=code>fform&nbsp;&nbsp;</em></TD>
     <TD>String noting whether file is opened for 'formatted' or 
         'unformatted' IO.</TD></TR>
 </TABLE>
 
 </div>
-<br>
+<br />
 
 <!--============= DESCRIPTION OF A SUBROUTINE =======================-->
 
 <A NAME="interactive_1d_integral"></A>
-<br>
+<br />
 <div class=routine>
-<em class=call> call interactive_1d_integral(key) </em>
+<em class=call> call interactive_1d_integral(igrkey) </em>
 <pre>
-integer, intent(out) :: <em class=code>key</em>
+integer, intent(out) :: <em class=code>igrkey</em>
 </pre>
 </div>
 
@@ -323,24 +356,24 @@
 </P>
 
 <TABLE width=100% border=0 summary="" cellpadding=3>
-<TR><TD valign=top><em class=code>key&nbsp;&nbsp;</em></TD>
+<TR><TD valign=top><em class=code>igrkey&nbsp;&nbsp;</em></TD>
     <TD>Unique identifier associated with the created observation definition 
         in the obs sequence.</TD></TR>
 </TABLE>
 
 </div>
-<br>
+<br />
 
 <!--===================== DESCRIPTION OF A ROUTINE =====================-->
 
 <A NAME="get_expected_1d_integral"></A>
-<br>
+<br />
 <div class=routine>
-<em class=call> call get_expected_1d_integral(state, location, key, val, istatus) </em>
+<em class=call> call get_expected_1d_integral(state, location, igrkey, val, istatus) </em>
 <pre>
 real(r8), intent(in)            :: <em class=code>state</em>
 type(location_type), intent(in) :: <em class=code>location</em>
-integer, intent(in)             :: <em class=code>key</em>
+integer, intent(in)             :: <em class=code>igrkey</em>
 real(r8), intent(out)           :: <em class=code>val</em>
 integer, intent(out)            :: <em class=code>istatus</em>
 </pre>
@@ -351,6 +384,9 @@
 
 <P>
 Computes the forward observation operator for a 1d integral observation.
+Calls the <em class="code">interpolate()</em> routine multiple times
+to invoke the forward operator code in whatever model this has been 
+compiled with.
 </P>
 
 <TABLE width=100% border=0 summary="" cellpadding=3>
@@ -358,17 +394,18 @@
     <TD>Model state vector (or extended state vector).</TD></TR>
 <TR><TD valign=top><em class=code>location&nbsp;&nbsp;</em></TD>
     <TD>Location of this observation.</TD></TR>
-<TR><TD valign=top><em class=code>key&nbsp;&nbsp;</em></TD>
+<TR><TD valign=top><em class=code>igrkey&nbsp;&nbsp;</em></TD>
     <TD>Unique integer key associated with this observation.</TD></TR>
 <TR><TD valign=top><em class=code>val&nbsp;&nbsp;</em></TD>
     <TD>Returned value of forward observation operator.</TD></TR>
 <TR><TD valign=top><em class=code>istatus&nbsp;&nbsp;</em></TD>
-    <TD>Returned as 0 if forward operator was successfully computed, 
-        else returned non-zero.</TD></TR>
+    <TD>Returns 0 if forward operator was successfully computed, 
+        else returns a positive value.  (Negative values are
+        reserved for system use.)</TD></TR>
 </TABLE>
 
 </div>
-<br>
+<br />
 
 <!--==================================================================-->
 <!-- Describe the Files Used by this module.                          -->
@@ -403,8 +440,8 @@
 <TR><TH>Routine</TH><TH>Message</TH><TH>Comment</TH></TR>
 
 <TR><!-- routine --><TD VALIGN=top>interactive_1d_integral</TD>
-    <!-- message --><TD VALIGN=top>Not enough space for a 1d_integral_obs. 
-                  Can only have max_1d_integral_obs (currently _____).</TD>
+    <!-- message --><TD VALIGN=top>Out of space, max_1d_integral_obs limit NNNN
+                                   (currently 1000).</TD>
     <!-- comment --><TD VALIGN=top> There is only room for a fixed number of
      1d integral observations. The max number is defined by max_1d_integral_obs.
      Set this to a larger value if more are needed. </TD>
@@ -430,17 +467,6 @@
 </P>
 
 <!--==================================================================-->
-<!-- PrivateComponents                                                -->
-<!--==================================================================-->
-
-<A NAME="PrivateComponents"></A>
-<HR>
-<H2>PRIVATE COMPONENTS</H2>
-<P>
-N/A
-</P>
-
-<!--==================================================================-->
 <!-- Legalese & Metadata                                              -->
 <!--==================================================================-->
 
@@ -449,9 +475,9 @@
 <H2>Terms of Use</H2>
 
 <P>
-DART software - Copyright &#169; 2004 - 2010 UCAR.<br>
-This open source software is provided by UCAR, "as is",<br>
-without charge, subject to all terms of use at<br>
+DART software - Copyright &copy; 2004 - 2010 UCAR.<br />
+This open source software is provided by UCAR, "as is",<br />
+without charge, subject to all terms of use at<br />
 <a href="http://www.image.ucar.edu/DAReS/DART/DART_download">
 http://www.image.ucar.edu/DAReS/DART/DART_download</a>
 </P>


More information about the Dart-dev mailing list