wiki:OMI_observation_modules

Version 7 (modified by lnerger, 3 months ago) (diff)

--

PDAF-OMI Observation Modules

Overview

The implementation of the observations with OMI is done in observation modules (obs-modules). For each observation type a separate module should be created.

Each obs-module contains four routines:

  • init_dim_obs initializes all variables holding the information about one observation type. The information about the observation type is stored in a data structure (Fortran derived type).
  • obs_op applies the observation operator to a state vector. One can call an observation operator routine provided by PDAF, or one can to implement a new operator.
  • init_dim_obs_l calls a PDAF-OMI routine to initialize the observation information corresponding to a local analysis domain. One can set localization parameters, like the localization radius, for each observation type.
  • localize_covar calls a PDAF-OMI routine to apply covariance localization. One can set localization parameters, like the localization radius, for each observation type.

The template file obs_TYPE_pdafomi_TEMPLATE.F90 shows the different steps needed when implementing these routines. The main work is to implement init_dim_obs, while the other routines mainly call a subroutine provided by PDAF-OMI.

In the obs-module the subroutines are named according to the observation type. The template file uses generic names which can be replaced by the user. Having distinct names for each observation type is relevant to include the subroutine from the module in the call-back routine with ‘use’. In the header of each obs-module, the user can declare further variables, e.g. assim_TYPE as a flag to control whether the observation type should be assimilated.

Data type obs_f

To ensure the functionality within each obs-module, we rely on a derived data type called obs_f that contains all information about the observation. One instance of this data type is allocated in each obs-module with the generic variable name thisobs. A few of the elements of obs_f are initialized by the user when the observation information is initialized on init_dim_obs_f. Further variables is set in a call to the routine PDAFomi_gather_obs. This information is then used by all other routines in the obs-module. The template file obs_TYPE_pdafomi_TEMPLATE.F90 shows the different steps needed to initialize thisobs.

The mandatory variables in obs_f that need to be set by the user are:

  TYPE obs_f
     ! ---- Mandatory variables to be set in INIT_DIM_OBS ----
     INTEGER :: doassim=0                 !< Whether to assimilate this observation type
     INTEGER :: disttype                  !< Type of distance computation to use for localization
                                          !   (0) Cartesian, (1) Cartesian periodic
                                          !   (2) simplified geographic, (3) geographic haversine function
     INTEGER :: ncoord                    !< Number of coordinates use for distance computation
     INTEGER, ALLOCATABLE :: id_obs_p(:,:) !< Indices of process-local observed field in state vector
     ...
  END TYPE obs_f

In addition there are optional variables that the be used:

  TYPE obs_f
     ...
     ! ---- Optional variables - they can be set in INIT_DIM_OBS ----
     REAL, ALLOCATABLE :: icoeff_p(:,:)   !< Interpolation coefficients for obs. operator (optional)
     REAL, ALLOCATABLE :: domainsize(:)   !< Size of domain for periodicity (<=0 for no periodicity) (optional)

     ! ---- Variables with predefined values - they can be changed in INIT_DIM_OBS  ----
     INTEGER :: obs_err_type=0            !< Type of observation error: (0) Gauss, (1) Laplace
     INTEGER :: use_global_obs=1          !< Whether to use (1) global full obs. 
                                          !< or (0) obs. restricted to those relevant for a process domain
     ...
  END TYPE obs_f

Apart from these variables, there is a number of variables that are set internally when the routine PDAFomi_gather_obs is called.

Next to the derived data type obs_f, there is a derived type obs_l for localization. This is only used internally. It will be filled in init_dim_obs_l when calling PDAFomi_init_dim_obs_l.

init_dim_obs_TYPE

This is the main routine to initialize observation information.

Please see the template file templates/omi/obs_TYPE_pdafomi_TEMPLATE.F90
for a step-by-step description of the implementation steps.

Each observation module uses the generic name thisobs for the variable with observation type obs_f. Elements of thisobs are accessed like thisobs%doassim.

The main steps performed in this routine are

  1. thisobs%doassim: Specify whether this observation type is assimilated
  2. thisobs%disttype: Specify the type of distance computation
  3. thisobs%ncoord: Specify the number of dimensions used to compute distances
  4. dim_obs_p: Count the number of available observations
  5. obs_p: Fill the vector of observations
  6. ocoord_p: store the coordinates of the observations
  7. ivar_obs_p: store the inverse error variance of each observation
  8. thisobs%id_obs_p: store the indices of state vector elements that correspond to an observation (A single value for observation at grid points, or multiple values for derived quantities or interpolation)

When the observation operator performs interpolation, one further needs to initialize an array of interpolation coefficients (thisobs%icoeff_p).

After these variables are filled, one calls

    CALL PDAFomi_gather_obs(thisobs, dim_obs_p, obs_p, ivar_obs_p, ocoord_p, &
         thisobs%ncoord, local_range, dim_obs)

This routine will complete all required initializations for OMI. As such it is mandatory to call the routine.

The routine PDAFomi_gather_obs returns the number of observations dim_obs which is the return variable for PDAF.

obs_op_TYPE

This routine applies the observation operator to a state vector. It returns the observed state vector to PDAF. The routine is used by all filters.

PDAF-OMI provides several observation operators. For example the observation operator for observations that are grid point values is called as:

    CALL PDAFomi_obs_op_gridpoint(thisobs, state_p, ostate)

Here, state_p is the state vector and ostate is the observed state vector.

For more information on the available observation operator and on how to implement your own observation operator see the documentation of observation operators for OMI?.

init_dim_obs_l_TYPE

This routine initializes local observation information. The routine is only used by the domain-localized filters (LESTKF, LETKF, LSEIK, LNETF).

For the initialization the following routine is called:

    CALL PDAFomi_init_dim_obs_l(thisobs_l, thisobs, coords_l, &
         locweight, local_range, srange, dim_obs_l)

Here, thisobs and thisobs_l are the data-type variables obs_f and obs_l. dim_obs_l, the local size of the observation vector, is the direct output of the routine.

Implementation steps:

  • Ensure that coords_l is filled in init_dim_l_pdaf
  • Specify the localization variables (These variables are usually set in init_pdaf and included with use mod_assimilation)
    • locweight: Type of localization (see init_pdaf)
    • local_range: The localization weight radius
    • srange: The support radius of the localization

localize_covar_TYPE

This routine initializes local observation information. The routine is only used by the local EnKF (LEnKF).

For the initialization the following routine is called:

    CALL PDAFomi_localize_covar(thisobs, dim_p, locweight, local_range, srange, &
         coords_p, HP_p, HPH)

Here, thisobs is the data-type variable obs_f. HP_p and HPH are the covariance matrices projected onto the observations. The localization will be applied to these variables.

Implementation steps:

  • Ensure that coords_p is filled in localize_covar_pdafomi
  • Specify the localization variables (These variables are usually set in init_pdaf and included with use mod_assimilation)
    • locweight: Type of localization (see init_pdaf)
    • local_range: The localization weight radius
    • srange: The support radius of the localization

Implementing a new observation type

To implement a new observation type, the approach is generally as follows:

  1. Create a copy of obs_TYPE_pdafomi_TEMPLATE.F90
  2. Rename the module and its subroutines according to the observation (replacing ‘TYPE’ by name of observation).
  3. Implement init_dim_obs for the observation type following the instructions in the template
  4. Adapt obs_obs for the observation type
  5. Adapt init_dim_obs_l for the observation type (if using a domain_localized filter)
  6. Adapt localize_covar for the observation type (if using a the local EnKF)
  7. Add subroutine calls for the new observation type into the routines in callback_obs_pdafomi.F90