= PDAF-OMI Debugging Information = {{{ #!html
}}} [[PageOutline(2-3,Contents of this page)]] == Overview == When implementing an observation with PDAF, or when performing the very first implementation of PDAF with a new model, it is useful to check whether the inputs to the PDAF-routines are correctly used. For this porpose, PDAF-OMI provides a debugging functionality. It allows you to activate debugging output e.g. for a single local analysis domain on a single process of a complex application of a local filter like LEKSTF. == Activating Debugging Output == Debugging output is activated by the routine `PDAFomi_set_debug_flag`. In particular this call can be inserted in any routines contained in `callback_obs_pdafomi.F90`. For example to activate debugging in `init_dim_obs_l_pdafomi` for the local analysis domain `domain_p=10` and filter process 0, one uses {{{ SUBROUTINE init_dim_obs_l_pdafomi(domain_p, step, dim_obs, dim_obs_l) USE PDAFomi, ONLY: PDAFomi_set_debug_flag USE mod_parallel_pdaf, ONLY: mype_filter ... IF (domain_p==10 .AND. mype_filter==0) THEN CALL PDAFomi_set_debug_flag(domain_p) ELSE CALL PDAFomi_set_debug_flag(0) ENDIF ... }}} == Understanding the Debugging Output == The debugging output mainly writes information about the different variables contained in the full data type `obs_f` allocated as `thisobs` and the local type `obs_l` allocate as `thisobs_l`. For reference we list the full declaration of these types. When reading the debugging output one can check for the meaning of the variables. {{{ 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 INTEGER :: ncoord !< Number of coordinates use for distance computation INTEGER, ALLOCATABLE :: id_obs_p(:,:) !< Indices of process-local observed field in state vector ! ---- 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 ! ---- The following variables are set in the routine PDAFomi_gather_obs --- INTEGER :: dim_obs_p !< number of PE-local observations INTEGER :: dim_obs_f !< number of full observations INTEGER :: dim_obs_g !< global number of observations INTEGER :: off_obs_f !< Offset of this observation in overall full obs. vector INTEGER :: off_obs_g !< Offset of this observation in overall global obs. vector INTEGER :: obsid !< Index of observation over all assimilated observations REAL, ALLOCATABLE :: obs_f(:) !< Full observed field REAL, ALLOCATABLE :: ocoord_f(:,:) !< Coordinates of full observation vector REAL, ALLOCATABLE :: ivar_obs_f(:) !< Inverse variance of full observations INTEGER, ALLOCATABLE :: id_obs_f_lim(:) !< Indices of domain-relevant full obs. in global vector of obs. END TYPE obs_f }}} {{{ TYPE obs_l INTEGER :: dim_obs_l !< number of local observations INTEGER :: off_obs_l !< Offset of this observation in overall local obs. vector INTEGER, ALLOCATABLE :: id_obs_l(:) !< Indices of local observations in full obs. vector REAL, ALLOCATABLE :: distance_l(:) !< Distances of local observations REAL, ALLOCATABLE :: ivar_obs_l(:) !< Inverse variance of local observations INTEGER :: locweight !< Specify localization function REAL :: lradius !< localization radius REAL :: sradius !< support radius for localization function END TYPE obs_l }}} === Example output === For illustration we insert the above call to PDAFomi_set_debug flag into `init_dim_obs_l_pdafomi` in `tutorial/online_2D_serialmodel_omi/`. then we compile and execute the tutorial program with: {{{ mpirun -np 4 ./model_pdaf -dim_ens 4 -filtertype 7 -local_range 5 -locweight 2 -assim_B .true. -assim_A .false. }}} With these settings only observation type B is activated, which are just 3 values in the model domain The first lines of the debugging output looks like this: {{{ ++ OMI-debug set_debug_flag: mype_filter 0 activate 10 ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- START ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- count local observations ++ OMI-debug init_dim_obs_l: 10 Re-init dim_obs_l=0 ++ OMI-debug init_dim_obs_l: 10 coords_l 1.0000000000000000 10.000000000000000 ++ OMI-debug cnt_dim_obs_l: 10 thisobs%ncoord 2 ++ OMI-debug cnt_dim_obs_l: 10 thisobs_l%lradius 5.0000000000000000 ++ OMI-debug cnt_dim_obs_l: 10 Check for observations within radius ++ OMI-debug comp_dist2: 10 compute Cartesian distance ++ OMI-debug cnt_dim_obs_l: 10 valid observation with coordinates 5.0000000000000000 8.0000000000000000 ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- initialize local observation arrays ++ OMI-debug comp_dist2: 10 compute Cartesian distance ++ OMI-debug init_dim_obs_l: 10 thisobs_l%dim_obs_l 1 ++ OMI-debug init_dim_obs_l: 10 thisobs_l%id_obs_l 1 ++ OMI-debug init_dim_obs_l: 10 thisobs_l%distance_l 4.4721359549995796 ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- END }}} The first line {{{ ++ OMI-debug set_debug_flag: mype_filter 0 activate 10 }}} is from PDAFomi_set_debug_flag showing that debugging is activates with value 10 (which is values fo `domain_p` specified in the call) The next lines are {{{ ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- START ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- count local observations ++ OMI-debug init_dim_obs_l: 10 Re-init dim_obs_l=0 }}} show that debugging output for PDAFomi_init_dim_obs_l is shown. Most routines show such a 'START' line. The second line shows that a segment of the orutine started, the counting of local observations. The third line states that dim_obs_l=0 is set. This line, as many others shows the name of the subroutine in short form without `PDAFomi` at the beginning of the line. The following lines show variable values {{{ ++ OMI-debug init_dim_obs_l: 10 coords_l 1.0000000000000000 10.000000000000000 ++ OMI-debug cnt_dim_obs_l: 10 thisobs%ncoord 2 ++ OMI-debug cnt_dim_obs_l: 10 thisobs_l%lradius 5.0000000000000000 }}} First we see that the coordinates `coords_l` of the grid point corresponding to domain_p=10 are (1.0, 10.0). Further we have two dimensions (thisobs%ncoord=2) and the localization radius is set to 5.0. In the following lines {{{ ++ OMI-debug cnt_dim_obs_l: 10 Check for observations within radius ++ OMI-debug comp_dist2: 10 compute Cartesian distance ++ OMI-debug cnt_dim_obs_l: 10 valid observation with coordinates 5.0000000000000000 8.0000000000000000 }}} the it is checked which observations lie within the distance thisobs_l%lradius=5.0 from coords_l=(1.0, 5.0). One observation with coordinates (5.0, 8.0) is found. The followign lines {{{ ++ OMI-debug: 10 PDAFomi_init_dim_obs_l -- initialize local observation arrays ++ OMI-debug comp_dist2: 10 compute Cartesian distance ++ OMI-debug init_dim_obs_l: 10 thisobs_l%dim_obs_l 1 ++ OMI-debug init_dim_obs_l: 10 thisobs_l%id_obs_l 1 ++ OMI-debug init_dim_obs_l: 10 thisobs_l%distance_l 4.4721359549995796 }}} show that observation arrays are initialized. A Cartesian distance is computerd. `thisobs_l%dim_obs_l` confirms that one local observation was found and it's the first element of the full observation vector (thisobs_l%id_obs_l=1) and the distance is thisobs_l%distance_l=4.4721359549995796. One could now compare this with the input information. Are the values of coords_l correct? Are the coordinates of the first observation (5.0, 8.0)? Later in the debugging output (not shown above) we find, for example, {{{ ++ OMI-debug: 10 PDAFomi_init_obs_l -- Get local vector of observations ++ OMI-debug g2l_obs: 10 thisobs%id_obs_l 1 ++ OMI-debug g2l_obs: 10 obs_l -0.98253999999999997 ++ OMI-debug: 10 PDAFomi_init_obs_l -- Get local vector of inverse obs. variances ++ OMI-debug g2l_obs: 10 thisobs%id_obs_l 1 ++ OMI-debug g2l_obs: 10 obs_l 4.0000000000000000 }}} These lines are from the internal routine `PDAFomi_init_obs_l`, which initializes the local vector of observations. (This is functionality also existing in the 'traditional' form of implementing the observation. The documention page about [wiki:init_obs_l_pdaf init_obs_l_pdaf] explains what is done here.) Important is that not only the local observation vector (a single value) is initialized, but also the inverse observation variance (4.0 in this example). Similarly {{{ ++ OMI-debug: 10 PDAFomi_g2l_obs -- START Get local observed ensemble member 1 ++ OMI-debug g2l_obs: 10 thisobs%id_obs_l 1 ++ OMI-debug g2l_obs: 10 obs_l 0.12725110911115362 ++ OMI-debug: 10 PDAFomi_g2l_obs -- END }}} shows the localization of ensemble member 1. This is performed in the interval routine `PDAFomi_g2l_obs` (see the page about [wiki:g2l_obs_pdaf g2l_obs_pdaf]). There is analogous output for all of the 4 ensemble states.