Index: branches/UKMO/dev_r5518_AMM15_package/.project
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/.project	(revision 10247)
+++ branches/UKMO/dev_r5518_AMM15_package/.project	(revision 10247)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dev_r5518_obs_oper_update</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/CONFIG/SHARED/namelist_ref
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/CONFIG/SHARED/namelist_ref	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/CONFIG/SHARED/namelist_ref	(revision 10247)
@@ -1193,64 +1193,103 @@
 &namobs       !  observation usage switch                               ('key_diaobs')
 !-----------------------------------------------------------------------
-   ln_t3d     = .false.    ! Logical switch for T profile observations
-   ln_s3d     = .false.    ! Logical switch for S profile observations
-   ln_ena     = .false.    ! Logical switch for ENACT insitu data set
-   !                       !     ln_cor                  Logical switch for Coriolis insitu data set
-   ln_profb   = .false.    ! Logical switch for feedback insitu data set
-   ln_sla     = .false.    ! Logical switch for SLA observations
-
-   ln_sladt   = .false.    ! Logical switch for AVISO SLA data
-
-   ln_slafb   = .false.    ! Logical switch for feedback SLA data
-                           !     ln_ssh                  Logical switch for SSH observations
-
-   ln_sst     = .false.     ! Logical switch for SST observations
-   ln_reysst  = .false.     !     ln_reysst               Logical switch for Reynolds observations
-   ln_ghrsst  = .false.    !     ln_ghrsst               Logical switch for GHRSST observations
-
-   ln_sstfb   = .false.    ! Logical switch for feedback SST data
-                           !     ln_sss                  Logical switch for SSS observations
-   ln_seaice  = .false.    ! Logical switch for Sea Ice observations
-                           !     ln_vel3d                Logical switch for velocity observations
-                           !     ln_velavcur             Logical switch for velocity daily av. cur.
-                           !     ln_velhrcur             Logical switch for velocity high freq. cur.
-                           !     ln_velavadcp            Logical switch for velocity daily av. ADCP
-                           !     ln_velhradcp            Logical switch for velocity high freq. ADCP
-                           !     ln_velfb                Logical switch for feedback velocity data
-                           !     ln_grid_global          Global distribtion of observations
-                           !     ln_grid_search_lookup   Logical switch for obs grid search w/lookup table
-                           !     grid_search_file        Grid search lookup file header
-                           !     enactfiles              ENACT input observation file names
-                           !     coriofiles              Coriolis input observation file name
-   !                       ! profbfiles: Profile feedback input observation file name
-   profbfiles = 'profiles_01.nc'
-                           !     ln_profb_enatim         Enact feedback input time setting switch
-                           !     slafilesact             Active SLA input observation file name
-                           !     slafilespas             Passive SLA input observation file name
-   !                       ! slafbfiles: Feedback SLA input observation file name
-   slafbfiles = 'sla_01.nc'
-                           !     sstfiles                GHRSST input observation file name
-   !                       ! sstfbfiles: Feedback SST input observation file name
-   sstfbfiles = 'sst_01.nc'
-                           !     seaicefiles             Sea Ice input observation file names
-   seaicefiles = 'seaice_01.nc'
-                           !     velavcurfiles           Vel. cur. daily av. input file name
-                           !     velhvcurfiles           Vel. cur. high freq. input file name
-                           !     velavadcpfiles          Vel. ADCP daily av. input file name
-                           !     velhvadcpfiles          Vel. ADCP high freq. input file name
-                           !     velfbfiles              Vel. feedback input observation file name
-                           !     dobsini                 Initial date in window YYYYMMDD.HHMMSS
-                           !     dobsend                 Final date in window YYYYMMDD.HHMMSS
-                           !     n1dint                  Type of vertical interpolation method
-                           !     n2dint                  Type of horizontal interpolation method
-                           !     ln_nea                  Rejection of observations near land switch
-   nmsshc     = 0          ! MSSH correction scheme
-                           !     mdtcorr                 MDT  correction
-                           !     mdtcutoff               MDT cutoff for computed correction
-   ln_altbias = .false.    ! Logical switch for alt bias
-   ln_ignmis  = .true.     ! Logical switch for ignoring missing files
-                           !     endailyavtypes   ENACT daily average types
-   ln_grid_global = .true.
-   ln_grid_search_lookup = .false.
+   ln_diaobs  = .false.             ! Logical switch for the observation operator
+   ln_t3d     = .false.             ! Logical switch for T profile observations
+   ln_s3d     = .false.             ! Logical switch for S profile observations
+   ln_sla     = .false.             ! Logical switch for SLA observations
+   ln_sst     = .false.             ! Logical switch for SST observations
+   ln_sic     = .false.             ! Logical switch for Sea Ice observations
+   ln_vel3d   = .false.             ! Logical switch for velocity observations
+   ln_sss     = .false.             ! Logical swithc for SSS observations
+   ln_slchltot = .false.            ! Logical switch for surface total              log10(chlorophyll) obs
+   ln_slchldia = .false.            ! Logical switch for surface diatom             log10(chlorophyll) obs
+   ln_slchlnon = .false.            ! Logical switch for surface non-diatom         log10(chlorophyll) obs
+   ln_slchldin = .false.            ! Logical switch for surface dinoflagellate     log10(chlorophyll) obs
+   ln_slchlmic = .false.            ! Logical switch for surface microphytoplankton log10(chlorophyll) obs
+   ln_slchlnan = .false.            ! Logical switch for surface nanophytoplankton  log10(chlorophyll) obs
+   ln_slchlpic = .false.            ! Logical switch for surface picophytoplankton  log10(chlorophyll) obs
+   ln_schltot  = .false.            ! Logical switch for surface total              chlorophyll        obs
+   ln_slphytot = .false.            ! Logical switch for surface total      log10(phytoplankton carbon) obs
+   ln_slphydia = .false.            ! Logical switch for surface diatom     log10(phytoplankton carbon) obs
+   ln_slphynon = .false.            ! Logical switch for surface non-diatom log10(phytoplankton carbon) obs
+   ln_sspm     = .false.            ! Logical switch for surface suspended particulate matter obs
+   ln_sfco2    = .false.            ! Logical switch for surface fugacity         of carbon dioxide obs
+   ln_spco2    = .false.            ! Logical switch for surface partial pressure of carbon dioxide obs
+   ln_plchltot = .false.            ! Logical switch for profile total log10(chlorophyll) obs
+   ln_pchltot  = .false.            ! Logical switch for profile total chlorophyll obs
+   ln_pno3     = .false.            ! Logical switch for profile nitrate obs
+   ln_psi4     = .false.            ! Logical switch for profile silicate obs
+   ln_ppo4     = .false.            ! Logical switch for profile phosphate obs
+   ln_pdic     = .false.            ! Logical switch for profile dissolved inorganic carbon obs
+   ln_palk     = .false.            ! Logical switch for profile alkalinity obs
+   ln_pph      = .false.            ! Logical switch for profile pH obs
+   ln_po2      = .false.            ! Logical switch for profile dissolved oxygen obs
+   ln_altbias = .false.             ! Logical switch for altimeter bias correction
+   ln_sstbias = .false.             ! Logical switch for SST bias correction
+   ln_nea     = .false.             ! Logical switch for rejection of observations near land
+   ln_grid_global = .true.          ! Logical switch for global distribution of observations
+   ln_grid_search_lookup = .false.  ! Logical switch for obs grid search w/lookup table
+   ln_ignmis  = .true.              ! Logical switch for ignoring missing files
+   ln_s_at_t  = .false.             ! Logical switch for computing model S at T obs if not there
+   ln_sstnight = .false.            ! Logical switch for calculating night-time average for SST obs
+   ln_default_fp_indegs = .true.    ! Logical: T=> averaging footprint is in degrees, F=> in metres
+   ln_sla_fp_indegs = .true.        ! Logical: T=> averaging footprint is in degrees, F=> in metres
+   ln_sst_fp_indegs = .true.
+   ln_sss_fp_indegs = .true.
+   ln_sic_fp_indegs = .true.
+! All of the *files* variables below are arrays. Use namelist_cfg to add more files
+   cn_profbfiles = 'profiles_01.nc'      ! Profile feedback input observation file names
+   cn_slafbfiles = 'sla_01.nc'           ! SLA feedback input observation file names
+   cn_sstfbfiles = 'sst_01.nc'           ! SST feedback input observation file names
+   cn_sicfbfiles = 'sic_01.nc'           ! SIC feedback input observation file names
+   cn_velfbfiles = 'vel_01.nc'           ! Velocity feedback input observation file names
+   cn_sssfbfiles = 'sss_01.nc'           ! SSS feedback input observation file names
+   cn_slchltotfbfiles = 'slchltot_01.nc' ! Surface total              log10(chlorophyll) obs file names
+   cn_slchldiafbfiles = 'slchldia_01.nc' ! Surface diatom             log10(chlorophyll) obs file names
+   cn_slchlnonfbfiles = 'slchlnon_01.nc' ! Surface non-diatom         log10(chlorophyll) obs file names
+   cn_slchldinfbfiles = 'slchldin_01.nc' ! Surface dinoflagellate     log10(chlorophyll) obs file names
+   cn_slchlmicfbfiles = 'slchlmic_01.nc' ! Surface microphytoplankton log10(chlorophyll) obs file names
+   cn_slchlnanfbfiles = 'slchlnan_01.nc' ! Surface nanophytoplankton  log10(chlorophyll) obs file names
+   cn_slchlpicfbfiles = 'slchlpic_01.nc' ! Surface picophytoplankton  log10(chlorophyll) obs file names
+   cn_schltotfbfiles  = 'schltot_01.nc'  ! Surface total              chlorophyll        obs file names
+   cn_slphytotfbfiles = 'slphytot_01.nc' ! Surface total      log10(phytoplankton carbon) obs file names
+   cn_slphydiafbfiles = 'slphydia_01.nc' ! Surface diatom     log10(phytoplankton carbon) obs file names
+   cn_slphynonfbfiles = 'slphynon_01.nc' ! Surface non-diatom log10(phytoplankton carbon) obs file names
+   cn_sspmfbfiles     = 'sspm_01.nc'     ! Surface suspended particulate matter obs file names
+   cn_sfco2fbfiles    = 'sfco2_01.nc'    ! Surface fugacity         of carbon dioxide obs file names
+   cn_spco2fbfiles    = 'spco2_01.nc'    ! Surface partial pressure of carbon dioxide obs file names
+   cn_plchltotfbfiles = 'plchltot_01.nc' ! Profile total log10(chlorophyll) obs file names
+   cn_pchltotfbfiles  = 'pchltot_01.nc'  ! Profile total chlorophyll obs file names
+   cn_pno3fbfiles     = 'pno3_01.nc'     ! Profile nitrate obs file names
+   cn_psi4fbfiles     = 'psi4_01.nc'     ! Profile silicate obs file names
+   cn_ppo4fbfiles     = 'ppo4_01.nc'     ! Profile phosphate obs file names
+   cn_pdicfbfiles     = 'pdic_01.nc'     ! Profile dissolved inorganic carbon obs file names
+   cn_palkfbfiles     = 'palk_01.nc'     ! Profile alkalinity obs file names
+   cn_pphfbfiles      = 'pph_01.nc'      ! Profile pH obs file names
+   cn_po2fbfiles      = 'po2_01.nc'      ! Profile dissolved oxygen obs file names
+   cn_altbiasfile = 'altbias.nc'         ! Altimeter bias input file name
+   cn_sstbiasfiles = 'sstbias.nc'        ! SST bias input file names
+   cn_gridsearchfile = 'gridsearch.nc'   ! Grid search file name
+   rn_gridsearchres = 0.5                ! Grid search resolution
+   rn_default_avglamscl = 0.             ! Default E/W diameter of observation footprint (metres/degrees)
+   rn_default_avgphiscl = 0.             ! Default N/S diameter of observation footprint (metres/degrees)
+   rn_sla_avglamscl = 0.                 ! E/W diameter of SLA observation footprint (metres/degrees)
+   rn_sla_avgphiscl = 0.                 ! N/S diameter of SLA observation footprint (metres/degrees)
+   rn_sst_avglamscl = 0.                 ! E/W diameter of SST observation footprint (metres/degrees)
+   rn_sst_avgphiscl = 0.                 ! N/S diameter of SST observation footprint (metres/degrees)
+   rn_sss_avglamscl = 0.                 ! E/W diameter of SSS observation footprint (metres/degrees)
+   rn_sss_avgphiscl = 0.                 ! N/S diameter of SSS observation footprint (metres/degrees)
+   rn_sic_avglamscl = 0.                 ! E/W diameter of SIC observation footprint (metres/degrees)
+   rn_sic_avgphiscl = 0.                 ! N/S diameter of SIC observation footprint (metres/degrees)
+   nn_1dint = 0                          ! Type of vertical interpolation method
+   nn_2dint_default = 0                  ! Default horizontal interpolation method
+   nn_2dint_sla = -1                     ! Horizontal interpolation method for SLA
+   nn_2dint_sst = -1                     ! Horizontal interpolation method for SST
+   nn_2dint_sss = -1                     ! Horizontal interpolation method for SSS
+   nn_2dint_sic = -1                     ! Horizontal interpolation method for SIC
+   nn_msshc = 0                          ! MSSH correction scheme
+   rn_mdtcorr = 1.61                     ! MDT  correction
+   rn_mdtcutoff = 65.0                   ! MDT cutoff for computed correction
+   nn_profdavtypes = -1                  ! Profile daily average types - array
+   
 /
 !-----------------------------------------------------------------------
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ASM/asminc.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ASM/asminc.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ASM/asminc.F90	(revision 10247)
@@ -72,7 +72,5 @@
    REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE ::   u_bkginc, v_bkginc   !: Increment to the u- & v-components 
    REAL(wp), PUBLIC, DIMENSION(:)    , ALLOCATABLE ::   wgtiau               !: IAU weights for each time step
-#if defined key_asminc
    REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   ssh_iau           !: IAU-weighted sea surface height increment
-#endif
    !                                !!! time steps relative to the cycle interval [0,nitend-nit000-1]
    INTEGER , PUBLIC ::   nitbkg      !: Time step of the background state used in the Jb term
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/DYN/dynspg_ts.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/DYN/dynspg_ts.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/DYN/dynspg_ts.F90	(revision 10247)
@@ -465,6 +465,6 @@
       ENDIF
 #endif
-      !                                   !* Fill boundary data arrays with AGRIF
-      !                                   ! -------------------------------------
+      !                                   !* Fill boundary data arrays for AGRIF
+      !                                   ! ------------------------------------
 #if defined key_agrif
          IF( .NOT.Agrif_Root() ) CALL agrif_dta_ts( kt )
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/diaobs.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/diaobs.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/diaobs.F90	(revision 10247)
@@ -6,6 +6,4 @@
    !!======================================================================
 
-   !!----------------------------------------------------------------------
-   !!   'key_diaobs' : Switch on the observation diagnostic computation
    !!----------------------------------------------------------------------
    !!   dia_obs_init : Reading and prepare observations
@@ -15,5 +13,5 @@
    !!   fin_date     : Compute the final date YYYYMMDD.HHMMSS
    !!----------------------------------------------------------------------
-   !! * Modules used   
+   !! * Modules used
    USE wrk_nemo                 ! Memory Allocation
    USE par_kind                 ! Precision variables
@@ -21,11 +19,7 @@
    USE par_oce
    USE dom_oce                  ! Ocean space and time domain variables
-   USE obs_fbm, ONLY: ln_cl4    ! Class 4 diagnostic switch
-   USE obs_read_prof            ! Reading and allocation of observations (Coriolis)
-   USE obs_read_sla             ! Reading and allocation of SLA observations  
-   USE obs_read_sst             ! Reading and allocation of SST observations  
+   USE obs_read_prof            ! Reading and allocation of profile obs
+   USE obs_read_surf            ! Reading and allocation of surface obs
    USE obs_readmdt              ! Reading and allocation of MDT for SLA.
-   USE obs_read_seaice          ! Reading and allocation of Sea Ice observations  
-   USE obs_read_vel             ! Reading and allocation of velocity component observations
    USE obs_prep                 ! Preparation of obs. (grid search etc).
    USE obs_oper                 ! Observation operators
@@ -33,10 +27,7 @@
    USE obs_grid                 ! Grid searching
    USE obs_read_altbias         ! Bias treatment for altimeter
+   USE obs_sstbias              ! Bias correction routine for SST
    USE obs_profiles_def         ! Profile data definitions
-   USE obs_profiles             ! Profile data storage
    USE obs_surf_def             ! Surface data definitions
-   USE obs_sla                  ! SLA data storage
-   USE obs_sst                  ! SST data storage
-   USE obs_seaice               ! Sea Ice data storage
    USE obs_types                ! Definitions for observation types
    USE mpp_map                  ! MPP mapping
@@ -52,63 +43,62 @@
       &   dia_obs_dealloc  ! Deallocate dia_obs data
 
-   !! * Shared Module variables
-   LOGICAL, PUBLIC, PARAMETER :: &
-#if defined key_diaobs
-      & lk_diaobs = .TRUE.   !: Logical switch for observation diangostics
-#else
-      & lk_diaobs = .FALSE.  !: Logical switch for observation diangostics
-#endif
-
    !! * Module variables
-   LOGICAL, PUBLIC :: ln_t3d         !: Logical switch for temperature profiles
-   LOGICAL, PUBLIC :: ln_s3d         !: Logical switch for salinity profiles
-   LOGICAL, PUBLIC :: ln_ena         !: Logical switch for the ENACT data set
-   LOGICAL, PUBLIC :: ln_cor         !: Logical switch for the Coriolis data set
-   LOGICAL, PUBLIC :: ln_profb       !: Logical switch for profile feedback datafiles
-   LOGICAL, PUBLIC :: ln_sla         !: Logical switch for sea level anomalies 
-   LOGICAL, PUBLIC :: ln_sladt       !: Logical switch for SLA from AVISO files
-   LOGICAL, PUBLIC :: ln_slafb       !: Logical switch for SLA from feedback files
-   LOGICAL, PUBLIC :: ln_sst         !: Logical switch for sea surface temperature
-   LOGICAL, PUBLIC :: ln_reysst      !: Logical switch for Reynolds sea surface temperature
-   LOGICAL, PUBLIC :: ln_ghrsst      !: Logical switch for GHRSST data
-   LOGICAL, PUBLIC :: ln_sstfb       !: Logical switch for SST from feedback files
-   LOGICAL, PUBLIC :: ln_seaice      !: Logical switch for sea ice concentration
-   LOGICAL, PUBLIC :: ln_vel3d       !: Logical switch for velocity component (u,v) observations
-   LOGICAL, PUBLIC :: ln_velavcur    !: Logical switch for raw daily averaged netCDF current meter vel. data 
-   LOGICAL, PUBLIC :: ln_velhrcur    !: Logical switch for raw high freq netCDF current meter vel. data 
-   LOGICAL, PUBLIC :: ln_velavadcp   !: Logical switch for raw daily averaged netCDF ADCP vel. data 
-   LOGICAL, PUBLIC :: ln_velhradcp   !: Logical switch for raw high freq netCDF ADCP vel. data 
-   LOGICAL, PUBLIC :: ln_velfb       !: Logical switch for velocities from feedback files
-   LOGICAL, PUBLIC :: ln_ssh         !: Logical switch for sea surface height
-   LOGICAL, PUBLIC :: ln_sss         !: Logical switch for sea surface salinity
-   LOGICAL, PUBLIC :: ln_sstnight    !: Logical switch for night mean SST observations
-   LOGICAL, PUBLIC :: ln_nea         !: Remove observations near land
-   LOGICAL, PUBLIC :: ln_altbias     !: Logical switch for altimeter bias  
-   LOGICAL, PUBLIC :: ln_ignmis      !: Logical switch for ignoring missing files
-   LOGICAL, PUBLIC :: ln_s_at_t      !: Logical switch to compute model S at T observations
-
-   REAL(KIND=dp), PUBLIC :: dobsini   !: Observation window start date YYYYMMDD.HHMMSS
-   REAL(KIND=dp), PUBLIC :: dobsend   !: Observation window end date YYYYMMDD.HHMMSS
-  
-   INTEGER, PUBLIC :: n1dint       !: Vertical interpolation method
-   INTEGER, PUBLIC :: n2dint       !: Horizontal interpolation method 
-
+   LOGICAL, PUBLIC :: &
+      &       lk_diaobs = .TRUE.   !: Include this for backwards compatibility at NEMO 3.6.
+   LOGICAL :: ln_diaobs            !: Logical switch for the obs operator
+   LOGICAL :: ln_sstnight          !: Logical switch for night mean SST obs
+   LOGICAL :: ln_default_fp_indegs !: T=> Default obs footprint size specified in degrees, F=> in metres
+   LOGICAL :: ln_sla_fp_indegs     !: T=>     SLA obs footprint size specified in degrees, F=> in metres
+   LOGICAL :: ln_sst_fp_indegs     !: T=>     SST obs footprint size specified in degrees, F=> in metres
+   LOGICAL :: ln_sss_fp_indegs     !: T=>     SSS obs footprint size specified in degrees, F=> in metres
+   LOGICAL :: ln_sic_fp_indegs     !: T=> sea-ice obs footprint size specified in degrees, F=> in metres
+
+   REAL(wp) :: rn_default_avglamscl !: Default E/W diameter of observation footprint
+   REAL(wp) :: rn_default_avgphiscl !: Default N/S diameter of observation footprint
+   REAL(wp) :: rn_sla_avglamscl     !: E/W diameter of SLA observation footprint
+   REAL(wp) :: rn_sla_avgphiscl     !: N/S diameter of SLA observation footprint
+   REAL(wp) :: rn_sst_avglamscl     !: E/W diameter of SST observation footprint
+   REAL(wp) :: rn_sst_avgphiscl     !: N/S diameter of SST observation footprint
+   REAL(wp) :: rn_sss_avglamscl     !: E/W diameter of SSS observation footprint
+   REAL(wp) :: rn_sss_avgphiscl     !: N/S diameter of SSS observation footprint
+   REAL(wp) :: rn_sic_avglamscl     !: E/W diameter of sea-ice observation footprint
+   REAL(wp) :: rn_sic_avgphiscl     !: N/S diameter of sea-ice observation footprint
+
+   INTEGER :: nn_1dint         !: Vertical interpolation method
+   INTEGER :: nn_2dint_default !: Default horizontal interpolation method
+   INTEGER :: nn_2dint_sla     !: SLA horizontal interpolation method (-1 = default)
+   INTEGER :: nn_2dint_sst     !: SST horizontal interpolation method (-1 = default)
+   INTEGER :: nn_2dint_sss     !: SSS horizontal interpolation method (-1 = default)
+   INTEGER :: nn_2dint_sic     !: Seaice horizontal interpolation method (-1 = default)
+ 
    INTEGER, DIMENSION(imaxavtypes) :: &
-      & endailyavtypes !: ENACT data types which are daily average
-
-   INTEGER, PARAMETER :: MaxNumFiles = 1000
-   LOGICAL, DIMENSION(MaxNumFiles) :: &
-      & ln_profb_ena, & !: Is the feedback files from ENACT data ?
-   !                    !: If so use endailyavtypes
-      & ln_profb_enatim !: Change tim for 820 enact data set.
-   
-   LOGICAL, DIMENSION(MaxNumFiles) :: &
-      & ln_velfb_av   !: Is the velocity feedback files daily average?
+      & nn_profdavtypes      !: Profile data types representing a daily average
+   INTEGER :: nproftypes     !: Number of profile obs types
+   INTEGER :: nsurftypes     !: Number of surface obs types
+   INTEGER, DIMENSION(:), ALLOCATABLE :: &
+      & nvarsprof, &         !: Number of profile variables
+      & nvarssurf            !: Number of surface variables
+   INTEGER, DIMENSION(:), ALLOCATABLE :: &
+      & nextrprof, &         !: Number of profile extra variables
+      & nextrsurf            !: Number of surface extra variables
+   INTEGER, DIMENSION(:), ALLOCATABLE :: &
+      & n2dintsurf           !: Interpolation option for surface variables
+   REAL(wp), DIMENSION(:), ALLOCATABLE :: &
+      & ravglamscl, &        !: E/W diameter of averaging footprint for surface variables
+      & ravgphiscl           !: N/S diameter of averaging footprint for surface variables
    LOGICAL, DIMENSION(:), ALLOCATABLE :: &
-      & ld_enact     !: Profile data is ENACT so use endailyavtypes
-   LOGICAL, DIMENSION(:), ALLOCATABLE :: &
-      & ld_velav     !: Velocity data is daily averaged
-   LOGICAL, DIMENSION(:), ALLOCATABLE :: &
-      & ld_sstnight  !: SST observation corresponds to night mean
+      & lfpindegs, &         !: T=> surface obs footprint size specified in degrees, F=> in metres
+      & llnightav            !: Logical for calculating night-time averages
+
+   TYPE(obs_surf), PUBLIC, POINTER, DIMENSION(:) :: &
+      & surfdata, &          !: Initial surface data
+      & surfdataqc           !: Surface data after quality control
+   TYPE(obs_prof), PUBLIC, POINTER, DIMENSION(:) :: &
+      & profdata, &          !: Initial profile data
+      & profdataqc           !: Profile data after quality control
+
+   CHARACTER(len=8), PUBLIC, DIMENSION(:), ALLOCATABLE :: &
+      & cobstypesprof, &     !: Profile obs types
+      & cobstypessurf        !: Surface obs types
 
    !!----------------------------------------------------------------------
@@ -118,4 +108,6 @@
    !!----------------------------------------------------------------------
 
+   !! * Substitutions 
+#  include "domzgr_substitute.h90"
 CONTAINS
 
@@ -135,4 +127,6 @@
       !!        !  06-10  (A. Weaver) Cleaning and add controls
       !!        !  07-03  (K. Mogensen) General handling of profiles
+      !!        !  14-08  (J.While) Incorporated SST bias correction
+      !!        !  15-02  (M. Martin) Simplification of namelist and code
       !!----------------------------------------------------------------------
 
@@ -140,67 +134,154 @@
 
       !! * Local declarations
-      CHARACTER(len=128) :: enactfiles(MaxNumFiles)
-      CHARACTER(len=128) :: coriofiles(MaxNumFiles)
-      CHARACTER(len=128) :: profbfiles(MaxNumFiles)
-      CHARACTER(len=128) :: sstfiles(MaxNumFiles)      
-      CHARACTER(len=128) :: sstfbfiles(MaxNumFiles) 
-      CHARACTER(len=128) :: slafilesact(MaxNumFiles)      
-      CHARACTER(len=128) :: slafilespas(MaxNumFiles)      
-      CHARACTER(len=128) :: slafbfiles(MaxNumFiles)
-      CHARACTER(len=128) :: seaicefiles(MaxNumFiles)           
-      CHARACTER(len=128) :: velcurfiles(MaxNumFiles)  
-      CHARACTER(len=128) :: veladcpfiles(MaxNumFiles)    
-      CHARACTER(len=128) :: velavcurfiles(MaxNumFiles)
-      CHARACTER(len=128) :: velhrcurfiles(MaxNumFiles)
-      CHARACTER(len=128) :: velavadcpfiles(MaxNumFiles)
-      CHARACTER(len=128) :: velhradcpfiles(MaxNumFiles)
-      CHARACTER(len=128) :: velfbfiles(MaxNumFiles)
-      CHARACTER(LEN=128) :: reysstname
-      CHARACTER(LEN=12)  :: reysstfmt
-      CHARACTER(LEN=128) :: bias_file
-      CHARACTER(LEN=20)  :: datestr=" ", timestr=" "
-      NAMELIST/namobs/ln_ena, ln_cor, ln_profb, ln_t3d, ln_s3d,       &
-         &            ln_sla, ln_sladt, ln_slafb,                     &
-         &            ln_ssh, ln_sst, ln_sstfb, ln_sss, ln_nea,       &
-         &            enactfiles, coriofiles, profbfiles,             &
-         &            slafilesact, slafilespas, slafbfiles,           &
-         &            sstfiles, sstfbfiles,                           &
-         &            ln_seaice, seaicefiles,                         &
-         &            dobsini, dobsend, n1dint, n2dint,               &
-         &            nmsshc, mdtcorr, mdtcutoff,                     &
-         &            ln_reysst, ln_ghrsst, reysstname, reysstfmt,    &
-         &            ln_sstnight,                                    &
-         &            ln_grid_search_lookup,                          &
-         &            grid_search_file, grid_search_res,              &
-         &            ln_grid_global, bias_file, ln_altbias,          &
-         &            endailyavtypes, ln_s_at_t, ln_profb_ena,        &
-         &            ln_vel3d, ln_velavcur, velavcurfiles,           &
-         &            ln_velhrcur, velhrcurfiles,                     &
-         &            ln_velavadcp, velavadcpfiles,                   &
-         &            ln_velhradcp, velhradcpfiles,                   &
-         &            ln_velfb, velfbfiles, ln_velfb_av,              &
-         &            ln_profb_enatim, ln_ignmis, ln_cl4
-
-      INTEGER :: jprofset
-      INTEGER :: jveloset
-      INTEGER :: jvar
-      INTEGER :: jnumenact
-      INTEGER :: jnumcorio
-      INTEGER :: jnumprofb
-      INTEGER :: jnumslaact
-      INTEGER :: jnumslapas
-      INTEGER :: jnumslafb
-      INTEGER :: jnumsst
-      INTEGER :: jnumsstfb
-      INTEGER :: jnumseaice
-      INTEGER :: jnumvelavcur
-      INTEGER :: jnumvelhrcur  
-      INTEGER :: jnumvelavadcp
-      INTEGER :: jnumvelhradcp   
-      INTEGER :: jnumvelfb
-      INTEGER :: ji
-      INTEGER :: jset
-      INTEGER :: ios                 ! Local integer output status for namelist read
-      LOGICAL :: lmask(MaxNumFiles), ll_u3d, ll_v3d
+      INTEGER, PARAMETER :: &
+         & jpmaxnfiles = 1000    ! Maximum number of files for each obs type
+      INTEGER, DIMENSION(:), ALLOCATABLE :: &
+         & ifilesprof, &         ! Number of profile files
+         & ifilessurf            ! Number of surface files
+      INTEGER :: ios             ! Local integer output status for namelist read
+      INTEGER :: jtype           ! Counter for obs types
+      INTEGER :: jvar            ! Counter for variables
+      INTEGER :: jfile           ! Counter for files
+      INTEGER :: jnumsstbias     ! Number of SST bias files to read and apply
+      INTEGER :: n2dint_type     ! Local version of nn_2dint*
+
+      CHARACTER(len=128), DIMENSION(jpmaxnfiles) :: &
+         & cn_profbfiles,      & ! T/S profile input filenames
+         & cn_sstfbfiles,      & ! Sea surface temperature input filenames
+         & cn_slafbfiles,      & ! Sea level anomaly input filenames
+         & cn_sicfbfiles,      & ! Seaice concentration input filenames
+         & cn_velfbfiles,      & ! Velocity profile input filenames
+         & cn_sssfbfiles,      & ! Sea surface salinity input filenames
+         & cn_slchltotfbfiles, & ! Surface total              log10(chlorophyll) input filenames
+         & cn_slchldiafbfiles, & ! Surface diatom             log10(chlorophyll) input filenames
+         & cn_slchlnonfbfiles, & ! Surface non-diatom         log10(chlorophyll) input filenames
+         & cn_slchldinfbfiles, & ! Surface dinoflagellate     log10(chlorophyll) input filenames
+         & cn_slchlmicfbfiles, & ! Surface microphytoplankton log10(chlorophyll) input filenames
+         & cn_slchlnanfbfiles, & ! Surface nanophytoplankton  log10(chlorophyll) input filenames
+         & cn_slchlpicfbfiles, & ! Surface picophytoplankton  log10(chlorophyll) input filenames
+         & cn_schltotfbfiles,  & ! Surface total              chlorophyll        input filenames
+         & cn_slphytotfbfiles, & ! Surface total      log10(phytoplankton carbon) input filenames
+         & cn_slphydiafbfiles, & ! Surface diatom     log10(phytoplankton carbon) input filenames
+         & cn_slphynonfbfiles, & ! Surface non-diatom log10(phytoplankton carbon) input filenames
+         & cn_sspmfbfiles,     & ! Surface suspended particulate matter input filenames
+         & cn_sfco2fbfiles,    & ! Surface fugacity         of carbon dioxide input filenames
+         & cn_spco2fbfiles,    & ! Surface partial pressure of carbon dioxide input filenames
+         & cn_plchltotfbfiles, & ! Profile total log10(chlorophyll) input filenames
+         & cn_pchltotfbfiles,  & ! Profile total chlorophyll input filenames
+         & cn_pno3fbfiles,     & ! Profile nitrate input filenames
+         & cn_psi4fbfiles,     & ! Profile silicate input filenames
+         & cn_ppo4fbfiles,     & ! Profile phosphate input filenames
+         & cn_pdicfbfiles,     & ! Profile dissolved inorganic carbon input filenames
+         & cn_palkfbfiles,     & ! Profile alkalinity input filenames
+         & cn_pphfbfiles,      & ! Profile pH input filenames
+         & cn_po2fbfiles,      & ! Profile dissolved oxygen input filenames
+         & cn_sstbiasfiles       ! SST bias input filenames
+
+      CHARACTER(LEN=128) :: &
+         & cn_altbiasfile        ! Altimeter bias input filename
+
+
+      LOGICAL :: ln_t3d          ! Logical switch for temperature profiles
+      LOGICAL :: ln_s3d          ! Logical switch for salinity profiles
+      LOGICAL :: ln_sla          ! Logical switch for sea level anomalies 
+      LOGICAL :: ln_sst          ! Logical switch for sea surface temperature
+      LOGICAL :: ln_sic          ! Logical switch for sea ice concentration
+      LOGICAL :: ln_sss          ! Logical switch for sea surface salinity obs
+      LOGICAL :: ln_vel3d        ! Logical switch for velocity (u,v) obs
+      LOGICAL :: ln_slchltot     ! Logical switch for surface total              log10(chlorophyll) obs
+      LOGICAL :: ln_slchldia     ! Logical switch for surface diatom             log10(chlorophyll) obs
+      LOGICAL :: ln_slchlnon     ! Logical switch for surface non-diatom         log10(chlorophyll) obs
+      LOGICAL :: ln_slchldin     ! Logical switch for surface dinoflagellate     log10(chlorophyll) obs
+      LOGICAL :: ln_slchlmic     ! Logical switch for surface microphytoplankton log10(chlorophyll) obs
+      LOGICAL :: ln_slchlnan     ! Logical switch for surface nanophytoplankton  log10(chlorophyll) obs
+      LOGICAL :: ln_slchlpic     ! Logical switch for surface picophytoplankton  log10(chlorophyll) obs
+      LOGICAL :: ln_schltot      ! Logical switch for surface total              chlorophyll        obs
+      LOGICAL :: ln_slphytot     ! Logical switch for surface total      log10(phytoplankton carbon) obs
+      LOGICAL :: ln_slphydia     ! Logical switch for surface diatom     log10(phytoplankton carbon) obs
+      LOGICAL :: ln_slphynon     ! Logical switch for surface non-diatom log10(phytoplankton carbon) obs
+      LOGICAL :: ln_sspm         ! Logical switch for surface suspended particulate matter obs
+      LOGICAL :: ln_sfco2        ! Logical switch for surface fugacity         of carbon dioxide obs
+      LOGICAL :: ln_spco2        ! Logical switch for surface partial pressure of carbon dioxide obs
+      LOGICAL :: ln_plchltot     ! Logical switch for profile total log10(chlorophyll) obs
+      LOGICAL :: ln_pchltot      ! Logical switch for profile total chlorophyll obs
+      LOGICAL :: ln_pno3         ! Logical switch for profile nitrate obs
+      LOGICAL :: ln_psi4         ! Logical switch for profile silicate obs
+      LOGICAL :: ln_ppo4         ! Logical switch for profile phosphate obs
+      LOGICAL :: ln_pdic         ! Logical switch for profile dissolved inorganic carbon obs
+      LOGICAL :: ln_palk         ! Logical switch for profile alkalinity obs
+      LOGICAL :: ln_pph          ! Logical switch for profile pH obs
+      LOGICAL :: ln_po2          ! Logical switch for profile dissolved oxygen obs
+      LOGICAL :: ln_nea          ! Logical switch to remove obs near land
+      LOGICAL :: ln_altbias      ! Logical switch for altimeter bias
+      LOGICAL :: ln_sstbias      ! Logical switch for bias correction of SST
+      LOGICAL :: ln_ignmis       ! Logical switch for ignoring missing files
+      LOGICAL :: ln_s_at_t       ! Logical switch to compute model S at T obs
+      LOGICAL :: ln_bound_reject ! Logical switch for rejecting obs near the boundary
+
+      REAL(dp) :: rn_dobsini     ! Obs window start date YYYYMMDD.HHMMSS
+      REAL(dp) :: rn_dobsend     ! Obs window end date   YYYYMMDD.HHMMSS
+
+      REAL(wp) :: ztype_avglamscl ! Local version of rn_*_avglamscl
+      REAL(wp) :: ztype_avgphiscl ! Local version of rn_*_avgphiscl
+
+      CHARACTER(len=128), DIMENSION(:,:), ALLOCATABLE :: &
+         & clproffiles, &        ! Profile filenames
+         & clsurffiles           ! Surface filenames
+
+      LOGICAL, DIMENSION(:), ALLOCATABLE :: llvar   ! Logical for profile variable read
+      LOGICAL :: ltype_fp_indegs ! Local version of ln_*_fp_indegs
+      LOGICAL :: ltype_night     ! Local version of ln_sstnight (false for other variables)
+
+      REAL(wp), POINTER, DIMENSION(:,:,:) :: &
+         & zglam                 ! Model longitudes for profile variables
+      REAL(wp), POINTER, DIMENSION(:,:,:) :: &
+         & zgphi                 ! Model latitudes for profile variables
+      REAL(wp), POINTER, DIMENSION(:,:,:,:) :: &
+         & zmask                 ! Model land/sea mask associated with variables
+
+
+      NAMELIST/namobs/ln_diaobs, ln_t3d, ln_s3d, ln_sla,              &
+         &            ln_sst, ln_sic, ln_sss, ln_vel3d,               &
+         &            ln_slchltot, ln_slchldia, ln_slchlnon,          &
+         &            ln_slchldin, ln_slchlmic, ln_slchlnan,          &
+         &            ln_slchlpic, ln_schltot,                        &
+         &            ln_slphytot, ln_slphydia, ln_slphynon,          &
+         &            ln_sspm,     ln_sfco2,    ln_spco2,             &
+         &            ln_plchltot, ln_pchltot,  ln_pno3,              &
+         &            ln_psi4,     ln_ppo4,     ln_pdic,              &
+         &            ln_palk,     ln_pph,      ln_po2,               &
+         &            ln_altbias, ln_sstbias, ln_nea,                 &
+         &            ln_grid_global, ln_grid_search_lookup,          &
+         &            ln_ignmis, ln_s_at_t, ln_bound_reject,          &
+         &            ln_sstnight, ln_default_fp_indegs,              &
+         &            ln_sla_fp_indegs, ln_sst_fp_indegs,             &
+         &            ln_sss_fp_indegs, ln_sic_fp_indegs,             &
+         &            cn_profbfiles, cn_slafbfiles,                   &
+         &            cn_sstfbfiles, cn_sicfbfiles,                   &
+         &            cn_velfbfiles, cn_sssfbfiles,                   &
+         &            cn_slchltotfbfiles, cn_slchldiafbfiles,         &
+         &            cn_slchlnonfbfiles, cn_slchldinfbfiles,         &
+         &            cn_slchlmicfbfiles, cn_slchlnanfbfiles,         &
+         &            cn_slchlpicfbfiles, cn_schltotfbfiles,          &
+         &            cn_slphytotfbfiles, cn_slphydiafbfiles,         &
+         &            cn_slphynonfbfiles, cn_sspmfbfiles,             &
+         &            cn_sfco2fbfiles, cn_spco2fbfiles,               &
+         &            cn_plchltotfbfiles, cn_pchltotfbfiles,          &
+         &            cn_pno3fbfiles, cn_psi4fbfiles, cn_ppo4fbfiles, &
+         &            cn_pdicfbfiles, cn_palkfbfiles, cn_pphfbfiles,  &
+         &            cn_po2fbfiles,                                  &
+         &            cn_sstbiasfiles, cn_altbiasfile,                &
+         &            cn_gridsearchfile, rn_gridsearchres,            &
+         &            rn_dobsini, rn_dobsend,                         &
+         &            rn_default_avglamscl, rn_default_avgphiscl,     &
+         &            rn_sla_avglamscl, rn_sla_avgphiscl,             &
+         &            rn_sst_avglamscl, rn_sst_avgphiscl,             &
+         &            rn_sss_avglamscl, rn_sss_avgphiscl,             &
+         &            rn_sic_avglamscl, rn_sic_avgphiscl,             &
+         &            nn_1dint, nn_2dint_default,                     &
+         &            nn_2dint_sla, nn_2dint_sst,                     &
+         &            nn_2dint_sss, nn_2dint_sic,                     &
+         &            nn_msshc, rn_mdtcorr, rn_mdtcutoff,             &
+         &            nn_profdavtypes
 
       !-----------------------------------------------------------------------
@@ -208,116 +289,61 @@
       !-----------------------------------------------------------------------
 
-      enactfiles(:) = ''
-      coriofiles(:) = ''
-      profbfiles(:) = ''
-      slafilesact(:) = ''
-      slafilespas(:) = ''
-      slafbfiles(:) = ''
-      sstfiles(:)   = ''
-      sstfbfiles(:) = ''
-      seaicefiles(:) = ''
-      velcurfiles(:) = ''
-      veladcpfiles(:) = ''
-      velavcurfiles(:) = ''
-      velhrcurfiles(:) = ''
-      velavadcpfiles(:) = ''
-      velhradcpfiles(:) = ''
-      velfbfiles(:) = ''
-      velcurfiles(:) = ''
-      veladcpfiles(:) = ''
-      endailyavtypes(:) = -1
-      endailyavtypes(1) = 820
-      ln_profb_ena(:) = .FALSE.
-      ln_profb_enatim(:) = .TRUE.
-      ln_velfb_av(:) = .FALSE.
-      ln_ignmis = .FALSE.
-      
-      CALL ini_date( dobsini )
-      CALL fin_date( dobsend )
- 
-      ! Read Namelist namobs : control observation diagnostics
-      REWIND( numnam_ref )              ! Namelist namobs in reference namelist : Diagnostic: control observation
+      ! Some namelist arrays need initialising
+      cn_profbfiles(:)      = ''
+      cn_slafbfiles(:)      = ''
+      cn_sstfbfiles(:)      = ''
+      cn_sicfbfiles(:)      = ''
+      cn_velfbfiles(:)      = ''
+      cn_sssfbfiles(:)      = ''
+      cn_slchltotfbfiles(:) = ''
+      cn_slchldiafbfiles(:) = ''
+      cn_slchlnonfbfiles(:) = ''
+      cn_slchldinfbfiles(:) = ''
+      cn_slchlmicfbfiles(:) = ''
+      cn_slchlnanfbfiles(:) = ''
+      cn_slchlpicfbfiles(:) = ''
+      cn_schltotfbfiles(:)  = ''
+      cn_slphytotfbfiles(:) = ''
+      cn_slphydiafbfiles(:) = ''
+      cn_slphynonfbfiles(:) = ''
+      cn_sspmfbfiles(:)     = ''
+      cn_sfco2fbfiles(:)    = ''
+      cn_spco2fbfiles(:)    = ''
+      cn_plchltotfbfiles(:) = ''
+      cn_pchltotfbfiles(:)  = ''
+      cn_pno3fbfiles(:)     = ''
+      cn_psi4fbfiles(:)     = ''
+      cn_ppo4fbfiles(:)     = ''
+      cn_pdicfbfiles(:)     = ''
+      cn_palkfbfiles(:)     = ''
+      cn_pphfbfiles(:)      = ''
+      cn_po2fbfiles(:)      = ''
+      cn_sstbiasfiles(:)    = ''
+      nn_profdavtypes(:)    = -1
+
+      CALL ini_date( rn_dobsini )
+      CALL fin_date( rn_dobsend )
+
+      ! Read namelist namobs : control observation diagnostics
+      REWIND( numnam_ref )   ! Namelist namobs in reference namelist
       READ  ( numnam_ref, namobs, IOSTAT = ios, ERR = 901)
 901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namobs in reference namelist', lwp )
 
-      REWIND( numnam_cfg )              ! Namelist namobs in configuration namelist : Diagnostic: control observation
+      REWIND( numnam_cfg )   ! Namelist namobs in configuration namelist
       READ  ( numnam_cfg, namobs, IOSTAT = ios, ERR = 902 )
 902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namobs in configuration namelist', lwp )
       IF(lwm) WRITE ( numond, namobs )
 
-      ! Count number of files for each type
-      IF (ln_ena) THEN
-         lmask(:) = .FALSE.
-         WHERE (enactfiles(:) /= '') lmask(:) = .TRUE.
-         jnumenact = COUNT(lmask)
+      lk_diaobs = .FALSE.
+#if defined key_diaobs
+      IF ( ln_diaobs ) lk_diaobs = .TRUE.
+#endif
+
+      IF ( .NOT. lk_diaobs ) THEN
+         IF(lwp) WRITE(numout,cform_war)
+         IF(lwp) WRITE(numout,*)' ln_diaobs is set to false or key_diaobs is not set, so not calling dia_obs'
+         RETURN
       ENDIF
-      IF (ln_cor) THEN
-         lmask(:) = .FALSE.
-         WHERE (coriofiles(:) /= '') lmask(:) = .TRUE.
-         jnumcorio = COUNT(lmask)
-      ENDIF
-      IF (ln_profb) THEN
-         lmask(:) = .FALSE.
-         WHERE (profbfiles(:) /= '') lmask(:) = .TRUE.
-         jnumprofb = COUNT(lmask)
-      ENDIF
-      IF (ln_sladt) THEN
-         lmask(:) = .FALSE.
-         WHERE (slafilesact(:) /= '') lmask(:) = .TRUE.
-         jnumslaact = COUNT(lmask)
-         lmask(:) = .FALSE.
-         WHERE (slafilespas(:) /= '') lmask(:) = .TRUE.
-         jnumslapas = COUNT(lmask)
-      ENDIF
-      IF (ln_slafb) THEN
-         lmask(:) = .FALSE.
-         WHERE (slafbfiles(:) /= '') lmask(:) = .TRUE.
-         jnumslafb = COUNT(lmask)
-         lmask(:) = .FALSE.
-      ENDIF
-      IF (ln_ghrsst) THEN
-         lmask(:) = .FALSE.
-         WHERE (sstfiles(:) /= '') lmask(:) = .TRUE.
-         jnumsst = COUNT(lmask)
-      ENDIF      
-      IF (ln_sstfb) THEN
-         lmask(:) = .FALSE.
-         WHERE (sstfbfiles(:) /= '') lmask(:) = .TRUE.
-         jnumsstfb = COUNT(lmask)
-         lmask(:) = .FALSE.
-      ENDIF
-      IF (ln_seaice) THEN
-         lmask(:) = .FALSE.
-         WHERE (seaicefiles(:) /= '') lmask(:) = .TRUE.
-         jnumseaice = COUNT(lmask)
-      ENDIF
-      IF (ln_velavcur) THEN
-         lmask(:) = .FALSE.
-         WHERE (velavcurfiles(:) /= '') lmask(:) = .TRUE.
-         jnumvelavcur = COUNT(lmask)
-      ENDIF
-      IF (ln_velhrcur) THEN
-         lmask(:) = .FALSE.
-         WHERE (velhrcurfiles(:) /= '') lmask(:) = .TRUE.
-         jnumvelhrcur = COUNT(lmask)
-      ENDIF
-      IF (ln_velavadcp) THEN
-         lmask(:) = .FALSE.
-         WHERE (velavadcpfiles(:) /= '') lmask(:) = .TRUE.
-         jnumvelavadcp = COUNT(lmask)
-      ENDIF
-      IF (ln_velhradcp) THEN
-         lmask(:) = .FALSE.
-         WHERE (velhradcpfiles(:) /= '') lmask(:) = .TRUE.
-         jnumvelhradcp = COUNT(lmask)
-      ENDIF
-      IF (ln_velfb) THEN
-         lmask(:) = .FALSE.
-         WHERE (velfbfiles(:) /= '') lmask(:) = .TRUE.
-         jnumvelfb = COUNT(lmask)
-         lmask(:) = .FALSE.
-      ENDIF
-      
-      ! Control print
+
       IF(lwp) THEN
          WRITE(numout,*)
@@ -325,138 +351,334 @@
          WRITE(numout,*) '~~~~~~~~~~~~'
          WRITE(numout,*) '          Namelist namobs : set observation diagnostic parameters' 
-         WRITE(numout,*) '             Logical switch for T profile observations          ln_t3d = ', ln_t3d
-         WRITE(numout,*) '             Logical switch for S profile observations          ln_s3d = ', ln_s3d
-         WRITE(numout,*) '             Logical switch for ENACT insitu data set           ln_ena = ', ln_ena
-         WRITE(numout,*) '             Logical switch for Coriolis insitu data set        ln_cor = ', ln_cor
-         WRITE(numout,*) '             Logical switch for feedback insitu data set      ln_profb = ', ln_profb
-         WRITE(numout,*) '             Logical switch for SLA observations                ln_sla = ', ln_sla
-         WRITE(numout,*) '             Logical switch for AVISO SLA data                ln_sladt = ', ln_sladt
-         WRITE(numout,*) '             Logical switch for feedback SLA data             ln_slafb = ', ln_slafb
-         WRITE(numout,*) '             Logical switch for SSH observations                ln_ssh = ', ln_ssh
-         WRITE(numout,*) '             Logical switch for SST observations                ln_sst = ', ln_sst
-         WRITE(numout,*) '             Logical switch for Reynolds observations        ln_reysst = ', ln_reysst    
-         WRITE(numout,*) '             Logical switch for GHRSST observations          ln_ghrsst = ', ln_ghrsst
-         WRITE(numout,*) '             Logical switch for feedback SST data             ln_sstfb = ', ln_sstfb
-         WRITE(numout,*) '             Logical switch for night-time SST obs         ln_sstnight = ', ln_sstnight
-         WRITE(numout,*) '             Logical switch for SSS observations                ln_sss = ', ln_sss
-         WRITE(numout,*) '             Logical switch for Sea Ice observations         ln_seaice = ', ln_seaice
-         WRITE(numout,*) '             Logical switch for velocity observations         ln_vel3d = ', ln_vel3d
-         WRITE(numout,*) '             Logical switch for velocity daily av. cur.    ln_velavcur = ', ln_velavcur
-         WRITE(numout,*) '             Logical switch for velocity high freq. cur.   ln_velhrcur = ', ln_velhrcur
-         WRITE(numout,*) '             Logical switch for velocity daily av. ADCP   ln_velavadcp = ', ln_velavadcp
-         WRITE(numout,*) '             Logical switch for velocity high freq. ADCP  ln_velhradcp = ', ln_velhradcp
-         WRITE(numout,*) '             Logical switch for feedback velocity data        ln_velfb = ', ln_velfb
-         WRITE(numout,*) '             Global distribtion of observations         ln_grid_global = ',ln_grid_global
-         WRITE(numout,*) &
-   '             Logical switch for obs grid search w/lookup table  ln_grid_search_lookup = ',ln_grid_search_lookup
+         WRITE(numout,*) '             Logical switch for T profile observations                ln_t3d = ', ln_t3d
+         WRITE(numout,*) '             Logical switch for S profile observations                ln_s3d = ', ln_s3d
+         WRITE(numout,*) '             Logical switch for SLA observations                      ln_sla = ', ln_sla
+         WRITE(numout,*) '             Logical switch for SST observations                      ln_sst = ', ln_sst
+         WRITE(numout,*) '             Logical switch for Sea Ice observations                  ln_sic = ', ln_sic
+         WRITE(numout,*) '             Logical switch for velocity observations               ln_vel3d = ', ln_vel3d
+         WRITE(numout,*) '             Logical switch for SSS observations                      ln_sss = ', ln_sss
+         WRITE(numout,*) '             Logical switch for surface total logchl obs         ln_slchltot = ', ln_slchltot
+         WRITE(numout,*) '             Logical switch for surface diatom logchl obs        ln_slchldia = ', ln_slchldia
+         WRITE(numout,*) '             Logical switch for surface non-diatom logchl obs    ln_slchlnon = ', ln_slchlnon
+         WRITE(numout,*) '             Logical switch for surface dino logchl obs          ln_slchldin = ', ln_slchldin
+         WRITE(numout,*) '             Logical switch for surface micro logchl obs         ln_slchlmic = ', ln_slchlmic
+         WRITE(numout,*) '             Logical switch for surface nano logchl obs          ln_slchlnan = ', ln_slchlnan
+         WRITE(numout,*) '             Logical switch for surface pico logchl obs          ln_slchlpic = ', ln_slchlpic
+         WRITE(numout,*) '             Logical switch for surface total chl obs             ln_schltot = ', ln_schltot
+         WRITE(numout,*) '             Logical switch for surface total log(phyC) obs      ln_slphytot = ', ln_slphytot
+         WRITE(numout,*) '             Logical switch for surface diatom log(phyC) obs     ln_slphydia = ', ln_slphydia
+         WRITE(numout,*) '             Logical switch for surface non-diatom log(phyC) obs ln_slphynon = ', ln_slphynon
+         WRITE(numout,*) '             Logical switch for surface SPM observations             ln_sspm = ', ln_sspm
+         WRITE(numout,*) '             Logical switch for surface fCO2 observations           ln_sfco2 = ', ln_sfco2
+         WRITE(numout,*) '             Logical switch for surface pCO2 observations           ln_spco2 = ', ln_spco2
+         WRITE(numout,*) '             Logical switch for profile total logchl obs         ln_plchltot = ', ln_plchltot
+         WRITE(numout,*) '             Logical switch for profile total chl obs             ln_pchltot = ', ln_pchltot
+         WRITE(numout,*) '             Logical switch for profile nitrate obs                  ln_pno3 = ', ln_pno3
+         WRITE(numout,*) '             Logical switch for profile silicate obs                 ln_psi4 = ', ln_psi4
+         WRITE(numout,*) '             Logical switch for profile phosphate obs                ln_ppo4 = ', ln_ppo4
+         WRITE(numout,*) '             Logical switch for profile DIC obs                      ln_pdic = ', ln_pdic
+         WRITE(numout,*) '             Logical switch for profile alkalinity obs               ln_palk = ', ln_palk
+         WRITE(numout,*) '             Logical switch for profile pH obs                        ln_pph = ', ln_pph
+         WRITE(numout,*) '             Logical switch for profile oxygen obs                    ln_po2 = ', ln_po2
+         WRITE(numout,*) '             Global distribution of observations              ln_grid_global = ', ln_grid_global
+         WRITE(numout,*) '             Logical switch for obs grid search lookup ln_grid_search_lookup = ', ln_grid_search_lookup
          IF (ln_grid_search_lookup) &
-            WRITE(numout,*) '             Grid search lookup file header       grid_search_file = ', grid_search_file
-         IF (ln_ena) THEN
-            DO ji = 1, jnumenact
-               WRITE(numout,'(1X,2A)') '             ENACT input observation file name          enactfiles = ', &
-                  TRIM(enactfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_cor) THEN
-            DO ji = 1, jnumcorio
-               WRITE(numout,'(1X,2A)') '             Coriolis input observation file name       coriofiles = ', &
-                  TRIM(coriofiles(ji))
-            END DO
-         ENDIF
-         IF (ln_profb) THEN
-            DO ji = 1, jnumprofb
-               IF (ln_profb_ena(ji)) THEN
-                  WRITE(numout,'(1X,2A)') '       Enact feedback input observation file name       profbfiles = ', &
-                     TRIM(profbfiles(ji))
+            WRITE(numout,*) '             Grid search lookup file header                cn_gridsearchfile = ', cn_gridsearchfile
+         WRITE(numout,*) '             Initial date in window YYYYMMDD.HHMMSS               rn_dobsini = ', rn_dobsini
+         WRITE(numout,*) '             Final date in window YYYYMMDD.HHMMSS                 rn_dobsend = ', rn_dobsend
+         WRITE(numout,*) '             Type of vertical interpolation method                  nn_1dint = ', nn_1dint
+         WRITE(numout,*) '             Default horizontal interpolation method        nn_2dint_default = ', nn_2dint_default
+         WRITE(numout,*) '             Type of horizontal interpolation method for SLA    nn_2dint_sla = ', nn_2dint_sla
+         WRITE(numout,*) '             Type of horizontal interpolation method for SST    nn_2dint_sst = ', nn_2dint_sst
+         WRITE(numout,*) '             Type of horizontal interpolation method for SSS    nn_2dint_sss = ', nn_2dint_sss
+         WRITE(numout,*) '             Type of horizontal interpolation method for SIC    nn_2dint_sic = ', nn_2dint_sic
+         WRITE(numout,*) '             Default E/W diameter of obs footprint      rn_default_avglamscl = ', rn_default_avglamscl
+         WRITE(numout,*) '             Default N/S diameter of obs footprint      rn_default_avgphiscl = ', rn_default_avgphiscl
+         WRITE(numout,*) '             Default obs footprint in deg [T] or m [F]  ln_default_fp_indegs = ', ln_default_fp_indegs
+         WRITE(numout,*) '             SLA E/W diameter of obs footprint              rn_sla_avglamscl = ', rn_sla_avglamscl
+         WRITE(numout,*) '             SLA N/S diameter of obs footprint              rn_sla_avgphiscl = ', rn_sla_avgphiscl
+         WRITE(numout,*) '             SLA obs footprint in deg [T] or m [F]          ln_sla_fp_indegs = ', ln_sla_fp_indegs
+         WRITE(numout,*) '             SST E/W diameter of obs footprint              rn_sst_avglamscl = ', rn_sst_avglamscl
+         WRITE(numout,*) '             SST N/S diameter of obs footprint              rn_sst_avgphiscl = ', rn_sst_avgphiscl
+         WRITE(numout,*) '             SST obs footprint in deg [T] or m [F]          ln_sst_fp_indegs = ', ln_sst_fp_indegs
+         WRITE(numout,*) '             SIC E/W diameter of obs footprint              rn_sic_avglamscl = ', rn_sic_avglamscl
+         WRITE(numout,*) '             SIC N/S diameter of obs footprint              rn_sic_avgphiscl = ', rn_sic_avgphiscl
+         WRITE(numout,*) '             SIC obs footprint in deg [T] or m [F]          ln_sic_fp_indegs = ', ln_sic_fp_indegs
+         WRITE(numout,*) '             Rejection of observations near land switch               ln_nea = ', ln_nea
+         WRITE(numout,*) '             Rejection of obs near open bdys                 ln_bound_reject = ', ln_bound_reject
+         WRITE(numout,*) '             MSSH correction scheme                                 nn_msshc = ', nn_msshc
+         WRITE(numout,*) '             MDT  correction                                      rn_mdtcorr = ', rn_mdtcorr
+         WRITE(numout,*) '             MDT cutoff for computed correction                 rn_mdtcutoff = ', rn_mdtcutoff
+         WRITE(numout,*) '             Logical switch for alt bias                          ln_altbias = ', ln_altbias
+         WRITE(numout,*) '             Logical switch for sst bias                          ln_sstbias = ', ln_sstbias
+         WRITE(numout,*) '             Logical switch for ignoring missing files             ln_ignmis = ', ln_ignmis
+         WRITE(numout,*) '             Daily average types                             nn_profdavtypes = ', nn_profdavtypes
+         WRITE(numout,*) '             Logical switch for night-time SST obs               ln_sstnight = ', ln_sstnight
+      ENDIF
+      !-----------------------------------------------------------------------
+      ! Set up list of observation types to be used
+      ! and the files associated with each type
+      !-----------------------------------------------------------------------
+
+      nproftypes = COUNT( (/ln_t3d .OR. ln_s3d, ln_vel3d, ln_plchltot,          &
+         &                  ln_pchltot,  ln_pno3,     ln_psi4,     ln_ppo4,     &
+         &                  ln_pdic,     ln_palk,     ln_pph,      ln_po2 /) )
+      nsurftypes = COUNT( (/ln_sla, ln_sst, ln_sic, ln_sss,                     &
+         &                  ln_slchltot, ln_slchldia, ln_slchlnon, ln_slchldin, &
+         &                  ln_slchlmic, ln_slchlnan, ln_slchlpic, ln_schltot,  &
+         &                  ln_slphytot, ln_slphydia, ln_slphynon, ln_sspm,     &
+         &                  ln_sfco2,    ln_spco2 /) )
+
+      IF ( nproftypes == 0 .AND. nsurftypes == 0 ) THEN
+         IF(lwp) WRITE(numout,cform_war)
+         IF(lwp) WRITE(numout,*) ' ln_diaobs is set to true, but all obs operator logical flags', &
+            &                    ' are set to .FALSE. so turning off calls to dia_obs'
+         nwarn = nwarn + 1
+         lk_diaobs = .FALSE.
+         RETURN
+      ENDIF
+
+      IF(lwp) WRITE(numout,*) '          Number of profile obs types: ',nproftypes
+      IF ( nproftypes > 0 ) THEN
+
+         ALLOCATE( cobstypesprof(nproftypes) )
+         ALLOCATE( ifilesprof(nproftypes) )
+         ALLOCATE( clproffiles(nproftypes,jpmaxnfiles) )
+
+         jtype = 0
+         IF (ln_t3d .OR. ln_s3d) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'prof'
+            clproffiles(jtype,:) = cn_profbfiles
+         ENDIF
+         IF (ln_vel3d) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) =  'vel'
+            clproffiles(jtype,:) = cn_velfbfiles
+         ENDIF
+         IF (ln_plchltot) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'plchltot'
+            clproffiles(jtype,:) = cn_plchltotfbfiles
+         ENDIF
+         IF (ln_pchltot) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'pchltot'
+            clproffiles(jtype,:) = cn_pchltotfbfiles
+         ENDIF
+         IF (ln_pno3) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'pno3'
+            clproffiles(jtype,:) = cn_pno3fbfiles
+         ENDIF
+         IF (ln_psi4) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'psi4'
+            clproffiles(jtype,:) = cn_psi4fbfiles
+         ENDIF
+         IF (ln_ppo4) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'ppo4'
+            clproffiles(jtype,:) = cn_ppo4fbfiles
+         ENDIF
+         IF (ln_pdic) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'pdic'
+            clproffiles(jtype,:) = cn_pdicfbfiles
+         ENDIF
+         IF (ln_palk) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'palk'
+            clproffiles(jtype,:) = cn_palkfbfiles
+         ENDIF
+         IF (ln_pph) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'pph'
+            clproffiles(jtype,:) = cn_pphfbfiles
+         ENDIF
+         IF (ln_po2) THEN
+            jtype = jtype + 1
+            cobstypesprof(jtype) = 'po2'
+            clproffiles(jtype,:) = cn_po2fbfiles
+         ENDIF
+
+         CALL obs_settypefiles( nproftypes, jpmaxnfiles, ifilesprof, cobstypesprof, clproffiles )
+
+      ENDIF
+
+      IF(lwp) WRITE(numout,*)'          Number of surface obs types: ',nsurftypes
+      IF ( nsurftypes > 0 ) THEN
+
+         ALLOCATE( cobstypessurf(nsurftypes) )
+         ALLOCATE( ifilessurf(nsurftypes) )
+         ALLOCATE( clsurffiles(nsurftypes, jpmaxnfiles) )
+         ALLOCATE(n2dintsurf(nsurftypes))
+         ALLOCATE(ravglamscl(nsurftypes))
+         ALLOCATE(ravgphiscl(nsurftypes))
+         ALLOCATE(lfpindegs(nsurftypes))
+         ALLOCATE(llnightav(nsurftypes))
+
+         jtype = 0
+         IF (ln_sla) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'sla'
+            clsurffiles(jtype,:) = cn_slafbfiles
+         ENDIF
+         IF (ln_sst) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'sst'
+            clsurffiles(jtype,:) = cn_sstfbfiles
+         ENDIF
+         IF (ln_sic) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'sic'
+            clsurffiles(jtype,:) = cn_sicfbfiles
+         ENDIF
+         IF (ln_sss) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'sss'
+            clsurffiles(jtype,:) = cn_sssfbfiles
+         ENDIF
+         IF (ln_slchltot) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchltot'
+            clsurffiles(jtype,:) = cn_slchltotfbfiles
+         ENDIF
+         IF (ln_slchldia) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchldia'
+            clsurffiles(jtype,:) = cn_slchldiafbfiles
+         ENDIF
+         IF (ln_slchlnon) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchlnon'
+            clsurffiles(jtype,:) = cn_slchlnonfbfiles
+         ENDIF
+         IF (ln_slchldin) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchldin'
+            clsurffiles(jtype,:) = cn_slchldinfbfiles
+         ENDIF
+         IF (ln_slchlmic) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchlmic'
+            clsurffiles(jtype,:) = cn_slchlmicfbfiles
+         ENDIF
+         IF (ln_slchlnan) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchlnan'
+            clsurffiles(jtype,:) = cn_slchlnanfbfiles
+         ENDIF
+         IF (ln_slchlpic) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slchlpic'
+            clsurffiles(jtype,:) = cn_slchlpicfbfiles
+         ENDIF
+         IF (ln_schltot) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'schltot'
+            clsurffiles(jtype,:) = cn_schltotfbfiles
+         ENDIF
+         IF (ln_slphytot) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slphytot'
+            clsurffiles(jtype,:) = cn_slphytotfbfiles
+         ENDIF
+         IF (ln_slphydia) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slphydia'
+            clsurffiles(jtype,:) = cn_slphydiafbfiles
+         ENDIF
+         IF (ln_slphynon) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'slphynon'
+            clsurffiles(jtype,:) = cn_slphynonfbfiles
+         ENDIF
+         IF (ln_sspm) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'sspm'
+            clsurffiles(jtype,:) = cn_sspmfbfiles
+         ENDIF
+         IF (ln_sfco2) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'sfco2'
+            clsurffiles(jtype,:) = cn_sfco2fbfiles
+         ENDIF
+         IF (ln_spco2) THEN
+            jtype = jtype + 1
+            cobstypessurf(jtype) = 'spco2'
+            clsurffiles(jtype,:) = cn_spco2fbfiles
+         ENDIF
+
+         CALL obs_settypefiles( nsurftypes, jpmaxnfiles, ifilessurf, cobstypessurf, clsurffiles )
+
+         DO jtype = 1, nsurftypes
+
+            IF ( TRIM(cobstypessurf(jtype)) == 'sla' ) THEN
+               IF ( nn_2dint_sla == -1 ) THEN
+                  n2dint_type  = nn_2dint_default
                ELSE
-                  WRITE(numout,'(1X,2A)') '             Feedback input observation file name       profbfiles = ', &
-                     TRIM(profbfiles(ji))
+                  n2dint_type  = nn_2dint_sla
                ENDIF
-               WRITE(numout,'(1X,2A)') '       Enact feedback input time setting switch    ln_profb_enatim = ', ln_profb_enatim(ji)
-            END DO
-         ENDIF
-         IF (ln_sladt) THEN
-            DO ji = 1, jnumslaact
-               WRITE(numout,'(1X,2A)') '             Active SLA input observation file name    slafilesact = ', &
-                  TRIM(slafilesact(ji))
-            END DO
-            DO ji = 1, jnumslapas
-               WRITE(numout,'(1X,2A)') '             Passive SLA input observation file name   slafilespas = ', &
-                  TRIM(slafilespas(ji))
-            END DO
-         ENDIF
-         IF (ln_slafb) THEN
-            DO ji = 1, jnumslafb
-               WRITE(numout,'(1X,2A)') '             Feedback SLA input observation file name   slafbfiles = ', &
-                  TRIM(slafbfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_ghrsst) THEN
-            DO ji = 1, jnumsst
-               WRITE(numout,'(1X,2A)') '             GHRSST input observation file name           sstfiles = ', &
-                  TRIM(sstfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_sstfb) THEN
-            DO ji = 1, jnumsstfb
-               WRITE(numout,'(1X,2A)') '             Feedback SST input observation file name   sstfbfiles = ', &
-                  TRIM(sstfbfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_seaice) THEN
-            DO ji = 1, jnumseaice
-               WRITE(numout,'(1X,2A)') '             Sea Ice input observation file name       seaicefiles = ', &
-                  TRIM(seaicefiles(ji))
-            END DO
-         ENDIF
-         IF (ln_velavcur) THEN
-            DO ji = 1, jnumvelavcur
-               WRITE(numout,'(1X,2A)') '             Vel. cur. daily av. input file name     velavcurfiles = ', &
-                  TRIM(velavcurfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_velhrcur) THEN
-            DO ji = 1, jnumvelhrcur
-               WRITE(numout,'(1X,2A)') '             Vel. cur. high freq. input file name    velhvcurfiles = ', &
-                  TRIM(velhrcurfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_velavadcp) THEN
-            DO ji = 1, jnumvelavadcp
-               WRITE(numout,'(1X,2A)') '             Vel. ADCP daily av. input file name    velavadcpfiles = ', &
-                  TRIM(velavadcpfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_velhradcp) THEN
-            DO ji = 1, jnumvelhradcp
-               WRITE(numout,'(1X,2A)') '             Vel. ADCP high freq. input file name   velhvadcpfiles = ', &
-                  TRIM(velhradcpfiles(ji))
-            END DO
-         ENDIF
-         IF (ln_velfb) THEN
-            DO ji = 1, jnumvelfb
-               IF (ln_velfb_av(ji)) THEN
-                  WRITE(numout,'(1X,2A)') '             Vel. feedback daily av. input file name    velfbfiles = ', &
-                     TRIM(velfbfiles(ji))
+               ztype_avglamscl = rn_sla_avglamscl
+               ztype_avgphiscl = rn_sla_avgphiscl
+               ltype_fp_indegs = ln_sla_fp_indegs
+               ltype_night     = .FALSE.
+            ELSE IF ( TRIM(cobstypessurf(jtype)) == 'sst' ) THEN
+               IF ( nn_2dint_sst == -1 ) THEN
+                  n2dint_type  = nn_2dint_default
                ELSE
-                  WRITE(numout,'(1X,2A)') '             Vel. feedback input observation file name  velfbfiles = ', &
-                     TRIM(velfbfiles(ji))
+                  n2dint_type  = nn_2dint_sst
                ENDIF
-            END DO
-         ENDIF
-         WRITE(numout,*) '             Initial date in window YYYYMMDD.HHMMSS        dobsini = ', dobsini
-         WRITE(numout,*) '             Final date in window YYYYMMDD.HHMMSS          dobsend = ', dobsend
-         WRITE(numout,*) '             Type of vertical interpolation method          n1dint = ', n1dint
-         WRITE(numout,*) '             Type of horizontal interpolation method        n2dint = ', n2dint
-         WRITE(numout,*) '             Rejection of observations near land swithch    ln_nea = ', ln_nea
-         WRITE(numout,*) '             MSSH correction scheme                         nmsshc = ', nmsshc
-         WRITE(numout,*) '             MDT  correction                               mdtcorr = ', mdtcorr
-         WRITE(numout,*) '             MDT cutoff for computed correction          mdtcutoff = ', mdtcutoff
-         WRITE(numout,*) '             Logical switch for alt bias                ln_altbias = ', ln_altbias
-         WRITE(numout,*) '             Logical switch for ignoring missing files   ln_ignmis = ', ln_ignmis
-         WRITE(numout,*) '             ENACT daily average types                             = ',endailyavtypes
+               ztype_avglamscl = rn_sst_avglamscl
+               ztype_avgphiscl = rn_sst_avgphiscl
+               ltype_fp_indegs = ln_sst_fp_indegs
+               ltype_night     = ln_sstnight
+            ELSE IF ( TRIM(cobstypessurf(jtype)) == 'sic' ) THEN
+               IF ( nn_2dint_sic == -1 ) THEN
+                  n2dint_type  = nn_2dint_default
+               ELSE
+                  n2dint_type  = nn_2dint_sic
+               ENDIF
+               ztype_avglamscl = rn_sic_avglamscl
+               ztype_avgphiscl = rn_sic_avgphiscl
+               ltype_fp_indegs = ln_sic_fp_indegs
+               ltype_night     = .FALSE.
+            ELSE IF ( TRIM(cobstypessurf(jtype)) == 'sss' ) THEN
+               IF ( nn_2dint_sss == -1 ) THEN
+                  n2dint_type  = nn_2dint_default
+               ELSE
+                  n2dint_type  = nn_2dint_sss
+               ENDIF
+               ztype_avglamscl = rn_sss_avglamscl
+               ztype_avgphiscl = rn_sss_avgphiscl
+               ltype_fp_indegs = ln_sss_fp_indegs
+               ltype_night     = .FALSE.
+            ELSE
+               n2dint_type     = nn_2dint_default
+               ztype_avglamscl = rn_default_avglamscl
+               ztype_avgphiscl = rn_default_avgphiscl
+               ltype_fp_indegs = ln_default_fp_indegs
+               ltype_night     = .FALSE.
+            ENDIF
+            
+            CALL obs_setinterpopts( nsurftypes, jtype, TRIM(cobstypessurf(jtype)), &
+               &                    nn_2dint_default, n2dint_type,                 &
+               &                    ztype_avglamscl, ztype_avgphiscl,              &
+               &                    ltype_fp_indegs, ltype_night,                  &
+               &                    n2dintsurf, ravglamscl, ravgphiscl,            &
+               &                    lfpindegs, llnightav )
+
+         END DO
 
       ENDIF
-      
+
+      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
+
+
+      !-----------------------------------------------------------------------
+      ! Obs operator parameter checking and initialisations
+      !-----------------------------------------------------------------------
+
       IF ( ln_vel3d .AND. ( .NOT. ln_grid_global ) ) THEN
          CALL ctl_stop( 'Velocity data only works with ln_grid_global=.true.' )
@@ -464,505 +686,154 @@
       ENDIF
 
-      CALL obs_typ_init
-      
-      CALL mppmap_init
-      
-      ! Parameter control
-#if defined key_diaobs
-      IF ( ( .NOT. ln_t3d ).AND.( .NOT. ln_s3d ).AND.( .NOT. ln_sla ).AND. &
-         & ( .NOT. ln_vel3d ).AND.                                         &
-         & ( .NOT. ln_ssh ).AND.( .NOT. ln_sst ).AND.( .NOT. ln_sss ).AND. &
-         & ( .NOT. ln_seaice ).AND.( .NOT. ln_vel3d ) ) THEN
-         IF(lwp) WRITE(numout,cform_war)
-         IF(lwp) WRITE(numout,*) ' key_diaobs is activated but logical flags', &
-            &                    ' ln_t3d, ln_s3d, ln_sla, ln_ssh, ln_sst, ln_sss, ln_seaice, ln_vel3d are all set to .FALSE.'
-         nwarn = nwarn + 1
-      ENDIF
-#endif
-
-      CALL obs_grid_setup( )
-      IF ( ( n1dint < 0 ).OR.( n1dint > 1 ) ) THEN
+      IF ( ( nn_1dint < 0 ) .OR. ( nn_1dint > 1 ) ) THEN
          CALL ctl_stop(' Choice of vertical (1D) interpolation method', &
             &                    ' is not available')
       ENDIF
-      IF ( ( n2dint < 0 ).OR.( n2dint > 4 ) ) THEN
-         CALL ctl_stop(' Choice of horizontal (2D) interpolation method', &
+
+      IF ( ( nn_2dint_default < 0 ) .OR. ( nn_2dint_default > 6 ) ) THEN
+         CALL ctl_stop(' Choice of default horizontal (2D) interpolation method', &
             &                    ' is not available')
       ENDIF
 
+      CALL obs_typ_init
+
+      CALL mppmap_init
+
+      CALL obs_grid_setup( )
+
       !-----------------------------------------------------------------------
       ! Depending on switches read the various observation types
       !-----------------------------------------------------------------------
-      !  - Temperature/salinity profiles
-
-      IF ( ln_t3d .OR. ln_s3d ) THEN
-
-         ! Set the number of variables for profiles to 2 (T and S)
-         nprofvars = 2
-         ! Set the number of extra variables for profiles to 1 (insitu temp).
-         nprofextr = 1
-
-         ! Count how may insitu data sets we have and allocate data.
-         jprofset = 0
-         IF ( ln_ena ) jprofset = jprofset + 1
-         IF ( ln_cor ) jprofset = jprofset + 1
-         IF ( ln_profb ) jprofset = jprofset + jnumprofb
-         nprofsets = jprofset
-         IF ( nprofsets > 0 ) THEN
-            ALLOCATE(ld_enact(nprofsets))
-            ALLOCATE(profdata(nprofsets))
-            ALLOCATE(prodatqc(nprofsets))
-         ENDIF
-
-         jprofset = 0
-          
-         ! ENACT insitu data
-
-         IF ( ln_ena ) THEN
-
-            jprofset = jprofset + 1
+
+      IF ( nproftypes > 0 ) THEN
+
+         ALLOCATE(profdata(nproftypes))
+         ALLOCATE(profdataqc(nproftypes))
+         ALLOCATE(nvarsprof(nproftypes))
+         ALLOCATE(nextrprof(nproftypes))
+
+         DO jtype = 1, nproftypes
+
+            IF ( TRIM(cobstypesprof(jtype)) == 'prof' ) THEN
+               nvarsprof(jtype) = 2
+               nextrprof(jtype) = 1
+               ALLOCATE(llvar(nvarsprof(jtype)))
+               CALL wrk_alloc( jpi, jpj,      nvarsprof(jtype), zglam )
+               CALL wrk_alloc( jpi, jpj,      nvarsprof(jtype), zgphi )
+               CALL wrk_alloc( jpi, jpj, jpk, nvarsprof(jtype), zmask )
+               llvar(1)       = ln_t3d
+               llvar(2)       = ln_s3d
+               zglam(:,:,1)   = glamt(:,:)
+               zglam(:,:,2)   = glamt(:,:)
+               zgphi(:,:,1)   = gphit(:,:)
+               zgphi(:,:,2)   = gphit(:,:)
+               zmask(:,:,:,1) = tmask(:,:,:)
+               zmask(:,:,:,2) = tmask(:,:,:)
+            ELSE IF ( TRIM(cobstypesprof(jtype)) == 'vel' )  THEN
+               nvarsprof(jtype) = 2
+               nextrprof(jtype) = 2
+               ALLOCATE(llvar(nvarsprof(jtype)))
+               CALL wrk_alloc( jpi, jpj,      nvarsprof(jtype), zglam )
+               CALL wrk_alloc( jpi, jpj,      nvarsprof(jtype), zgphi )
+               CALL wrk_alloc( jpi, jpj, jpk, nvarsprof(jtype), zmask )
+               llvar(1)       = ln_vel3d
+               llvar(2)       = ln_vel3d
+               zglam(:,:,1)   = glamu(:,:)
+               zglam(:,:,2)   = glamv(:,:)
+               zgphi(:,:,1)   = gphiu(:,:)
+               zgphi(:,:,2)   = gphiv(:,:)
+               zmask(:,:,:,1) = umask(:,:,:)
+               zmask(:,:,:,2) = vmask(:,:,:)
+            ELSE
+               nvarsprof(jtype) = 1
+               nextrprof(jtype) = 0
+               ALLOCATE(llvar(nvarsprof(jtype)))
+               CALL wrk_alloc( jpi, jpj,      nvarsprof(jtype), zglam )
+               CALL wrk_alloc( jpi, jpj,      nvarsprof(jtype), zgphi )
+               CALL wrk_alloc( jpi, jpj, jpk, nvarsprof(jtype), zmask )
+               llvar(1)       = .TRUE.
+               zglam(:,:,1)   = glamt(:,:)
+               zgphi(:,:,1)   = gphit(:,:)
+               zmask(:,:,:,1) = tmask(:,:,:)
+            ENDIF
+
+            !Read in profile or profile obs types
+            CALL obs_rea_prof( profdata(jtype), ifilesprof(jtype),       &
+               &               clproffiles(jtype,1:ifilesprof(jtype)), &
+               &               nvarsprof(jtype), nextrprof(jtype), nitend-nit000+2, &
+               &               rn_dobsini, rn_dobsend, llvar, &
+               &               ln_ignmis, ln_s_at_t, .FALSE., &
+               &               kdailyavtypes = nn_profdavtypes )
+
+            DO jvar = 1, nvarsprof(jtype)
+               CALL obs_prof_staend( profdata(jtype), jvar )
+            END DO
+
+            CALL obs_pre_prof( profdata(jtype), profdataqc(jtype), &
+               &               llvar, &
+               &               jpi, jpj, jpk, &
+               &               zmask, zglam, zgphi,  &
+               &               ln_nea, ln_bound_reject, &
+               &               kdailyavtypes = nn_profdavtypes )
             
-            ld_enact(jprofset) = .TRUE.
-
-            CALL obs_rea_pro_dri( 1, profdata(jprofset),          &
-               &                  jnumenact, enactfiles(1:jnumenact), &
-               &                  nprofvars, nprofextr,        &
-               &                  nitend-nit000+2,             &
-               &                  dobsini, dobsend, ln_t3d, ln_s3d, &
-               &                  ln_ignmis, ln_s_at_t, .TRUE., .FALSE., &
-               &                  kdailyavtypes = endailyavtypes )
-
-            DO jvar = 1, 2
-
-               CALL obs_prof_staend( profdata(jprofset), jvar )
-
-            END DO
-
-            CALL obs_pre_pro( profdata(jprofset), prodatqc(jprofset),   &
-               &              ln_t3d, ln_s3d, ln_nea, &
-               &              kdailyavtypes=endailyavtypes )
-            
-         ENDIF
-
-         ! Coriolis insitu data
-
-         IF ( ln_cor ) THEN
-           
-            jprofset = jprofset + 1
-
-            ld_enact(jprofset) = .FALSE.
-
-            CALL obs_rea_pro_dri( 2, profdata(jprofset),          &
-               &                  jnumcorio, coriofiles(1:jnumcorio), &
-               &                  nprofvars, nprofextr,        &
-               &                  nitend-nit000+2,             &
-               &                  dobsini, dobsend, ln_t3d, ln_s3d, &
-               &                  ln_ignmis, ln_s_at_t, .FALSE., .FALSE. )
-
-            DO jvar = 1, 2
-
-               CALL obs_prof_staend( profdata(jprofset), jvar )
-
-            END DO
-
-            CALL obs_pre_pro( profdata(jprofset), prodatqc(jprofset),   &
-                 &            ln_t3d, ln_s3d, ln_nea )
-            
-         ENDIF
- 
-         ! Feedback insitu data
-
-         IF ( ln_profb ) THEN
-           
-            DO jset = 1, jnumprofb
-               
-               jprofset = jprofset + 1
-               ld_enact (jprofset) = ln_profb_ena(jset)
-
-               CALL obs_rea_pro_dri( 0, profdata(jprofset),          &
-                  &                  1, profbfiles(jset:jset), &
-                  &                  nprofvars, nprofextr,        &
-                  &                  nitend-nit000+2,             &
-                  &                  dobsini, dobsend, ln_t3d, ln_s3d, &
-                  &                  ln_ignmis, ln_s_at_t, &
-                  &                  ld_enact(jprofset).AND.&
-                  &                  ln_profb_enatim(jset), &
-                  &                  .FALSE., kdailyavtypes = endailyavtypes )
-               
-               DO jvar = 1, 2
-                  
-                  CALL obs_prof_staend( profdata(jprofset), jvar )
-                  
+            DEALLOCATE( llvar )
+            CALL wrk_dealloc( jpi, jpj,      nvarsprof(jtype), zglam )
+            CALL wrk_dealloc( jpi, jpj,      nvarsprof(jtype), zgphi )
+            CALL wrk_dealloc( jpi, jpj, jpk, nvarsprof(jtype), zmask )
+
+         END DO
+
+         DEALLOCATE( ifilesprof, clproffiles )
+
+      ENDIF
+
+      IF ( nsurftypes > 0 ) THEN
+
+         ALLOCATE(surfdata(nsurftypes))
+         ALLOCATE(surfdataqc(nsurftypes))
+         ALLOCATE(nvarssurf(nsurftypes))
+         ALLOCATE(nextrsurf(nsurftypes))
+
+         DO jtype = 1, nsurftypes
+
+            nvarssurf(jtype) = 1
+            nextrsurf(jtype) = 0
+            IF ( TRIM(cobstypessurf(jtype)) == 'sla' ) nextrsurf(jtype) = 2
+
+            !Read in surface obs types
+            CALL obs_rea_surf( surfdata(jtype), ifilessurf(jtype), &
+               &               clsurffiles(jtype,1:ifilessurf(jtype)), &
+               &               nvarssurf(jtype), nextrsurf(jtype), nitend-nit000+2, &
+               &               rn_dobsini, rn_dobsend, ln_ignmis, .FALSE., llnightav(jtype) )
+
+            CALL obs_pre_surf( surfdata(jtype), surfdataqc(jtype), ln_nea, ln_bound_reject )
+
+            IF ( TRIM(cobstypessurf(jtype)) == 'sla' ) THEN
+               CALL obs_rea_mdt( surfdataqc(jtype), n2dintsurf(jtype) )
+               IF ( ln_altbias ) &
+                  & CALL obs_rea_altbias ( surfdataqc(jtype), n2dintsurf(jtype), cn_altbiasfile )
+            ENDIF
+
+            IF ( TRIM(cobstypessurf(jtype)) == 'sst' .AND. ln_sstbias ) THEN
+               jnumsstbias = 0
+               DO jfile = 1, jpmaxnfiles
+                  IF ( TRIM(cn_sstbiasfiles(jfile)) /= '' ) &
+                     &  jnumsstbias = jnumsstbias + 1
                END DO
-               
-               IF ( ld_enact(jprofset) ) THEN
-                  CALL obs_pre_pro( profdata(jprofset), prodatqc(jprofset),   &
-                     &              ln_t3d, ln_s3d, ln_nea, &
-                     &              kdailyavtypes = endailyavtypes )
-               ELSE
-                  CALL obs_pre_pro( profdata(jprofset), prodatqc(jprofset),   &
-                     &              ln_t3d, ln_s3d, ln_nea )
+               IF ( jnumsstbias == 0 ) THEN
+                  CALL ctl_stop("ln_sstbias set but no bias files to read in")    
                ENDIF
-               
-            END DO
-
-         ENDIF
+
+               CALL obs_app_sstbias( surfdataqc(jtype), n2dintsurf(jtype), & 
+                  &                  jnumsstbias, cn_sstbiasfiles(1:jnumsstbias) ) 
+
+            ENDIF
+
+         END DO
+
+         DEALLOCATE( ifilessurf, clsurffiles )
 
       ENDIF
 
-      !  - Sea level anomalies
-      IF ( ln_sla ) THEN
-        ! Set the number of variables for sla to 1
-         nslavars = 1
-
-         ! Set the number of extra variables for sla to 2
-         nslaextr = 2
-         
-         ! Set the number of sla data sets to 2
-         nslasets = 0
-         IF ( ln_sladt ) THEN
-            nslasets = nslasets + 2
-         ENDIF
-         IF ( ln_slafb ) THEN
-            nslasets = nslasets + jnumslafb
-         ENDIF
-         
-         ALLOCATE(sladata(nslasets))
-         ALLOCATE(sladatqc(nslasets))
-         sladata(:)%nsurf=0
-         sladatqc(:)%nsurf=0
-
-         nslasets = 0
-
-         ! AVISO SLA data
-
-         IF ( ln_sladt ) THEN
-
-            ! Active SLA observations
-            
-            nslasets = nslasets + 1
-            
-            CALL obs_rea_sla( 1, sladata(nslasets), jnumslaact, &
-               &              slafilesact(1:jnumslaact), &
-               &              nslavars, nslaextr, nitend-nit000+2, &
-               &              dobsini, dobsend, ln_ignmis, .FALSE. )
-            CALL obs_pre_sla( sladata(nslasets), sladatqc(nslasets), &
-               &              ln_sla, ln_nea )
-            
-            ! Passive SLA observations
-            
-            nslasets = nslasets + 1
-            
-            CALL obs_rea_sla( 1, sladata(nslasets), jnumslapas, &
-               &              slafilespas(1:jnumslapas), &
-               &              nslavars, nslaextr, nitend-nit000+2, &
-               &              dobsini, dobsend, ln_ignmis, .FALSE. )
-            
-            CALL obs_pre_sla( sladata(nslasets), sladatqc(nslasets), &
-               &              ln_sla, ln_nea )
-
-         ENDIF
-         
-         ! Feedback SLA data
-
-         IF ( ln_slafb ) THEN
-
-            DO jset = 1, jnumslafb
-            
-               nslasets = nslasets + 1
-            
-               CALL obs_rea_sla( 0, sladata(nslasets), 1, &
-                  &              slafbfiles(jset:jset), &
-                  &              nslavars, nslaextr, nitend-nit000+2, &
-                  &              dobsini, dobsend, ln_ignmis, .FALSE. )
-               CALL obs_pre_sla( sladata(nslasets), sladatqc(nslasets), &
-                  &              ln_sla, ln_nea )
-
-            END DO               
-
-         ENDIF
-         
-         CALL obs_rea_mdt( nslasets, sladatqc, n2dint )
-            
-         ! read in altimeter bias
-         
-         IF ( ln_altbias ) THEN     
-            CALL obs_rea_altbias ( nslasets, sladatqc, n2dint, bias_file )
-         ENDIF
-     
-      ENDIF
-
-      !  - Sea surface height
-      IF ( ln_ssh ) THEN
-         IF(lwp) WRITE(numout,*) ' SSH currently not available'
-      ENDIF
-
-      !  - Sea surface temperature
-      IF ( ln_sst ) THEN
-
-         ! Set the number of variables for sst to 1
-         nsstvars = 1
-
-         ! Set the number of extra variables for sst to 0
-         nsstextr = 0
-
-         nsstsets = 0
-
-         IF (ln_reysst) nsstsets = nsstsets + 1
-         IF (ln_ghrsst) nsstsets = nsstsets + 1
-         IF ( ln_sstfb ) THEN
-            nsstsets = nsstsets + jnumsstfb
-         ENDIF
-
-         ALLOCATE(sstdata(nsstsets))
-         ALLOCATE(sstdatqc(nsstsets))
-         ALLOCATE(ld_sstnight(nsstsets))
-         sstdata(:)%nsurf=0
-         sstdatqc(:)%nsurf=0    
-         ld_sstnight(:)=.false.
-
-         nsstsets = 0
-
-         IF (ln_reysst) THEN
-
-            nsstsets = nsstsets + 1
-
-            ld_sstnight(nsstsets) = ln_sstnight
-
-            CALL obs_rea_sst_rey( reysstname, reysstfmt, sstdata(nsstsets), &
-               &                  nsstvars, nsstextr, &
-               &                  nitend-nit000+2, dobsini, dobsend )
-            CALL obs_pre_sst( sstdata(nsstsets), sstdatqc(nsstsets), ln_sst, &
-               &              ln_nea )
-
-        ENDIF
-        
-        IF (ln_ghrsst) THEN
-        
-            nsstsets = nsstsets + 1
-
-            ld_sstnight(nsstsets) = ln_sstnight
-          
-            CALL obs_rea_sst( 1, sstdata(nsstsets), jnumsst, &
-               &              sstfiles(1:jnumsst), &
-               &              nsstvars, nsstextr, nitend-nit000+2, &
-               &              dobsini, dobsend, ln_ignmis, .FALSE. )
-            CALL obs_pre_sst( sstdata(nsstsets), sstdatqc(nsstsets), ln_sst, &
-               &              ln_nea )
-
-        ENDIF
-               
-         ! Feedback SST data
-
-         IF ( ln_sstfb ) THEN
-
-            DO jset = 1, jnumsstfb
-            
-               nsstsets = nsstsets + 1
-
-               ld_sstnight(nsstsets) = ln_sstnight
-            
-               CALL obs_rea_sst( 0, sstdata(nsstsets), 1, &
-                  &              sstfbfiles(jset:jset), &
-                  &              nsstvars, nsstextr, nitend-nit000+2, &
-                  &              dobsini, dobsend, ln_ignmis, .FALSE. )
-               CALL obs_pre_sst( sstdata(nsstsets), sstdatqc(nsstsets), &
-                  &              ln_sst, ln_nea )
-
-            END DO               
-
-         ENDIF
-
-      ENDIF
-
-      !  - Sea surface salinity
-      IF ( ln_sss ) THEN
-         IF(lwp) WRITE(numout,*) ' SSS currently not available'
-      ENDIF
-
-      !  - Sea Ice Concentration
-      
-      IF ( ln_seaice ) THEN
-
-         ! Set the number of variables for seaice to 1
-         nseaicevars = 1
-
-         ! Set the number of extra variables for seaice to 0
-         nseaiceextr = 0
-         
-         ! Set the number of data sets to 1
-         nseaicesets = 1
-
-         ALLOCATE(seaicedata(nseaicesets))
-         ALLOCATE(seaicedatqc(nseaicesets))
-         seaicedata(:)%nsurf=0
-         seaicedatqc(:)%nsurf=0
-
-         CALL obs_rea_seaice( 1, seaicedata(nseaicesets), jnumseaice, &
-            &                 seaicefiles(1:jnumseaice), &
-            &                 nseaicevars, nseaiceextr, nitend-nit000+2, &
-            &                 dobsini, dobsend, ln_ignmis, .FALSE. )
-
-         CALL obs_pre_seaice( seaicedata(nseaicesets), seaicedatqc(nseaicesets), &
-            &                 ln_seaice, ln_nea )
- 
-      ENDIF
-
-      IF (ln_vel3d) THEN
-
-         ! Set the number of variables for profiles to 2 (U and V)
-         nvelovars = 2
-
-         ! Set the number of extra variables for profiles to 2 to store 
-         ! rotation parameters
-         nveloextr = 2
-
-         jveloset = 0
-         
-         IF ( ln_velavcur ) jveloset = jveloset + 1
-         IF ( ln_velhrcur ) jveloset = jveloset + 1
-         IF ( ln_velavadcp ) jveloset = jveloset + 1
-         IF ( ln_velhradcp ) jveloset = jveloset + 1
-         IF (ln_velfb) jveloset = jveloset + jnumvelfb
-
-         nvelosets = jveloset
-         IF ( nvelosets > 0 ) THEN
-            ALLOCATE( velodata(nvelosets) )
-            ALLOCATE( veldatqc(nvelosets) )
-            ALLOCATE( ld_velav(nvelosets) )
-         ENDIF
-         
-         jveloset = 0
-         
-         ! Daily averaged data
-
-         IF ( ln_velavcur ) THEN
-            
-            jveloset = jveloset + 1
-            
-            ld_velav(jveloset) = .TRUE.
-            
-            CALL obs_rea_vel_dri( 1, velodata(jveloset), jnumvelavcur, &
-               &                  velavcurfiles(1:jnumvelavcur), &
-               &                  nvelovars, nveloextr, &
-               &                  nitend-nit000+2,              &
-               &                  dobsini, dobsend, ln_ignmis, &
-               &                  ld_velav(jveloset), &
-               &                  .FALSE. )
-            
-            DO jvar = 1, 2
-               CALL obs_prof_staend( velodata(jveloset), jvar )
-            END DO
-            
-            CALL obs_pre_vel( velodata(jveloset), veldatqc(jveloset), &
-               &              ln_vel3d, ln_nea, ld_velav(jveloset) )
-            
-         ENDIF
-
-         ! High frequency data
-
-         IF ( ln_velhrcur ) THEN
-            
-            jveloset = jveloset + 1
-            
-            ld_velav(jveloset) = .FALSE.
-               
-            CALL obs_rea_vel_dri( 1, velodata(jveloset), jnumvelhrcur, &
-               &                  velhrcurfiles(1:jnumvelhrcur), &
-               &                  nvelovars, nveloextr, &
-               &                  nitend-nit000+2,              &
-               &                  dobsini, dobsend, ln_ignmis, &
-               &                  ld_velav(jveloset), &
-               &                  .FALSE. )
-            
-            DO jvar = 1, 2
-               CALL obs_prof_staend( velodata(jveloset), jvar )
-            END DO
-            
-            CALL obs_pre_vel( velodata(jveloset), veldatqc(jveloset), &
-               &              ln_vel3d, ln_nea, ld_velav(jveloset) )
-            
-         ENDIF
-
-         ! Daily averaged data
-
-         IF ( ln_velavadcp ) THEN
-            
-            jveloset = jveloset + 1
-            
-            ld_velav(jveloset) = .TRUE.
-            
-            CALL obs_rea_vel_dri( 1, velodata(jveloset), jnumvelavadcp, &
-               &                  velavadcpfiles(1:jnumvelavadcp), &
-               &                  nvelovars, nveloextr, &
-               &                  nitend-nit000+2,              &
-               &                  dobsini, dobsend, ln_ignmis, &
-               &                  ld_velav(jveloset), &
-               &                  .FALSE. )
-            
-            DO jvar = 1, 2
-               CALL obs_prof_staend( velodata(jveloset), jvar )
-            END DO
-            
-            CALL obs_pre_vel( velodata(jveloset), veldatqc(jveloset), &
-               &              ln_vel3d, ln_nea, ld_velav(jveloset) )
-            
-         ENDIF
-
-         ! High frequency data
-
-         IF ( ln_velhradcp ) THEN
-            
-            jveloset = jveloset + 1
-            
-            ld_velav(jveloset) = .FALSE.
-               
-            CALL obs_rea_vel_dri( 1, velodata(jveloset), jnumvelhradcp, &
-               &                  velhradcpfiles(1:jnumvelhradcp), &
-               &                  nvelovars, nveloextr, &
-               &                  nitend-nit000+2,              &
-               &                  dobsini, dobsend, ln_ignmis, &
-               &                  ld_velav(jveloset), &
-               &                  .FALSE. )
-            
-            DO jvar = 1, 2
-               CALL obs_prof_staend( velodata(jveloset), jvar )
-            END DO
-            
-            CALL obs_pre_vel( velodata(jveloset), veldatqc(jveloset), &
-               &              ln_vel3d, ln_nea, ld_velav(jveloset) )
-            
-         ENDIF
-
-         IF ( ln_velfb ) THEN
-
-            DO jset = 1, jnumvelfb
-            
-               jveloset = jveloset + 1
-
-               ld_velav(jveloset) = ln_velfb_av(jset)
-               
-               CALL obs_rea_vel_dri( 0, velodata(jveloset), 1, &
-                  &                  velfbfiles(jset:jset), &
-                  &                  nvelovars, nveloextr, &
-                  &                  nitend-nit000+2,              &
-                  &                  dobsini, dobsend, ln_ignmis, &
-                  &                  ld_velav(jveloset), &
-                  &                  .FALSE. )
-               
-               DO jvar = 1, 2
-                  CALL obs_prof_staend( velodata(jveloset), jvar )
-               END DO
-               
-               CALL obs_pre_vel( velodata(jveloset), veldatqc(jveloset), &
-                  &              ln_vel3d, ln_nea, ld_velav(jveloset) )
-
-
-            END DO
-            
-         ENDIF
-
-      ENDIF
-     
    END SUBROUTINE dia_obs_init
 
@@ -974,13 +845,9 @@
       !!
       !! ** Method  : Call the observation operators on each time step to
-      !!              compute the model equivalent of the following date:
-      !!               - T profiles
-      !!               - S profiles
-      !!               - Sea surface height (referenced to a mean)
-      !!               - Sea surface temperature
-      !!               - Sea surface salinity
-      !!               - Velocity component (U,V) profiles
-      !!
-      !! ** Action  : 
+      !!              compute the model equivalent of the following data:
+      !!               - Profile data, currently T/S or U/V
+      !!               - Surface data, currently SST, SLA or sea-ice concentration.
+      !!
+      !! ** Action  :
       !!
       !! History :
@@ -991,44 +858,80 @@
       !!        !  07-04  (G. Smith) Generalized surface operators
       !!        !  08-10  (M. Valdivieso) obs operator for velocity profiles
+      !!        !  15-08  (M. Martin) Combined surface/profile routines.
       !!----------------------------------------------------------------------
       !! * Modules used
-      USE dom_oce, ONLY : &             ! Ocean space and time domain variables
-         & rdt,           &                       
-         & gdept_1d,       &             
-         & tmask, umask, vmask                            
-      USE phycst, ONLY : &              ! Physical constants
-         & rday                         
-      USE oce, ONLY : &                 ! Ocean dynamics and tracers variables
-         & tsn,  &             
-         & un, vn,  &
+      USE phycst, ONLY : &         ! Physical constants
+         & rday
+      USE oce, ONLY : &            ! Ocean dynamics and tracers variables
+         & tsn,       &
+         & un,        &
+         & vn,        &
          & sshn
 #if defined  key_lim3
-      USE ice, ONLY : &                     ! LIM Ice model variables
+      USE ice, ONLY : &            ! LIM3 Ice model variables
          & frld
 #endif
 #if defined key_lim2
-      USE ice_2, ONLY : &                     ! LIM Ice model variables
+      USE ice_2, ONLY : &          ! LIM2 Ice model variables
          & frld
 #endif
+#if defined key_cice
+      USE sbc_oce, ONLY : fr_i     ! ice fraction
+#endif
+#if defined key_hadocc
+      USE trc, ONLY :  &           ! HadOCC variables
+         & trn, &
+         & HADOCC_CHL, &
+         & HADOCC_FCO2, &
+         & HADOCC_PCO2, &
+         & HADOCC_FILL_FLT
+      USE par_hadocc
+      USE had_bgc_const, ONLY: c2n_p
+#elif defined key_medusa
+      USE trc, ONLY :  &           ! MEDUSA variables
+         & trn
+      USE par_medusa
+      USE sms_medusa, ONLY: &
+         & xthetapn, &
+         & xthetapd
+#if defined key_roam
+      USE sms_medusa, ONLY: &
+         & f2_pco2w, &
+         & f2_fco2w, &
+         & f3_pH
+#endif
+#elif defined key_fabm
+      USE fabm
+      USE par_fabm
+#endif
+#if defined key_spm
+      USE par_spm, ONLY: &         ! ERSEM/SPM sediments
+         & jp_spm
+      USE trc, ONLY :  &
+         & trn
+#endif
+
       IMPLICIT NONE
 
       !! * Arguments
-      INTEGER, INTENT(IN) :: kstp                         ! Current timestep
+      INTEGER, INTENT(IN) :: kstp  ! Current timestep
       !! * Local declarations
-      INTEGER :: idaystp                ! Number of timesteps per day
-      INTEGER :: jprofset               ! Profile data set loop variable
-      INTEGER :: jslaset                ! SLA data set loop variable
-      INTEGER :: jsstset                ! SST data set loop variable
-      INTEGER :: jseaiceset             ! sea ice data set loop variable
-      INTEGER :: jveloset               ! velocity profile data loop variable
-      INTEGER :: jvar                   ! Variable number    
-#if ! defined key_lim2 && ! defined key_lim3
-      REAL(wp), POINTER, DIMENSION(:,:) :: frld   
-#endif
-      CHARACTER(LEN=20) :: datestr=" ",timestr=" "
- 
-#if ! defined key_lim2 && ! defined key_lim3
-      CALL wrk_alloc(jpi,jpj,frld) 
-#endif
+      INTEGER :: idaystp           ! Number of timesteps per day
+      INTEGER :: jtype             ! Data loop variable
+      INTEGER :: jvar              ! Variable number
+      INTEGER :: ji, jj, jk        ! Loop counters
+      REAL(wp) :: tiny             ! small number
+      REAL(wp), POINTER, DIMENSION(:,:,:,:) :: &
+         & zprofvar                ! Model values for variables in a prof ob
+      REAL(wp), POINTER, DIMENSION(:,:,:,:) :: &
+         & zprofmask               ! Mask associated with zprofvar
+      REAL(wp), POINTER, DIMENSION(:,:) :: &
+         & zsurfvar, &             ! Model values equivalent to surface ob.
+         & zsurfmask               ! Mask associated with surface variable
+      REAL(wp), POINTER, DIMENSION(:,:,:) :: &
+         & zglam,    &             ! Model longitudes for prof variables
+         & zgphi                   ! Model latitudes for prof variables
+      LOGICAL :: llog10            ! Perform log10 transform of variable
+
 
       IF(lwp) THEN
@@ -1036,4 +939,5 @@
          WRITE(numout,*) 'dia_obs : Call the observation operators', kstp
          WRITE(numout,*) '~~~~~~~'
+         CALL FLUSH(numout)
       ENDIF
 
@@ -1041,82 +945,550 @@
 
       !-----------------------------------------------------------------------
-      ! No LIM => frld == 0.0_wp
-      !-----------------------------------------------------------------------
-#if ! defined key_lim2 && ! defined key_lim3
-      frld(:,:) = 0.0_wp
-#endif
-      !-----------------------------------------------------------------------
-      ! Depending on switches call various observation operators
-      !-----------------------------------------------------------------------
-
-      !  - Temperature/salinity profiles
-      IF ( ln_t3d .OR. ln_s3d ) THEN
-         DO jprofset = 1, nprofsets
-            IF ( ld_enact(jprofset) ) THEN
-               CALL obs_pro_opt( prodatqc(jprofset),                     &
-                  &              kstp, jpi, jpj, jpk, nit000, idaystp,   &
-                  &              tsn(:,:,:,jp_tem), tsn(:,:,:,jp_sal),   &
-                  &              gdept_1d, tmask, n1dint, n2dint,        &
-                  &              kdailyavtypes = endailyavtypes )
-            ELSE
-               CALL obs_pro_opt( prodatqc(jprofset),                     &
-                  &              kstp, jpi, jpj, jpk, nit000, idaystp,   &
-                  &              tsn(:,:,:,jp_tem), tsn(:,:,:,jp_sal),   &
-                  &              gdept_1d, tmask, n1dint, n2dint              )
+      ! Call the profile and surface observation operators
+      !-----------------------------------------------------------------------
+
+      IF ( nproftypes > 0 ) THEN
+
+         DO jtype = 1, nproftypes
+
+            ! Allocate local work arrays
+            CALL wrk_alloc( jpi, jpj, jpk, profdataqc(jtype)%nvar, zprofvar  )
+            CALL wrk_alloc( jpi, jpj, jpk, profdataqc(jtype)%nvar, zprofmask )
+            CALL wrk_alloc( jpi, jpj,      profdataqc(jtype)%nvar, zglam     )
+            CALL wrk_alloc( jpi, jpj,      profdataqc(jtype)%nvar, zgphi     )
+            
+            ! Defaults which might change
+            DO jvar = 1, profdataqc(jtype)%nvar
+               zprofmask(:,:,:,jvar) = tmask(:,:,:)
+               zglam(:,:,jvar)       = glamt(:,:)
+               zgphi(:,:,jvar)       = gphit(:,:)
+            END DO
+
+            SELECT CASE ( TRIM(cobstypesprof(jtype)) )
+
+            CASE('prof')
+               zprofvar(:,:,:,1) = tsn(:,:,:,jp_tem)
+               zprofvar(:,:,:,2) = tsn(:,:,:,jp_sal)
+
+            CASE('vel')
+               zprofvar(:,:,:,1) = un(:,:,:)
+               zprofvar(:,:,:,2) = vn(:,:,:)
+               zprofmask(:,:,:,1) = umask(:,:,:)
+               zprofmask(:,:,:,2) = vmask(:,:,:)
+               zglam(:,:,1) = glamu(:,:)
+               zglam(:,:,2) = glamv(:,:)
+               zgphi(:,:,1) = gphiu(:,:)
+               zgphi(:,:,2) = gphiv(:,:)
+
+            CASE('plchltot')
+#if defined key_hadocc
+               ! Chlorophyll from HadOCC
+               zprofvar(:,:,:,1) = HADOCC_CHL(:,:,:)
+#elif defined key_medusa
+               ! Add non-diatom and diatom chlorophyll from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpchn) + trn(:,:,:,jpchd)
+#elif defined key_fabm
+               ! Add all chlorophyll groups from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_chl1) + trn(:,:,:,jp_fabm_chl2) + &
+                  &                trn(:,:,:,jp_fabm_chl3) + trn(:,:,:,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run plchltot observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               ! Take the log10 where we can, otherwise exclude
+               tiny = 1.0e-20
+               WHERE(zprofvar(:,:,:,:) > tiny .AND. zprofvar(:,:,:,:) /= obfillflt )
+                  zprofvar(:,:,:,:)  = LOG10(zprofvar(:,:,:,:))
+               ELSEWHERE
+                  zprofvar(:,:,:,:)  = obfillflt
+                  zprofmask(:,:,:,:) = 0
+               END WHERE
+               ! Mask out model below any excluded values,
+               ! to avoid interpolation issues
+               DO jvar = 1, profdataqc(jtype)%nvar
+                 DO jj = 1, jpj
+                    DO ji = 1, jpi
+                       depth_loop: DO jk = 1, jpk
+                          IF ( zprofmask(ji,jj,jk,jvar) == 0 ) THEN
+                             zprofmask(ji,jj,jk:jpk,jvar) = 0
+                             EXIT depth_loop
+                          ENDIF
+                       END DO depth_loop
+                    END DO
+                 END DO
+              END DO
+
+            CASE('pchltot')
+#if defined key_hadocc
+               ! Chlorophyll from HadOCC
+               zprofvar(:,:,:,1) = HADOCC_CHL(:,:,:)
+#elif defined key_medusa
+               ! Add non-diatom and diatom chlorophyll from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpchn) + trn(:,:,:,jpchd)
+#elif defined key_fabm
+               ! Add all chlorophyll groups from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_chl1) + trn(:,:,:,jp_fabm_chl2) + &
+                  &                trn(:,:,:,jp_fabm_chl3) + trn(:,:,:,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run pchltot observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('pno3')
+#if defined key_hadocc
+               ! Dissolved inorganic nitrogen from HadOCC
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_had_nut)
+#elif defined key_medusa
+               ! Dissolved inorganic nitrogen from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpdin)
+#elif defined key_fabm
+               ! Nitrate from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_n3n)
+#else
+               CALL ctl_stop( ' Trying to run pno3 observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('psi4')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run psi4 observation operator', &
+                  &           ' but HadOCC does not simulate silicate' )
+#elif defined key_medusa
+               ! Silicate from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpsil)
+#elif defined key_fabm
+               ! Silicate from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_n5s)
+#else
+               CALL ctl_stop( ' Trying to run psi4 observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('ppo4')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run ppo4 observation operator', &
+                  &           ' but HadOCC does not simulate phosphate' )
+#elif defined key_medusa
+               CALL ctl_stop( ' Trying to run ppo4 observation operator', &
+                  &           ' but MEDUSA does not simulate phosphate' )
+#elif defined key_fabm
+               ! Phosphate from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_n1p)
+#else
+               CALL ctl_stop( ' Trying to run ppo4 observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('pdic')
+#if defined key_hadocc
+               ! Dissolved inorganic carbon from HadOCC
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_had_dic)
+#elif defined key_medusa
+               ! Dissolved inorganic carbon from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpdic)
+#elif defined key_fabm
+               ! Dissolved inorganic carbon from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_o3c)
+#else
+               CALL ctl_stop( ' Trying to run pdic observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('palk')
+#if defined key_hadocc
+               ! Alkalinity from HadOCC
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_had_alk)
+#elif defined key_medusa
+               ! Alkalinity from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpalk)
+#elif defined key_fabm
+               ! Alkalinity from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_o3a)
+#else
+               CALL ctl_stop( ' Trying to run palk observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('pph')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run pph observation operator', &
+                  &           ' but HadOCC has no pH diagnostic defined' )
+#elif defined key_medusa && defined key_roam
+               ! pH from MEDUSA
+               zprofvar(:,:,:,1) = f3_pH(:,:,:)
+#elif defined key_fabm
+               ! pH from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_o3ph)
+#else
+               CALL ctl_stop( ' Trying to run pph observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('po2')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run po2 observation operator', &
+                  &           ' but HadOCC does not simulate oxygen' )
+#elif defined key_medusa
+               ! Oxygen from MEDUSA
+               zprofvar(:,:,:,1) = trn(:,:,:,jpoxy)
+#elif defined key_fabm
+               ! Oxygen from ERSEM
+               zprofvar(:,:,:,1) = trn(:,:,:,jp_fabm_o2o)
+#else
+               CALL ctl_stop( ' Trying to run po2 observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE DEFAULT
+               CALL ctl_stop( 'Unknown profile observation type '//TRIM(cobstypesprof(jtype))//' in dia_obs' )
+
+            END SELECT
+
+            DO jvar = 1, profdataqc(jtype)%nvar
+               CALL obs_prof_opt( profdataqc(jtype), kstp, jpi, jpj, jpk,  &
+                  &               nit000, idaystp, jvar,                   &
+                  &               zprofvar(:,:,:,jvar),                    &
+                  &               fsdept(:,:,:), fsdepw(:,:,:),            & 
+                  &               zprofmask(:,:,:,jvar),                   &
+                  &               zglam(:,:,jvar), zgphi(:,:,jvar),        &
+                  &               nn_1dint, nn_2dint_default,              &
+                  &               kdailyavtypes = nn_profdavtypes )
+            END DO
+
+            CALL wrk_dealloc( jpi, jpj, jpk, profdataqc(jtype)%nvar, zprofvar  )
+            CALL wrk_dealloc( jpi, jpj, jpk, profdataqc(jtype)%nvar, zprofmask )
+            CALL wrk_dealloc( jpi, jpj,      profdataqc(jtype)%nvar, zglam     )
+            CALL wrk_dealloc( jpi, jpj,      profdataqc(jtype)%nvar, zgphi     )
+
+         END DO
+
+      ENDIF
+
+      IF ( nsurftypes > 0 ) THEN
+
+         !Allocate local work arrays
+         CALL wrk_alloc( jpi, jpj, zsurfvar )
+         CALL wrk_alloc( jpi, jpj, zsurfmask )
+
+         DO jtype = 1, nsurftypes
+
+            !Defaults which might be changed
+            zsurfmask(:,:) = tmask(:,:,1)
+            llog10 = .FALSE.
+
+            SELECT CASE ( TRIM(cobstypessurf(jtype)) )
+            CASE('sst')
+               zsurfvar(:,:) = tsn(:,:,1,jp_tem)
+            CASE('sla')
+               zsurfvar(:,:) = sshn(:,:)
+            CASE('sss')
+               zsurfvar(:,:) = tsn(:,:,1,jp_sal)
+            CASE('sic')
+               IF ( kstp == 0 ) THEN
+                  IF ( lwp .AND. surfdataqc(jtype)%nsstpmpp(1) > 0 ) THEN
+                     CALL ctl_warn( 'Sea-ice not initialised on zeroth '// &
+                        &           'time-step but some obs are valid then.' )
+                     WRITE(numout,*)surfdataqc(jtype)%nsstpmpp(1), &
+                        &           ' sea-ice obs will be missed'
+                  ENDIF
+                  surfdataqc(jtype)%nsurfup = surfdataqc(jtype)%nsurfup + &
+                     &                        surfdataqc(jtype)%nsstp(1)
+                  CYCLE
+               ELSE
+#if defined key_cice
+                  zsurfvar(:,:) = fr_i(:,:)
+#elif defined key_lim2 || defined key_lim3
+                  zsurfvar(:,:) = 1._wp - frld(:,:)
+#else
+               CALL ctl_stop( ' Trying to run sea-ice observation operator', &
+                  &           ' but no sea-ice model appears to have been defined' )
+#endif
+               ENDIF
+
+            CASE('slchltot')
+#if defined key_hadocc
+               ! Surface chlorophyll from HadOCC
+               zsurfvar(:,:) = HADOCC_CHL(:,:,1)
+#elif defined key_medusa
+               ! Add non-diatom and diatom surface chlorophyll from MEDUSA
+               zsurfvar(:,:) = trn(:,:,1,jpchn) + trn(:,:,1,jpchd)
+#elif defined key_fabm
+               ! Add all surface chlorophyll groups from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl1) + trn(:,:,1,jp_fabm_chl2) + &
+                  &            trn(:,:,1,jp_fabm_chl3) + trn(:,:,1,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run slchltot observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slchldia')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slchldia observation operator', &
+                  &           ' but HadOCC does not explicitly simulate diatoms' )
+#elif defined key_medusa
+               ! Diatom surface chlorophyll from MEDUSA
+               zsurfvar(:,:) = trn(:,:,1,jpchd)
+#elif defined key_fabm
+               ! Diatom surface chlorophyll from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl1)
+#else
+               CALL ctl_stop( ' Trying to run slchldia observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slchlnon')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slchlnon observation operator', &
+                  &           ' but HadOCC does not explicitly simulate non-diatoms' )
+#elif defined key_medusa
+               ! Non-diatom surface chlorophyll from MEDUSA
+               zsurfvar(:,:) = trn(:,:,1,jpchn)
+#elif defined key_fabm
+               ! Add all non-diatom surface chlorophyll groups from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl2) + &
+                  &            trn(:,:,1,jp_fabm_chl3) + trn(:,:,1,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run slchlnon observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slchldin')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slchldin observation operator', &
+                  &           ' but HadOCC does not explicitly simulate dinoflagellates' )
+#elif defined key_medusa
+               CALL ctl_stop( ' Trying to run slchldin observation operator', &
+                  &           ' but MEDUSA does not explicitly simulate dinoflagellates' )
+#elif defined key_fabm
+               ! Dinoflagellate surface chlorophyll from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run slchldin observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slchlmic')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slchlmic observation operator', &
+                  &           ' but HadOCC does not explicitly simulate microphytoplankton' )
+#elif defined key_medusa
+               CALL ctl_stop( ' Trying to run slchlmic observation operator', &
+                  &           ' but MEDUSA does not explicitly simulate microphytoplankton' )
+#elif defined key_fabm
+               ! Add diatom and dinoflagellate surface chlorophyll from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl1) + trn(:,:,1,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run slchlmic observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slchlnan')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slchlnan observation operator', &
+                  &           ' but HadOCC does not explicitly simulate nanophytoplankton' )
+#elif defined key_medusa
+               CALL ctl_stop( ' Trying to run slchlnan observation operator', &
+                  &           ' but MEDUSA does not explicitly simulate nanophytoplankton' )
+#elif defined key_fabm
+               ! Nanophytoplankton surface chlorophyll from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl2)
+#else
+               CALL ctl_stop( ' Trying to run slchlnan observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slchlpic')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slchlpic observation operator', &
+                  &           ' but HadOCC does not explicitly simulate picophytoplankton' )
+#elif defined key_medusa
+               CALL ctl_stop( ' Trying to run slchlpic observation operator', &
+                  &           ' but MEDUSA does not explicitly simulate picophytoplankton' )
+#elif defined key_fabm
+               ! Picophytoplankton surface chlorophyll from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl3)
+#else
+               CALL ctl_stop( ' Trying to run slchlpic observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('schltot')
+#if defined key_hadocc
+               ! Surface chlorophyll from HadOCC
+               zsurfvar(:,:) = HADOCC_CHL(:,:,1)
+#elif defined key_medusa
+               ! Add non-diatom and diatom surface chlorophyll from MEDUSA
+               zsurfvar(:,:) = trn(:,:,1,jpchn) + trn(:,:,1,jpchd)
+#elif defined key_fabm
+               ! Add all surface chlorophyll groups from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_chl1) + trn(:,:,1,jp_fabm_chl2) + &
+                  &            trn(:,:,1,jp_fabm_chl3) + trn(:,:,1,jp_fabm_chl4)
+#else
+               CALL ctl_stop( ' Trying to run schltot observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('slphytot')
+#if defined key_hadocc
+               ! Surface phytoplankton nitrogen from HadOCC multiplied by C:N ratio
+               zsurfvar(:,:) = trn(:,:,1,jp_had_phy) * c2n_p
+#elif defined key_medusa
+               ! Add non-diatom and diatom surface phytoplankton nitrogen from MEDUSA
+               ! multiplied by C:N ratio for each
+               zsurfvar(:,:) = (trn(:,:,1,jpphn) * xthetapn) + (trn(:,:,1,jpphd) * xthetapd)
+#elif defined key_fabm
+               ! Add all surface phytoplankton carbon groups from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_p1c) + trn(:,:,1,jp_fabm_p2c) + &
+                  &            trn(:,:,1,jp_fabm_p3c) + trn(:,:,1,jp_fabm_p4c)
+#else
+               CALL ctl_stop( ' Trying to run slphytot observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slphydia')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slphydia observation operator', &
+                  &           ' but HadOCC does not explicitly simulate diatoms' )
+#elif defined key_medusa
+               ! Diatom surface phytoplankton nitrogen from MEDUSA multiplied by C:N ratio
+               zsurfvar(:,:) = trn(:,:,1,jpphd) * xthetapd
+#elif defined key_fabm
+               ! Diatom surface phytoplankton carbon from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_p1c)
+#else
+               CALL ctl_stop( ' Trying to run slphydia observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('slphynon')
+#if defined key_hadocc
+               CALL ctl_stop( ' Trying to run slphynon observation operator', &
+                  &           ' but HadOCC does not explicitly simulate non-diatoms' )
+#elif defined key_medusa
+               ! Non-diatom surface phytoplankton nitrogen from MEDUSA multiplied by C:N ratio
+               zsurfvar(:,:) = trn(:,:,1,jpphn) * xthetapn
+#elif defined key_fabm
+               ! Add all non-diatom surface phytoplankton carbon groups from ERSEM
+               zsurfvar(:,:) = trn(:,:,1,jp_fabm_p2c) + &
+                  &            trn(:,:,1,jp_fabm_p3c) + trn(:,:,1,jp_fabm_p4c)
+#else
+               CALL ctl_stop( ' Trying to run slphynon observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+               llog10 = .TRUE.
+
+            CASE('sspm')
+#if defined key_spm
+               zsurfvar(:,:) = 0.0
+               DO jn = 1, jp_spm
+                  zsurfvar(:,:) = zsurfvar(:,:) + trn(:,:,1,jn)   ! sum SPM sizes
+               END DO
+#else
+               CALL ctl_stop( ' Trying to run sspm observation operator', &
+                  &           ' but no spm model appears to have been defined' )
+#endif
+
+            CASE('sfco2')
+#if defined key_hadocc
+               zsurfvar(:,:) = HADOCC_FCO2(:,:)    ! fCO2 from HadOCC
+               IF ( ( MINVAL( HADOCC_FCO2 ) == HADOCC_FILL_FLT ) .AND. &
+                  & ( MAXVAL( HADOCC_FCO2 ) == HADOCC_FILL_FLT ) ) THEN
+                  zsurfvar(:,:) = obfillflt
+                  zsurfmask(:,:) = 0
+                  CALL ctl_warn( ' HadOCC fCO2 values masked out for observation operator', &
+                     &           ' as HADOCC_FCO2(:,:) == HADOCC_FILL_FLT' )
+               ENDIF
+#elif defined key_medusa && defined key_roam
+               zsurfvar(:,:) = f2_fco2w(:,:)
+#elif defined key_fabm
+               ! First, get pCO2 from FABM
+               pco2_3d(:,:,:) = fabm_get_bulk_diagnostic_data(model, jp_fabm_o3pc)
+               zsurfvar(:,:) = pco2_3d(:,:,1)
+               ! Now, convert pCO2 to fCO2, based on SST in K. This follows the standard methodology of:
+               ! Pierrot et al. (2009), Recommendations for autonomous underway pCO2 measuring systems
+               ! and data reduction routines, Deep-Sea Research II, 56: 512-522.
+               ! and
+               ! Weiss (1974), Carbon dioxide in water and seawater: the solubility of a non-ideal gas,
+               ! Marine Chemistry, 2: 203-215.
+               ! In the implementation below, atmospheric pressure has been assumed to be 1 atm and so
+               ! not explicitly included - atmospheric pressure is not necessarily available so this is
+               ! the best assumption.
+               ! Further, the (1-xCO2)^2 term has been neglected. This is common practice
+               ! (see e.g. Zeebe and Wolf-Gladrow (2001), CO2 in Seawater: Equilibrium, Kinetics, Isotopes)
+               ! because xCO2 in atm is ~0, and so this term will only affect the result to the 3rd decimal
+               ! place for typical values, and xCO2 would need to be approximated from pCO2 anyway.
+               zsurfvar(:,:) = zsurfvar(:,:) * EXP((-1636.75                                                          + &
+                  &            12.0408      * (tsn(:,:,1,jp_tem)+rt0)                                                 - &
+                  &            0.0327957    * (tsn(:,:,1,jp_tem)+rt0)*(tsn(:,:,1,jp_tem)+rt0)                         + &
+                  &            0.0000316528 * (tsn(:,:,1,jp_tem)+rt0)*(tsn(:,:,1,jp_tem)+rt0)*(tsn(:,:,1,jp_tem)+rt0) + &
+                  &            2.0 * (57.7 - 0.118 * (tsn(:,:,1,jp_tem)+rt0)))                                        / &
+                  &            (82.0578 * (tsn(:,:,1,jp_tem)+rt0)))
+#else
+               CALL ctl_stop( ' Trying to run sfco2 observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE('spco2')
+#if defined key_hadocc
+               zsurfvar(:,:) = HADOCC_PCO2(:,:)    ! pCO2 from HadOCC
+               IF ( ( MINVAL( HADOCC_PCO2 ) == HADOCC_FILL_FLT ) .AND. &
+                  & ( MAXVAL( HADOCC_PCO2 ) == HADOCC_FILL_FLT ) ) THEN
+                  zsurfvar(:,:) = obfillflt
+                  zsurfmask(:,:) = 0
+                  CALL ctl_warn( ' HadOCC pCO2 values masked out for observation operator', &
+                     &           ' as HADOCC_PCO2(:,:) == HADOCC_FILL_FLT' )
+               ENDIF
+#elif defined key_medusa && defined key_roam
+               zsurfvar(:,:) = f2_pco2w(:,:)
+#elif defined key_fabm
+               pco2_3d(:,:,:) = fabm_get_bulk_diagnostic_data(model, jp_fabm_o3pc)
+               zsurfvar(:,:) = pco2_3d(:,:,1)
+#else
+               CALL ctl_stop( ' Trying to run spco2 observation operator', &
+                  &           ' but no biogeochemical model appears to have been defined' )
+#endif
+
+            CASE DEFAULT
+
+               CALL ctl_stop( 'Unknown surface observation type '//TRIM(cobstypessurf(jtype))//' in dia_obs' )
+
+            END SELECT
+            
+            IF ( llog10 ) THEN
+               ! Take the log10 where we can, otherwise exclude
+               tiny = 1.0e-20
+               WHERE(zsurfvar(:,:) > tiny .AND. zsurfvar(:,:) /= obfillflt )
+                  zsurfvar(:,:)  = LOG10(zsurfvar(:,:))
+               ELSEWHERE
+                  zsurfvar(:,:)  = obfillflt
+                  zsurfmask(:,:) = 0
+               END WHERE
             ENDIF
+
+            CALL obs_surf_opt( surfdataqc(jtype), kstp, jpi, jpj,       &
+               &               nit000, idaystp, zsurfvar, zsurfmask,    &
+               &               n2dintsurf(jtype), llnightav(jtype),     &
+               &               ravglamscl(jtype), ravgphiscl(jtype),     &
+               &               lfpindegs(jtype) )
+
          END DO
+
+         CALL wrk_dealloc( jpi, jpj, zsurfvar )
+         CALL wrk_dealloc( jpi, jpj, zsurfmask )
+
       ENDIF
 
-      !  - Sea surface anomaly
-      IF ( ln_sla ) THEN
-         DO jslaset = 1, nslasets
-            CALL obs_sla_opt( sladatqc(jslaset),            &
-               &              kstp, jpi, jpj, nit000, sshn, &
-               &              tmask(:,:,1), n2dint )
-         END DO         
-      ENDIF
-
-      !  - Sea surface temperature
-      IF ( ln_sst ) THEN
-         DO jsstset = 1, nsstsets
-            CALL obs_sst_opt( sstdatqc(jsstset),                &
-               &              kstp, jpi, jpj, nit000, idaystp,  &
-               &              tsn(:,:,1,jp_tem), tmask(:,:,1),  &
-               &              n2dint, ld_sstnight(jsstset) )
-         END DO
-      ENDIF
-
-      !  - Sea surface salinity
-      IF ( ln_sss ) THEN
-         IF(lwp) WRITE(numout,*) ' SSS currently not available'
-      ENDIF
-
-#if defined key_lim2 || defined key_lim3
-      IF ( ln_seaice ) THEN
-         DO jseaiceset = 1, nseaicesets
-            CALL obs_seaice_opt( seaicedatqc(jseaiceset),      &
-               &              kstp, jpi, jpj, nit000, 1.-frld, &
-               &              tmask(:,:,1), n2dint )
-         END DO
-      ENDIF      
-#endif
-
-      !  - Velocity profiles
-      IF ( ln_vel3d ) THEN
-         DO jveloset = 1, nvelosets
-           ! zonal component of velocity
-           CALL obs_vel_opt( veldatqc(jveloset), kstp, jpi, jpj, jpk, &
-              &              nit000, idaystp, un, vn, gdept_1d, umask, vmask, &
-                             n1dint, n2dint, ld_velav(jveloset) )
-         END DO
-      ENDIF
-
-#if ! defined key_lim2 && ! defined key_lim3
-      CALL wrk_dealloc(jpi,jpj,frld) 
-#endif
-
    END SUBROUTINE dia_obs
-  
-   SUBROUTINE dia_obs_wri 
+
+   SUBROUTINE dia_obs_wri
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE dia_obs_wri  ***
@@ -1126,5 +1498,5 @@
       !! ** Method  : Call observation diagnostic output routines
       !!
-      !! ** Action  : 
+      !! ** Action  :
       !!
       !! History :
@@ -1134,258 +1506,76 @@
       !!        !  07-03  (K. Mogensen) General handling of profiles
       !!        !  08-09  (M. Valdivieso) Velocity component (U,V) profiles
+      !!        !  15-08  (M. Martin) Combined writing for prof and surf types
       !!----------------------------------------------------------------------
+      !! * Modules used
+      USE obs_rot_vel          ! Rotation of velocities
+
       IMPLICIT NONE
 
       !! * Local declarations
-
-      INTEGER :: jprofset                 ! Profile data set loop variable
-      INTEGER :: jveloset                 ! Velocity data set loop variable
-      INTEGER :: jslaset                  ! SLA data set loop variable
-      INTEGER :: jsstset                  ! SST data set loop variable
-      INTEGER :: jseaiceset               ! Sea Ice data set loop variable
-      INTEGER :: jset
-      INTEGER :: jfbini
-      CHARACTER(LEN=20) :: datestr=" ",timestr=" "
-      CHARACTER(LEN=10) :: cdtmp
+      INTEGER :: jtype                    ! Data set loop variable
+      INTEGER :: jo, jvar, jk
+      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
+         & zu, &
+         & zv
+
       !-----------------------------------------------------------------------
       ! Depending on switches call various observation output routines
       !-----------------------------------------------------------------------
 
-      !  - Temperature/salinity profiles
-
-      IF( ln_t3d .OR. ln_s3d ) THEN
-
-         ! Copy data from prodatqc to profdata structures
-         DO jprofset = 1, nprofsets
-
-            CALL obs_prof_decompress( prodatqc(jprofset), &
-                 &                    profdata(jprofset), .TRUE., numout )
+      IF ( nproftypes > 0 ) THEN
+
+         DO jtype = 1, nproftypes
+
+            IF ( TRIM(cobstypesprof(jtype)) == 'vel' ) THEN
+
+               ! For velocity data, rotate the model velocities to N/S, E/W
+               ! using the compressed data structure.
+               ALLOCATE( &
+                  & zu(profdataqc(jtype)%nvprot(1)), &
+                  & zv(profdataqc(jtype)%nvprot(2))  &
+                  & )
+
+               CALL obs_rotvel( profdataqc(jtype), nn_2dint_default, zu, zv )
+
+               DO jo = 1, profdataqc(jtype)%nprof
+                  DO jvar = 1, 2
+                     DO jk = profdataqc(jtype)%npvsta(jo,jvar), profdataqc(jtype)%npvend(jo,jvar)
+
+                        IF ( jvar == 1 ) THEN
+                           profdataqc(jtype)%var(jvar)%vmod(jk) = zu(jk)
+                        ELSE
+                           profdataqc(jtype)%var(jvar)%vmod(jk) = zv(jk)
+                        ENDIF
+
+                     END DO
+                  END DO
+               END DO
+
+               DEALLOCATE( zu )
+               DEALLOCATE( zv )
+
+            END IF
+
+            CALL obs_prof_decompress( profdataqc(jtype), &
+               &                      profdata(jtype), .TRUE., numout )
+
+            CALL obs_wri_prof( profdata(jtype) )
 
          END DO
 
-         ! Write the profiles.
-
-         jprofset = 0
-
-         ! ENACT insitu data
-
-         IF ( ln_ena ) THEN
-           
-            jprofset = jprofset + 1
-
-            CALL obs_wri_p3d( 'enact', profdata(jprofset) )
-
-         ENDIF
-
-         ! Coriolis insitu data
-
-         IF ( ln_cor ) THEN
-            
-            jprofset = jprofset + 1
-
-            CALL obs_wri_p3d( 'corio', profdata(jprofset) )
-            
-         ENDIF
-         
-         ! Feedback insitu data
-
-         IF ( ln_profb ) THEN
-
-            jfbini = jprofset + 1
-
-            DO jprofset = jfbini, nprofsets
-               
-               jset = jprofset - jfbini + 1
-               WRITE(cdtmp,'(A,I2.2)')'profb_',jset
-               CALL obs_wri_p3d( cdtmp, profdata(jprofset) )
-
-            END DO
-
-         ENDIF
-
       ENDIF
 
-      !  - Sea surface anomaly
-      IF ( ln_sla ) THEN
-
-         ! Copy data from sladatqc to sladata structures
-         DO jslaset = 1, nslasets
-
-              CALL obs_surf_decompress( sladatqc(jslaset), &
-                 &                    sladata(jslaset), .TRUE., numout )
+      IF ( nsurftypes > 0 ) THEN
+
+         DO jtype = 1, nsurftypes
+
+            CALL obs_surf_decompress( surfdataqc(jtype), &
+               &                      surfdata(jtype), .TRUE., numout )
+
+            CALL obs_wri_surf( surfdata(jtype) )
 
          END DO
 
-         jslaset = 0 
-
-         ! Write the AVISO SLA data
-
-         IF ( ln_sladt ) THEN
-            
-            jslaset = 1
-            CALL obs_wri_sla( 'aviso_act', sladata(jslaset) )
-            jslaset = 2
-            CALL obs_wri_sla( 'aviso_pas', sladata(jslaset) )
-
-         ENDIF
-
-         IF ( ln_slafb ) THEN
-            
-            jfbini = jslaset + 1
-
-            DO jslaset = jfbini, nslasets
-               
-               jset = jslaset - jfbini + 1
-               WRITE(cdtmp,'(A,I2.2)')'slafb_',jset
-               CALL obs_wri_sla( cdtmp, sladata(jslaset) )
-
-            END DO
-
-         ENDIF
-
-      ENDIF
-
-      !  - Sea surface temperature
-      IF ( ln_sst ) THEN
-
-         ! Copy data from sstdatqc to sstdata structures
-         DO jsstset = 1, nsstsets
-     
-              CALL obs_surf_decompress( sstdatqc(jsstset), &
-                 &                    sstdata(jsstset), .TRUE., numout )
-
-         END DO
-
-         jsstset = 0 
-
-         ! Write the AVISO SST data
-
-         IF ( ln_reysst ) THEN
-            
-            jsstset = jsstset + 1
-            CALL obs_wri_sst( 'reynolds', sstdata(jsstset) )
-
-         ENDIF
-
-         IF ( ln_ghrsst ) THEN
-            
-            jsstset = jsstset + 1
-            CALL obs_wri_sst( 'ghr', sstdata(jsstset) )
-
-         ENDIF
-
-         IF ( ln_sstfb ) THEN
-            
-            jfbini = jsstset + 1
-
-            DO jsstset = jfbini, nsstsets
-               
-               jset = jsstset - jfbini + 1
-               WRITE(cdtmp,'(A,I2.2)')'sstfb_',jset
-               CALL obs_wri_sst( cdtmp, sstdata(jsstset) )
-
-            END DO
-
-         ENDIF
-
-      ENDIF
-
-      !  - Sea surface salinity
-      IF ( ln_sss ) THEN
-         IF(lwp) WRITE(numout,*) ' SSS currently not available'
-      ENDIF
-
-      !  - Sea Ice Concentration
-      IF ( ln_seaice ) THEN
-
-         ! Copy data from seaicedatqc to seaicedata structures
-         DO jseaiceset = 1, nseaicesets
-
-              CALL obs_surf_decompress( seaicedatqc(jseaiceset), &
-                 &                    seaicedata(jseaiceset), .TRUE., numout )
-
-         END DO
-
-         ! Write the Sea Ice data
-         DO jseaiceset = 1, nseaicesets
-      
-            WRITE(cdtmp,'(A,I2.2)')'seaicefb_',jseaiceset
-            CALL obs_wri_seaice( cdtmp, seaicedata(jseaiceset) )
-
-         END DO
-
-      ENDIF
-      
-      ! Velocity data
-      IF( ln_vel3d ) THEN
-
-         ! Copy data from veldatqc to velodata structures
-         DO jveloset = 1, nvelosets
-
-            CALL obs_prof_decompress( veldatqc(jveloset), &
-                 &                    velodata(jveloset), .TRUE., numout )
-
-         END DO
-
-         ! Write the profiles.
-
-         jveloset = 0
-
-         ! Daily averaged data
-
-         IF ( ln_velavcur ) THEN
-            
-            jveloset = jveloset + 1
-
-            CALL obs_wri_vel( 'velavcurr', velodata(jveloset), n2dint )
-
-         ENDIF
-
-         ! High frequency data
-
-         IF ( ln_velhrcur ) THEN
-            
-            jveloset = jveloset + 1
-
-            CALL obs_wri_vel( 'velhrcurr', velodata(jveloset), n2dint )
-
-         ENDIF
-
-         ! Daily averaged data
-
-         IF ( ln_velavadcp ) THEN
-            
-            jveloset = jveloset + 1
-
-            CALL obs_wri_vel( 'velavadcp', velodata(jveloset), n2dint )
-
-         ENDIF
-
-         ! High frequency data
-
-         IF ( ln_velhradcp ) THEN
-            
-            jveloset = jveloset + 1
-            
-            CALL obs_wri_vel( 'velhradcp', velodata(jveloset), n2dint )
-               
-         ENDIF
-
-         ! Feedback velocity data
-
-         IF ( ln_velfb ) THEN
-
-            jfbini = jveloset + 1
-
-            DO jveloset = jfbini, nvelosets
-               
-               jset = jveloset - jfbini + 1
-               WRITE(cdtmp,'(A,I2.2)')'velfb_',jset
-               CALL obs_wri_vel( cdtmp, velodata(jveloset), n2dint )
-
-            END DO
-
-         ENDIF
-         
       ENDIF
 
@@ -1405,30 +1595,15 @@
       !!
       !!----------------------------------------------------------------------
-      !! obs_grid deallocation
+      ! obs_grid deallocation
       CALL obs_grid_deallocate
 
-      !! diaobs deallocation
-      IF ( nprofsets > 0 ) THEN
-          DEALLOCATE(ld_enact, &
-                  &  profdata, &
-                  &  prodatqc)
-      END IF
-      IF ( ln_sla ) THEN
-          DEALLOCATE(sladata, &
-                  &  sladatqc)
-      END IF
-      IF ( ln_seaice ) THEN
-          DEALLOCATE(sladata, &
-                  &  sladatqc)
-      END IF
-      IF ( ln_sst ) THEN
-          DEALLOCATE(sstdata, &
-                  &  sstdatqc)
-      END IF
-      IF ( ln_vel3d ) THEN
-          DEALLOCATE(ld_velav, &
-                  &  velodata, &
-                  &  veldatqc)
-      END IF
+      ! diaobs deallocation
+      IF ( nproftypes > 0 ) &
+         &   DEALLOCATE( cobstypesprof, profdata, profdataqc, nvarsprof, nextrprof )
+
+      IF ( nsurftypes > 0 ) &
+         &   DEALLOCATE( cobstypessurf, surfdata, surfdataqc, nvarssurf, nextrsurf, &
+         &               n2dintsurf, ravglamscl, ravgphiscl, lfpindegs, llnightav )
+
    END SUBROUTINE dia_obs_dealloc
 
@@ -1436,10 +1611,10 @@
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE ini_date  ***
-      !!          
-      !! ** Purpose : Get initial data in double precision YYYYMMDD.HHMMSS format
-      !!
-      !! ** Method  : Get initial data in double precision YYYYMMDD.HHMMSS format
-      !!
-      !! ** Action  : Get initial data in double precision YYYYMMDD.HHMMSS format
+      !!
+      !! ** Purpose : Get initial date in double precision YYYYMMDD.HHMMSS format
+      !!
+      !! ** Method  : Get initial date in double precision YYYYMMDD.HHMMSS format
+      !!
+      !! ** Action  : Get initial date in double precision YYYYMMDD.HHMMSS format
       !!
       !! History :
@@ -1452,6 +1627,4 @@
       USE phycst, ONLY : &            ! Physical constants
          & rday
-!      USE daymod, ONLY : &            ! Time variables
-!         & nmonth_len           
       USE dom_oce, ONLY : &           ! Ocean space and time domain variables
          & rdt
@@ -1460,5 +1633,5 @@
 
       !! * Arguments
-      REAL(KIND=dp), INTENT(OUT) :: ddobsini                         ! Initial date in YYYYMMDD.HHMMSS
+      REAL(dp), INTENT(OUT) :: ddobsini  ! Initial date in YYYYMMDD.HHMMSS
 
       !! * Local declarations
@@ -1468,13 +1641,13 @@
       INTEGER :: ihou
       INTEGER :: imin
-      INTEGER :: imday         ! Number of days in month.
-      REAL(KIND=wp) :: zdayfrc ! Fraction of day
-
-      INTEGER, DIMENSION(12) ::   imonth_len    !: length in days of the months of the current year
-
-      !!----------------------------------------------------------------------
-      !! Initial date initialization (year, month, day, hour, minute)
-      !! (This assumes that the initial date is for 00z))
-      !!----------------------------------------------------------------------
+      INTEGER :: imday       ! Number of days in month.
+      INTEGER, DIMENSION(12) :: &
+         &       imonth_len  ! Length in days of the months of the current year
+      REAL(wp) :: zdayfrc    ! Fraction of day
+
+      !----------------------------------------------------------------------
+      ! Initial date initialization (year, month, day, hour, minute)
+      ! (This assumes that the initial date is for 00z))
+      !----------------------------------------------------------------------
       iyea =   ndate0 / 10000
       imon = ( ndate0 - iyea * 10000 ) / 100
@@ -1483,7 +1656,7 @@
       imin = 0
 
-      !!----------------------------------------------------------------------
-      !! Compute number of days + number of hours + min since initial time
-      !!----------------------------------------------------------------------
+      !----------------------------------------------------------------------
+      ! Compute number of days + number of hours + min since initial time
+      !----------------------------------------------------------------------
       iday = iday + ( nit000 -1 ) * rdt / rday
       zdayfrc = ( nit000 -1 ) * rdt / rday
@@ -1492,10 +1665,10 @@
       imin = int( (zdayfrc * 24 - ihou) * 60 )
 
-      !!-----------------------------------------------------------------------
-      !! Convert number of days (iday) into a real date
-      !!----------------------------------------------------------------------
+      !-----------------------------------------------------------------------
+      ! Convert number of days (iday) into a real date
+      !----------------------------------------------------------------------
 
       CALL calc_month_len( iyea, imonth_len )
-      
+
       DO WHILE ( iday > imonth_len(imon) )
          iday = iday - imonth_len(imon)
@@ -1508,7 +1681,7 @@
       END DO
 
-      !!----------------------------------------------------------------------
-      !! Convert it into YYYYMMDD.HHMMSS format.
-      !!----------------------------------------------------------------------
+      !----------------------------------------------------------------------
+      ! Convert it into YYYYMMDD.HHMMSS format.
+      !----------------------------------------------------------------------
       ddobsini = iyea * 10000_dp + imon * 100_dp + &
          &       iday + ihou * 0.01_dp + imin * 0.0001_dp
@@ -1520,10 +1693,10 @@
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE fin_date  ***
-      !!          
-      !! ** Purpose : Get final data in double precision YYYYMMDD.HHMMSS format
-      !!
-      !! ** Method  : Get final data in double precision YYYYMMDD.HHMMSS format
-      !!
-      !! ** Action  : Get final data in double precision YYYYMMDD.HHMMSS format
+      !!
+      !! ** Purpose : Get final date in double precision YYYYMMDD.HHMMSS format
+      !!
+      !! ** Method  : Get final date in double precision YYYYMMDD.HHMMSS format
+      !!
+      !! ** Action  : Get final date in double precision YYYYMMDD.HHMMSS format
       !!
       !! History :
@@ -1535,6 +1708,4 @@
       USE phycst, ONLY : &            ! Physical constants
          & rday
-!      USE daymod, ONLY : &            ! Time variables
-!         & nmonth_len                
       USE dom_oce, ONLY : &           ! Ocean space and time domain variables
          & rdt
@@ -1543,5 +1714,5 @@
 
       !! * Arguments
-      REAL(KIND=dp), INTENT(OUT) :: ddobsfin                   ! Final date in YYYYMMDD.HHMMSS
+      REAL(dp), INTENT(OUT) :: ddobsfin ! Final date in YYYYMMDD.HHMMSS
 
       !! * Local declarations
@@ -1551,9 +1722,9 @@
       INTEGER :: ihou
       INTEGER :: imin
-      INTEGER :: imday         ! Number of days in month.
-      REAL(KIND=wp) :: zdayfrc       ! Fraction of day
-         
-      INTEGER, DIMENSION(12) ::   imonth_len    !: length in days of the months of the current year
-            
+      INTEGER :: imday       ! Number of days in month.
+      INTEGER, DIMENSION(12) :: &
+         &       imonth_len  ! Length in days of the months of the current year
+      REAL(wp) :: zdayfrc    ! Fraction of day
+
       !-----------------------------------------------------------------------
       ! Initial date initialization (year, month, day, hour, minute)
@@ -1565,5 +1736,5 @@
       ihou = 0
       imin = 0
-      
+
       !-----------------------------------------------------------------------
       ! Compute number of days + number of hours + min since initial time
@@ -1580,5 +1751,5 @@
 
       CALL calc_month_len( iyea, imonth_len )
-      
+
       DO WHILE ( iday > imonth_len(imon) )
          iday = iday - imonth_len(imon)
@@ -1598,4 +1769,119 @@
 
     END SUBROUTINE fin_date
-    
+
+    SUBROUTINE obs_settypefiles( ntypes, jpmaxnfiles, ifiles, cobstypes, cfiles )
+
+       INTEGER, INTENT(IN) :: ntypes      ! Total number of obs types
+       INTEGER, INTENT(IN) :: jpmaxnfiles ! Maximum number of files allowed for each type
+       INTEGER, DIMENSION(ntypes), INTENT(OUT) :: &
+          &                   ifiles      ! Out number of files for each type
+       CHARACTER(len=8), DIMENSION(ntypes), INTENT(IN) :: &
+          &                   cobstypes   ! List of obs types
+       CHARACTER(len=128), DIMENSION(ntypes, jpmaxnfiles), INTENT(IN) :: &
+          &                   cfiles      ! List of files for all types
+
+       !Local variables
+       INTEGER :: jfile
+       INTEGER :: jtype
+
+       DO jtype = 1, ntypes
+
+          ifiles(jtype) = 0
+          DO jfile = 1, jpmaxnfiles
+             IF ( trim(cfiles(jtype,jfile)) /= '' ) &
+                       ifiles(jtype) = ifiles(jtype) + 1
+          END DO
+
+          IF ( ifiles(jtype) == 0 ) THEN
+               CALL ctl_stop( 'Logical for observation type '//TRIM(cobstypes(jtype))//   &
+                  &           ' set to true but no files available to read' )
+          ENDIF
+
+          IF(lwp) THEN    
+             WRITE(numout,*) '             '//cobstypes(jtype)//' input observation file names:'
+             DO jfile = 1, ifiles(jtype)
+                WRITE(numout,*) '                '//TRIM(cfiles(jtype,jfile))
+             END DO
+          ENDIF
+
+       END DO
+
+    END SUBROUTINE obs_settypefiles
+
+    SUBROUTINE obs_setinterpopts( ntypes, jtype, ctypein,             &
+               &                  n2dint_default, n2dint_type,        &
+               &                  ravglamscl_type, ravgphiscl_type,   &
+               &                  lfp_indegs_type, lavnight_type,     &
+               &                  n2dint, ravglamscl, ravgphiscl,     &
+               &                  lfpindegs, lavnight )
+
+       INTEGER, INTENT(IN)  :: ntypes             ! Total number of obs types
+       INTEGER, INTENT(IN)  :: jtype              ! Index of the current type of obs
+       INTEGER, INTENT(IN)  :: n2dint_default     ! Default option for interpolation type
+       INTEGER, INTENT(IN)  :: n2dint_type        ! Option for interpolation type
+       REAL(wp), INTENT(IN) :: &
+          &                    ravglamscl_type, & !E/W diameter of obs footprint for this type
+          &                    ravgphiscl_type    !N/S diameter of obs footprint for this type
+       LOGICAL, INTENT(IN)  :: lfp_indegs_type    !T=> footprint in degrees, F=> in metres
+       LOGICAL, INTENT(IN)  :: lavnight_type      !T=> obs represent night time average
+       CHARACTER(len=8), INTENT(IN) :: ctypein 
+
+       INTEGER, DIMENSION(ntypes), INTENT(INOUT) :: &
+          &                    n2dint 
+       REAL(wp), DIMENSION(ntypes), INTENT(INOUT) :: &
+          &                    ravglamscl, ravgphiscl
+       LOGICAL, DIMENSION(ntypes), INTENT(INOUT) :: &
+          &                    lfpindegs, lavnight
+
+       lavnight(jtype) = lavnight_type
+
+       IF ( (n2dint_type >= 0) .AND. (n2dint_type <= 6) ) THEN
+          n2dint(jtype) = n2dint_type
+       ELSE IF ( n2dint_type == -1 ) THEN
+          n2dint(jtype) = n2dint_default
+       ELSE
+          CALL ctl_stop(' Choice of '//TRIM(ctypein)//' horizontal (2D) interpolation method', &
+            &                    ' is not available')
+       ENDIF
+
+       ! For averaging observation footprints set options for size of footprint 
+       IF ( (n2dint(jtype) > 4) .AND. (n2dint(jtype) <= 6) ) THEN
+          IF ( ravglamscl_type > 0._wp ) THEN
+             ravglamscl(jtype) = ravglamscl_type
+          ELSE
+             CALL ctl_stop( 'Incorrect value set for averaging footprint '// &
+                            'scale (ravglamscl) for observation type '//TRIM(ctypein) )      
+          ENDIF
+
+          IF ( ravgphiscl_type > 0._wp ) THEN
+             ravgphiscl(jtype) = ravgphiscl_type
+          ELSE
+             CALL ctl_stop( 'Incorrect value set for averaging footprint '// &
+                            'scale (ravgphiscl) for observation type '//TRIM(ctypein) )      
+          ENDIF
+
+          lfpindegs(jtype) = lfp_indegs_type 
+
+       ENDIF
+
+       ! Write out info 
+       IF(lwp) THEN
+          IF ( n2dint(jtype) <= 4 ) THEN
+             WRITE(numout,*) '             '//TRIM(ctypein)// &
+                &            ' model counterparts will be interpolated horizontally'
+          ELSE IF ( n2dint(jtype) <= 6 ) THEN
+             WRITE(numout,*) '             '//TRIM(ctypein)// &
+                &            ' model counterparts will be averaged horizontally'
+             WRITE(numout,*) '             '//'    with E/W scale: ',ravglamscl(jtype)
+             WRITE(numout,*) '             '//'    with N/S scale: ',ravgphiscl(jtype)
+             IF ( lfpindegs(jtype) ) THEN
+                 WRITE(numout,*) '             '//'    (in degrees)'
+             ELSE
+                 WRITE(numout,*) '             '//'    (in metres)'
+             ENDIF
+          ENDIF
+       ENDIF
+
+    END SUBROUTINE obs_setinterpopts
+
 END MODULE diaobs
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_averg_h2d.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_averg_h2d.F90	(revision 10247)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_averg_h2d.F90	(revision 10247)
@@ -0,0 +1,54 @@
+MODULE obs_averg_h2d
+   !!======================================================================
+   !!                       ***  MODULE obs_averg_h2d   ***
+   !! Observation diagnostics: Perform the horizontal averaging
+   !!                          from model grid to observation footprint
+   !!=====================================================================
+
+   !!----------------------------------------------------------------------
+   !!   obs_averg_h2d     : Horizontal averaging to the observation footprint
+   !!----------------------------------------------------------------------
+   !! * Modules used
+   USE par_kind, ONLY : &  ! Precision variables
+      & wp
+   USE phycst,   ONLY : &  ! Physical constants
+      & rad,  &
+      & ra,   &
+      & rpi
+   USE dom_oce,   ONLY : &
+      & jpi, jpj, &
+      & e1t, e2t, &
+      & e1f, e2f, &
+      & glamt, gphit, &
+      & nproc
+   USE in_out_manager
+   USE obs_const, ONLY : &
+      & obfillflt		! Fillvalue
+   USE obs_utils           ! Utility functions
+   USE lib_mpp,   ONLY : &
+      & ctl_warn, ctl_stop, &
+      & mpp_min, lk_mpp
+
+   IMPLICIT NONE
+
+   !! * Routine accessibility
+   PRIVATE obs_avg_h2d_rad, & ! Horizontal averaging using a radial footprint
+      &    obs_avg_h2d_rec, & ! Horizontal averaging using a rectangular footprint
+      &    obs_deg2dist,    & ! Conversion of distance in degrees to distance in metres
+      &    obs_dist2corners   ! Distance from the centre of obs footprint to the corners of a grid box
+   
+   PUBLIC obs_avg_h2d,      & ! Horizontal averaging to the observation footprint
+      &   obs_avg_h2d_init, & ! Set up weights for the averaging
+      &   obs_max_fpsize      ! Works out the maximum number of grid points required for the averaging
+
+   !!----------------------------------------------------------------------
+   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
+   !! $Id$
+   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
+   !!----------------------------------------------------------------------
+
+CONTAINS
+ 
+#include "obsaverg_h2d.h90"
+
+END MODULE obs_averg_h2d
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grd_bruteforce.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grd_bruteforce.h90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grd_bruteforce.h90	(revision 10247)
@@ -325,5 +325,5 @@
          CALL obs_mpp_max_integer( kobsj, kobs )
       ELSE
-         CALL obs_mpp_find_obs_proc( kproc, kobsi, kobsj, kobs )
+         CALL obs_mpp_find_obs_proc( kproc,kobs )
       ENDIF
 
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grid.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grid.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_grid.F90	(revision 10247)
@@ -52,5 +52,5 @@
 
    !! Default values
-   REAL, PUBLIC :: grid_search_res = 0.5    ! Resolution of grid
+   REAL, PUBLIC :: rn_gridsearchres = 0.5   ! Resolution of grid
    INTEGER, PRIVATE :: gsearch_nlons_def    ! Num of longitudes
    INTEGER, PRIVATE :: gsearch_nlats_def    ! Num of latitudes
@@ -83,5 +83,5 @@
    LOGICAL, PUBLIC :: ln_grid_global         ! Use global distribution of observations
    CHARACTER(LEN=44), PUBLIC :: &
-      & grid_search_file    ! file name head for grid search lookup 
+      & cn_gridsearchfile    ! file name head for grid search lookup 
 
    !!----------------------------------------------------------------------
@@ -613,5 +613,5 @@
          CALL obs_mpp_max_integer( kobsj, kobs )
       ELSE
-         CALL obs_mpp_find_obs_proc( kproc, kobsi, kobsj, kobs )
+         CALL obs_mpp_find_obs_proc( kproc, kobs )
       ENDIF
 
@@ -690,12 +690,12 @@
          
          IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*)'Grid search resolution : ', grid_search_res
-         
-         gsearch_nlons_def  = NINT( 360.0_wp / grid_search_res ) 
-         gsearch_nlats_def  = NINT( 180.0_wp / grid_search_res )
-         gsearch_lonmin_def = -180.0_wp + 0.5_wp * grid_search_res
-         gsearch_latmin_def =  -90.0_wp + 0.5_wp * grid_search_res
-         gsearch_dlon_def   = grid_search_res
-         gsearch_dlat_def   = grid_search_res
+         IF(lwp) WRITE(numout,*)'Grid search resolution : ', rn_gridsearchres
+         
+         gsearch_nlons_def  = NINT( 360.0_wp / rn_gridsearchres ) 
+         gsearch_nlats_def  = NINT( 180.0_wp / rn_gridsearchres )
+         gsearch_lonmin_def = -180.0_wp + 0.5_wp * rn_gridsearchres
+         gsearch_latmin_def =  -90.0_wp + 0.5_wp * rn_gridsearchres
+         gsearch_dlon_def   = rn_gridsearchres
+         gsearch_dlat_def   = rn_gridsearchres
          
          IF (lwp) THEN
@@ -710,8 +710,8 @@
          IF ( ln_grid_global ) THEN
             WRITE(cfname, FMT="(A,'_',A)") &
-               &          TRIM(grid_search_file), 'global.nc'
+               &          TRIM(cn_gridsearchfile), 'global.nc'
          ELSE
             WRITE(cfname, FMT="(A,'_',I4.4,'of',I4.4,'by',I4.4,'.nc')") &
-               &          TRIM(grid_search_file), nproc, jpni, jpnj
+               &          TRIM(cn_gridsearchfile), nproc, jpni, jpnj
          ENDIF
 
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_inter_sup.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_inter_sup.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_inter_sup.F90	(revision 10247)
@@ -35,5 +35,5 @@
 CONTAINS
 
-   SUBROUTINE obs_int_comm_3d( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
+   SUBROUTINE obs_int_comm_3d( kptsi, kptsj, kobs, kpi, kpj, kpk, kgrdi, kgrdj, &
       &                        pval, pgval, kproc )
       !!----------------------------------------------------------------------
@@ -57,4 +57,6 @@
       INTEGER, INTENT(IN) :: kptsj     ! Number of j horizontal points per stencil
       INTEGER, INTENT(IN) :: kobs      ! Local number of observations
+      INTEGER, INTENT(IN) :: kpi       ! Number of points in i direction
+      INTEGER, INTENT(IN) :: kpj       ! Number of points in j direction
       INTEGER, INTENT(IN) :: kpk       ! Number of levels
       INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
@@ -63,5 +65,5 @@
       INTEGER, OPTIONAL, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
          & kproc            ! Precomputed processor for each i,j,iobs points
-      REAL(KIND=wp), DIMENSION(jpi,jpj,kpk), INTENT(IN) ::&
+      REAL(KIND=wp), DIMENSION(kpi,kpj,kpk), INTENT(IN) ::&
          & pval             ! Local 3D array to extract data from
       REAL(KIND=wp), DIMENSION(kptsi,kptsj,kpk,kobs), INTENT(OUT) ::&
@@ -73,10 +75,10 @@
          IF (PRESENT(kproc)) THEN
 
-            CALL obs_int_comm_3d_global( kptsi, kptsj, kobs, kpk, kgrdi, &
+            CALL obs_int_comm_3d_global( kptsi, kptsj, kobs, kpi, kpj, kpk, kgrdi, &
                &                         kgrdj, pval, pgval, kproc=kproc )
 
          ELSE
 
-            CALL obs_int_comm_3d_global( kptsi, kptsj, kobs, kpk, kgrdi, &
+            CALL obs_int_comm_3d_global( kptsi, kptsj, kobs, kpi, kpj, kpk, kgrdi, &
                &                         kgrdj, pval, pgval )
 
@@ -85,5 +87,5 @@
       ELSE
 
-         CALL obs_int_comm_3d_local( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
+         CALL obs_int_comm_3d_local( kptsi, kptsj, kobs, kpi, kpj, kpk, kgrdi, kgrdj, &
             &                        pval, pgval )
 
@@ -92,5 +94,5 @@
    END SUBROUTINE obs_int_comm_3d
 
-   SUBROUTINE obs_int_comm_2d( kptsi, kptsj, kobs, kgrdi, kgrdj, pval, pgval, &
+   SUBROUTINE obs_int_comm_2d( kptsi, kptsj, kobs, kpi, kpj, kgrdi, kgrdj, pval, pgval, &
       &                        kproc )
       !!----------------------------------------------------------------------
@@ -111,4 +113,6 @@
       INTEGER, INTENT(IN) :: kptsj        ! Number of j horizontal points per stencil
       INTEGER, INTENT(IN) :: kobs          ! Local number of observations
+      INTEGER, INTENT(IN) :: kpi          ! Number of model grid points in i direction
+      INTEGER, INTENT(IN) :: kpj          ! Number of model grid points in j direction
       INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
          & kgrdi, &         ! i,j indicies for each stencil
@@ -116,5 +120,5 @@
       INTEGER, OPTIONAL, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
          & kproc            ! Precomputed processor for each i,j,iobs points
-      REAL(KIND=wp), DIMENSION(jpi,jpj), INTENT(IN) ::&
+      REAL(KIND=wp), DIMENSION(kpi,kpj), INTENT(IN) ::&
          & pval             ! Local 3D array to extra data from
       REAL(KIND=wp), DIMENSION(kptsi,kptsj,kobs), INTENT(OUT) ::&
@@ -136,9 +140,9 @@
       IF (PRESENT(kproc)) THEN
 
-         CALL obs_int_comm_3d( kptsi, kptsj, kobs, 1, kgrdi, kgrdj, zval, &
+         CALL obs_int_comm_3d( kptsi, kptsj, kobs, kpi, kpj, 1, kgrdi, kgrdj, zval, &
             &                  zgval, kproc=kproc )
       ELSE
 
-         CALL obs_int_comm_3d( kptsi, kptsj, kobs, 1, kgrdi, kgrdj, zval, &
+         CALL obs_int_comm_3d( kptsi, kptsj, kobs, kpi, kpj, 1, kgrdi, kgrdj, zval, &
             &                  zgval )
 
@@ -154,5 +158,5 @@
    END SUBROUTINE obs_int_comm_2d
 
-   SUBROUTINE obs_int_comm_3d_global( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
+   SUBROUTINE obs_int_comm_3d_global( kptsi, kptsj, kobs, kpi, kpj, kpk, kgrdi, kgrdj, &
       &                               pval, pgval, kproc )
       !!----------------------------------------------------------------------
@@ -174,4 +178,6 @@
       INTEGER, INTENT(IN) :: kptsj     ! Number of j horizontal points per stencil
       INTEGER, INTENT(IN) :: kobs      ! Local number of observations
+      INTEGER, INTENT(IN) :: kpi       ! Number of model points in i direction
+      INTEGER, INTENT(IN) :: kpj       ! Number of model points in j direction
       INTEGER, INTENT(IN) :: kpk       ! Number of levels
       INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
@@ -180,5 +186,5 @@
       INTEGER, OPTIONAL, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
          & kproc            ! Precomputed processor for each i,j,iobs points
-      REAL(KIND=wp), DIMENSION(jpi,jpj,kpk), INTENT(IN) ::&
+      REAL(KIND=wp), DIMENSION(kpi,kpj,kpk), INTENT(IN) ::&
          & pval             ! Local 3D array to extract data from
       REAL(KIND=wp), DIMENSION(kptsi,kptsj,kpk,kobs), INTENT(OUT) ::&
@@ -207,11 +213,11 @@
 
       ! Check valid points
-      
+
       IF ( ( MAXVAL(kgrdi) > jpiglo ) .OR. ( MINVAL(kgrdi) < 1 ) .OR. &
          & ( MAXVAL(kgrdj) > jpjglo ) .OR. ( MINVAL(kgrdj) < 1 ) ) THEN
-         
+
          CALL ctl_stop( 'Error in obs_int_comm_3d_global', &
             &           'Point outside global domain' )
-         
+
       ENDIF
 
@@ -323,5 +329,5 @@
    END SUBROUTINE obs_int_comm_3d_global
    
-   SUBROUTINE obs_int_comm_3d_local( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
+   SUBROUTINE obs_int_comm_3d_local( kptsi, kptsj, kobs, kpi, kpj, kpk, kgrdi, kgrdj, &
       &                              pval, pgval )
       !!----------------------------------------------------------------------
@@ -343,9 +349,11 @@
       INTEGER, INTENT(IN) :: kptsj        ! Number of j horizontal points per stencil
       INTEGER, INTENT(IN) :: kobs         ! Local number of observations
+      INTEGER, INTENT(IN) :: kpi          ! Number of model points in i direction
+      INTEGER, INTENT(IN) :: kpj          ! Number of model points in j direction
       INTEGER, INTENT(IN) :: kpk          ! Number of levels
       INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
          & kgrdi, &         ! i,j indicies for each stencil
          & kgrdj
-      REAL(KIND=wp), DIMENSION(jpi,jpj,kpk), INTENT(IN) ::&
+      REAL(KIND=wp), DIMENSION(kpi,kpj,kpk), INTENT(IN) ::&
          & pval             ! Local 3D array to extract data from
       REAL(KIND=wp), DIMENSION(kptsi,kptsj,kpk,kobs), INTENT(OUT) ::&
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_mpp.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_mpp.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_mpp.F90	(revision 10247)
@@ -7,4 +7,6 @@
    !!             -   ! 2006-05  (K. Mogensen)  Reformatted
    !!             -   ! 2008-01  (K. Mogensen)  add mpp_global_max
+   !!            3.6  ! 2015-01  (J. Waters) obs_mpp_find_obs_proc 
+   !!                            rewritten to avoid global arrays
    !!----------------------------------------------------------------------
 #  define mpivar mpi_double_precision
@@ -12,5 +14,5 @@
    !! obs_mpp_bcast_integer : Broadcast an integer array from a processor to all processors
    !! obs_mpp_max_integer   : Find maximum on all processors of each value in an integer on all processors
-   !! obs_mpp_find_obs_proc : Find processors which should hold the observations
+   !! obs_mpp_find_obs_proc : Find processors which should hold the observations, avoiding global arrays
    !! obs_mpp_sum_integers  : Sum an integer array from all processors
    !! obs_mpp_sum_integer   : Sum an integer from all processors
@@ -96,8 +98,10 @@
       !
       INTEGER :: ierr 
-      INTEGER, DIMENSION(kno) ::   ivals
-      !
-INCLUDE 'mpif.h'
-      !!----------------------------------------------------------------------
+      INTEGER, DIMENSION(:), ALLOCATABLE ::   ivals
+      !
+INCLUDE 'mpif.h'
+      !!----------------------------------------------------------------------
+
+      ALLOCATE( ivals(kno) )
 
       ! Call the MPI library to find the maximum across processors
@@ -105,4 +109,6 @@
          &                mpi_max, mpi_comm_opa, ierr )
       kvals(:) = ivals(:)
+
+      DEALLOCATE( ivals )
 #else
       ! no MPI: empty routine
@@ -111,18 +117,18 @@
 
 
-   SUBROUTINE obs_mpp_find_obs_proc( kobsp, kobsi, kobsj, kno )
-      !!----------------------------------------------------------------------
-      !!               ***  ROUTINE obs_mpp_find_obs_proc ***
-      !!          
-      !! ** Purpose : From the array kobsp containing the results of the grid
+   SUBROUTINE obs_mpp_find_obs_proc( kobsp,kno )
+      !!----------------------------------------------------------------------
+      !!               ***  ROUTINE obs_mpp_find_obs_proc  ***
+      !!         
+      !! ** Purpose : From the array kobsp containing the results of the
       !!              grid search on each processor the processor return a
       !!              decision of which processors should hold the observation.
       !!
-      !! ** Method  : A temporary 2D array holding all the decisions is
-      !!              constructed using mpi_allgather on each processor.
-      !!              If more than one processor has found the observation
-      !!              with the observation in the inner domain gets it
-      !!
-      !! ** Action  : This does only work for MPI. 
+      !! ** Method  : Synchronize the processor number for each obs using
+      !!              obs_mpp_max_integer. If an observation exists on two 
+      !!              processors it will be allocated to the lower numbered
+      !!              processor.
+      !!
+      !! ** Action  : This does only work for MPI.
       !!              It does not work for SHMEM.
       !!
@@ -130,99 +136,48 @@
       !!----------------------------------------------------------------------
       INTEGER                , INTENT(in   ) ::   kno
-      INTEGER, DIMENSION(kno), INTENT(in   ) ::   kobsi, kobsj
       INTEGER, DIMENSION(kno), INTENT(inout) ::   kobsp
       !
 #if defined key_mpp_mpi
       !
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: size
-      INTEGER :: ierr
-      INTEGER :: iobsip
-      INTEGER :: iobsjp
-      INTEGER :: num_sus_obs
-      INTEGER, DIMENSION(kno) ::   iobsig, iobsjg
-      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iobsp, iobsi, iobsj
-      !!
-INCLUDE 'mpif.h'
-      !!----------------------------------------------------------------------
-
-      !-----------------------------------------------------------------------
-      ! Call the MPI library to find the maximum accross processors
-      !-----------------------------------------------------------------------
-      CALL mpi_comm_size( mpi_comm_opa, size, ierr )
-      !-----------------------------------------------------------------------
-      ! Convert local grids points to global grid points
-      !-----------------------------------------------------------------------
+      !
+      INTEGER :: ji, isum
+      INTEGER, DIMENSION(:), ALLOCATABLE ::   iobsp
+      !!
+      !!
+
+      ALLOCATE( iobsp(kno) )
+
+      iobsp(:)=kobsp(:)
+
+      WHERE( iobsp(:) == -1 )
+         iobsp(:) = 9999999
+      END WHERE
+
+      iobsp(:)=-1*iobsp(:)
+
+      CALL obs_mpp_max_integer( iobsp, kno )
+
+      kobsp(:)=-1*iobsp(:)
+
+      isum=0
       DO ji = 1, kno
-         IF ( ( kobsi(ji) >= 1 ) .AND. ( kobsi(ji) <= jpi ) .AND. &
-            & ( kobsj(ji) >= 1 ) .AND. ( kobsj(ji) <= jpj ) ) THEN
-            iobsig(ji) = mig( kobsi(ji) )
-            iobsjg(ji) = mjg( kobsj(ji) )
-         ELSE
-            iobsig(ji) = -1
-            iobsjg(ji) = -1
+         IF ( kobsp(ji) == 9999999 ) THEN
+            isum=isum+1
+            kobsp(ji)=-1
          ENDIF
-      END DO
-      !-----------------------------------------------------------------------
-      ! Get the decisions from all processors
-      !-----------------------------------------------------------------------
-      ALLOCATE( iobsp(kno,size) )
-      ALLOCATE( iobsi(kno,size) )
-      ALLOCATE( iobsj(kno,size) )
-      CALL mpi_allgather( kobsp, kno, mpi_integer, &
-         &                iobsp, kno, mpi_integer, &
-         &                mpi_comm_opa, ierr )
-      CALL mpi_allgather( iobsig, kno, mpi_integer, &
-         &                iobsi, kno, mpi_integer, &
-         &                mpi_comm_opa, ierr )
-      CALL mpi_allgather( iobsjg, kno, mpi_integer, &
-         &                iobsj, kno, mpi_integer, &
-         &                mpi_comm_opa, ierr )
-
-      !-----------------------------------------------------------------------
-      ! Find the processor with observations from the lowest processor 
-      ! number among processors holding the observation.
-      !-----------------------------------------------------------------------
-      kobsp(:) = -1
-      num_sus_obs = 0
-      DO ji = 1, kno
-         DO jj = 1, size
-            IF ( ( kobsp(ji) == -1 ) .AND. ( iobsp(ji,jj) /= -1 ) ) THEN
-               kobsp(ji) = iobsp(ji,jj)
-               iobsip = iobsi(ji,jj)
-               iobsjp = iobsj(ji,jj)
-            ENDIF
-            IF ( ( kobsp(ji) /= -1 ) .AND. ( iobsp(ji,jj) /= -1 ) ) THEN
-               IF ( ( iobsip /= iobsi(ji,jj) ) .OR. &
-                  & ( iobsjp /= iobsj(ji,jj) ) ) THEN
-                  IF ( ( kobsp(ji) < 1000000 ) .AND. &
-                     & ( iobsp(ji,jj) < 1000000 ) ) THEN
-                     num_sus_obs=num_sus_obs+1
-                  ENDIF
-               ENDIF
-               IF ( mppmap(iobsip,iobsjp) /= ( kobsp(ji)+1 ) ) THEN
-                  IF ( ( iobsi(ji,jj) /= -1 ) .AND. &
-                     & ( iobsj(ji,jj) /= -1 ) ) THEN
-                     IF ((mppmap(iobsi(ji,jj),iobsj(ji,jj)) == (iobsp(ji,jj)+1))&
-                        & .OR. ( iobsp(ji,jj) < kobsp(ji) ) ) THEN
-                        kobsp(ji) = iobsp(ji,jj)
-                        iobsip = iobsi(ji,jj)
-                        iobsjp = iobsj(ji,jj)
-                     ENDIF
-                  ENDIF
-               ENDIF
-            ENDIF
-         END DO
-      END DO
-      IF (lwp) WRITE(numout,*) 'Number of suspicious observations: ',num_sus_obs
-
-      DEALLOCATE( iobsj )
-      DEALLOCATE( iobsi )
+      ENDDO
+
+
+      IF ( isum > 0 ) THEN
+         IF (lwp) WRITE(numout,*) isum, ' observations failed the grid search.'
+         IF (lwp) WRITE(numout,*)'If ln_grid_search_lookup=.TRUE., try reducing grid_search_res'
+      ENDIF
+
       DEALLOCATE( iobsp )
+
 #else
       ! no MPI: empty routine
-#endif
-      !
+#endif     
+      
    END SUBROUTINE obs_mpp_find_obs_proc
 
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_oper.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_oper.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_oper.F90	(revision 10247)
@@ -7,37 +7,34 @@
 
    !!----------------------------------------------------------------------
-   !!   obs_pro_opt :    Compute the model counterpart of temperature and
-   !!                    salinity observations from profiles
-   !!   obs_sla_opt :    Compute the model counterpart of sea level anomaly
-   !!                    observations
-   !!   obs_sst_opt :    Compute the model counterpart of sea surface temperature
-   !!                    observations
-   !!   obs_sss_opt :    Compute the model counterpart of sea surface salinity
-   !!                    observations
-   !!   obs_seaice_opt : Compute the model counterpart of sea ice concentration
-   !!                    observations
-   !!
-   !!   obs_vel_opt :    Compute the model counterpart of zonal and meridional
-   !!                    components of velocity from observations.
+   !!   obs_prof_opt :    Compute the model counterpart of profile data
+   !!   obs_surf_opt :    Compute the model counterpart of surface data
    !!----------------------------------------------------------------------
 
-   !! * Modules used   
+   !! * Modules used
    USE par_kind, ONLY : &         ! Precision variables
       & wp
    USE in_out_manager             ! I/O manager
    USE obs_inter_sup              ! Interpolation support
-   USE obs_inter_h2d, ONLY : &    ! Horizontal interpolation to the observation pt
+   USE obs_inter_h2d, ONLY : &    ! Horizontal interpolation to the obs pt
       & obs_int_h2d, &
       & obs_int_h2d_init
-   USE obs_inter_z1d, ONLY : &    ! Vertical interpolation to the observation pt
+   USE obs_averg_h2d, ONLY : &    ! Horizontal averaging to the obs footprint
+      & obs_avg_h2d, &
+      & obs_avg_h2d_init, &
+      & obs_max_fpsize
+   USE obs_inter_z1d, ONLY : &    ! Vertical interpolation to the obs pt
       & obs_int_z1d,    &
       & obs_int_z1d_spl
-   USE obs_const,  ONLY :     &
-      & obfillflt		  ! Fillvalue   
+   USE obs_const,  ONLY :    &    ! Obs fill value
+      & obfillflt
    USE dom_oce,       ONLY : &
-      & glamt, glamu, glamv, &
-      & gphit, gphiu, gphiv
-   USE lib_mpp,       ONLY : &
+      & glamt, glamf, &
+      & gphit, gphif
+   USE lib_mpp,       ONLY : &    ! Warning and stopping routines
       & ctl_warn, ctl_stop
+   USE sbcdcy,        ONLY : &    ! For calculation of where it is night-time
+      & sbc_dcy, nday_qsr
+   USE obs_grid,      ONLY : & 
+      & obs_level_search     
 
    IMPLICIT NONE
@@ -46,12 +43,9 @@
    PRIVATE
 
-   PUBLIC obs_pro_opt, &  ! Compute the model counterpart of profile observations
-      &   obs_sla_opt, &  ! Compute the model counterpart of SLA observations
-      &   obs_sst_opt, &  ! Compute the model counterpart of SST observations
-      &   obs_sss_opt, &  ! Compute the model counterpart of SSS observations
-      &   obs_seaice_opt, &
-      &   obs_vel_opt     ! Compute the model counterpart of velocity profile data
-
-   INTEGER, PARAMETER, PUBLIC :: imaxavtypes = 20 ! Max number of daily avgd obs types
+   PUBLIC obs_prof_opt, &  ! Compute the model counterpart of profile obs
+      &   obs_surf_opt     ! Compute the model counterpart of surface obs
+
+   INTEGER, PARAMETER, PUBLIC :: &
+      & imaxavtypes = 20   ! Max number of daily avgd obs types
 
    !!----------------------------------------------------------------------
@@ -61,9 +55,16 @@
    !!----------------------------------------------------------------------
 
+   !! * Substitutions 
+#  include "domzgr_substitute.h90" 
 CONTAINS
 
-   SUBROUTINE obs_pro_opt( prodatqc, kt, kpi, kpj, kpk, kit000, kdaystp, &
-      &                    ptn, psn, pgdept, ptmask, k1dint, k2dint, &
-      &                    kdailyavtypes )
+
+   SUBROUTINE obs_prof_opt( prodatqc, kt, kpi, kpj, kpk, &
+      &                     kit000, kdaystp, kvar,       &
+      &                     pvar, pgdept, pgdepw,        &
+      &                     pmask,                       &  
+      &                     plam, pphi,                  &
+      &                     k1dint, k2dint, kdailyavtypes )
+
       !!-----------------------------------------------------------------------
       !!
@@ -78,5 +79,5 @@
       !!
       !!    First, a vertical profile of horizontally interpolated model
-      !!    now temperatures is computed at the obs (lon, lat) point.
+      !!    now values is computed at the obs (lon, lat) point.
       !!    Several horizontal interpolation schemes are available:
       !!        - distance-weighted (great circle) (k2dint = 0)
@@ -86,5 +87,5 @@
       !!        - polynomial (quadrilateral grid)  (k2dint = 4)
       !!
-      !!    Next, the vertical temperature profile is interpolated to the
+      !!    Next, the vertical profile is interpolated to the
       !!    data depth points. Two vertical interpolation schemes are
       !!    available:
@@ -96,14 +97,11 @@
       !!    routine.
       !!
-      !!    For ENACT moored buoy data (e.g., TAO), the model equivalent is
+      !!    If the logical is switched on, the model equivalent is
       !!    a daily mean model temperature field. So, we first compute
       !!    the mean, then interpolate only at the end of the day.
       !!
-      !!    Note: the in situ temperature observations must be converted
+      !!    Note: in situ temperature observations must be converted
       !!    to potential temperature (the model variable) prior to
       !!    assimilation. 
-      !!??????????????????????????????????????????????????????????????
-      !!    INCLUDE POTENTIAL TEMP -> IN SITU TEMP IN OBS OPERATOR???
-      !!??????????????????????????????????????????????????????????????
       !!
       !! ** Action  :
@@ -115,6 +113,8 @@
       !!      ! 07-01 (K. Mogensen) Merge of temperature and salinity
       !!      ! 07-03 (K. Mogensen) General handling of profiles
+      !!      ! 15-02 (M. Martin) Combined routine for all profile types
+      !!      ! 17-02 (M. Martin) Include generalised vertical coordinate changes
       !!-----------------------------------------------------------------------
-  
+
       !! * Modules used
       USE obs_profiles_def ! Definition of storage space for profile obs.
@@ -123,22 +123,28 @@
 
       !! * Arguments
-      TYPE(obs_prof), INTENT(INOUT) :: prodatqc  ! Subset of profile data not failing screening
-      INTEGER, INTENT(IN) :: kt        ! Time step
-      INTEGER, INTENT(IN) :: kpi       ! Model grid parameters
+      TYPE(obs_prof), INTENT(INOUT) :: &
+         & prodatqc                  ! Subset of profile data passing QC
+      INTEGER, INTENT(IN) :: kt      ! Time step
+      INTEGER, INTENT(IN) :: kpi     ! Model grid parameters
       INTEGER, INTENT(IN) :: kpj
       INTEGER, INTENT(IN) :: kpk
-      INTEGER, INTENT(IN) :: kit000    ! Number of the first time step 
-                                       !   (kit000-1 = restart time)
-      INTEGER, INTENT(IN) :: k1dint    ! Vertical interpolation type (see header)
-      INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header)
-      INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day                    
+      INTEGER, INTENT(IN) :: kit000  ! Number of the first time step
+                                     !   (kit000-1 = restart time)
+      INTEGER, INTENT(IN) :: k1dint  ! Vertical interpolation type (see header)
+      INTEGER, INTENT(IN) :: k2dint  ! Horizontal interpolation type (see header)
+      INTEGER, INTENT(IN) :: kdaystp ! Number of time steps per day
+      INTEGER, INTENT(IN) :: kvar    ! Number of variable in prodatqc
       REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj,kpk) :: &
-         & ptn,    &    ! Model temperature field
-         & psn,    &    ! Model salinity field
-         & ptmask       ! Land-sea mask
-      REAL(KIND=wp), INTENT(IN), DIMENSION(kpk) :: &
-         & pgdept       ! Model array of depth levels
+         & pvar,   &                 ! Model field for variable
+         & pmask                     ! Land-sea mask for variable
+      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: &
+         & plam,   &                 ! Model longitudes for variable
+         & pphi                      ! Model latitudes for variable
+      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj,kpk) :: & 
+         & pgdept, &                 ! Model array of depth T levels 
+         & pgdepw                    ! Model array of depth W levels 
       INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: &
-         & kdailyavtypes! Types for daily averages
+         & kdailyavtypes             ! Types for daily averages
+
       !! * Local declarations
       INTEGER ::   ji
@@ -152,130 +158,147 @@
       INTEGER ::   iend
       INTEGER ::   iobs
+      INTEGER ::   iin, ijn, ikn, ik   ! looping indices over interpolation nodes 
+      INTEGER ::   inum_obs
       INTEGER, DIMENSION(imaxavtypes) :: &
          & idailyavtypes
+      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
+         & igrdi, &
+         & igrdj
+      INTEGER, ALLOCATABLE, DIMENSION(:) :: iv_indic
+
       REAL(KIND=wp) :: zlam
       REAL(KIND=wp) :: zphi
       REAL(KIND=wp) :: zdaystp
       REAL(KIND=wp), DIMENSION(kpk) :: &
-         & zobsmask, &
          & zobsk,    &
          & zobs2k
-      REAL(KIND=wp), DIMENSION(2,2,kpk) :: &
+      REAL(KIND=wp), DIMENSION(2,2,1) :: &
+         & zweig1, &
          & zweig
       REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE :: &
-         & zmask, &
-         & zintt, &
-         & zints, &
-         & zinmt, &
-         & zinms
+         & zmask,  &
+         & zint,   &
+         & zinm,   &
+         & zgdept, & 
+         & zgdepw
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
-         & zglam, &
+         & zglam,  &
          & zgphi
-      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
-         & igrdi, &
-         & igrdj
+      REAL(KIND=wp), DIMENSION(1) :: zmsk
+      REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: interp_corner
+
+      LOGICAL :: ld_dailyav
 
       !------------------------------------------------------------------------
       ! Local initialization 
       !------------------------------------------------------------------------
-      ! ... Record and data counters
+      ! Record and data counters
       inrc = kt - kit000 + 2
       ipro = prodatqc%npstp(inrc)
- 
+
       ! Daily average types
+      ld_dailyav = .FALSE.
       IF ( PRESENT(kdailyavtypes) ) THEN
          idailyavtypes(:) = kdailyavtypes(:)
+         IF ( ANY (idailyavtypes(:) /= -1) ) ld_dailyav = .TRUE.
       ELSE
          idailyavtypes(:) = -1
       ENDIF
 
-      ! Initialize daily mean for first timestep
+      ! Daily means are calculated for values over timesteps:
+      !  [1 <= kt <= kdaystp], [kdaystp+1 <= kt <= 2*kdaystp], ...
       idayend = MOD( kt - kit000 + 1, kdaystp )
 
-      ! Added kt == 0 test to catch restart case 
-      IF ( idayend == 1 .OR. kt == 0) THEN
-         IF (lwp) WRITE(numout,*) 'Reset prodatqc%vdmean on time-step: ',kt
+      IF ( ld_dailyav ) THEN
+
+         ! Initialize daily mean for first timestep of the day
+         IF ( idayend == 1 .OR. kt == 0 ) THEN
+            DO jk = 1, jpk
+               DO jj = 1, jpj
+                  DO ji = 1, jpi
+                     prodatqc%vdmean(ji,jj,jk,kvar) = 0.0
+                  END DO
+               END DO
+            END DO
+         ENDIF
+
          DO jk = 1, jpk
             DO jj = 1, jpj
                DO ji = 1, jpi
-                  prodatqc%vdmean(ji,jj,jk,1) = 0.0
-                  prodatqc%vdmean(ji,jj,jk,2) = 0.0
+                  ! Increment field for computing daily mean
+                  prodatqc%vdmean(ji,jj,jk,kvar) = prodatqc%vdmean(ji,jj,jk,kvar) &
+                     &                           + pvar(ji,jj,jk)
                END DO
             END DO
          END DO
-      ENDIF
-
-      DO jk = 1, jpk
-         DO jj = 1, jpj
-            DO ji = 1, jpi
-               ! Increment the temperature field for computing daily mean
-               prodatqc%vdmean(ji,jj,jk,1) = prodatqc%vdmean(ji,jj,jk,1) &
-                  &                        + ptn(ji,jj,jk)
-               ! Increment the salinity field for computing daily mean
-               prodatqc%vdmean(ji,jj,jk,2) = prodatqc%vdmean(ji,jj,jk,2) &
-                  &                        + psn(ji,jj,jk)
-            END DO
-         END DO
-      END DO
-   
-      ! Compute the daily mean at the end of day
-      zdaystp = 1.0 / REAL( kdaystp )
-      IF ( idayend == 0 ) THEN
-         DO jk = 1, jpk
-            DO jj = 1, jpj
-               DO ji = 1, jpi
-                  prodatqc%vdmean(ji,jj,jk,1) = prodatqc%vdmean(ji,jj,jk,1) &
-                     &                        * zdaystp
-                  prodatqc%vdmean(ji,jj,jk,2) = prodatqc%vdmean(ji,jj,jk,2) &
-                  &                           * zdaystp
+
+         ! Compute the daily mean at the end of day
+         zdaystp = 1.0 / REAL( kdaystp )
+         IF ( idayend == 0 ) THEN
+            IF (lwp) WRITE(numout,*) 'Calculating prodatqc%vdmean on time-step: ',kt
+            CALL FLUSH(numout)
+            DO jk = 1, jpk
+               DO jj = 1, jpj
+                  DO ji = 1, jpi
+                     prodatqc%vdmean(ji,jj,jk,kvar) = prodatqc%vdmean(ji,jj,jk,kvar) &
+                        &                           * zdaystp
+                  END DO
                END DO
             END DO
-         END DO
+         ENDIF
+
       ENDIF
 
       ! Get the data for interpolation
       ALLOCATE( &
-         & igrdi(2,2,ipro),      &
-         & igrdj(2,2,ipro),      &
-         & zglam(2,2,ipro),      &
-         & zgphi(2,2,ipro),      &
-         & zmask(2,2,kpk,ipro),  &
-         & zintt(2,2,kpk,ipro),  &
-         & zints(2,2,kpk,ipro)   &
+         & igrdi(2,2,ipro),       &
+         & igrdj(2,2,ipro),       &
+         & zglam(2,2,ipro),       &
+         & zgphi(2,2,ipro),       &
+         & zmask(2,2,kpk,ipro),   &
+         & zint(2,2,kpk,ipro),    &
+         & zgdept(2,2,kpk,ipro),  & 
+         & zgdepw(2,2,kpk,ipro)   & 
          & )
 
       DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro
          iobs = jobs - prodatqc%nprofup
-         igrdi(1,1,iobs) = prodatqc%mi(jobs,1)-1
-         igrdj(1,1,iobs) = prodatqc%mj(jobs,1)-1
-         igrdi(1,2,iobs) = prodatqc%mi(jobs,1)-1
-         igrdj(1,2,iobs) = prodatqc%mj(jobs,1)
-         igrdi(2,1,iobs) = prodatqc%mi(jobs,1)
-         igrdj(2,1,iobs) = prodatqc%mj(jobs,1)-1
-         igrdi(2,2,iobs) = prodatqc%mi(jobs,1)
-         igrdj(2,2,iobs) = prodatqc%mj(jobs,1)
+         igrdi(1,1,iobs) = prodatqc%mi(jobs,kvar)-1
+         igrdj(1,1,iobs) = prodatqc%mj(jobs,kvar)-1
+         igrdi(1,2,iobs) = prodatqc%mi(jobs,kvar)-1
+         igrdj(1,2,iobs) = prodatqc%mj(jobs,kvar)
+         igrdi(2,1,iobs) = prodatqc%mi(jobs,kvar)
+         igrdj(2,1,iobs) = prodatqc%mj(jobs,kvar)-1
+         igrdi(2,2,iobs) = prodatqc%mi(jobs,kvar)
+         igrdj(2,2,iobs) = prodatqc%mj(jobs,kvar)
       END DO
 
-      CALL obs_int_comm_2d( 2, 2, ipro, igrdi, igrdj, glamt, zglam )
-      CALL obs_int_comm_2d( 2, 2, ipro, igrdi, igrdj, gphit, zgphi )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, ptmask,zmask )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, ptn,   zintt )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, psn,   zints )
+      ! Initialise depth arrays
+      zgdept(:,:,:,:) = 0.0
+      zgdepw(:,:,:,:) = 0.0
+
+      CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi, igrdj, plam, zglam )
+      CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi, igrdj, pphi, zgphi )
+      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi, igrdj, pmask, zmask )
+      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi, igrdj, pvar,   zint )
+
+      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi, igrdj, pgdept, zgdept ) 
+      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi, igrdj, pgdepw, zgdepw ) 
 
       ! At the end of the day also get interpolated means
-      IF ( idayend == 0 ) THEN
-
-         ALLOCATE( &
-            & zinmt(2,2,kpk,ipro),  &
-            & zinms(2,2,kpk,ipro)   &
-            & )
-
-         CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, &
-            &                  prodatqc%vdmean(:,:,:,1), zinmt )
-         CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, &
-            &                  prodatqc%vdmean(:,:,:,2), zinms )
+      IF ( ld_dailyav .AND. idayend == 0 ) THEN
+
+         ALLOCATE( zinm(2,2,kpk,ipro) )
+
+         CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi, igrdj, &
+            &                  prodatqc%vdmean(:,:,:,kvar), zinm )
 
       ENDIF
 
+      ! Return if no observations to process 
+      ! Has to be done after comm commands to ensure processors 
+      ! stay in sync 
+      IF ( ipro == 0 ) RETURN 
+
       DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro
 
@@ -283,5 +306,5 @@
 
          IF ( kt /= prodatqc%mstp(jobs) ) THEN
-            
+
             IF(lwp) THEN
                WRITE(numout,*)
@@ -298,162 +321,179 @@
             CALL ctl_stop( 'obs_pro_opt', 'Inconsistent time' )
          ENDIF
-         
+
          zlam = prodatqc%rlam(jobs)
          zphi = prodatqc%rphi(jobs)
+
+         ! Horizontal weights 
+         ! Masked values are calculated later.  
+         IF ( prodatqc%npvend(jobs,kvar) > 0 ) THEN
+
+            CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,     &
+               &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
+               &                   zmask(:,:,1,iobs), zweig1, zmsk )
+
+         ENDIF
+
+         IF ( prodatqc%npvend(jobs,kvar) > 0 ) THEN
+
+            zobsk(:) = obfillflt
+
+            IF ( ANY (idailyavtypes(:) == prodatqc%ntyp(jobs)) ) THEN
+
+               IF ( idayend == 0 )  THEN
+                  ! Daily averaged data
+
+                  ! vertically interpolate all 4 corners 
+                  ista = prodatqc%npvsta(jobs,kvar) 
+                  iend = prodatqc%npvend(jobs,kvar) 
+                  inum_obs = iend - ista + 1 
+                  ALLOCATE(interp_corner(2,2,inum_obs),iv_indic(inum_obs)) 
+
+                  DO iin=1,2 
+                     DO ijn=1,2 
+
+                        IF ( k1dint == 1 ) THEN 
+                           CALL obs_int_z1d_spl( kpk, & 
+                              &     zinm(iin,ijn,:,iobs), & 
+                              &     zobs2k, zgdept(iin,ijn,:,iobs), & 
+                              &     zmask(iin,ijn,:,iobs)) 
+                        ENDIF 
+       
+                        CALL obs_level_search(kpk, & 
+                           &    zgdept(iin,ijn,:,iobs), & 
+                           &    inum_obs, prodatqc%var(kvar)%vdep(ista:iend), & 
+                           &    iv_indic) 
+
+                        CALL obs_int_z1d(kpk, iv_indic, k1dint, inum_obs, & 
+                           &    prodatqc%var(kvar)%vdep(ista:iend), & 
+                           &    zinm(iin,ijn,:,iobs), & 
+                           &    zobs2k, interp_corner(iin,ijn,:), & 
+                           &    zgdept(iin,ijn,:,iobs), & 
+                           &    zmask(iin,ijn,:,iobs)) 
+       
+                     ENDDO 
+                  ENDDO 
+
+               ENDIF !idayend
+
+            ELSE   
+
+               ! Point data 
+     
+               ! vertically interpolate all 4 corners 
+               ista = prodatqc%npvsta(jobs,kvar) 
+               iend = prodatqc%npvend(jobs,kvar) 
+               inum_obs = iend - ista + 1 
+               ALLOCATE(interp_corner(2,2,inum_obs), iv_indic(inum_obs)) 
+               DO iin=1,2  
+                  DO ijn=1,2 
+                    
+                     IF ( k1dint == 1 ) THEN 
+                        CALL obs_int_z1d_spl( kpk, & 
+                           &    zint(iin,ijn,:,iobs),& 
+                           &    zobs2k, zgdept(iin,ijn,:,iobs), & 
+                           &    zmask(iin,ijn,:,iobs)) 
+  
+                     ENDIF 
+       
+                     CALL obs_level_search(kpk, & 
+                         &        zgdept(iin,ijn,:,iobs),& 
+                         &        inum_obs, prodatqc%var(kvar)%vdep(ista:iend), & 
+                         &        iv_indic) 
+
+                     CALL obs_int_z1d(kpk, iv_indic, k1dint, inum_obs,     & 
+                         &          prodatqc%var(kvar)%vdep(ista:iend),     & 
+                         &          zint(iin,ijn,:,iobs),            & 
+                         &          zobs2k,interp_corner(iin,ijn,:), & 
+                         &          zgdept(iin,ijn,:,iobs),         & 
+                         &          zmask(iin,ijn,:,iobs) )      
          
-         ! Horizontal weights and vertical mask
-
-         IF ( ( prodatqc%npvend(jobs,1) > 0 ) .OR. &
-            & ( prodatqc%npvend(jobs,2) > 0 ) ) THEN
-
-            CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     &
-               &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
-               &                   zmask(:,:,:,iobs), zweig, zobsmask )
-
-         ENDIF
-
-         IF ( prodatqc%npvend(jobs,1) > 0 ) THEN
-
-            zobsk(:) = obfillflt
-
-	    IF ( ANY (idailyavtypes(:) == prodatqc%ntyp(jobs)) ) THEN
-
-               IF ( idayend == 0 )  THEN
+                  ENDDO 
+               ENDDO 
+             
+            ENDIF 
+
+            !------------------------------------------------------------- 
+            ! Compute the horizontal interpolation for every profile level 
+            !------------------------------------------------------------- 
+             
+            DO ikn=1,inum_obs 
+               iend=ista+ikn-1
                   
-                  ! Daily averaged moored buoy (MRB) data
-                  
-                  CALL obs_int_h2d( kpk, kpk,      &
-                     &              zweig, zinmt(:,:,:,iobs), zobsk )
-                  
-                  
-               ELSE
-               
-                  CALL ctl_stop( ' A nonzero' //     &
-                     &           ' number of profile T BUOY data should' // &
-                     &           ' only occur at the end of a given day' )
-
-               ENDIF
-	       
-            ELSE 
-               
-               ! Point data
-
-               CALL obs_int_h2d( kpk, kpk,      &
-                  &              zweig, zintt(:,:,:,iobs), zobsk )
-
-            ENDIF
-
-            !-------------------------------------------------------------
-            ! Compute vertical second-derivative of the interpolating 
-            ! polynomial at obs points
-            !-------------------------------------------------------------
-            
-            IF ( k1dint == 1 ) THEN
-               CALL obs_int_z1d_spl( kpk, zobsk, zobs2k,   &
-                  &                  pgdept, zobsmask )
-            ENDIF
-            
-            !-----------------------------------------------------------------
-            !  Vertical interpolation to the observation point
-            !-----------------------------------------------------------------
-            ista = prodatqc%npvsta(jobs,1)
-            iend = prodatqc%npvend(jobs,1)
-            CALL obs_int_z1d( kpk,                &
-               & prodatqc%var(1)%mvk(ista:iend),  &
-               & k1dint, iend - ista + 1,         &
-               & prodatqc%var(1)%vdep(ista:iend), &
-               & zobsk, zobs2k,                   &
-               & prodatqc%var(1)%vmod(ista:iend), &
-               & pgdept, zobsmask )
-
-         ENDIF
-
-         IF ( prodatqc%npvend(jobs,2) > 0 ) THEN
-
-            zobsk(:) = obfillflt
-
-            IF ( ANY (idailyavtypes(:) == prodatqc%ntyp(jobs)) ) THEN
-
-               IF ( idayend == 0 )  THEN
-
-                  ! Daily averaged moored buoy (MRB) data
-                  
-                  CALL obs_int_h2d( kpk, kpk,      &
-                     &              zweig, zinms(:,:,:,iobs), zobsk )
-                  
-               ELSE
-
-                  CALL ctl_stop( ' A nonzero' //     &
-                     &           ' number of profile S BUOY data should' // &
-                     &           ' only occur at the end of a given day' )
-
-               ENDIF
-
-            ELSE
-               
-               ! Point data
-
-               CALL obs_int_h2d( kpk, kpk,      &
-                  &              zweig, zints(:,:,:,iobs), zobsk )
-
-            ENDIF
-
-
-            !-------------------------------------------------------------
-            ! Compute vertical second-derivative of the interpolating 
-            ! polynomial at obs points
-            !-------------------------------------------------------------
-            
-            IF ( k1dint == 1 ) THEN
-               CALL obs_int_z1d_spl( kpk, zobsk, zobs2k, &
-                  &                  pgdept, zobsmask )
-            ENDIF
-            
-            !----------------------------------------------------------------
-            !  Vertical interpolation to the observation point
-            !----------------------------------------------------------------
-            ista = prodatqc%npvsta(jobs,2)
-            iend = prodatqc%npvend(jobs,2)
-            CALL obs_int_z1d( kpk, &
-               & prodatqc%var(2)%mvk(ista:iend),&
-               & k1dint, iend - ista + 1, &
-               & prodatqc%var(2)%vdep(ista:iend),&
-               & zobsk, zobs2k, &
-               & prodatqc%var(2)%vmod(ista:iend),&
-               & pgdept, zobsmask )
-
-         ENDIF
-
-      END DO
+               zweig(:,:,1) = 0._wp 
+   
+               ! This code forces the horizontal weights to be  
+               ! zero IF the observation is below the bottom of the  
+               ! corners of the interpolation nodes, Or if it is in  
+               ! the mask. This is important for observations near  
+               ! steep bathymetry 
+               DO iin=1,2 
+                  DO ijn=1,2 
+     
+                     depth_loop: DO ik=kpk,2,-1 
+                        IF(zmask(iin,ijn,ik-1,iobs ) > 0.9 )THEN   
+                            
+                           zweig(iin,ijn,1) = &  
+                              & zweig1(iin,ijn,1) * & 
+                              & MAX( SIGN(1._wp,(zgdepw(iin,ijn,ik,iobs) ) & 
+                              &  - prodatqc%var(kvar)%vdep(iend)),0._wp) 
+                            
+                           EXIT depth_loop
+
+                        ENDIF 
+
+                     ENDDO depth_loop
+     
+                  ENDDO 
+               ENDDO 
+   
+               CALL obs_int_h2d( 1, 1, zweig, interp_corner(:,:,ikn), & 
+                  &              prodatqc%var(kvar)%vmod(iend:iend) ) 
+
+                  ! Set QC flag for any observations found below the bottom
+                  ! needed as the check here is more strict than that in obs_prep
+               IF (sum(zweig) == 0.0_wp) prodatqc%var(kvar)%nvqc(iend:iend)=4
  
+            ENDDO 
+ 
+            DEALLOCATE(interp_corner,iv_indic) 
+          
+         ENDIF
+
+      ENDDO
+
       ! Deallocate the data for interpolation
-      DEALLOCATE( &
-         & igrdi, &
-         & igrdj, &
-         & zglam, &
-         & zgphi, &
-         & zmask, &
-         & zintt, &
-         & zints  &
+      DEALLOCATE(  &
+         & igrdi,  &
+         & igrdj,  &
+         & zglam,  &
+         & zgphi,  &
+         & zmask,  &
+         & zint,   &
+         & zgdept, &
+         & zgdepw  &
          & )
+
       ! At the end of the day also get interpolated means
-      IF ( idayend == 0 ) THEN
-         DEALLOCATE( &
-            & zinmt,  &
-            & zinms   &
-            & )
+      IF ( ld_dailyav .AND. idayend == 0 ) THEN
+         DEALLOCATE( zinm )
       ENDIF
 
-      prodatqc%nprofup = prodatqc%nprofup + ipro 
-      
-   END SUBROUTINE obs_pro_opt
-
-   SUBROUTINE obs_sla_opt( sladatqc, kt, kpi, kpj, kit000, &
-      &                    psshn, psshmask, k2dint )
+      IF ( kvar == prodatqc%nvar ) THEN
+         prodatqc%nprofup = prodatqc%nprofup + ipro 
+      ENDIF
+
+   END SUBROUTINE obs_prof_opt
+
+   SUBROUTINE obs_surf_opt( surfdataqc, kt, kpi, kpj,            &
+      &                     kit000, kdaystp, psurf, psurfmask,   &
+      &                     k2dint, ldnightav, plamscl, pphiscl, &
+      &                     lindegrees )
+
       !!-----------------------------------------------------------------------
       !!
-      !!                     ***  ROUTINE obs_sla_opt  ***
-      !!
-      !! ** Purpose : Compute the model counterpart of sea level anomaly
+      !!                     ***  ROUTINE obs_surf_opt  ***
+      !!
+      !! ** Purpose : Compute the model counterpart of surface
       !!              data by interpolating from the model grid to the 
       !!              observation point.
@@ -462,5 +502,5 @@
       !!              the model values at the corners of the surrounding grid box.
       !!
-      !!    The now model SSH is first computed at the obs (lon, lat) point.
+      !!    The new model value is first computed at the obs (lon, lat) point.
       !!
       !!    Several horizontal interpolation schemes are available:
@@ -470,7 +510,9 @@
       !!        - bilinear (quadrilateral grid)    (k2dint = 3)
       !!        - polynomial (quadrilateral grid)  (k2dint = 4)
-      !!  
-      !!    The sea level anomaly at the observation points is then computed 
-      !!    by removing a mean dynamic topography (defined at the obs. point).
+      !!
+      !!    Two horizontal averaging schemes are also available:
+      !!        - weighted radial footprint        (k2dint = 5)
+      !!        - weighted rectangular footprint   (k2dint = 6)
+      !!
       !!
       !! ** Action  :
@@ -478,6 +520,8 @@
       !! History :
       !!      ! 07-03 (A. Weaver)
+      !!      ! 15-02 (M. Martin) Combined routine for surface types
+      !!      ! 17-03 (M. Martin) Added horizontal averaging options
       !!-----------------------------------------------------------------------
-  
+
       !! * Modules used
       USE obs_surf_def  ! Definition of storage space for surface observations
@@ -486,15 +530,23 @@
 
       !! * Arguments
-      TYPE(obs_surf), INTENT(INOUT) :: sladatqc     ! Subset of surface data not failing screening
-      INTEGER, INTENT(IN) :: kt      ! Time step
-      INTEGER, INTENT(IN) :: kpi     ! Model grid parameters
+      TYPE(obs_surf), INTENT(INOUT) :: &
+         & surfdataqc                  ! Subset of surface data passing QC
+      INTEGER, INTENT(IN) :: kt        ! Time step
+      INTEGER, INTENT(IN) :: kpi       ! Model grid parameters
       INTEGER, INTENT(IN) :: kpj
-      INTEGER, INTENT(IN) :: kit000   ! Number of the first time step 
-                                      !   (kit000-1 = restart time)
-      INTEGER, INTENT(IN) :: k2dint   ! Horizontal interpolation type (see header)
-      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: &
-         & psshn,  &    ! Model SSH field
-         & psshmask     ! Land-sea mask
-         
+      INTEGER, INTENT(IN) :: kit000    ! Number of the first time step 
+                                       !   (kit000-1 = restart time)
+      INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day
+      INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header)
+      REAL(wp), INTENT(IN), DIMENSION(kpi,kpj) :: &
+         & psurf,  &                   ! Model surface field
+         & psurfmask                   ! Land-sea mask
+      LOGICAL, INTENT(IN) :: ldnightav ! Logical for averaging night-time data
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plamscl, &                  ! Diameter in metres of obs footprint in E/W, N/S directions
+         & pphiscl                     ! This is the full width (rather than half-width)
+      LOGICAL, INTENT(IN) :: &
+         & lindegrees                  ! T=> plamscl and pphiscl are specified in degrees, F=> in metres
+
       !! * Local declarations
       INTEGER :: ji
@@ -502,67 +554,189 @@
       INTEGER :: jobs
       INTEGER :: inrc
-      INTEGER :: isla
+      INTEGER :: isurf
       INTEGER :: iobs
-      REAL(KIND=wp) :: zlam
-      REAL(KIND=wp) :: zphi
-      REAL(KIND=wp) :: zext(1), zobsmask(1)
-      REAL(kind=wp), DIMENSION(2,2,1) :: &
-         & zweig
+      INTEGER :: imaxifp, imaxjfp
+      INTEGER :: imodi, imodj
+      INTEGER :: idayend
+      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
+         & igrdi,   &
+         & igrdj,   &
+         & igrdip1, &
+         & igrdjp1
+      INTEGER, DIMENSION(:,:), SAVE, ALLOCATABLE :: &
+         & icount_night,      &
+         & imask_night
+      REAL(wp) :: zlam
+      REAL(wp) :: zphi
+      REAL(wp), DIMENSION(1) :: zext, zobsmask
+      REAL(wp) :: zdaystp
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
-         & zmask, &
-         & zsshl, &
-         & zglam, &
-         & zgphi
-      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
-         & igrdi, &
-         & igrdj
+         & zweig,  &
+         & zmask,  &
+         & zsurf,  &
+         & zsurfm, &
+         & zsurftmp, &
+         & zglam,  &
+         & zgphi,  &
+         & zglamf, &
+         & zgphif
+
+      REAL(wp), DIMENSION(:,:), SAVE, ALLOCATABLE :: &
+         & zintmp,  &
+         & zouttmp, &
+         & zmeanday    ! to compute model sst in region of 24h daylight (pole)
 
       !------------------------------------------------------------------------
       ! Local initialization 
       !------------------------------------------------------------------------
-      ! ... Record and data counters
+      ! Record and data counters
       inrc = kt - kit000 + 2
-      isla = sladatqc%nsstp(inrc)
+      isurf = surfdataqc%nsstp(inrc)
+
+      ! Work out the maximum footprint size for the 
+      ! interpolation/averaging in model grid-points - has to be even.
+
+      CALL obs_max_fpsize( k2dint, plamscl, pphiscl, lindegrees, psurfmask, imaxifp, imaxjfp )
+
+
+      IF ( ldnightav ) THEN
+
+      ! Initialize array for night mean
+         IF ( kt == 0 ) THEN
+            ALLOCATE ( icount_night(kpi,kpj) )
+            ALLOCATE ( imask_night(kpi,kpj) )
+            ALLOCATE ( zintmp(kpi,kpj) )
+            ALLOCATE ( zouttmp(kpi,kpj) )
+            ALLOCATE ( zmeanday(kpi,kpj) )
+            nday_qsr = -1   ! initialisation flag for nbc_dcy
+         ENDIF
+
+         ! Night-time means are calculated for night-time values over timesteps:
+         !  [1 <= kt <= kdaystp], [kdaystp+1 <= kt <= 2*kdaystp], .....
+         idayend = MOD( kt - kit000 + 1, kdaystp )
+
+         ! Initialize night-time mean for first timestep of the day
+         IF ( idayend == 1 .OR. kt == 0 ) THEN
+            DO jj = 1, jpj
+               DO ji = 1, jpi
+                  surfdataqc%vdmean(ji,jj) = 0.0
+                  zmeanday(ji,jj) = 0.0
+                  icount_night(ji,jj) = 0
+               END DO
+            END DO
+         ENDIF
+
+         zintmp(:,:) = 0.0
+         zouttmp(:,:) = sbc_dcy( zintmp(:,:), .TRUE. )
+         imask_night(:,:) = INT( zouttmp(:,:) )
+
+         DO jj = 1, jpj
+            DO ji = 1, jpi
+               ! Increment the temperature field for computing night mean and counter
+               surfdataqc%vdmean(ji,jj) = surfdataqc%vdmean(ji,jj)  &
+                      &                    + psurf(ji,jj) * REAL( imask_night(ji,jj) )
+               zmeanday(ji,jj)          = zmeanday(ji,jj) + psurf(ji,jj)
+               icount_night(ji,jj)      = icount_night(ji,jj) + imask_night(ji,jj)
+            END DO
+         END DO
+
+         ! Compute the night-time mean at the end of the day
+         zdaystp = 1.0 / REAL( kdaystp )
+         IF ( idayend == 0 ) THEN
+            IF (lwp) WRITE(numout,*) 'Calculating surfdataqc%vdmean on time-step: ',kt
+            DO jj = 1, jpj
+               DO ji = 1, jpi
+                  ! Test if "no night" point
+                  IF ( icount_night(ji,jj) > 0 ) THEN
+                     surfdataqc%vdmean(ji,jj) = surfdataqc%vdmean(ji,jj) &
+                       &                        / REAL( icount_night(ji,jj) )
+                  ELSE
+                     !At locations where there is no night (e.g. poles),
+                     ! calculate daily mean instead of night-time mean.
+                     surfdataqc%vdmean(ji,jj) = zmeanday(ji,jj) * zdaystp
+                  ENDIF
+               END DO
+            END DO
+         ENDIF
+
+      ENDIF
 
       ! Get the data for interpolation
 
       ALLOCATE( &
-         & igrdi(2,2,isla), &
-         & igrdj(2,2,isla), &
-         & zglam(2,2,isla), &
-         & zgphi(2,2,isla), &
-         & zmask(2,2,isla), &
-         & zsshl(2,2,isla)  &
+         & zweig(imaxifp,imaxjfp,1),      &
+         & igrdi(imaxifp,imaxjfp,isurf), &
+         & igrdj(imaxifp,imaxjfp,isurf), &
+         & zglam(imaxifp,imaxjfp,isurf), &
+         & zgphi(imaxifp,imaxjfp,isurf), &
+         & zmask(imaxifp,imaxjfp,isurf), &
+         & zsurf(imaxifp,imaxjfp,isurf), &
+         & zsurftmp(imaxifp,imaxjfp,isurf),  &
+         & zglamf(imaxifp+1,imaxjfp+1,isurf), &
+         & zgphif(imaxifp+1,imaxjfp+1,isurf), &
+         & igrdip1(imaxifp+1,imaxjfp+1,isurf), &
+         & igrdjp1(imaxifp+1,imaxjfp+1,isurf) &
          & )
-      
-      DO jobs = sladatqc%nsurfup + 1, sladatqc%nsurfup + isla
-         iobs = jobs - sladatqc%nsurfup
-         igrdi(1,1,iobs) = sladatqc%mi(jobs)-1
-         igrdj(1,1,iobs) = sladatqc%mj(jobs)-1
-         igrdi(1,2,iobs) = sladatqc%mi(jobs)-1
-         igrdj(1,2,iobs) = sladatqc%mj(jobs)
-         igrdi(2,1,iobs) = sladatqc%mi(jobs)
-         igrdj(2,1,iobs) = sladatqc%mj(jobs)-1
-         igrdi(2,2,iobs) = sladatqc%mi(jobs)
-         igrdj(2,2,iobs) = sladatqc%mj(jobs)
+
+      DO jobs = surfdataqc%nsurfup + 1, surfdataqc%nsurfup + isurf
+         iobs = jobs - surfdataqc%nsurfup
+         DO ji = 0, imaxifp
+            imodi = surfdataqc%mi(jobs) - int(imaxifp/2) + ji - 1
+            
+            !Deal with wrap around in longitude
+            IF ( imodi < 1      ) imodi = imodi + jpiglo
+            IF ( imodi > jpiglo ) imodi = imodi - jpiglo
+            
+            DO jj = 0, imaxjfp
+               imodj = surfdataqc%mj(jobs) - int(imaxjfp/2) + jj - 1
+               !If model values are out of the domain to the north/south then
+               !set them to be the edge of the domain
+               IF ( imodj < 1      ) imodj = 1
+               IF ( imodj > jpjglo ) imodj = jpjglo
+
+               igrdip1(ji+1,jj+1,iobs) = imodi
+               igrdjp1(ji+1,jj+1,iobs) = imodj
+               
+               IF ( ji >= 1 .AND. jj >= 1 ) THEN
+                  igrdi(ji,jj,iobs) = imodi
+                  igrdj(ji,jj,iobs) = imodj
+               ENDIF
+               
+            END DO
+         END DO
       END DO
 
-      CALL obs_int_comm_2d( 2, 2, isla, &
+      CALL obs_int_comm_2d( imaxifp, imaxjfp, isurf, kpi, kpj, &
          &                  igrdi, igrdj, glamt, zglam )
-      CALL obs_int_comm_2d( 2, 2, isla, &
+      CALL obs_int_comm_2d( imaxifp, imaxjfp, isurf, kpi, kpj, &
          &                  igrdi, igrdj, gphit, zgphi )
-      CALL obs_int_comm_2d( 2, 2, isla, &
-         &                  igrdi, igrdj, psshmask, zmask )
-      CALL obs_int_comm_2d( 2, 2, isla, &
-         &                  igrdi, igrdj, psshn, zsshl )
+      CALL obs_int_comm_2d( imaxifp, imaxjfp, isurf, kpi, kpj, &
+         &                  igrdi, igrdj, psurfmask, zmask )
+      CALL obs_int_comm_2d( imaxifp, imaxjfp, isurf, kpi, kpj, &
+         &                  igrdi, igrdj, psurf, zsurf )
+      CALL obs_int_comm_2d( imaxifp+1, imaxjfp+1, isurf, kpi, kpj, &
+         &                  igrdip1, igrdjp1, glamf, zglamf )
+      CALL obs_int_comm_2d( imaxifp+1, imaxjfp+1, isurf, kpi, kpj, &
+         &                  igrdip1, igrdjp1, gphif, zgphif )
+
+      ! At the end of the day get interpolated means
+      IF ( idayend == 0 .AND. ldnightav ) THEN
+
+         ALLOCATE( &
+            & zsurfm(imaxifp,imaxjfp,isurf)  &
+            & )
+
+         CALL obs_int_comm_2d( imaxifp,imaxjfp, isurf, kpi, kpj, igrdi, igrdj, &
+            &               surfdataqc%vdmean(:,:), zsurfm )
+
+      ENDIF
 
       ! Loop over observations
-
-      DO jobs = sladatqc%nsurfup + 1, sladatqc%nsurfup + isla
-
-         iobs = jobs - sladatqc%nsurfup
-
-         IF ( kt /= sladatqc%mstp(jobs) ) THEN
-            
+      DO jobs = surfdataqc%nsurfup + 1, surfdataqc%nsurfup + isurf
+
+         iobs = jobs - surfdataqc%nsurfup
+
+         IF ( kt /= surfdataqc%mstp(jobs) ) THEN
+
             IF(lwp) THEN
                WRITE(numout,*)
@@ -574,27 +748,58 @@
                WRITE(numout,*) ' Record  = ', jobs,                &
                   &            ' kt      = ', kt,                  &
-                  &            ' mstp    = ', sladatqc%mstp(jobs), &
-                  &            ' ntyp    = ', sladatqc%ntyp(jobs)
+                  &            ' mstp    = ', surfdataqc%mstp(jobs), &
+                  &            ' ntyp    = ', surfdataqc%ntyp(jobs)
             ENDIF
-            CALL ctl_stop( 'obs_sla_opt', 'Inconsistent time' )
-            
+            CALL ctl_stop( 'obs_surf_opt', 'Inconsistent time' )
+
+         ENDIF
+
+         zlam = surfdataqc%rlam(jobs)
+         zphi = surfdataqc%rphi(jobs)
+
+         IF ( ldnightav .AND. idayend == 0 ) THEN
+            ! Night-time averaged data
+            zsurftmp(:,:,iobs) = zsurfm(:,:,iobs)
+         ELSE
+            zsurftmp(:,:,iobs) = zsurf(:,:,iobs)
+         ENDIF
+
+         IF ( k2dint <= 4 ) THEN
+
+            ! Get weights to interpolate the model value to the observation point
+            CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
+               &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
+               &                   zmask(:,:,iobs), zweig, zobsmask )
+
+            ! Interpolate the model value to the observation point 
+            CALL obs_int_h2d( 1, 1, zweig, zsurftmp(:,:,iobs), zext )
+
+         ELSE
+
+            ! Get weights to average the model SLA to the observation footprint
+            CALL obs_avg_h2d_init( 1, 1, imaxifp, imaxjfp, k2dint, zlam,  zphi, &
+               &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
+               &                   zglamf(:,:,iobs), zgphif(:,:,iobs), &
+               &                   zmask(:,:,iobs), plamscl, pphiscl, &
+               &                   lindegrees, zweig, zobsmask )
+
+            ! Average the model SST to the observation footprint
+            CALL obs_avg_h2d( 1, 1, imaxifp, imaxjfp, &
+               &              zweig, zsurftmp(:,:,iobs),  zext )
+
+         ENDIF
+
+         IF ( TRIM(surfdataqc%cvars(1)) == 'SLA' .AND. surfdataqc%nextra == 2 ) THEN
+            ! ... Remove the MDT from the SSH at the observation point to get the SLA
+            surfdataqc%rext(jobs,1) = zext(1)
+            surfdataqc%rmod(jobs,1) = surfdataqc%rext(jobs,1) - surfdataqc%rext(jobs,2)
+         ELSE
+            surfdataqc%rmod(jobs,1) = zext(1)
          ENDIF
          
-         zlam = sladatqc%rlam(jobs)
-         zphi = sladatqc%rphi(jobs)
-
-         ! Get weights to interpolate the model SSH to the observation point
-         CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
-            &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
-            &                   zmask(:,:,iobs), zweig, zobsmask )
-         
-
-         ! Interpolate the model SSH to the observation point
-         CALL obs_int_h2d( 1, 1,      &
-            &              zweig, zsshl(:,:,iobs),  zext )
-         
-         sladatqc%rext(jobs,1) = zext(1)
-         ! ... Remove the MDT at the observation point
-         sladatqc%rmod(jobs,1) = sladatqc%rext(jobs,1) - sladatqc%rext(jobs,2)
+         IF ( zext(1) == obfillflt ) THEN
+            ! If the observation value is a fill value, set QC flag to bad
+            surfdataqc%nqc(jobs) = 4
+         ENDIF
 
       END DO
@@ -602,4 +807,5 @@
       ! Deallocate the data for interpolation
       DEALLOCATE( &
+         & zweig, &
          & igrdi, &
          & igrdj, &
@@ -607,836 +813,22 @@
          & zgphi, &
          & zmask, &
-         & zsshl  &
+         & zsurf, &
+         & zsurftmp, &
+         & zglamf, &
+         & zgphif, &
+         & igrdip1,&
+         & igrdjp1 &
          & )
 
-      sladatqc%nsurfup = sladatqc%nsurfup + isla
-
-   END SUBROUTINE obs_sla_opt
-
-   SUBROUTINE obs_sst_opt( sstdatqc, kt, kpi, kpj, kit000, kdaystp, &
-      &                    psstn, psstmask, k2dint, ld_nightav )
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     ***  ROUTINE obs_sst_opt  ***
-      !!
-      !! ** Purpose : Compute the model counterpart of surface temperature
-      !!              data by interpolating from the model grid to the 
-      !!              observation point.
-      !!
-      !! ** Method  : Linearly interpolate to each observation point using 
-      !!              the model values at the corners of the surrounding grid box.
-      !!
-      !!    The now model SST is first computed at the obs (lon, lat) point.
-      !!
-      !!    Several horizontal interpolation schemes are available:
-      !!        - distance-weighted (great circle) (k2dint = 0)
-      !!        - distance-weighted (small angle)  (k2dint = 1)
-      !!        - bilinear (geographical grid)     (k2dint = 2)
-      !!        - bilinear (quadrilateral grid)    (k2dint = 3)
-      !!        - polynomial (quadrilateral grid)  (k2dint = 4)
-      !!
-      !!
-      !! ** Action  :
-      !!
-      !! History :
-      !!        !  07-07  (S. Ricci ) : Original
-      !!      
-      !!-----------------------------------------------------------------------
-
-      !! * Modules used
-      USE obs_surf_def  ! Definition of storage space for surface observations
-      USE sbcdcy
-
-      IMPLICIT NONE
-
-      !! * Arguments
-      TYPE(obs_surf), INTENT(INOUT) :: &
-         & sstdatqc     ! Subset of surface data not failing screening
-      INTEGER, INTENT(IN) :: kt        ! Time step
-      INTEGER, INTENT(IN) :: kpi       ! Model grid parameters
-      INTEGER, INTENT(IN) :: kpj
-      INTEGER, INTENT(IN) :: kit000    ! Number of the first time step 
-                                       !   (kit000-1 = restart time)
-      INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header)
-      INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day  
-      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: &
-         & psstn,  &    ! Model SST field
-         & psstmask     ! Land-sea mask
-
-      !! * Local declarations
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jobs
-      INTEGER :: inrc
-      INTEGER :: isst
-      INTEGER :: iobs
-      INTEGER :: idayend
-      REAL(KIND=wp) :: zlam
-      REAL(KIND=wp) :: zphi
-      REAL(KIND=wp) :: zext(1), zobsmask(1)
-      REAL(KIND=wp) :: zdaystp
-      INTEGER, DIMENSION(:,:), SAVE, ALLOCATABLE :: &
-         & icount_sstnight,      &
-         & imask_night
-      REAL(kind=wp), DIMENSION(:,:), SAVE, ALLOCATABLE :: &
-         & zintmp, &
-         & zouttmp, & 
-         & zmeanday    ! to compute model sst in region of 24h daylight (pole)
-      REAL(kind=wp), DIMENSION(2,2,1) :: &
-         & zweig
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
-         & zmask, &
-         & zsstl, &
-         & zsstm, &
-         & zglam, &
-         & zgphi
-      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
-         & igrdi, &
-         & igrdj
-      LOGICAL, INTENT(IN) :: ld_nightav
-
-      !-----------------------------------------------------------------------
-      ! Local initialization 
-      !-----------------------------------------------------------------------
-      ! ... Record and data counters
-      inrc = kt - kit000 + 2
-      isst = sstdatqc%nsstp(inrc)
-
-      IF ( ld_nightav ) THEN
-
-      ! Initialize array for night mean
-
-      IF ( kt .EQ. 0 ) THEN
-         ALLOCATE ( icount_sstnight(kpi,kpj) )
-         ALLOCATE ( imask_night(kpi,kpj) )
-         ALLOCATE ( zintmp(kpi,kpj) )
-         ALLOCATE ( zouttmp(kpi,kpj) )
-         ALLOCATE ( zmeanday(kpi,kpj) )
-         nday_qsr = -1   ! initialisation flag for nbc_dcy
-      ENDIF
-
-      ! Initialize daily mean for first timestep
-      idayend = MOD( kt - kit000 + 1, kdaystp )
-
-      ! Added kt == 0 test to catch restart case 
-      IF ( idayend == 1 .OR. kt == 0) THEN
-         IF (lwp) WRITE(numout,*) 'Reset sstdatqc%vdmean on time-step: ',kt
-         DO jj = 1, jpj
-            DO ji = 1, jpi
-               sstdatqc%vdmean(ji,jj) = 0.0
-               zmeanday(ji,jj) = 0.0
-               icount_sstnight(ji,jj) = 0
-            END DO
-         END DO
-      ENDIF
-
-      zintmp(:,:) = 0.0
-      zouttmp(:,:) = sbc_dcy( zintmp(:,:), .TRUE. )
-      imask_night(:,:) = INT( zouttmp(:,:) )
-
-      DO jj = 1, jpj
-         DO ji = 1, jpi
-            ! Increment the temperature field for computing night mean and counter
-            sstdatqc%vdmean(ji,jj) = sstdatqc%vdmean(ji,jj)  &
-                   &                        + psstn(ji,jj)*imask_night(ji,jj)
-            zmeanday(ji,jj)        = zmeanday(ji,jj) + psstn(ji,jj)
-            icount_sstnight(ji,jj) = icount_sstnight(ji,jj) + imask_night(ji,jj)
-         END DO
-      END DO
-   
-      ! Compute the daily mean at the end of day
-
-      zdaystp = 1.0 / REAL( kdaystp )
-
-      IF ( idayend == 0 ) THEN 
-         DO jj = 1, jpj
-            DO ji = 1, jpi
-               ! Test if "no night" point
-               IF ( icount_sstnight(ji,jj) .NE. 0 ) THEN
-                  sstdatqc%vdmean(ji,jj) = sstdatqc%vdmean(ji,jj) &
-                    &                        / icount_sstnight(ji,jj) 
-               ELSE
-                  sstdatqc%vdmean(ji,jj) = zmeanday(ji,jj) * zdaystp
-               ENDIF
-            END DO
-         END DO
-      ENDIF
-
-      ENDIF
-
-      ! Get the data for interpolation
-      
-      ALLOCATE( &
-         & igrdi(2,2,isst), &
-         & igrdj(2,2,isst), &
-         & zglam(2,2,isst), &
-         & zgphi(2,2,isst), &
-         & zmask(2,2,isst), &
-         & zsstl(2,2,isst)  &
-         & )
-      
-      DO jobs = sstdatqc%nsurfup + 1, sstdatqc%nsurfup + isst
-         iobs = jobs - sstdatqc%nsurfup
-         igrdi(1,1,iobs) = sstdatqc%mi(jobs)-1
-         igrdj(1,1,iobs) = sstdatqc%mj(jobs)-1
-         igrdi(1,2,iobs) = sstdatqc%mi(jobs)-1
-         igrdj(1,2,iobs) = sstdatqc%mj(jobs)
-         igrdi(2,1,iobs) = sstdatqc%mi(jobs)
-         igrdj(2,1,iobs) = sstdatqc%mj(jobs)-1
-         igrdi(2,2,iobs) = sstdatqc%mi(jobs)
-         igrdj(2,2,iobs) = sstdatqc%mj(jobs)
-      END DO
-      
-      CALL obs_int_comm_2d( 2, 2, isst, &
-         &                  igrdi, igrdj, glamt, zglam )
-      CALL obs_int_comm_2d( 2, 2, isst, &
-         &                  igrdi, igrdj, gphit, zgphi )
-      CALL obs_int_comm_2d( 2, 2, isst, &
-         &                  igrdi, igrdj, psstmask, zmask )
-      CALL obs_int_comm_2d( 2, 2, isst, &
-         &                  igrdi, igrdj, psstn, zsstl )
-
-      ! At the end of the day get interpolated means
-      IF ( idayend == 0 .AND. ld_nightav ) THEN
-
-         ALLOCATE( &
-            & zsstm(2,2,isst)  &
-            & )
-
-         CALL obs_int_comm_2d( 2, 2, isst, igrdi, igrdj, &
-            &               sstdatqc%vdmean(:,:), zsstm )
-
-      ENDIF
-
-      ! Loop over observations
-
-      DO jobs = sstdatqc%nsurfup + 1, sstdatqc%nsurfup + isst
-         
-         iobs = jobs - sstdatqc%nsurfup
-         
-         IF ( kt /= sstdatqc%mstp(jobs) ) THEN
-            
-            IF(lwp) THEN
-               WRITE(numout,*)
-               WRITE(numout,*) ' E R R O R : Observation',              &
-                  &            ' time step is not consistent with the', &
-                  &            ' model time step'
-               WRITE(numout,*) ' ========='
-               WRITE(numout,*)
-               WRITE(numout,*) ' Record  = ', jobs,                &
-                  &            ' kt      = ', kt,                  &
-                  &            ' mstp    = ', sstdatqc%mstp(jobs), &
-                  &            ' ntyp    = ', sstdatqc%ntyp(jobs)
-            ENDIF
-            CALL ctl_stop( 'obs_sst_opt', 'Inconsistent time' )
-            
-         ENDIF
-         
-         zlam = sstdatqc%rlam(jobs)
-         zphi = sstdatqc%rphi(jobs)
-         
-         ! Get weights to interpolate the model SST to the observation point
-         CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
-            &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
-            &                   zmask(:,:,iobs), zweig, zobsmask )
-            
-         ! Interpolate the model SST to the observation point 
-
-         IF ( ld_nightav ) THEN
-
-           IF ( idayend == 0 )  THEN
-               ! Daily averaged/diurnal cycle of SST  data
-               CALL obs_int_h2d( 1, 1,      & 
-                     &              zweig, zsstm(:,:,iobs), zext )
-            ELSE 
-               CALL ctl_stop( ' ld_nightav is set to true: a nonzero' //     &
-                     &           ' number of night SST data should' // &
-                     &           ' only occur at the end of a given day' )
-            ENDIF
-
-         ELSE
-
-            CALL obs_int_h2d( 1, 1,      &
-            &              zweig, zsstl(:,:,iobs),  zext )
-
-         ENDIF
-         sstdatqc%rmod(jobs,1) = zext(1)
-         
-      END DO
-      
-      ! Deallocate the data for interpolation
-      DEALLOCATE( &
-         & igrdi, &
-         & igrdj, &
-         & zglam, &
-         & zgphi, &
-         & zmask, &
-         & zsstl  &
-         & )
-
-      ! At the end of the day also get interpolated means
-      IF ( idayend == 0 .AND. ld_nightav ) THEN
+      ! At the end of the day also deallocate night-time mean array
+      IF ( idayend == 0 .AND. ldnightav ) THEN
          DEALLOCATE( &
-            & zsstm  &
+            & zsurfm  &
             & )
       ENDIF
-      
-      sstdatqc%nsurfup = sstdatqc%nsurfup + isst
-
-   END SUBROUTINE obs_sst_opt
-
-   SUBROUTINE obs_sss_opt
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     ***  ROUTINE obs_sss_opt  ***
-      !!
-      !! ** Purpose : Compute the model counterpart of sea surface salinity
-      !!              data by interpolating from the model grid to the 
-      !!              observation point.
-      !!
-      !! ** Method  : 
-      !!
-      !! ** Action  :
-      !!
-      !! History :
-      !!      ! ??-?? 
-      !!-----------------------------------------------------------------------
-
-      IMPLICIT NONE
-
-   END SUBROUTINE obs_sss_opt
-
-   SUBROUTINE obs_seaice_opt( seaicedatqc, kt, kpi, kpj, kit000, &
-      &                    pseaicen, pseaicemask, k2dint )
-
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     ***  ROUTINE obs_seaice_opt  ***
-      !!
-      !! ** Purpose : Compute the model counterpart of surface temperature
-      !!              data by interpolating from the model grid to the 
-      !!              observation point.
-      !!
-      !! ** Method  : Linearly interpolate to each observation point using 
-      !!              the model values at the corners of the surrounding grid box.
-      !!
-      !!    The now model sea ice is first computed at the obs (lon, lat) point.
-      !!
-      !!    Several horizontal interpolation schemes are available:
-      !!        - distance-weighted (great circle) (k2dint = 0)
-      !!        - distance-weighted (small angle)  (k2dint = 1)
-      !!        - bilinear (geographical grid)     (k2dint = 2)
-      !!        - bilinear (quadrilateral grid)    (k2dint = 3)
-      !!        - polynomial (quadrilateral grid)  (k2dint = 4)
-      !!
-      !!
-      !! ** Action  :
-      !!
-      !! History :
-      !!        !  07-07  (S. Ricci ) : Original
-      !!      
-      !!-----------------------------------------------------------------------
-
-      !! * Modules used
-      USE obs_surf_def  ! Definition of storage space for surface observations
-
-      IMPLICIT NONE
-
-      !! * Arguments
-      TYPE(obs_surf), INTENT(INOUT) :: seaicedatqc     ! Subset of surface data not failing screening
-      INTEGER, INTENT(IN) :: kt       ! Time step
-      INTEGER, INTENT(IN) :: kpi      ! Model grid parameters
-      INTEGER, INTENT(IN) :: kpj
-      INTEGER, INTENT(IN) :: kit000   ! Number of the first time step 
-                                      !   (kit000-1 = restart time)
-      INTEGER, INTENT(IN) :: k2dint   ! Horizontal interpolation type (see header)
-      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: &
-         & pseaicen,  &    ! Model sea ice field
-         & pseaicemask     ! Land-sea mask
-         
-      !! * Local declarations
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jobs
-      INTEGER :: inrc
-      INTEGER :: iseaice
-      INTEGER :: iobs
-       
-      REAL(KIND=wp) :: zlam
-      REAL(KIND=wp) :: zphi
-      REAL(KIND=wp) :: zext(1), zobsmask(1)
-      REAL(kind=wp), DIMENSION(2,2,1) :: &
-         & zweig
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
-         & zmask, &
-         & zseaicel, &
-         & zglam, &
-         & zgphi
-      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
-         & igrdi, &
-         & igrdj
-
-      !------------------------------------------------------------------------
-      ! Local initialization 
-      !------------------------------------------------------------------------
-      ! ... Record and data counters
-      inrc = kt - kit000 + 2
-      iseaice = seaicedatqc%nsstp(inrc)
-
-      ! Get the data for interpolation
-      
-      ALLOCATE( &
-         & igrdi(2,2,iseaice), &
-         & igrdj(2,2,iseaice), &
-         & zglam(2,2,iseaice), &
-         & zgphi(2,2,iseaice), &
-         & zmask(2,2,iseaice), &
-         & zseaicel(2,2,iseaice)  &
-         & )
-      
-      DO jobs = seaicedatqc%nsurfup + 1, seaicedatqc%nsurfup + iseaice
-         iobs = jobs - seaicedatqc%nsurfup
-         igrdi(1,1,iobs) = seaicedatqc%mi(jobs)-1
-         igrdj(1,1,iobs) = seaicedatqc%mj(jobs)-1
-         igrdi(1,2,iobs) = seaicedatqc%mi(jobs)-1
-         igrdj(1,2,iobs) = seaicedatqc%mj(jobs)
-         igrdi(2,1,iobs) = seaicedatqc%mi(jobs)
-         igrdj(2,1,iobs) = seaicedatqc%mj(jobs)-1
-         igrdi(2,2,iobs) = seaicedatqc%mi(jobs)
-         igrdj(2,2,iobs) = seaicedatqc%mj(jobs)
-      END DO
-      
-      CALL obs_int_comm_2d( 2, 2, iseaice, &
-         &                  igrdi, igrdj, glamt, zglam )
-      CALL obs_int_comm_2d( 2, 2, iseaice, &
-         &                  igrdi, igrdj, gphit, zgphi )
-      CALL obs_int_comm_2d( 2, 2, iseaice, &
-         &                  igrdi, igrdj, pseaicemask, zmask )
-      CALL obs_int_comm_2d( 2, 2, iseaice, &
-         &                  igrdi, igrdj, pseaicen, zseaicel )
-      
-      DO jobs = seaicedatqc%nsurfup + 1, seaicedatqc%nsurfup + iseaice
-         
-         iobs = jobs - seaicedatqc%nsurfup
-         
-         IF ( kt /= seaicedatqc%mstp(jobs) ) THEN
-            
-            IF(lwp) THEN
-               WRITE(numout,*)
-               WRITE(numout,*) ' E R R O R : Observation',              &
-                  &            ' time step is not consistent with the', &
-                  &            ' model time step'
-               WRITE(numout,*) ' ========='
-               WRITE(numout,*)
-               WRITE(numout,*) ' Record  = ', jobs,                &
-                  &            ' kt      = ', kt,                  &
-                  &            ' mstp    = ', seaicedatqc%mstp(jobs), &
-                  &            ' ntyp    = ', seaicedatqc%ntyp(jobs)
-            ENDIF
-            CALL ctl_stop( 'obs_seaice_opt', 'Inconsistent time' )
-            
-         ENDIF
-         
-         zlam = seaicedatqc%rlam(jobs)
-         zphi = seaicedatqc%rphi(jobs)
-         
-         ! Get weights to interpolate the model sea ice to the observation point
-         CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
-            &                   zglam(:,:,iobs), zgphi(:,:,iobs), &
-            &                   zmask(:,:,iobs), zweig, zobsmask )
-         
-         ! ... Interpolate the model sea ice to the observation point
-         CALL obs_int_h2d( 1, 1,      &
-            &              zweig, zseaicel(:,:,iobs),  zext )
-         
-         seaicedatqc%rmod(jobs,1) = zext(1)
-         
-      END DO
-      
-      ! Deallocate the data for interpolation
-      DEALLOCATE( &
-         & igrdi,    &
-         & igrdj,    &
-         & zglam,    &
-         & zgphi,    &
-         & zmask,    &
-         & zseaicel  &
-         & )
-      
-      seaicedatqc%nsurfup = seaicedatqc%nsurfup + iseaice
-
-   END SUBROUTINE obs_seaice_opt
-
-   SUBROUTINE obs_vel_opt( prodatqc, kt, kpi, kpj, kpk, kit000, kdaystp, &
-      &                    pun, pvn, pgdept, pumask, pvmask, k1dint, k2dint, &
-      &                    ld_dailyav )
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     ***  ROUTINE obs_vel_opt  ***
-      !!
-      !! ** Purpose : Compute the model counterpart of velocity profile
-      !!              data by interpolating from the model grid to the 
-      !!              observation point.
-      !!
-      !! ** Method  : Linearly interpolate zonal and meridional components of velocity 
-      !!              to each observation point using the model values at the corners of 
-      !!              the surrounding grid box. The model velocity components are on a 
-      !!              staggered C- grid.
-      !!
-      !!    For velocity data from the TAO array, the model equivalent is
-      !!    a daily mean velocity field. So, we first compute
-      !!    the mean, then interpolate only at the end of the day.
-      !!
-      !! ** Action  :
-      !!
-      !! History :
-      !!    ! 07-03 (K. Mogensen)      : Temperature and Salinity profiles
-      !!    ! 08-10 (Maria Valdivieso) : Velocity component (U,V) profiles
-      !!-----------------------------------------------------------------------
-    
-      !! * Modules used
-      USE obs_profiles_def ! Definition of storage space for profile obs.
-
-      IMPLICIT NONE
-
-      !! * Arguments
-      TYPE(obs_prof), INTENT(INOUT) :: &
-         & prodatqc        ! Subset of profile data not failing screening
-      INTEGER, INTENT(IN) :: kt        ! Time step
-      INTEGER, INTENT(IN) :: kpi       ! Model grid parameters
-      INTEGER, INTENT(IN) :: kpj
-      INTEGER, INTENT(IN) :: kpk 
-      INTEGER, INTENT(IN) :: kit000    ! Number of the first time step 
-                                       !   (kit000-1 = restart time)
-      INTEGER, INTENT(IN) :: k1dint    ! Vertical interpolation type (see header)
-      INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header)
-      INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day                    
-      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj,kpk) :: &
-         & pun,    &    ! Model zonal component of velocity
-         & pvn,    &    ! Model meridional component of velocity
-         & pumask, &    ! Land-sea mask
-         & pvmask       ! Land-sea mask
-      REAL(KIND=wp), INTENT(IN), DIMENSION(kpk) :: &
-         & pgdept       ! Model array of depth levels
-      LOGICAL, INTENT(IN) :: ld_dailyav
-         
-      !! * Local declarations
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jk
-      INTEGER :: jobs
-      INTEGER :: inrc
-      INTEGER :: ipro
-      INTEGER :: idayend
-      INTEGER :: ista
-      INTEGER :: iend
-      INTEGER :: iobs
-      INTEGER, DIMENSION(imaxavtypes) :: &
-         & idailyavtypes
-      REAL(KIND=wp) :: zlam
-      REAL(KIND=wp) :: zphi
-      REAL(KIND=wp) :: zdaystp
-      REAL(KIND=wp), DIMENSION(kpk) :: &
-         & zobsmasku, &
-         & zobsmaskv, &
-         & zobsmask,  &
-         & zobsk,     &
-         & zobs2k
-      REAL(KIND=wp), DIMENSION(2,2,kpk) :: &
-         & zweigu,zweigv
-      REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE :: &
-         & zumask, zvmask, &
-         & zintu, &
-         & zintv, &
-         & zinmu, &
-         & zinmv
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
-         & zglamu, zglamv, &
-         & zgphiu, zgphiv
-      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
-         & igrdiu, &
-         & igrdju, &
-         & igrdiv, &
-         & igrdjv
-
-      !------------------------------------------------------------------------
-      ! Local initialization 
-      !------------------------------------------------------------------------
-      ! ... Record and data counters
-      inrc = kt - kit000 + 2
-      ipro = prodatqc%npstp(inrc)
-
-      ! Initialize daily mean for first timestep
-      idayend = MOD( kt - kit000 + 1, kdaystp )
-
-      ! Added kt == 0 test to catch restart case 
-      IF ( idayend == 1 .OR. kt == 0) THEN
-         IF (lwp) WRITE(numout,*) 'Reset prodatqc%vdmean on time-step: ',kt
-         prodatqc%vdmean(:,:,:,1) = 0.0
-         prodatqc%vdmean(:,:,:,2) = 0.0
-      ENDIF
-
-      ! Increment the zonal velocity field for computing daily mean
-      prodatqc%vdmean(:,:,:,1) = prodatqc%vdmean(:,:,:,1) + pun(:,:,:)
-      ! Increment the meridional velocity field for computing daily mean
-      prodatqc%vdmean(:,:,:,2) = prodatqc%vdmean(:,:,:,2) + pvn(:,:,:)
-   
-      ! Compute the daily mean at the end of day
-      zdaystp = 1.0 / REAL( kdaystp )
-      IF ( idayend == 0 ) THEN
-         prodatqc%vdmean(:,:,:,1) = prodatqc%vdmean(:,:,:,1) * zdaystp
-         prodatqc%vdmean(:,:,:,2) = prodatqc%vdmean(:,:,:,2) * zdaystp
-      ENDIF
-
-      ! Get the data for interpolation
-      ALLOCATE( &
-         & igrdiu(2,2,ipro),      &
-         & igrdju(2,2,ipro),      &
-         & igrdiv(2,2,ipro),      &
-         & igrdjv(2,2,ipro),      &
-         & zglamu(2,2,ipro), zglamv(2,2,ipro), &
-         & zgphiu(2,2,ipro), zgphiv(2,2,ipro), &
-         & zumask(2,2,kpk,ipro), zvmask(2,2,kpk,ipro), &
-         & zintu(2,2,kpk,ipro),  &
-         & zintv(2,2,kpk,ipro)   &
-         & )
-
-      DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro
-         iobs = jobs - prodatqc%nprofup
-         igrdiu(1,1,iobs) = prodatqc%mi(jobs,1)-1
-         igrdju(1,1,iobs) = prodatqc%mj(jobs,1)-1
-         igrdiu(1,2,iobs) = prodatqc%mi(jobs,1)-1
-         igrdju(1,2,iobs) = prodatqc%mj(jobs,1)
-         igrdiu(2,1,iobs) = prodatqc%mi(jobs,1)
-         igrdju(2,1,iobs) = prodatqc%mj(jobs,1)-1
-         igrdiu(2,2,iobs) = prodatqc%mi(jobs,1)
-         igrdju(2,2,iobs) = prodatqc%mj(jobs,1)
-         igrdiv(1,1,iobs) = prodatqc%mi(jobs,2)-1
-         igrdjv(1,1,iobs) = prodatqc%mj(jobs,2)-1
-         igrdiv(1,2,iobs) = prodatqc%mi(jobs,2)-1
-         igrdjv(1,2,iobs) = prodatqc%mj(jobs,2)
-         igrdiv(2,1,iobs) = prodatqc%mi(jobs,2)
-         igrdjv(2,1,iobs) = prodatqc%mj(jobs,2)-1
-         igrdiv(2,2,iobs) = prodatqc%mi(jobs,2)
-         igrdjv(2,2,iobs) = prodatqc%mj(jobs,2)
-      END DO
-
-      CALL obs_int_comm_2d( 2, 2, ipro, igrdiu, igrdju, glamu, zglamu )
-      CALL obs_int_comm_2d( 2, 2, ipro, igrdiu, igrdju, gphiu, zgphiu )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiu, igrdju, pumask, zumask )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiu, igrdju, pun, zintu )
-
-      CALL obs_int_comm_2d( 2, 2, ipro, igrdiv, igrdjv, glamv, zglamv )
-      CALL obs_int_comm_2d( 2, 2, ipro, igrdiv, igrdjv, gphiv, zgphiv )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiv, igrdjv, pvmask, zvmask )
-      CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiv, igrdjv, pvn, zintv )
-
-      ! At the end of the day also get interpolated means
-      IF ( idayend == 0 ) THEN
-
-         ALLOCATE( &
-            & zinmu(2,2,kpk,ipro),  &
-            & zinmv(2,2,kpk,ipro)   &
-            & )
-
-         CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiu, igrdju, &
-            &                  prodatqc%vdmean(:,:,:,1), zinmu )
-         CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiv, igrdjv, &
-            &                  prodatqc%vdmean(:,:,:,2), zinmv )
-
-      ENDIF
-
-! loop over observations
-
-      DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro
-
-         iobs = jobs - prodatqc%nprofup
-
-         IF ( kt /= prodatqc%mstp(jobs) ) THEN
-            
-            IF(lwp) THEN
-               WRITE(numout,*)
-               WRITE(numout,*) ' E R R O R : Observation',              &
-                  &            ' time step is not consistent with the', &
-                  &            ' model time step'
-               WRITE(numout,*) ' ========='
-               WRITE(numout,*)
-               WRITE(numout,*) ' Record  = ', jobs,                    &
-                  &            ' kt      = ', kt,                      &
-                  &            ' mstp    = ', prodatqc%mstp(jobs), &
-                  &            ' ntyp    = ', prodatqc%ntyp(jobs)
-            ENDIF
-            CALL ctl_stop( 'obs_pro_opt', 'Inconsistent time' )
-         ENDIF
-         
-         zlam = prodatqc%rlam(jobs)
-         zphi = prodatqc%rphi(jobs)
-
-         ! Initialize observation masks
-
-         zobsmasku(:) = 0.0
-         zobsmaskv(:) = 0.0
-         
-         ! Horizontal weights and vertical mask
-
-         IF  ( prodatqc%npvend(jobs,1) > 0 ) THEN
-
-            CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     &
-               &                   zglamu(:,:,iobs), zgphiu(:,:,iobs), &
-               &                   zumask(:,:,:,iobs), zweigu, zobsmasku )
-
-         ENDIF
-
-         
-         IF ( prodatqc%npvend(jobs,2) > 0 ) THEN
-
-            CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     &
-               &                   zglamv(:,:,iobs), zgphiv(:,:,iobs), &
-               &                   zvmask(:,:,:,iobs), zweigv, zobsmasku )
-
-         ENDIF
-
-         ! Ensure that the vertical mask on u and v are consistent.
-
-         zobsmask(:) = MIN( zobsmasku(:), zobsmaskv(:) )
-
-         IF ( prodatqc%npvend(jobs,1) > 0 ) THEN
-
-            zobsk(:) = obfillflt
-
-	    IF ( ld_dailyav ) THEN
-
-               IF ( idayend == 0 )  THEN
-                  
-                  ! Daily averaged data
-                  
-                  CALL obs_int_h2d( kpk, kpk,      &
-                     &              zweigu, zinmu(:,:,:,iobs), zobsk )
-                  
-                  
-               ELSE
-               
-                  CALL ctl_stop( ' A nonzero' //     &
-                     &           ' number of U profile data should' // &
-                     &           ' only occur at the end of a given day' )
-
-               ENDIF
-	       
-            ELSE 
-               
-               ! Point data
-
-               CALL obs_int_h2d( kpk, kpk,      &
-                  &              zweigu, zintu(:,:,:,iobs), zobsk )
-
-            ENDIF
-
-            !-------------------------------------------------------------
-            ! Compute vertical second-derivative of the interpolating 
-            ! polynomial at obs points
-            !-------------------------------------------------------------
-            
-            IF ( k1dint == 1 ) THEN
-               CALL obs_int_z1d_spl( kpk, zobsk, zobs2k,   &
-                  &                  pgdept, zobsmask )
-            ENDIF
-            
-            !-----------------------------------------------------------------
-            !  Vertical interpolation to the observation point
-            !-----------------------------------------------------------------
-            ista = prodatqc%npvsta(jobs,1)
-            iend = prodatqc%npvend(jobs,1)
-            CALL obs_int_z1d( kpk,                &
-               & prodatqc%var(1)%mvk(ista:iend),  &
-               & k1dint, iend - ista + 1,         &
-               & prodatqc%var(1)%vdep(ista:iend), &
-               & zobsk, zobs2k,                   &
-               & prodatqc%var(1)%vmod(ista:iend), &
-               & pgdept, zobsmask )
-
-         ENDIF
-
-         IF ( prodatqc%npvend(jobs,2) > 0 ) THEN
-
-            zobsk(:) = obfillflt
-
-            IF ( ld_dailyav ) THEN
-
-               IF ( idayend == 0 )  THEN
-
-                  ! Daily averaged data
-                  
-                  CALL obs_int_h2d( kpk, kpk,      &
-                     &              zweigv, zinmv(:,:,:,iobs), zobsk )
-                  
-               ELSE
-
-                  CALL ctl_stop( ' A nonzero' //     &
-                     &           ' number of V profile data should' // &
-                     &           ' only occur at the end of a given day' )
-
-               ENDIF
-
-            ELSE
-               
-               ! Point data
-
-               CALL obs_int_h2d( kpk, kpk,      &
-                  &              zweigv, zintv(:,:,:,iobs), zobsk )
-
-            ENDIF
-
-
-            !-------------------------------------------------------------
-            ! Compute vertical second-derivative of the interpolating 
-            ! polynomial at obs points
-            !-------------------------------------------------------------
-            
-            IF ( k1dint == 1 ) THEN
-               CALL obs_int_z1d_spl( kpk, zobsk, zobs2k, &
-                  &                  pgdept, zobsmask )
-            ENDIF
-            
-            !----------------------------------------------------------------
-            !  Vertical interpolation to the observation point
-            !----------------------------------------------------------------
-            ista = prodatqc%npvsta(jobs,2)
-            iend = prodatqc%npvend(jobs,2)
-            CALL obs_int_z1d( kpk, &
-               & prodatqc%var(2)%mvk(ista:iend),&
-               & k1dint, iend - ista + 1, &
-               & prodatqc%var(2)%vdep(ista:iend),&
-               & zobsk, zobs2k, &
-               & prodatqc%var(2)%vmod(ista:iend),&
-               & pgdept, zobsmask )
-
-         ENDIF
-
-      END DO
- 
-      ! Deallocate the data for interpolation
-      DEALLOCATE( &
-         & igrdiu, &
-         & igrdju, &
-         & igrdiv, &
-         & igrdjv, &
-         & zglamu, zglamv, &
-         & zgphiu, zgphiv, &
-         & zumask, zvmask, &
-         & zintu, &
-         & zintv  &
-         & )
-      ! At the end of the day also get interpolated means
-      IF ( idayend == 0 ) THEN
-         DEALLOCATE( &
-            & zinmu,  &
-            & zinmv   &
-            & )
-      ENDIF
-
-      prodatqc%nprofup = prodatqc%nprofup + ipro 
-      
-   END SUBROUTINE obs_vel_opt
+
+      surfdataqc%nsurfup = surfdataqc%nsurfup + isurf
+
+   END SUBROUTINE obs_surf_opt
 
 END MODULE obs_oper
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prep.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prep.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prep.F90	(revision 10247)
@@ -7,12 +7,9 @@
 
    !!---------------------------------------------------------------------
-   !!   obs_pre_pro  : First level check and screening of T/S profiles
-   !!   obs_pre_sla  : First level check and screening of SLA observations
-   !!   obs_pre_sst  : First level check and screening of SLA observations
-   !!   obs_pre_seaice : First level check and screening of sea ice observations
-   !!   obs_pre_vel  : First level check and screening of velocity obs.
-   !!   obs_scr      : Basic screening of the observations
-   !!   obs_coo_tim  : Compute number of time steps to the observation time
-   !!   obs_sor      : Sort the observation arrays
+   !!   obs_pre_prof  : First level check and screening of profile observations
+   !!   obs_pre_surf  : First level check and screening of surface observations
+   !!   obs_scr       : Basic screening of the observations
+   !!   obs_coo_tim   : Compute number of time steps to the observation time
+   !!   obs_sor       : Sort the observation arrays
    !!---------------------------------------------------------------------
    !! * Modules used
@@ -27,4 +24,8 @@
    USE obs_inter_sup      ! Interpolation support
    USE obs_oper           ! Observation operators
+#if defined key_bdy
+   USE bdy_oce, ONLY : &        ! Boundary information
+      idx_bdy, nb_bdy
+#endif
    USE lib_mpp, ONLY : &
       & ctl_warn, ctl_stop
@@ -36,10 +37,7 @@
 
    PUBLIC &
-      & obs_pre_pro, &    ! First level check and screening of profiles
-      & obs_pre_sla, &    ! First level check and screening of SLA data
-      & obs_pre_sst, &    ! First level check and screening of SLA data
-      & obs_pre_seaice, & ! First level check and screening of sea ice data
-      & obs_pre_vel, &     ! First level check and screening of velocity profiles
-      & calc_month_len     ! Calculate the number of days in the months of a year  
+      & obs_pre_prof, &    ! First level check and screening of profile obs
+      & obs_pre_surf, &    ! First level check and screening of surface obs
+      & calc_month_len     ! Calculate the number of days in the months of a year
 
    !!----------------------------------------------------------------------
@@ -49,299 +47,17 @@
    !!----------------------------------------------------------------------
 
+!! * Substitutions 
+#  include "domzgr_substitute.h90"  
+
 CONTAINS
 
-   SUBROUTINE obs_pre_pro( profdata, prodatqc, ld_t3d, ld_s3d, ld_nea, &
-      &                    kdailyavtypes )
-      !!----------------------------------------------------------------------
-      !!                    ***  ROUTINE obs_pre_pro  ***
-      !!
-      !! ** Purpose : First level check and screening of T and S profiles
-      !!
-      !! ** Method  : First level check and screening of T and S profiles
-      !!
-      !! ** Action  : 
-      !!
-      !! References :
-      !!   
-      !! History :
-      !!        !  2007-01  (K. Mogensen) Merge of obs_pre_t3d and obs_pre_s3d 
-      !!        !  2007-03  (K. Mogensen) General handling of profiles
-      !!        !  2007-06  (K. Mogensen et al) Reject obs. near land.
-      !!----------------------------------------------------------------------
-      !! * Modules used
-      USE domstp              ! Domain: set the time-step
-      USE par_oce             ! Ocean parameters
-      USE dom_oce, ONLY : &   ! Geographical information
-         & glamt,   &
-         & gphit,   &
-         & gdept_1d,&
-         & tmask,   &
-         & nproc
-      !! * Arguments
-      TYPE(obs_prof), INTENT(INOUT) :: profdata     ! Full set of profile data
-      TYPE(obs_prof), INTENT(INOUT) :: prodatqc     ! Subset of profile data not failing screening
-      LOGICAL, INTENT(IN) :: ld_t3d         ! Switch for temperature
-      LOGICAL, INTENT(IN) :: ld_s3d         ! Switch for salinity
-      LOGICAL, INTENT(IN) :: ld_nea         ! Switch for rejecting observation near land
-      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: &
-         & kdailyavtypes! Types for daily averages
-      !! * Local declarations   
-      INTEGER :: iyea0         ! Initial date
-      INTEGER :: imon0         !  - (year, month, day, hour, minute)
-      INTEGER :: iday0   
-      INTEGER :: ihou0
-      INTEGER :: imin0
-      INTEGER :: icycle        ! Current assimilation cycle
-                               ! Counters for observations that
-      INTEGER :: iotdobs       !  - outside time domain
-      INTEGER :: iosdtobs      !  - outside space domain (temperature)
-      INTEGER :: iosdsobs      !  - outside space domain (salinity)
-      INTEGER :: ilantobs      !  - within a model land cell (temperature)
-      INTEGER :: ilansobs      !  - within a model land cell (salinity)
-      INTEGER :: inlatobs      !  - close to land (temperature)
-      INTEGER :: inlasobs      !  - close to land (salinity)
-      INTEGER :: igrdobs       !  - fail the grid search
-                               ! Global counters for observations that
-      INTEGER :: iotdobsmpp    !  - outside time domain
-      INTEGER :: iosdtobsmpp   !  - outside space domain (temperature)
-      INTEGER :: iosdsobsmpp   !  - outside space domain (salinity)
-      INTEGER :: ilantobsmpp   !  - within a model land cell (temperature)
-      INTEGER :: ilansobsmpp   !  - within a model land cell (salinity)
-      INTEGER :: inlatobsmpp   !  - close to land (temperature)
-      INTEGER :: inlasobsmpp   !  - close to land (salinity)
-      INTEGER :: igrdobsmpp    !  - fail the grid search
-      TYPE(obs_prof_valid) ::  llvalid     ! Profile selection 
-      TYPE(obs_prof_valid), DIMENSION(profdata%nvar) :: &
-         & llvvalid            ! T,S selection 
-      INTEGER :: jvar          ! Variable loop variable
-      INTEGER :: jobs          ! Obs. loop variable
-      INTEGER :: jstp          ! Time loop variable
-      INTEGER :: inrc          ! Time index variable
-      
-      IF(lwp) WRITE(numout,*)'obs_pre_pro : Preparing the profile observations...'
-
-      ! Initial date initialization (year, month, day, hour, minute)
-      iyea0 =   ndate0 / 10000
-      imon0 = ( ndate0 - iyea0 * 10000 ) / 100
-      iday0 =   ndate0 - iyea0 * 10000 - imon0 * 100
-      ihou0 = 0
-      imin0 = 0
-
-      icycle = no     ! Assimilation cycle
-
-      ! Diagnotics counters for various failures.
-
-      iotdobs  = 0
-      igrdobs  = 0
-      iosdtobs = 0
-      iosdsobs = 0
-      ilantobs = 0
-      ilansobs = 0
-      inlatobs = 0
-      inlasobs = 0
-
-      ! -----------------------------------------------------------------------
-      ! Find time coordinate for profiles
-      ! -----------------------------------------------------------------------
-
-      IF ( PRESENT(kdailyavtypes) ) THEN
-         CALL obs_coo_tim_prof( icycle, &
-            &                iyea0,   imon0,   iday0,   ihou0,   imin0,      &
-            &                profdata%nprof,   profdata%nyea, profdata%nmon, &
-            &                profdata%nday,    profdata%nhou, profdata%nmin, &
-            &                profdata%ntyp,    profdata%nqc,  profdata%mstp, &
-            &                iotdobs, kdailyavtypes = kdailyavtypes        )
-      ELSE
-         CALL obs_coo_tim_prof( icycle, &
-            &                iyea0,   imon0,   iday0,   ihou0,   imin0,      &
-            &                profdata%nprof,   profdata%nyea, profdata%nmon, &
-            &                profdata%nday,    profdata%nhou, profdata%nmin, &
-            &                profdata%ntyp,    profdata%nqc,  profdata%mstp, &
-            &                iotdobs )
-      ENDIF
-      CALL obs_mpp_sum_integer( iotdobs, iotdobsmpp )
-      
-      ! -----------------------------------------------------------------------
-      ! Check for profiles failing the grid search
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_grd( profdata%nprof,   profdata%mi, profdata%mj, &
-         &              profdata%nqc,     igrdobs                         )
-
-      CALL obs_mpp_sum_integer( igrdobs, igrdobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Reject all observations for profiles with nqc > 10
-      ! -----------------------------------------------------------------------
-
-      CALL obs_pro_rej( profdata )
-
-      ! -----------------------------------------------------------------------
-      ! Check for land points. This includes points below the model
-      ! bathymetry so this is done for every point in the profile
-      ! -----------------------------------------------------------------------
-
-      ! Temperature
-
-      CALL obs_coo_spc_3d( profdata%nprof,        profdata%nvprot(1),   &
-         &                 profdata%npvsta(:,1),  profdata%npvend(:,1), &
-         &                 jpi,                   jpj,                  &
-         &                 jpk,                                         &
-         &                 profdata%mi,           profdata%mj,          & 
-         &                 profdata%var(1)%mvk,                         &
-         &                 profdata%rlam,         profdata%rphi,        &
-         &                 profdata%var(1)%vdep,                        &
-         &                 glamt,                 gphit,                &
-         &                 gdept_1d,              tmask,                &
-         &                 profdata%nqc,          profdata%var(1)%nvqc, &
-         &                 iosdtobs,              ilantobs,             &
-         &                 inlatobs,              ld_nea                )
-
-      CALL obs_mpp_sum_integer( iosdtobs, iosdtobsmpp )
-      CALL obs_mpp_sum_integer( ilantobs, ilantobsmpp )
-      CALL obs_mpp_sum_integer( inlatobs, inlatobsmpp )
-
-      ! Salinity
-
-      CALL obs_coo_spc_3d( profdata%nprof,        profdata%nvprot(2),   &
-         &                 profdata%npvsta(:,2),  profdata%npvend(:,2), &
-         &                 jpi,                   jpj,                  &
-         &                 jpk,                                         &
-         &                 profdata%mi,           profdata%mj,          & 
-         &                 profdata%var(2)%mvk,                         &
-         &                 profdata%rlam,         profdata%rphi,        &
-         &                 profdata%var(2)%vdep,                        &
-         &                 glamt,                 gphit,                &
-         &                 gdept_1d,              tmask,                &
-         &                 profdata%nqc,          profdata%var(2)%nvqc, &
-         &                 iosdsobs,              ilansobs,             &
-         &                 inlasobs,              ld_nea                )
-
-      CALL obs_mpp_sum_integer( iosdsobs, iosdsobsmpp )
-      CALL obs_mpp_sum_integer( ilansobs, ilansobsmpp )
-      CALL obs_mpp_sum_integer( inlasobs, inlasobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Copy useful data from the profdata data structure to
-      ! the prodatqc data structure 
-      ! -----------------------------------------------------------------------
-
-      ! Allocate the selection arrays
-
-      ALLOCATE( llvalid%luse(profdata%nprof) )
-      DO jvar = 1,profdata%nvar
-         ALLOCATE( llvvalid(jvar)%luse(profdata%nvprot(jvar)) )
-      END DO
-
-      ! We want all data which has qc flags <= 10
-
-      llvalid%luse(:) = ( profdata%nqc(:)  <= 10 )
-      DO jvar = 1,profdata%nvar
-         llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= 10 )
-      END DO
-
-      ! The actual copying
-
-      CALL obs_prof_compress( profdata,     prodatqc,       .TRUE.,  numout, &
-         &                    lvalid=llvalid, lvvalid=llvvalid )
-
-      ! Dellocate the selection arrays
-      DEALLOCATE( llvalid%luse )
-      DO jvar = 1,profdata%nvar
-         DEALLOCATE( llvvalid(jvar)%luse )
-      END DO
-
-      ! -----------------------------------------------------------------------
-      ! Print information about what observations are left after qc
-      ! -----------------------------------------------------------------------
-
-      ! Update the total observation counter array
-      
-      IF(lwp) THEN
-         WRITE(numout,*)
-         WRITE(numout,*) 'obs_pre_pro :'
-         WRITE(numout,*) '~~~~~~~~~~~'
-         WRITE(numout,*)
-         WRITE(numout,*) ' Profiles outside time domain                = ', &
-            &            iotdobsmpp
-         WRITE(numout,*) ' Remaining profiles that failed grid search  = ', &
-            &            igrdobsmpp
-         WRITE(numout,*) ' Remaining T data outside space domain       = ', &
-            &            iosdtobsmpp
-         WRITE(numout,*) ' Remaining T data at land points             = ', &
-            &            ilantobsmpp
-         IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining T data near land points (removed) = ',&
-               &            inlatobsmpp
-         ELSE
-            WRITE(numout,*) ' Remaining T data near land points (kept)    = ',&
-               &            inlatobsmpp
-         ENDIF
-         WRITE(numout,*) ' T data accepted                             = ', &
-            &            prodatqc%nvprotmpp(1)
-         WRITE(numout,*) ' Remaining S data outside space domain       = ', &
-            &            iosdsobsmpp
-         WRITE(numout,*) ' Remaining S data at land points             = ', &
-            &            ilansobsmpp
-         IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining S data near land points (removed) = ',&
-               &            inlasobsmpp
-         ELSE
-            WRITE(numout,*) ' Remaining S data near land points (kept)    = ',&
-               &            inlasobsmpp
-         ENDIF
-         WRITE(numout,*) ' S data accepted                             = ', &
-            &            prodatqc%nvprotmpp(2)
-
-         WRITE(numout,*)
-         WRITE(numout,*) ' Number of observations per time step :'
-         WRITE(numout,*)
-         WRITE(numout,997)
-         WRITE(numout,998)
-      ENDIF
-      
-      DO jobs = 1, prodatqc%nprof
-         inrc = prodatqc%mstp(jobs) + 2 - nit000
-         prodatqc%npstp(inrc)  = prodatqc%npstp(inrc) + 1
-         DO jvar = 1, prodatqc%nvar
-            IF ( prodatqc%npvend(jobs,jvar) > 0 ) THEN
-               prodatqc%nvstp(inrc,jvar) = prodatqc%nvstp(inrc,jvar) + &
-                  &                      ( prodatqc%npvend(jobs,jvar) - &
-                  &                        prodatqc%npvsta(jobs,jvar) + 1 )
-            ENDIF
-         END DO
-      END DO
-      
-      
-      CALL obs_mpp_sum_integers( prodatqc%npstp, prodatqc%npstpmpp, &
-         &                       nitend - nit000 + 2 )
-      DO jvar = 1, prodatqc%nvar
-         CALL obs_mpp_sum_integers( prodatqc%nvstp(:,jvar), &
-            &                       prodatqc%nvstpmpp(:,jvar), &
-            &                       nitend - nit000 + 2 )
-      END DO
-
-      IF ( lwp ) THEN
-         DO jstp = nit000 - 1, nitend
-            inrc = jstp - nit000 + 2
-            WRITE(numout,999) jstp, prodatqc%npstpmpp(inrc), &
-               &                    prodatqc%nvstpmpp(inrc,1), &
-               &                    prodatqc%nvstpmpp(inrc,2)
-         END DO
-      ENDIF
-
-997   FORMAT(10X,'Time step',5X,'Profiles',5X,'Temperature',5X,'Salinity')
-998   FORMAT(10X,'---------',5X,'--------',5X,'-----------',5X,'--------')
-999   FORMAT(10X,I9,5X,I8,5X,I11,5X,I8)
-      
-   END SUBROUTINE obs_pre_pro
-
-   SUBROUTINE obs_pre_sla( sladata, sladatqc, ld_sla, ld_nea )
+   SUBROUTINE obs_pre_surf( surfdata, surfdataqc, ld_nea, ld_bound_reject, &
+                            kqc_cutoff )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE obs_pre_sla  ***
       !!
-      !! ** Purpose : First level check and screening of SLA observations
-      !!
-      !! ** Method  : First level check and screening of SLA observations
+      !! ** Purpose : First level check and screening of surface observations
+      !!
+      !! ** Method  : First level check and screening of surface observations
       !!
       !! ** Action  : 
@@ -352,4 +68,5 @@
       !!        !  2007-03  (A. Weaver, K. Mogensen) Original
       !!        !  2007-06  (K. Mogensen et al) Reject obs. near land.
+      !!        !  2015-02  (M. Martin) Combined routine for surface types.
       !!----------------------------------------------------------------------
       !! * Modules used
@@ -362,9 +79,11 @@
          & nproc
       !! * Arguments
-      TYPE(obs_surf), INTENT(INOUT) :: sladata    ! Full set of SLA data
-      TYPE(obs_surf), INTENT(INOUT) :: sladatqc   ! Subset of SLA data not failing screening
-      LOGICAL, INTENT(IN) :: ld_sla         ! Switch for SLA data
-      LOGICAL, INTENT(IN) :: ld_nea         ! Switch for rejecting observation near land
+      TYPE(obs_surf), INTENT(INOUT) :: surfdata    ! Full set of surface data
+      TYPE(obs_surf), INTENT(INOUT) :: surfdataqc  ! Subset of surface data not failing screening
+      LOGICAL, INTENT(IN) :: ld_nea                ! Switch for rejecting observation near land
+      LOGICAL, INTENT(IN) :: ld_bound_reject       ! Switch for rejecting obs near the boundary
+      INTEGER, INTENT(IN), OPTIONAL :: kqc_cutoff   ! cut off for QC value
       !! * Local declarations
+      INTEGER :: iqc_cutoff = 255   ! cut off for QC value
       INTEGER :: iyea0        ! Initial date
       INTEGER :: imon0        !  - (year, month, day, hour, minute)
@@ -379,4 +98,5 @@
       INTEGER :: inlasobs     !  - close to land
       INTEGER :: igrdobs      !  - fail the grid search
+      INTEGER :: ibdysobs     !  - close to open boundary
                               ! Global counters for observations that
       INTEGER :: iotdobsmpp     !  - outside time domain
@@ -385,4 +105,5 @@
       INTEGER :: inlasobsmpp    !  - close to land
       INTEGER :: igrdobsmpp     !  - fail the grid search
+      INTEGER :: ibdysobsmpp  !  - close to open boundary
       LOGICAL, DIMENSION(:), ALLOCATABLE :: & 
          & llvalid            ! SLA data selection
@@ -391,6 +112,7 @@
       INTEGER :: inrc         ! Time index variable
 
-      IF(lwp) WRITE(numout,*)'obs_pre_sla : Preparing the SLA observations...'
-
+      IF(lwp) WRITE(numout,*)'obs_pre_surf : Preparing the surface observations...'
+      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+      
       ! Initial date initialization (year, month, day, hour, minute)
       iyea0 =   ndate0 / 10000
@@ -409,23 +131,27 @@
       ilansobs = 0
       inlasobs = 0
-
-      ! -----------------------------------------------------------------------
-      ! Find time coordinate for SLA data
+      ibdysobs = 0 
+
+      ! Set QC cutoff to optional value if provided
+      IF ( PRESENT(kqc_cutoff) ) iqc_cutoff=kqc_cutoff
+
+      ! -----------------------------------------------------------------------
+      ! Find time coordinate for surface data
       ! -----------------------------------------------------------------------
 
       CALL obs_coo_tim( icycle, &
          &              iyea0,   imon0,   iday0,   ihou0,   imin0,      &
-         &              sladata%nsurf,   sladata%nyea, sladata%nmon, &
-         &              sladata%nday,    sladata%nhou, sladata%nmin, &
-         &              sladata%nqc,     sladata%mstp, iotdobs        )
+         &              surfdata%nsurf,   surfdata%nyea, surfdata%nmon, &
+         &              surfdata%nday,    surfdata%nhou, surfdata%nmin, &
+         &              surfdata%nqc,     surfdata%mstp, iotdobs        )
 
       CALL obs_mpp_sum_integer( iotdobs, iotdobsmpp )
       
       ! -----------------------------------------------------------------------
-      ! Check for SLA data failing the grid search
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_grd( sladata%nsurf,   sladata%mi, sladata%mj, &
-         &              sladata%nqc,     igrdobs                         )
+      ! Check for surface data failing the grid search
+      ! -----------------------------------------------------------------------
+
+      CALL obs_coo_grd( surfdata%nsurf,   surfdata%mi, surfdata%mj, &
+         &              surfdata%nqc,     igrdobs                         )
 
       CALL obs_mpp_sum_integer( igrdobs, igrdobsmpp )
@@ -435,33 +161,36 @@
       ! -----------------------------------------------------------------------
 
-      CALL obs_coo_spc_2d( sladata%nsurf,              &
+      CALL obs_coo_spc_2d( surfdata%nsurf,              &
          &                 jpi,          jpj,          &
-         &                 sladata%mi,   sladata%mj,   & 
-         &                 sladata%rlam, sladata%rphi, &
+         &                 surfdata%mi,   surfdata%mj,   & 
+         &                 surfdata%rlam, surfdata%rphi, &
          &                 glamt,        gphit,        &
-         &                 tmask(:,:,1), sladata%nqc,  &
+         &                 tmask(:,:,1), surfdata%nqc,  &
          &                 iosdsobs,     ilansobs,     &
-         &                 inlasobs,     ld_nea        )
+         &                 inlasobs,     ld_nea,       &
+         &                 ibdysobs,     ld_bound_reject, &
+         &                 iqc_cutoff                     )
 
       CALL obs_mpp_sum_integer( iosdsobs, iosdsobsmpp )
       CALL obs_mpp_sum_integer( ilansobs, ilansobsmpp )
       CALL obs_mpp_sum_integer( inlasobs, inlasobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Copy useful data from the sladata data structure to
-      ! the sladatqc data structure 
+      CALL obs_mpp_sum_integer( ibdysobs, ibdysobsmpp )
+
+      ! -----------------------------------------------------------------------
+      ! Copy useful data from the surfdata data structure to
+      ! the surfdataqc data structure 
       ! -----------------------------------------------------------------------
 
       ! Allocate the selection arrays
 
-      ALLOCATE( llvalid(sladata%nsurf) )
-      
-      ! We want all data which has qc flags <= 10
-
-      llvalid(:)  = ( sladata%nqc(:)  <= 10 )
+      ALLOCATE( llvalid(surfdata%nsurf) )
+      
+      ! We want all data which has qc flags <= iqc_cutoff
+
+      llvalid(:)  = ( surfdata%nqc(:)  <= iqc_cutoff )
 
       ! The actual copying
 
-      CALL obs_surf_compress( sladata,     sladatqc,       .TRUE.,  numout, &
+      CALL obs_surf_compress( surfdata,     surfdataqc,       .TRUE.,  numout, &
          &                    lvalid=llvalid )
 
@@ -477,38 +206,38 @@
       IF(lwp) THEN
          WRITE(numout,*)
-         WRITE(numout,*) 'obs_pre_sla :'
-         WRITE(numout,*) '~~~~~~~~~~~'
-         WRITE(numout,*)
-         WRITE(numout,*) ' SLA data outside time domain                  = ', &
+         WRITE(numout,*) ' '//surfdataqc%cvars(1)//' data outside time domain                  = ', &
             &            iotdobsmpp
-         WRITE(numout,*) ' Remaining SLA data that failed grid search    = ', &
+         WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data that failed grid search    = ', &
             &            igrdobsmpp
-         WRITE(numout,*) ' Remaining SLA data outside space domain       = ', &
+         WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data outside space domain       = ', &
             &            iosdsobsmpp
-         WRITE(numout,*) ' Remaining SLA data at land points             = ', &
+         WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data at land points             = ', &
             &            ilansobsmpp
          IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining SLA data near land points (removed) = ', &
+            WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data near land points (removed) = ', &
                &            inlasobsmpp
          ELSE
-            WRITE(numout,*) ' Remaining SLA data near land points (kept)    = ', &
+            WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data near land points (kept)    = ', &
                &            inlasobsmpp
          ENDIF
-         WRITE(numout,*) ' SLA data accepted                             = ', &
-            &            sladatqc%nsurfmpp
+         WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data near open boundary (removed) = ', &
+            &            ibdysobsmpp  
+         WRITE(numout,*) ' '//surfdataqc%cvars(1)//' data accepted                             = ', &
+            &            surfdataqc%nsurfmpp
 
          WRITE(numout,*)
          WRITE(numout,*) ' Number of observations per time step :'
          WRITE(numout,*)
-         WRITE(numout,1997)
-         WRITE(numout,1998)
+         WRITE(numout,'(10X,A,10X,A)')'Time step',surfdataqc%cvars(1)
+         WRITE(numout,'(10X,A,5X,A)')'---------','-----------------'
+         CALL FLUSH(numout)
       ENDIF
       
-      DO jobs = 1, sladatqc%nsurf
-         inrc = sladatqc%mstp(jobs) + 2 - nit000
-         sladatqc%nsstp(inrc)  = sladatqc%nsstp(inrc) + 1
-      END DO
-      
-      CALL obs_mpp_sum_integers( sladatqc%nsstp, sladatqc%nsstpmpp, &
+      DO jobs = 1, surfdataqc%nsurf
+         inrc = surfdataqc%mstp(jobs) + 2 - nit000
+         surfdataqc%nsstp(inrc)  = surfdataqc%nsstp(inrc) + 1
+      END DO
+      
+      CALL obs_mpp_sum_integers( surfdataqc%nsstp, surfdataqc%nsstpmpp, &
          &                       nitend - nit000 + 2 )
 
@@ -516,28 +245,32 @@
          DO jstp = nit000 - 1, nitend
             inrc = jstp - nit000 + 2
-            WRITE(numout,1999) jstp, sladatqc%nsstpmpp(inrc)
+            WRITE(numout,1999) jstp, surfdataqc%nsstpmpp(inrc)
+            CALL FLUSH(numout)
          END DO
       ENDIF
 
-1997  FORMAT(10X,'Time step',5X,'Sea level anomaly')
-1998  FORMAT(10X,'---------',5X,'-----------------')
 1999  FORMAT(10X,I9,5X,I17)
 
-   END SUBROUTINE obs_pre_sla
-
-   SUBROUTINE obs_pre_sst( sstdata, sstdatqc, ld_sst, ld_nea )
-      !!----------------------------------------------------------------------
-      !!                    ***  ROUTINE obs_pre_sst  ***
-      !!
-      !! ** Purpose : First level check and screening of SST observations
-      !!
-      !! ** Method  : First level check and screening of SST observations
-      !!
-      !! ** Action  : 
-      !!
-      !! References :
-      !!   
+   END SUBROUTINE obs_pre_surf
+
+
+   SUBROUTINE obs_pre_prof( profdata, prodatqc, ld_var, &
+      &                     kpi, kpj, kpk, &
+      &                     zmask, pglam, pgphi,  &
+      &                     ld_nea, ld_bound_reject, kdailyavtypes,  kqc_cutoff )
+
+!!----------------------------------------------------------------------
+      !!                    ***  ROUTINE obs_pre_prof  ***
+      !!
+      !! ** Purpose : First level check and screening of profiles
+      !!
+      !! ** Method  : First level check and screening of profiles
+      !!
       !! History :
-      !!        !  2007-03  (S. Ricci) SST data preparation 
+      !!        !  2007-06  (K. Mogensen) original : T and S profile data
+      !!        !  2008-09  (M. Valdivieso) : TAO velocity data
+      !!        !  2009-01  (K. Mogensen) : New feedback stricture
+      !!        !  2015-02  (M. Martin) : Combined profile routine.
+      !!
       !!----------------------------------------------------------------------
       !! * Modules used
@@ -545,39 +278,62 @@
       USE par_oce             ! Ocean parameters
       USE dom_oce, ONLY : &   ! Geographical information
-         & glamt,   &
-         & gphit,   &
-         & tmask,   &
+         & gdept_1d,             &
          & nproc
+
       !! * Arguments
-      TYPE(obs_surf), INTENT(INOUT) :: sstdata     ! Full set of SST data
-      TYPE(obs_surf), INTENT(INOUT) :: sstdatqc    ! Subset of SST data not failing screening
-      LOGICAL :: ld_sst             ! Switch for SST data
-      LOGICAL :: ld_nea             ! Switch for rejecting observation near land
+      TYPE(obs_prof), INTENT(INOUT) :: profdata   ! Full set of profile data
+      TYPE(obs_prof), INTENT(INOUT) :: prodatqc   ! Subset of profile data not failing screening
+      LOGICAL, DIMENSION(profdata%nvar), INTENT(IN) :: &
+         & ld_var                                 ! Observed variables switches
+      LOGICAL, INTENT(IN) :: ld_nea               ! Switch for rejecting observation near land
+      LOGICAL, INTENT(IN) :: ld_bound_reject      ! Switch for rejecting observations near the boundary
+      INTEGER, INTENT(IN) :: kpi, kpj, kpk        ! Local domain sizes
+      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: &
+         & kdailyavtypes                          ! Types for daily averages
+      REAL(wp), INTENT(IN), DIMENSION(kpi,kpj,kpk,profdata%nvar) :: &
+         & zmask
+      REAL(wp), INTENT(IN), DIMENSION(kpi,kpj,profdata%nvar) :: &
+         & pglam, &
+         & pgphi
+      INTEGER, INTENT(IN), OPTIONAL :: kqc_cutoff   ! cut off for QC value
+
       !! * Local declarations
+      INTEGER :: iqc_cutoff = 255   ! cut off for QC value
       INTEGER :: iyea0        ! Initial date
       INTEGER :: imon0        !  - (year, month, day, hour, minute)
-      INTEGER :: iday0   
+      INTEGER :: iday0    
       INTEGER :: ihou0    
       INTEGER :: imin0
       INTEGER :: icycle       ! Current assimilation cycle
-                              ! Counters for observations that
-      INTEGER :: iotdobs      !  - outside time domain
-      INTEGER :: iosdsobs     !  - outside space domain
-      INTEGER :: ilansobs     !  - within a model land cell
-      INTEGER :: inlasobs     !  - close to land
-      INTEGER :: igrdobs      !  - fail the grid search
-                              ! Global counters for observations that
-      INTEGER :: iotdobsmpp   !  - outside time domain
-      INTEGER :: iosdsobsmpp  !  - outside space domain
-      INTEGER :: ilansobsmpp  !  - within a model land cell
-      INTEGER :: inlasobsmpp  !  - close to land
-      INTEGER :: igrdobsmpp   !  - fail the grid search
-      LOGICAL, DIMENSION(:), ALLOCATABLE :: & 
-         & llvalid            ! SST data selection
+                                                       ! Counters for observations that are
+      INTEGER                           :: iotdobs     !  - outside time domain
+      INTEGER, DIMENSION(profdata%nvar) :: iosdvobs    !  - outside space domain
+      INTEGER, DIMENSION(profdata%nvar) :: ilanvobs    !  - within a model land cell
+      INTEGER, DIMENSION(profdata%nvar) :: inlavobs    !  - close to land
+      INTEGER, DIMENSION(profdata%nvar) :: ibdyvobs    !  - boundary   
+      INTEGER                           :: igrdobs     !  - fail the grid search
+      INTEGER                           :: iuvchku     !  - reject UVEL if VVEL rejected
+      INTEGER                           :: iuvchkv     !  - reject VVEL if UVEL rejected
+                                                       ! Global counters for observations that are
+      INTEGER                           :: iotdobsmpp  !  - outside time domain
+      INTEGER, DIMENSION(profdata%nvar) :: iosdvobsmpp !  - outside space domain
+      INTEGER, DIMENSION(profdata%nvar) :: ilanvobsmpp !  - within a model land cell
+      INTEGER, DIMENSION(profdata%nvar) :: inlavobsmpp !  - close to land
+      INTEGER, DIMENSION(profdata%nvar) :: ibdyvobsmpp !  - boundary
+      INTEGER :: igrdobsmpp                            !  - fail the grid search
+      INTEGER :: iuvchkumpp                            !  - reject UVEL if VVEL rejected
+      INTEGER :: iuvchkvmpp                            !  - reject VVEL if UVEL rejected
+      TYPE(obs_prof_valid) ::  llvalid      ! Profile selection 
+      TYPE(obs_prof_valid), DIMENSION(profdata%nvar) :: &
+         & llvvalid           ! vars selection 
+      INTEGER :: jvar         ! Variable loop variable
       INTEGER :: jobs         ! Obs. loop variable
       INTEGER :: jstp         ! Time loop variable
       INTEGER :: inrc         ! Time index variable
-
-      IF(lwp) WRITE(numout,*)'obs_pre_sst : Preparing the SST observations...'
+      CHARACTER(LEN=256) :: cout1  ! Diagnostic output line
+      CHARACTER(LEN=256) :: cout2  ! Diagnostic output line
+
+      IF(lwp) WRITE(numout,*)'obs_pre_prof: Preparing the profile data...'
+      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
 
       ! Initial date initialization (year, month, day, hour, minute)
@@ -590,429 +346,58 @@
       icycle = no     ! Assimilation cycle
 
-      ! Diagnotics counters for various failures.
-
-      iotdobs  = 0
-      igrdobs  = 0
-      iosdsobs = 0
-      ilansobs = 0
-      inlasobs = 0
-
-      ! -----------------------------------------------------------------------
-      ! Find time coordinate for SST data
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_tim( icycle, &
-         &              iyea0,   imon0,   iday0,   ihou0,   imin0,      &
-         &              sstdata%nsurf,   sstdata%nyea, sstdata%nmon, &
-         &              sstdata%nday,    sstdata%nhou, sstdata%nmin, &
-         &              sstdata%nqc,     sstdata%mstp, iotdobs        )
+      ! Diagnostics counters for various failures.
+
+      iotdobs     = 0
+      igrdobs     = 0
+      iosdvobs(:) = 0
+      ilanvobs(:) = 0
+      inlavobs(:) = 0
+      ibdyvobs(:) = 0
+      iuvchku     = 0
+      iuvchkv     = 0
+
+
+      ! Set QC cutoff to optional value if provided
+      IF ( PRESENT(kqc_cutoff) ) iqc_cutoff=kqc_cutoff
+
+      ! -----------------------------------------------------------------------
+      ! Find time coordinate for profiles
+      ! -----------------------------------------------------------------------
+
+      IF ( PRESENT(kdailyavtypes) ) THEN
+         CALL obs_coo_tim_prof( icycle, &
+            &              iyea0,   imon0,   iday0,   ihou0,   imin0,      &
+            &              profdata%nprof,   profdata%nyea, profdata%nmon, &
+            &              profdata%nday,    profdata%nhou, profdata%nmin, &
+            &              profdata%ntyp,    profdata%nqc,  profdata%mstp, &
+            &              iotdobs, kdailyavtypes = kdailyavtypes,         &
+            &              kqc_cutoff = iqc_cutoff )
+      ELSE
+         CALL obs_coo_tim_prof( icycle, &
+            &              iyea0,   imon0,   iday0,   ihou0,   imin0,      &
+            &              profdata%nprof,   profdata%nyea, profdata%nmon, &
+            &              profdata%nday,    profdata%nhou, profdata%nmin, &
+            &              profdata%ntyp,    profdata%nqc,  profdata%mstp, &
+            &              iotdobs,          kqc_cutoff = iqc_cutoff )
+      ENDIF
+
       CALL obs_mpp_sum_integer( iotdobs, iotdobsmpp )
-      ! -----------------------------------------------------------------------
-      ! Check for SST data failing the grid search
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_grd( sstdata%nsurf,   sstdata%mi, sstdata%mj, &
-         &              sstdata%nqc,     igrdobs                         )
+      
+      ! -----------------------------------------------------------------------
+      ! Check for profiles failing the grid search
+      ! -----------------------------------------------------------------------
+
+      DO jvar = 1, profdata%nvar
+         CALL obs_coo_grd( profdata%nprof,   profdata%mi(:,jvar), profdata%mj(:,jvar), &
+            &              profdata%nqc,     igrdobs )
+      END DO
+
       CALL obs_mpp_sum_integer( igrdobs, igrdobsmpp )
 
       ! -----------------------------------------------------------------------
-      ! Check for land points. 
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_spc_2d( sstdata%nsurf,              &
-         &                 jpi,          jpj,          &
-         &                 sstdata%mi,   sstdata%mj,   & 
-         &                 sstdata%rlam, sstdata%rphi, &
-         &                 glamt,        gphit,        &
-         &                 tmask(:,:,1), sstdata%nqc,  &
-         &                 iosdsobs,     ilansobs,     &
-         &                 inlasobs,     ld_nea        )
-
-      CALL obs_mpp_sum_integer( iosdsobs, iosdsobsmpp )
-      CALL obs_mpp_sum_integer( ilansobs, ilansobsmpp )
-      CALL obs_mpp_sum_integer( inlasobs, inlasobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Copy useful data from the sstdata data structure to
-      ! the sstdatqc data structure 
-      ! -----------------------------------------------------------------------
-
-      ! Allocate the selection arrays
-
-      ALLOCATE( llvalid(sstdata%nsurf) )
-      
-      ! We want all data which has qc flags <= 0
-
-      llvalid(:)  = ( sstdata%nqc(:)  <= 10 )
-
-      ! The actual copying
-
-      CALL obs_surf_compress( sstdata,     sstdatqc,       .TRUE.,  numout, &
-         &                    lvalid=llvalid )
-
-      ! Dellocate the selection arrays
-      DEALLOCATE( llvalid )
-
-      ! -----------------------------------------------------------------------
-      ! Print information about what observations are left after qc
-      ! -----------------------------------------------------------------------
-
-      ! Update the total observation counter array
-      
-      IF(lwp) THEN
-         WRITE(numout,*)
-         WRITE(numout,*) 'obs_pre_sst :'
-         WRITE(numout,*) '~~~~~~~~~~~'
-         WRITE(numout,*)
-         WRITE(numout,*) ' SST data outside time domain                  = ', &
-            &            iotdobsmpp
-         WRITE(numout,*) ' Remaining SST data that failed grid search    = ', &
-            &            igrdobsmpp
-         WRITE(numout,*) ' Remaining SST data outside space domain       = ', &
-            &            iosdsobsmpp
-         WRITE(numout,*) ' Remaining SST data at land points             = ', &
-            &            ilansobsmpp
-         IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining SST data near land points (removed) = ', &
-               &            inlasobsmpp
-         ELSE
-            WRITE(numout,*) ' Remaining SST data near land points (kept)    = ', &
-               &            inlasobsmpp
-         ENDIF
-         WRITE(numout,*) ' SST data accepted                             = ', &
-            &            sstdatqc%nsurfmpp
-
-         WRITE(numout,*)
-         WRITE(numout,*) ' Number of observations per time step :'
-         WRITE(numout,*)
-         WRITE(numout,1997)
-         WRITE(numout,1998)
-      ENDIF
-      
-      DO jobs = 1, sstdatqc%nsurf
-         inrc = sstdatqc%mstp(jobs) + 2 - nit000
-         sstdatqc%nsstp(inrc)  = sstdatqc%nsstp(inrc) + 1
-      END DO
-      
-      CALL obs_mpp_sum_integers( sstdatqc%nsstp, sstdatqc%nsstpmpp, &
-         &                       nitend - nit000 + 2 )
-
-      IF ( lwp ) THEN
-         DO jstp = nit000 - 1, nitend
-            inrc = jstp - nit000 + 2
-            WRITE(numout,1999) jstp, sstdatqc%nsstpmpp(inrc)
-         END DO
-      ENDIF
-
-1997  FORMAT(10X,'Time step',5X,'Sea surface temperature')
-1998  FORMAT(10X,'---------',5X,'-----------------')
-1999  FORMAT(10X,I9,5X,I17)
-      
-   END SUBROUTINE obs_pre_sst
-
-   SUBROUTINE obs_pre_seaice( seaicedata, seaicedatqc, ld_seaice, ld_nea )
-      !!----------------------------------------------------------------------
-      !!                    ***  ROUTINE obs_pre_seaice  ***
-      !!
-      !! ** Purpose : First level check and screening of Sea Ice observations
-      !!
-      !! ** Method  : First level check and screening of Sea Ice observations
-      !!
-      !! ** Action  : 
-      !!
-      !! References :
-      !!   
-      !! History :
-      !!        !  2007-11 (D. Lea) based on obs_pre_sst
-      !!----------------------------------------------------------------------
-      !! * Modules used
-      USE domstp              ! Domain: set the time-step
-      USE par_oce             ! Ocean parameters
-      USE dom_oce, ONLY : &   ! Geographical information
-         & glamt,   &
-         & gphit,   &
-         & tmask,   &
-         & nproc
-      !! * Arguments
-      TYPE(obs_surf), INTENT(INOUT) :: seaicedata     ! Full set of Sea Ice data
-      TYPE(obs_surf), INTENT(INOUT) :: seaicedatqc    ! Subset of sea ice data not failing screening
-      LOGICAL :: ld_seaice     ! Switch for sea ice data
-      LOGICAL :: ld_nea        ! Switch for rejecting observation near land
-      !! * Local declarations
-      INTEGER :: iyea0         ! Initial date
-      INTEGER :: imon0         !  - (year, month, day, hour, minute)
-      INTEGER :: iday0    
-      INTEGER :: ihou0    
-      INTEGER :: imin0
-      INTEGER :: icycle       ! Current assimilation cycle
-                              ! Counters for observations that
-      INTEGER :: iotdobs      !  - outside time domain
-      INTEGER :: iosdsobs     !  - outside space domain
-      INTEGER :: ilansobs     !  - within a model land cell
-      INTEGER :: inlasobs     !  - close to land
-      INTEGER :: igrdobs      !  - fail the grid search
-                              ! Global counters for observations that
-      INTEGER :: iotdobsmpp   !  - outside time domain
-      INTEGER :: iosdsobsmpp  !  - outside space domain
-      INTEGER :: ilansobsmpp  !  - within a model land cell
-      INTEGER :: inlasobsmpp  !  - close to land
-      INTEGER :: igrdobsmpp   !  - fail the grid search
-      LOGICAL, DIMENSION(:), ALLOCATABLE :: & 
-         & llvalid            ! data selection
-      INTEGER :: jobs         ! Obs. loop variable
-      INTEGER :: jstp         ! Time loop variable
-      INTEGER :: inrc         ! Time index variable
-
-      IF (lwp) WRITE(numout,*)'obs_pre_seaice : Preparing the sea ice observations...'
-
-      ! Initial date initialization (year, month, day, hour, minute)
-      iyea0 =   ndate0 / 10000
-      imon0 = ( ndate0 - iyea0 * 10000 ) / 100
-      iday0 =   ndate0 - iyea0 * 10000 - imon0 * 100
-      ihou0 = 0
-      imin0 = 0
-
-      icycle = no     ! Assimilation cycle
-
-      ! Diagnotics counters for various failures.
-
-      iotdobs  = 0
-      igrdobs  = 0
-      iosdsobs = 0
-      ilansobs = 0
-      inlasobs = 0
-
-      ! -----------------------------------------------------------------------
-      ! Find time coordinate for sea ice data
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_tim( icycle, &
-         &              iyea0,   imon0,   iday0,   ihou0,   imin0,      &
-         &              seaicedata%nsurf,   seaicedata%nyea, seaicedata%nmon, &
-         &              seaicedata%nday,    seaicedata%nhou, seaicedata%nmin, &
-         &              seaicedata%nqc,     seaicedata%mstp, iotdobs        )
-      CALL obs_mpp_sum_integer( iotdobs, iotdobsmpp )
-      ! -----------------------------------------------------------------------
-      ! Check for sea ice data failing the grid search
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_grd( seaicedata%nsurf,   seaicedata%mi, seaicedata%mj, &
-         &              seaicedata%nqc,     igrdobs                         )
-      CALL obs_mpp_sum_integer( igrdobs, igrdobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Check for land points. 
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_spc_2d( seaicedata%nsurf,                 &
-         &                 jpi,             jpj,             &
-         &                 seaicedata%mi,   seaicedata%mj,   & 
-         &                 seaicedata%rlam, seaicedata%rphi, &
-         &                 glamt,           gphit,           &
-         &                 tmask(:,:,1),    seaicedata%nqc,  &
-         &                 iosdsobs,        ilansobs,        &
-         &                 inlasobs,        ld_nea           )
-
-      CALL obs_mpp_sum_integer( iosdsobs, iosdsobsmpp )
-      CALL obs_mpp_sum_integer( ilansobs, ilansobsmpp )
-      CALL obs_mpp_sum_integer( inlasobs, inlasobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Copy useful data from the seaicedata data structure to
-      ! the seaicedatqc data structure 
-      ! -----------------------------------------------------------------------
-
-      ! Allocate the selection arrays
-
-      ALLOCATE( llvalid(seaicedata%nsurf) )
-      
-      ! We want all data which has qc flags <= 0
-
-      llvalid(:)  = ( seaicedata%nqc(:)  <= 10 )
-
-      ! The actual copying
-
-      CALL obs_surf_compress( seaicedata,     seaicedatqc,       .TRUE.,  numout, &
-         &                    lvalid=llvalid )
-
-      ! Dellocate the selection arrays
-      DEALLOCATE( llvalid )
-
-      ! -----------------------------------------------------------------------
-      ! Print information about what observations are left after qc
-      ! -----------------------------------------------------------------------
-
-      ! Update the total observation counter array
-      
-      IF(lwp) THEN
-         WRITE(numout,*)
-         WRITE(numout,*) 'obs_pre_seaice :'
-         WRITE(numout,*) '~~~~~~~~~~~'
-         WRITE(numout,*)
-         WRITE(numout,*) ' Sea ice data outside time domain                  = ', &
-            &            iotdobsmpp
-         WRITE(numout,*) ' Remaining sea ice data that failed grid search    = ', &
-            &            igrdobsmpp
-         WRITE(numout,*) ' Remaining sea ice data outside space domain       = ', &
-            &            iosdsobsmpp
-         WRITE(numout,*) ' Remaining sea ice data at land points             = ', &
-            &            ilansobsmpp
-         IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining sea ice data near land points (removed) = ', &
-               &            inlasobsmpp
-         ELSE
-            WRITE(numout,*) ' Remaining sea ice data near land points (kept)    = ', &
-               &            inlasobsmpp
-         ENDIF
-         WRITE(numout,*) ' Sea ice data accepted                             = ', &
-            &            seaicedatqc%nsurfmpp
-
-         WRITE(numout,*)
-         WRITE(numout,*) ' Number of observations per time step :'
-         WRITE(numout,*)
-         WRITE(numout,1997)
-         WRITE(numout,1998)
-      ENDIF
-      
-      DO jobs = 1, seaicedatqc%nsurf
-         inrc = seaicedatqc%mstp(jobs) + 2 - nit000
-         seaicedatqc%nsstp(inrc)  = seaicedatqc%nsstp(inrc) + 1
-      END DO
-      
-      CALL obs_mpp_sum_integers( seaicedatqc%nsstp, seaicedatqc%nsstpmpp, &
-         &                       nitend - nit000 + 2 )
-
-      IF ( lwp ) THEN
-         DO jstp = nit000 - 1, nitend
-            inrc = jstp - nit000 + 2
-            WRITE(numout,1999) jstp, seaicedatqc%nsstpmpp(inrc)
-         END DO
-      ENDIF
-
-1997  FORMAT(10X,'Time step',5X,'Sea ice data           ')
-1998  FORMAT(10X,'---------',5X,'-----------------')
-1999  FORMAT(10X,I9,5X,I17)
-      
-   END SUBROUTINE obs_pre_seaice
-
-   SUBROUTINE obs_pre_vel( profdata, prodatqc, ld_vel3d, ld_nea, ld_dailyav )
-      !!----------------------------------------------------------------------
-      !!                    ***  ROUTINE obs_pre_taovel  ***
-      !!
-      !! ** Purpose : First level check and screening of U and V profiles
-      !!
-      !! ** Method  : First level check and screening of U and V profiles
-      !!
-      !! History :
-      !!        !  2007-06  (K. Mogensen) original : T and S profile data
-      !!        !  2008-09  (M. Valdivieso) : TAO velocity data
-      !!        !  2009-01  (K. Mogensen) : New feedback strictuer
-      !!
-      !!----------------------------------------------------------------------
-      !! * Modules used
-      USE domstp              ! Domain: set the time-step
-      USE par_oce             ! Ocean parameters
-      USE dom_oce, ONLY : &   ! Geographical information
-         & glamt, glamu, glamv,    &
-         & gphit, gphiu, gphiv,    &
-         & gdept_1d,             &
-         & tmask, umask, vmask,  &
-         & nproc
-      !! * Arguments
-      TYPE(obs_prof), INTENT(INOUT) :: profdata   ! Full set of profile data
-      TYPE(obs_prof), INTENT(INOUT) :: prodatqc   ! Subset of profile data not failing screening
-      LOGICAL, INTENT(IN) :: ld_vel3d      ! Switch for zonal and meridional velocity components
-      LOGICAL, INTENT(IN) :: ld_nea        ! Switch for rejecting observation near land
-      LOGICAL, INTENT(IN) :: ld_dailyav    ! Switch for daily average data
-      !! * Local declarations
-      INTEGER :: iyea0        ! Initial date
-      INTEGER :: imon0        !  - (year, month, day, hour, minute)
-      INTEGER :: iday0    
-      INTEGER :: ihou0    
-      INTEGER :: imin0
-      INTEGER :: icycle       ! Current assimilation cycle
-                              ! Counters for observations that
-      INTEGER :: iotdobs      !  - outside time domain
-      INTEGER :: iosduobs     !  - outside space domain (zonal velocity component)
-      INTEGER :: iosdvobs     !  - outside space domain (meridional velocity component)
-      INTEGER :: ilanuobs     !  - within a model land cell (zonal velocity component)
-      INTEGER :: ilanvobs     !  - within a model land cell (meridional velocity component)
-      INTEGER :: inlauobs     !  - close to land (zonal velocity component)
-      INTEGER :: inlavobs     !  - close to land (meridional velocity component)
-      INTEGER :: igrdobs      !  - fail the grid search
-      INTEGER :: iuvchku      !  - reject u if v rejected and vice versa
-      INTEGER :: iuvchkv      !
-                              ! Global counters for observations that
-      INTEGER :: iotdobsmpp   !  - outside time domain
-      INTEGER :: iosduobsmpp  !  - outside space domain (zonal velocity component)
-      INTEGER :: iosdvobsmpp  !  - outside space domain (meridional velocity component)
-      INTEGER :: ilanuobsmpp  !  - within a model land cell (zonal velocity component)
-      INTEGER :: ilanvobsmpp  !  - within a model land cell (meridional velocity component)
-      INTEGER :: inlauobsmpp  !  - close to land (zonal velocity component)
-      INTEGER :: inlavobsmpp  !  - close to land (meridional velocity component)
-      INTEGER :: igrdobsmpp   !  - fail the grid search
-      INTEGER :: iuvchkumpp   !  - reject u if v rejected and vice versa
-      INTEGER :: iuvchkvmpp   !
-      TYPE(obs_prof_valid) ::  llvalid      ! Profile selection 
-      TYPE(obs_prof_valid), DIMENSION(profdata%nvar) :: &
-         & llvvalid           ! U,V selection 
-      INTEGER :: jvar         ! Variable loop variable
-      INTEGER :: jobs         ! Obs. loop variable
-      INTEGER :: jstp         ! Time loop variable
-      INTEGER :: inrc         ! Time index variable
-
-      IF(lwp) WRITE(numout,*)'obs_pre_vel: Preparing the velocity profile data'
-
-      ! Initial date initialization (year, month, day, hour, minute)
-      iyea0 =   ndate0 / 10000
-      imon0 = ( ndate0 - iyea0 * 10000 ) / 100
-      iday0 =   ndate0 - iyea0 * 10000 - imon0 * 100
-      ihou0 = 0
-      imin0 = 0
-
-      icycle = no     ! Assimilation cycle
-
-      ! Diagnotics counters for various failures.
-
-      iotdobs  = 0
-      igrdobs  = 0
-      iosduobs = 0
-      iosdvobs = 0
-      ilanuobs = 0
-      ilanvobs = 0
-      inlauobs = 0
-      inlavobs = 0
-      iuvchku  = 0
-      iuvchkv = 0
-
-      ! -----------------------------------------------------------------------
-      ! Find time coordinate for profiles
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_tim_prof( icycle, &
-         &              iyea0,   imon0,   iday0,   ihou0,   imin0,      &
-         &              profdata%nprof,   profdata%nyea, profdata%nmon, &
-         &              profdata%nday,    profdata%nhou, profdata%nmin, &
-         &              profdata%ntyp,    profdata%nqc,  profdata%mstp, &
-         &              iotdobs, ld_dailyav = ld_dailyav        )
-	 
-      CALL obs_mpp_sum_integer( iotdobs, iotdobsmpp )
-      
-      ! -----------------------------------------------------------------------
-      ! Check for profiles failing the grid search
-      ! -----------------------------------------------------------------------
-
-      CALL obs_coo_grd( profdata%nprof,   profdata%mi(:,1), profdata%mj(:,1), &
-         &              profdata%nqc,     igrdobs                         )
-      CALL obs_coo_grd( profdata%nprof,   profdata%mi(:,2), profdata%mj(:,2), &
-         &              profdata%nqc,     igrdobs                         )
-
-      CALL obs_mpp_sum_integer( igrdobs, igrdobsmpp )
-
-      ! -----------------------------------------------------------------------
-      ! Reject all observations for profiles with nqc > 10
-      ! -----------------------------------------------------------------------
-
-      CALL obs_pro_rej( profdata )
+      ! Reject all observations for profiles with nqc > iqc_cutoff
+      ! -----------------------------------------------------------------------
+
+      CALL obs_pro_rej( profdata, kqc_cutoff = iqc_cutoff )
 
       ! -----------------------------------------------------------------------
@@ -1021,43 +406,26 @@
       ! -----------------------------------------------------------------------
 
-      ! Zonal Velocity Component
-
-      CALL obs_coo_spc_3d( profdata%nprof,        profdata%nvprot(1),   &
-         &                 profdata%npvsta(:,1),  profdata%npvend(:,1), &
-         &                 jpi,                   jpj,                  &
-         &                 jpk,                                         &
-         &                 profdata%mi,           profdata%mj,          & 
-         &                 profdata%var(1)%mvk,                         &
-         &                 profdata%rlam,         profdata%rphi,        &
-         &                 profdata%var(1)%vdep,                        &
-         &                 glamu,                 gphiu,                &
-         &                 gdept_1d,              umask,                &
-         &                 profdata%nqc,          profdata%var(1)%nvqc, &
-         &                 iosduobs,              ilanuobs,             &
-         &                 inlauobs,              ld_nea                )
-
-      CALL obs_mpp_sum_integer( iosduobs, iosduobsmpp )
-      CALL obs_mpp_sum_integer( ilanuobs, ilanuobsmpp )
-      CALL obs_mpp_sum_integer( inlauobs, inlauobsmpp )
-
-      ! Meridional Velocity Component
-
-      CALL obs_coo_spc_3d( profdata%nprof,        profdata%nvprot(2),   &
-         &                 profdata%npvsta(:,2),  profdata%npvend(:,2), &
-         &                 jpi,                   jpj,                  &
-         &                 jpk,                                         &
-         &                 profdata%mi,           profdata%mj,          & 
-         &                 profdata%var(2)%mvk,                         &
-         &                 profdata%rlam,         profdata%rphi,        &
-         &                 profdata%var(2)%vdep,                        &
-         &                 glamv,                 gphiv,                &
-         &                 gdept_1d,              vmask,                &
-         &                 profdata%nqc,          profdata%var(2)%nvqc, &
-         &                 iosdvobs,              ilanvobs,             &
-         &                 inlavobs,              ld_nea                )
-
-      CALL obs_mpp_sum_integer( iosdvobs, iosdvobsmpp )
-      CALL obs_mpp_sum_integer( ilanvobs, ilanvobsmpp )
-      CALL obs_mpp_sum_integer( inlavobs, inlavobsmpp )
+      DO jvar = 1, profdata%nvar
+         CALL obs_coo_spc_3d( profdata%nprof,          profdata%nvprot(jvar),   &
+            &                 profdata%npvsta(:,jvar), profdata%npvend(:,jvar), &
+            &                 jpi,                     jpj,                     &
+            &                 jpk,                                              &
+            &                 profdata%mi,             profdata%mj,             &
+            &                 profdata%var(jvar)%mvk,                           &
+            &                 profdata%rlam,           profdata%rphi,           &
+            &                 profdata%var(jvar)%vdep,                          &
+            &                 pglam(:,:,jvar),         pgphi(:,:,jvar),         &
+            &                 gdept_1d,                zmask(:,:,:,jvar),       &
+            &                 profdata%nqc,            profdata%var(jvar)%nvqc, &
+            &                 iosdvobs(jvar),          ilanvobs(jvar),          &
+            &                 inlavobs(jvar),          ld_nea,                  &
+            &                 ibdyvobs(jvar),          ld_bound_reject,         &
+            &                 iqc_cutoff       )
+
+         CALL obs_mpp_sum_integer( iosdvobs(jvar), iosdvobsmpp(jvar) )
+         CALL obs_mpp_sum_integer( ilanvobs(jvar), ilanvobsmpp(jvar) )
+         CALL obs_mpp_sum_integer( inlavobs(jvar), inlavobsmpp(jvar) )
+         CALL obs_mpp_sum_integer( ibdyvobs(jvar), ibdyvobsmpp(jvar) )
+      END DO
 
       ! -----------------------------------------------------------------------
@@ -1065,7 +433,9 @@
       ! -----------------------------------------------------------------------
 
-      CALL obs_uv_rej( profdata, iuvchku, iuvchkv )
-      CALL obs_mpp_sum_integer( iuvchku, iuvchkumpp )
-      CALL obs_mpp_sum_integer( iuvchkv, iuvchkvmpp )
+      IF ( TRIM(profdata%cvars(1)) == 'UVEL' ) THEN
+         CALL obs_uv_rej( profdata, iuvchku, iuvchkv, iqc_cutoff )
+         CALL obs_mpp_sum_integer( iuvchku, iuvchkumpp )
+         CALL obs_mpp_sum_integer( iuvchkv, iuvchkvmpp )
+      ENDIF
 
       ! -----------------------------------------------------------------------
@@ -1081,9 +451,9 @@
       END DO
 
-      ! We want all data which has qc flags = 0
-
-      llvalid%luse(:) = ( profdata%nqc(:)  <= 10 )
+      ! We want all data which has qc flags <= iqc_cutoff
+
+      llvalid%luse(:) = ( profdata%nqc(:)  <= iqc_cutoff )
       DO jvar = 1,profdata%nvar
-         llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= 10 )
+         llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= iqc_cutoff )
       END DO
 
@@ -1106,48 +476,46 @@
       
       IF(lwp) THEN
+      
          WRITE(numout,*)
-         WRITE(numout,*) 'obs_pre_vel :'
-         WRITE(numout,*) '~~~~~~~~~~~'
-         WRITE(numout,*)
-         WRITE(numout,*) ' Profiles outside time domain                = ', &
+         WRITE(numout,*) ' Profiles outside time domain                       = ', &
             &            iotdobsmpp
-         WRITE(numout,*) ' Remaining profiles that failed grid search  = ', &
+         WRITE(numout,*) ' Remaining profiles that failed grid search         = ', &
             &            igrdobsmpp
-         WRITE(numout,*) ' Remaining U data outside space domain       = ', &
-            &            iosduobsmpp
-         WRITE(numout,*) ' Remaining U data at land points             = ', &
-            &            ilanuobsmpp
-         IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining U data near land points (removed) = ',&
-               &            inlauobsmpp
-         ELSE
-            WRITE(numout,*) ' Remaining U data near land points (kept)    = ',&
-               &            inlauobsmpp
-         ENDIF
-         WRITE(numout,*) ' U observation rejected since V rejected     = ', &
-            &            iuvchku     
-         WRITE(numout,*) ' U data accepted                             = ', &
-            &            prodatqc%nvprotmpp(1)
-         WRITE(numout,*) ' Remaining V data outside space domain       = ', &
-            &            iosdvobsmpp
-         WRITE(numout,*) ' Remaining V data at land points             = ', &
-            &            ilanvobsmpp
-         IF (ld_nea) THEN
-            WRITE(numout,*) ' Remaining V data near land points (removed) = ',&
-               &            inlavobsmpp
-         ELSE
-            WRITE(numout,*) ' Remaining V data near land points (kept)    = ',&
-               &            inlavobsmpp
-         ENDIF
-         WRITE(numout,*) ' V observation rejected since U rejected     = ', &
-            &            iuvchkv     
-         WRITE(numout,*) ' V data accepted                             = ', &
-            &            prodatqc%nvprotmpp(2)
+         DO jvar = 1, profdata%nvar
+            WRITE(numout,*) ' Remaining '//prodatqc%cvars(jvar)//' data outside space domain       = ', &
+               &            iosdvobsmpp(jvar)
+            WRITE(numout,*) ' Remaining '//prodatqc%cvars(jvar)//' data at land points             = ', &
+               &            ilanvobsmpp(jvar)
+            IF (ld_nea) THEN
+               WRITE(numout,*) ' Remaining '//prodatqc%cvars(jvar)//' data near land points (removed) = ',&
+                  &            inlavobsmpp(jvar)
+            ELSE
+               WRITE(numout,*) ' Remaining '//prodatqc%cvars(jvar)//' data near land points (kept)    = ',&
+                  &            inlavobsmpp(jvar)
+            ENDIF
+            IF ( TRIM(profdata%cvars(jvar)) == 'UVEL' ) THEN
+               WRITE(numout,*) ' U observation rejected since V rejected     = ', &
+                  &            iuvchku
+            ELSE IF ( TRIM(profdata%cvars(jvar)) == 'VVEL' ) THEN
+               WRITE(numout,*) ' V observation rejected since U rejected     = ', &
+                  &            iuvchkv
+            ENDIF
+            WRITE(numout,*) ' Remaining '//prodatqc%cvars(jvar)//' data near open boundary (removed) = ',&
+                  &            ibdyvobsmpp(jvar)
+            WRITE(numout,*) ' '//prodatqc%cvars(jvar)//' data accepted                             = ', &
+               &            prodatqc%nvprotmpp(jvar)
+         END DO
 
          WRITE(numout,*)
          WRITE(numout,*) ' Number of observations per time step :'
          WRITE(numout,*)
-         WRITE(numout,997)
-         WRITE(numout,998)
+         WRITE(cout1,'(10X,A9,5X,A8)') 'Time step', 'Profiles'
+         WRITE(cout2,'(10X,A9,5X,A8)') '---------', '--------'
+         DO jvar = 1, prodatqc%nvar
+            WRITE(cout1,'(A,5X,A11)') TRIM(cout1), TRIM(prodatqc%cvars(jvar))
+            WRITE(cout2,'(A,5X,A11)') TRIM(cout2), '-----------'
+         END DO
+         WRITE(numout,*) cout1
+         WRITE(numout,*) cout2
       ENDIF
       
@@ -1176,15 +544,13 @@
          DO jstp = nit000 - 1, nitend
             inrc = jstp - nit000 + 2
-            WRITE(numout,999) jstp, prodatqc%npstpmpp(inrc), &
-               &                    prodatqc%nvstpmpp(inrc,1), &
-               &                    prodatqc%nvstpmpp(inrc,2)
+            WRITE(cout1,'(10X,I9,5X,I8)') jstp, prodatqc%npstpmpp(inrc)
+            DO jvar = 1, prodatqc%nvar
+               WRITE(cout1,'(A,5X,I11)') TRIM(cout1), prodatqc%nvstpmpp(inrc,jvar)
+            END DO
+            WRITE(numout,*) cout1
          END DO
       ENDIF
 
-997   FORMAT(10X,'Time step',5X,'Profiles',5X,'Zonal Comp.',5X,'Meridional Comp.')
-998   FORMAT(10X,'---------',5X,'--------',5X,'-----------',5X,'----------------')
-999   FORMAT(10X,I9,5X,I8,5X,I11,5X,I8)
-
-   END SUBROUTINE obs_pre_vel
+   END SUBROUTINE obs_pre_prof
 
    SUBROUTINE obs_coo_tim( kcycle, &
@@ -1293,5 +659,5 @@
             &        .AND. ( kobsmin(jobs) <= kmin0 ) ) ) THEN
             kobsstp(jobs) = -1
-            kobsqc(jobs)  = kobsqc(jobs) + 11
+            kobsqc(jobs)  = IBSET(kobsqc(jobs),13)
             kotdobs       = kotdobs + 1
             CYCLE
@@ -1344,5 +710,5 @@
          IF ( ( kobsstp(jobs) < ( nit000 - 1 ) ) &
             & .OR.( kobsstp(jobs) > nitend ) ) THEN
-            kobsqc(jobs) = kobsqc(jobs) + 12
+            kobsqc(jobs) = IBSET(kobsqc(jobs),13)
             kotdobs = kotdobs + 1
             CYCLE
@@ -1389,5 +755,5 @@
       &                    kobsyea, kobsmon, kobsday, kobshou, kobsmin,   &
       &                    ktyp,    kobsqc,  kobsstp, kotdobs, kdailyavtypes, &
-      &                    ld_dailyav )
+      &                    kqc_cutoff )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE obs_coo_tim ***
@@ -1433,7 +799,9 @@
       INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: &
          & kdailyavtypes    ! Types for daily averages
-      LOGICAL, OPTIONAL :: ld_dailyav    ! All types are daily averages
+      INTEGER, OPTIONAL, INTENT(IN) :: kqc_cutoff           ! QC cutoff value
+
       !! * Local declarations
       INTEGER :: jobs
+      INTEGER :: iqc_cutoff=255
 
       !-----------------------------------------------------------------------
@@ -1454,9 +822,9 @@
          DO jobs = 1, kobsno
             
-            IF ( kobsqc(jobs) <= 10 ) THEN
+            IF ( kobsqc(jobs) <= iqc_cutoff ) THEN
                
                IF ( ( kobsstp(jobs) == (nit000 - 1) ).AND.&
                   & ( ANY (kdailyavtypes(:) == ktyp(jobs)) ) ) THEN
-                  kobsqc(jobs) = kobsqc(jobs) + 14
+                  kobsqc(jobs) = IBSET(kobsqc(jobs),13)
                   kotdobs      = kotdobs + 1
                   CYCLE
@@ -1467,24 +835,4 @@
       ENDIF
 
-      !------------------------------------------------------------------------
-      ! If ld_dailyav is set then all data assumed to be daily averaged
-      !------------------------------------------------------------------------
-      
-      IF ( PRESENT( ld_dailyav) ) THEN
-         IF (ld_dailyav) THEN
-            DO jobs = 1, kobsno
-               
-               IF ( kobsqc(jobs) <= 10 ) THEN
-                  
-                  IF ( kobsstp(jobs) == (nit000 - 1) ) THEN
-                     kobsqc(jobs) = kobsqc(jobs) + 14
-                     kotdobs      = kotdobs + 1
-                     CYCLE
-                  ENDIF
-                  
-               ENDIF
-            END DO
-         ENDIF
-      ENDIF
 
    END SUBROUTINE obs_coo_tim_prof
@@ -1521,5 +869,5 @@
       DO jobs = 1, kobsno
          IF ( ( kobsi(jobs) <= 0 ) .AND. ( kobsj(jobs) <= 0 ) ) THEN
-            kobsqc(jobs) = kobsqc(jobs) + 18
+            kobsqc(jobs) = IBSET(kobsqc(jobs),12)
             kgrdobs = kgrdobs + 1
          ENDIF
@@ -1532,5 +880,7 @@
       &                       plam,   pphi,    pmask,            &
       &                       kobsqc, kosdobs, klanobs,          &
-      &                       knlaobs,ld_nea                     )
+      &                       knlaobs,ld_nea,                    &
+      &                       kbdyobs,ld_bound_reject,           &
+      &                       kqc_cutoff                         )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE obs_coo_spc_2d  ***
@@ -1565,11 +915,20 @@
       INTEGER, DIMENSION(kobsno), INTENT(INOUT) :: &
          & kobsqc             ! Observation quality control
-      INTEGER, INTENT(INOUT) :: kosdobs   ! Observations outside space domain
-      INTEGER, INTENT(INOUT) :: klanobs   ! Observations within a model land cell
-      INTEGER, INTENT(INOUT) :: knlaobs   ! Observations near land
-      LOGICAL, INTENT(IN) :: ld_nea       ! Flag observations near land
+      INTEGER, INTENT(INOUT) :: kosdobs          ! Observations outside space domain
+      INTEGER, INTENT(INOUT) :: klanobs          ! Observations within a model land cell
+      INTEGER, INTENT(INOUT) :: knlaobs          ! Observations near land
+      INTEGER, INTENT(INOUT) :: kbdyobs          ! Observations near boundary
+      LOGICAL, INTENT(IN)    :: ld_nea           ! Flag observations near land
+      LOGICAL, INTENT(IN)    :: ld_bound_reject  ! Flag observations near open boundary 
+      INTEGER, INTENT(IN)    :: kqc_cutoff       ! Cutoff QC value
+
       !! * Local declarations
       REAL(KIND=wp), DIMENSION(2,2,kobsno) :: &
          & zgmsk              ! Grid mask
+#if defined key_bdy 
+      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: &
+         & zbmsk              ! Boundary mask
+      REAL(KIND=wp), DIMENSION(jpi,jpj) :: zbdymask
+#endif 
       REAL(KIND=wp), DIMENSION(2,2,kobsno) :: &
          & zglam, &           ! Model longitude at grid points
@@ -1588,5 +947,5 @@
          ! For invalid points use 2,2
 
-         IF ( kobsqc(jobs) >= 10 ) THEN
+         IF ( kobsqc(jobs) >= kqc_cutoff ) THEN
 
             igrdi(1,1,jobs) = 1
@@ -1613,13 +972,27 @@
 
       END DO
-      
-      CALL obs_int_comm_2d( 2, 2, kobsno, igrdi, igrdj, pmask, zgmsk )
-      CALL obs_int_comm_2d( 2, 2, kobsno, igrdi, igrdj, plam, zglam )
-      CALL obs_int_comm_2d( 2, 2, kobsno, igrdi, igrdj, pphi, zgphi )
+
+#if defined key_bdy             
+      ! Create a mask grid points in boundary rim
+      IF (ld_bound_reject) THEN
+         zbdymask(:,:) = 1.0_wp
+         DO ji = 1, nb_bdy
+            DO jj = 1, idx_bdy(ji)%nblen(1)
+               zbdymask(idx_bdy(ji)%nbi(jj,1),idx_bdy(ji)%nbj(jj,1)) = 0.0_wp
+            ENDDO
+         ENDDO
+ 
+         CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, zbdymask, zbmsk )
+      ENDIF
+#endif       
+      
+      CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, pmask, zgmsk )
+      CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, plam, zglam )
+      CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, pphi, zgphi )
 
       DO jobs = 1, kobsno
 
          ! Skip bad observations
-         IF ( kobsqc(jobs) >= 10 ) CYCLE
+         IF ( kobsqc(jobs) >= kqc_cutoff ) CYCLE
 
          ! Flag if the observation falls outside the model spatial domain
@@ -1628,5 +1001,5 @@
             &  .OR. ( pobsphi(jobs) <  -90. ) &
             &  .OR. ( pobsphi(jobs) >   90. ) ) THEN
-            kobsqc(jobs) = kobsqc(jobs) + 11
+            kobsqc(jobs) = IBSET(kobsqc(jobs),11)
             kosdobs = kosdobs + 1
             CYCLE
@@ -1635,5 +1008,5 @@
          ! Flag if the observation falls with a model land cell
          IF ( SUM( zgmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN
-            kobsqc(jobs) = kobsqc(jobs)  + 12
+            kobsqc(jobs) = IBSET(kobsqc(jobs),10)
             klanobs = klanobs + 1
             CYCLE
@@ -1649,6 +1022,6 @@
                IF ( ( ABS( zgphi(ji,jj,jobs) - pobsphi(jobs) ) < 1.0e-6_wp ) &
                   & .AND. &
-                  & ( ABS( zglam(ji,jj,jobs) - pobslam(jobs) ) < 1.0e-6_wp ) &
-                  & ) THEN
+                  & ( ABS( MOD( zglam(ji,jj,jobs) - pobslam(jobs),360.0) )  &
+                  & < 1.0e-6_wp ) ) THEN
                   lgridobs = .TRUE.
                   iig = ji
@@ -1657,22 +1030,41 @@
             END DO
          END DO
-  
-         ! For observations on the grid reject them if their are at
-         ! a masked point
-         
+ 
          IF (lgridobs) THEN
             IF (zgmsk(iig,ijg,jobs) == 0.0_wp ) THEN
-               kobsqc(jobs) = kobsqc(jobs) + 12
+               kobsqc(jobs) = IBSET(kobsqc(jobs),10)
                klanobs = klanobs + 1
                CYCLE
             ENDIF
          ENDIF
-                      
+
+ 
          ! Flag if the observation falls is close to land
          IF ( MINVAL( zgmsk(1:2,1:2,jobs) ) == 0.0_wp) THEN
-            IF (ld_nea) kobsqc(jobs) = kobsqc(jobs) + 14
             knlaobs = knlaobs + 1
-            CYCLE
+            IF (ld_nea) THEN
+               kobsqc(jobs) = IBSET(kobsqc(jobs),9)
+               CYCLE
+            ENDIF
          ENDIF
+
+#if defined key_bdy
+         ! Flag if the observation falls close to the boundary rim
+         IF (ld_bound_reject) THEN
+            IF ( MINVAL( zbmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN
+               kobsqc(jobs) = IBSET(kobsqc(jobs),8)
+               kbdyobs = kbdyobs + 1
+               CYCLE
+            ENDIF
+            ! for observations on the grid...
+            IF (lgridobs) THEN
+               IF (zbmsk(iig,ijg,jobs) == 0.0_wp ) THEN
+                  kobsqc(jobs) = IBSET(kobsqc(jobs),8)
+                  kbdyobs = kbdyobs + 1
+                  CYCLE
+               ENDIF
+            ENDIF
+         ENDIF
+#endif 
             
       END DO
@@ -1686,5 +1078,7 @@
       &                       plam,    pphi,    pdep,    pmask, &
       &                       kpobsqc, kobsqc,  kosdobs,        &
-      &                       klanobs, knlaobs, ld_nea          )
+      &                       klanobs, knlaobs, ld_nea,         &
+      &                       kbdyobs, ld_bound_reject,         &
+      &                       kqc_cutoff                        )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE obs_coo_spc_3d  ***
@@ -1709,5 +1103,13 @@
       !! * Modules used
       USE dom_oce, ONLY : &       ! Geographical information
-         & gdepw_1d                        
+         & gdepw_1d,      &
+         & gdepw_0,       &                       
+#if defined key_vvl
+         & gdepw_n,       & 
+         & gdept_n,       &
+#endif
+         & ln_zco,        &
+         & ln_zps,        &
+         & lk_vvl                        
 
       !! * Arguments
@@ -1743,8 +1145,19 @@
       INTEGER, INTENT(INOUT) :: klanobs     ! Observations within a model land cell
       INTEGER, INTENT(INOUT) :: knlaobs     ! Observations near land
+      INTEGER, INTENT(INOUT) :: kbdyobs     ! Observations near boundary
       LOGICAL, INTENT(IN) :: ld_nea         ! Flag observations near land
+      LOGICAL, INTENT(IN) :: ld_bound_reject  ! Flag observations near open boundary
+      INTEGER, INTENT(IN) :: kqc_cutoff     ! Cutoff QC value
+
       !! * Local declarations
       REAL(KIND=wp), DIMENSION(2,2,kpk,kprofno) :: &
          & zgmsk              ! Grid mask
+#if defined key_bdy 
+      REAL(KIND=wp), DIMENSION(2,2,kprofno) :: &
+         & zbmsk              ! Boundary mask
+      REAL(KIND=wp), DIMENSION(jpi,jpj) :: zbdymask
+#endif 
+      REAL(KIND=wp), DIMENSION(2,2,kpk,kprofno) :: &
+         & zgdepw         
       REAL(KIND=wp), DIMENSION(2,2,kprofno) :: &
          & zglam, &           ! Model longitude at grid points
@@ -1754,4 +1167,5 @@
          & igrdj
       LOGICAL :: lgridobs           ! Is observation on a model grid point.
+      LOGICAL :: ll_next_to_land    ! Is a profile next to land 
       INTEGER :: iig, ijg           ! i,j of observation on model grid point.
       INTEGER :: jobs, jobsp, jk, ji, jj
@@ -1763,5 +1177,5 @@
          ! For invalid points use 2,2
 
-         IF ( kpobsqc(jobs) >= 10 ) THEN
+         IF ( kpobsqc(jobs) >= kqc_cutoff ) THEN
             
             igrdi(1,1,jobs) = 1
@@ -1788,13 +1202,30 @@
          
       END DO
-      
-      CALL obs_int_comm_3d( 2, 2, kprofno, kpk, igrdi, igrdj, pmask, zgmsk )
-      CALL obs_int_comm_2d( 2, 2, kprofno, igrdi, igrdj, plam, zglam )
-      CALL obs_int_comm_2d( 2, 2, kprofno, igrdi, igrdj, pphi, zgphi )
+
+#if defined key_bdy 
+      ! Create a mask grid points in boundary rim
+      IF (ld_bound_reject) THEN           
+         zbdymask(:,:) = 1.0_wp
+         DO ji = 1, nb_bdy
+            DO jj = 1, idx_bdy(ji)%nblen(1)
+               zbdymask(idx_bdy(ji)%nbi(jj,1),idx_bdy(ji)%nbj(jj,1)) = 0.0_wp
+            ENDDO
+         ENDDO
+      ENDIF
+ 
+      CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, zbdymask, zbmsk )
+#endif 
+      
+      CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, pmask, zgmsk )
+      CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, plam, zglam )
+      CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, pphi, zgphi )
+      ! Need to know the bathy depth for each observation for sco
+      CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, fsdepw(:,:,:), &
+         &                  zgdepw )
 
       DO jobs = 1, kprofno
 
          ! Skip bad profiles
-         IF ( kpobsqc(jobs) >= 10 ) CYCLE
+         IF ( kpobsqc(jobs) >= kqc_cutoff ) CYCLE
 
          ! Check if this observation is on a grid point
@@ -1807,5 +1238,5 @@
                IF ( ( ABS( zgphi(ji,jj,jobs) - pobsphi(jobs) ) < 1.0e-6_wp ) &
                   & .AND. &
-                  & ( ABS( zglam(ji,jj,jobs) - pobslam(jobs) ) < 1.0e-6_wp ) &
+                  & ( ABS( MOD( zglam(ji,jj,jobs) - pobslam(jobs),360.0) ) < 1.0e-6_wp ) &
                   & ) THEN
                   lgridobs = .TRUE.
@@ -1816,4 +1247,11 @@
          END DO
 
+         ! Check if next to land 
+         IF (  ANY( zgmsk(1:2,1:2,1,jobs) == 0.0_wp ) ) THEN 
+            ll_next_to_land=.TRUE. 
+         ELSE 
+            ll_next_to_land=.FALSE. 
+         ENDIF 
+         
          ! Reject observations
 
@@ -1827,15 +1265,53 @@
                &  .OR. ( pobsdep(jobsp) < 0.0          )       &
                &  .OR. ( pobsdep(jobsp) > gdepw_1d(kpk)) ) THEN
-               kobsqc(jobsp) = kobsqc(jobsp) + 11
+               kobsqc(jobsp) = IBSET(kobsqc(jobsp),11)
                kosdobs = kosdobs + 1
                CYCLE
             ENDIF
 
-            ! Flag if the observation falls with a model land cell
-            IF ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) &
-               &  == 0.0_wp ) THEN
-               kobsqc(jobsp) = kobsqc(jobsp) + 12
-               klanobs = klanobs + 1
-               CYCLE
+            ! To check if an observations falls within land there are two cases: 
+            ! 1: z-coordibnates, where the check uses the mask 
+            ! 2: terrain following (eg s-coordinates),  
+            !    where we use the depth of the bottom cell to mask observations 
+             
+            IF( (.NOT. lk_vvl) .AND. ( ln_zps .OR. ln_zco )  ) THEN !(CASE 1) 
+                
+               ! Flag if the observation falls with a model land cell 
+               IF ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) & 
+                  &  == 0.0_wp ) THEN 
+                  kobsqc(jobsp) = IBSET(kobsqc(jobsp),10)
+                  klanobs = klanobs + 1 
+                  CYCLE 
+               ENDIF 
+             
+               ! Flag if the observation is close to land 
+               IF ( MINVAL( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) == & 
+                  &  0.0_wp) THEN 
+                  knlaobs = knlaobs + 1 
+                  IF (ld_nea) THEN   
+                     kobsqc(jobsp) = IBSET(kobsqc(jobsp),10)
+                  ENDIF  
+               ENDIF 
+             
+            ELSE ! Case 2 
+               ! Flag if the observation is deeper than the bathymetry 
+               ! Or if it is within the mask 
+               IF ( ANY( zgdepw(1:2,1:2,kpk,jobs) < pobsdep(jobsp) ) &
+                  &     .OR. & 
+                  &  ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) &
+                  &  == 0.0_wp) ) THEN
+                  kobsqc(jobsp) = IBSET(kobsqc(jobsp),10)
+                  klanobs = klanobs + 1 
+                  CYCLE 
+               ENDIF 
+                
+               ! Flag if the observation is close to land 
+               IF ( ll_next_to_land ) THEN 
+                  knlaobs = knlaobs + 1 
+                  IF (ld_nea) THEN   
+                     kobsqc(jobsp) = IBSET(kobsqc(jobsp),10)
+                  ENDIF  
+               ENDIF 
+             
             ENDIF
 
@@ -1845,5 +1321,5 @@
             IF (lgridobs) THEN
                IF (zgmsk(iig,ijg,kobsk(jobsp)-1,jobs) == 0.0_wp ) THEN
-                  kobsqc(jobsp) = kobsqc(jobsp) + 12
+                  kobsqc(jobsp) = IBSET(kobsqc(jobs),10)
                   klanobs = klanobs + 1
                   CYCLE
@@ -1851,11 +1327,4 @@
             ENDIF
             
-            ! Flag if the observation falls is close to land
-            IF ( MINVAL( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) == &
-               &  0.0_wp) THEN
-               IF (ld_nea) kobsqc(jobsp) = kobsqc(jobsp) + 14
-               knlaobs = knlaobs + 1
-            ENDIF
-
             ! Set observation depth equal to that of the first model depth
             IF ( pobsdep(jobsp) <= pdep(1) ) THEN
@@ -1863,4 +1332,23 @@
             ENDIF
             
+#if defined key_bdy
+            ! Flag if the observation falls close to the boundary rim
+            IF (ld_bound_reject) THEN
+               IF ( MINVAL( zbmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN
+                  kobsqc(jobsp) = IBSET(kobsqc(jobs),8)
+                  kbdyobs = kbdyobs + 1
+                  CYCLE
+               ENDIF
+               ! for observations on the grid...
+               IF (lgridobs) THEN
+                  IF (zbmsk(iig,ijg,jobs) == 0.0_wp ) THEN
+                     kobsqc(jobsp) = IBSET(kobsqc(jobs),8)
+                     kbdyobs = kbdyobs + 1
+                     CYCLE
+                  ENDIF
+               ENDIF
+            ENDIF
+#endif 
+            
          END DO
       END DO
@@ -1868,5 +1356,5 @@
    END SUBROUTINE obs_coo_spc_3d
 
-   SUBROUTINE obs_pro_rej( profdata )
+   SUBROUTINE obs_pro_rej( profdata, kqc_cutoff )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE obs_pro_rej ***
@@ -1886,4 +1374,6 @@
       !! * Arguments
       TYPE(obs_prof), INTENT(INOUT) :: profdata     ! Profile data
+      INTEGER, INTENT(IN) :: kqc_cutoff             ! QC cutoff value
+
       !! * Local declarations
       INTEGER :: jprof
@@ -1895,5 +1385,5 @@
       DO jprof = 1, profdata%nprof
 
-         IF ( profdata%nqc(jprof) > 10 ) THEN
+         IF ( profdata%nqc(jprof) > kqc_cutoff ) THEN
             
             DO jvar = 1, profdata%nvar
@@ -1903,5 +1393,5 @@
                   
                   profdata%var(jvar)%nvqc(jobs) = &
-                     & profdata%var(jvar)%nvqc(jobs) + 26
+                     & IBSET(profdata%var(jvar)%nvqc(jobs),14)
 
                END DO
@@ -1915,5 +1405,5 @@
    END SUBROUTINE obs_pro_rej
 
-   SUBROUTINE obs_uv_rej( profdata, knumu, knumv )
+   SUBROUTINE obs_uv_rej( profdata, knumu, knumv, kqc_cutoff )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE obs_uv_rej ***
@@ -1935,4 +1425,6 @@
       INTEGER, INTENT(INOUT) :: knumu             ! Number of u rejected
       INTEGER, INTENT(INOUT) :: knumv             ! Number of v rejected
+      INTEGER, INTENT(IN) :: kqc_cutoff           ! QC cutoff value
+
       !! * Local declarations
       INTEGER :: jprof
@@ -1954,12 +1446,12 @@
          DO jobs = profdata%npvsta(jprof,1), profdata%npvend(jprof,1)
             
-            IF ( ( profdata%var(1)%nvqc(jobs) > 10 ) .AND. &
-               & ( profdata%var(2)%nvqc(jobs) <= 10) ) THEN
-               profdata%var(2)%nvqc(jobs) = profdata%var(2)%nvqc(jobs) + 42
+            IF ( ( profdata%var(1)%nvqc(jobs) >  kqc_cutoff ) .AND. &
+               & ( profdata%var(2)%nvqc(jobs) <=  kqc_cutoff) ) THEN
+               profdata%var(2)%nvqc(jobs) = IBSET(profdata%var(1)%nvqc(jobs),15)
                knumv = knumv + 1
             ENDIF
-            IF ( ( profdata%var(2)%nvqc(jobs) > 10 ) .AND. &
-               & ( profdata%var(1)%nvqc(jobs) <= 10) ) THEN
-               profdata%var(1)%nvqc(jobs) = profdata%var(1)%nvqc(jobs) + 42
+            IF ( ( profdata%var(2)%nvqc(jobs) >  kqc_cutoff ) .AND. &
+               & ( profdata%var(1)%nvqc(jobs) <=  kqc_cutoff) ) THEN
+               profdata%var(1)%nvqc(jobs) = IBSET(profdata%var(1)%nvqc(jobs),15)
                knumu = knumu + 1
             ENDIF
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prof_io.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prof_io.F90	(revision 10246)
+++ 	(revision )
@@ -1,32 +1,0 @@
-MODULE obs_prof_io
-   !!======================================================================
-   !!                       ***  MODULE obs_prof_io  ***
-   !! Observation operators : I/O for ENACT and Coriolis files
-   !!======================================================================
-   !! History : 
-   !!             !  09-01  (K. Mogensen) Initial version
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !!   read_enactfile    :  Read a obfbdata structure from an ENACT file.
-   !!   read_coriofile    :  Read a obfbdata structure from an Coriolis file.
-   !!----------------------------------------------------------------------
-   USE par_kind
-   USE obs_utils
-   USE obs_fbm
-   USE obs_conv
-   USE netcdf
-   IMPLICIT NONE
-
-   INTEGER, PARAMETER :: imaxlev = 10000
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-#include "obsprof_io.h90"
-
-END MODULE obs_prof_io
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_profiles_def.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_profiles_def.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_profiles_def.F90	(revision 10247)
@@ -104,4 +104,7 @@
       ! Bookkeeping arrays with sizes equal to number of variables
 
+      CHARACTER(len=8), POINTER, DIMENSION(:) :: &
+         & cvars          !: Variable names
+
       INTEGER, POINTER, DIMENSION(:) :: &
          & nvprot,   &    !: Local total number of profile T data
@@ -237,4 +240,5 @@
 
       ALLOCATE( &
+         & prof%cvars(kvar),    &
          & prof%nvprot(kvar),   &
          & prof%nvprotmpp(kvar) &
@@ -242,4 +246,5 @@
          
       DO jvar = 1, kvar
+         prof%cvars    (jvar) = "NotSet"
          prof%nvprot   (jvar) = ko3dt(jvar)
          prof%nvprotmpp(jvar) = 0
@@ -452,5 +457,6 @@
 
       DEALLOCATE( &
-         & prof%nvprot,  &
+         & prof%cvars,    &
+         & prof%nvprot,   &
          & prof%nvprotmpp &
          )
@@ -770,4 +776,5 @@
       newprof%npj      = prof%npj
       newprof%npk      = prof%npk
+      newprof%cvars(:) = prof%cvars(:)
  
       ! Deallocate temporary data
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_altbias.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_altbias.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_altbias.F90	(revision 10247)
@@ -50,5 +50,5 @@
 CONTAINS
 
-   SUBROUTINE obs_rea_altbias( kslano, sladata, k2dint, bias_file )
+   SUBROUTINE obs_rea_altbias( sladata, k2dint, bias_file )
       !!---------------------------------------------------------------------
       !!
@@ -70,6 +70,5 @@
       !
       !! * Arguments
-      INTEGER, INTENT(IN) :: kslano      ! Number of SLA Products
-      TYPE(obs_surf), DIMENSION(kslano), INTENT(INOUT) :: &
+      TYPE(obs_surf), INTENT(INOUT) :: &
          & sladata       ! SLA data
       INTEGER, INTENT(IN) :: k2dint
@@ -80,5 +79,4 @@
       CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_rea_altbias'
 
-      INTEGER :: jslano       ! Data set loop variable
       INTEGER :: jobs         ! Obs loop variable
       INTEGER :: jpialtbias   ! Number of grid point in latitude for the bias
@@ -130,5 +128,5 @@
          ! Get the Alt bias data
          
-         CALL iom_get( numaltbias, jpdom_data, 'altbias', z_altbias(:,:), 1 )
+         CALL iom_get( numaltbias, jpdom_autoglo, 'altbias', z_altbias(:,:), 1 )
          
          ! Close the file
@@ -144,68 +142,63 @@
       ! Intepolate the bias already on the model grid at the observation point
   
-      DO jslano = 1, kslano
-
-         ALLOCATE( &
-            & igrdi(2,2,sladata(jslano)%nsurf), &
-            & igrdj(2,2,sladata(jslano)%nsurf), &
-            & zglam(2,2,sladata(jslano)%nsurf), &
-            & zgphi(2,2,sladata(jslano)%nsurf), &
-            & zmask(2,2,sladata(jslano)%nsurf), &
-            & zbias(2,2,sladata(jslano)%nsurf)  &
-            & )
-         
-         DO jobs = 1, sladata(jslano)%nsurf
-
-            igrdi(1,1,jobs) = sladata(jslano)%mi(jobs)-1
-            igrdj(1,1,jobs) = sladata(jslano)%mj(jobs)-1
-            igrdi(1,2,jobs) = sladata(jslano)%mi(jobs)-1
-            igrdj(1,2,jobs) = sladata(jslano)%mj(jobs)
-            igrdi(2,1,jobs) = sladata(jslano)%mi(jobs)
-            igrdj(2,1,jobs) = sladata(jslano)%mj(jobs)-1
-            igrdi(2,2,jobs) = sladata(jslano)%mi(jobs)
-            igrdj(2,2,jobs) = sladata(jslano)%mj(jobs)
-
-         END DO
-
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, &
-            &                  igrdi, igrdj, glamt, zglam )
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, &
-            &                  igrdi, igrdj, gphit, zgphi )
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, &
-            &                  igrdi, igrdj, tmask(:,:,1), zmask )
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, &
-            &                  igrdi, igrdj, z_altbias, zbias )
-
-         DO jobs = 1, sladata(jslano)%nsurf
-
-            zlam = sladata(jslano)%rlam(jobs)
-            zphi = sladata(jslano)%rphi(jobs)
-            iico = sladata(jslano)%mi(jobs)
-            ijco = sladata(jslano)%mj(jobs)
+      ALLOCATE( &
+         & igrdi(2,2,sladata%nsurf), &
+         & igrdj(2,2,sladata%nsurf), &
+         & zglam(2,2,sladata%nsurf), &
+         & zgphi(2,2,sladata%nsurf), &
+         & zmask(2,2,sladata%nsurf), &
+         & zbias(2,2,sladata%nsurf)  &
+         & )
+         
+      DO jobs = 1, sladata%nsurf
+
+         igrdi(1,1,jobs) = sladata%mi(jobs)-1
+         igrdj(1,1,jobs) = sladata%mj(jobs)-1
+         igrdi(1,2,jobs) = sladata%mi(jobs)-1
+         igrdj(1,2,jobs) = sladata%mj(jobs)
+         igrdi(2,1,jobs) = sladata%mi(jobs)
+         igrdj(2,1,jobs) = sladata%mj(jobs)-1
+         igrdi(2,2,jobs) = sladata%mi(jobs)
+         igrdj(2,2,jobs) = sladata%mj(jobs)
+
+      END DO
+
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, glamt, zglam )
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, gphit, zgphi )
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, tmask(:,:,1), zmask )
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, z_altbias, zbias )
+
+      DO jobs = 1, sladata%nsurf
+
+         zlam = sladata%rlam(jobs)
+         zphi = sladata%rphi(jobs)
+         iico = sladata%mi(jobs)
+         ijco = sladata%mj(jobs)
             
-            CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
-               &                   zglam(:,:,jobs), zgphi(:,:,jobs), &
-               &                   zmask(:,:,jobs), zweig, zobsmask )
+         CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
+            &                   zglam(:,:,jobs), zgphi(:,:,jobs), &
+            &                   zmask(:,:,jobs), zweig, zobsmask )
             
-            CALL obs_int_h2d( 1, 1,      &
-               &              zweig, zbias(:,:,jobs),  zext )
-
-            ! adjust mdt with bias field
-            sladata(jslano)%rext(jobs,2) = &
-               sladata(jslano)%rext(jobs,2) - zext(1)
+         CALL obs_int_h2d( 1, 1,      &
+            &              zweig, zbias(:,:,jobs),  zext )
+
+         ! adjust mdt with bias field
+         sladata%rext(jobs,2) = sladata%rext(jobs,2) - zext(1)
             
-         END DO
-
-         DEALLOCATE( &
-            & igrdi, &
-            & igrdj, &
-            & zglam, &
-            & zgphi, &
-            & zmask, &
-            & zbias  &
-            & )
-         
       END DO
 
+      DEALLOCATE( &
+         & igrdi, &
+         & igrdj, &
+         & zglam, &
+         & zgphi, &
+         & zmask, &
+         & zbias  &
+         & )
+         
       CALL wrk_dealloc(jpi,jpj,z_altbias) 
 
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_prof.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_prof.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_prof.F90	(revision 10247)
@@ -25,6 +25,6 @@
    USE netcdf                   ! NetCDF library
    USE obs_oper                 ! Observation operators
-   USE obs_prof_io              ! Profile files I/O (non-FB files)
    USE lib_mpp                  ! For ctl_warn/stop
+   USE obs_fbm                  ! Feedback routines
 
    IMPLICIT NONE
@@ -33,5 +33,5 @@
    PRIVATE
 
-   PUBLIC obs_rea_pro_dri  ! Read the profile observations 
+   PUBLIC obs_rea_prof  ! Read the profile observations 
 
    !!----------------------------------------------------------------------
@@ -42,18 +42,17 @@
 
 CONTAINS
- 
-   SUBROUTINE obs_rea_pro_dri( kformat, &
-      &                        profdata, knumfiles, cfilenames, &
-      &                        kvars, kextr, kstp, ddobsini, ddobsend, &
-      &                        ldt3d, lds3d, ldignmis, ldsatt, ldavtimset, &
-      &                        ldmod, kdailyavtypes )
+
+   SUBROUTINE obs_rea_prof( profdata, knumfiles, cdfilenames, &
+      &                     kvars, kextr, kstp, ddobsini, ddobsend, &
+      &                     ldvar, ldignmis, ldsatt, &
+      &                     ldmod, kdailyavtypes )
       !!---------------------------------------------------------------------
       !!
-      !!                   *** ROUTINE obs_rea_pro_dri ***
+      !!                   *** ROUTINE obs_rea_prof ***
       !!
       !! ** Purpose : Read from file the profile observations
       !!
-      !! ** Method  : Depending on kformat either ENACT, CORIOLIS or
-      !!              feedback data files are read
+      !! ** Method  : Read feedback data in and transform to NEMO internal 
+      !!              profile data structure
       !!
       !! ** Action  : 
@@ -63,31 +62,29 @@
       !! History :  
       !!      ! :  2009-09 (K. Mogensen) : New merged version of old routines
+      !!      ! :  2015-08 (M. Martin) : Merged profile and velocity routines
       !!----------------------------------------------------------------------
-      !! * Modules used
-   
+
       !! * Arguments
-      INTEGER ::  kformat    ! Format of input data
-      !                      ! 1: ENACT
-      !                      ! 2: Coriolis
-      TYPE(obs_prof), INTENT(OUT) ::  profdata     ! Profile data to be read
-      INTEGER, INTENT(IN) :: knumfiles      ! Number of files to read in
+      TYPE(obs_prof), INTENT(OUT) :: &
+         & profdata                     ! Profile data to be read
+      INTEGER, INTENT(IN) :: knumfiles  ! Number of files to read
       CHARACTER(LEN=128), INTENT(IN) ::  &
-         & cfilenames(knumfiles)  ! File names to read in
+         & cdfilenames(knumfiles)        ! File names to read in
       INTEGER, INTENT(IN) :: kvars      ! Number of variables in profdata
-      INTEGER, INTENT(IN) :: kextr      ! Number of extra fields for each var in profdata
-      INTEGER, INTENT(IN) :: kstp        ! Ocean time-step index
-      LOGICAL, INTENT(IN) :: ldt3d       ! Observed variables switches
-      LOGICAL, INTENT(IN) :: lds3d
-      LOGICAL, INTENT(IN) :: ldignmis    ! Ignore missing files
-      LOGICAL, INTENT(IN) :: ldsatt      ! Compute salinity at all temperature points
-      LOGICAL, INTENT(IN) :: ldavtimset  ! Correct time for daily averaged data
-      LOGICAL, INTENT(IN) :: ldmod       ! Initialize model from input data
-      REAL(KIND=dp), INTENT(IN) :: ddobsini    ! Obs. ini time in YYYYMMDD.HHMMSS
-      REAL(KIND=dp), INTENT(IN) :: ddobsend    ! Obs. end time in YYYYMMDD.HHMMSS
+      INTEGER, INTENT(IN) :: kextr      ! Number of extra fields for each var
+      INTEGER, INTENT(IN) :: kstp       ! Ocean time-step index
+      LOGICAL, DIMENSION(kvars), INTENT(IN) :: ldvar     ! Observed variables switches
+      LOGICAL, INTENT(IN) :: ldignmis   ! Ignore missing files
+      LOGICAL, INTENT(IN) :: ldsatt     ! Compute salinity at all temperature points
+      LOGICAL, INTENT(IN) :: ldmod      ! Initialize model from input data
+      REAL(dp), INTENT(IN) :: ddobsini  ! Obs. ini time in YYYYMMDD.HHMMSS
+      REAL(dp), INTENT(IN) :: ddobsend  ! Obs. end time in YYYYMMDD.HHMMSS
       INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: &
-         & kdailyavtypes
+         & kdailyavtypes                ! Types of daily average observations
 
       !! * Local declarations
-      CHARACTER(LEN=15), PARAMETER :: cpname='obs_rea_pro_dri'
+      CHARACTER(LEN=15), PARAMETER :: cpname='obs_rea_prof'
+      CHARACTER(len=8) :: clrefdate
+      CHARACTER(len=8), DIMENSION(:), ALLOCATABLE :: clvars
       INTEGER :: jvar
       INTEGER :: ji
@@ -105,57 +102,55 @@
       INTEGER :: imin
       INTEGER :: isec
+      INTEGER :: iprof
+      INTEGER :: iproftot
+      INTEGER, DIMENSION(kvars) :: ivart0
+      INTEGER, DIMENSION(kvars) :: ivart
+      INTEGER :: ip3dt
+      INTEGER :: ios
+      INTEGER :: ioserrcount
+      INTEGER, DIMENSION(kvars) :: ivartmpp
+      INTEGER :: ip3dtmpp
+      INTEGER :: itype
       INTEGER, DIMENSION(knumfiles) :: &
          & irefdate
-      INTEGER, DIMENSION(ntyp1770+1) :: &
-         & itypt,    &
-         & ityptmpp, &
-         & ityps,    &
-         & itypsmpp 
-      INTEGER :: it3dtmpp
-      INTEGER :: is3dtmpp
-      INTEGER :: ip3dtmpp
-      INTEGER, DIMENSION(:), ALLOCATABLE :: &
+      INTEGER, DIMENSION(ntyp1770+1,kvars) :: &
+         & itypvar,    &
+         & itypvarmpp
+      INTEGER, DIMENSION(:,:), ALLOCATABLE :: &
          & iobsi,    &
          & iobsj,    &
-         & iproc,    &
+         & iproc
+      INTEGER, DIMENSION(:), ALLOCATABLE :: &
          & iindx,    &
          & ifileidx, &
          & iprofidx
-      INTEGER :: itype
       INTEGER, DIMENSION(imaxavtypes) :: &
          & idailyavtypes
+      INTEGER, DIMENSION(kvars) :: &
+         & iv3dt
       REAL(wp), DIMENSION(:), ALLOCATABLE :: &
          & zphi, &
          & zlam
-      real(wp), DIMENSION(:), ALLOCATABLE :: &
+      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
          & zdat
+      REAL(wp), DIMENSION(knumfiles) :: &
+         & djulini, &
+         & djulend
       LOGICAL :: llvalprof
+      LOGICAL :: lldavtimset
+      LOGICAL :: llcycle
       TYPE(obfbdata), POINTER, DIMENSION(:) :: &
          & inpfiles
-      real(wp), DIMENSION(knumfiles) :: &
-         & djulini, &
-         & djulend
-      INTEGER :: iprof
-      INTEGER :: iproftot
-      INTEGER :: it3dt0
-      INTEGER :: is3dt0
-      INTEGER :: it3dt
-      INTEGER :: is3dt
-      INTEGER :: ip3dt
-      INTEGER :: ios
-      INTEGER :: ioserrcount
-      INTEGER, DIMENSION(kvars) :: &
-         & iv3dt
-      CHARACTER(len=8) :: cl_refdate
-   
+
       ! Local initialization
       iprof = 0
-      it3dt0 = 0
-      is3dt0 = 0
+      ivart0(:) = 0
       ip3dt = 0
 
       ! Daily average types
+      lldavtimset = .FALSE.
       IF ( PRESENT(kdailyavtypes) ) THEN
          idailyavtypes(:) = kdailyavtypes(:)
+         IF ( ANY (idailyavtypes(:) /= -1) ) lldavtimset = .TRUE.
       ELSE
          idailyavtypes(:) = -1
@@ -163,21 +158,13 @@
 
       !-----------------------------------------------------------------------
-      ! Check data the model part is just with feedback data files
-      !-----------------------------------------------------------------------
-      IF ( ldmod .AND. ( kformat /= 0 ) ) THEN
-         CALL ctl_stop( 'Model can only be read from feedback data' )
-         RETURN
-      ENDIF
-
-      !-----------------------------------------------------------------------
       ! Count the number of files needed and allocate the obfbdata type
       !-----------------------------------------------------------------------
-      
+
       inobf = knumfiles
-      
+
       ALLOCATE( inpfiles(inobf) )
 
       prof_files : DO jj = 1, inobf
-          
+
          !---------------------------------------------------------------------
          ! Prints
@@ -186,5 +173,5 @@
             WRITE(numout,*)
             WRITE(numout,*) ' obs_rea_pro_dri : Reading from file = ', &
-               & TRIM( TRIM( cfilenames(jj) ) )
+               & TRIM( TRIM( cdfilenames(jj) ) )
             WRITE(numout,*) ' ~~~~~~~~~~~~~~~'
             WRITE(numout,*)
@@ -194,25 +181,25 @@
          !  Initialization: Open file and get dimensions only
          !---------------------------------------------------------------------
-         
-         iflag = nf90_open( TRIM( TRIM( cfilenames(jj) ) ), nf90_nowrite, &
+
+         iflag = nf90_open( TRIM( cdfilenames(jj) ), nf90_nowrite, &
             &                      i_file_id )
-         
+
          IF ( iflag /= nf90_noerr ) THEN
 
             IF ( ldignmis ) THEN
                inpfiles(jj)%nobs = 0
-               CALL ctl_warn( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
+               CALL ctl_warn( 'File ' // TRIM( cdfilenames(jj) ) // &
                   &           ' not found' )
             ELSE 
-               CALL ctl_stop( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
+               CALL ctl_stop( 'File ' // TRIM( cdfilenames(jj) ) // &
                   &           ' not found' )
             ENDIF
 
          ELSE 
-            
+
             !------------------------------------------------------------------
-            !  Close the file since it is opened in read_proffile
+            !  Close the file since it is opened in read_obfbdata
             !------------------------------------------------------------------
-            
+
             iflag = nf90_close( i_file_id )
 
@@ -220,39 +207,31 @@
             !  Read the profile file into inpfiles
             !------------------------------------------------------------------
-            IF ( kformat == 0 ) THEN
-               CALL init_obfbdata( inpfiles(jj) )
-               IF(lwp) THEN
-                  WRITE(numout,*)
-                  WRITE(numout,*)'Reading from feedback file :', &
-                     &           TRIM( cfilenames(jj) )
-               ENDIF
-               CALL read_obfbdata( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                ldgrid = .TRUE. )
-               IF ( inpfiles(jj)%nvar < 2 ) THEN
-                  CALL ctl_stop( 'Feedback format error' )
-                  RETURN
-               ENDIF
-               IF ( TRIM(inpfiles(jj)%cname(1)) /= 'POTM' ) THEN
-                  CALL ctl_stop( 'Feedback format error' )
-                  RETURN
-               ENDIF
-               IF ( TRIM(inpfiles(jj)%cname(2)) /= 'PSAL' ) THEN
-                  CALL ctl_stop( 'Feedback format error' )
-                  RETURN
-               ENDIF
-               IF ( ldmod .AND. ( inpfiles(jj)%nadd == 0 ) ) THEN
-                  CALL ctl_stop( 'Model not in input data' )
-                  RETURN
-               ENDIF
-            ELSEIF ( kformat == 1 ) THEN
-               CALL read_enactfile( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                 numout, lwp, .TRUE. )
-            ELSEIF ( kformat == 2 ) THEN
-               CALL read_coriofile( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                 numout, lwp, .TRUE. )
+            CALL init_obfbdata( inpfiles(jj) )
+            CALL read_obfbdata( TRIM( cdfilenames(jj) ), inpfiles(jj), &
+               &                ldgrid = .TRUE. )
+
+            IF ( inpfiles(jj)%nvar /= kvars ) THEN
+               CALL ctl_stop( 'Feedback format error: ', &
+                  &           ' unexpected number of vars in profile file' )
+            ENDIF
+
+            IF ( ldmod .AND. ( inpfiles(jj)%nadd == 0 ) ) THEN
+               CALL ctl_stop( 'Model not in input data' )
+            ENDIF
+
+            IF ( jj == 1 ) THEN
+               ALLOCATE( clvars( inpfiles(jj)%nvar ) )
+               DO ji = 1, inpfiles(jj)%nvar
+                 clvars(ji) = inpfiles(jj)%cname(ji)
+               END DO
             ELSE
-               CALL ctl_stop( 'File format unknown' )
-            ENDIF
-            
+               DO ji = 1, inpfiles(jj)%nvar
+                  IF ( inpfiles(jj)%cname(ji) /= clvars(ji) ) THEN
+                     CALL ctl_stop( 'Feedback file variables not consistent', &
+                        &           ' with previous files for this type' )
+                  ENDIF
+               END DO
+            ENDIF
+
             !------------------------------------------------------------------
             !  Change longitude (-180,180)
@@ -272,7 +251,7 @@
             !  Calculate the date  (change eventually)
             !------------------------------------------------------------------
-            cl_refdate=inpfiles(jj)%cdjuldref(1:8)
-            READ(cl_refdate,'(I8)') irefdate(jj)
-            
+            clrefdate=inpfiles(jj)%cdjuldref(1:8)
+            READ(clrefdate,'(I8)') irefdate(jj)
+
             CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
             CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
@@ -283,32 +262,50 @@
 
             ioserrcount=0
-            IF ( ldavtimset ) THEN
+            IF ( lldavtimset ) THEN
+
+               IF ( ANY ( idailyavtypes(:) /= -1 ) .AND. lwp) THEN
+                  WRITE(numout,*)' Resetting time of daily averaged', &
+                     &           ' observations to the end of the day'
+               ENDIF
+
                DO ji = 1, inpfiles(jj)%nobs
-                  ! 
-                  !  for daily averaged data for example
-                  !  MRB data (itype==820) force the time
-                  !  to be the  end of the day
-                  !
                   READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 900 ) itype
 900               IF ( ios /= 0 ) THEN
-                     itype = 0         ! Set type to zero if there is a problem in the string conversion
-                  ENDIF
-                  IF ( ANY (idailyavtypes == itype ) ) THEN
-                     inpfiles(jj)%ptim(ji) = &
-                     & INT(inpfiles(jj)%ptim(ji)) + 1
-                  ENDIF
+                     ! Set type to zero if there is a problem in the string conversion
+                     itype = 0
+                  ENDIF
+
+                  IF ( ANY ( idailyavtypes(:) == itype ) ) THEN
+                  !  for daily averaged data force the time
+                  !  to be the last time-step of the day, but still within the day.
+                     IF ( inpfiles(jj)%ptim(ji) >= 0. ) THEN
+                        inpfiles(jj)%ptim(ji) = &
+                           & INT(inpfiles(jj)%ptim(ji)) + 0.9999
+                     ELSE
+                        inpfiles(jj)%ptim(ji) = &
+                           & INT(inpfiles(jj)%ptim(ji)) - 0.0001
+                     ENDIF
+                  ENDIF
+
                END DO
-            ENDIF
-            
+
+            ENDIF
+
             IF ( inpfiles(jj)%nobs > 0 ) THEN
-               inpfiles(jj)%iproc = -1
-               inpfiles(jj)%iobsi = -1
-               inpfiles(jj)%iobsj = -1
+               inpfiles(jj)%iproc(:,:) = -1
+               inpfiles(jj)%iobsi(:,:) = -1
+               inpfiles(jj)%iobsj(:,:) = -1
             ENDIF
             inowin = 0
             DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-                  & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+               IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+               llcycle = .TRUE.
+               DO jvar = 1, kvars
+                  IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                     llcycle = .FALSE.
+                     EXIT
+                  ENDIF
+               END DO
+               IF ( llcycle ) CYCLE
                IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
                   & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
@@ -318,12 +315,18 @@
             ALLOCATE( zlam(inowin)  )
             ALLOCATE( zphi(inowin)  )
-            ALLOCATE( iobsi(inowin) )
-            ALLOCATE( iobsj(inowin) )
-            ALLOCATE( iproc(inowin) )
+            ALLOCATE( iobsi(inowin,kvars) )
+            ALLOCATE( iobsj(inowin,kvars) )
+            ALLOCATE( iproc(inowin,kvars) )
             inowin = 0
             DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-                  & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+               IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+               llcycle = .TRUE.
+               DO jvar = 1, kvars
+                  IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                     llcycle = .FALSE.
+                     EXIT
+                  ENDIF
+               END DO
+               IF ( llcycle ) CYCLE
                IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
                   & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
@@ -334,17 +337,50 @@
             END DO
 
-            CALL obs_grid_search( inowin, zlam, zphi, iobsi, iobsj, iproc, 'T' )
+            ! Assume anything other than velocity is on T grid
+            IF ( TRIM( inpfiles(jj)%cname(1) ) == 'UVEL' ) THEN
+               CALL obs_grid_search( inowin, zlam, zphi, iobsi(:,1), iobsj(:,1), &
+                  &                  iproc(:,1), 'U' )
+               CALL obs_grid_search( inowin, zlam, zphi, iobsi(:,2), iobsj(:,2), &
+                  &                  iproc(:,2), 'V' )
+            ELSE
+               CALL obs_grid_search( inowin, zlam, zphi, iobsi(:,1), iobsj(:,1), &
+                  &                  iproc(:,1), 'T' )
+               IF ( kvars > 1 ) THEN
+                  DO jvar = 2, kvars
+                     iobsi(:,jvar) = iobsi(:,1)
+                     iobsj(:,jvar) = iobsj(:,1)
+                     iproc(:,jvar) = iproc(:,1)
+                  END DO
+               ENDIF
+            ENDIF
 
             inowin = 0
             DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-                  & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+               IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+               llcycle = .TRUE.
+               DO jvar = 1, kvars
+                  IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                     llcycle = .FALSE.
+                     EXIT
+                  ENDIF
+               END DO
+               IF ( llcycle ) CYCLE
                IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
                   & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
                   inowin = inowin + 1
-                  inpfiles(jj)%iproc(ji,1) = iproc(inowin)
-                  inpfiles(jj)%iobsi(ji,1) = iobsi(inowin)
-                  inpfiles(jj)%iobsj(ji,1) = iobsj(inowin)
+                  DO jvar = 1, kvars
+                     inpfiles(jj)%iproc(ji,jvar) = iproc(inowin,jvar)
+                     inpfiles(jj)%iobsi(ji,jvar) = iobsi(inowin,jvar)
+                     inpfiles(jj)%iobsj(ji,jvar) = iobsj(inowin,jvar)
+                  END DO
+                  IF ( kvars > 1 ) THEN
+                     DO jvar = 2, kvars
+                        IF ( inpfiles(jj)%iproc(ji,jvar) /= &
+                           & inpfiles(jj)%iproc(ji,1) ) THEN
+                           CALL ctl_stop( 'Error in obs_read_prof:', &
+                              & 'observation on different processors for different vars')
+                        ENDIF
+                     END DO
+                  ENDIF
                ENDIF
             END DO
@@ -352,7 +388,13 @@
 
             DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-                  & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+               IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+               llcycle = .TRUE.
+               DO jvar = 1, kvars
+                  IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                     llcycle = .FALSE.
+                     EXIT
+                  ENDIF
+               END DO
+               IF ( llcycle ) CYCLE
                IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
                   & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
@@ -363,37 +405,29 @@
                   ENDIF
                   llvalprof = .FALSE.
-                  IF ( ldt3d ) THEN
-                     loop_t_count : DO ij = 1,inpfiles(jj)%nlev
-                        IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
-                           & CYCLE
-                        IF ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                           & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                           it3dt0 = it3dt0 + 1
-                        ENDIF
-                     END DO loop_t_count
-                  ENDIF
-                  IF ( lds3d ) THEN
-                     loop_s_count : DO ij = 1,inpfiles(jj)%nlev
-                        IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
-                           & CYCLE
-                        IF ( ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                           & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                           is3dt0 = is3dt0 + 1
-                        ENDIF
-                     END DO loop_s_count
-                  ENDIF
-                  loop_p_count : DO ij = 1,inpfiles(jj)%nlev
+                  DO jvar = 1, kvars
+                     IF ( ldvar(jvar) ) THEN
+                        DO ij = 1,inpfiles(jj)%nlev
+                           IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
+                              & CYCLE
+                           IF ( .NOT. BTEST(inpfiles(jj)%ivlqc(ij,ji,jvar),2) .AND. &
+                              & .NOT. BTEST(inpfiles(jj)%idqc(ij,ji),2) ) THEN
+                              ivart0(jvar) = ivart0(jvar) + 1
+                           ENDIF
+                        END DO
+                     ENDIF
+                  END DO
+                  DO ij = 1,inpfiles(jj)%nlev
                      IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
                         & CYCLE
-                     IF ( ( ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                        &     ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) .AND. &
-                        &     ldt3d ) .OR. &
-                        & ( ( ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                        &     ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) .AND. &
-                        &     lds3d ) ) THEN
-                        ip3dt = ip3dt + 1
-                        llvalprof = .TRUE.
-                     ENDIF
-                  END DO loop_p_count
+                     DO jvar = 1, kvars
+                        IF ( ( .NOT. BTEST(inpfiles(jj)%ivlqc(ij,ji,jvar),2) .AND. &
+                           &   .NOT. BTEST(inpfiles(jj)%idqc(ij,ji),2) .AND. &
+                           &    ldvar(jvar) ) ) THEN
+                           ip3dt = ip3dt + 1
+                           llvalprof = .TRUE.
+                           EXIT
+                        ENDIF
+                     END DO
+                  END DO
 
                   IF ( llvalprof ) iprof = iprof + 1
@@ -405,5 +439,5 @@
 
       END DO prof_files
-      
+
       !-----------------------------------------------------------------------
       ! Get the time ordered indices of the input data
@@ -416,7 +450,13 @@
       DO jj = 1, inobf
          DO ji = 1, inpfiles(jj)%nobs
-            IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-            IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-               & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+            IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+            llcycle = .TRUE.
+            DO jvar = 1, kvars
+               IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                  llcycle = .FALSE.
+                  EXIT
+               ENDIF
+            END DO
+            IF ( llcycle ) CYCLE
             IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
                & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
@@ -431,7 +471,13 @@
       DO jj = 1, inobf
          DO ji = 1, inpfiles(jj)%nobs
-            IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-            IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-               & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+            IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+            llcycle = .TRUE.
+            DO jvar = 1, kvars
+               IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                  llcycle = .FALSE.
+                  EXIT
+               ENDIF
+            END DO
+            IF ( llcycle ) CYCLE
             IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
                & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
@@ -446,45 +492,45 @@
          &               zdat,     &
          &               iindx   )
-      
+
       iv3dt(:) = -1
       IF (ldsatt) THEN
-         iv3dt(1) = ip3dt
-         iv3dt(2) = ip3dt
+         iv3dt(:) = ip3dt
       ELSE
-         iv3dt(1) = it3dt0
-         iv3dt(2) = is3dt0
+         iv3dt(:) = ivart0(:)
       ENDIF
       CALL obs_prof_alloc( profdata, kvars, kextr, iprof, iv3dt, &
          &                 kstp, jpi, jpj, jpk )
-      
+
       ! * Read obs/positions, QC, all variable and assign to profdata
 
       profdata%nprof     = 0
       profdata%nvprot(:) = 0
-
+      profdata%cvars(:)  = clvars(:)
       iprof = 0
 
       ip3dt = 0
-      it3dt = 0
-      is3dt = 0
-      itypt   (:) = 0
-      ityptmpp(:) = 0
-      
-      ityps   (:) = 0
-      itypsmpp(:) = 0
-      
-      ioserrcount = 0      
+      ivart(:) = 0
+      itypvar   (:,:) = 0
+      itypvarmpp(:,:) = 0
+
+      ioserrcount = 0
       DO jk = 1, iproftot
-         
+
          jj = ifileidx(iindx(jk))
          ji = iprofidx(iindx(jk))
 
-         IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-         IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-            & ( inpfiles(jj)%ivqc(ji,2) > 2 )) CYCLE
+         IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+         llcycle = .TRUE.
+         DO jvar = 1, kvars
+            IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+               llcycle = .FALSE.
+               EXIT
+            ENDIF
+         END DO
+         IF ( llcycle ) CYCLE
 
          IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND.  &
             & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
-            
+
             IF ( nproc == 0 ) THEN
                IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
@@ -492,39 +538,40 @@
                IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
             ENDIF
-            
+
             llvalprof = .FALSE.
 
             IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
 
-            IF ( ( inpfiles(jj)%ivqc(ji,1) > 2 ) .AND. &
-               & ( inpfiles(jj)%ivqc(ji,2) > 2 ) ) CYCLE
+            IF ( BTEST(inpfiles(jj)%ioqc(ji),2 ) ) CYCLE
+            llcycle = .TRUE.
+            DO jvar = 1, kvars
+               IF ( .NOT. ( BTEST(inpfiles(jj)%ivqc(ji,jvar),2) ) ) THEN
+                  llcycle = .FALSE.
+                  EXIT
+               ENDIF
+            END DO
+            IF ( llcycle ) CYCLE
 
             loop_prof : DO ij = 1, inpfiles(jj)%nlev
-               
+
                IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
                   & CYCLE
-               
-               IF ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                  & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                  
-                  llvalprof = .TRUE. 
-                  EXIT loop_prof
-                  
-               ENDIF
-               
-               IF ( ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                  & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                  
-                  llvalprof = .TRUE. 
-                  EXIT loop_prof
-                  
-               ENDIF
-               
+
+               DO jvar = 1, kvars
+                  IF ( .NOT. BTEST(inpfiles(jj)%ivlqc(ij,ji,jvar),2) .AND. &
+                     & .NOT. BTEST(inpfiles(jj)%idqc(ij,ji),2) ) THEN
+
+                     llvalprof = .TRUE. 
+                     EXIT loop_prof
+
+                  ENDIF
+               END DO
+
             END DO loop_prof
-            
+
             ! Set profile information
-            
+
             IF ( llvalprof ) THEN
-               
+
                iprof = iprof + 1
 
@@ -545,5 +592,5 @@
                profdata%nhou(iprof) = ihou
                profdata%nmin(iprof) = imin
-               
+
                ! Profile space coordinates
                profdata%rlam(iprof) = inpfiles(jj)%plam(ji)
@@ -551,10 +598,12 @@
 
                ! Coordinate search parameters
-               profdata%mi  (iprof,:) = inpfiles(jj)%iobsi(ji,1)
-               profdata%mj  (iprof,:) = inpfiles(jj)%iobsj(ji,1)
-               
+               DO jvar = 1, kvars
+                  profdata%mi  (iprof,jvar) = inpfiles(jj)%iobsi(ji,jvar)
+                  profdata%mj  (iprof,jvar) = inpfiles(jj)%iobsj(ji,jvar)
+               END DO
+
                ! Profile WMO number
                profdata%cwmo(iprof) = inpfiles(jj)%cdwmo(ji)
-               
+
                ! Instrument type
                READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
@@ -564,7 +613,7 @@
                   itype = 0
                ENDIF
-               
+
                profdata%ntyp(iprof) = itype
-               
+
                ! QC stuff
 
@@ -585,6 +634,6 @@
                profdata%nqc(iprof)  = 0 !TODO
 
-               loop_p : DO ij = 1, inpfiles(jj)%nlev            
-                  
+               loop_p : DO ij = 1, inpfiles(jj)%nlev
+
                   IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
                      & CYCLE
@@ -592,137 +641,85 @@
                   IF (ldsatt) THEN
 
-                     IF ( ( ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                        &     ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) .AND. &
-                        &     ldt3d ) .OR. &
-                        & ( ( ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                        &     ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) .AND. &
-                        &     lds3d ) ) THEN
-                        ip3dt = ip3dt + 1
-                     ELSE
-                        CYCLE
+                     DO jvar = 1, kvars
+                        IF ( ( .NOT. BTEST(inpfiles(jj)%ivlqc(ij,ji,jvar),2) .AND. &
+                           &   .NOT. BTEST(inpfiles(jj)%idqc(ij,ji),2) .AND. &
+                           &    ldvar(jvar) ) ) THEN
+                           ip3dt = ip3dt + 1
+                           EXIT
+                        ELSE IF ( jvar == kvars ) THEN
+                           CYCLE loop_p
+                        ENDIF
+                     END DO
+
+                  ENDIF
+
+                  DO jvar = 1, kvars
+                  
+                     IF ( ( .NOT. BTEST(inpfiles(jj)%ivlqc(ij,ji,jvar),2) .AND. &
+                       &   .NOT. BTEST(inpfiles(jj)%idqc(ij,ji),2) .AND. &
+                       &    ldvar(jvar) ) .OR. ldsatt ) THEN
+
+                        IF (ldsatt) THEN
+
+                           ivart(jvar) = ip3dt
+
+                        ELSE
+
+                           ivart(jvar) = ivart(jvar) + 1
+
+                        ENDIF
+
+                        ! Depth of jvar observation
+                        profdata%var(jvar)%vdep(ivart(jvar)) = &
+                           &                inpfiles(jj)%pdep(ij,ji)
+
+                        ! Depth of jvar observation QC
+                        profdata%var(jvar)%idqc(ivart(jvar)) = &
+                           &                inpfiles(jj)%idqc(ij,ji)
+
+                        ! Depth of jvar observation QC flags
+                        profdata%var(jvar)%idqcf(:,ivart(jvar)) = &
+                           &                inpfiles(jj)%idqcf(:,ij,ji)
+
+                        ! Profile index
+                        profdata%var(jvar)%nvpidx(ivart(jvar)) = iprof
+
+                        ! Vertical index in original profile
+                        profdata%var(jvar)%nvlidx(ivart(jvar)) = ij
+
+                        ! Profile jvar value
+                        IF ( .NOT. BTEST(inpfiles(jj)%ivlqc(ij,ji,jvar),2) .AND. &
+                           & .NOT. BTEST(inpfiles(jj)%idqc(ij,ji),2) ) THEN
+                           profdata%var(jvar)%vobs(ivart(jvar)) = &
+                              &                inpfiles(jj)%pob(ij,ji,jvar)
+                           IF ( ldmod ) THEN
+                              profdata%var(jvar)%vmod(ivart(jvar)) = &
+                                 &                inpfiles(jj)%padd(ij,ji,1,jvar)
+                           ENDIF
+                           ! Count number of profile var1 data as function of type
+                           itypvar( profdata%ntyp(iprof) + 1, jvar ) = &
+                              & itypvar( profdata%ntyp(iprof) + 1, jvar ) + 1
+                        ELSE
+                           profdata%var(jvar)%vobs(ivart(jvar)) = fbrmdi
+                        ENDIF
+
+                        ! Profile jvar qc
+                        profdata%var(jvar)%nvqc(ivart(jvar)) = &
+                           & inpfiles(jj)%ivlqc(ij,ji,jvar)
+
+                        ! Profile jvar qc flags
+                        profdata%var(jvar)%nvqcf(:,ivart(jvar)) = &
+                           & inpfiles(jj)%ivlqcf(:,ij,ji,jvar)
+
+                        ! Profile insitu T value
+                        IF ( TRIM( inpfiles(jj)%cname(jvar) ) == 'POTM' ) THEN
+                           profdata%var(jvar)%vext(ivart(jvar),1) = &
+                              &                inpfiles(jj)%pext(ij,ji,1)
+                        ENDIF
+
                      ENDIF
-                     
-                  ENDIF
-
-                  IF ( ( ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                     &     ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) .AND. &
-                     &       ldt3d ) .OR. ldsatt ) THEN
-                     
-                     IF (ldsatt) THEN
-
-                        it3dt = ip3dt
-
-                     ELSE
-
-                        it3dt = it3dt + 1
-                        
-                     ENDIF
-
-                     ! Depth of T observation
-                     profdata%var(1)%vdep(it3dt) = &
-                        &                inpfiles(jj)%pdep(ij,ji)
-                     
-                     ! Depth of T observation QC
-                     profdata%var(1)%idqc(it3dt) = &
-                        &                inpfiles(jj)%idqc(ij,ji)
-                     
-                     ! Depth of T observation QC flags
-                     profdata%var(1)%idqcf(:,it3dt) = &
-                        &                inpfiles(jj)%idqcf(:,ij,ji)
-                     
-                     ! Profile index
-                     profdata%var(1)%nvpidx(it3dt) = iprof
-                     
-                     ! Vertical index in original profile
-                     profdata%var(1)%nvlidx(it3dt) = ij
-
-                     ! Profile potential T value
-                     IF ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                        & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                        profdata%var(1)%vobs(it3dt) = &
-                           &                inpfiles(jj)%pob(ij,ji,1)
-                        IF ( ldmod ) THEN
-                           profdata%var(1)%vmod(it3dt) = &
-                              &                inpfiles(jj)%padd(ij,ji,1,1)
-                        ENDIF
-                        ! Count number of profile T data as function of type
-                        itypt( profdata%ntyp(iprof) + 1 ) = &
-                           & itypt( profdata%ntyp(iprof) + 1 ) + 1
-                     ELSE
-                        profdata%var(1)%vobs(it3dt) = fbrmdi
-                     ENDIF
-
-                     ! Profile T qc
-                     profdata%var(1)%nvqc(it3dt) = &
-                        & inpfiles(jj)%ivlqc(ij,ji,1)
-
-                     ! Profile T qc flags
-                     profdata%var(1)%nvqcf(:,it3dt) = &
-                        & inpfiles(jj)%ivlqcf(:,ij,ji,1)
-
-                     ! Profile insitu T value
-                     profdata%var(1)%vext(it3dt,1) = &
-                        &                inpfiles(jj)%pext(ij,ji,1)
-                     
-                  ENDIF
                   
-                  IF ( ( ( ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                     &   ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) .AND. &
-                     &   lds3d ) .OR. ldsatt ) THEN
-                     
-                     IF (ldsatt) THEN
-
-                        is3dt = ip3dt
-
-                     ELSE
-
-                        is3dt = is3dt + 1
-                        
-                     ENDIF
-
-                     ! Depth of S observation
-                     profdata%var(2)%vdep(is3dt) = &
-                        &                inpfiles(jj)%pdep(ij,ji)
-                     
-                     ! Depth of S observation QC
-                     profdata%var(2)%idqc(is3dt) = &
-                        &                inpfiles(jj)%idqc(ij,ji)
-                     
-                     ! Depth of S observation QC flags
-                     profdata%var(2)%idqcf(:,is3dt) = &
-                        &                inpfiles(jj)%idqcf(:,ij,ji)
-                     
-                     ! Profile index
-                     profdata%var(2)%nvpidx(is3dt) = iprof
-                     
-                     ! Vertical index in original profile
-                     profdata%var(2)%nvlidx(is3dt) = ij
-
-                     ! Profile S value
-                     IF ( ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                        & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                        profdata%var(2)%vobs(is3dt) = &
-                           &                inpfiles(jj)%pob(ij,ji,2)
-                        IF ( ldmod ) THEN
-                           profdata%var(2)%vmod(is3dt) = &
-                              &                inpfiles(jj)%padd(ij,ji,1,2)
-                        ENDIF
-                        ! Count number of profile S data as function of type
-                        ityps( profdata%ntyp(iprof) + 1 ) = &
-                           & ityps( profdata%ntyp(iprof) + 1 ) + 1
-                     ELSE
-                        profdata%var(2)%vobs(is3dt) = fbrmdi
-                     ENDIF
-                     
-                     ! Profile S qc
-                     profdata%var(2)%nvqc(is3dt) = &
-                        & inpfiles(jj)%ivlqc(ij,ji,2)
-
-                     ! Profile S qc flags
-                     profdata%var(2)%nvqcf(:,is3dt) = &
-                        & inpfiles(jj)%ivlqcf(:,ij,ji,2)
-
-                  ENDIF
-            
+                  END DO
+
                END DO loop_p
 
@@ -736,12 +733,14 @@
       ! Sum up over processors
       !-----------------------------------------------------------------------
-      
-      CALL obs_mpp_sum_integer ( it3dt0, it3dtmpp )
-      CALL obs_mpp_sum_integer ( is3dt0, is3dtmpp )
-      CALL obs_mpp_sum_integer ( ip3dt, ip3dtmpp )
-      
-      CALL obs_mpp_sum_integers( itypt, ityptmpp, ntyp1770 + 1 )
-      CALL obs_mpp_sum_integers( ityps, itypsmpp, ntyp1770 + 1 )
-      
+
+      DO jvar = 1, kvars
+         CALL obs_mpp_sum_integer ( ivart0(jvar), ivartmpp(jvar) )
+      END DO
+      CALL obs_mpp_sum_integer ( ip3dt,   ip3dtmpp  )
+
+      DO jvar = 1, kvars
+         CALL obs_mpp_sum_integers( itypvar(:,jvar), itypvarmpp(:,jvar), ntyp1770 + 1 )
+      END DO
+
       !-----------------------------------------------------------------------
       ! Output number of observations.
@@ -749,53 +748,36 @@
       IF(lwp) THEN
          WRITE(numout,*) 
-         WRITE(numout,'(1X,A)') 'Profile data'
+         WRITE(numout,'(A)') ' Profile data'
          WRITE(numout,'(1X,A)') '------------'
          WRITE(numout,*) 
-         WRITE(numout,'(1X,A)') 'Profile T data'
-         WRITE(numout,'(1X,A)') '--------------'
-         DO ji = 0, ntyp1770
-            IF ( ityptmpp(ji+1) > 0 ) THEN
-               WRITE(numout,'(1X,A3,1X,A48,A3,I8)') ctypshort(ji), &
-                  & cwmonam1770(ji)(1:52),' = ', &
-                  & ityptmpp(ji+1)
-            ENDIF
+         DO jvar = 1, kvars
+            WRITE(numout,'(1X,A)') 'Profile data, '//TRIM( profdata%cvars(jvar) )
+            WRITE(numout,'(1X,A)') '------------------------'
+            DO ji = 0, ntyp1770
+               IF ( itypvarmpp(ji+1,jvar) > 0 ) THEN
+                  WRITE(numout,'(1X,A3,1X,A48,A3,I8)') ctypshort(ji), &
+                     & cwmonam1770(ji)(1:52),' = ', &
+                     & itypvarmpp(ji+1,jvar)
+               ENDIF
+            END DO
+            WRITE(numout,'(1X,A)') &
+               & '---------------------------------------------------------------'
+            WRITE(numout,'(1X,A55,I8)') &
+               & 'Total profile data for variable '//TRIM( profdata%cvars(jvar) )// &
+               & '             = ', ivartmpp(jvar)
+            WRITE(numout,'(1X,A)') &
+               & '---------------------------------------------------------------'
+            WRITE(numout,*) 
          END DO
-         WRITE(numout,'(1X,A)') &
-            & '---------------------------------------------------------------'
-         WRITE(numout,'(1X,A55,I8)') &
-            & 'Total profile T data                                 = ',&
-            & it3dtmpp
-         WRITE(numout,'(1X,A)') &
-            & '---------------------------------------------------------------'
-         WRITE(numout,*) 
-         WRITE(numout,'(1X,A)') 'Profile S data'
-         WRITE(numout,'(1X,A)') '--------------'
-         DO ji = 0, ntyp1770
-            IF ( itypsmpp(ji+1) > 0 ) THEN
-               WRITE(numout,'(1X,A3,1X,A48,A3,I8)') ctypshort(ji), &
-                  & cwmonam1770(ji)(1:52),' = ', &
-                  & itypsmpp(ji+1)
-            ENDIF
+      ENDIF
+
+      IF (ldsatt) THEN
+         profdata%nvprot(:)    = ip3dt
+         profdata%nvprotmpp(:) = ip3dtmpp
+      ELSE
+         DO jvar = 1, kvars
+            profdata%nvprot(jvar)    = ivart(jvar)
+            profdata%nvprotmpp(jvar) = ivartmpp(jvar)
          END DO
-         WRITE(numout,'(1X,A)') &
-            & '---------------------------------------------------------------'
-         WRITE(numout,'(1X,A55,I8)') &
-            & 'Total profile S data                                 = ',&
-            & is3dtmpp
-         WRITE(numout,'(1X,A)') &
-            & '---------------------------------------------------------------'
-         WRITE(numout,*) 
-      ENDIF
-      
-      IF (ldsatt) THEN
-         profdata%nvprot(1)    = ip3dt
-         profdata%nvprot(2)    = ip3dt
-         profdata%nvprotmpp(1) = ip3dtmpp
-         profdata%nvprotmpp(2) = ip3dtmpp
-      ELSE
-         profdata%nvprot(1)    = it3dt
-         profdata%nvprot(2)    = is3dt
-         profdata%nvprotmpp(1) = it3dtmpp
-         profdata%nvprotmpp(2) = is3dtmpp
       ENDIF
       profdata%nprof        = iprof
@@ -804,15 +786,12 @@
       ! Model level search
       !-----------------------------------------------------------------------
-      IF ( ldt3d ) THEN
-         CALL obs_level_search( jpk, gdept_1d, &
-            & profdata%nvprot(1), profdata%var(1)%vdep, &
-            & profdata%var(1)%mvk )
-      ENDIF
-      IF ( lds3d ) THEN
-         CALL obs_level_search( jpk, gdept_1d, &
-            & profdata%nvprot(2), profdata%var(2)%vdep, &
-            & profdata%var(2)%mvk )
-      ENDIF
-      
+      DO jvar = 1, kvars
+         IF ( ldvar(jvar) ) THEN
+            CALL obs_level_search( jpk, gdept_1d, &
+               & profdata%nvprot(jvar), profdata%var(jvar)%vdep, &
+               & profdata%var(jvar)%mvk )
+         ENDIF
+      END DO
+
       !-----------------------------------------------------------------------
       ! Set model equivalent to 99999
@@ -826,5 +805,5 @@
       ! Deallocate temporary data
       !-----------------------------------------------------------------------
-      DEALLOCATE( ifileidx, iprofidx, zdat )
+      DEALLOCATE( ifileidx, iprofidx, zdat, clvars )
 
       !-----------------------------------------------------------------------
@@ -836,5 +815,5 @@
       DEALLOCATE( inpfiles )
 
-   END SUBROUTINE obs_rea_pro_dri
+   END SUBROUTINE obs_rea_prof
 
 END MODULE obs_read_prof
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_seaice.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_seaice.F90	(revision 10246)
+++ 	(revision )
@@ -1,465 +1,0 @@
-MODULE obs_read_seaice
-   !!======================================================================
-   !!                       ***  MODULE obs_read_seaice  ***
-   !! Observation diagnostics: Read the along track SEAICE data from
-   !!                          GHRSST or any SEAICE data from feedback files
-   !!======================================================================
-
-   !!----------------------------------------------------------------------
-   !!   obs_rea_seaice : Driver for reading seaice data from the GHRSST/feedback
-   !!----------------------------------------------------------------------
-
-   !! * Modules used   
-   USE par_kind                 ! Precision variables
-   USE in_out_manager           ! I/O manager
-   USE dom_oce                  ! Ocean space and time domain variables
-   USE obs_mpp                  ! MPP support routines for observation diagnostics
-   USE julian                   ! Julian date routines
-   USE obs_utils                ! Observation operator utility functions
-   USE obs_grid                 ! Grid search
-   USE obs_sort                 ! Sorting observation arrays
-   USE obs_surf_def             ! Surface observation definitions
-   USE obs_types                ! Observation type definitions
-   USE obs_seaice_io            ! I/O for seaice files
-   USE iom                      ! I/O of fields for Reynolds data
-   USE netcdf                   ! NetCDF library
-
-   IMPLICIT NONE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC obs_rea_seaice      ! Read the seaice observations from the point data
-   
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-   SUBROUTINE obs_rea_seaice( kformat, &
-      &                    seaicedata, knumfiles, cfilenames, &
-      &                    kvars, kextr, kstp, ddobsini, ddobsend, &
-      &                    ldignmis, ldmod )
-      !!---------------------------------------------------------------------
-      !!
-      !!                   *** ROUTINE obs_rea_seaice ***
-      !!
-      !! ** Purpose : Read from file the seaice data
-      !!
-      !! ** Method  : Depending on kformat either AVISO or
-      !!              feedback data files are read
-      !!
-      !! ** Action  : 
-      !!
-      !!
-      !! History :  
-      !!      ! :  2009-01 (K. Mogensen) Initial version based on old versions
-      !!----------------------------------------------------------------------
-      !! * Modules used
-
-      !! * Arguments
-      INTEGER :: kformat   ! Format of input data 
-      !                    ! 0: Feedback
-      !                    ! 1: GHRSST
-      TYPE(obs_surf), INTENT(INOUT) :: &
-         & seaicedata     ! seaice data to be read
-      INTEGER, INTENT(IN) :: knumfiles   ! Number of corio format files to read in
-      CHARACTER(LEN=128), INTENT(IN) :: cfilenames(knumfiles) ! File names to read in
-      INTEGER, INTENT(IN) :: kvars    ! Number of variables in seaicedata
-      INTEGER, INTENT(IN) :: kextr    ! Number of extra fields for each var in seaicedata
-      INTEGER, INTENT(IN) :: kstp     ! Ocean time-step index
-      LOGICAL, INTENT(IN) :: ldignmis   ! Ignore missing files
-      LOGICAL, INTENT(IN) :: ldmod      ! Initialize model from input data
-      REAL(KIND=dp), INTENT(IN) :: ddobsini    ! Obs. ini time in YYYYMMDD.HHMMSS
-      REAL(KIND=dp), INTENT(IN) :: ddobsend    ! Obs. end time in YYYYMMDD.HHMMSS
-         
-      !! * Local declarations
-      CHARACTER(LEN=14), PARAMETER :: cpname='obs_rea_seaice'
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jk
-      INTEGER :: iflag
-      INTEGER :: inobf
-      INTEGER :: i_file_id
-      INTEGER :: inowin
-      INTEGER :: iyea
-      INTEGER :: imon
-      INTEGER :: iday
-      INTEGER :: ihou
-      INTEGER :: imin
-      INTEGER :: isec
-      INTEGER, DIMENSION(knumfiles) :: &
-         & irefdate
-      INTEGER :: iobsmpp
-      INTEGER, PARAMETER :: iseaicemaxtype = 1024
-      INTEGER, DIMENSION(0:iseaicemaxtype) :: &
-         & ityp, &
-         & itypmpp
-      INTEGER, DIMENSION(:), ALLOCATABLE :: &
-         & iobsi,    &
-         & iobsj,    &
-         & iproc,    &
-         & iindx,    &
-         & ifileidx, &
-         & iseaiceidx
-      INTEGER :: itype
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zphi, &
-         & zlam
-      real(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zdat
-      LOGICAL :: llvalprof
-      TYPE(obfbdata), POINTER, DIMENSION(:) :: &
-         & inpfiles
-      real(wp), DIMENSION(knumfiles) :: &
-         & djulini, &
-         & djulend
-      INTEGER :: iobs
-      INTEGER :: iobstot
-      INTEGER :: ios
-      INTEGER :: ioserrcount
-      CHARACTER(len=8) :: cl_refdate
-   
-      ! Local initialization
-      iobs = 0
- 
-      !-----------------------------------------------------------------------
-      ! Check data the model part is just with feedback data files
-      !-----------------------------------------------------------------------
-      IF ( ldmod .AND. ( kformat /= 0 ) ) THEN
-         CALL ctl_stop( 'Model can only be read from feedback data' )
-         RETURN
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Count the number of files needed and allocate the obfbdata type
-      !-----------------------------------------------------------------------
-      
-      inobf = knumfiles
-      
-      ALLOCATE( inpfiles(inobf) )
-
-      seaice_files : DO jj = 1, inobf
-          
-         !---------------------------------------------------------------------
-         ! Prints
-         !---------------------------------------------------------------------
-         IF(lwp) THEN
-            WRITE(numout,*)
-            WRITE(numout,*) ' obs_rea_seaice : Reading from file = ', &
-               & TRIM( TRIM( cfilenames(jj) ) )
-            WRITE(numout,*) ' ~~~~~~~~~~~~~~'
-            WRITE(numout,*)
-         ENDIF
-
-         !---------------------------------------------------------------------
-         !  Initialization: Open file and get dimensions only
-         !---------------------------------------------------------------------
-         
-         iflag = nf90_open( TRIM( TRIM( cfilenames(jj) ) ), nf90_nowrite, &
-            &                      i_file_id )
-         
-         IF ( iflag /= nf90_noerr ) THEN
-
-            IF ( ldignmis ) THEN
-               inpfiles(jj)%nobs = 0
-               CALL ctl_warn( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ELSE 
-               CALL ctl_stop( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ENDIF
-
-         ELSE 
-            
-            !------------------------------------------------------------------
-            !  Close the file since it is opened in read_proffile
-            !------------------------------------------------------------------
-            
-            iflag = nf90_close( i_file_id )
-
-            !------------------------------------------------------------------
-            !  Read the profile file into inpfiles
-            !------------------------------------------------------------------
-            IF ( kformat == 0 ) THEN
-               CALL init_obfbdata( inpfiles(jj) )
-               IF(lwp) THEN
-                  WRITE(numout,*)
-                  WRITE(numout,*)'Reading from feedback file :', &
-                     &           TRIM( cfilenames(jj) )
-               ENDIF
-               CALL read_obfbdata( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                ldgrid = .TRUE. )
-               IF ( ldmod .AND. ( ( inpfiles(jj)%nadd == 0 ) .OR.&
-                  &               ( inpfiles(jj)%next < 2 ) ) ) THEN
-                  CALL ctl_stop( 'Model not in input data' )
-                  RETURN
-               ENDIF
-            ELSEIF ( kformat == 1) THEN
-               CALL read_seaice( TRIM( cfilenames(jj) ), inpfiles(jj), &
-               &                 numout, lwp, .TRUE. )
-            ELSE
-               CALL ctl_stop( 'File format unknown' )
-            ENDIF
-
-            !------------------------------------------------------------------
-            !  Change longitude (-180,180)
-            !------------------------------------------------------------------
-
-            DO ji = 1, inpfiles(jj)%nobs 
-
-               IF ( inpfiles(jj)%plam(ji) < -180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) + 360.
-
-               IF ( inpfiles(jj)%plam(ji) >  180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) - 360.
-
-            END DO
-
-            !------------------------------------------------------------------
-            !  Calculate the date  (change eventually)
-            !------------------------------------------------------------------
-            cl_refdate=inpfiles(jj)%cdjuldref(1:8)
-            READ(cl_refdate,'(I8)') irefdate(jj)
-            
-            CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
-               &           krefdate = irefdate(jj) )
-            CALL ddatetoymdhms( ddobsend, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulend(jj), &
-               &           krefdate = irefdate(jj) )
-            IF ( inpfiles(jj)%nobs > 0 ) THEN
-               inpfiles(jj)%iproc = -1
-               inpfiles(jj)%iobsi = -1
-               inpfiles(jj)%iobsj = -1
-            ENDIF
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-               ENDIF
-            END DO
-            ALLOCATE( zlam(inowin)  )
-            ALLOCATE( zphi(inowin)  )
-            ALLOCATE( iobsi(inowin) )
-            ALLOCATE( iobsj(inowin) )
-            ALLOCATE( iproc(inowin) )
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  zlam(inowin) = inpfiles(jj)%plam(ji)
-                  zphi(inowin) = inpfiles(jj)%pphi(ji)
-               ENDIF
-            END DO
-
-            CALL obs_grid_search( inowin, zlam, zphi, iobsi, iobsj, iproc, 'T' )
-
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  inpfiles(jj)%iproc(ji,1) = iproc(inowin)
-                  inpfiles(jj)%iobsi(ji,1) = iobsi(inowin)
-                  inpfiles(jj)%iobsj(ji,1) = iobsj(inowin)
-               ENDIF
-            END DO
-            DEALLOCATE( zlam, zphi, iobsi, iobsj, iproc )
-
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  IF ( nproc == 0 ) THEN
-                     IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-                  ELSE
-                     IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-                  ENDIF
-                  llvalprof = .FALSE.
-                  IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
-                     & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
-                     iobs = iobs + 1
-                  ENDIF
-               ENDIF
-            END DO
-
-         ENDIF
-
-      END DO seaice_files
-
-      !-----------------------------------------------------------------------
-      ! Get the time ordered indices of the input data
-      !-----------------------------------------------------------------------
-
-      !---------------------------------------------------------------------
-      !  Loop over input data files to count total number of profiles
-      !---------------------------------------------------------------------
-      iobstot = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               iobstot = iobstot + 1
-            ENDIF
-         END DO
-      END DO
-
-      ALLOCATE( iindx(iobstot), ifileidx(iobstot), &
-         &      iseaiceidx(iobstot), zdat(iobstot) )
-      jk = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               jk = jk + 1
-               ifileidx(jk) = jj
-               iseaiceidx(jk) = ji
-               zdat(jk)     = inpfiles(jj)%ptim(ji)
-            ENDIF
-         END DO
-      END DO
-      CALL sort_dp_indx( iobstot, &
-         &               zdat,     &
-         &               iindx   )
-      
-      CALL obs_surf_alloc( seaicedata, iobs, & 
-                           kvars, kextr, kstp, jpi, jpj )
-      
-      ! * Read obs/positions, QC, all variable and assign to seaicedata
- 
-      iobs = 0
-
-      ityp   (:) = 0
-      itypmpp(:) = 0
-
-      ioserrcount=0      
-
-      DO jk = 1, iobstot
-         
-         jj = ifileidx(iindx(jk))
-         ji = iseaiceidx(iindx(jk))
-         IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND.  &
-            & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
-            
-            IF ( nproc == 0 ) THEN
-               IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-            ELSE
-               IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-            ENDIF
-            
-            ! Set observation information
-            
-            IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
-               & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
-
-               iobs = iobs + 1
-
-               CALL jul2greg( isec,                   &
-                  &           imin,                   &
-                  &           ihou,                   &
-                  &           iday,                   &
-                  &           imon,                   &
-                  &           iyea,                   &
-                  &           inpfiles(jj)%ptim(ji), &
-                  &           irefdate(jj) )
-
-
-               ! seaice time coordinates
-               seaicedata%nyea(iobs) = iyea
-               seaicedata%nmon(iobs) = imon
-               seaicedata%nday(iobs) = iday
-               seaicedata%nhou(iobs) = ihou
-               seaicedata%nmin(iobs) = imin
-               
-               ! seaice space coordinates
-               seaicedata%rlam(iobs) = inpfiles(jj)%plam(ji)
-               seaicedata%rphi(iobs) = inpfiles(jj)%pphi(ji)
-
-               ! Coordinate search parameters
-               seaicedata%mi  (iobs) = inpfiles(jj)%iobsi(ji,1)
-               seaicedata%mj  (iobs) = inpfiles(jj)%iobsj(ji,1)
-               
-               ! Instrument type
-               READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
-901            IF ( ios /= 0 ) THEN
-                  IF (ioserrcount == 0) CALL ctl_warn ( 'Problem converting an instrument type to integer. Setting type to zero' ) 
-                  ioserrcount = ioserrcount + 1
-                  itype = 0
-               ENDIF
-               seaicedata%ntyp(iobs) = itype
-               IF ( itype < iseaicemaxtype + 1 ) THEN
-                  ityp(itype+1) = ityp(itype+1) + 1
-               ELSE
-                  IF(lwp)WRITE(numout,*)'WARNING:Increase iseaicemaxtype in ',&
-                     &                  cpname
-               ENDIF
-
-               ! Bookkeeping data to match observations
-               seaicedata%nsidx(iobs) = iobs
-               seaicedata%nsfil(iobs) = iindx(jk)
-
-               ! QC flags
-               seaicedata%nqc(iobs) = inpfiles(jj)%ivqc(ji,1)
-
-               ! Observed value
-               seaicedata%robs(iobs,1) = inpfiles(jj)%pob(1,ji,1)
-
-
-               ! Model and MDT is set to fbrmdi unless read from file
-               IF ( ldmod ) THEN
-                  seaicedata%rmod(iobs,1) = inpfiles(jj)%padd(1,ji,1,1)
-               ELSE
-                  seaicedata%rmod(iobs,1) = fbrmdi
-               ENDIF
-            ENDIF
-         ENDIF
-
-      END DO
-
-      !-----------------------------------------------------------------------
-      ! Sum up over processors
-      !-----------------------------------------------------------------------
-      
-      CALL obs_mpp_sum_integer( iobs, iobsmpp )
-      
-      !-----------------------------------------------------------------------
-      ! Output number of observations.
-      !-----------------------------------------------------------------------
-      IF (lwp) THEN
-
-         WRITE(numout,*)
-         WRITE(numout,'(1X,A)')'Seaice data types'
-         WRITE(numout,'(1X,A)')'-----------------'
-         DO jj = 1,8
-            IF ( itypmpp(jj) > 0 ) THEN
-               WRITE(numout,'(1X,A4,I4,A3,I10)')'Type ', jj,' = ',itypmpp(jj)
-            ENDIF
-         END DO
-         WRITE(numout,'(1X,A50)')'--------------------------------------------------'
-         WRITE(numout,'(1X,A40,I10)')'Total                                 = ',iobsmpp
-         WRITE(numout,*)
-
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Deallocate temporary data
-      !-----------------------------------------------------------------------
-      DEALLOCATE( ifileidx, iseaiceidx, zdat )
-
-      !-----------------------------------------------------------------------
-      ! Deallocate input data
-      !-----------------------------------------------------------------------
-      DO jj = 1, inobf
-         CALL dealloc_obfbdata( inpfiles(jj) )
-      END DO
-      DEALLOCATE( inpfiles )
-
-   END SUBROUTINE obs_rea_seaice
-
-END MODULE obs_read_seaice
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_sla.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_sla.F90	(revision 10246)
+++ 	(revision )
@@ -1,548 +1,0 @@
-MODULE obs_read_sla
-   !!======================================================================
-   !!                       ***  MODULE obs_read_sla  ***
-   !! Observation diagnostics: Read the along track SLA data from
-   !!                          the AVISO/CLS database or any SLA data 
-   !!                          from feedback files
-   !!======================================================================
-
-   !!----------------------------------------------------------------------
-   !!   obs_rea_sla : Driver for reading SLA data from the AVISO/CLS/feedback
-   !!----------------------------------------------------------------------
-
-   !! * Modules used   
-   USE par_kind                 ! Precision variables
-   USE in_out_manager           ! I/O manager
-   USE dom_oce                  ! Ocean space and time domain variables
-   USE obs_mpp                  ! MPP support routines for observation diagnostics
-   USE julian                   ! Julian date routines
-   USE obs_utils                ! Observation operator utility functions
-   USE obs_grid                 ! Grid search
-   USE obs_sort                 ! Sorting observation arrays
-   USE obs_surf_def             ! Surface observation definitions
-   USE obs_types                ! Observation type definitions
-   USE obs_sla_io               ! I/O for sla files
-   USE netcdf                   ! NetCDF library
-
-   IMPLICIT NONE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC obs_rea_sla  ! Read the SLA observations from the AVISO/SLA database
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-   SUBROUTINE obs_rea_sla( kformat, &
-      &                    sladata, knumfiles, cfilenames, &
-      &                    kvars, kextr, kstp, ddobsini, ddobsend, &
-      &                    ldignmis, ldmod, ldobstd )
-      !!---------------------------------------------------------------------
-      !!
-      !!                   *** ROUTINE obs_rea_sla ***
-      !!
-      !! ** Purpose : Read from file the SLA data
-      !!
-      !! ** Method  : Depending on kformat either AVISO or
-      !!              feedback data files are read
-      !!
-      !! ** Action  : 
-      !!
-      !!
-      !! History :  
-      !!      ! :  2009-01 (K. Mogensen) Initial version based on old versions
-      !!----------------------------------------------------------------------
-      !! * Modules used
-
-      !! * Arguments
-      INTEGER :: kformat    ! Format of input data
-      !                     ! 0: Feedback
-      !                     ! 1: AVISO
-      TYPE(obs_surf), INTENT(INOUT) :: sladata    ! SLA data to be read
-      INTEGER, INTENT(IN) :: knumfiles      ! Number of files to read in
-      CHARACTER(LEN=128), INTENT(IN) ::  &
-         & cfilenames(knumfiles) ! File names to read in
-      INTEGER, INTENT(IN) :: kvars     ! Number of variables in sladata
-      INTEGER, INTENT(IN) :: kextr     ! Number of extra fields for each var in sladata
-      INTEGER, INTENT(IN) :: kstp      ! Ocean time-step index
-      LOGICAL, INTENT(IN) :: ldignmis    ! Ignore missing files
-      LOGICAL, INTENT(IN) :: ldmod       ! Initialize model from input data
-      LOGICAL, INTENT(INOUT), optional :: &
-         & ldobstd        ! Read observation standard deviation from fb. file
-      REAL(KIND=dp), INTENT(IN) :: ddobsini  ! Obs. ini time in YYYYMMDD.HHMMSS
-      REAL(KIND=dp), INTENT(IN) :: ddobsend  ! Obs. end time in YYYYMMDD.HHMMSS
-         
-      !! * Local declarations
-      CHARACTER(LEN=11), PARAMETER :: cpname='obs_rea_sla'
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jk
-      INTEGER :: iflag
-      INTEGER :: inobf
-      INTEGER :: i_file_id
-      INTEGER :: inowin
-      INTEGER :: iyea
-      INTEGER :: imon
-      INTEGER :: iday
-      INTEGER :: ihou
-      INTEGER :: imin
-      INTEGER :: isec
-      INTEGER, DIMENSION(knumfiles) :: &
-         & irefdate
-      INTEGER :: iobsmpp
-      INTEGER, DIMENSION(imaxmissions+1) :: &
-         & ityp, &
-         & itypmpp
-      INTEGER, DIMENSION(:), ALLOCATABLE :: &
-         & iobsi,    &
-         & iobsj,    &
-         & iproc,    &
-         & iindx,    &
-         & ifileidx, &
-         & islaidx
-      INTEGER :: itype 
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zphi, &
-         & zlam
-      real(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zdat
-      LOGICAL :: llvalprof
-      LOGICAL :: llobstd
-      TYPE(obfbdata), POINTER, DIMENSION(:) :: &
-         & inpfiles
-      real(wp), DIMENSION(knumfiles) :: &
-         & djulini, &
-         & djulend
-      INTEGER, DIMENSION(knumfiles) :: &
-         & iobspos, &
-         & iobcpos
-      INTEGER :: iobs
-      INTEGER :: iobstot
-      INTEGER :: ios
-      INTEGER :: ioserrcount
-      CHARACTER(len=8) :: cl_refdate
-   
-      ! Local initialization
-      iobs = 0
-      IF ( PRESENT(ldobstd) ) THEN
-         IF (.NOT.ldmod) THEN
-            llobstd = .false.
-         ELSE
-            llobstd = ldobstd
-         ENDIF
-      ELSE
-         llobstd = .FALSE.
-      ENDIF
- 
-      !-----------------------------------------------------------------------
-      ! Check that the model part is just with feedback data files
-      !-----------------------------------------------------------------------
-      IF ( ldmod .AND. ( kformat /= 0 ) ) THEN
-         CALL ctl_stop( 'Model can only be read from feedback data' )
-         RETURN
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Check that the prescribed obs err is just with feedback data files
-      !-----------------------------------------------------------------------
-      IF ( llobstd .AND. ( kformat /= 0 ) ) THEN
-         CALL ctl_stop( 'Observation error can only be read from feedback files' )
-         RETURN
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Count the number of files needed and allocate the obfbdata type
-      !-----------------------------------------------------------------------
-      
-      inobf = knumfiles
-      
-      ALLOCATE( inpfiles(inobf) )
-
-      sla_files : DO jj = 1, inobf
-          
-         !---------------------------------------------------------------------
-         ! Prints
-         !---------------------------------------------------------------------
-         IF(lwp) THEN
-            WRITE(numout,*)
-            WRITE(numout,*) ' obs_rea_sla : Reading from file = ', &
-               & TRIM( TRIM( cfilenames(jj) ) )
-            WRITE(numout,*) ' ~~~~~~~~~~~'
-            WRITE(numout,*)
-         ENDIF
-
-         !---------------------------------------------------------------------
-         !  Initialization: Open file and get dimensions only
-         !---------------------------------------------------------------------
-         
-         iflag = nf90_open( TRIM( TRIM( cfilenames(jj) ) ), nf90_nowrite, &
-            &                      i_file_id )
-         
-         IF ( iflag /= nf90_noerr ) THEN
-
-            IF ( ldignmis ) THEN
-               inpfiles(jj)%nobs = 0
-               CALL ctl_warn( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ELSE 
-               CALL ctl_stop( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ENDIF
-
-         ELSE 
-            
-            !------------------------------------------------------------------
-            !  Close the file since it is opened in read_proffile
-            !------------------------------------------------------------------
-            
-            iflag = nf90_close( i_file_id )
-
-            !------------------------------------------------------------------
-            !  Read the profile file into inpfiles
-            !------------------------------------------------------------------
-            IF ( kformat == 0 ) THEN
-               CALL init_obfbdata( inpfiles(jj) )
-               IF(lwp) THEN
-                  WRITE(numout,*)
-                  WRITE(numout,*)'Reading from feedback file :', &
-                     &           TRIM( cfilenames(jj) )
-               ENDIF
-               CALL read_obfbdata( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                ldgrid = .TRUE. )
-               IF ( inpfiles(jj)%nvar < 1 ) THEN
-                  CALL ctl_stop( 'Feedback format error' )
-                  RETURN
-               ENDIF
-               IF ( TRIM(inpfiles(jj)%cname(1)) /= 'SLA' ) THEN
-                  CALL ctl_stop( 'Feedback format error' )
-                  RETURN
-               ENDIF 
-               IF ( ldmod .AND. ( ( inpfiles(jj)%nadd == 0 ) .OR.&
-                  &               ( inpfiles(jj)%next == 0 ) ) ) THEN
-                  CALL ctl_stop( 'Model not in input data' )
-                  RETURN
-               ENDIF
-            ELSEIF ( kformat == 1) THEN
-               CALL read_avisofile( TRIM( cfilenames(jj) ), inpfiles(jj), &
-               &                    numout, lwp, .TRUE. )
-            ELSE
-               CALL ctl_stop( 'File format unknown' )
-            ENDIF
-
-            !------------------------------------------------------------------
-            !  Change longitude (-180,180)
-            !------------------------------------------------------------------
-
-            DO ji = 1, inpfiles(jj)%nobs 
-
-               IF ( inpfiles(jj)%plam(ji) < -180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) + 360.
-
-               IF ( inpfiles(jj)%plam(ji) >  180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) - 360.
-
-            END DO
-
-            !------------------------------------------------------------------
-            !  Calculate the date  (change eventually)
-            !------------------------------------------------------------------
-            cl_refdate=inpfiles(jj)%cdjuldref(1:8)
-            READ(cl_refdate,'(I8)') irefdate(jj)
-            
-            CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
-               &           krefdate = irefdate(jj) )
-            CALL ddatetoymdhms( ddobsend, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulend(jj), &
-               &           krefdate = irefdate(jj) )
-            IF ( inpfiles(jj)%nobs > 0 ) THEN
-               inpfiles(jj)%iproc = -1
-               inpfiles(jj)%iobsi = -1
-               inpfiles(jj)%iobsj = -1
-            ENDIF
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-               ENDIF
-            END DO
-            ALLOCATE( zlam(inowin)  )
-            ALLOCATE( zphi(inowin)  )
-            ALLOCATE( iobsi(inowin) )
-            ALLOCATE( iobsj(inowin) )
-            ALLOCATE( iproc(inowin) )
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  zlam(inowin) = inpfiles(jj)%plam(ji)
-                  zphi(inowin) = inpfiles(jj)%pphi(ji)
-               ENDIF
-            END DO
-
-            CALL obs_grid_search( inowin, zlam, zphi, iobsi, iobsj, iproc, 'T' )
-
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  inpfiles(jj)%iproc(ji,1) = iproc(inowin)
-                  inpfiles(jj)%iobsi(ji,1) = iobsi(inowin)
-                  inpfiles(jj)%iobsj(ji,1) = iobsj(inowin)
-               ENDIF
-            END DO
-            DEALLOCATE( zlam, zphi, iobsi, iobsj, iproc )
-
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-               IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  IF ( nproc == 0 ) THEN
-                     IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-                  ELSE
-                     IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-                  ENDIF
-                  llvalprof = .FALSE.
-                  IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
-                     & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
-                     iobs = iobs + 1
-                  ENDIF
-               ENDIF
-            END DO
-
-         ENDIF
-      
-      END DO sla_files
-
-      IF (llobstd) THEN
-         
-         DO jj = 1, inobf
-            iobspos(jj) = -1
-            iobcpos(jj) = -1
-            DO ji = 1,inpfiles(jj)%nadd
-               IF ( TRIM(inpfiles(jj)%caddname(ji)) == 'OSTD' ) THEN
-                  iobspos(jj)=ji
-               ENDIF
-               IF ( TRIM(inpfiles(jj)%caddname(ji)) == 'OCNT' ) THEN
-                  iobcpos(jj)=ji
-               ENDIF
-            END DO
-         END DO
-         llobstd = ( ( MINVAL(iobspos) > 0 ) .AND. ( MINVAL(iobcpos) > 0 ) )
-         IF (llobstd) THEN
-            IF (lwp) WRITE(numout,*)'SLA superobs information present.'
-         ELSE
-            IF (lwp) WRITE(numout,*)'SLA superobs information not present.'
-         ENDIF
-
-      ENDIF
-      
-      !-----------------------------------------------------------------------
-      ! Get the time ordered indices of the input data
-      !-----------------------------------------------------------------------
-
-      !---------------------------------------------------------------------
-      !  Loop over input data files to count total number of profiles
-      !---------------------------------------------------------------------
-      iobstot = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-            IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               iobstot = iobstot + 1
-            ENDIF
-         END DO
-      END DO
-
-      ALLOCATE( iindx(iobstot), ifileidx(iobstot), &
-         &      islaidx(iobstot), zdat(iobstot) )
-      jk = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-            IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               jk = jk + 1
-               ifileidx(jk) = jj
-               islaidx(jk) = ji
-               zdat(jk)     = inpfiles(jj)%ptim(ji)
-            ENDIF
-         END DO
-      END DO
-      CALL sort_dp_indx( iobstot, &
-         &               zdat,     &
-         &               iindx   )
-      
-      CALL obs_surf_alloc( sladata, iobs, kvars, kextr, kstp, jpi, jpj )
-      
-      ! * Read obs/positions, QC, all variable and assign to sladata
- 
-      iobs = 0
-
-      ityp   (:) = 0
-      itypmpp(:) = 0
-
-      ioserrcount = 0
-      
-      DO jk = 1, iobstot
-         
-         jj = ifileidx(iindx(jk))
-         ji = islaidx(iindx(jk))
-
-         IF ( inpfiles(jj)%ioqc(ji) > 2 ) CYCLE
-         IF ( inpfiles(jj)%ivqc(ji,1) > 2 ) CYCLE
-
-         IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND.  &
-            & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
-            
-            IF ( nproc == 0 ) THEN
-               IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-            ELSE
-               IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-            ENDIF
-            
-            ! Set observation information
-            
-            IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
-               & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
-
-               iobs = iobs + 1
-
-               CALL jul2greg( isec,                   &
-                  &           imin,                   &
-                  &           ihou,                   &
-                  &           iday,                   &
-                  &           imon,                   &
-                  &           iyea,                   &
-                  &           inpfiles(jj)%ptim(ji), &
-                  &           irefdate(jj) )
-
-
-               ! SLA time coordinates
-               sladata%nyea(iobs) = iyea
-               sladata%nmon(iobs) = imon
-               sladata%nday(iobs) = iday
-               sladata%nhou(iobs) = ihou
-               sladata%nmin(iobs) = imin
-               
-               ! SLA space coordinates
-               sladata%rlam(iobs) = inpfiles(jj)%plam(ji)
-               sladata%rphi(iobs) = inpfiles(jj)%pphi(ji)
-
-               ! Coordinate search parameters
-               sladata%mi  (iobs) = inpfiles(jj)%iobsi(ji,1)
-               sladata%mj  (iobs) = inpfiles(jj)%iobsj(ji,1)
-               
-               ! Instrument type
-               READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
-901            IF ( ios /= 0 ) THEN
-                  IF (ioserrcount == 0) CALL ctl_warn ( 'Problem converting an instrument type to integer. Setting type to zero' ) 
-                  ioserrcount = ioserrcount + 1
-                  itype = 0
-               ENDIF
-               sladata%ntyp(iobs) = itype
-               ityp(itype+1) = ityp(itype+1) + 1
-
-               ! Identifier
-               sladata%cwmo(iobs) = inpfiles(jj)%cdwmo(ji)
-
-               ! Bookkeeping data to match observations
-               sladata%nsidx(iobs) = iobs
-               sladata%nsfil(iobs) = iindx(jk)
-
-               ! QC flags
-               sladata%nqc(iobs) = inpfiles(jj)%ivqc(ji,1)
-
-               ! Observed value
-               sladata%robs(iobs,1) = inpfiles(jj)%pob(1,ji,1)
-
-
-               ! Model and MDT is set to fbrmdi unless read from file
-               IF ( ldmod ) THEN
-                  sladata%rmod(iobs,1) = inpfiles(jj)%padd(1,ji,1,1)
-                  sladata%rext(iobs,1) = inpfiles(jj)%padd(1,ji,2,1)
-                  sladata%rext(iobs,2) = inpfiles(jj)%pext(1,ji,1)
-                  IF (llobstd) THEN
-                     sladata%rext(iobs,3) = &
-                        & inpfiles(jj)%padd(1,ji,iobspos(jj),1)
-                     sladata%rext(iobs,4) = &
-                        & inpfiles(jj)%padd(1,ji,iobcpos(jj),1)
-                  ENDIF
-               ELSE
-                  sladata%rmod(iobs,1) = fbrmdi
-                  sladata%rext(iobs,:) = fbrmdi
-               ENDIF
-
-            ENDIF
-         ENDIF
-
-      END DO
-
-      !-----------------------------------------------------------------------
-      ! Sum up over processors
-      !-----------------------------------------------------------------------
-      
-      CALL obs_mpp_sum_integer( iobs, iobsmpp )
-      CALL obs_mpp_sum_integers( ityp, itypmpp, imaxmissions + 1 )
-      
-      !-----------------------------------------------------------------------
-      ! Output number of observations.
-      !-----------------------------------------------------------------------
-      IF (lwp) THEN
-
-         WRITE(numout,*)
-         WRITE(numout,'(1X,A)')'Altimeter satellites'
-         WRITE(numout,'(1X,A)')'--------------------'
-         DO jj = 1,8
-            IF ( itypmpp(jj) > 0 ) THEN
-               WRITE(numout,'(1X,A38,A2,I10)')calttyp(jj-1),'= ',itypmpp(jj)
-            ENDIF
-         END DO
-         WRITE(numout,'(1X,A50)')'--------------------------------------------------'
-         WRITE(numout,'(1X,A40,I10)')'Total                                 = ',iobsmpp
-         WRITE(numout,*)
-
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Deallocate temporary data
-      !-----------------------------------------------------------------------
-      DEALLOCATE( ifileidx, islaidx, zdat )
-
-      !-----------------------------------------------------------------------
-      ! Deallocate input data
-      !-----------------------------------------------------------------------
-      DO jj = 1, inobf
-         CALL dealloc_obfbdata( inpfiles(jj) )
-      END DO
-      DEALLOCATE( inpfiles )
-
-      !-----------------------------------------------------------------------
-      ! Reset ldobstd if the data is present
-      !-----------------------------------------------------------------------
-      IF ( PRESENT(ldobstd) ) THEN
-         ldobstd = llobstd
-      ENDIF
-
-   END SUBROUTINE obs_rea_sla
-
-END MODULE obs_read_sla
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_sst.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_sst.F90	(revision 10246)
+++ 	(revision )
@@ -1,771 +1,0 @@
-MODULE obs_read_sst
-   !!======================================================================
-   !!                       ***  MODULE obs_read_sst  ***
-   !! Observation diagnostics: Read the SST data from the GHRSST database 
-   !!                          or any SST data from feedback files
-   !!======================================================================
-
-   !!----------------------------------------------------------------------
-   !!   obs_rea_sst : Driver for reading SST data from the GHRSST/feedback
-   !!   obs_rea_sst_rey : Driver for reading SST data from Reynolds
-   !!----------------------------------------------------------------------
-
-   !! * Modules used   
-   USE par_kind                 ! Precision variables
-   USE in_out_manager           ! I/O manager
-   USE dom_oce                  ! Ocean space and time domain variables
-   USE obs_mpp                  ! MPP support routines for observation diagnostics
-   USE julian                   ! Julian date routines
-   USE obs_utils                ! Observation operator utility functions
-   USE obs_grid                 ! Grid search
-   USE obs_sort                 ! Sorting observation arrays
-   USE obs_surf_def             ! Surface observation definitions
-   USE obs_types                ! Observation type definitions
-   USE obs_sst_io               ! I/O for sst files
-   USE iom                      ! I/O of fields for Reynolds data
-   USE netcdf                   ! NetCDF library
-
-   IMPLICIT NONE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC obs_rea_sst      ! Read the SST observations from the point data
-   PUBLIC obs_rea_sst_rey  ! Read the gridded Reynolds SST 
-   
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-   SUBROUTINE obs_rea_sst( kformat, &
-      &                    sstdata, knumfiles, cfilenames, &
-      &                    kvars, kextr, kstp, ddobsini, ddobsend, &
-      &                    ldignmis, ldmod )
-      !!---------------------------------------------------------------------
-      !!
-      !!                   *** ROUTINE obs_rea_sst ***
-      !!
-      !! ** Purpose : Read from file the SST data
-      !!
-      !! ** Method  : Depending on kformat either AVISO or
-      !!              feedback data files are read
-      !!
-      !! ** Action  : 
-      !!
-      !!
-      !! History :  
-      !!      ! :  2009-01 (K. Mogensen) Initial version based on old versions
-      !!----------------------------------------------------------------------
-      !! * Modules used
-
-      !! * Arguments
-      INTEGER :: kformat   ! Format of input data
-      !                    ! 0: Feedback
-      !                    ! 1: GHRSST
-      TYPE(obs_surf), INTENT(INOUT) :: sstdata   ! SST data to be read
-      INTEGER, INTENT(IN) :: knumfiles    ! Number of corio format files to read in
-      CHARACTER(LEN=128), INTENT(IN) :: cfilenames(knumfiles) ! File names to read in
-      INTEGER, INTENT(IN) :: kvars      ! Number of variables in sstdata
-      INTEGER, INTENT(IN) :: kextr      ! Number of extra fields for each var in sstdata
-      INTEGER, INTENT(IN) :: kstp       ! Ocean time-step index
-      LOGICAL, INTENT(IN) :: ldignmis   ! Ignore missing files
-      LOGICAL, INTENT(IN) :: ldmod      ! Initialize model from input data
-      REAL(KIND=dp), INTENT(IN) :: ddobsini   ! Obs. ini time in YYYYMMDD.HHMMSS
-      REAL(KIND=dp), INTENT(IN) :: ddobsend   ! Obs. end time in YYYYMMDD.HHMMSS
-         
-      !! * Local declarations
-      CHARACTER(LEN=11), PARAMETER :: cpname='obs_rea_sst'
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jk
-      INTEGER :: iflag
-      INTEGER :: inobf
-      INTEGER :: i_file_id
-      INTEGER :: inowin
-      INTEGER :: iyea
-      INTEGER :: imon
-      INTEGER :: iday
-      INTEGER :: ihou
-      INTEGER :: imin
-      INTEGER :: isec
-      INTEGER, DIMENSION(knumfiles) :: irefdate
-      INTEGER :: iobsmpp
-      INTEGER, PARAMETER :: isstmaxtype = 1024
-      INTEGER, DIMENSION(0:isstmaxtype) :: &
-         & ityp, &
-         & itypmpp
-      INTEGER, DIMENSION(:), ALLOCATABLE :: &
-         & iobsi,    &
-         & iobsj,    &
-         & iproc,    &
-         & iindx,    &
-         & ifileidx, &
-         & isstidx
-      INTEGER :: itype
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zphi, &
-         & zlam
-      real(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zdat
-      LOGICAL :: llvalprof
-      TYPE(obfbdata), POINTER, DIMENSION(:) :: &
-         & inpfiles
-      real(wp), DIMENSION(knumfiles) :: &
-         & djulini, &
-         & djulend
-      INTEGER :: iobs
-      INTEGER :: iobstot
-      INTEGER :: ios
-      INTEGER :: ioserrcount
-      CHARACTER(len=8) :: cl_refdate
-   
-      ! Local initialization
-      iobs = 0
- 
-      !-----------------------------------------------------------------------
-      ! Check data the model part is just with feedback data files
-      !-----------------------------------------------------------------------
-      IF ( ldmod .AND. ( kformat /= 0 ) ) THEN
-         CALL ctl_stop( 'Model can only be read from feedback data' )
-         RETURN
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Count the number of files needed and allocate the obfbdata type
-      !-----------------------------------------------------------------------
-      
-      inobf = knumfiles
-      
-      ALLOCATE( inpfiles(inobf) )
-
-      sst_files : DO jj = 1, inobf
-
-         CALL init_obfbdata( inpfiles(jj) )
-          
-         !---------------------------------------------------------------------
-         ! Prints
-         !---------------------------------------------------------------------
-         IF(lwp) THEN
-            WRITE(numout,*)
-            WRITE(numout,*) ' obs_rea_sst : Reading from file = ', &
-               & TRIM( TRIM( cfilenames(jj) ) )
-            WRITE(numout,*) ' ~~~~~~~~~~~'
-            WRITE(numout,*)
-         ENDIF
-
-         !---------------------------------------------------------------------
-         !  Initialization: Open file and get dimensions only
-         !---------------------------------------------------------------------
-         
-         iflag = nf90_open( TRIM( TRIM( cfilenames(jj) ) ), nf90_nowrite, &
-            &                      i_file_id )
-         
-         IF ( iflag /= nf90_noerr ) THEN
-
-            IF ( ldignmis ) THEN
-               inpfiles(jj)%nobs = 0
-               CALL ctl_warn( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ELSE 
-               CALL ctl_stop( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ENDIF
-
-         ELSE 
-            
-            !------------------------------------------------------------------
-            !  Close the file since it is opened in read_proffile
-            !------------------------------------------------------------------
-            
-            iflag = nf90_close( i_file_id )
-
-            !------------------------------------------------------------------
-            !  Read the profile file into inpfiles
-            !------------------------------------------------------------------
-            IF ( kformat == 0 ) THEN
-               IF(lwp) THEN
-                  WRITE(numout,*)
-                  WRITE(numout,*)'Reading from feedback file :', &
-                     &           TRIM( cfilenames(jj) )
-               ENDIF
-               CALL read_obfbdata( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                ldgrid = .TRUE. )
-               IF ( ldmod .AND. ( inpfiles(jj)%nadd == 0 ) ) THEN
-                  CALL ctl_stop( 'Model not in input data' )
-                  RETURN
-               ENDIF
-            ELSEIF ( kformat == 1) THEN
-               CALL read_ghrsst( TRIM( cfilenames(jj) ), inpfiles(jj), &
-               &                 numout, lwp, .TRUE. )
-            ELSE
-               CALL ctl_stop( 'File format unknown' )
-            ENDIF
-
-            !------------------------------------------------------------------
-            !  Change longitude (-180,180)
-            !------------------------------------------------------------------
-
-            DO ji = 1, inpfiles(jj)%nobs 
-
-               IF ( inpfiles(jj)%plam(ji) < -180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) + 360.
-
-               IF ( inpfiles(jj)%plam(ji) >  180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) - 360.
-
-            END DO
-
-            !------------------------------------------------------------------
-            !  Calculate the date  (change eventually)
-            !------------------------------------------------------------------
-            cl_refdate=inpfiles(jj)%cdjuldref(1:8)
-            READ(cl_refdate,'(I8)') irefdate(jj)
-            
-            CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
-               &           krefdate = irefdate(jj) )
-            CALL ddatetoymdhms( ddobsend, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulend(jj), &
-               &           krefdate = irefdate(jj) )
-            IF ( inpfiles(jj)%nobs > 0 ) THEN
-               inpfiles(jj)%iproc = -1
-               inpfiles(jj)%iobsi = -1
-               inpfiles(jj)%iobsj = -1
-            ENDIF
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-               ENDIF
-            END DO
-            ALLOCATE( zlam(inowin)  )
-            ALLOCATE( zphi(inowin)  )
-            ALLOCATE( iobsi(inowin) )
-            ALLOCATE( iobsj(inowin) )
-            ALLOCATE( iproc(inowin) )
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  zlam(inowin) = inpfiles(jj)%plam(ji)
-                  zphi(inowin) = inpfiles(jj)%pphi(ji)
-               ENDIF
-            END DO
-
-            CALL obs_grid_search( inowin, zlam, zphi, iobsi, iobsj, iproc, 'T' )
-
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  inpfiles(jj)%iproc(ji,1) = iproc(inowin)
-                  inpfiles(jj)%iobsi(ji,1) = iobsi(inowin)
-                  inpfiles(jj)%iobsj(ji,1) = iobsj(inowin)
-               ENDIF
-            END DO
-            DEALLOCATE( zlam, zphi, iobsi, iobsj, iproc )
-
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  IF ( nproc == 0 ) THEN
-                     IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-                  ELSE
-                     IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-                  ENDIF
-                  llvalprof = .FALSE.
-                  IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
-                     & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
-                     iobs = iobs + 1
-                  ENDIF
-               ENDIF
-            END DO
-
-         ENDIF
-
-      END DO sst_files
-
-      !-----------------------------------------------------------------------
-      ! Get the time ordered indices of the input data
-      !-----------------------------------------------------------------------
-
-      !---------------------------------------------------------------------
-      !  Loop over input data files to count total number of profiles
-      !---------------------------------------------------------------------
-      iobstot = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               iobstot = iobstot + 1
-            ENDIF
-         END DO
-      END DO
-
-      ALLOCATE( iindx(iobstot), ifileidx(iobstot), &
-         &      isstidx(iobstot), zdat(iobstot) )
-      jk = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               jk = jk + 1
-               ifileidx(jk) = jj
-               isstidx(jk) = ji
-               zdat(jk)     = inpfiles(jj)%ptim(ji)
-            ENDIF
-         END DO
-      END DO
-      CALL sort_dp_indx( iobstot, &
-         &               zdat,     &
-         &               iindx   )
-      
-      CALL obs_surf_alloc( sstdata, iobs, kvars, kextr, kstp, jpi, jpj )
-      
-      ! * Read obs/positions, QC, all variable and assign to sstdata
- 
-      iobs = 0
-
-      ityp   (:) = 0
-      itypmpp(:) = 0
-      
-      ioserrcount = 0
-      
-      DO jk = 1, iobstot
-         
-         jj = ifileidx(iindx(jk))
-         ji = isstidx(iindx(jk))
-         IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND.  &
-            & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
-            
-            IF ( nproc == 0 ) THEN
-               IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-            ELSE
-               IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-            ENDIF
-            
-            ! Set observation information
-            
-            IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
-               & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
-
-               iobs = iobs + 1
-
-               CALL jul2greg( isec,                   &
-                  &           imin,                   &
-                  &           ihou,                   &
-                  &           iday,                   &
-                  &           imon,                   &
-                  &           iyea,                   &
-                  &           inpfiles(jj)%ptim(ji), &
-                  &           irefdate(jj) )
-
-
-               ! SST time coordinates
-               sstdata%nyea(iobs) = iyea
-               sstdata%nmon(iobs) = imon
-               sstdata%nday(iobs) = iday
-               sstdata%nhou(iobs) = ihou
-               sstdata%nmin(iobs) = imin
-               
-               ! SST space coordinates
-               sstdata%rlam(iobs) = inpfiles(jj)%plam(ji)
-               sstdata%rphi(iobs) = inpfiles(jj)%pphi(ji)
-
-               ! Coordinate search parameters
-               sstdata%mi  (iobs) = inpfiles(jj)%iobsi(ji,1)
-               sstdata%mj  (iobs) = inpfiles(jj)%iobsj(ji,1)
-               
-               ! Instrument type
-               READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
-901            IF ( ios /= 0 ) THEN
-                  IF (ioserrcount == 0) CALL ctl_warn ( 'Problem converting an instrument type to integer. Setting type to zero' ) 
-                  ioserrcount = ioserrcount + 1
-                  itype = 0
-               ENDIF
-               sstdata%ntyp(iobs) = itype
-               IF ( itype < isstmaxtype + 1 ) THEN
-                  ityp(itype+1) = ityp(itype+1) + 1
-               ELSE
-                  IF(lwp)WRITE(numout,*)'WARNING:Increase isstmaxtype in ',&
-                     &                  cpname
-               ENDIF
-
-               ! Bookkeeping data to match observations
-               sstdata%nsidx(iobs) = iobs
-               sstdata%nsfil(iobs) = iindx(jk)
-
-               ! QC flags
-               sstdata%nqc(iobs) = inpfiles(jj)%ivqc(ji,1)
-
-               ! Observed value
-               sstdata%robs(iobs,1) = inpfiles(jj)%pob(1,ji,1)
-
-
-               ! Model and MDT is set to fbrmdi unless read from file
-               IF ( ldmod ) THEN
-                  sstdata%rmod(iobs,1) = inpfiles(jj)%padd(1,ji,1,1)
-               ELSE
-                  sstdata%rmod(iobs,1) = fbrmdi
-               ENDIF
-            ENDIF
-         ENDIF
-
-      END DO
-
-      !-----------------------------------------------------------------------
-      ! Sum up over processors
-      !-----------------------------------------------------------------------
-      
-      CALL obs_mpp_sum_integer( iobs, iobsmpp )
-      
-      !-----------------------------------------------------------------------
-      ! Output number of observations.
-      !-----------------------------------------------------------------------
-      IF (lwp) THEN
-
-         WRITE(numout,*)
-         WRITE(numout,'(1X,A)')'SST data types'
-         WRITE(numout,'(1X,A)')'--------------'
-         DO jj = 1,8
-            IF ( itypmpp(jj) > 0 ) THEN
-               WRITE(numout,'(1X,A4,I4,A3,I10)')'Type ', jj,' = ',itypmpp(jj)
-            ENDIF
-         END DO
-         WRITE(numout,'(1X,A50)')'--------------------------------------------------'
-         WRITE(numout,'(1X,A40,I10)')'Total                                 = ',iobsmpp
-         WRITE(numout,*)
-
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Deallocate temporary data
-      !-----------------------------------------------------------------------
-      DEALLOCATE( ifileidx, isstidx, zdat )
-
-      !-----------------------------------------------------------------------
-      ! Deallocate input data
-      !-----------------------------------------------------------------------
-      DO jj = 1, inobf
-         IF ( inpfiles(jj)%lalloc ) THEN
-            CALL dealloc_obfbdata( inpfiles(jj) )
-         ENDIF
-      END DO
-      DEALLOCATE( inpfiles )
-
-   END SUBROUTINE obs_rea_sst
-
-   SUBROUTINE obs_rea_sst_rey( sstname, cdsstfmt, sstdata, kvars, kextra, &
-      &                        kstp, ddobsini, ddobsend )
-      !!---------------------------------------------------------------------
-      !!
-      !!                   *** ROUTINE obs_rea_sst ***
-      !!
-      !! ** Purpose : Read from file the pseudo SST data from Reynolds
-      !!
-      !! ** Method  : 
-      !!
-      !! ** Action  : 
-      !!
-      !! References : 
-      !!
-      !! History :  
-      !!      ! :  
-      !!----------------------------------------------------------------------
-      !! * Modules used
-      USE par_oce          ! Ocean parameters
-   
-      !! * Arguments
-      CHARACTER(len=128), INTENT(IN) :: sstname   ! Generic file name
-      CHARACTER(len=12), INTENT(IN) :: cdsstfmt   ! Format of SST files (yearly/monthly)
-      TYPE(obs_surf), INTENT(INOUT) :: sstdata    ! SST data
-      REAL(KIND=dp), INTENT(IN) :: ddobsini    ! Obs. ini time in YYYYMMDD.HHMMSS
-      REAL(KIND=dp), INTENT(IN) :: ddobsend    ! Obs. end time in YYYYMMDD.HHMMSS
-      INTEGER, INTENT(IN) :: kvars      ! Number of variables in sstdata structures
-      INTEGER, INTENT(IN) :: kextra     ! Number of extra variables in sstdata structures
-      INTEGER, INTENT(IN) :: kstp       ! Ocean time-step index
-      
-      INTEGER :: iyear
-      INTEGER :: imon
-      INTEGER :: iday
-      INTEGER :: ihour
-      INTEGER :: imin
-      INTEGER :: isec
-      INTEGER :: ihhmmss
-      INTEGER :: iyear1
-      INTEGER :: iyear2
-      INTEGER :: imon1
-      INTEGER :: imon2
-      INTEGER :: iyearf
-      INTEGER :: imonf
-      REAL(KIND=wp) :: pjulini
-      REAL(KIND=wp) :: pjulend
-      REAL(KIND=wp) :: pjulb
-      REAL(KIND=wp) :: pjule
-      REAL(KIND=wp) :: pjul
-      INTEGER :: inumsst
-      INTEGER :: itotrec
-      INTEGER :: inumobs
-      INTEGER :: irec
-      INTEGER :: ifld
-      INTEGER :: inum
-      INTEGER :: ji, jj
-      CHARACTER(len=128) :: clname
-      CHARACTER(len=4) :: cdyear
-      CHARACTER(len=2) :: cdmon
-      REAL(kind=wp), ALLOCATABLE, DIMENSION(:,:,:) :: zsstin
-
-      IF (lwp) WRITE(numout,*)'In obs_rea_sst_rey',sstname
-
-      !-----------------------------------------------------------------------
-      ! Convert observation window to julian dates.
-      !-----------------------------------------------------------------------
-      iyear1 = NINT( ddobsini / 10000 )
-      imon1 = NINT( ( ddobsini - iyear1 * 10000 ) / 100 )
-      iday = MOD( NINT( ddobsini ), 100 )
-      ihhmmss = ( ddobsini - NINT( ddobsini ) ) * 1000000
-      ihour = ihhmmss / 10000
-      imin = ( ihhmmss - ihour * 100 ) / 100
-      isec = MOD( ihhmmss, 100 )
-      CALL greg2jul ( isec, imin, ihour, iday, imon1, iyear1, pjulini )
-      IF (lwp) WRITE(numout,*)'dateini',ddobsini,iyear1,imon1,iday,ihour, &
-         & imin,isec,pjulini
-
-      iyear2 = NINT( ddobsini / 10000 )
-      imon2 = NINT( ( ddobsend - iyear2 * 10000 ) / 100 )
-      iday = MOD( NINT( ddobsend ), 100 )
-      ihhmmss = ( ddobsend - NINT( ddobsend ) ) * 1000000
-      ihour = ihhmmss / 10000
-      imin = ( ihhmmss - ihour * 100 ) / 100
-      isec = MOD( ihhmmss, 100 )
-      CALL greg2jul ( isec, imin, ihour, iday, imon2, iyear2, pjulend )
-      IF (lwp) WRITE(numout,*)'dateend',ddobsend,iyear2,imon2,iday,ihour, &
-         & imin,isec,pjulend
-
-      itotrec = NINT( pjulend - pjulini ) 
-      ALLOCATE( &
-         & zsstin( jpi, jpj, itotrec) &
-         & )
-      
-      pjul = pjulini + 1
-      
-      iyearf = -1 
-      imonf = -1
-
-      IF ( TRIM(cdsstfmt) == 'yearly' ) THEN
-
-         DO
-         
-            CALL jul2greg( isec, imin, ihour, iday, imon, iyear, &
-               &           pjul, 19500101 )
-            !
-            IF ( iyear /= iyearf ) THEN
-               
-               CALL greg2jul ( 0, 0, 0, 1, 1, iyear, pjulb )
-               
-               IF ( iyearf /= -1 ) THEN
-                  
-                  CALL iom_close ( inumsst )      
-                  
-               ENDIF
-               
-               clname = sstname
-               jj = INDEX( clname, 'YYYY' )
-               
-               IF ( jj == 0 ) THEN
-                  
-                  CALL ctl_stop( 'obs_rea_sst_rey : ', &
-                  &           'Error processing filename ' // TRIM(sstname) )
-                  
-               ENDIF
-               
-               WRITE(cdyear,'(I4.4)') iyear
-               clname(jj:jj+3) = cdyear
-               IF(lwp) WRITE(numout,*)'Reading from Reynolds SST file : ',&
-                  & TRIM(clname)
-               
-               inumsst = 0
-               
-               CALL iom_open ( clname, inumsst )
-               
-               IF ( inumsst == 0 ) THEN
-                  
-                  CALL ctl_stop( 'obs_rea_sst_rey : ', &
-                     &           'Error reading ' // TRIM(clname) )
-                  
-               ENDIF
-               
-               iyearf = iyear
-               
-            ENDIF
-            
-            irec = pjul - pjulb + 1
-            ifld = pjul - pjulini
-            
-            CALL iom_get ( inumsst, jpdom_data, 'sst', zsstin(:,:,ifld), irec )
-            
-            pjul = pjul + 1
-            
-            IF ( pjul > pjulend ) EXIT
-         
-         END DO
-
-      ELSEIF ( TRIM(cdsstfmt) == 'monthly' ) THEN
-
-         DO
-         
-            CALL jul2greg( isec, imin, ihour, iday, imon, iyear, &
-               &           pjul, 19500101 )
-            !
-            IF ( iyear /= iyearf .OR. imon /= imonf ) THEN
-               
-               CALL greg2jul ( 0, 0, 0, 1, imon, iyear, pjulb )
-               
-               IF ( iyearf /= -1 .AND. imonf /= -1 ) THEN
-                  
-                  CALL iom_close ( inumsst )      
-                  
-               ENDIF
-               
-               clname = sstname
-
-               jj = INDEX( clname, 'YYYY' )
-
-               IF ( jj == 0 ) THEN
-                  
-                  CALL ctl_stop( 'obs_rea_sst_rey : ', &
-                  &           'Error processing filename ' // TRIM(sstname) )
-                  
-               ENDIF
-               
-               WRITE(cdyear,'(I4.4)') iyear
-               clname(jj:jj+3) = cdyear
-
-               jj = INDEX( clname, 'MM' )
-               
-               IF ( jj == 0 ) THEN
-                  
-                  CALL ctl_stop( 'obs_rea_sst_rey : ', &
-                  &           'Error processing filename ' // TRIM(sstname) )
-                  
-               ENDIF
-               
-               WRITE(cdmon,'(I2.2)') imon
-               clname(jj:jj+1) = cdmon
-
-
-               IF(lwp) WRITE(numout,*)'Reading from Reynolds SST file : ',&
-                  & TRIM(clname)
-               
-               inumsst = 0
-               
-               CALL iom_open ( clname, inumsst )
-               
-               IF ( inumsst == 0 ) THEN
-                  
-                  CALL ctl_stop( 'obs_rea_sst_rey : ', &
-                     &           'Error reading ' // TRIM(clname) )
-                  
-               ENDIF
-               
-               iyearf = iyear
-               imonf = iyear
-               
-            ENDIF
-            
-            irec = pjul - pjulb + 1
-            ifld = pjul - pjulini
-            
-            CALL iom_get ( inumsst, jpdom_data, 'sst', zsstin(:,:,ifld), irec )
-            
-            pjul = pjul + 1
-            
-            IF ( pjul > pjulend ) EXIT
-         
-         END DO
-
-      ELSE
-         
-         CALL ctl_stop('Unknown REYNOLDS sst input data file format')
-
-      ENDIF
-
-      CALL iom_close ( inumsst )      
-
-      inumobs = 0
-      DO jj = nldj, nlej
-         DO ji = nldi, nlei
-            IF ( tmask(ji,jj,1) == 1.0_wp ) inumobs = inumobs + 1
-         END DO
-      END DO
-      inumobs = inumobs * itotrec
-
-      ! Allocate obs_surf data structure for time sorted data
-         
-      CALL obs_surf_alloc( sstdata, inumobs, kvars, kextra, kstp, jpi, jpj )
-
-      pjul = pjulini + 1
-
-      inumobs = 0
-
-      DO
-
-         CALL jul2greg( isec, imin, ihour, iday, imon, iyear, &
-            &           pjul, 19500101 )
-
-         ifld = pjul - pjulini
-
-         DO jj = nldj, nlej
-            DO ji = nldi, nlei
-
-               IF ( tmask(ji,jj,1) == 1.0_wp ) THEN
-
-                  inumobs = inumobs + 1
-                  
-                  ! Integer values
-                  IF (ln_grid_global) THEN
-                     sstdata%mi(inumobs)     = MAX(mig(ji),2)
-                     sstdata%mj(inumobs)     = MAX(mjg(jj),2)
-                  ELSE
-                     sstdata%mi(inumobs)     = MAX(ji,2)
-                     sstdata%mj(inumobs)     = MAX(jj,2)
-                  ENDIF
-                  sstdata%nsidx(inumobs)  = 0
-                  sstdata%nsfil(inumobs)  = 0
-                  sstdata%nyea(inumobs)   = iyear
-                  sstdata%nmon(inumobs)   = imon
-                  sstdata%nday(inumobs)   = iday
-                  sstdata%nhou(inumobs)   = ihour
-                  sstdata%nmin(inumobs)   = imin
-                  sstdata%mstp(inumobs)   = 0
-                  sstdata%nqc(inumobs)    = 0
-                  sstdata%ntyp(inumobs)   = 0
-         
-                  ! Real values
-                  sstdata%rlam(inumobs)   = glamt(ji,jj)
-                  sstdata%rphi(inumobs)   = gphit(ji,jj)
-                  sstdata%robs(inumobs,1) = zsstin(ji,jj,ifld)
-                  sstdata%rmod(inumobs,1) = fbrmdi
-                  sstdata%rext(inumobs,:) = fbrmdi
-
-               ENDIF
-
-            END DO
-         END DO
-
-         pjul = pjul + 1
-
-         IF ( pjul > pjulend ) EXIT
-
-      END DO
-
-   END SUBROUTINE obs_rea_sst_rey
-
-END MODULE obs_read_sst
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_surf.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_surf.F90	(revision 10247)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_surf.F90	(revision 10247)
@@ -0,0 +1,523 @@
+MODULE obs_read_surf
+   !!======================================================================
+   !!                       ***  MODULE obs_read_surf  ***
+   !! Observation diagnostics: Read the surface data from feedback files
+   !!======================================================================
+
+   !!----------------------------------------------------------------------
+   !!   obs_rea_surf : Driver for reading surface data from feedback files
+   !!----------------------------------------------------------------------
+
+   !! * Modules used
+   USE par_kind                 ! Precision variables
+   USE in_out_manager           ! I/O manager
+   USE dom_oce                  ! Ocean space and time domain variables
+   USE obs_mpp                  ! MPP support routines for observation diagnostics
+   USE julian                   ! Julian date routines
+   USE obs_utils                ! Observation operator utility functions
+   USE obs_grid                 ! Grid search
+   USE obs_sort                 ! Sorting observation arrays
+   USE obs_surf_def             ! Surface observation definitions
+   USE obs_types                ! Observation type definitions
+   USE obs_fbm                  ! Feedback routines
+   USE netcdf                   ! NetCDF library
+
+   IMPLICIT NONE
+
+   !! * Routine accessibility
+   PRIVATE
+
+   PUBLIC obs_rea_surf      ! Read the surface observations from the point data
+
+   !!----------------------------------------------------------------------
+   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
+   !! $Id$
+   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
+   !!----------------------------------------------------------------------
+
+CONTAINS
+
+   SUBROUTINE obs_rea_surf( surfdata, knumfiles, cdfilenames, &
+      &                     kvars, kextr, kstp, ddobsini, ddobsend, &
+      &                     ldignmis, ldmod, ldnightav )
+      !!---------------------------------------------------------------------
+      !!
+      !!                   *** ROUTINE obs_rea_surf ***
+      !!
+      !! ** Purpose : Read from file the surface data
+      !!
+      !! ** Method  : Read in the data from feedback format files and 
+      !!              put into the NEMO internal surface data structure
+      !!
+      !! ** Action  : 
+      !!
+      !!
+      !! History :  
+      !!      ! :  2009-01 (K. Mogensen) Initial version based on old versions
+      !!      ! :  2015-02 (M. Martin)   Unify the different surface data type reading.
+      !!----------------------------------------------------------------------
+      !! * Modules used
+
+      !! * Arguments
+      TYPE(obs_surf), INTENT(INOUT) :: &
+         & surfdata                     ! Surface data to be read
+      INTEGER, INTENT(IN) :: knumfiles  ! Number of corio format files to read
+      CHARACTER(LEN=128), INTENT(IN) :: &
+         & cdfilenames(knumfiles)       ! File names to read in
+      INTEGER, INTENT(IN) :: kvars      ! Number of variables in surfdata
+      INTEGER, INTENT(IN) :: kextr      ! Number of extra fields for each var
+      INTEGER, INTENT(IN) :: kstp       ! Ocean time-step index
+      LOGICAL, INTENT(IN) :: ldignmis   ! Ignore missing files
+      LOGICAL, INTENT(IN) :: ldmod      ! Initialize model from input data
+      LOGICAL, INTENT(IN) :: ldnightav  ! Observations represent a night-time average
+      REAL(dp), INTENT(IN) :: ddobsini   ! Obs. ini time in YYYYMMDD.HHMMSS
+      REAL(dp), INTENT(IN) :: ddobsend   ! Obs. end time in YYYYMMDD.HHMMSS
+
+      !! * Local declarations
+      CHARACTER(LEN=11), PARAMETER :: cpname='obs_rea_surf'
+      CHARACTER(len=8) :: clrefdate
+      CHARACTER(len=8), DIMENSION(:), ALLOCATABLE :: clvars
+      INTEGER :: ji
+      INTEGER :: jj
+      INTEGER :: jk
+      INTEGER :: iflag
+      INTEGER :: inobf
+      INTEGER :: i_file_id
+      INTEGER :: inowin
+      INTEGER :: iyea
+      INTEGER :: imon
+      INTEGER :: iday
+      INTEGER :: ihou
+      INTEGER :: imin
+      INTEGER :: isec
+      INTEGER :: itype
+      INTEGER :: iobsmpp
+      INTEGER :: iobs
+      INTEGER :: iobstot
+      INTEGER :: ios
+      INTEGER :: ioserrcount
+      INTEGER :: iextr
+      INTEGER, PARAMETER :: jpsurfmaxtype = 1024
+      INTEGER, DIMENSION(knumfiles) :: irefdate
+      INTEGER, DIMENSION(jpsurfmaxtype+1) :: &
+         & ityp, &
+         & itypmpp
+      INTEGER, DIMENSION(:), ALLOCATABLE :: &
+         & iobsi,    &
+         & iobsj,    &
+         & iproc,    &
+         & iindx,    &
+         & ifileidx, &
+         & isurfidx, &
+         & iadd_std
+      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
+         & zphi, &
+         & zlam
+      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
+         & zdat
+      REAL(wp), DIMENSION(knumfiles) :: &
+         & djulini, &
+         & djulend
+      LOGICAL :: llvalprof
+      TYPE(obfbdata), POINTER, DIMENSION(:) :: &
+         & inpfiles
+
+      ! Local initialization
+      iobs  = 0
+      iextr = kextr
+      !-----------------------------------------------------------------------
+      ! Count the number of files needed and allocate the obfbdata type
+      !-----------------------------------------------------------------------
+
+      inobf = knumfiles
+
+      ALLOCATE( inpfiles(inobf) )
+      ALLOCATE( iadd_std(inobf) )
+
+      surf_files : DO jj = 1, inobf
+
+         !---------------------------------------------------------------------
+         ! Prints
+         !---------------------------------------------------------------------
+         IF(lwp) THEN
+            WRITE(numout,*)
+            WRITE(numout,*) ' obs_rea_surf : Reading from file = ', &
+               & TRIM( TRIM( cdfilenames(jj) ) )
+            WRITE(numout,*) ' ~~~~~~~~~~~'
+            WRITE(numout,*)
+         ENDIF
+
+         !---------------------------------------------------------------------
+         !  Initialization: Open file and get dimensions only
+         !---------------------------------------------------------------------
+
+         iflag = nf90_open( TRIM( TRIM( cdfilenames(jj) ) ), nf90_nowrite, &
+            &                      i_file_id )
+
+         IF ( iflag /= nf90_noerr ) THEN
+
+            IF ( ldignmis ) THEN
+               inpfiles(jj)%nobs = 0
+               CALL ctl_warn( 'File ' // TRIM( TRIM( cdfilenames(jj) ) ) // &
+                  &           ' not found' )
+            ELSE 
+               CALL ctl_stop( 'File ' // TRIM( TRIM( cdfilenames(jj) ) ) // &
+                  &           ' not found' )
+            ENDIF
+
+         ELSE 
+
+            !------------------------------------------------------------------
+            !  Close the file since it is opened in read_obfbdata
+            !------------------------------------------------------------------
+
+            iflag = nf90_close( i_file_id )
+
+            !------------------------------------------------------------------
+            !  Read the surface file into inpfiles
+            !------------------------------------------------------------------
+            CALL init_obfbdata( inpfiles(jj) )
+            CALL read_obfbdata( TRIM( cdfilenames(jj) ), inpfiles(jj), &
+               &                ldgrid = .TRUE. )
+
+            IF ( ldmod .AND. ( inpfiles(jj)%nadd == 0 ) ) THEN
+               CALL ctl_stop( 'Model not in input data' )
+               RETURN
+            ENDIF
+
+            IF ( jj == 1 ) THEN
+               ALLOCATE( clvars( inpfiles(jj)%nvar ) )
+               DO ji = 1, inpfiles(jj)%nvar
+                 clvars(ji) = inpfiles(jj)%cname(ji)
+               END DO
+            ELSE
+               DO ji = 1, inpfiles(jj)%nvar
+                  IF ( inpfiles(jj)%cname(ji) /= clvars(ji) ) THEN
+                     CALL ctl_stop( 'Feedback file variables not consistent', &
+                        &           ' with previous files for this type' )
+                  ENDIF
+               END DO
+            ENDIF
+
+            iadd_std(jj) = -1
+            IF ( inpfiles(jj)%nadd > 0 ) THEN
+               DO ji = 1, inpfiles(jj)%nadd
+                  IF ( TRIM( inpfiles(jj)%caddname(ji) ) == 'STD' ) THEN
+                     iextr = kextr + 1
+                     iadd_std(jj) = ji
+                  ENDIF
+               END DO
+            ENDIF
+
+            IF(lwp) THEN
+               IF ( iadd_std(jj) /= -1 ) THEN
+                  WRITE(numout,*) ' STD variable available in input file so passing it through the obs oper'
+                  WRITE(numout,*)
+               ENDIF
+            ENDIF
+
+            !------------------------------------------------------------------
+            !  Change longitude (-180,180)
+            !------------------------------------------------------------------
+
+            DO ji = 1, inpfiles(jj)%nobs
+
+               IF ( inpfiles(jj)%plam(ji) < -180. ) &
+                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) + 360.
+
+               IF ( inpfiles(jj)%plam(ji) >  180. ) &
+                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) - 360.
+
+            END DO
+
+            !------------------------------------------------------------------
+            !  Calculate the date  (change eventually)
+            !------------------------------------------------------------------
+            clrefdate=inpfiles(jj)%cdjuldref(1:8)
+            READ(clrefdate,'(I8)') irefdate(jj)
+
+            CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
+            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
+               &           krefdate = irefdate(jj) )
+            CALL ddatetoymdhms( ddobsend, iyea, imon, iday, ihou, imin, isec )
+            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulend(jj), &
+               &           krefdate = irefdate(jj) )
+
+            IF ( ldnightav ) THEN
+
+               IF ( lwp ) THEN
+                  WRITE(numout,*)'Resetting time of night-time averaged observations', &
+                     &             ' to the end of the day'
+               ENDIF
+
+               DO ji = 1, inpfiles(jj)%nobs
+                  !  for night-time averaged data force the time
+                  !  to be the last time-step of the day, but still within the day.
+                  IF ( inpfiles(jj)%ptim(ji) >= 0. ) THEN
+                     inpfiles(jj)%ptim(ji) = &
+                        & INT(inpfiles(jj)%ptim(ji)) + 0.9999
+                  ELSE
+                     inpfiles(jj)%ptim(ji) = &
+                        & INT(inpfiles(jj)%ptim(ji)) - 0.0001
+                  ENDIF
+               END DO
+            ENDIF
+
+            IF ( inpfiles(jj)%nobs > 0 ) THEN
+               inpfiles(jj)%iproc = -1
+               inpfiles(jj)%iobsi = -1
+               inpfiles(jj)%iobsj = -1
+            ENDIF
+            inowin = 0
+            DO ji = 1, inpfiles(jj)%nobs
+               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
+                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
+                  inowin = inowin + 1
+               ENDIF
+            END DO
+            ALLOCATE( zlam(inowin)  )
+            ALLOCATE( zphi(inowin)  )
+            ALLOCATE( iobsi(inowin) )
+            ALLOCATE( iobsj(inowin) )
+            ALLOCATE( iproc(inowin) )
+            inowin = 0
+            DO ji = 1, inpfiles(jj)%nobs
+               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
+                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
+                  inowin = inowin + 1
+                  zlam(inowin) = inpfiles(jj)%plam(ji)
+                  zphi(inowin) = inpfiles(jj)%pphi(ji)
+               ENDIF
+            END DO
+
+            CALL obs_grid_search( inowin, zlam, zphi, iobsi, iobsj, iproc, 'T' )
+
+            inowin = 0
+            DO ji = 1, inpfiles(jj)%nobs
+               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
+                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
+                  inowin = inowin + 1
+                  inpfiles(jj)%iproc(ji,1) = iproc(inowin)
+                  inpfiles(jj)%iobsi(ji,1) = iobsi(inowin)
+                  inpfiles(jj)%iobsj(ji,1) = iobsj(inowin)
+               ENDIF
+            END DO
+            DEALLOCATE( zlam, zphi, iobsi, iobsj, iproc )
+
+            DO ji = 1, inpfiles(jj)%nobs
+               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
+                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
+                  IF ( nproc == 0 ) THEN
+                     IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
+                  ELSE
+                     IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
+                  ENDIF
+                  llvalprof = .FALSE.
+                  IF ( .NOT. BTEST(inpfiles(jj)%ivlqc(1,ji,1),2) ) THEN
+                     iobs = iobs + 1
+                  ENDIF
+               ENDIF
+            END DO
+
+         ENDIF
+
+      END DO surf_files
+
+      !-----------------------------------------------------------------------
+      ! Get the time ordered indices of the input data
+      !-----------------------------------------------------------------------
+
+      !---------------------------------------------------------------------
+      !  Loop over input data files to count total number of profiles
+      !---------------------------------------------------------------------
+      iobstot = 0
+      DO jj = 1, inobf
+         DO ji = 1, inpfiles(jj)%nobs
+            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
+               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
+               iobstot = iobstot + 1
+            ENDIF
+         END DO
+      END DO
+
+      ALLOCATE( iindx(iobstot), ifileidx(iobstot), &
+         &      isurfidx(iobstot), zdat(iobstot) )
+      jk = 0
+      DO jj = 1, inobf
+         DO ji = 1, inpfiles(jj)%nobs
+            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
+               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
+               jk = jk + 1
+               ifileidx(jk) = jj
+               isurfidx(jk) = ji
+               zdat(jk)     = inpfiles(jj)%ptim(ji)
+            ENDIF
+         END DO
+      END DO
+      CALL sort_dp_indx( iobstot, &
+         &               zdat,     &
+         &               iindx   )
+
+      CALL obs_surf_alloc( surfdata, iobs, kvars, iextr, kstp, jpi, jpj )
+
+      ! Read obs/positions, QC, all variable and assign to surfdata
+
+      iobs = 0
+      surfdata%cvars(:)  = clvars(:)
+      IF ( ldmod .AND. ( TRIM( surfdata%cvars(1) ) == 'SLA' ) ) THEN
+         surfdata%cext(1) = 'SSH'
+         surfdata%cext(2) = 'MDT'
+      ENDIF
+      IF ( iextr > kextr ) surfdata%cext(iextr) = 'STD'
+
+      ityp   (:) = 0
+      itypmpp(:) = 0
+
+      ioserrcount = 0
+
+      DO jk = 1, iobstot
+
+         jj = ifileidx(iindx(jk))
+         ji = isurfidx(iindx(jk))
+         IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND.  &
+            & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
+
+            IF ( nproc == 0 ) THEN
+               IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
+            ELSE
+               IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
+            ENDIF
+
+            ! Set observation information
+
+            IF ( .NOT. BTEST(inpfiles(jj)%ivlqc(1,ji,1),2) ) THEN
+
+               iobs = iobs + 1
+
+               CALL jul2greg( isec,                   &
+                  &           imin,                   &
+                  &           ihou,                   &
+                  &           iday,                   &
+                  &           imon,                   &
+                  &           iyea,                   &
+                  &           inpfiles(jj)%ptim(ji), &
+                  &           irefdate(jj) )
+
+
+               ! Surface time coordinates
+               surfdata%nyea(iobs) = iyea
+               surfdata%nmon(iobs) = imon
+               surfdata%nday(iobs) = iday
+               surfdata%nhou(iobs) = ihou
+               surfdata%nmin(iobs) = imin
+
+               ! Surface space coordinates
+               surfdata%rlam(iobs) = inpfiles(jj)%plam(ji)
+               surfdata%rphi(iobs) = inpfiles(jj)%pphi(ji)
+
+               ! Coordinate search parameters
+               surfdata%mi  (iobs) = inpfiles(jj)%iobsi(ji,1)
+               surfdata%mj  (iobs) = inpfiles(jj)%iobsj(ji,1)
+
+               ! WMO number
+               surfdata%cwmo(iobs) = inpfiles(jj)%cdwmo(ji)
+
+               ! Instrument type
+               READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
+901            IF ( ios /= 0 ) THEN
+                  IF (ioserrcount == 0) THEN
+                     CALL ctl_warn ( 'Problem converting an instrument type ', &
+                        &            'to integer. Setting type to zero' )
+                  ENDIF
+                  ioserrcount = ioserrcount + 1
+                  itype = 0
+               ENDIF
+               surfdata%ntyp(iobs) = itype
+               IF ( itype < jpsurfmaxtype + 1 ) THEN
+                  ityp(itype+1) = ityp(itype+1) + 1
+               ELSE
+                  IF(lwp)WRITE(numout,*)'WARNING:Increase jpsurfmaxtype in ',&
+                     &                  cpname
+               ENDIF
+
+               ! Bookkeeping data to match observations
+               surfdata%nsidx(iobs) = iobs
+               surfdata%nsfil(iobs) = iindx(jk)
+
+               ! QC flags
+               surfdata%nqc(iobs) = inpfiles(jj)%ivqc(ji,1)
+
+               ! Observed value
+               surfdata%robs(iobs,1) = inpfiles(jj)%pob(1,ji,1)
+
+               ! Model and MDT is set to fbrmdi unless read from file
+               IF ( ldmod ) THEN
+                  surfdata%rmod(iobs,1) = inpfiles(jj)%padd(1,ji,1,1)
+                  IF ( TRIM(surfdata%cvars(1)) == 'SLA' ) THEN
+                     surfdata%rext(iobs,1) = inpfiles(jj)%padd(1,ji,2,1)
+                     surfdata%rext(iobs,2) = inpfiles(jj)%pext(1,ji,1)
+                  ENDIF
+                ELSE
+                  surfdata%rmod(iobs,1) = fbrmdi
+                  IF ( TRIM(surfdata%cvars(1)) == 'SLA' ) surfdata%rext(iobs,:) = fbrmdi
+               ENDIF
+
+               ! STD (obs error standard deviation) read from file and passed through obs operator
+               IF ( iadd_std(jj) /= -1 ) THEN
+                  surfdata%rext(iobs,iextr) = inpfiles(jj)%padd(1,ji,iadd_std(jj),1)
+               ENDIF
+            ENDIF
+         ENDIF
+
+      END DO
+
+      !-----------------------------------------------------------------------
+      ! Sum up over processors
+      !-----------------------------------------------------------------------
+
+      CALL obs_mpp_sum_integer( iobs, iobsmpp )
+      CALL obs_mpp_sum_integers( ityp, itypmpp, jpsurfmaxtype + 1 )
+
+      !-----------------------------------------------------------------------
+      ! Output number of observations.
+      !-----------------------------------------------------------------------
+      IF (lwp) THEN
+
+         WRITE(numout,*)
+         WRITE(numout,'(1X,A)')TRIM( surfdata%cvars(1) )//' data'
+         WRITE(numout,'(1X,A)')'--------------'
+         DO jj = 1,8
+            IF ( itypmpp(jj) > 0 ) THEN
+               WRITE(numout,'(1X,A4,I4,A3,I10)')'Type ', jj,' = ',itypmpp(jj)
+            ENDIF
+         END DO
+         WRITE(numout,'(1X,A)') &
+            & '---------------------------------------------------------------'
+         WRITE(numout,'(1X,A,I8)') &
+            & 'Total data for variable '//TRIM( surfdata%cvars(1) )// &
+            & '           = ', iobsmpp
+         WRITE(numout,'(1X,A)') &
+            & '---------------------------------------------------------------'
+         WRITE(numout,*)
+
+      ENDIF
+
+      !-----------------------------------------------------------------------
+      ! Deallocate temporary data
+      !-----------------------------------------------------------------------
+      DEALLOCATE( ifileidx, isurfidx, zdat, clvars )
+
+      !-----------------------------------------------------------------------
+      ! Deallocate input data
+      !-----------------------------------------------------------------------
+      DO jj = 1, inobf
+         IF ( inpfiles(jj)%lalloc ) THEN
+            CALL dealloc_obfbdata( inpfiles(jj) )
+         ENDIF
+      END DO
+      DEALLOCATE( inpfiles )
+      DEALLOCATE( iadd_std )
+
+   END SUBROUTINE obs_rea_surf
+
+END MODULE obs_read_surf
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_vel.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_read_vel.F90	(revision 10246)
+++ 	(revision )
@@ -1,653 +1,0 @@
-MODULE obs_read_vel
-   !!======================================================================
-   !!                       ***  MODULE obs_read_vel  ***
-   !! Observation diagnostics: Read the velocity profile observations
-   !!======================================================================
-
-   !!----------------------------------------------------------------------
-   !!   obs_rea_vel_dri : Driver for reading profile obs
-   !!----------------------------------------------------------------------
-
-   !! * Modules used   
-   USE par_kind                 ! Precision variables
-   USE par_oce                  ! Ocean parameters
-   USE in_out_manager           ! I/O manager
-   USE dom_oce                  ! Ocean space and time domain variables
-   USE obs_mpp                  ! MPP support routines for observation diagnostics
-   USE julian                   ! Julian date routines
-   USE obs_utils                ! Observation operator utility functions
-   USE obs_prep                 ! Prepare observation arrays
-   USE obs_grid                 ! Grid search
-   USE obs_sort                 ! Sorting observation arrays
-   USE obs_profiles_def         ! Profile definitions
-   USE obs_conv                 ! Various conversion routines
-   USE obs_types                ! Observation type definitions
-   USE netcdf                   ! NetCDF library
-   USE obs_oper                 ! Observation operators
-   USE obs_vel_io               ! Velocity profile files I/O (non-FB files)
-   USE lib_mpp                  ! For ctl_warn/stop
-
-   IMPLICIT NONE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC obs_rea_vel_dri  ! Read the profile observations 
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
- 
-   SUBROUTINE obs_rea_vel_dri( kformat, &
-      &                        profdata, knumfiles, cfilenames, &
-      &                        kvars, kextr, kstp, ddobsini, ddobsend, &
-      &                        ldignmis, ldavtimset, ldmod )
-      !!---------------------------------------------------------------------
-      !!
-      !!                   *** ROUTINE obs_rea_pro_dri ***
-      !!
-      !! ** Purpose : Read from file the profile observations
-      !!
-      !! ** Method  : Depending on kformat either ENACT, CORIOLIS or
-      !!              feedback data files are read
-      !!
-      !! ** Action  : 
-      !!
-      !! References : 
-      !!
-      !! History :  
-      !!      ! :  2009-01 (K. Mogensen) : New merged version of old routines
-      !!----------------------------------------------------------------------
-      !! * Modules used
-   
-      !! * Arguments
-      INTEGER :: kformat   ! Format of input data
-      !                    ! 1: ENACT
-      !                    ! 2: Coriolis
-      TYPE(obs_prof), INTENT(OUT) :: profdata    ! Profile data to be read
-      INTEGER, INTENT(IN) :: knumfiles           ! Number of files to read in
-      CHARACTER(LEN=128), INTENT(IN) ::  cfilenames(knumfiles) ! File names to read in
-      INTEGER, INTENT(IN) :: kvars       ! Number of variables in profdata
-      INTEGER, INTENT(IN) :: kextr       ! Number of extra fields for each var in profdata
-      INTEGER, INTENT(IN) :: kstp        !  Ocean time-step index
-      LOGICAL, INTENT(IN) :: ldignmis    ! Ignore missing files
-      LOGICAL, INTENT(IN) :: ldavtimset  ! Set time to be equal to the end of the day
-      LOGICAL, INTENT(IN) :: ldmod       ! Initialize model from input data
-      REAL(KIND=dp), INTENT(IN) :: ddobsini   ! Obs. ini time in YYYYMMDD.HHMMSS
-      REAL(KIND=dp), INTENT(IN) :: ddobsend   ! Obs. end time in YYYYMMDD.HHMMSS
-
-      !! * Local declarations
-      CHARACTER(LEN=15), PARAMETER :: cpname='obs_rea_vel_dri'
-      INTEGER :: jvar
-      INTEGER :: ji
-      INTEGER :: jj
-      INTEGER :: jk
-      INTEGER :: ij
-      INTEGER :: iflag
-      INTEGER :: inobf
-      INTEGER :: i_file_id
-      INTEGER :: inowin
-      INTEGER :: iyea
-      INTEGER :: imon
-      INTEGER :: iday
-      INTEGER :: ihou
-      INTEGER :: imin
-      INTEGER :: isec
-      INTEGER, DIMENSION(knumfiles) :: &
-         & irefdate
-      INTEGER, DIMENSION(ntyp1770+1) :: &
-         & itypuv,    &
-         & itypuvmpp 
-      INTEGER :: iuv3dtmpp
-      INTEGER, DIMENSION(:), ALLOCATABLE :: &
-         & iobsiu,   &
-         & iobsju,   &
-         & iprocu,   &
-         & iobsiv,   &
-         & iobsjv,   &
-         & iprocv,   &
-         & iindx,    &
-         & ifileidx, &
-         & iprofidx
-      INTEGER :: itype
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zphi, &
-         & zlam
-      real(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zdat
-      LOGICAL :: &
-         & llvalprof
-      TYPE(obfbdata), POINTER, DIMENSION(:) :: &
-         & inpfiles
-      real(wp), DIMENSION(knumfiles) :: &
-         & djulini, &
-         & djulend
-      INTEGER :: iprof
-      INTEGER :: iproftot
-      INTEGER :: iuv3dt
-      INTEGER :: ios
-      INTEGER :: ioserrcount
-      INTEGER, DIMENSION(kvars) :: iv3dt
-      CHARACTER(len=8) :: cl_refdate
-   
-      ! Local initialization
-      iprof = 0
-      iuv3dt = 0
-
-      !-----------------------------------------------------------------------
-      ! Check data the model part is just with feedback data files
-      !-----------------------------------------------------------------------
-      IF ( ldmod .AND. ( kformat /= 0 ) ) THEN
-         CALL ctl_stop( 'Model can only be read from feedback data' )
-         RETURN
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Count the number of files needed and allocate the obfbdata type
-      !-----------------------------------------------------------------------
-      
-      inobf = knumfiles
-
-      ALLOCATE( inpfiles(inobf) )
-
-      prof_files : DO jj = 1, inobf
-          
-         !---------------------------------------------------------------------
-         ! Prints
-         !---------------------------------------------------------------------
-         IF(lwp) THEN
-            WRITE(numout,*)
-            WRITE(numout,*) ' obs_rea_vel_dri : Reading from file = ', &
-               & TRIM( TRIM( cfilenames(jj) ) )
-            WRITE(numout,*) ' ~~~~~~~~~~~~~~~'
-            WRITE(numout,*)
-         ENDIF
-
-         !---------------------------------------------------------------------
-         !  Initialization: Open file and get dimensions only
-         !---------------------------------------------------------------------
-         
-         iflag = nf90_open( TRIM( TRIM( cfilenames(jj) ) ), nf90_nowrite, &
-            &                      i_file_id )
-         
-         IF ( iflag /= nf90_noerr ) THEN
-
-            IF ( ldignmis ) THEN
-               inpfiles(jj)%nobs = 0
-               CALL ctl_warn( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ELSE 
-               CALL ctl_stop( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
-                  &           ' not found' )
-            ENDIF
-
-         ELSE 
-            
-            !------------------------------------------------------------------
-            !  Close the file since it is opened in read_proffile
-            !------------------------------------------------------------------
-            
-            iflag = nf90_close( i_file_id )
-
-            !------------------------------------------------------------------
-            !  Read the profile file into inpfiles
-            !------------------------------------------------------------------
-            IF ( kformat == 0 ) THEN
-               CALL init_obfbdata( inpfiles(jj) )
-               IF(lwp) THEN
-                  WRITE(numout,*)
-                  WRITE(numout,*)'Reading from feedback file :', &
-                     &           TRIM( cfilenames(jj) )
-               ENDIF
-               CALL read_obfbdata( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &                ldgrid = .TRUE. )
-               IF ( ldmod .AND. ( inpfiles(jj)%nadd == 0 ) ) THEN
-                  CALL ctl_stop( 'Model not in input data' )
-                  RETURN
-               ENDIF
-            ELSEIF ( kformat == 1 ) THEN
-               CALL read_taondbc( TRIM( cfilenames(jj) ), inpfiles(jj), &
-                  &               numout, lwp, .TRUE. )
-            ELSE
-               CALL ctl_stop( 'File format unknown' )
-            ENDIF
-            
-            !------------------------------------------------------------------
-            !  Change longitude (-180,180)
-            !------------------------------------------------------------------
-
-            DO ji = 1, inpfiles(jj)%nobs 
-
-               IF ( inpfiles(jj)%plam(ji) < -180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) + 360.
-
-               IF ( inpfiles(jj)%plam(ji) >  180. ) &
-                  &   inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) - 360.
-
-            END DO
-
-            !------------------------------------------------------------------
-            !  Calculate the date  (change eventually)
-            !------------------------------------------------------------------
-            cl_refdate=inpfiles(jj)%cdjuldref(1:8)
-            READ(cl_refdate,'(I8)') irefdate(jj)
-            
-            CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
-               &           krefdate = irefdate(jj) )
-            CALL ddatetoymdhms( ddobsend, iyea, imon, iday, ihou, imin, isec )
-            CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulend(jj), &
-               &           krefdate = irefdate(jj) )
-
-            IF ( ldavtimset ) THEN
-               DO ji = 1, inpfiles(jj)%nobs
-                  ! 
-                  !  for daily averaged data force the time
-                  !  to be the  end of the day
-                  !
-                  inpfiles(jj)%ptim(ji) = &
-                     & INT(inpfiles(jj)%ptim(ji)) + 1
-               END DO
-            ENDIF
-            
-            IF ( inpfiles(jj)%nobs > 0 ) THEN
-               inpfiles(jj)%iproc = -1
-               inpfiles(jj)%iobsi = -1
-               inpfiles(jj)%iobsj = -1
-            ENDIF
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-               ENDIF
-            END DO
-            ALLOCATE( zlam(inowin)  )
-            ALLOCATE( zphi(inowin)  )
-            ALLOCATE( iobsiu(inowin) )
-            ALLOCATE( iobsju(inowin) )
-            ALLOCATE( iprocu(inowin) )
-            ALLOCATE( iobsiv(inowin) )
-            ALLOCATE( iobsjv(inowin) )
-            ALLOCATE( iprocv(inowin) )
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  zlam(inowin) = inpfiles(jj)%plam(ji)
-                  zphi(inowin) = inpfiles(jj)%pphi(ji)
-               ENDIF
-            END DO
-
-            CALL obs_grid_search( inowin, zlam, zphi, iobsiu, iobsju, iprocu, &
-               & 'U' )
-            CALL obs_grid_search( inowin, zlam, zphi, iobsiv, iobsjv, iprocv, &
-               & 'V' )
-
-            inowin = 0
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  inowin = inowin + 1
-                  inpfiles(jj)%iproc(ji,1) = iprocu(inowin)
-                  inpfiles(jj)%iobsi(ji,1) = iobsiu(inowin)
-                  inpfiles(jj)%iobsj(ji,1) = iobsju(inowin)
-                  inpfiles(jj)%iproc(ji,2) = iprocv(inowin)
-                  inpfiles(jj)%iobsi(ji,2) = iobsiv(inowin)
-                  inpfiles(jj)%iobsj(ji,2) = iobsjv(inowin)
-                  IF ( inpfiles(jj)%iproc(ji,1) /= &
-                     & inpfiles(jj)%iproc(ji,2) ) THEN
-                     CALL ctl_stop( 'Error in obs_read_vel:', &
-                        & 'U and V observation on different processors')
-                  ENDIF
-               ENDIF
-            END DO
-            DEALLOCATE( zlam, zphi, iobsiu, iobsju, iprocu,  &
-               & iobsiv, iobsjv, iprocv )
-
-            DO ji = 1, inpfiles(jj)%nobs
-               IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-                  & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-                  IF ( nproc == 0 ) THEN
-                     IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-                  ELSE
-                     IF ( inpfiles(jj)%iproc(ji,1) /=  nproc ) CYCLE
-                  ENDIF
-                  llvalprof = .FALSE.
-                  IF ( ( ( nproc == 0 ) .AND. &
-                     & ( inpfiles(jj)%iproc(ji,1) <=  nproc ) ) .OR. &
-                     & ( inpfiles(jj)%iproc(ji,1) ==  nproc ) ) THEN
-                     loop_uv_count : DO ij = 1,inpfiles(jj)%nlev
-                        IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
-                           & CYCLE
-                        IF ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                           & ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                           & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                           iuv3dt = iuv3dt + 1
-                           llvalprof = .TRUE.
-                        ENDIF
-                     END DO loop_uv_count
-                  ENDIF
-                  IF ( llvalprof ) iprof = iprof + 1
-               ENDIF
-            END DO
-
-         ENDIF
-         
-      END DO prof_files
-
-      !-----------------------------------------------------------------------
-      ! Get the time ordered indices of the input data
-      !-----------------------------------------------------------------------
-
-      !---------------------------------------------------------------------
-      !  Loop over input data files to count total number of profiles
-      !---------------------------------------------------------------------
-      iproftot = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               iproftot = iproftot + 1
-            ENDIF
-         END DO
-      END DO
-
-      ALLOCATE( iindx(iproftot), ifileidx(iproftot), &
-         &      iprofidx(iproftot), zdat(iproftot) )
-      jk = 0
-      DO jj = 1, inobf
-         DO ji = 1, inpfiles(jj)%nobs
-            IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND. &
-               & ( inpfiles(jj)%ptim(ji) <= djulend(jj) )       ) THEN
-               jk = jk + 1
-               ifileidx(jk) = jj
-               iprofidx(jk) = ji
-               zdat(jk)     = inpfiles(jj)%ptim(ji)
-            ENDIF
-         END DO
-      END DO
-      CALL sort_dp_indx( iproftot, &
-         &               zdat,     &
-         &               iindx   )
-      
-      iv3dt(:) = -1
-      iv3dt(1:2) = iuv3dt
-      CALL obs_prof_alloc( profdata, kvars, kextr, iprof, iv3dt, &
-         &                 kstp, jpi, jpj, jpk )
-      
-      ! * Read obs/positions, QC, all variable and assign to profdata
-
-      profdata%nprof     = 0
-      profdata%nvprot(:) = 0
-
-      iprof = 0
-
-      iuv3dt = 0
-      itypuv   (:) = 0
-      itypuvmpp(:) = 0
-      
-      DO jk = 1, iproftot
-         
-         jj = ifileidx(iindx(jk))
-         ji = iprofidx(iindx(jk))
-         IF ( ( inpfiles(jj)%ptim(ji) >  djulini(jj) ) .AND.  &
-            & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
-            
-            IF ( nproc == 0 ) THEN
-               IF ( inpfiles(jj)%iproc(ji,1) >  nproc ) CYCLE
-            ELSE
-               IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
-            ENDIF
-            
-            llvalprof = .FALSE.
-
-            loop_prof : DO ij = 1, inpfiles(jj)%nlev
-               
-               IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
-                  & CYCLE
-               
-               IF ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                  & ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                  & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-
-                  llvalprof = .TRUE.
-                  EXIT loop_prof
-
-               ENDIF
-
-            END DO loop_prof
-            
-            ! Set profile information
-            
-            IF ( llvalprof ) THEN
-               
-               iprof = iprof + 1
-
-               CALL jul2greg( isec,                   &
-                  &           imin,                   &
-                  &           ihou,                   &
-                  &           iday,                   &
-                  &           imon,                   &
-                  &           iyea,                   &
-                  &           inpfiles(jj)%ptim(ji), &
-                  &           irefdate(jj) )
-
-
-               ! Profile time coordinates
-               profdata%nyea(iprof) = iyea
-               profdata%nmon(iprof) = imon
-               profdata%nday(iprof) = iday
-               profdata%nhou(iprof) = ihou
-               profdata%nmin(iprof) = imin
-               
-               ! Profile space coordinates
-               profdata%rlam(iprof) = inpfiles(jj)%plam(ji)
-               profdata%rphi(iprof) = inpfiles(jj)%pphi(ji)
-
-               ! Coordinate search parameters
-               profdata%mi  (iprof,1) = inpfiles(jj)%iobsi(ji,1)
-               profdata%mj  (iprof,1) = inpfiles(jj)%iobsj(ji,1)
-               profdata%mi  (iprof,2) = inpfiles(jj)%iobsi(ji,2)
-               profdata%mj  (iprof,2) = inpfiles(jj)%iobsj(ji,2)
-               
-               ! Profile WMO number
-               profdata%cwmo(iprof) = inpfiles(jj)%cdwmo(ji)
-               
-               ! Instrument type
-               READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
-901            IF ( ios /= 0 ) THEN
-                  IF (ioserrcount == 0) CALL ctl_warn ( 'Problem converting an instrument type to integer. Setting type to zero' ) 
-                  ioserrcount = ioserrcount + 1
-                  itype = 0
-               ENDIF
-               profdata%ntyp(iprof) = itype
-               
-               ! QC stuff
-
-               profdata%nqc(iprof)     = inpfiles(jj)%ioqc(ji)
-               profdata%nqcf(:,iprof)  = inpfiles(jj)%ioqcf(:,ji)
-               profdata%ipqc(iprof)    = inpfiles(jj)%ipqc(ji)
-               profdata%ipqcf(:,iprof) = inpfiles(jj)%ipqcf(:,ji)
-               profdata%itqc(iprof)    = inpfiles(jj)%itqc(ji)
-               profdata%itqcf(:,iprof) = inpfiles(jj)%itqcf(:,ji)
-               profdata%ivqc(iprof,:)  = inpfiles(jj)%ivqc(ji,:)
-               profdata%ivqcf(:,iprof,:) = inpfiles(jj)%ivqcf(:,ji,:)
-
-               ! Bookkeeping data to match profiles
-               profdata%npidx(iprof) = iprof
-               profdata%npfil(iprof) = iindx(jk)
-
-               ! Observation QC flag (whole profile)
-               profdata%nqc(iprof)  = 0 !TODO
-
-               loop_uv : DO ij = 1, inpfiles(jj)%nlev            
-                   
-                  IF ( inpfiles(jj)%pdep(ij,ji) >= 6000. ) &
-                     & CYCLE
-
-                  IF ( ( inpfiles(jj)%ivlqc(ij,ji,1) <= 2 ) .AND. &
-                     & ( inpfiles(jj)%ivlqc(ij,ji,2) <= 2 ) .AND. &
-                     & ( inpfiles(jj)%idqc(ij,ji) <= 2 ) ) THEN
-                     iuv3dt = iuv3dt + 1
-                  ELSE
-                     CYCLE
-                  ENDIF
-
-                  ! Depth of U observation
-                  profdata%var(1)%vdep(iuv3dt) = &
-                     &                inpfiles(jj)%pdep(ij,ji)
-                  
-                  ! Depth of U observation QC
-                  profdata%var(1)%idqc(iuv3dt) = &
-                     &                inpfiles(jj)%idqc(ij,ji)
-                  
-                  ! Depth of U observation QC flags
-                  profdata%var(1)%idqcf(:,iuv3dt) = &
-                     &                inpfiles(jj)%idqcf(:,ij,ji)
-                  
-                  ! Profile index
-                  profdata%var(1)%nvpidx(iuv3dt) = iprof
-                  
-                  ! Vertical index in original profile
-                  profdata%var(1)%nvlidx(iuv3dt) = ij
-
-                  ! Profile U value
-
-                  profdata%var(1)%vobs(iuv3dt) = &
-                     &                inpfiles(jj)%pob(ij,ji,1)
-                  IF ( ldmod ) THEN
-                     profdata%var(1)%vmod(iuv3dt) = &
-                        &                inpfiles(jj)%padd(ij,ji,1,1)
-                  ENDIF
-                  
-                  ! Profile U qc
-                  profdata%var(1)%nvqc(iuv3dt) = &
-                     & inpfiles(jj)%ivlqc(ij,ji,1)
-                  
-                  ! Profile U qc flags
-                  profdata%var(1)%nvqcf(:,iuv3dt) = &
-                     & inpfiles(jj)%ivlqcf(:,ij,ji,1)
-                  
-                  
-                  ! Depth of V observation
-                  profdata%var(2)%vdep(iuv3dt) = &
-                     &                inpfiles(jj)%pdep(ij,ji)
-                  
-                  ! Depth of V observation QC
-                  profdata%var(2)%idqc(iuv3dt) = &
-                     &                inpfiles(jj)%idqc(ij,ji)
-                  
-                  ! Depth of V observation QC flags
-                  profdata%var(2)%idqcf(:,iuv3dt) = &
-                     &                inpfiles(jj)%idqcf(:,ij,ji)
-                  
-                  ! Profile index
-                  profdata%var(2)%nvpidx(iuv3dt) = iprof
-                  
-                  ! Vertical index in original profile
-                  profdata%var(2)%nvlidx(iuv3dt) = ij
-                  
-                  ! Profile V value
-                  profdata%var(2)%vobs(iuv3dt) = &
-                     &                inpfiles(jj)%pob(ij,ji,2)
-                  IF ( ldmod ) THEN
-                     profdata%var(2)%vmod(iuv3dt) = &
-                        &                inpfiles(jj)%padd(ij,ji,1,2)
-                  ENDIF
-                     
-                  ! Profile V qc
-                  profdata%var(2)%nvqc(iuv3dt) = &
-                     & inpfiles(jj)%ivlqc(ij,ji,2)
-                  
-                  ! Profile V qc flags
-                  profdata%var(2)%nvqcf(:,iuv3dt) = &
-                        & inpfiles(jj)%ivlqcf(:,ij,ji,2)
-                  
-                  ! Observation type
-                  itypuv( profdata%ntyp(iprof) + 1 ) = &
-                     & itypuv( profdata%ntyp(iprof) + 1 ) + 1
-
-
-               END DO loop_uv
-
-            ENDIF
-
-         ENDIF
-
-      END DO
-
-      !-----------------------------------------------------------------------
-      ! Sum up over processors
-      !-----------------------------------------------------------------------
-      
-      CALL obs_mpp_sum_integer ( iuv3dt, iuv3dtmpp )
-      
-      CALL obs_mpp_sum_integers( itypuv, itypuvmpp, ntyp1770 + 1 )
-      
-      !-----------------------------------------------------------------------
-      ! Output number of observations.
-      !-----------------------------------------------------------------------
-      IF(lwp) THEN
-         WRITE(numout,*) 
-         WRITE(numout,'(1X,A)') 'Profile U,V velocity data'
-         WRITE(numout,'(1X,A)') '-------------------------'
-         WRITE(numout,*) 
-         DO ji = 0, ntyp1770
-            IF ( itypuvmpp(ji+1) > 0 ) THEN
-               WRITE(numout,'(1X,A3,A3,I8)') ctypshort(ji), ' = ', &
-                  & itypuvmpp(ji+1)
-            ENDIF
-         END DO
-         WRITE(numout,'(1X,A)') '--------------'
-         WRITE(numout,'(1X,A6,I8)') &
-            & 'Total profile UV data                                 = ',&
-            & iuv3dtmpp
-         WRITE(numout,'(1X,A)') '--------------'
-      ENDIF
-      
-      profdata%nvprot(1)    = iuv3dt
-      profdata%nvprot(2)    = iuv3dt
-      profdata%nvprotmpp(1) = iuv3dtmpp
-      profdata%nvprotmpp(2) = iuv3dtmpp
-      profdata%nprof        = iprof
-
-      !-----------------------------------------------------------------------
-      ! Model level search
-      !-----------------------------------------------------------------------
-      CALL obs_level_search( jpk, gdept_1d,          &
-         & profdata%nvprot(1), profdata%var(1)%vdep, &
-         & profdata%var(1)%mvk )
-      CALL obs_level_search( jpk, gdept_1d,          &
-         & profdata%nvprot(2), profdata%var(2)%vdep, &
-         & profdata%var(2)%mvk )
-      
-      !-----------------------------------------------------------------------
-      ! Set model equivalent to 99999
-      !-----------------------------------------------------------------------
-      IF ( .NOT. ldmod ) THEN
-         DO jvar = 1, kvars
-            profdata%var(jvar)%vmod(:) = fbrmdi
-         END DO
-      ENDIF
-      !-----------------------------------------------------------------------
-      ! Deallocate temporary data
-      !-----------------------------------------------------------------------
-      DEALLOCATE( ifileidx, iprofidx, zdat )
-
-      !-----------------------------------------------------------------------
-      ! Deallocate input data
-      !-----------------------------------------------------------------------
-      DO jj = 1, inobf
-         CALL dealloc_obfbdata( inpfiles(jj) )
-      END DO
-      DEALLOCATE( inpfiles )
-
-   END SUBROUTINE obs_rea_vel_dri
-   
-END MODULE obs_read_vel
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_readmdt.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_readmdt.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_readmdt.F90	(revision 10247)
@@ -31,10 +31,10 @@
    PRIVATE
    
-   PUBLIC   obs_rea_mdt     ! called by ?
-   PUBLIC   obs_offset_mdt  ! called by ?
-
-   INTEGER , PUBLIC ::   nmsshc    = 1         ! MDT correction scheme
-   REAL(wp), PUBLIC ::   mdtcorr   = 1.61_wp   ! User specified MDT correction
-   REAL(wp), PUBLIC ::   mdtcutoff = 65.0_wp   ! MDT cutoff for computed correction
+   PUBLIC   obs_rea_mdt     ! called by dia_obs_init
+   PUBLIC   obs_offset_mdt  ! called by obs_rea_mdt
+
+   INTEGER , PUBLIC :: nn_msshc    = 1         ! MDT correction scheme
+   REAL(wp), PUBLIC :: rn_mdtcorr   = 1.61_wp  ! User specified MDT correction
+   REAL(wp), PUBLIC :: rn_mdtcutoff = 65.0_wp  ! MDT cutoff for computed correction
 
    !!----------------------------------------------------------------------
@@ -45,5 +45,5 @@
 CONTAINS
 
-   SUBROUTINE obs_rea_mdt( kslano, sladata, k2dint )
+   SUBROUTINE obs_rea_mdt( sladata, k2dint )
       !!---------------------------------------------------------------------
       !!
@@ -58,12 +58,10 @@
       USE iom
       !
-      INTEGER                          , INTENT(IN)    ::   kslano    ! Number of SLA Products
-      TYPE(obs_surf), DIMENSION(kslano), INTENT(inout) ::   sladata   ! SLA data
-      INTEGER                          , INTENT(in)    ::   k2dint    ! ?
+      TYPE(obs_surf), INTENT(inout) ::   sladata   ! SLA data
+      INTEGER       , INTENT(in)    ::   k2dint    ! ?
       !
       CHARACTER(LEN=12), PARAMETER ::   cpname  = 'obs_rea_mdt'
       CHARACTER(LEN=20), PARAMETER ::   mdtname = 'slaReferenceLevel.nc'
 
-      INTEGER ::   jslano              ! Data set loop variable
       INTEGER ::   jobs                ! Obs loop variable
       INTEGER ::   jpimdt, jpjmdt      ! Number of grid point in lat/lon for the MDT
@@ -88,4 +86,5 @@
       IF(lwp)WRITE(numout,*) ' obs_rea_mdt : Read MDT for referencing altimeter anomalies'
       IF(lwp)WRITE(numout,*) ' ------------- '
+      CALL FLUSH(numout)
 
       CALL iom_open( mdtname, nummdt )       ! Open the file
@@ -109,71 +108,70 @@
 
       ! Remove the offset between the MDT used with the sla and the model MDT
-      IF( nmsshc == 1 .OR. nmsshc == 2 )   CALL obs_offset_mdt( z_mdt, zfill )
+      IF( nn_msshc == 1 .OR. nn_msshc == 2 ) &
+         & CALL obs_offset_mdt( jpi, jpj, z_mdt, zfill )
 
       ! Intepolate the MDT already on the model grid at the observation point
   
-      DO jslano = 1, kslano
-         ALLOCATE( &
-            & igrdi(2,2,sladata(jslano)%nsurf), &
-            & igrdj(2,2,sladata(jslano)%nsurf), &
-            & zglam(2,2,sladata(jslano)%nsurf), &
-            & zgphi(2,2,sladata(jslano)%nsurf), &
-            & zmask(2,2,sladata(jslano)%nsurf), &
-            & zmdtl(2,2,sladata(jslano)%nsurf)  &
-            & )
+      ALLOCATE( &
+         & igrdi(2,2,sladata%nsurf), &
+         & igrdj(2,2,sladata%nsurf), &
+         & zglam(2,2,sladata%nsurf), &
+         & zgphi(2,2,sladata%nsurf), &
+         & zmask(2,2,sladata%nsurf), &
+         & zmdtl(2,2,sladata%nsurf)  &
+         & )
          
-         DO jobs = 1, sladata(jslano)%nsurf
-
-            igrdi(1,1,jobs) = sladata(jslano)%mi(jobs)-1
-            igrdj(1,1,jobs) = sladata(jslano)%mj(jobs)-1
-            igrdi(1,2,jobs) = sladata(jslano)%mi(jobs)-1
-            igrdj(1,2,jobs) = sladata(jslano)%mj(jobs)
-            igrdi(2,1,jobs) = sladata(jslano)%mi(jobs)
-            igrdj(2,1,jobs) = sladata(jslano)%mj(jobs)-1
-            igrdi(2,2,jobs) = sladata(jslano)%mi(jobs)
-            igrdj(2,2,jobs) = sladata(jslano)%mj(jobs)
-
-         END DO
-
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, igrdi, igrdj, glamt  , zglam )
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, igrdi, igrdj, gphit  , zgphi )
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, igrdi, igrdj, mdtmask, zmask )
-         CALL obs_int_comm_2d( 2, 2, sladata(jslano)%nsurf, igrdi, igrdj, z_mdt  , zmdtl )
-
-         DO jobs = 1, sladata(jslano)%nsurf
+      DO jobs = 1, sladata%nsurf
+
+         igrdi(1,1,jobs) = sladata%mi(jobs)-1
+         igrdj(1,1,jobs) = sladata%mj(jobs)-1
+         igrdi(1,2,jobs) = sladata%mi(jobs)-1
+         igrdj(1,2,jobs) = sladata%mj(jobs)
+         igrdi(2,1,jobs) = sladata%mi(jobs)
+         igrdj(2,1,jobs) = sladata%mj(jobs)-1
+         igrdi(2,2,jobs) = sladata%mi(jobs)
+         igrdj(2,2,jobs) = sladata%mj(jobs)
+
+      END DO
+
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, igrdi, igrdj, glamt  , zglam )
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, igrdi, igrdj, gphit  , zgphi )
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, igrdi, igrdj, mdtmask, zmask )
+      CALL obs_int_comm_2d( 2, 2, sladata%nsurf, jpi, jpj, igrdi, igrdj, z_mdt  , zmdtl )
+
+      DO jobs = 1, sladata%nsurf
             
-            zlam = sladata(jslano)%rlam(jobs)
-            zphi = sladata(jslano)%rphi(jobs)
-
-            CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
-               &                   zglam(:,:,jobs), zgphi(:,:,jobs), &
-               &                   zmask(:,:,jobs), zweig, zobsmask )
+         zlam = sladata%rlam(jobs)
+         zphi = sladata%rphi(jobs)
+
+         CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         &
+            &                   zglam(:,:,jobs), zgphi(:,:,jobs), &
+            &                   zmask(:,:,jobs), zweig, zobsmask )
             
-            CALL obs_int_h2d( 1, 1, zweig, zmdtl(:,:,jobs),  zext )
+         CALL obs_int_h2d( 1, 1, zweig, zmdtl(:,:,jobs),  zext )
  
-            sladata(jslano)%rext(jobs,2) = zext(1)
+         sladata%rext(jobs,2) = zext(1)
 
 ! mark any masked data with a QC flag
-            IF( zobsmask(1) == 0 )   sladata(jslano)%nqc(jobs) = 11
+         IF( zobsmask(1) == 0 )   sladata%nqc(jobs) = IBSET(sladata%nqc(jobs),15)
 
          END DO
          
-         DEALLOCATE( &
-            & igrdi, &
-            & igrdj, &
-            & zglam, &
-            & zgphi, &
-            & zmask, &
-            & zmdtl  &
-            & )
-
-      END DO
+      DEALLOCATE( &
+         & igrdi, &
+         & igrdj, &
+         & zglam, &
+         & zgphi, &
+         & zmask, &
+         & zmdtl  &
+         & )
 
       CALL wrk_dealloc(jpi,jpj,z_mdt,mdtmask) 
+      IF(lwp)WRITE(numout,*) ' ------------- '
       !
    END SUBROUTINE obs_rea_mdt
 
 
-   SUBROUTINE obs_offset_mdt( mdt, zfill )
+   SUBROUTINE obs_offset_mdt( kpi, kpj, mdt, zfill )
       !!---------------------------------------------------------------------
       !!
@@ -188,6 +186,7 @@
       !! ** Action  : 
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) ::   mdt     ! MDT used on the model grid
-      REAL(wp)                    , INTENT(in   ) ::   zfill 
+      INTEGER, INTENT(IN) ::  kpi, kpj
+      REAL(wp), DIMENSION(kpi,kpj), INTENT(INOUT) ::   mdt     ! MDT used on the model grid
+      REAL(wp)                    , INTENT(IN   ) ::   zfill 
       ! 
       INTEGER  :: ji, jj
@@ -205,6 +204,6 @@
         DO jj = 1, jpj
            zpromsk(ji,jj) = tmask_i(ji,jj)
-           IF (    ( gphit(ji,jj) .GT.  mdtcutoff ) &
-              &.OR.( gphit(ji,jj) .LT. -mdtcutoff ) &
+           IF (    ( gphit(ji,jj) .GT.  rn_mdtcutoff ) &
+              &.OR.( gphit(ji,jj) .LT. -rn_mdtcutoff ) &
               &.OR.( mdt(ji,jj) .EQ. zfill ) ) &
               &        zpromsk(ji,jj) = 0.0
@@ -212,5 +211,5 @@
       END DO 
 
-      ! Compute MSSH mean over [0,360] x [-mdtcutoff,mdtcutoff]
+      ! Compute MSSH mean over [0,360] x [-rn_mdtcutoff,rn_mdtcutoff]
 
       zarea = 0.0
@@ -240,22 +239,22 @@
       !  Correct spatial mean of the MSSH
 
-      IF( nmsshc == 1 )   mdt(:,:) = mdt(:,:) - zcorr  
+      IF( nn_msshc == 1 )   mdt(:,:) = mdt(:,:) - zcorr  
 
       ! User defined value : 1.6 m for the Rio MDT compared to ORCA2 MDT
 
-      IF( nmsshc == 2 )   mdt(:,:) = mdt(:,:) - mdtcorr
+      IF( nn_msshc == 2 )   mdt(:,:) = mdt(:,:) - rn_mdtcorr
 
       IF(lwp) THEN
          WRITE(numout,*)
-         WRITE(numout,*) ' obs_readmdt : mdtcutoff     = ', mdtcutoff
+         WRITE(numout,*) ' obs_readmdt : rn_mdtcutoff     = ', rn_mdtcutoff
          WRITE(numout,*) ' -----------   zcorr_mdt     = ', zcorr_mdt
          WRITE(numout,*) '               zcorr_bcketa  = ', zcorr_bcketa
          WRITE(numout,*) '               zcorr         = ', zcorr
-         WRITE(numout,*) '               nmsshc        = ', nmsshc
+         WRITE(numout,*) '               nn_msshc        = ', nn_msshc
       ENDIF
 
-      IF ( nmsshc == 0 ) WRITE(numout,*) '           MSSH correction is not applied'
-      IF ( nmsshc == 1 ) WRITE(numout,*) '           MSSH correction is applied'
-      IF ( nmsshc == 2 ) WRITE(numout,*) '           User defined MSSH correction' 
+      IF ( nn_msshc == 0 ) WRITE(numout,*) '           MSSH correction is not applied'
+      IF ( nn_msshc == 1 ) WRITE(numout,*) '           MSSH correction is applied'
+      IF ( nn_msshc == 2 ) WRITE(numout,*) '           User defined MSSH correction' 
 
       CALL wrk_dealloc( jpi,jpj, zpromsk )
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_rot_vel.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_rot_vel.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_rot_vel.F90	(revision 10247)
@@ -140,23 +140,23 @@
       END DO
 
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiu, igrdju, &
          &                  glamu, zglamu )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiu, igrdju, &
          &                  gphiu, zgphiu )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiu, igrdju, &
          &                  umask(:,:,1), zmasku )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiu, igrdju, &
          &                  zsingu, zsinlu )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiu, igrdju, &
          &                  zcosgu, zcoslu )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiv, igrdjv, &
          &                  glamv, zglamv )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiv, igrdjv, &
          &                  gphiv, zgphiv )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiv, igrdjv, &
          &                  vmask(:,:,1), zmaskv )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiv, igrdjv, &
          &                  zsingv, zsinlv )
-      CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
+      CALL obs_int_comm_2d( 2, 2, profdata%nprof, jpi, jpj, igrdiv, igrdjv, &
          &                  zcosgv, zcoslv )
 
@@ -195,7 +195,7 @@
          DO jk = profdata%npvsta(ji,1), profdata%npvend(ji,1)
             IF ( ( profdata%var(1)%vmod(jk) /= fbrmdi ) .AND. &
-               & ( profdata%var(1)%vmod(jk) /= fbrmdi ) ) THEN
+               & ( profdata%var(2)%vmod(jk) /= fbrmdi ) ) THEN
                pu(jk) = profdata%var(1)%vmod(jk) * zcos - &
-                  &     profdata%var(2)%vmod(jk) * zsin 
+                  &     profdata%var(2)%vmod(jk) * zsin
                pv(jk) = profdata%var(2)%vmod(jk) * zcos + &
                   &     profdata%var(1)%vmod(jk) * zsin
@@ -204,4 +204,5 @@
                pv(jk) = fbrmdi
             ENDIF
+
          END DO
 
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_seaice.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_seaice.F90	(revision 10246)
+++ 	(revision )
@@ -1,35 +1,0 @@
-MODULE obs_seaice
-   !!=====================================================================
-   !!                       ***  MODULE  obs_seaice  ***
-   !! Observation diagnostics: Storage space for sea ice observations
-   !!                          arrays and additional flags etc.
-   !!=====================================================================
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   
-   !! * Modules used 
-   USE obs_surf_def ! Definition of sea ice data types and tools
-
-   IMPLICIT NONE
-   
-   SAVE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC nseaicevars, nseaiceextr, nseaicesets, seaicedata, seaicedatqc
-
-   !! * Shared Module variables
-   INTEGER :: nseaicevars                               ! Number of seaicedata variables
-   INTEGER :: nseaiceextr                               ! Number of seaicedata extra 
-                                                     ! variables
-   INTEGER :: nseaicesets                               ! Number of seaicedata sets
-   TYPE(obs_surf), POINTER, DIMENSION(:) :: seaicedata  ! Initial sea ice data
-   TYPE(obs_surf), POINTER, DIMENSION(:) :: seaicedatqc ! Sea ice data after quality control
-
-END MODULE obs_seaice
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_seaice_io.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_seaice_io.F90	(revision 10246)
+++ 	(revision )
@@ -1,30 +1,0 @@
-MODULE obs_seaice_io
-   !!======================================================================
-   !!                       ***  MODULE obs_seaice_io  ***
-   !! Observation operators : I/O for GHRSEAICE files
-   !!======================================================================
-   !! History : 
-   !!             !  09-01  (K. Mogensen) Initial version
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !!   read_seaicefile    :  Read a obfbdata structure from an GHRSEAICE file
-   !!----------------------------------------------------------------------
-   USE par_kind
-   USE obs_utils
-   USE obs_fbm
-   USE julian
-   USE netcdf
-
-   IMPLICIT NONE
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-#include "obsseaice_io.h90"
-
-END MODULE obs_seaice_io
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sla.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sla.F90	(revision 10246)
+++ 	(revision )
@@ -1,33 +1,0 @@
-MODULE obs_sla
-   !!=====================================================================
-   !!                       ***  MODULE  obs_sla  ***
-   !! Observation diagnostics: Storage space for SLA observations
-   !!                          arrays and additional flags etc.
-   !!=====================================================================
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-   
-   !! * Modules used 
-   USE obs_surf_def ! Definition of SLA data types and tools
-
-   IMPLICIT NONE
-   
-   SAVE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC nslavars, nslaextr, nslasets, sladata, sladatqc
-
-   !! * Shared Module variables
-   INTEGER :: nslavars                               ! Number of sladata variables
-   INTEGER :: nslaextr                               ! Number of sladata extra 
-                                                     ! variables
-   INTEGER :: nslasets                               ! Number of sladata sets                                               
-   TYPE(obs_surf), POINTER, DIMENSION(:) :: sladata  ! Initial SLA data
-   TYPE(obs_surf), POINTER, DIMENSION(:) :: sladatqc ! SLA data after quality control
-
-END MODULE obs_sla
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sla_io.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sla_io.F90	(revision 10246)
+++ 	(revision )
@@ -1,30 +1,0 @@
-MODULE obs_sla_io
-   !!======================================================================
-   !!                       ***  MODULE obs_sla_io  ***
-   !! Observation operators : I/O for AVISO SLA files
-   !!======================================================================
-   !! History : 
-   !!             !  09-01  (K. Mogensen) Initial version
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !!   read_enactfile    :  Read a obfbdata structure from an AVISO SLA file
-   !!----------------------------------------------------------------------
-   USE par_kind
-   USE obs_utils
-   USE obs_fbm
-   use obs_sla_types
-   USE netcdf
-
-   IMPLICIT NONE
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-#include "obssla_io.h90"
-
-END MODULE obs_sla_io
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sla_types.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sla_types.F90	(revision 10246)
+++ 	(revision )
@@ -1,19 +1,0 @@
-MODULE obs_sla_types
-   !!======================================================================
-   !!                       ***  MODULE obs_sla_type  ***
-   !! Observation operators : Satellite identifiers for SLA data
-   !!======================================================================
-   !! History : 
-   !!             !  09-01  (K. Mogensen) Initial version
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   IMPLICIT NONE
-
-#include "obssla_types.h90"
-
-END MODULE obs_sla_types
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sst.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sst.F90	(revision 10246)
+++ 	(revision )
@@ -1,35 +1,0 @@
-MODULE obs_sst
-   !!=====================================================================
-   !!                       ***  MODULE  obs_sst  ***
-   !! Observation diagnostics: Storage space for SST observations
-   !!                          arrays and additional flags etc.
-   !!=====================================================================
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   
-   !! * Modules used 
-   USE obs_surf_def ! Definition of SST data types and tools
-
-   IMPLICIT NONE
-   
-   SAVE
-
-   !! * Routine accessibility
-   PRIVATE
-
-   PUBLIC nsstvars, nsstextr, nsstsets, sstdata, sstdatqc
-
-   !! * Shared Module variables
-   INTEGER :: nsstvars                               ! Number of sstdata variables
-   INTEGER :: nsstextr                               ! Number of sstdata extra 
-                                                     ! variables
-   INTEGER :: nsstsets                               ! Number of sstdata sets
-   TYPE(obs_surf), POINTER, DIMENSION(:) :: sstdata  ! Initial SST data
-   TYPE(obs_surf), POINTER, DIMENSION(:) :: sstdatqc ! SST data after quality control
-
-END MODULE obs_sst
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sst_io.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sst_io.F90	(revision 10246)
+++ 	(revision )
@@ -1,30 +1,0 @@
-MODULE obs_sst_io
-   !!======================================================================
-   !!                       ***  MODULE obs_sst_io  ***
-   !! Observation operators : I/O for GHRSST files
-   !!======================================================================
-   !! History : 
-   !!             !  09-01  (K. Mogensen) Initial version
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !!   read_sstfile    :  Read a obfbdata structure from an GHRSST file
-   !!----------------------------------------------------------------------
-   USE par_kind
-   USE obs_utils
-   USE obs_fbm
-   USE julian
-   USE netcdf
-
-   IMPLICIT NONE
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-#include "obssst_io.h90"
-
-END MODULE obs_sst_io
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sstbias.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sstbias.F90	(revision 10247)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_sstbias.F90	(revision 10247)
@@ -0,0 +1,272 @@
+MODULE obs_sstbias
+   !!======================================================================
+   !!                       ***  MODULE obs_sstbias  ***
+   !! Observation diagnostics: Read the bias for SST data
+   !!======================================================================
+   !!----------------------------------------------------------------------
+   !!   obs_app_sstbias : Driver for reading and applying the SST bias
+   !!----------------------------------------------------------------------
+   !! * Modules used   
+   USE par_kind, ONLY : &       ! Precision variables
+      & wp, &
+      & dp, &
+      & sp
+   USE par_oce, ONLY : &        ! Domain parameters
+      & jpi, &
+      & jpj, &
+      & jpim1
+   USE in_out_manager, ONLY : & ! I/O manager
+      & lwp,    &
+      & numout 
+   USE obs_surf_def             ! Surface observation definitions
+   USE dom_oce, ONLY : &        ! Domain variables
+      & tmask, &
+      & gphit, &
+      & glamt
+   USE obs_inter_h2d
+   USE obs_utils               ! Various observation tools
+   USE obs_inter_sup
+   IMPLICIT NONE
+   !! * Routine accessibility
+   PRIVATE
+   PUBLIC obs_app_sstbias     ! Read the altimeter bias
+CONTAINS
+   SUBROUTINE obs_app_sstbias( sstdata, k2dint, knumtypes, &
+                               cl_bias_files )
+      !!---------------------------------------------------------------------
+      !!
+      !!                   *** ROUTINE obs_app_sstbias ***
+      !!
+      !! ** Purpose : Read SST bias data from files and apply correction to
+      !!             observations
+      !!
+      !! ** Method  :
+      !!
+      !! ** Action  :
+      !!
+      !! References :
+      !!
+      !! History : 
+      !!      ! :  2014-08 (J. While) Bias correction code for SST obs,
+      !!      !                       based on obs_rea_altbias
+      !!----------------------------------------------------------------------
+      !! * Modules used
+      USE iom
+      USE netcdf
+
+      !! * Arguments
+      TYPE(obs_surf), INTENT(INOUT) :: &
+         & sstdata            ! SST data
+      INTEGER, INTENT(IN) :: k2dint
+      INTEGER, INTENT(IN) :: &
+         & knumtypes          ! Number of bias types to read in
+      CHARACTER(LEN=128), DIMENSION(knumtypes), INTENT(IN) :: &
+         & cl_bias_files      ! List of files to read
+
+      !! * Local declarations
+      INTEGER :: jslano       ! Data set loop variable
+      INTEGER :: jobs         ! Obs loop variable
+      INTEGER :: jpisstbias   ! Number of grid point in latitude for the bias
+      INTEGER :: jpjsstbias   ! Number of grid point in longitude for the bias
+      INTEGER :: jt
+      INTEGER :: i_nx_id      ! Index to read the NetCDF file
+      INTEGER :: i_ny_id      !
+      INTEGER :: i_file_id    !
+      INTEGER :: i_var_id
+      INTEGER, DIMENSION(knumtypes) :: &
+         & ibiastypes         ! Array of the bias types in each file
+      REAL(wp), DIMENSION(jpi,jpj,knumtypes) :: & 
+         & z_sstbias          ! Array to store the SST bias values
+      REAL(wp), DIMENSION(jpi,jpj) :: & 
+         & z_sstbias_2d       ! Array to store the SST bias values   
+      REAL(wp), DIMENSION(1) :: &
+         & zext, &
+         & zobsmask
+      REAL(wp), DIMENSION(2,2,1) :: &
+         & zweig
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
+         & zmask, &
+         & zglam, &
+         & zgphi
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
+         & zmask_tmp, &
+         & zglam_tmp, &
+         & zgphi_tmp   
+      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::  zbias   
+      REAL(wp) :: zlam
+      REAL(wp) :: zphi
+      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
+         & igrdi, &
+         & igrdj
+      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
+         & igrdi_tmp, &
+         & igrdj_tmp   
+      INTEGER :: numsstbias
+      INTEGER(KIND=NF90_INT) :: ifile_source
+     
+      INTEGER :: incfile
+      INTEGER :: jtype
+      INTEGER :: iret 
+      INTEGER :: inumtype
+
+      IF ( lwp ) THEN
+         WRITE(numout,*) 
+         WRITE(numout,*) 'obs_app_sstbias : '
+         WRITE(numout,*) '----------------- '
+         WRITE(numout,*) 'Read SST bias '
+      ENDIF
+
+      ! Open and read the SST bias files for each bias type
+      z_sstbias(:,:,:) = 0.0_wp
+
+      DO jtype = 1, knumtypes
+     
+         numsstbias=0
+
+         IF ( lwp ) WRITE(numout,*) 'Opening ',cl_bias_files(jtype)
+         CALL iom_open( cl_bias_files(jtype), numsstbias, ldstop=.FALSE. )
+
+         IF (numsstbias > 0) THEN
+     
+            !Read the bias type from the file
+            !No IOM get attribute command at time of writing, 
+            !so have to use NETCDF
+            !routines directly - should be upgraded in the future
+            iret=NF90_OPEN(TRIM(cl_bias_files(jtype)), NF90_NOWRITE, incfile)
+            iret=NF90_GET_ATT( incfile, NF90_GLOBAL, "SST_source", &
+                               ifile_source )
+            ibiastypes(jtype) = ifile_source                 
+            iret=NF90_CLOSE(incfile)       
+           
+            IF ( iret /= 0  ) THEN
+               CALL ctl_stop( 'obs_app_sstbias : Cannot read bias type from file '// &
+                  &           TRIM( cl_bias_files(jtype) ) )
+            ENDIF
+
+            ! Get the SST bias data
+            CALL iom_get( numsstbias, jpdom_data, 'tn', z_sstbias_2d(:,:), 1 )
+            z_sstbias(:,:,jtype) = z_sstbias_2d(:,:)       
+            ! Close the file
+            CALL iom_close(numsstbias)
+            IF ( lwp ) WRITE(numout,*) 'Read in bias for type: ',ibiastypes(jtype)
+         ELSE
+            CALL ctl_stop('obs_read_sstbias: File '// & 
+               &          TRIM( cl_bias_files(jtype) )//' Not found')
+         ENDIF
+
+      END DO
+           
+      ! Interpolate the bias from the model grid to the observation points
+      ALLOCATE( &
+         & igrdi(2,2,sstdata%nsurf), &
+         & igrdj(2,2,sstdata%nsurf), &
+         & zglam(2,2,sstdata%nsurf), &
+         & zgphi(2,2,sstdata%nsurf), &
+         & zmask(2,2,sstdata%nsurf)  )
+       
+      DO jobs = 1, sstdata%nsurf 
+         igrdi(1,1,jobs) = sstdata%mi(jobs)-1
+         igrdj(1,1,jobs) = sstdata%mj(jobs)-1
+         igrdi(1,2,jobs) = sstdata%mi(jobs)-1
+         igrdj(1,2,jobs) = sstdata%mj(jobs)
+         igrdi(2,1,jobs) = sstdata%mi(jobs)
+         igrdj(2,1,jobs) = sstdata%mj(jobs)-1
+         igrdi(2,2,jobs) = sstdata%mi(jobs)
+         igrdj(2,2,jobs) = sstdata%mj(jobs)
+      END DO
+
+      CALL obs_int_comm_2d( 2, 2, sstdata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, glamt, zglam )
+      CALL obs_int_comm_2d( 2, 2, sstdata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, gphit, zgphi )
+      CALL obs_int_comm_2d( 2, 2, sstdata%nsurf, jpi, jpj, &
+         &                  igrdi, igrdj, tmask(:,:,1), zmask )
+
+      DO jtype = 1, knumtypes
+         
+         !Find the number observations of this type
+         !and allocate tempory arrays
+         inumtype = COUNT( sstdata%ntyp(:) == ibiastypes(jtype) )
+
+         ALLOCATE( &
+            & igrdi_tmp(2,2,inumtype), &
+            & igrdj_tmp(2,2,inumtype), &
+            & zglam_tmp(2,2,inumtype), &
+            & zgphi_tmp(2,2,inumtype), &
+            & zmask_tmp(2,2,inumtype), &
+            & zbias( 2,2,inumtype ) )
+
+         IF ( lwp ) WRITE(numout,*) 'Number of obs of type: ',ibiastypes(jtype),' is: ',inumtype
+         
+         jt=1
+         DO jobs = 1, sstdata%nsurf 
+            IF ( sstdata%ntyp(jobs) == ibiastypes(jtype) ) THEN
+
+               igrdi_tmp(:,:,jt) = igrdi(:,:,jobs) 
+               igrdj_tmp(:,:,jt) = igrdj(:,:,jobs)
+               zglam_tmp(:,:,jt) = zglam(:,:,jobs)
+               zgphi_tmp(:,:,jt) = zgphi(:,:,jobs)
+               zmask_tmp(:,:,jt) = zmask(:,:,jobs)
+
+               jt = jt +1
+
+            ENDIF
+         END DO
+                         
+         CALL obs_int_comm_2d( 2, 2, inumtype, jpi, jpj,       &
+               &           igrdi_tmp(:,:,:), igrdj_tmp(:,:,:), &
+               &           z_sstbias(:,:,jtype), zbias(:,:,:) )
+
+         jt=1
+         DO jobs = 1, sstdata%nsurf
+            IF ( sstdata%ntyp(jobs) == ibiastypes(jtype) ) THEN
+
+               zlam = sstdata%rlam(jobs)
+               zphi = sstdata%rphi(jobs)
+
+               CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,             &
+                  &                   zglam_tmp(:,:,jt), zgphi_tmp(:,:,jt), &
+                  &                   zmask_tmp(:,:,jt), zweig, zobsmask )
+
+               CALL obs_int_h2d( 1, 1, zweig, zbias(:,:,jt),  zext )
+
+               ! adjust sst with bias field
+               sstdata%robs(jobs,1) = sstdata%robs(jobs,1) - zext(1)
+
+               jt=jt+1
+
+            ENDIF
+         END DO 
+
+         IF ( lwp ) THEN
+            WRITE(numout,*) 'Applied bias to obs of type: ',ibiastypes(jtype)
+            WRITE(numout,*) 'Max/min of bias: ', maxval(zbias(:,:,:)), minval(zbias(:,:,:))
+         ENDIF
+
+         !Deallocate arrays
+         DEALLOCATE( &
+         & igrdi_tmp, &
+         & igrdj_tmp, &
+         & zglam_tmp, &
+         & zgphi_tmp, &
+         & zmask_tmp, &
+         & zbias )      
+     
+      END DO !jtype
+
+      DEALLOCATE( &
+         & igrdi, &
+         & igrdj, &
+         & zglam, &
+         & zgphi, &
+         & zmask )
+
+      IF(lwp) THEN
+         WRITE(numout,*) " "
+         WRITE(numout,*) "SST bias correction applied successfully"
+         WRITE(numout,*) "Obs types: ",ibiastypes(:), &
+                              " have all been bias corrected\n"
+      ENDIF
+   END SUBROUTINE obs_app_sstbias
+ 
+END MODULE obs_sstbias
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_surf_def.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_surf_def.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_surf_def.F90	(revision 10247)
@@ -50,4 +50,5 @@
       INTEGER :: npj
       INTEGER :: nsurfup    !: Observation counter used in obs_oper
+      INTEGER :: nrec       !: Number of surface observation records in window
 
       ! Arrays with size equal to the number of surface observations
@@ -56,4 +57,5 @@
          & mi,   &        !: i-th grid coord. for interpolating to surface observation
          & mj,   &        !: j-th grid coord. for interpolating to surface observation
+         & mt,   &        !: time record number for gridded data
          & nsidx,&        !: Surface observation number
          & nsfil,&        !: Surface observation number in file
@@ -67,4 +69,10 @@
          & ntyp           !: Type of surface observation product
 
+      CHARACTER(len=8), POINTER, DIMENSION(:) :: &
+         & cvars          !: Variable names
+
+      CHARACTER(len=8), POINTER, DIMENSION(:) :: &
+         & cext           !: Extra field names
+
       CHARACTER(LEN=8), POINTER, DIMENSION(:) :: &
          & cwmo           !: WMO indentifier
@@ -90,4 +98,8 @@
          & nsstpmpp       !: Global number of surface observations per time step
 
+      ! Arrays with size equal to the number of observation records in the window
+      INTEGER, POINTER, DIMENSION(:) :: &
+         & mrecstp   ! Time step of the records
+
       ! Arrays used to store source indices when 
       ! compressing obs_surf derived types
@@ -97,4 +109,8 @@
       INTEGER, POINTER, DIMENSION(:) :: &
          & nsind          !: Source indices of surface data in compressed data
+
+      ! Is this a gridded product?
+     
+      LOGICAL :: lgrid
 
    END TYPE obs_surf
@@ -130,4 +146,5 @@
       !!* Local variables
       INTEGER :: ji
+      INTEGER :: jvar
 
       ! Set bookkeeping variables
@@ -140,4 +157,14 @@
       surf%npi      = kpi
       surf%npj      = kpj
+
+      ! Allocate arrays of size number of variables
+
+      ALLOCATE( &
+         & surf%cvars(kvar)    &
+         & )
+
+      DO jvar = 1, kvar
+         surf%cvars(jvar) = "NotSet"
+      END DO
       
       ! Allocate arrays of number of surface data size
@@ -146,4 +173,5 @@
          & surf%mi(ksurf),      &
          & surf%mj(ksurf),      &
+         & surf%mt(ksurf),      &
          & surf%nsidx(ksurf),   &
          & surf%nsfil(ksurf),   &
@@ -162,4 +190,6 @@
          & )
 
+      surf%mt(:) = -1
+
 
       ! Allocate arrays of number of surface data size * number of variables
@@ -173,6 +203,13 @@
 
       ALLOCATE( & 
-         & surf%rext(ksurf,kextra) &
-         & )
+         & surf%rext(ksurf,kextra), &
+         & surf%cext(kextra)        &
+         & )
+
+      surf%rext(:,:) = 0.0_wp 
+
+      DO ji = 1, kextra
+         surf%cext(ji) = "NotSet"
+      END DO
 
       ! Allocate arrays of number of time step size
@@ -203,4 +240,8 @@
 
       surf%nsurfup     = 0
+      
+      ! Not gridded by default
+          
+      surf%lgrid       = .FALSE.
               
    END SUBROUTINE obs_surf_alloc
@@ -228,4 +269,5 @@
          & surf%mi,      &
          & surf%mj,      &
+         & surf%mt,      &
          & surf%nsidx,   &
          & surf%nsfil,   &
@@ -254,5 +296,6 @@
 
       DEALLOCATE( & 
-         & surf%rext &
+         & surf%rext, &
+         & surf%cext &
          & )
 
@@ -269,4 +312,10 @@
          & surf%nsstp,     &
          & surf%nsstpmpp   &
+         & )
+
+      ! Dellocate arrays of size number of variables
+
+      DEALLOCATE( &
+         & surf%cvars     &
          & )
 
@@ -350,4 +399,5 @@
             newsurf%mi(insurf)    = surf%mi(ji)
             newsurf%mj(insurf)    = surf%mj(ji)
+            newsurf%mt(insurf)    = surf%mt(ji)
             newsurf%nsidx(insurf) = surf%nsidx(ji)
             newsurf%nsfil(insurf) = surf%nsfil(ji)
@@ -392,5 +442,11 @@
       ! Set book keeping variables which do not depend on number of obs.
 
-      newsurf%nstp  = surf%nstp
+      newsurf%nstp     = surf%nstp
+      newsurf%cvars(:) = surf%cvars(:)
+      newsurf%cext(:)  = surf%cext(:)
+      
+      ! Set gridded stuff
+      
+      newsurf%mt(insurf)    = surf%mt(ji)
  
       ! Deallocate temporary data
@@ -433,4 +489,5 @@
          oldsurf%mi(jj)    = surf%mi(ji)
          oldsurf%mj(jj)    = surf%mj(ji)
+         oldsurf%mt(jj)    = surf%mt(ji)
          oldsurf%nsidx(jj) = surf%nsidx(ji)
          oldsurf%nsfil(jj) = surf%nsfil(ji)
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_types.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_types.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_types.F90	(revision 10247)
@@ -117,5 +117,5 @@
 
          cwmonam1770(ji) = 'Not defined'
-         ctypshort(ji) = 'XBT'
+         ctypshort(ji) = '---'
 
 !         IF ( ji < 1000 ) THEN
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_vel_io.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_vel_io.F90	(revision 10246)
+++ 	(revision )
@@ -1,32 +1,0 @@
-MODULE obs_vel_io
-   !!======================================================================
-   !!                       ***  MODULE obs_vel_io  ***
-   !! Observation operators : I/O for TAO velocity data
-   !!======================================================================
-   !! History : 
-   !!             !  09-01  (K. Mogensen) Initial version based on obs_read_taovel
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !!   read_taofile    :  Read a obfbdata structure from an TAO velocity file.
-   !!----------------------------------------------------------------------
-   USE par_kind
-   USE obs_utils
-   USE obs_fbm
-   USE obs_conv
-   USE in_out_manager
-   USE netcdf
-   IMPLICIT NONE
-
-   INTEGER, PARAMETER :: imaxlev = 10000
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-CONTAINS
-
-#include "obsvel_io.h90"
-
-END MODULE obs_vel_io
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_write.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_write.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obs_write.F90	(revision 10247)
@@ -6,10 +6,7 @@
 
    !!----------------------------------------------------------------------
-   !!   obs_wri_p3d   : Write profile observation diagnostics in NetCDF format
-   !!   obs_wri_sla   : Write SLA observation related diagnostics
-   !!   obs_wri_sst   : Write SST observation related diagnostics
-   !!   obs_wri_seaice: Write seaice observation related diagnostics
-   !!   obs_wri_vel   : Write velocity observation diagnostics in NetCDF format
-   !!   obs_wri_stats : Print basic statistics on the data being written out
+   !!   obs_wri_prof   : Write profile observations in feedback format
+   !!   obs_wri_surf   : Write surface observations in feedback format
+   !!   obs_wri_stats  : Print basic statistics on the data being written out
    !!----------------------------------------------------------------------
 
@@ -30,6 +27,4 @@
    USE obs_conv             ! Conversion between units
    USE obs_const
-   USE obs_sla_types
-   USE obs_rot_vel          ! Rotation of velocities
    USE obs_mpp              ! MPP support routines for observation diagnostics
    USE lib_mpp		    ! MPP routines
@@ -39,10 +34,6 @@
    !! * Routine accessibility
    PRIVATE
-   PUBLIC obs_wri_p3d, &    ! Write profile observation related diagnostics
-      &   obs_wri_sla, &    ! Write SLA observation related diagnostics
-      &   obs_wri_sst, &    ! Write SST observation related diagnostics
-      &   obs_wri_sss, &    ! Write SSS observation related diagnostics
-      &   obs_wri_seaice, & ! Write seaice observation related diagnostics
-      &   obs_wri_vel, &    ! Write velocity observation related diagnostics
+   PUBLIC obs_wri_prof, &    ! Write profile observation files
+      &   obs_wri_surf, &    ! Write surface observation files
       &   obswriinfo
    
@@ -63,11 +54,10 @@
 CONTAINS
 
-   SUBROUTINE obs_wri_p3d( cprefix, profdata, padd, pext )
+   SUBROUTINE obs_wri_prof( profdata, padd, pext )
       !!-----------------------------------------------------------------------
       !!
-      !!                     *** ROUTINE obs_wri_p3d  ***
-      !!
-      !! ** Purpose : Write temperature and salinity (profile) observation 
-      !!              related diagnostics
+      !!                     *** ROUTINE obs_wri_prof  ***
+      !!
+      !! ** Purpose : Write profile feedback files
       !!
       !! ** Method  : NetCDF
@@ -82,17 +72,19 @@
       !!      ! 07-03  (K. Mogensen) General handling of profiles
       !!      ! 09-01  (K. Mogensen) New feedback format
+      !!      ! 15-02  (M. Martin) Combined routine for writing profiles
       !!-----------------------------------------------------------------------
 
-      !! * Modules used
-
       !! * Arguments
-      CHARACTER(LEN=*), INTENT(IN) :: cprefix        ! Prefix for output files
       TYPE(obs_prof), INTENT(INOUT) :: profdata      ! Full set of profile data
       TYPE(obswriinfo), OPTIONAL :: padd             ! Additional info for each variable
       TYPE(obswriinfo), OPTIONAL :: pext             ! Extra info
-      
+
       !! * Local declarations
       TYPE(obfbdata) :: fbdata
-      CHARACTER(LEN=40) :: cfname
+      CHARACTER(LEN=40) :: clfname
+      CHARACTER(LEN=10) :: clfiletype
+      CHARACTER(LEN=ilenlong) :: cllongname  ! Long name of variable
+      CHARACTER(LEN=ilenunit) :: clunits     ! Units of variable
+      CHARACTER(LEN=ilengrid) :: clgrid      ! Grid of variable
       INTEGER :: ilevel
       INTEGER :: jvar
@@ -102,68 +94,187 @@
       INTEGER :: ja
       INTEGER :: je
+      INTEGER :: iadd
+      INTEGER :: iext
       REAL(wp) :: zpres
-      INTEGER :: nadd
-      INTEGER :: next
 
       IF ( PRESENT( padd ) ) THEN
-         nadd = padd%inum
+         iadd = padd%inum
       ELSE
-         nadd = 0
+         iadd = 0
       ENDIF
 
       IF ( PRESENT( pext ) ) THEN
-         next = pext%inum
+         iext = pext%inum
       ELSE
-         next = 0
-      ENDIF
-      
+         iext = 0
+      ENDIF
+
       CALL init_obfbdata( fbdata )
 
       ! Find maximum level
       ilevel = 0
-      DO jvar = 1, 2
+      DO jvar = 1, profdata%nvar
          ilevel = MAX( ilevel, MAXVAL( profdata%var(jvar)%nvlidx(:) ) )
       END DO
-      CALL alloc_obfbdata( fbdata, 2, profdata%nprof, ilevel, &
-         &                 1 + nadd, 1 + next, .TRUE. )
-
-      fbdata%cname(1)      = 'POTM'
-      fbdata%cname(2)      = 'PSAL'
-      fbdata%coblong(1)    = 'Potential temperature'
-      fbdata%coblong(2)    = 'Practical salinity'
-      fbdata%cobunit(1)    = 'Degrees centigrade'
-      fbdata%cobunit(2)    = 'PSU'
-      fbdata%cextname(1)   = 'TEMP'
-      fbdata%cextlong(1)   = 'Insitu temperature'
-      fbdata%cextunit(1)   = 'Degrees centigrade'
-      DO je = 1, next
-         fbdata%cextname(1+je) = pext%cdname(je)
-         fbdata%cextlong(1+je) = pext%cdlong(je,1)
-         fbdata%cextunit(1+je) = pext%cdunit(je,1)
-      END DO
+
+      SELECT CASE ( TRIM(profdata%cvars(1)) )
+      CASE('POTM')
+
+         clfiletype='profb'
+         CALL alloc_obfbdata( fbdata, 2, profdata%nprof, ilevel, &
+            &                 1 + iadd, 1 + iext, .TRUE. )
+         fbdata%cname(1)      = profdata%cvars(1)
+         fbdata%cname(2)      = profdata%cvars(2)
+         fbdata%coblong(1)    = 'Potential temperature'
+         fbdata%coblong(2)    = 'Practical salinity'
+         fbdata%cobunit(1)    = 'Degrees centigrade'
+         fbdata%cobunit(2)    = 'PSU'
+         fbdata%cextname(1)   = 'TEMP'
+         fbdata%cextlong(1)   = 'Insitu temperature'
+         fbdata%cextunit(1)   = 'Degrees centigrade'
+         fbdata%caddlong(1,1) = 'Model interpolated potential temperature'
+         fbdata%caddlong(1,2) = 'Model interpolated practical salinity'
+         fbdata%caddunit(1,1) = 'Degrees centigrade'
+         fbdata%caddunit(1,2) = 'PSU'
+         fbdata%cgrid(:)      = 'T'
+         DO je = 1, iext
+            fbdata%cextname(1+je) = pext%cdname(je)
+            fbdata%cextlong(1+je) = pext%cdlong(je,1)
+            fbdata%cextunit(1+je) = pext%cdunit(je,1)
+         END DO
+         DO ja = 1, iadd
+            fbdata%caddname(1+ja) = padd%cdname(ja)
+            DO jvar = 1, 2
+               fbdata%caddlong(1+ja,jvar) = padd%cdlong(ja,jvar)
+               fbdata%caddunit(1+ja,jvar) = padd%cdunit(ja,jvar)
+            END DO
+         END DO
+
+      CASE('UVEL')
+
+         clfiletype='velfb'
+         CALL alloc_obfbdata( fbdata, 2, profdata%nprof, ilevel, 1, 0, .TRUE. )
+         fbdata%cname(1)      = profdata%cvars(1)
+         fbdata%cname(2)      = profdata%cvars(2)
+         fbdata%coblong(1)    = 'Zonal velocity'
+         fbdata%coblong(2)    = 'Meridional velocity'
+         fbdata%cobunit(1)    = 'm/s'
+         fbdata%cobunit(2)    = 'm/s'
+         DO je = 1, iext
+            fbdata%cextname(je) = pext%cdname(je)
+            fbdata%cextlong(je) = pext%cdlong(je,1)
+            fbdata%cextunit(je) = pext%cdunit(je,1)
+         END DO
+         fbdata%caddlong(1,1) = 'Model interpolated zonal velocity'
+         fbdata%caddlong(1,2) = 'Model interpolated meridional velocity'
+         fbdata%caddunit(1,1) = 'm/s'
+         fbdata%caddunit(1,2) = 'm/s'
+         fbdata%cgrid(1)      = 'U' 
+         fbdata%cgrid(2)      = 'V'
+         DO ja = 1, iadd
+            fbdata%caddname(1+ja) = padd%cdname(ja)
+            fbdata%caddlong(1+ja,1) = padd%cdlong(ja,1)
+            fbdata%caddunit(1+ja,1) = padd%cdunit(ja,1)
+         END DO
+
+      CASE('PLCHLTOT')
+
+         clfiletype = 'plchltotfb'
+         cllongname = 'log10(chlorophyll concentration)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('PCHLTOT')
+
+         clfiletype = 'pchltotfb'
+         cllongname = 'chlorophyll concentration'
+         clunits    = 'mg/m3'
+         clgrid     = 'T'
+
+      CASE('PNO3')
+
+         clfiletype = 'pno3fb'
+         cllongname = 'nitrate'
+         clunits    = 'mmol/m3'
+         clgrid     = 'T'
+
+      CASE('PSI4')
+
+         clfiletype = 'psi4fb'
+         cllongname = 'silicate'
+         clunits    = 'mmol/m3'
+         clgrid     = 'T'
+
+      CASE('PPO4')
+
+         clfiletype = 'ppo4fb'
+         cllongname = 'phosphate'
+         clunits    = 'mmol/m3'
+         clgrid     = 'T'
+
+      CASE('PDIC')
+
+         clfiletype = 'pdicfb'
+         cllongname = 'dissolved inorganic carbon'
+         clunits    = 'mmol/m3'
+         clgrid     = 'T'
+
+      CASE('PALK')
+
+         clfiletype = 'palkfb'
+         cllongname = 'alkalinity'
+         clunits    = 'meq/m3'
+         clgrid     = 'T'
+
+      CASE('PPH')
+
+         clfiletype = 'pphfb'
+         cllongname = 'pH'
+         clunits    = '-'
+         clgrid     = 'T'
+
+      CASE('PO2')
+
+         clfiletype = 'po2fb'
+         cllongname = 'dissolved oxygen'
+         clunits    = 'mmol/m3'
+         clgrid     = 'T'
+
+      END SELECT
+      
+      IF ( ( TRIM(profdata%cvars(1)) /= 'POTM' ) .AND. &
+         & ( TRIM(profdata%cvars(1)) /= 'UVEL' ) ) THEN
+         CALL alloc_obfbdata( fbdata, 1, profdata%nprof, ilevel, &
+            &                 1 + iadd, iext, .TRUE. )
+         fbdata%cname(1)      = profdata%cvars(1)
+         fbdata%coblong(1)    = cllongname
+         fbdata%cobunit(1)    = clunits
+         fbdata%caddlong(1,1) = 'Model interpolated ' // TRIM(cllongname)
+         fbdata%caddunit(1,1) = clunits
+         fbdata%cgrid(:)      = clgrid
+         DO je = 1, iext
+            fbdata%cextname(je) = pext%cdname(je)
+            fbdata%cextlong(je) = pext%cdlong(je,1)
+            fbdata%cextunit(je) = pext%cdunit(je,1)
+         END DO
+         DO ja = 1, iadd
+            fbdata%caddname(1+ja) = padd%cdname(ja)
+            fbdata%caddlong(1+ja,1) = padd%cdlong(ja,1)
+            fbdata%caddunit(1+ja,1) = padd%cdunit(ja,1)
+         END DO
+      ENDIF
+
       fbdata%caddname(1)   = 'Hx'
-      fbdata%caddlong(1,1) = 'Model interpolated potential temperature'
-      fbdata%caddlong(1,2) = 'Model interpolated practical salinity'
-      fbdata%caddunit(1,1) = 'Degrees centigrade'
-      fbdata%caddunit(1,2) = 'PSU'
-      fbdata%cgrid(:)      = 'T'
-      DO ja = 1, nadd
-         fbdata%caddname(1+ja) = padd%cdname(ja)
-         DO jvar = 1, 2
-            fbdata%caddlong(1+ja,jvar) = padd%cdlong(ja,jvar)
-            fbdata%caddunit(1+ja,jvar) = padd%cdunit(ja,jvar)
-         END DO
-      END DO
-         
-      WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
+
+      WRITE(clfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(clfiletype), nproc
 
       IF(lwp) THEN
          WRITE(numout,*)
-         WRITE(numout,*)'obs_wri_p3d :'
+         WRITE(numout,*)'obs_wri_prof :'
          WRITE(numout,*)'~~~~~~~~~~~~~'
-         WRITE(numout,*)'Writing profile feedback file : ',TRIM(cfname)
-      ENDIF
-
-      ! Transform obs_prof data structure into obfbdata structure
+         WRITE(numout,*)'Writing '//TRIM(clfiletype)//' feedback file : ',TRIM(clfname)
+      ENDIF
+
+      ! Transform obs_prof data structure into obfb data structure
       fbdata%cdjuldref = '19500101000000'
       DO jo = 1, profdata%nprof
@@ -173,8 +284,8 @@
          fbdata%ivqc(jo,:)    = profdata%ivqc(jo,:)
          fbdata%ivqcf(:,jo,:) = profdata%ivqcf(:,jo,:)
-         IF ( profdata%nqc(jo) > 10 ) THEN
-            fbdata%ioqc(jo)    = 4
+         IF ( profdata%nqc(jo) > 255 ) THEN
+            fbdata%ioqc(jo)    = IBSET(profdata%nqc(jo),2)
             fbdata%ioqcf(1,jo) = profdata%nqcf(1,jo)
-            fbdata%ioqcf(2,jo) = profdata%nqc(jo) - 10
+            fbdata%ioqcf(2,jo) = profdata%nqc(jo)
          ELSE
             fbdata%ioqc(jo)    = profdata%nqc(jo)
@@ -205,5 +316,5 @@
             &           krefdate = 19500101 )
          ! Reform the profiles arrays for output
-         DO jvar = 1, 2
+         DO jvar = 1, profdata%nvar
             DO jk = profdata%npvsta(jo,jvar), profdata%npvend(jo,jvar)
                ik = profdata%var(jvar)%nvlidx(jk)
@@ -213,8 +324,8 @@
                fbdata%idqc(ik,jo)        = profdata%var(jvar)%idqc(jk)
                fbdata%idqcf(:,ik,jo)     = profdata%var(jvar)%idqcf(:,jk)
-               IF ( profdata%var(jvar)%nvqc(jk) > 10 ) THEN
-                  fbdata%ivlqc(ik,jo,jvar) = 4
+               IF ( profdata%var(jvar)%nvqc(jk) > 255 ) THEN
+                  fbdata%ivlqc(ik,jo,jvar) = IBSET(profdata%var(jvar)%nvqc(jk),2)
                   fbdata%ivlqcf(1,ik,jo,jvar) = profdata%var(jvar)%nvqcf(1,jk)
-                  fbdata%ivlqcf(2,ik,jo,jvar) = profdata%var(jvar)%nvqc(jk) - 10
+                  fbdata%ivlqcf(2,ik,jo,jvar) = IAND(profdata%var(jvar)%nvqc(jk),b'0000 0000 1111 1111')
                ELSE
                   fbdata%ivlqc(ik,jo,jvar) = profdata%var(jvar)%nvqc(jk)
@@ -222,13 +333,14 @@
                ENDIF
                fbdata%iobsk(ik,jo,jvar)  = profdata%var(jvar)%mvk(jk)
-               DO ja = 1, nadd
+               DO ja = 1, iadd
                   fbdata%padd(ik,jo,1+ja,jvar) = &
                      & profdata%var(jvar)%vext(jk,padd%ipoint(ja))
                END DO
-               DO je = 1, next
+               DO je = 1, iext
                   fbdata%pext(ik,jo,1+je) = &
                      & profdata%var(jvar)%vext(jk,pext%ipoint(je))
                END DO
-               IF ( jvar == 1 ) THEN
+               IF ( ( jvar == 1 ) .AND. &
+                  & ( TRIM(profdata%cvars(1)) == 'POTM' ) ) THEN
                   fbdata%pext(ik,jo,1) = profdata%var(jvar)%vext(jk,1)
                ENDIF 
@@ -237,26 +349,28 @@
       END DO
 
-      ! Convert insitu temperature to potential temperature using the model
-      ! salinity if no potential temperature
-      DO jo = 1, fbdata%nobs
-         IF ( fbdata%pphi(jo) < 9999.0 ) THEN
-            DO jk = 1, fbdata%nlev
-               IF ( ( fbdata%pob(jk,jo,1) >= 9999.0 ) .AND. &
-                  & ( fbdata%pdep(jk,jo) < 9999.0 ) .AND. &
-                  & ( fbdata%padd(jk,jo,1,2) < 9999.0 ) .AND. &
-                  & ( fbdata%pext(jk,jo,1) < 9999.0 ) ) THEN
-                  zpres = dep_to_p( REAL(fbdata%pdep(jk,jo),wp), &
-                     &              REAL(fbdata%pphi(jo),wp) )
-                  fbdata%pob(jk,jo,1) = potemp( &
-                     &                     REAL(fbdata%padd(jk,jo,1,2), wp),  &
-                     &                     REAL(fbdata%pext(jk,jo,1), wp), &
-                     &                     zpres, 0.0_wp )
-               ENDIF
-            END DO
-         ENDIF
-      END DO
-      
+      IF ( TRIM(profdata%cvars(1)) == 'POTM' ) THEN
+         ! Convert insitu temperature to potential temperature using the model
+         ! salinity if no potential temperature
+         DO jo = 1, fbdata%nobs
+            IF ( fbdata%pphi(jo) < 9999.0 ) THEN
+               DO jk = 1, fbdata%nlev
+                  IF ( ( fbdata%pob(jk,jo,1) >= 9999.0 ) .AND. &
+                     & ( fbdata%pdep(jk,jo) < 9999.0 ) .AND. &
+                     & ( fbdata%padd(jk,jo,1,2) < 9999.0 ) .AND. &
+                     & ( fbdata%pext(jk,jo,1) < 9999.0 ) ) THEN
+                     zpres = dep_to_p( REAL(fbdata%pdep(jk,jo),wp), &
+                        &              REAL(fbdata%pphi(jo),wp) )
+                     fbdata%pob(jk,jo,1) = potemp( &
+                        &                     REAL(fbdata%padd(jk,jo,1,2), wp),  &
+                        &                     REAL(fbdata%pext(jk,jo,1), wp), &
+                        &                     zpres, 0.0_wp )
+                  ENDIF
+               END DO
+            ENDIF
+         END DO
+      ENDIF
+
       ! Write the obfbdata structure
-      CALL write_obfbdata( cfname, fbdata )
+      CALL write_obfbdata( clfname, fbdata )
 
       ! Output some basic statistics
@@ -264,14 +378,13 @@
 
       CALL dealloc_obfbdata( fbdata )
-     
-   END SUBROUTINE obs_wri_p3d
-
-   SUBROUTINE obs_wri_sla( cprefix, sladata, padd, pext )
+
+   END SUBROUTINE obs_wri_prof
+
+   SUBROUTINE obs_wri_surf( surfdata, padd, pext )
       !!-----------------------------------------------------------------------
       !!
-      !!                     *** ROUTINE obs_wri_sla  ***
-      !!
-      !! ** Purpose : Write SLA observation diagnostics
-      !!              related 
+      !!                     *** ROUTINE obs_wri_surf  ***
+      !!
+      !! ** Purpose : Write surface observation files
       !!
       !! ** Method  : NetCDF
@@ -281,4 +394,5 @@
       !!      ! 07-03  (K. Mogensen) Original
       !!      ! 09-01  (K. Mogensen) New feedback format.
+      !!      ! 15-02  (M. Martin) Combined surface writing routine.
       !!-----------------------------------------------------------------------
 
@@ -287,6 +401,5 @@
 
       !! * Arguments
-      CHARACTER(LEN=*), INTENT(IN) :: cprefix          ! Prefix for output files
-      TYPE(obs_surf), INTENT(INOUT) :: sladata         ! Full set of SLAa
+      TYPE(obs_surf), INTENT(INOUT) :: surfdata         ! Full set of surface data
       TYPE(obswriinfo), OPTIONAL :: padd               ! Additional info for each variable
       TYPE(obswriinfo), OPTIONAL :: pext               ! Extra info
@@ -294,76 +407,263 @@
       !! * Local declarations
       TYPE(obfbdata) :: fbdata
-      CHARACTER(LEN=40) :: cfname         ! netCDF filename
-      CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_sla'
+      CHARACTER(LEN=40) :: clfname         ! netCDF filename
+      CHARACTER(LEN=10) :: clfiletype
+      CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_surf'
+      CHARACTER(LEN=ilenlong) :: cllongname  ! Long name of variable
+      CHARACTER(LEN=ilenunit) :: clunits     ! Units of variable
+      CHARACTER(LEN=ilengrid) :: clgrid      ! Grid of variable
       INTEGER :: jo
       INTEGER :: ja
       INTEGER :: je
-      INTEGER :: nadd
-      INTEGER :: next
+      INTEGER :: iadd
+      INTEGER :: iext
+      INTEGER :: indx_std
+      INTEGER :: iadd_std
 
       IF ( PRESENT( padd ) ) THEN
-         nadd = padd%inum
+         iadd = padd%inum
       ELSE
-         nadd = 0
+         iadd = 0
       ENDIF
 
       IF ( PRESENT( pext ) ) THEN
-         next = pext%inum
+         iext = pext%inum
       ELSE
-         next = 0
-      ENDIF
-
+         iext = 0
+      ENDIF
+
+      iadd_std = 0
+      indx_std = -1
+      IF ( surfdata%nextra > 0 ) THEN
+         DO je = 1, surfdata%nextra
+           IF ( TRIM( surfdata%cext(je) ) == 'STD' ) THEN
+             iadd_std = 1
+             indx_std = je
+           ENDIF
+         END DO
+      ENDIF
+      
       CALL init_obfbdata( fbdata )
 
-      CALL alloc_obfbdata( fbdata, 1, sladata%nsurf, 1, &
-         &                 2 + nadd, 1 + next, .TRUE. )
-
-      fbdata%cname(1)      = 'SLA'
-      fbdata%coblong(1)    = 'Sea level anomaly'
-      fbdata%cobunit(1)    = 'Metres'
-      fbdata%cextname(1)   = 'MDT'
-      fbdata%cextlong(1)   = 'Mean dynamic topography'
-      fbdata%cextunit(1)   = 'Metres'
-      DO je = 1, next
-         fbdata%cextname(1+je) = pext%cdname(je)
-         fbdata%cextlong(1+je) = pext%cdlong(je,1)
-         fbdata%cextunit(1+je) = pext%cdunit(je,1)
-      END DO
+      SELECT CASE ( TRIM(surfdata%cvars(1)) )
+      CASE('SLA')
+
+         ! SLA needs special treatment because of MDT, so is all done here
+         ! Other variables are done more generically
+
+         CALL alloc_obfbdata( fbdata, 1, surfdata%nsurf, 1, &
+            &                 2 + iadd + iadd_std, 1 + iext, .TRUE. )
+
+         clfiletype = 'slafb'
+         fbdata%cname(1)      = surfdata%cvars(1)
+         fbdata%coblong(1)    = 'Sea level anomaly'
+         fbdata%cobunit(1)    = 'Metres'
+         fbdata%cextname(1)   = 'MDT'
+         fbdata%cextlong(1)   = 'Mean dynamic topography'
+         fbdata%cextunit(1)   = 'Metres'
+         DO je = 1, iext
+            fbdata%cextname(je) = pext%cdname(je)
+            fbdata%cextlong(je) = pext%cdlong(je,1)
+            fbdata%cextunit(je) = pext%cdunit(je,1)
+         END DO
+         fbdata%caddlong(1,1) = 'Model interpolated SSH - MDT'
+         fbdata%caddunit(1,1) = 'Metres' 
+         fbdata%caddname(2)   = 'SSH'
+         fbdata%caddlong(2,1) = 'Model Sea surface height'
+         fbdata%caddunit(2,1) = 'Metres'
+         fbdata%cgrid(1)      = 'T'
+         DO ja = 1, iadd
+            fbdata%caddname(2+iadd_std+ja) = padd%cdname(ja)
+            fbdata%caddlong(2+iadd_std+ja,1) = padd%cdlong(ja,1)
+            fbdata%caddunit(2+iadd_std+ja,1) = padd%cdunit(ja,1)
+         END DO
+
+      CASE('SST')
+
+         clfiletype = 'sstfb'
+         cllongname = 'Sea surface temperature'
+         clunits    = 'Degree centigrade'
+         clgrid     = 'T'
+
+      CASE('ICECONC')
+
+         clfiletype = 'sicfb'
+         cllongname = 'Sea ice'
+         clunits    = 'Fraction'
+         clgrid     = 'T'
+
+      CASE('SSS')
+
+         clfiletype = 'sssfb'
+         cllongname = 'Sea surface salinity'
+         clunits    = 'psu'
+         clgrid     = 'T'
+
+      CASE('SLCHLTOT','LOGCHL','LogChl','logchl')
+
+         clfiletype = 'slchltotfb'
+         cllongname = 'Surface total log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SLCHLDIA')
+
+         clfiletype = 'slchldiafb'
+         cllongname = 'Surface diatom log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SLCHLNON')
+
+         clfiletype = 'slchlnonfb'
+         cllongname = 'Surface non-diatom log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SLCHLDIN')
+
+         clfiletype = 'slchldinfb'
+         cllongname = 'Surface dinoflagellate log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SLCHLMIC')
+
+         clfiletype = 'slchlmicfb'
+         cllongname = 'Surface microphytoplankton log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SLCHLNAN')
+
+         clfiletype = 'slchlnanfb'
+         cllongname = 'Surface nanophytoplankton log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SLCHLPIC')
+
+         clfiletype = 'slchlpicfb'
+         cllongname = 'Surface picophytoplankton log10(chlorophyll)'
+         clunits    = 'log10(mg/m3)'
+         clgrid     = 'T'
+
+      CASE('SCHLTOT')
+
+         clfiletype = 'schltotfb'
+         cllongname = 'Surface total chlorophyll'
+         clunits    = 'mg/m3'
+         clgrid     = 'T'
+
+      CASE('SLPHYTOT')
+
+         clfiletype = 'slphytotfb'
+         cllongname = 'Surface total log10(phytoplankton carbon)'
+         clunits    = 'log10(mmolC/m3)'
+         clgrid     = 'T'
+
+      CASE('SLPHYDIA')
+
+         clfiletype = 'slphydiafb'
+         cllongname = 'Surface diatom log10(phytoplankton carbon)'
+         clunits    = 'log10(mmolC/m3)'
+         clgrid     = 'T'
+
+      CASE('SLPHYNON')
+
+         clfiletype = 'slphynonfb'
+         cllongname = 'Surface non-diatom log10(phytoplankton carbon)'
+         clunits    = 'log10(mmolC/m3)'
+         clgrid     = 'T'
+
+      CASE('SSPM')
+
+         clfiletype = 'sspmfb'
+         cllongname = 'Surface suspended particulate matter'
+         clunits    = 'g/m3'
+         clgrid     = 'T'
+
+      CASE('SFCO2','FCO2','fCO2','fco2')
+
+         clfiletype = 'sfco2fb'
+         cllongname = 'Surface fugacity of carbon dioxide'
+         clunits    = 'uatm'
+         clgrid     = 'T'
+
+      CASE('SPCO2')
+
+         clfiletype = 'spco2fb'
+         cllongname = 'Surface partial pressure of carbon dioxide'
+         clunits    = 'uatm'
+         clgrid     = 'T'
+
+      CASE DEFAULT
+
+         CALL ctl_stop( 'Unknown observation type '//TRIM(surfdata%cvars(1))//' in obs_wri_surf' )
+
+      END SELECT
+
+      ! SLA needs special treatment because of MDT, so is done above
+      ! Remaining variables treated more generically
+
+      IF ( TRIM(surfdata%cvars(1)) /= 'SLA' ) THEN
+      
+         CALL alloc_obfbdata( fbdata, 1, surfdata%nsurf, 1, &
+            &                 1 + iadd + iadd_std, iext, .TRUE. )
+
+         fbdata%cname(1)      = surfdata%cvars(1)
+         fbdata%coblong(1)    = cllongname
+         fbdata%cobunit(1)    = clunits
+         DO je = 1, iext
+            fbdata%cextname(je) = pext%cdname(je)
+            fbdata%cextlong(je) = pext%cdlong(je,1)
+            fbdata%cextunit(je) = pext%cdunit(je,1)
+         END DO
+         IF ( TRIM(surfdata%cvars(1)) == 'ICECONC' ) THEN
+            fbdata%caddlong(1,1) = 'Model interpolated ICE'
+         ELSE
+            fbdata%caddlong(1,1) = 'Model interpolated ' // TRIM(surfdata%cvars(1))
+         ENDIF
+         fbdata%caddunit(1,1) = clunits
+         fbdata%cgrid(1)      = clgrid
+         DO ja = 1, iadd
+            fbdata%caddname(1+iadd_std+ja) = padd%cdname(ja)
+            fbdata%caddlong(1+iadd_std+ja,1) = padd%cdlong(ja,1)
+            fbdata%caddunit(1+iadd_std+ja,1) = padd%cdunit(ja,1)
+         END DO
+
+      ENDIF
+      
       fbdata%caddname(1)   = 'Hx'
-      fbdata%caddlong(1,1) = 'Model interpolated SSH - MDT'
-      fbdata%caddunit(1,1) = 'Metres' 
-      fbdata%caddname(2)   = 'SSH'
-      fbdata%caddlong(2,1) = 'Model Sea surface height'
-      fbdata%caddunit(2,1) = 'Metres'
-      fbdata%cgrid(1)      = 'T'
-      DO ja = 1, nadd
-         fbdata%caddname(2+ja) = padd%cdname(ja)
-         fbdata%caddlong(2+ja,1) = padd%cdlong(ja,1)
-         fbdata%caddunit(2+ja,1) = padd%cdunit(ja,1)
-      END DO
-
-      WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
+      IF ( indx_std /= -1 ) THEN
+         IF ( TRIM(surfdata%cvars(1)) == 'SLA' ) iadd_std = iadd_std + 1
+         fbdata%caddname(1+iadd_std)   = surfdata%cext(indx_std)
+         fbdata%caddlong(1+iadd_std,1) = 'Obs error standard deviation'
+         fbdata%caddunit(1+iadd_std,1) = fbdata%cobunit(1)
+      ENDIF
+      
+      WRITE(clfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(clfiletype), nproc
 
       IF(lwp) THEN
          WRITE(numout,*)
-         WRITE(numout,*)'obs_wri_sla :'
+         WRITE(numout,*)'obs_wri_surf :'
          WRITE(numout,*)'~~~~~~~~~~~~~'
-         WRITE(numout,*)'Writing SLA feedback file : ',TRIM(cfname)
-      ENDIF
-
-      ! Transform obs_prof data structure into obfbdata structure
+         WRITE(numout,*)'Writing '//TRIM(surfdata%cvars(1))//' feedback file : ',TRIM(clfname)
+      ENDIF
+
+      ! Transform surf data structure into obfbdata structure
       fbdata%cdjuldref = '19500101000000'
-      DO jo = 1, sladata%nsurf
-         fbdata%plam(jo)      = sladata%rlam(jo)
-         fbdata%pphi(jo)      = sladata%rphi(jo)
-         WRITE(fbdata%cdtyp(jo),'(I4)') sladata%ntyp(jo)
+      DO jo = 1, surfdata%nsurf
+         fbdata%plam(jo)      = surfdata%rlam(jo)
+         fbdata%pphi(jo)      = surfdata%rphi(jo)
+         WRITE(fbdata%cdtyp(jo),'(I4)') surfdata%ntyp(jo)
          fbdata%ivqc(jo,:)    = 0
          fbdata%ivqcf(:,jo,:) = 0
-         IF ( sladata%nqc(jo) > 10 ) THEN
+         IF ( surfdata%nqc(jo) > 255 ) THEN
             fbdata%ioqc(jo)    = 4
             fbdata%ioqcf(1,jo) = 0
-            fbdata%ioqcf(2,jo) = sladata%nqc(jo) - 10
+            fbdata%ioqcf(2,jo) = IAND(surfdata%nqc(jo),b'0000 0000 1111 1111')
          ELSE
-            fbdata%ioqc(jo)    = sladata%nqc(jo)
+            fbdata%ioqc(jo)    = surfdata%nqc(jo)
             fbdata%ioqcf(:,jo) = 0
          ENDIF
@@ -372,51 +672,55 @@
          fbdata%itqc(jo)      = 0
          fbdata%itqcf(:,jo)   = 0
-         fbdata%cdwmo(jo)     = sladata%cwmo(jo)
-         fbdata%kindex(jo)    = sladata%nsfil(jo)
+         fbdata%cdwmo(jo)     = surfdata%cwmo(jo)
+         fbdata%kindex(jo)    = surfdata%nsfil(jo)
          IF (ln_grid_global) THEN
-            fbdata%iobsi(jo,1) = sladata%mi(jo)
-            fbdata%iobsj(jo,1) = sladata%mj(jo)
+            fbdata%iobsi(jo,1) = surfdata%mi(jo)
+            fbdata%iobsj(jo,1) = surfdata%mj(jo)
          ELSE
-            fbdata%iobsi(jo,1) = mig(sladata%mi(jo))
-            fbdata%iobsj(jo,1) = mjg(sladata%mj(jo))
+            fbdata%iobsi(jo,1) = mig(surfdata%mi(jo))
+            fbdata%iobsj(jo,1) = mjg(surfdata%mj(jo))
          ENDIF
          CALL greg2jul( 0, &
-            &           sladata%nmin(jo), &
-            &           sladata%nhou(jo), &
-            &           sladata%nday(jo), &
-            &           sladata%nmon(jo), &
-            &           sladata%nyea(jo), &
+            &           surfdata%nmin(jo), &
+            &           surfdata%nhou(jo), &
+            &           surfdata%nday(jo), &
+            &           surfdata%nmon(jo), &
+            &           surfdata%nyea(jo), &
             &           fbdata%ptim(jo),   &
             &           krefdate = 19500101 )
-         fbdata%padd(1,jo,1,1) = sladata%rmod(jo,1)
-         fbdata%padd(1,jo,2,1) = sladata%rext(jo,1)
-         fbdata%pob(1,jo,1)    = sladata%robs(jo,1) 
+         fbdata%padd(1,jo,1,1) = surfdata%rmod(jo,1)
+         IF ( TRIM(surfdata%cvars(1)) == 'SLA' ) fbdata%padd(1,jo,2,1) = surfdata%rext(jo,1)
+         fbdata%pob(1,jo,1)    = surfdata%robs(jo,1) 
          fbdata%pdep(1,jo)     = 0.0
          fbdata%idqc(1,jo)     = 0
          fbdata%idqcf(:,1,jo)  = 0
-         IF ( sladata%nqc(jo) > 10 ) THEN
+         IF ( surfdata%nqc(jo) > 255 ) THEN
             fbdata%ivqc(jo,1)       = 4
             fbdata%ivlqc(1,jo,1)    = 4
             fbdata%ivlqcf(1,1,jo,1) = 0
-            fbdata%ivlqcf(2,1,jo,1) = sladata%nqc(jo) - 10
+            fbdata%ivlqcf(2,1,jo,1) = IAND(surfdata%nqc(jo),b'0000 0000 1111 1111')
          ELSE
-            fbdata%ivqc(jo,1)       = sladata%nqc(jo)
-            fbdata%ivlqc(1,jo,1)    = sladata%nqc(jo)
+            fbdata%ivqc(jo,1)       = surfdata%nqc(jo)
+            fbdata%ivlqc(1,jo,1)    = surfdata%nqc(jo)
             fbdata%ivlqcf(:,1,jo,1) = 0
          ENDIF
          fbdata%iobsk(1,jo,1)  = 0
-         fbdata%pext(1,jo,1) = sladata%rext(jo,2)
-         DO ja = 1, nadd
-            fbdata%padd(1,jo,2+ja,1) = &
-               & sladata%rext(jo,padd%ipoint(ja))
-         END DO
-         DO je = 1, next
+         IF ( TRIM(surfdata%cvars(1)) == 'SLA' ) fbdata%pext(1,jo,1) = surfdata%rext(jo,2)
+         IF ( indx_std /= -1 ) THEN
+            fbdata%padd(1,jo,1+iadd_std,1) = surfdata%rext(jo,indx_std)
+         ENDIF
+         
+         DO ja = 1, iadd
+            fbdata%padd(1,jo,2+iadd_std+ja,1) = &
+               & surfdata%rext(jo,padd%ipoint(ja))
+         END DO
+         DO je = 1, iext
             fbdata%pext(1,jo,1+je) = &
-               & sladata%rext(jo,pext%ipoint(je))
+               & surfdata%rext(jo,pext%ipoint(je))
          END DO
       END DO
 
       ! Write the obfbdata structure
-      CALL write_obfbdata( cfname, fbdata )
+      CALL write_obfbdata( clfname, fbdata )
 
       ! Output some basic statistics
@@ -425,508 +729,5 @@
       CALL dealloc_obfbdata( fbdata )
 
-   END SUBROUTINE obs_wri_sla
-
-   SUBROUTINE obs_wri_sst( cprefix, sstdata, padd, pext )
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     *** ROUTINE obs_wri_sst  ***
-      !!
-      !! ** Purpose : Write SST observation diagnostics
-      !!              related 
-      !!
-      !! ** Method  : NetCDF
-      !! 
-      !! ** Action  :
-      !!
-      !!      ! 07-07  (S. Ricci) Original
-      !!      ! 09-01  (K. Mogensen) New feedback format.
-      !!-----------------------------------------------------------------------
-
-      !! * Modules used
-      IMPLICIT NONE
-
-      !! * Arguments
-      CHARACTER(LEN=*), INTENT(IN) :: cprefix       ! Prefix for output files
-      TYPE(obs_surf), INTENT(INOUT) :: sstdata      ! Full set of SST
-      TYPE(obswriinfo), OPTIONAL :: padd            ! Additional info for each variable
-      TYPE(obswriinfo), OPTIONAL :: pext            ! Extra info
-
-      !! * Local declarations 
-      TYPE(obfbdata) :: fbdata
-      CHARACTER(LEN=40) ::  cfname             ! netCDF filename
-      CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_sst'
-      INTEGER :: jo
-      INTEGER :: ja
-      INTEGER :: je
-      INTEGER :: nadd
-      INTEGER :: next
-
-      IF ( PRESENT( padd ) ) THEN
-         nadd = padd%inum
-      ELSE
-         nadd = 0
-      ENDIF
-
-      IF ( PRESENT( pext ) ) THEN
-         next = pext%inum
-      ELSE
-         next = 0
-      ENDIF
-
-      CALL init_obfbdata( fbdata )
-
-      CALL alloc_obfbdata( fbdata, 1, sstdata%nsurf, 1, &
-         &                 1 + nadd, next, .TRUE. )
-
-      fbdata%cname(1)      = 'SST'
-      fbdata%coblong(1)    = 'Sea surface temperature'
-      fbdata%cobunit(1)    = 'Degree centigrade'
-      DO je = 1, next
-         fbdata%cextname(je) = pext%cdname(je)
-         fbdata%cextlong(je) = pext%cdlong(je,1)
-         fbdata%cextunit(je) = pext%cdunit(je,1)
-      END DO
-      fbdata%caddname(1)   = 'Hx'
-      fbdata%caddlong(1,1) = 'Model interpolated SST'
-      fbdata%caddunit(1,1) = 'Degree centigrade'
-      fbdata%cgrid(1)      = 'T'
-      DO ja = 1, nadd
-         fbdata%caddname(1+ja) = padd%cdname(ja)
-         fbdata%caddlong(1+ja,1) = padd%cdlong(ja,1)
-         fbdata%caddunit(1+ja,1) = padd%cdunit(ja,1)
-      END DO
-
-      WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
-
-      IF(lwp) THEN
-         WRITE(numout,*)
-         WRITE(numout,*)'obs_wri_sst :'
-         WRITE(numout,*)'~~~~~~~~~~~~~'
-         WRITE(numout,*)'Writing SST feedback file : ',TRIM(cfname)
-      ENDIF
-
-      ! Transform obs_prof data structure into obfbdata structure
-      fbdata%cdjuldref = '19500101000000'
-      DO jo = 1, sstdata%nsurf
-         fbdata%plam(jo)      = sstdata%rlam(jo)
-         fbdata%pphi(jo)      = sstdata%rphi(jo)
-         WRITE(fbdata%cdtyp(jo),'(I4)') sstdata%ntyp(jo)
-         fbdata%ivqc(jo,:)    = 0
-         fbdata%ivqcf(:,jo,:) = 0
-         IF ( sstdata%nqc(jo) > 10 ) THEN
-            fbdata%ioqc(jo)    = 4
-            fbdata%ioqcf(1,jo) = 0
-            fbdata%ioqcf(2,jo) = sstdata%nqc(jo) - 10
-         ELSE
-            fbdata%ioqc(jo)    = MAX(sstdata%nqc(jo),1)
-            fbdata%ioqcf(:,jo) = 0
-         ENDIF
-         fbdata%ipqc(jo)      = 0
-         fbdata%ipqcf(:,jo)   = 0
-         fbdata%itqc(jo)      = 0
-         fbdata%itqcf(:,jo)   = 0
-         fbdata%cdwmo(jo)     = ''
-         fbdata%kindex(jo)    = sstdata%nsfil(jo)
-         IF (ln_grid_global) THEN
-            fbdata%iobsi(jo,1) = sstdata%mi(jo)
-            fbdata%iobsj(jo,1) = sstdata%mj(jo)
-         ELSE
-            fbdata%iobsi(jo,1) = mig(sstdata%mi(jo))
-            fbdata%iobsj(jo,1) = mjg(sstdata%mj(jo))
-         ENDIF
-         CALL greg2jul( 0, &
-            &           sstdata%nmin(jo), &
-            &           sstdata%nhou(jo), &
-            &           sstdata%nday(jo), &
-            &           sstdata%nmon(jo), &
-            &           sstdata%nyea(jo), &
-            &           fbdata%ptim(jo),   &
-            &           krefdate = 19500101 )
-         fbdata%padd(1,jo,1,1) = sstdata%rmod(jo,1)
-         fbdata%pob(1,jo,1)    = sstdata%robs(jo,1)
-         fbdata%pdep(1,jo)     = 0.0
-         fbdata%idqc(1,jo)     = 0
-         fbdata%idqcf(:,1,jo)  = 0
-         IF ( sstdata%nqc(jo) > 10 ) THEN
-            fbdata%ivqc(jo,1)       = 4
-            fbdata%ivlqc(1,jo,1)    = 4
-            fbdata%ivlqcf(1,1,jo,1) = 0
-            fbdata%ivlqcf(2,1,jo,1) = sstdata%nqc(jo) - 10
-         ELSE
-            fbdata%ivqc(jo,1)       = MAX(sstdata%nqc(jo),1)
-            fbdata%ivlqc(1,jo,1)    = MAX(sstdata%nqc(jo),1)
-            fbdata%ivlqcf(:,1,jo,1) = 0
-         ENDIF
-         fbdata%iobsk(1,jo,1)  = 0
-         DO ja = 1, nadd
-            fbdata%padd(1,jo,1+ja,1) = &
-               & sstdata%rext(jo,padd%ipoint(ja))
-         END DO
-         DO je = 1, next
-            fbdata%pext(1,jo,je) = &
-               & sstdata%rext(jo,pext%ipoint(je))
-         END DO
-
-      END DO
-
-      ! Write the obfbdata structure
-
-      CALL write_obfbdata( cfname, fbdata )
-
-      ! Output some basic statistics
-      CALL obs_wri_stats( fbdata )
-
-      CALL dealloc_obfbdata( fbdata )
-
-   END SUBROUTINE obs_wri_sst
-
-   SUBROUTINE obs_wri_sss
-   END SUBROUTINE obs_wri_sss
-
-   SUBROUTINE obs_wri_seaice( cprefix, seaicedata, padd, pext )
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     *** ROUTINE obs_wri_seaice  ***
-      !!
-      !! ** Purpose : Write sea ice observation diagnostics
-      !!              related 
-      !!
-      !! ** Method  : NetCDF
-      !! 
-      !! ** Action  :
-      !!
-      !!      ! 07-07  (S. Ricci) Original
-      !!      ! 09-01  (K. Mogensen) New feedback format.
-      !!-----------------------------------------------------------------------
-
-      !! * Modules used
-      IMPLICIT NONE
-
-      !! * Arguments
-      CHARACTER(LEN=*), INTENT(IN) :: cprefix       ! Prefix for output files
-      TYPE(obs_surf), INTENT(INOUT) :: seaicedata   ! Full set of sea ice
-      TYPE(obswriinfo), OPTIONAL :: padd            ! Additional info for each variable
-      TYPE(obswriinfo), OPTIONAL :: pext            ! Extra info
-
-      !! * Local declarations 
-      TYPE(obfbdata) :: fbdata
-      CHARACTER(LEN=40) :: cfname             ! netCDF filename
-      CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_seaice'
-      INTEGER :: jo
-      INTEGER :: ja
-      INTEGER :: je
-      INTEGER :: nadd
-      INTEGER :: next
-
-      IF ( PRESENT( padd ) ) THEN
-         nadd = padd%inum
-      ELSE
-         nadd = 0
-      ENDIF
-
-      IF ( PRESENT( pext ) ) THEN
-         next = pext%inum
-      ELSE
-         next = 0
-      ENDIF
-
-      CALL init_obfbdata( fbdata )
-
-      CALL alloc_obfbdata( fbdata, 1, seaicedata%nsurf, 1, 1, 0, .TRUE. )
-
-      fbdata%cname(1)      = 'SEAICE'
-      fbdata%coblong(1)    = 'Sea ice'
-      fbdata%cobunit(1)    = 'Fraction'
-      DO je = 1, next
-         fbdata%cextname(je) = pext%cdname(je)
-         fbdata%cextlong(je) = pext%cdlong(je,1)
-         fbdata%cextunit(je) = pext%cdunit(je,1)
-      END DO
-      fbdata%caddname(1)   = 'Hx'
-      fbdata%caddlong(1,1) = 'Model interpolated ICE'
-      fbdata%caddunit(1,1) = 'Fraction'
-      fbdata%cgrid(1)      = 'T'
-      DO ja = 1, nadd
-         fbdata%caddname(1+ja) = padd%cdname(ja)
-         fbdata%caddlong(1+ja,1) = padd%cdlong(ja,1)
-         fbdata%caddunit(1+ja,1) = padd%cdunit(ja,1)
-      END DO
-
-      WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
-
-      IF(lwp) THEN
-         WRITE(numout,*)
-         WRITE(numout,*)'obs_wri_seaice :'
-         WRITE(numout,*)'~~~~~~~~~~~~~~~~'
-         WRITE(numout,*)'Writing SEAICE feedback file : ',TRIM(cfname)
-      ENDIF
-
-      ! Transform obs_prof data structure into obfbdata structure
-      fbdata%cdjuldref = '19500101000000'
-      DO jo = 1, seaicedata%nsurf
-         fbdata%plam(jo)      = seaicedata%rlam(jo)
-         fbdata%pphi(jo)      = seaicedata%rphi(jo)
-         WRITE(fbdata%cdtyp(jo),'(I4)') seaicedata%ntyp(jo)
-         fbdata%ivqc(jo,:)    = 0
-         fbdata%ivqcf(:,jo,:) = 0
-         IF ( seaicedata%nqc(jo) > 10 ) THEN
-            fbdata%ioqc(jo)    = 4
-            fbdata%ioqcf(1,jo) = 0
-            fbdata%ioqcf(2,jo) = seaicedata%nqc(jo) - 10
-         ELSE
-            fbdata%ioqc(jo)    = MAX(seaicedata%nqc(jo),1)
-            fbdata%ioqcf(:,jo) = 0
-         ENDIF
-         fbdata%ipqc(jo)      = 0
-         fbdata%ipqcf(:,jo)   = 0
-         fbdata%itqc(jo)      = 0
-         fbdata%itqcf(:,jo)   = 0
-         fbdata%cdwmo(jo)     = ''
-         fbdata%kindex(jo)    = seaicedata%nsfil(jo)
-         IF (ln_grid_global) THEN
-            fbdata%iobsi(jo,1) = seaicedata%mi(jo)
-            fbdata%iobsj(jo,1) = seaicedata%mj(jo)
-         ELSE
-            fbdata%iobsi(jo,1) = mig(seaicedata%mi(jo))
-            fbdata%iobsj(jo,1) = mjg(seaicedata%mj(jo))
-         ENDIF
-         CALL greg2jul( 0, &
-            &           seaicedata%nmin(jo), &
-            &           seaicedata%nhou(jo), &
-            &           seaicedata%nday(jo), &
-            &           seaicedata%nmon(jo), &
-            &           seaicedata%nyea(jo), &
-            &           fbdata%ptim(jo),   &
-            &           krefdate = 19500101 )
-         fbdata%padd(1,jo,1,1) = seaicedata%rmod(jo,1)
-         fbdata%pob(1,jo,1)    = seaicedata%robs(jo,1)
-         fbdata%pdep(1,jo)     = 0.0
-         fbdata%idqc(1,jo)     = 0
-         fbdata%idqcf(:,1,jo)  = 0
-         IF ( seaicedata%nqc(jo) > 10 ) THEN
-            fbdata%ivlqc(1,jo,1) = 4
-            fbdata%ivlqcf(1,1,jo,1) = 0
-            fbdata%ivlqcf(2,1,jo,1) = seaicedata%nqc(jo) - 10
-         ELSE
-            fbdata%ivlqc(1,jo,1) = MAX(seaicedata%nqc(jo),1)
-            fbdata%ivlqcf(:,1,jo,1) = 0
-         ENDIF
-         fbdata%iobsk(1,jo,1)  = 0
-         DO ja = 1, nadd
-            fbdata%padd(1,jo,1+ja,1) = &
-               & seaicedata%rext(jo,padd%ipoint(ja))
-         END DO
-         DO je = 1, next
-            fbdata%pext(1,jo,je) = &
-               & seaicedata%rext(jo,pext%ipoint(je))
-         END DO
-
-      END DO
-
-      ! Write the obfbdata structure
-      CALL write_obfbdata( cfname, fbdata )
-
-      ! Output some basic statistics
-      CALL obs_wri_stats( fbdata )
-
-      CALL dealloc_obfbdata( fbdata )
-
-   END SUBROUTINE obs_wri_seaice
-
-   SUBROUTINE obs_wri_vel( cprefix, profdata, k2dint, padd, pext )
-      !!-----------------------------------------------------------------------
-      !!
-      !!                     *** ROUTINE obs_wri_vel  ***
-      !!
-      !! ** Purpose : Write current (profile) observation 
-      !!              related diagnostics
-      !!
-      !! ** Method  : NetCDF
-      !! 
-      !! ** Action  :
-      !!
-      !! History :
-      !!      ! 09-01  (K. Mogensen) New feedback format routine
-      !!-----------------------------------------------------------------------
-
-      !! * Modules used
-
-      !! * Arguments
-      CHARACTER(LEN=*), INTENT(IN) :: cprefix       ! Prefix for output files
-      TYPE(obs_prof), INTENT(INOUT) :: profdata     ! Full set of profile data
-      INTEGER, INTENT(IN) :: k2dint                 ! Horizontal interpolation method
-      TYPE(obswriinfo), OPTIONAL :: padd            ! Additional info for each variable
-      TYPE(obswriinfo), OPTIONAL :: pext            ! Extra info
-
-      !! * Local declarations
-      TYPE(obfbdata) :: fbdata
-      CHARACTER(LEN=40) :: cfname
-      INTEGER :: ilevel
-      INTEGER :: jvar
-      INTEGER :: jk
-      INTEGER :: ik
-      INTEGER :: jo
-      INTEGER :: ja
-      INTEGER :: je
-      INTEGER :: nadd
-      INTEGER :: next
-      REAL(wp) :: zpres
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
-         & zu, &
-         & zv
-
-      IF ( PRESENT( padd ) ) THEN
-         nadd = padd%inum
-      ELSE
-         nadd = 0
-      ENDIF
-
-      IF ( PRESENT( pext ) ) THEN
-         next = pext%inum
-      ELSE
-         next = 0
-      ENDIF
-
-      CALL init_obfbdata( fbdata )
-
-      ! Find maximum level
-      ilevel = 0
-      DO jvar = 1, 2
-         ilevel = MAX( ilevel, MAXVAL( profdata%var(jvar)%nvlidx(:) ) )
-      END DO
-      CALL alloc_obfbdata( fbdata, 2, profdata%nprof, ilevel, 2, 0, .TRUE. )
-
-      fbdata%cname(1)      = 'UVEL'
-      fbdata%cname(2)      = 'VVEL'
-      fbdata%coblong(1)    = 'Zonal velocity'
-      fbdata%coblong(2)    = 'Meridional velocity'
-      fbdata%cobunit(1)    = 'm/s'
-      fbdata%cobunit(2)    = 'm/s'
-      DO je = 1, next
-         fbdata%cextname(je) = pext%cdname(je)
-         fbdata%cextlong(je) = pext%cdlong(je,1)
-         fbdata%cextunit(je) = pext%cdunit(je,1)
-      END DO
-      fbdata%caddname(1)   = 'Hx'
-      fbdata%caddlong(1,1) = 'Model interpolated zonal velocity'
-      fbdata%caddlong(1,2) = 'Model interpolated meridional velocity'
-      fbdata%caddunit(1,1) = 'm/s'
-      fbdata%caddunit(1,2) = 'm/s'
-      fbdata%caddname(2)   = 'HxG'
-      fbdata%caddlong(2,1) = 'Model interpolated zonal velocity (model grid)'
-      fbdata%caddlong(2,2) = 'Model interpolated meridional velocity (model grid)'
-      fbdata%caddunit(2,1) = 'm/s'
-      fbdata%caddunit(2,2) = 'm/s' 
-      fbdata%cgrid(1)      = 'U' 
-      fbdata%cgrid(2)      = 'V'
-      DO ja = 1, nadd
-         fbdata%caddname(2+ja) = padd%cdname(ja)
-         fbdata%caddlong(2+ja,1) = padd%cdlong(ja,1)
-         fbdata%caddunit(2+ja,1) = padd%cdunit(ja,1)
-      END DO
-
-      WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
-
-      IF(lwp) THEN
-         WRITE(numout,*)
-         WRITE(numout,*)'obs_wri_vel :'
-         WRITE(numout,*)'~~~~~~~~~~~~~'
-         WRITE(numout,*)'Writing velocuty feedback file : ',TRIM(cfname)
-      ENDIF
-
-      ALLOCATE( &
-         & zu(profdata%nvprot(1)), &
-         & zv(profdata%nvprot(2))  &
-         & )
-      CALL obs_rotvel( profdata, k2dint, zu, zv )
-
-      ! Transform obs_prof data structure into obfbdata structure
-      fbdata%cdjuldref = '19500101000000'
-      DO jo = 1, profdata%nprof
-         fbdata%plam(jo)      = profdata%rlam(jo)
-         fbdata%pphi(jo)      = profdata%rphi(jo)
-         WRITE(fbdata%cdtyp(jo),'(I4)') profdata%ntyp(jo)
-         fbdata%ivqc(jo,:)    = profdata%ivqc(jo,:)
-         fbdata%ivqcf(:,jo,:) = profdata%ivqcf(:,jo,:)
-         IF ( profdata%nqc(jo) > 10 ) THEN
-            fbdata%ioqc(jo)    = 4
-            fbdata%ioqcf(1,jo) = profdata%nqcf(1,jo)
-            fbdata%ioqcf(2,jo) = profdata%nqc(jo) - 10
-         ELSE
-            fbdata%ioqc(jo)    = profdata%nqc(jo)
-            fbdata%ioqcf(:,jo) = profdata%nqcf(:,jo)
-         ENDIF
-         fbdata%ipqc(jo)      = profdata%ipqc(jo)
-         fbdata%ipqcf(:,jo)   = profdata%ipqcf(:,jo)
-         fbdata%itqc(jo)      = profdata%itqc(jo)
-         fbdata%itqcf(:,jo)   = profdata%itqcf(:,jo)
-         fbdata%cdwmo(jo)     = profdata%cwmo(jo)
-         fbdata%kindex(jo)    = profdata%npfil(jo)
-         DO jvar = 1, profdata%nvar
-            IF (ln_grid_global) THEN
-               fbdata%iobsi(jo,jvar) = profdata%mi(jo,jvar)
-               fbdata%iobsj(jo,jvar) = profdata%mj(jo,jvar)
-            ELSE
-               fbdata%iobsi(jo,jvar) = mig(profdata%mi(jo,jvar))
-               fbdata%iobsj(jo,jvar) = mjg(profdata%mj(jo,jvar))
-            ENDIF
-         END DO
-         CALL greg2jul( 0, &
-            &           profdata%nmin(jo), &
-            &           profdata%nhou(jo), &
-            &           profdata%nday(jo), &
-            &           profdata%nmon(jo), &
-            &           profdata%nyea(jo), &
-            &           fbdata%ptim(jo),   &
-            &           krefdate = 19500101 )
-         ! Reform the profiles arrays for output
-         DO jvar = 1, 2
-            DO jk = profdata%npvsta(jo,jvar), profdata%npvend(jo,jvar)
-               ik = profdata%var(jvar)%nvlidx(jk)
-               IF ( jvar == 1 ) THEN
-                  fbdata%padd(ik,jo,1,jvar) = zu(jk)
-               ELSE
-                  fbdata%padd(ik,jo,1,jvar) = zv(jk)
-               ENDIF
-               fbdata%padd(ik,jo,2,jvar) = profdata%var(jvar)%vmod(jk)
-               fbdata%pob(ik,jo,jvar)    = profdata%var(jvar)%vobs(jk)
-               fbdata%pdep(ik,jo)        = profdata%var(jvar)%vdep(jk)
-               fbdata%idqc(ik,jo)        = profdata%var(jvar)%idqc(jk)
-               fbdata%idqcf(:,ik,jo)     = profdata%var(jvar)%idqcf(:,jk)
-               IF ( profdata%var(jvar)%nvqc(jk) > 10 ) THEN
-                  fbdata%ivlqc(ik,jo,jvar) = 4
-                  fbdata%ivlqcf(1,ik,jo,jvar) = profdata%var(jvar)%nvqcf(1,jk)
-                  fbdata%ivlqcf(2,ik,jo,jvar) = profdata%var(jvar)%nvqc(jk) - 10
-               ELSE
-                  fbdata%ivlqc(ik,jo,jvar) = profdata%var(jvar)%nvqc(jk)
-                  fbdata%ivlqcf(:,ik,jo,jvar) = profdata%var(jvar)%nvqcf(:,jk)
-               ENDIF
-               fbdata%iobsk(ik,jo,jvar)  = profdata%var(jvar)%mvk(jk)
-               DO ja = 1, nadd
-                  fbdata%padd(ik,jo,2+ja,jvar) = &
-                     & profdata%var(jvar)%vext(jk,padd%ipoint(ja))
-               END DO
-               DO je = 1, next
-                  fbdata%pext(ik,jo,je) = &
-                     & profdata%var(jvar)%vext(jk,pext%ipoint(je))
-               END DO
-            END DO
-         END DO
-      END DO
-
-      ! Write the obfbdata structure
-      CALL write_obfbdata( cfname, fbdata )
-      
-      ! Output some basic statistics
-      CALL obs_wri_stats( fbdata )
-
-      CALL dealloc_obfbdata( fbdata )
-     
-      DEALLOCATE( &
-         & zu, &
-         & zv  &
-         & )
-
-   END SUBROUTINE obs_wri_vel
+   END SUBROUTINE obs_wri_surf
 
    SUBROUTINE obs_wri_stats( fbdata )
@@ -951,18 +752,15 @@
       INTEGER :: jo
       INTEGER :: jk
-
-!      INTEGER :: nlev
-!      INTEGER :: nlevmpp
-!      INTEGER :: nobsmpp
-      INTEGER :: numgoodobs
-      INTEGER :: numgoodobsmpp
+      INTEGER :: inumgoodobs
+      INTEGER :: inumgoodobsmpp
       REAL(wp) :: zsumx
       REAL(wp) :: zsumx2
       REAL(wp) :: zomb
+      
 
       IF (lwp) THEN
          WRITE(numout,*) ''
          WRITE(numout,*) 'obs_wri_stats :'
-         WRITE(numout,*) '~~~~~~~~~~~~~~~' 
+         WRITE(numout,*) '~~~~~~~~~~~~~~~'
       ENDIF
 
@@ -970,5 +768,5 @@
          zsumx=0.0_wp
          zsumx2=0.0_wp
-         numgoodobs=0
+         inumgoodobs=0
          DO jo = 1, fbdata%nobs
             DO jk = 1, fbdata%nlev
@@ -976,24 +774,24 @@
                   & ( fbdata%pdep(jk,jo) < 9999.0 ) .AND. &
                   & ( fbdata%padd(jk,jo,1,jvar) < 9999.0 ) ) THEN
-	    
-	          zomb=fbdata%pob(jk, jo, jvar)-fbdata%padd(jk, jo, 1, jvar)
+
+                  zomb=fbdata%pob(jk, jo, jvar)-fbdata%padd(jk, jo, 1, jvar)
                   zsumx=zsumx+zomb
                   zsumx2=zsumx2+zomb**2
-                  numgoodobs=numgoodobs+1
-	       ENDIF
+                  inumgoodobs=inumgoodobs+1
+               ENDIF
             ENDDO
          ENDDO
 
-         CALL obs_mpp_sum_integer( numgoodobs, numgoodobsmpp )
+         CALL obs_mpp_sum_integer( inumgoodobs, inumgoodobsmpp )
          CALL mpp_sum(zsumx)
          CALL mpp_sum(zsumx2)
 
          IF (lwp) THEN
-	    WRITE(numout,*) 'Type: ',fbdata%cname(jvar),'  Total number of good observations: ',numgoodobsmpp 
-	    WRITE(numout,*) 'Overall mean obs minus model of the good observations: ',zsumx/numgoodobsmpp
-            WRITE(numout,*) 'Overall RMS obs minus model of the good observations: ',sqrt( zsumx2/numgoodobsmpp )
-	    WRITE(numout,*) ''
+            WRITE(numout,*) 'Type: ',fbdata%cname(jvar),'  Total number of good observations: ',inumgoodobsmpp 
+            WRITE(numout,*) 'Overall mean obs minus model of the good observations: ',zsumx/inumgoodobsmpp
+            WRITE(numout,*) 'Overall RMS obs minus model of the good observations: ',sqrt( zsumx2/inumgoodobsmpp )
+            WRITE(numout,*) ''
          ENDIF
- 
+
       ENDDO
 
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsaverg_h2d.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsaverg_h2d.h90	(revision 10247)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsaverg_h2d.h90	(revision 10247)
@@ -0,0 +1,777 @@
+   !!----------------------------------------------------------------------
+   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
+   !! $Id$
+   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
+   !!----------------------------------------------------------------------
+
+   SUBROUTINE obs_avg_h2d_init( kpk, kpk2, kmaxifp, kmaxjfp, k2dint, plam,  pphi, &
+      &                         pglam, pgphi, pglamf, pgphif, pmask, plamscl, pphiscl, lindegrees, &
+      &                         pweig, pobsmask, iminpoints )
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_avg_h2d_init  ***
+      !!
+      !! ** Purpose : Computes weights for horizontal averaging to the 
+      !!              observation footprint.
+      !!
+      !! ** Method  : Horizontal averaging to the observation footprint using
+      !!              model values at a defined area.
+      !!
+      !!    Averaging schemes :
+      !!
+      !!    Two horizontal averaging schemes are available:
+      !!        - weighted radial footprint        (k2dint = 5)
+      !!        - weighted rectangular footprint   (k2dint = 6)
+      !!
+      !! History :
+      !!        ! 13-10 (M. Martin)
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      !! * Arguments
+      INTEGER, INTENT(IN) :: &
+         & kpk,   &             ! Parameter values for automatic arrays
+         & kpk2,  &
+         & kmaxifp,  &          ! Max size of model points in i-direction for obs footprint
+         & kmaxjfp,  &          ! Max size of model points in j-direction for obs footprint
+         & k2dint               ! Averaging scheme options - see header
+      REAL(KIND=wp), INTENT(INOUT) :: &
+         & plam, &              ! Geographical (lat,lon) coordinates of
+         & pphi                 ! observation
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp), INTENT(IN) :: &
+         & pglam, &             ! Model variable lon
+         & pgphi                ! Model variable lat
+      REAL(KIND=wp), DIMENSION(kmaxifp+1,kmaxjfp+1), INTENT(IN) :: &
+         & pglamf, &            ! Model variable lon at corners of grid-boxes
+         & pgphif               ! Model variable lat at corners of grid-boxes
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(IN) :: &
+         & pmask                ! Model variable mask
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plamscl, &           ! Diameter (lat,lon) of obs footprint in metres
+         & pphiscl              ! This is the full width (rather than half-width)
+      LOGICAL, INTENT(IN) :: &
+         & lindegrees           ! T=> obs footprint specified in degrees, F=> in metres
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(OUT) ::  &
+         & pweig                ! Weights for averaging
+      REAL(KIND=wp), DIMENSION(kpk2), INTENT(OUT) ::  &
+         & pobsmask             ! Vertical mask for observations
+      INTEGER, INTENT(IN), OPTIONAL :: &
+         & iminpoints           ! Reject point which is not surrounded
+                                ! by at least iminpoints sea points
+
+      !! * Local declarations
+      INTEGER :: &
+         & jk
+      INTEGER :: &
+         & ikmax
+
+
+      !------------------------------------------------------------------------
+      !
+      !------------------------------------------------------------------------
+
+      !------------------------------------------------------------------------
+      ! Initialize number of levels
+      !------------------------------------------------------------------------
+      IF ( kpk2 == 1 ) THEN
+         ikmax = 1
+      ELSEIF ( kpk2 == kpk) THEN
+         ikmax = kpk-1
+      ENDIF
+
+
+         SELECT CASE (k2dint)
+         CASE(5)
+            CALL obs_avg_h2d_rad( kpk2, ikmax, kmaxifp, kmaxjfp, plam, pphi, &
+      &                           plamscl, pphiscl, lindegrees, pmask, pglam, pgphi, pglamf, pgphif, pweig )
+         CASE(6)
+            CALL obs_avg_h2d_rec( kpk2, ikmax, kmaxifp, kmaxjfp, plam, pphi, &
+      &                           plamscl, pphiscl, lindegrees, pmask, pglam, pgphi, pglamf, pgphif, pweig )
+         END SELECT
+
+
+      END SUBROUTINE obs_avg_h2d_init
+
+
+      SUBROUTINE obs_avg_h2d_rad( kpk2, kmax, kmaxifp, kmaxjfp, plam, pphi, &
+      &                           plamscl, pphiscl, lindegrees, pmask, pglam, pgphi, pglamf, pgphif, pweig )
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_avg_h2d_rad  ***
+      !!
+      !! ** Purpose : Computes weights for horizontal averaging to the 
+      !!              observation using a radial footprint.
+      !!
+      !! ** Method  : Calculate whether each grid box is completely or 
+      !!              partially within the observation footprint.
+      !!              If it is partially in the footprint then calculate
+      !!              the ratio of the area inside the footprint to the total 
+      !!              area of the grid box.
+      !!
+      !! History :
+      !!        ! 14-01 (M. Martin)
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      USE phycst,   ONLY : &  ! Physical constants
+         & ra,  &
+         & rpi
+
+      !! * Arguments
+      INTEGER, INTENT(IN) :: &
+         & kpk2, &             ! Parameter values for automatic arrays
+         & kmax
+
+      INTEGER, INTENT(IN) :: &
+         & kmaxifp,   &         ! Max size of model points in i-direction for obs footprint
+         & kmaxjfp              ! Max size of model points in j-direction for obs footprint
+
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plam, &
+         & pphi                 ! Geographical (lat,lon) coordinates of
+                                ! observation
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plamscl, &           ! Diameter (lat,lon) of obs footprint in metres or degrees (see below)
+         & pphiscl              ! This is the full width (rather than half-width)
+      LOGICAL, INTENT(IN) :: &
+         & lindegrees           ! T=>scales specified in degrees, F=> in metres
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(IN) :: &
+         & pmask                ! Model variable mask
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp), INTENT(IN) :: &
+         & pglam, &             ! Model variable lon
+         & pgphi                ! Model variable lat
+      REAL(KIND=wp), DIMENSION(kmaxifp+1,kmaxjfp+1), INTENT(IN) :: &
+         & pglamf, &             ! Model variable lon at corners of grid boxes
+         & pgphif                ! Model variable lat at corners of grid boxes
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(OUT) ::  &
+         & pweig                ! Weights for interpolation
+
+      !! Local declarations
+      INTEGER :: ji, jj, jk
+      INTEGER :: jvert, jis, jjs
+      INTEGER :: jnumvert, jnumvertbig
+      INTEGER, PARAMETER :: &
+         & jnumsubgrid = 20     ! The number of sub grid-boxes (in x and y directions) used to approximate area of obs fp
+
+      REAL(KIND=wp), DIMENSION(4) :: &
+         & zxvert, zyvert, &    ! The lon/lat of the vertices(corners) of the grid box in m relative to centre of obs fp
+         & zdist                ! Distance of each vertex to the centre of the obs footprint
+      REAL(KIND=wp), DIMENSION(4) :: &
+         & zxgrid, zygrid, &      ! Distance of each vertex of grid box to the centre of the grid box in x/y directions
+         & zdgrid
+      REAL(KIND=wp) :: &
+         & zdx, zdy, &          ! The sub grid-box sizes (in metres)
+         & zarea_subbox, &      ! The area of each sub grid-box (in metres squared)
+         & zxpos, zypos, &      ! The x,y position (relative to centre of obs footprint) of the centre of each sub grid-box
+         & zsubdist, &          ! The distance of the centre of each sub grid-box from the centre of the obs footprint
+         & zarea_fp, &          ! Total area of obs footprint within the grid box
+         & zareabox             ! Total area of the grid box
+      REAL(KIND=wp) :: &
+         & zphiscl_m, &         ! Diameter of obs footprint in metres
+         & zlamscl_m
+      !---------------------------------------------------------------------------------------------------
+      !Initialise weights to zero.
+      pweig(:,:,:) = 0.0_wp
+      
+      !Two footprint sizes can be specified in the namelist but this routine assumes a circular footprint. 
+      !If the two sizes are different then write out a warning.
+      IF ( pphiscl /= plamscl ) THEN
+               CALL ctl_warn( 'obs_avg_h2d_rad:',   &
+                  &           'The two components of the obs footprint size are not equal', &
+                  &           'yet the radial option has been selected - using pphiscl here' )
+      ENDIF
+      
+      DO jk = 1, kmax
+         DO ji = 1, kmaxifp
+            DO jj = 1, kmaxjfp
+            
+               IF ( pmask(ji,jj,jk) == 1.0_wp ) THEN
+
+                  IF ( lindegrees ) THEN
+                     !If the scales are specified in degrees, work out the
+                     !scales (metres) in x/y directions
+                     CALL obs_deg2dist( 1, 1, pglam(ji,jj), pgphi(ji,jj), &
+                        &               plamscl, pphiscl, zlamscl_m, zphiscl_m )
+                  ELSE
+                     zphiscl_m = pphiscl
+                  ENDIF
+
+
+                  ! Work out the area of the grid box using distance of corners relative to centre of grid box
+                  CALL obs_dist2corners(pglamf(ji,jj), pglamf(ji+1,jj), pglamf(ji,jj+1), pglamf(ji+1,jj+1), &
+                     &                  pgphif(ji,jj), pgphif(ji+1,jj), pgphif(ji,jj+1), pgphif(ji+1,jj+1), &
+                     &                  pglam(ji,jj), pgphi(ji,jj), zxgrid, zygrid, zdgrid)
+                  zareabox = ABS( zxgrid(1) - zxgrid(2) ) * ABS( zygrid(1) - zygrid(4) )
+
+                  !1. Determine how many of the vertices of the grid box lie within the circle
+                  
+                  !For each vertex, calculate its location and distance relative 
+                  !to the centre of the observation footprint
+                  
+                  CALL obs_dist2corners(pglamf(ji,jj), pglamf(ji+1,jj), pglamf(ji,jj+1), pglamf(ji+1,jj+1), &
+                     &                  pgphif(ji,jj), pgphif(ji+1,jj), pgphif(ji,jj+1), pgphif(ji+1,jj+1), &
+                     &                  plam, pphi, zxvert, zyvert, zdist)
+
+                  jnumvert = 0
+                  jnumvertbig = 0
+                  DO jvert = 1, 4
+
+                     !If the distance to the center to the observation footprint is less
+                     !than the radius of the footprint (half the diameter) then this
+                     !vertex is within the observation footprint
+                     IF ( zdist(jvert) <= ( zphiscl_m / 2.0_wp ) ) jnumvert = jnumvert + 1
+                     
+                     !For expediency, check if the vertices are "nearly" within the obs
+                     !footprint as if none of them are close to the edge of the footprint
+                     !then the footprint is unlikely to be intersecting the grid box
+                     IF ( zdist(jvert) - ( 0.5_wp * zareabox ) <= ( zphiscl_m / 2.0 ) ) &
+                        & jnumvertbig = jnumvertbig + 1
+                     
+                  END DO
+                  
+                  !2. If none of the vertices are even close to the edge of the obs
+                  !footprint then leave weight as zero and cycle to next grid box.
+                  IF ( jnumvertbig == 0 ) CYCLE
+
+                  !3. If all the vertices of the box are within the observation footprint then the 
+                  !      whole grid box is within the footprint so set the weight to one and 
+                  !      move to the next grid box.
+                  IF ( jnumvert == 4 ) THEN
+                     pweig(ji,jj,jk) = 1.0_wp
+                     CYCLE
+                  ENDIF
+
+
+                  !4. Use a brute force technique for calculating the area within 
+                  !   the grid box covered by the obs footprint.
+                  !  (alternative could be to use formulae on 
+                  !         http://mathworld.wolfram.com/Circle-LineIntersection.html)
+                  !   For now split the grid box into a specified number of smaller 
+                  !   boxes and add up the area of those whose centre is within the obs footprint.
+                  !   Order of vertices is 1=topleft, 2=topright, 3=bottomright, 4=bottomleft
+                  zdx = ABS( zxvert(3) - zxvert(4) ) / REAL(jnumsubgrid, wp)
+                  zdy = ABS( zyvert(1) - zyvert(4) ) / REAL(jnumsubgrid, wp)
+                  zarea_subbox = zdx * zdy
+
+                  zarea_fp = 0.0_wp
+                  DO jis = 1, jnumsubgrid
+                     zxpos = zxvert(4) + ( REAL(jis, wp) * zdx ) - (0.5_wp * zdx )
+                     DO jjs = 1, jnumsubgrid
+                        !Find the distance of the centre of this sub grid box to the
+                        !centre of the obs footprint
+                        zypos = zyvert(4) + ( REAL(jjs, wp) * zdy ) - ( 0.5_wp * zdy )
+                        zsubdist = SQRT( (zxpos * zxpos) + (zypos * zypos) )
+                        IF ( zsubdist < ( zphiscl_m / 2.0_wp ) ) &
+                           &  zarea_fp = zarea_fp + zarea_subbox
+                     END DO
+                  END DO
+
+                  !6. Calculate the ratio of the area of the footprint within the box 
+                  !   to the total area of the grid box and use this fraction to weight 
+                  !   the model value in this grid box.
+                  pweig(ji,jj,jk) = MIN( zarea_fp / zareabox, 1.0_wp )
+
+               END IF  !pmask
+            END DO
+         END DO
+      END DO
+      
+      END SUBROUTINE obs_avg_h2d_rad
+
+
+      SUBROUTINE obs_avg_h2d_rec( kpk2, kmax, kmaxifp, kmaxjfp, plam, pphi, &
+      &                           plamscl, pphiscl, lindegrees, pmask, pglam, pgphi, pglamf, pgphif, pweig )
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_avg_h2d_rec  ***
+      !!
+      !! ** Purpose : Computes weights for horizontal averaging to the
+      !!              observation using a rectangular footprint which
+      !!              is aligned with lines of lat/lon.
+      !!
+      !! ** Method  : Horizontal averaging to the observation footprint using
+      !!              model values at a defined area.
+      !!
+      !! History :
+      !!        ! 14-01 (M. Martin)
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      USE phycst,   ONLY : &    ! Physical constants
+         & ra,  &
+         & rpi
+
+      !! * Arguments
+      INTEGER, INTENT(IN) :: &
+         & kpk2, &              ! Parameter values for automatic arrays
+         & kmax
+
+      INTEGER, INTENT(IN) :: &
+         & kmaxifp,   &         ! Max size of model points in i-direction for obs footprint
+         & kmaxjfp              ! Max size of model points in j-direction for obs footprint
+
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plam, &
+         & pphi                 ! Geographical (lat,lon) coordinates of
+                                ! observation
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plamscl, &
+         & pphiscl              ! Width in x/y directions of obs footprint in metres
+                                ! This is the full width (rather than half-width)
+      LOGICAL, INTENT(IN) :: &
+         & lindegrees           !T=> scales specified in degrees, F=> in metres
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(IN) :: &
+         & pmask                ! Model variable mask
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp), INTENT(IN) :: &
+         & pglam, &             ! Model variable lat at centre of grid boxes
+         & pgphi                ! Model variable lon at centre of grid boxes
+      REAL(KIND=wp), DIMENSION(kmaxifp+1,kmaxjfp+1), INTENT(IN) :: &
+         & pglamf, &             ! Model variable lat at corners of grid boxes
+         & pgphif                ! Model variable lon at corners of grid boxes
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(OUT) ::  &
+         & pweig                ! Weights for interpolation
+
+      !! Local declarations
+      INTEGER :: ji, jj, jk
+      INTEGER :: jvert
+      INTEGER, DIMENSION(4) :: &
+         & jnumvert
+      REAL(KIND=wp), DIMENSION(4) :: &
+         & zxvert, zyvert         ! The lon/lat of the vertices(corners) of the grid box in m relative to centre of obs fp
+      REAL(KIND=wp), DIMENSION(4) :: &
+         & zdist                  ! Distance of each vertex to the centre of the obs footprint
+      REAL(KIND=wp), DIMENSION(4) :: &
+         & zxgrid, zygrid, &      ! Distance of each vertex of grid box to the centre of the grid box in x/y directions
+         & zdgrid
+      REAL(KIND=wp) :: &
+         & zareabox, &            ! Total area of grid box
+         & zarea_fp, &            ! Total area of obs footprint
+         & zarea_intersect        ! Area of the intersection between the grid box and the obs footprint
+      REAL(KIND=wp) :: &
+         & zlamscl_m, &
+         & zphiscl_m              ! Total width (lat,lon) of obs footprint in metres
+      REAL(KIND=wp) :: &
+         & z_awidth, z_aheight, & ! Width and height of model grid box
+         & z_cwidth, z_cheight    ! Width and height of union of model grid box and obs footprint
+      REAL(KIND=wp) :: &
+         & zleft, zright, &       ! Distance (metres) of corners area of intersection
+         & ztop, zbottom          ! between grid box and obs footprint
+
+      !-----------------------------------------------------------------------
+
+      !Initialise weights to zero
+      pweig(:,:,:) = 0.0_wp
+      
+      !Loop over the grid boxes which have been identified as potentially being within the
+      !observation footprint
+      DO jk = 1, kmax
+         DO ji = 1, kmaxifp
+            DO jj = 1, kmaxjfp
+
+               IF ( pmask(ji,jj,jk) == 1.0_wp ) THEN
+
+
+                  IF ( lindegrees ) THEN
+                     !If the scales are specified in degrees, work out the
+                     !scales (metres) in x/y directions
+                     CALL obs_deg2dist( 1, 1, pglam(ji,jj), pgphi(ji,jj), &
+                        &               plamscl, pphiscl, zlamscl_m, zphiscl_m )
+                  ELSE
+                     zlamscl_m = plamscl
+                     zphiscl_m = pphiscl
+                  ENDIF
+
+                  ! Work out the area of the grid box using distance of corners relative to centre of grid box
+                  CALL obs_dist2corners(pglamf(ji,jj), pglamf(ji+1,jj), pglamf(ji,jj+1), pglamf(ji+1,jj+1), &
+                     &                  pgphif(ji,jj), pgphif(ji+1,jj), pgphif(ji,jj+1), pgphif(ji+1,jj+1), &
+                     &                  pglam(ji,jj), pgphi(ji,jj), zxgrid, zygrid, zdgrid)
+
+                  !Calculate width and height of model grid box
+                  z_awidth  = ABS( zxgrid(1) - zxgrid(2) )
+                  z_aheight = ABS( zygrid(1) - zygrid(4) )
+                  zareabox = z_awidth * z_aheight
+
+                  ! Work out area of the observation footprint
+                  zarea_fp = zlamscl_m * zphiscl_m
+
+                  ! For each corner of the grid box, calculate its location and distance relative
+                  ! to the centre of the observation footprint
+                  CALL obs_dist2corners(pglamf(ji,jj), pglamf(ji+1,jj), pglamf(ji,jj+1), pglamf(ji+1,jj+1), &
+                     &                  pgphif(ji,jj), pgphif(ji+1,jj), pgphif(ji,jj+1), pgphif(ji+1,jj+1), &
+                     &                  plam, pphi, zxvert, zyvert, zdist)
+
+                  !Work out maximum width and height of rectangle covered by corners of obs fp and grid box
+                  z_cwidth  = MAX( zxvert(1), zxvert(2), -zlamscl_m/2.0_wp, zlamscl_m/2.0_wp ) - &
+                     &       MIN( zxvert(1), zxvert(2), -zlamscl_m/2.0_wp, zlamscl_m/2.0_wp )
+                     
+                  z_cheight = MAX( zyvert(1), zyvert(4), zphiscl_m/2.0_wp, -zphiscl_m/2.0_wp ) - &
+                     &       MIN( zyvert(1), zyvert(4), zphiscl_m/2.0_wp, -zphiscl_m/2.0_wp )
+                  
+                  IF ( ( z_cwidth  >= z_awidth  + zlamscl_m  ) .OR. &
+                     & ( z_cheight >= z_aheight + zphiscl_m ) ) THEN
+                     !The obs footprint and the model grid box don't overlap so set weight to zero
+                     pweig(ji,jj,jk) = 0.0_wp
+                  ELSE IF ( ( z_cwidth  == zlamscl_m ) .AND. &
+                     &      ( z_cheight == zphiscl_m ) ) THEN
+                     !The grid box is totally contained within the obs footprint so set weight to one
+                     pweig(ji,jj,jk) = 1.0_wp
+                  ELSE IF ( ( z_cwidth  == z_awidth  ) .AND. &
+                     &      ( z_cheight == z_aheight ) ) THEN
+                     !The obs footprint is totally contained within the grid box so set weight as ratio of the two
+                     pweig(ji,jj,jk) = zarea_fp / zareabox
+                  ELSE 
+                     !The obs footprint and the grid box overlap so calculate the area of the intersection of the two
+                     zleft   = max(zxvert(1), -zlamscl_m/2.0_wp)
+                     zright  = min(zxvert(2),  zlamscl_m/2.0_wp)
+                     zbottom = max(zyvert(4), -zphiscl_m/2.0_wp)
+                     ztop    = min(zyvert(1),  zphiscl_m/2.0_wp)
+                     
+                     IF (  ( zleft < zright ) .AND. ( zbottom < ztop ) ) THEN
+                        zarea_intersect = ( zright - zleft ) * ( ztop - zbottom )
+                        pweig(ji,jj,jk) = zarea_intersect / zareabox
+                     ENDIF
+                  ENDIF
+
+               END IF !pmask
+            END DO
+         END DO
+      END DO
+
+   END SUBROUTINE obs_avg_h2d_rec
+
+   SUBROUTINE obs_avg_h2d( kpk, kpk2, kmaxifp, kmaxjfp, pweig, pmod, pobsk )
+
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_int_h2d  ***
+      !!
+      !! ** Purpose : Horizontal averaging to the observation footprint.
+      !!
+      !! ** Method  : Average the model points based on the weights already calculated.
+      !!
+      !! ** Action  :
+      !!                   
+      !! References : 
+      !!
+      !! History :
+      !!        ! 13/10. M. Martin.
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      !! * Arguments
+      INTEGER, INTENT(IN) :: &
+         & kpk,   &             ! Parameter values for automatic arrays
+         & kpk2
+      INTEGER, INTENT(IN) :: &
+         & kmaxifp,   &         ! Max size of model points in i-direction for obs footprint
+         & kmaxjfp              ! Max size of model points in j-direction for obs footprint
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(IN) :: &
+         & pweig                ! Interpolation weights
+      REAL(KIND=wp), DIMENSION(kmaxifp,kmaxjfp,kpk2), INTENT(IN) :: &
+         & pmod                 ! Model variable to interpolate
+      REAL(KIND=wp), DIMENSION(kpk2), INTENT(OUT) ::  &
+         & pobsk                ! Model profile interpolated to obs (i,j) pt
+
+      INTEGER :: &
+         & jk
+      INTEGER :: &
+         & ikmax
+      REAL(KIND=wp) :: &
+         & zsum
+
+      !------------------------------------------------------------------------
+      ! Initialize number of levels
+      !------------------------------------------------------------------------
+      IF ( kpk2 == 1 ) THEN
+         ikmax = 1
+      ELSEIF ( kpk2 == kpk) THEN
+         ikmax = kpk-1
+      ENDIF
+
+      !------------------------------------------------------------------------
+      ! Average model values to the observation footprint
+      !------------------------------------------------------------------------
+      pobsk = obfillflt
+
+      DO jk = 1, ikmax
+
+         zsum = SUM( pweig(:,:,jk) )
+
+         IF ( zsum /= 0.0_wp ) THEN
+            pobsk(jk) = SUM ( pweig(:,:,jk) * pmod(:,:,jk), Mask=pweig(:,:,jk) > 0.0_wp )
+            pobsk(jk) = pobsk(jk) / zsum
+         END IF
+
+      END DO
+
+   END SUBROUTINE obs_avg_h2d
+
+   SUBROUTINE obs_max_fpsize( k2dint, plamscl, pphiscl, lindegrees, pmask, kmaxifp, kmaxjfp )
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_max_fpsize  ***
+      !!
+      !! ** Purpose : Calculate maximum number of grid points which may
+      !!              need to be used in the averaging in the global domain.
+      !!
+      !!
+      !! ** Method  : Work out the minimum grid size and work out
+      !!              how many of the smallest grid points would be needed
+      !!              to cover the scale of the observation footprint.
+      !!              This needs to be done using the max/min of the global domain
+      !!              as the obs can be distributed from other parts of the grid.
+      !!
+      !! ** Action  :
+      !!                   
+      !! References : 
+      !!
+      !! History :
+      !!        ! 14/01. M. Martin. 
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      !! * Arguments
+      INTEGER , INTENT(IN) :: &
+         & k2dint                   !Type of interpolation/averaging used
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plamscl,   &             !Total width/radius in metres of the observation footprint
+         & pphiscl                  !
+      LOGICAL, INTENT(IN) :: &
+         & lindegrees               !T=> plamscl and pphiscl are specified in degrees
+      REAL(KIND=wp), DIMENSION(jpi,jpj), INTENT(IN) :: &
+         & pmask                    !Land/sea mask
+                                    !F=> plamscl and pphiscl are specified in metres
+      INTEGER, INTENT(OUT)  :: &
+         & kmaxifp,   &             !Max number of grid points in i,j directions to use in averaging
+         & kmaxjfp                  !these have to be even so that the footprint is centred
+
+      !! * Local variables
+      REAL(KIND=wp) :: &
+         & ze1min,     &            !Minimum global grid-size in i,j directions
+         & ze2min
+      REAL(KIND=wp) :: &
+         & zphiscl_m, &
+         & zlamscl_m
+      !------------------------------------------------------------------------
+
+      IF ( k2dint <= 4 ) THEN
+         !If interpolation is being used then only need to use a 2x2 footprint
+         kmaxifp = 2
+         kmaxjfp = 2
+
+      ELSE
+
+         IF ( lindegrees ) THEN
+            !If the scales are specified in degrees, work out the max 
+            !distance (metres) in x/y directions
+            CALL obs_deg2dist( jpi, jpj, glamt, gphit, &
+               &               plamscl, pphiscl, zlamscl_m, zphiscl_m )
+         ELSE
+            zlamscl_m = plamscl
+            zphiscl_m = pphiscl
+         ENDIF
+
+         ze1min = MINVAL( e1t(:,:), mask = pmask(:,:) == 1._wp )
+         ze2min = MINVAL( e2t(:,:), mask = pmask(:,:) == 1._wp )
+         
+         IF(lk_mpp) THEN
+            CALL mpp_min( ze1min )
+            CALL mpp_min( ze2min )
+         ENDIF
+
+         kmaxifp = ceiling(zlamscl_m/ze1min) + 1
+         kmaxjfp = ceiling(zphiscl_m/ze2min) + 1
+         
+         !Ensure that these numbers are even
+         kmaxifp = kmaxifp + MOD(kmaxifp,2)
+         kmaxjfp = kmaxjfp + MOD(kmaxjfp,2)
+         
+
+      ENDIF
+
+   END SUBROUTINE obs_max_fpsize
+
+   SUBROUTINE obs_deg2dist( ki, kj, pglam, pgphi, plamscl_deg, pphiscl_deg, &
+      &                     plamscl_max, pphiscl_max )
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_deg2dist  ***
+      !!
+      !! ** Purpose : Calculate the maximum distance in m of the length scale
+      !!              in degrees.
+      !!
+      !! ** Method  : At each lon/lat point, work out the distances in the 
+      !!              zonal and meridional directions.
+      !!
+      !! ** Action  :
+      !!                   
+      !! References : 
+      !!
+      !! History :
+      !!        ! 14/01. M. Martin. 
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      !! * Arguments
+      INTEGER , INTENT(IN) :: &
+         & ki, kj                   !x/y dimensions of input lat/lon variables
+      REAL(KIND=wp), INTENT(IN), DIMENSION(ki,kj) :: &
+         & pglam, pgphi             !Longitude and latitudes of grid points
+      REAL(KIND=wp), INTENT(IN) :: &
+         & plamscl_deg,   &         !Size in degrees of the observation footprint
+         & pphiscl_deg              !
+      REAL(KIND=wp), INTENT(OUT) :: &
+         & plamscl_max, &           !Maximum size of obs footprint in metres
+         & pphiscl_max
+      
+      !! * Local declarations
+      INTEGER :: &
+         & ji, jj                   !Counters
+      REAL(KIND=wp) :: &
+         & zlon1, zlon2, &          !Lon values surrounding centre of grid point
+         & zlat1, zlat2, &          !Lat values surrounding centre of grid point
+         & zdlat, zdlon             !Distance in radians in lat/lon directions
+      REAL(KIND=wp) :: &
+         & za1, za2, za, zc, zd
+      
+      plamscl_max = -1.0_wp
+      pphiscl_max = -1.0_wp
+
+      DO ji = 1, ki
+         DO jj = 1, kj
+
+            !Calculate distance in metres in zonal(x) direction
+
+            zlon1 = rad * ( pglam(ji,jj) + ( 0.5_wp * plamscl_deg ) )
+            zlon2 = rad * ( pglam(ji,jj) - ( 0.5_wp * plamscl_deg ) )
+            zlat1 = rad * pgphi(ji,jj)
+            zlat2 = rad * pgphi(ji,jj)
+            zdlon = zlon2 - zlon1
+            zdlat = zlat2 - zlat1
+
+            za1 = sin( zdlat/2.0_wp )
+            za2 = sin( zdlon/2.0_wp )
+            za = ( za1 * za1 ) + ( COS( zlat1 ) * COS( zlat2 ) * ( za2 * za2 ) )
+            zc = 2.0_wp * atan2( SQRT( za ), SQRT( 1.0_wp-za ) )
+            zd = ra * zc
+
+            IF ( zd > plamscl_max ) plamscl_max = zd
+
+            !Calculate distance in metres in meridional(y) direction
+
+            zlon1 = rad * pglam(ji,jj)
+            zlon2 = rad * pglam(ji,jj)
+            zlat1 = rad * ( pgphi(ji,jj) + ( 0.5_wp * pphiscl_deg ) )
+            zlat2 = rad * ( pgphi(ji,jj) - ( 0.5_wp * pphiscl_deg ) )
+            zdlon = zlon2 - zlon1
+            zdlat = zlat2 - zlat1
+
+            za1 = sin( zdlat/2.0_wp )
+            za2 = sin( zdlon/2.0_wp )
+            za = ( za1 * za1 ) + ( COS( zlat1 ) * COS( zlat2 ) * ( za2 * za2 ) )
+            zc = 2.0_wp * atan2( SQRT( za ), SQRT( 1.0_wp-za ) )
+            zd = ra * zc
+
+            IF ( zd > pphiscl_max ) pphiscl_max = zd
+
+         END DO
+      END DO
+         
+   END SUBROUTINE obs_deg2dist
+
+   SUBROUTINE obs_dist2corners(pglam_bl, pglam_br, pglam_tl, pglam_tr, &
+      &                        pgphi_bl, pgphi_br, pgphi_tl, pgphi_tr, &
+      &                        plam, pphi, pxvert, pyvert, pdist)
+      !!-----------------------------------------------------------------------
+      !!
+      !!                     ***  ROUTINE obs_dist2corners  ***
+      !!
+      !! ** Purpose : Calculate distance from centre of obs footprint to the corners of a grid box
+      !!
+      !! ** Method  : Use great circle distance formulae.
+      !!              Order of corners is 1=topleft, 2=topright, 3=bottomright, 4=bottomleft
+      !!
+      !! ** Action  :
+      !!                   
+      !! References : 
+      !!
+      !! History :
+      !!        ! 14/01. M. Martin.
+      !!-----------------------------------------------------------------------
+      !! * Modules used
+      !! * Arguments
+         REAL(KIND=wp), INTENT(IN) :: &
+            &  pglam_bl, pglam_br, &       !lon at corners of grid box
+            &  pglam_tl, pglam_tr
+         REAL(KIND=wp), INTENT(IN) :: &
+            &  pgphi_bl, pgphi_br, &       !lat at corners of grid box
+            &  pgphi_tl, pgphi_tr
+         REAL(KIND=wp), INTENT(IN) :: &
+            &  pphi, plam                  !lat/lon of centre of obs footprint
+         REAL(KIND=wp), DIMENSION(4), INTENT(OUT) :: &
+            &  pxvert, pyvert              !x/y location (in metres relative to centre of obs footprint) of corners
+         REAL(KIND=wp), DIMENSION(4), INTENT(OUT) :: &
+            &  pdist                       !distance (in metres) of each corner relative to centre of obs footprint
+
+      !! * Local variables
+         INTEGER :: &
+            &  jvert                       !Counter for corners
+         REAL(KIND=wp) :: &
+            &  zphi, zlam                  !Local values for lon/lat of corners
+         REAL(KIND=wp) :: & 
+            &  za1, za2,  &                !For great circle distance calculations
+            &  zb1, zb2,  &
+            &  zc1, zc2
+         REAL(KIND=wp) :: &
+            &  zdist_centre_lat, &         !Distances in lat/lon directions (in metres)
+            &  zdist_centre_lon
+
+      !!-----------------------------------------------------------------------
+
+         ! Work out latitudinal and longitudinal distance from centre of 
+         ! obs fp to corners of grid box
+         DO jvert = 1, 4
+            SELECT CASE(jvert)
+            CASE(1)
+               zphi = pgphi_tl
+               zlam = pglam_tl
+            CASE(2)
+               zphi = pgphi_tr
+               zlam = pglam_tr
+            CASE(3)
+               zphi = pgphi_br
+               zlam = pglam_br
+            CASE(4)
+               zphi = pgphi_bl
+               zlam = pglam_bl
+            END SELECT
+            
+            IF (zlam == plam ) THEN
+               pxvert(jvert) = 0.0_wp
+            ELSE
+               za1 = SIN( zphi * rad )
+               za2 = SIN( zphi * rad )
+               zb1 = COS( zphi * rad ) * COS( zlam * rad )
+               zb2 = COS( zphi * rad ) * COS( plam  * rad )
+               zc1 = COS( zphi * rad ) * SIN( zlam * rad )
+               zc2 = COS( zphi * rad ) * SIN( plam  * rad )
+               pxvert(jvert) = grt_cir_dis( za1, za2, zb1, zb2, zc1, zc2 )
+               pxvert(jvert) =  ra * pxvert(jvert)
+               IF ( zlam < plam ) pxvert(jvert) = - pxvert(jvert)
+            ENDIF
+            
+            IF ( zphi == pphi ) THEN
+               pyvert(jvert) = 0.0_wp
+            ELSE
+               za1 = SIN( zphi * rad )
+               za2 = SIN( pphi * rad )
+               zb1 = COS( zphi * rad ) * COS( zlam * rad )
+               zb2 = COS( pphi * rad ) * COS( zlam * rad )
+               zc1 = COS( zphi * rad ) * SIN( zlam * rad )
+               zc2 = COS( pphi * rad ) * SIN( zlam * rad )
+               pyvert(jvert) = grt_cir_dis( za1, za2, zb1, zb2, zc1, zc2 )
+               pyvert(jvert) =  ra * pyvert(jvert)
+               IF ( zphi < pphi ) pyvert(jvert) = - pyvert(jvert)
+            ENDIF
+
+            !Calculate the distance of each vertex relative to centre of obs footprint
+            pdist(jvert) = SQRT( ( pxvert(jvert) * pxvert(jvert) ) + &
+               &                 ( pyvert(jvert) * pyvert(jvert) ) )
+
+         END DO
+
+      END SUBROUTINE obs_dist2corners
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsinter_h2d.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsinter_h2d.h90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsinter_h2d.h90	(revision 10247)
@@ -1240,5 +1240,6 @@
          & zdum,  &
          & zaamax
-       
+      
+      imax = -1 
       ! Main computation
       pflt = 1.0_wp
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsprof_io.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsprof_io.h90	(revision 10246)
+++ 	(revision )
@@ -1,834 +1,0 @@
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   SUBROUTINE read_enactfile( cdfilename, inpfile, kunit, ldwp, ldgrid )
-      !!---------------------------------------------------------------------
-      !!
-      !!                     ** ROUTINE read_enactfile **
-      !!
-      !! ** Purpose : Read from file the profile ENACT observations.
-      !!
-      !! ** Method  : The data file is a NetCDF file. 
-      !!
-      !! ** Action  :
-      !!
-      !! History : 
-      !!          ! 09-01 (K. Mogensen) Original based on old versions
-      !!----------------------------------------------------------------------
-      !! * Arguments
-      CHARACTER(LEN=*) :: cdfilename ! Input filename
-      TYPE(obfbdata)   :: inpfile    ! Output obfbdata structure
-      INTEGER          :: kunit      ! Unit for output
-      LOGICAL          :: ldwp       ! Print info
-      LOGICAL          :: ldgrid     ! Save grid info in data structure
-      !! * Local declarations
-      INTEGER :: iobs                ! Number of observations
-      INTEGER :: ilev                      ! Number of levels
-      INTEGER :: i_file_id
-      INTEGER :: i_obs_id
-      INTEGER :: i_lev_id
-      INTEGER :: i_phi_id
-      INTEGER :: i_lam_id
-      INTEGER :: i_depth_id
-      INTEGER :: i_var_id
-      INTEGER :: i_pl_num_id
-      INTEGER :: i_reference_date_time_id
-      INTEGER :: i_format_version_id
-      INTEGER :: i_juld_id
-      INTEGER :: i_data_type_id
-      INTEGER :: i_wmo_inst_type_id
-      INTEGER :: i_qc_var_id
-      INTEGER :: i_dc_ref_id
-      INTEGER :: i_qc_flag_id
-      CHARACTER(LEN=40) :: cl_fld_lam
-      CHARACTER(LEN=40) :: cl_fld_phi
-      CHARACTER(LEN=40) :: cl_fld_depth 
-      CHARACTER(LEN=40) :: cl_fld_var_tp
-      CHARACTER(LEN=40) :: cl_fld_var_s
-      CHARACTER(LEN=40) :: cl_fld_var_ti
-      CHARACTER(LEN=40) :: cl_fld_var_juld_qc
-      CHARACTER(LEN=40) :: cl_fld_var_pos_qc
-      CHARACTER(LEN=40) :: cl_fld_var_depth_qc 
-      CHARACTER(LEN=40) :: cl_fld_var_qc_t
-      CHARACTER(LEN=40) :: cl_fld_var_qc_s
-      CHARACTER(LEN=40) :: cl_fld_var_prof_qc_t
-      CHARACTER(LEN=40) :: cl_fld_var_prof_qc_s
-      CHARACTER(LEN=40) :: cl_fld_reference_date_time
-      CHARACTER(LEN=40) :: cl_fld_juld
-      CHARACTER(LEN=40) :: cl_fld_data_type
-      CHARACTER(LEN=40) :: cl_fld_pl_num
-      CHARACTER(LEN=40) :: cl_fld_format_version
-      CHARACTER(LEN=40) :: cl_fld_wmo_inst_type
-      CHARACTER(LEN=40) :: cl_fld_qc_flags_profiles
-      CHARACTER(LEN=40) :: cl_fld_qc_flags_levels
-
-      CHARACTER(LEN=14), PARAMETER :: cl_name = 'read_enactfile'
-      CHARACTER(LEN=16)            :: cl_data_type = ''
-      CHARACTER(LEN=4 )            :: cl_format_version = ''
-      INTEGER, DIMENSION(1) :: istart1, icount1
-      INTEGER, DIMENSION(2) :: istart2, icount2
-      CHARACTER(len=imaxlev) :: clqc
-      CHARACTER(len=1) :: cqc
-      INTEGER :: ji, jk
-      INTEGER, ALLOCATABLE, DIMENSION(:) :: iqc1
-      INTEGER, ALLOCATABLE, DIMENSION(:,:) :: iqc2
-
-      !-----------------------------------------------------------------------
-      ! Initialization
-      !-----------------------------------------------------------------------
-
-      cl_fld_lam                 = 'LONGITUDE'
-      cl_fld_phi                 = 'LATITUDE'
-      cl_fld_depth               = 'DEPH_CORRECTED'
-      cl_fld_reference_date_time = 'REFERENCE_DATE_TIME'
-      cl_fld_juld                = 'JULD'
-      cl_fld_data_type           = 'DATA_TYPE'
-      cl_fld_format_version      = 'FORMAT_VERSION'
-      cl_fld_wmo_inst_type       = 'WMO_INST_TYPE'
-      cl_fld_pl_num              = 'PLATFORM_NUMBER'
-
-      cl_fld_var_qc_t            = 'POTM_CORRECTED_QC'
-      cl_fld_var_prof_qc_t       = 'PROFILE_POTM_QC'
-      cl_fld_var_tp              = 'POTM_CORRECTED'
-      cl_fld_var_qc_s            = 'PSAL_CORRECTED_QC'
-      cl_fld_var_prof_qc_s       = 'PROFILE_PSAL_QC'
-      cl_fld_var_s               = 'PSAL_CORRECTED'
-      cl_fld_var_depth_qc        = 'DEPH_CORRECTED_QC'
-      cl_fld_var_juld_qc         = 'JULD_QC'
-      cl_fld_var_pos_qc          = 'POSITION_QC'
-      cl_fld_var_ti              = 'TEMP'
-      cl_fld_qc_flags_profiles   = 'QC_FLAGS_PROFILES'
-      cl_fld_qc_flags_levels     = 'QC_FLAGS_LEVELS'
-
-      icount1(1) = 1 
-
-      !-----------------------------------------------------------------------
-      ! Open file
-      !-----------------------------------------------------------------------
-
-      CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, &
-            &      i_file_id ),           cl_name, __LINE__ )
-
-      !-----------------------------------------------------------------------
-      ! Read the heading of the file
-      !-----------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_data_type,      &
-         &         i_data_type_id ),      cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_data_type_id,        &
-         &         cl_data_type ),        cl_name, __LINE__ )
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_format_version, &
-         &         i_format_version_id ), cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_format_version_id,   &
-         &         cl_format_version ),   cl_name, __LINE__ )
-      
-      CALL str_c_to_for( cl_data_type )
-      CALL str_c_to_for( cl_format_version )
-      
-      IF(ldwp)WRITE(kunit,*)
-      IF(ldwp)WRITE(kunit,*) ' read_enactfile :' 
-      IF(ldwp)WRITE(kunit,*) ' ~~~~~~~~~~~~~~~~'
-      IF(ldwp)WRITE(kunit,*) '               Data type           = ', &
-         &                TRIM( ADJUSTL( cl_data_type ) )
-      IF(ldwp)WRITE(kunit,*) '               Format version      = ',  &
-         &                TRIM( ADJUSTL( cl_format_version ) )
-      
-      IF ( ( ( INDEX( cl_data_type,"ENACT v1.0" ) == 1 ) .OR.   &
-         &   ( INDEX( cl_data_type,"ENACT v1.4" ) == 1 ) .OR.   &
-         &   ( INDEX( cl_data_type,"ENACT v1.5" ) == 1 ) .OR.   &
-         &   ( INDEX( cl_data_type,"ENSEMBLES EN3 v1" ) == 1 )      ) &
-         &   .AND.                                              &
-         &   ( INDEX( cl_format_version,"2.0"   ) == 1 ) ) THEN
-         IF(ldwp)WRITE(kunit,*)'               Valid input file'
-      ELSE
-         CALL fatal_error( 'Invalid input file', __LINE__ )
-      ENDIF
-
-      !---------------------------------------------------------------------
-      ! Read the number of observations and levels to allocate arrays
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_dimid        ( i_file_id, 'N_PROF', i_obs_id ),         &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_obs_id, len = iobs ),     &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inq_dimid        ( i_file_id, 'N_LEVELS', i_lev_id ),     &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_lev_id, len = ilev ), &
-         &         cl_name, __LINE__ )
-      IF(ldwp)WRITE(kunit,*) '               No. of data records = ', iobs
-      IF(ldwp)WRITE(kunit,*) '               No. of levels       = ', ilev
-      IF(ldwp)WRITE(kunit,*) 
-      IF (ilev > imaxlev) THEN
-         CALL fatal_error( 'Increase imaxlev in obs_prof_io.F90', __LINE__ )
-      ENDIF
-
-      !---------------------------------------------------------------------
-      ! Allocate arrays
-      !---------------------------------------------------------------------
-
-      CALL init_obfbdata( inpfile )
-      CALL alloc_obfbdata( inpfile, 2, iobs, ilev, 0, 1, ldgrid )
-      inpfile%cname(1) = 'POTM'
-      inpfile%cname(2) = 'PSAL'
-      inpfile%coblong(1) = 'Potential temperature'
-      inpfile%coblong(2) = 'Practical salinity'
-      inpfile%cobunit(1) = 'Degrees Celsius'
-      inpfile%cobunit(2) = 'PSU'
-      inpfile%cextname(1) = 'TEMP'
-      inpfile%cextlong(1) = 'Insitu temperature'
-      inpfile%cextunit(1) = 'Degrees Celsius'
-
-      !---------------------------------------------------------------------
-      ! Read the QC atributes
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_qc_t, i_qc_var_id ),                         &
-         &         cl_name, __LINE__ )        
-      istart2(1) = 1
-      icount2(2) = 1
-      icount2(1) = ilev
-      DO ji = 1, iobs 
-         istart2(2) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, clqc,                                   &
-            &                         start = istart2, count = icount2),                              &
-            &         cl_name, __LINE__ )
-         DO jk = 1, ilev
-            inpfile%ivlqc(jk,ji,1) = IACHAR( clqc(jk:jk) ) - IACHAR( '0' )
-         END DO
-      END DO
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_qc_s, i_qc_var_id ),                         &
-         &         cl_name, __LINE__ )
-      DO ji = 1, iobs
-         istart2(2) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, clqc,                                   &
-            &                         start = istart2, count = icount2),                              &
-            &         cl_name, __LINE__ )
-         DO jk = 1, ilev
-            inpfile%ivlqc(jk,ji,2) = IACHAR( clqc(jk:jk) ) - IACHAR( '0' )
-         END DO
-      END DO
-      ! No depth QC in files
-      DO ji = 1, iobs
-         DO jk = 1, ilev
-            inpfile%idqc(jk,ji)  = 1
-            inpfile%idqcf(:,jk,ji) = 0
-         END DO
-      END DO
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_prof_qc_t, i_qc_var_id ),                    &
-         &         cl_name,  __LINE__ )
-      DO ji = 1,iobs
-         istart1(1) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                    &
-            &                         start = istart1, count = icount1),                              &
-            &         cl_name, __LINE__ )
-         inpfile%ivqc(ji,1) = IACHAR( cqc ) - IACHAR( '0' )
-      END DO
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_prof_qc_s, i_qc_var_id ),                    & 
-         &         cl_name, __LINE__ ) 
-      DO ji = 1,iobs
-         istart1(1) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                    &
-            &                         start = istart1, count = icount1),                              &
-            &         cl_name, __LINE__ )
-         inpfile%ivqc(ji,2) = IACHAR( cqc ) - IACHAR( '0' )
-      END DO
-!!      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_juld_qc, i_qc_var_id ),                       &
-!!         &         cl_name, __LINE__ ) 
-!!      !DO ji = 1,iobs
-!!         istart1(1) = ji
-!!         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                    &
-!!            &                         start = istart1, count = icount1),                              &
-!!            &         cl_name, __LINE__ )
-!!         inpfile%itqc(ji)    = IACHAR( cqc ) - IACHAR( '0' )
-!!         inpfile%itqcf(:,ji) = 0
-!!      END DO
-      ! Since the flags are not set in the ENACT files we reset them to 0
-      inpfile%itqc(:)    = 1      
-      inpfile%itqcf(:,:) = 0
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_pos_qc, i_qc_var_id ),                       &
-         &         cl_name, __LINE__ ) 
-      DO ji = 1,iobs
-         istart1(1) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                    &
-            &                         start = istart1, count = icount1),                              &
-            &         cl_name, __LINE__ )
-         inpfile%ipqc(ji)    = IACHAR( cqc ) - IACHAR( '0' )
-         inpfile%ipqcf(:,ji) = 0
-      END DO
-      DO ji = 1,iobs
-         inpfile%ioqc(ji) = MIN( inpfile%ivqc(ji,1), inpfile%ivqc(ji,2) )
-      END DO
-      IF ( nf90_inq_varid( i_file_id, cl_fld_qc_flags_profiles, i_qc_flag_id ) == nf90_noerr ) THEN
-         ALLOCATE( &
-            & iqc1(iobs) &
-            & )
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_flag_id, iqc1 ),                                &
-            &         cl_name, __LINE__ )
-         DO ji = 1,iobs
-            inpfile%ioqcf(1,ji)   = iqc1(ji)
-            inpfile%ivqcf(1,ji,:) = iqc1(ji)
-            inpfile%ioqcf(2,ji)   = 0
-            inpfile%ivqcf(2,ji,:) = 0
-         END DO
-         DEALLOCATE( &
-            & iqc1 &
-            & )
-      ELSE
-         IF(ldwp) WRITE(kunit,*)'No QC profile flags in file'
-         inpfile%ioqcf(:,:)   = 0
-         inpfile%ivqcf(:,:,:) = 0
-      ENDIF
-      IF ( nf90_inq_varid( i_file_id, cl_fld_qc_flags_levels, i_qc_flag_id ) == nf90_noerr ) THEN
-         ALLOCATE( &
-            & iqc2(ilev,iobs) &
-            & )
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_flag_id, iqc2 ),                                &
-            &         cl_name, __LINE__ )
-         DO ji = 1,iobs
-            DO jk = 1,ilev
-               inpfile%ivlqcf(1,jk,ji,:) = iqc2(jk,ji)
-               inpfile%ivlqcf(2,jk,ji,:) = 0
-            END DO
-         END DO
-         DEALLOCATE( &
-            & iqc2 &
-            & )
-      ELSE
-         IF(ldwp) WRITE(kunit,*)'No QC level flags in file'
-         inpfile%ivlqcf(:,:,:,:) = 0
-      ENDIF
-
-      !---------------------------------------------------------------------
-      ! Read the time/position variables 
-      !---------------------------------------------------------------------
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_juld, i_juld_id ),                               &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_juld_id, inpfile%ptim ),                              &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_depth, i_depth_id ),                             &
-            &         cl_name, __LINE__ )         
-      CALL chkerr( nf90_get_var  ( i_file_id, i_depth_id, inpfile%pdep ),                             &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_phi, i_phi_id ),                                 &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_phi_id, inpfile%pphi ),                               &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_lam, i_lam_id ),                                 &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_lam_id, inpfile%plam ),                               &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_reference_date_time, i_reference_date_time_id ), &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_reference_date_time_id, inpfile%cdjuldref ),          &
-         &         cl_name, __LINE__ )
-      
-      !---------------------------------------------------------------------
-      ! Read the platform information
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_wmo_inst_type, i_wmo_inst_type_id ),             &
-         &         cl_name, __LINE__ )          
-      CALL chkerr( nf90_get_var  ( i_file_id, i_wmo_inst_type_id, inpfile%cdtyp ),                    &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_pl_num, i_pl_num_id ),                           &
-         &         cl_name, __LINE__ )         
-      CALL chkerr( nf90_get_var  ( i_file_id, i_pl_num_id, inpfile%cdwmo ),                           &
-         &         cl_name, __LINE__ )         
-
-      !---------------------------------------------------------------------
-      ! Read the variables
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_tp, i_var_id ),                              &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, inpfile%pob(:,:,1) ),                         &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_s, i_var_id ),                               &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, inpfile%pob(:,:,2) ),                         &
-         &         cl_name, __LINE__ )
- 
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_ti, i_var_id ),                              &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, inpfile%pext(:,:,1) ),                        &
-         &         cl_name, __LINE__ )
-
-      !---------------------------------------------------------------------
-      ! Close file
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_close( i_file_id ),           cl_name, __LINE__ )
-
-      !---------------------------------------------------------------------
-      ! Set file indexes
-      !---------------------------------------------------------------------
-      DO ji = 1, inpfile%nobs
-         inpfile%kindex(ji) = ji
-      END DO
-
-   END SUBROUTINE read_enactfile
-
-   SUBROUTINE read_coriofile( cdfilename, inpfile, kunit, ldwp, ldgrid )
-      !!---------------------------------------------------------------------
-      !!
-      !!                     ** ROUTINE read_coriofile **
-      !!
-      !! ** Purpose : Read from file the profile CORIO observations.
-      !!
-      !! ** Method  : The data file is a NetCDF file. 
-      !!
-      !! ** Action  :
-      !!
-      !! History : 
-      !!          ! 09-01 (K. Mogensen) Original based on old versions
-      !!----------------------------------------------------------------------
-      !! * Arguments
-      CHARACTER(LEN=*) :: cdfilename ! Input filename
-      TYPE(obfbdata)   :: inpfile    ! Output enactfile structure
-      INTEGER          :: kunit      ! Unit for output
-      LOGICAL          :: ldwp       ! Print info
-      LOGICAL          :: ldgrid     ! Save grid info in data structure
-      INTEGER  :: &
-         & iobs, &
-         & ilev
-      !! * Local declarations
-      INTEGER :: &
-         & i_file_id,                &
-         & i_obs_id,                 &
-         & i_lev_id,                 &
-         & i_phi_id,                 & 
-         & i_lam_id,                 &
-         & i_depth_id,               &
-         & i_pres_id,                &
-         & i_var_id,                 &
-         & i_pl_num_id,              &
-         & i_format_version_id,      &
-         & i_juld_id,                &
-         & i_data_type_id,           &
-         & i_wmo_inst_type_id,       &
-         & i_qc_var_id,              &
-         & i_dc_ref_id
-      CHARACTER(LEN=40) :: & 
-         & cl_fld_lam,                 &
-         & cl_fld_phi,                 &
-         & cl_fld_depth,               & 
-         & cl_fld_depth_qc,            & 
-         & cl_fld_pres,                & 
-         & cl_fld_pres_qc,             & 
-         & cl_fld_var_t,               &
-         & cl_fld_var_s,               &
-         & cl_fld_var_ti,              &
-         & cl_fld_var_pos_qc,          &
-         & cl_fld_var_qc_t,            &
-         & cl_fld_var_qc_s,            &
-         & cl_fld_var_prof_qc_t,       &
-         & cl_fld_var_prof_qc_s,       &
-         & cl_fld_dc_ref,              &
-         & cl_fld_juld,                &
-         & cl_fld_pl_num,              &
-         & cl_fld_wmo_inst_type
-      CHARACTER(LEN=14), PARAMETER :: &
-         & cl_name = 'read_coriofile'
-      CHARACTER(LEN=4 )            :: &
-         & cl_format_version = ''
-      INTEGER, DIMENSION(1) :: &
-         & istart1, icount1
-      INTEGER, DIMENSION(2) :: &
-         & istart2, icount2
-      CHARACTER(len=imaxlev) :: &
-         & clqc
-      CHARACTER(len=1) :: &
-         & cqc
-      CHARACTER(len=256) :: &
-         & cdjulref
-      INTEGER :: &
-         & ji, jk
-      INTEGER :: &
-         & iformat
-      LOGICAL :: & 
-         & lsal
-      REAL(fbdp), DIMENSION(:,:), ALLOCATABLE :: &
-         & zpres
-      INTEGER, DIMENSION(:,:), ALLOCATABLE :: &
-         & ipresqc
-      CHARACTER(len=256) :: &
-         & cerr
-      !-----------------------------------------------------------------------
-      ! Initialization
-      !-----------------------------------------------------------------------
-
-      icount1(1) = 1 
-      lsal = .TRUE.
-
-      !-----------------------------------------------------------------------
-      ! Open file
-      !-----------------------------------------------------------------------
-
-      CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, &
-            &      i_file_id ),           cl_name, __LINE__ )
-
-      !-----------------------------------------------------------------------
-      ! Check format and set variables accordingly
-      !-----------------------------------------------------------------------
-
-      IF ( ( nf90_inq_dimid( i_file_id, 'N_PROF', i_obs_id ) == nf90_noerr ) .AND. &
-         & ( nf90_inq_dimid( i_file_id, 'N_LEVELS', i_lev_id ) == nf90_noerr ) ) THEN
-         iformat = 1
-      ELSEIF ( ( nf90_inq_dimid( i_file_id, 'mN_PROF', i_obs_id ) == nf90_noerr ) .AND. &
-         & ( nf90_inq_dimid( i_file_id, 'mN_ZLEV', i_lev_id ) == nf90_noerr ) ) THEN
-         iformat = 2
-      ELSE
-         WRITE(cerr,'(2A)')'Invalid data format in ',cl_name
-         CALL fatal_error( cerr, __LINE__ )
-      ENDIF
-      IF ( iformat == 1 ) THEN
-         cl_fld_lam                 = 'LONGITUDE'
-         cl_fld_phi                 = 'LATITUDE'  
-         cl_fld_depth               = 'DEPH'
-         cl_fld_depth_qc            = 'DEPH_QC'
-         cl_fld_pres                = 'PRES'
-         cl_fld_pres_qc             = 'PRES_QC'
-         cl_fld_juld                = 'JULD'
-         cl_fld_wmo_inst_type       = 'WMO_INST_TYPE'
-         cl_fld_dc_ref              = 'DC_REFERENCE'
-         cl_fld_pl_num              = 'PLATFORM_NUMBER'
-         cl_fld_var_qc_t            = 'TEMP_QC'
-         cl_fld_var_prof_qc_t       = 'PROFILE_TEMP_QC'
-         cl_fld_var_t               = 'TEMP'
-         cl_fld_var_qc_s            = 'PSAL_QC'
-         cl_fld_var_prof_qc_s       = 'PROFILE_PSAL_QC'
-         cl_fld_var_s               = 'PSAL'
-         cl_fld_var_pos_qc          = 'POSITION_QC'
-      ELSEIF ( iformat==2 ) THEN
-         cl_fld_lam                 = 'LONGITUDE'
-         cl_fld_phi                 = 'LATITUDE'  
-         cl_fld_depth               = 'DEPH'
-         cl_fld_depth_qc            = 'QC_DEPH'
-         cl_fld_pres                = 'PRES'
-         cl_fld_pres_qc             = 'QC_PRES'
-         cl_fld_juld                = 'JULD'
-         cl_fld_wmo_inst_type       = 'INST_TYPE'
-         cl_fld_dc_ref              = 'REFERENCE'
-         cl_fld_pl_num              = 'PLATFORM_NUMBER'
-         cl_fld_var_qc_t            = 'QC_TEMP'
-         cl_fld_var_prof_qc_t       = 'Q_PROFILE_TEMP'
-         cl_fld_var_t               = 'TEMP'
-         cl_fld_var_qc_s            = 'QC_PSAL'
-         cl_fld_var_prof_qc_s       = 'Q_PROFILE_PSAL'
-         cl_fld_var_s               = 'PSAL'
-         cl_fld_var_pos_qc          = 'Q_POSITION'
-      ENDIF
-
-      !-----------------------------------------------------------------------
-      ! Read the heading of the file
-      !-----------------------------------------------------------------------
-
-      IF(ldwp)WRITE(kunit,*)
-      IF(ldwp)WRITE(kunit,*) ' read_coriofile :' 
-      IF(ldwp)WRITE(kunit,*) ' ~~~~~~~~~~~~~~~~'
-      IF(ldwp)WRITE(kunit,*) '               Format version      = ', iformat
-
-      !---------------------------------------------------------------------
-      ! Read the number of observations and levels to allocate arrays
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_obs_id, len = iobs ), &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_lev_id, len = ilev ), &
-         &         cl_name, __LINE__ )
-      IF(ldwp)WRITE(kunit,*) '               No. of data records = ', iobs
-      IF(ldwp)WRITE(kunit,*) '               No. of levels       = ', ilev
-      IF(ldwp)WRITE(kunit,*) 
-      IF (ilev > imaxlev) THEN
-         CALL fatal_error( 'Increase imaxlev in obs_prof_io.F90', __LINE__ )
-      ENDIF
-
-      !---------------------------------------------------------------------
-      ! Allocate arrays
-      !---------------------------------------------------------------------
-
-      CALL init_obfbdata( inpfile )
-      CALL alloc_obfbdata( inpfile, 2, iobs, ilev, 0, 1, ldgrid )
-      inpfile%cname(1) = 'POTM'
-      inpfile%cname(2) = 'PSAL'
-      inpfile%coblong(1) = 'Potential temperature'
-      inpfile%coblong(2) = 'Practical salinity'
-      inpfile%cobunit(1) = 'Degrees Celsius'
-      inpfile%cobunit(2) = 'PSU'
-      inpfile%cextname(1) = 'TEMP'
-      inpfile%cextlong(1) = 'Insitu temperature'
-      inpfile%cextunit(1) = 'Degrees Celsius'
-      ALLOCATE( &
-         & zpres(ilev,iobs),  &
-         & ipresqc(ilev,iobs) &
-         & )
-      !---------------------------------------------------------------------
-      ! Get julian data reference (iformat==2)
-      !---------------------------------------------------------------------
-
-      IF (iformat==2) THEN
-         CALL chkerr ( nf90_get_att( i_file_id, nf90_global, &
-            &                        "Reference_date_time", cdjulref ), &
-            &         cl_name, __LINE__ )
-         inpfile%cdjuldref = cdjulref(7:10)//cdjulref(4:5)// &
-            & cdjulref(1:2)//cdjulref(12:13)//cdjulref(15:16)//cdjulref(18:19)
-      ENDIF
-
-      !---------------------------------------------------------------------
-      ! Read the QC attributes
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_qc_t, i_qc_var_id ),                                &
-         &         cl_name, __LINE__ )
-      istart2(1) = 1
-      icount2(2) = 1
-      icount2(1) = ilev
-      DO ji = 1, iobs 
-         istart2(2) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, clqc,                                   &
-            &                         start = istart2, count = icount2),                              &
-            &         cl_name, __LINE__ )
-         DO jk = 1, ilev
-            inpfile%ivlqc(jk,ji,1) = IACHAR( clqc(jk:jk) ) - IACHAR( '0' )
-         END DO
-      END DO
-      IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_s, i_qc_var_id ) == nf90_noerr ) THEN
-         DO ji = 1, iobs
-            istart2(2) = ji
-            CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, clqc,                                &
-               &                         start = istart2, count = icount2),                           &
-               &         cl_name, __LINE__ )
-            DO jk = 1, ilev
-               inpfile%ivlqc(jk,ji,2) = IACHAR( clqc(jk:jk) ) - IACHAR( '0' )
-            END DO
-         END DO
-      ELSE
-         inpfile%ivlqc(:,:,2) = 4
-         inpfile%pob(:,:,2) = fbrmdi
-         lsal = .FALSE.
-      ENDIF
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_prof_qc_t, i_qc_var_id ),                    &
-         &         cl_name,  __LINE__ )
-      DO ji = 1,iobs
-         istart1(1) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                    &
-            &                         start = istart1, count = icount1),                              &
-            &         cl_name, __LINE__ )
-         inpfile%ivqc(ji,1) = IACHAR( cqc ) - IACHAR( '0' )
-      END DO
-      IF (lsal) THEN
-         CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_prof_qc_s, i_qc_var_id ),                 & 
-            &         cl_name, __LINE__ ) 
-         DO ji = 1,iobs
-            istart1(1) = ji
-            CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                 &
-               &                         start = istart1, count = icount1),                           &
-               &         cl_name, __LINE__ )
-            inpfile%ivqc(ji,2) = IACHAR( cqc ) - IACHAR( '0' )
-         END DO
-      ELSE
-         inpfile%ivqc(:,2) = 4
-      ENDIF
-      DO ji = 1,iobs
-         inpfile%ioqc(ji) = MIN( inpfile%ivqc(ji,1), inpfile%ivqc(ji,2) )
-      END DO
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_pos_qc, i_qc_var_id ),                       &
-         &         cl_name, __LINE__ ) 
-      DO ji = 1, iobs
-         istart1(1) = ji
-         CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, cqc,                                    &
-            &                         start = istart1, count = icount1),                              &
-            &         cl_name, __LINE__ )
-         inpfile%ipqc(ji)  = IACHAR( cqc ) - IACHAR( '0' )
-      END DO
-      
-      !---------------------------------------------------------------------
-      ! Read the time/position variables 
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_juld, i_juld_id ),                               &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_juld_id, inpfile%ptim ),                              &
-         &         cl_name, __LINE__ )
-      IF (iformat==1) THEN
-         CALL chkerr ( nf90_get_att( i_file_id, i_juld_id, &
-            &                        "units", cdjulref ), &
-            &         cl_name, __LINE__ )
-         inpfile%cdjuldref = cdjulref(12:15)//cdjulref(17:18)// &
-            & cdjulref(20:21)//cdjulref(23:24)//cdjulref(26:27)//&
-            & cdjulref(29:30)
-      ENDIF
-      
-      IF ( nf90_inq_varid( i_file_id, cl_fld_depth, i_depth_id ) == nf90_noerr ) THEN
-         CALL chkerr( nf90_get_var  ( i_file_id, i_depth_id, inpfile%pdep ),                          &
-            &         cl_name, __LINE__ )
-         CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_depth_qc, i_qc_var_id ),                      & 
-            &         cl_name, __LINE__ ) 
-         DO ji = 1, iobs
-            istart2(2) = ji
-            CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, clqc,                                &
-               &                         start = istart2, count = icount2),                           &
-               &         cl_name, __LINE__ )
-            DO jk = 1, ilev
-               inpfile%idqc(jk,ji) = IACHAR( clqc(jk:jk) ) - IACHAR( '0' )
-            END DO
-         END DO
-      ELSE
-         inpfile%pdep(:,:) = fbrmdi
-         inpfile%idqc(:,:) = 4
-      ENDIF
-
-      IF ( nf90_inq_varid( i_file_id, cl_fld_pres, i_pres_id ) == nf90_noerr ) THEN
-         CALL chkerr( nf90_get_var  ( i_file_id, i_pres_id, zpres ),                                  &
-            &         cl_name, __LINE__ )
-         CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_pres_qc, i_qc_var_id ),                       & 
-            &         cl_name, __LINE__ ) 
-         DO ji = 1, iobs
-            istart2(2) = ji
-            CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, clqc,                                &
-               &                         start = istart2, count = icount2),                           &
-               &         cl_name, __LINE__ )
-            DO jk = 1, ilev
-               ipresqc(jk,ji) = IACHAR( clqc(jk:jk) ) - IACHAR( '0' )
-            END DO
-         END DO
-      ELSE
-         zpres(:,:) = fbrmdi
-         ipresqc(:,:) = 4
-      ENDIF
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_phi, i_phi_id ),                                 &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_phi_id, inpfile%pphi ),                               &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_lam, i_lam_id ),                                 &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_lam_id, inpfile%plam ),                               &
-         &         cl_name, __LINE__ )
-      
-      !---------------------------------------------------------------------
-      ! Read the platform information
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_wmo_inst_type, i_wmo_inst_type_id ),             &
-         &         cl_name, __LINE__ )          
-      CALL chkerr( nf90_get_var  ( i_file_id, i_wmo_inst_type_id, inpfile%cdtyp ),                    &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_pl_num, i_pl_num_id ),                           &
-         &         cl_name, __LINE__ )         
-      CALL chkerr( nf90_get_var  ( i_file_id, i_pl_num_id, inpfile%cdwmo ),                           &
-         &         cl_name, __LINE__ )         
-
-      
-      !---------------------------------------------------------------------
-      ! Read the variables
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_t, i_var_id ),                               &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, inpfile%pext(:,:,1) ),                        &
-         &         cl_name, __LINE__ )
-
-      IF (lsal) THEN      
-         CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_var_s, i_var_id ),                            &
-            &         cl_name, __LINE__ )
-         CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, inpfile%pob(:,:,2) ),                      &
-            &         cl_name, __LINE__ )
-      ENDIF
-
-      !---------------------------------------------------------------------
-      ! Close file
-      !---------------------------------------------------------------------
-         
-      CALL chkerr( nf90_close( i_file_id ),           cl_name, __LINE__ )
-
-      !---------------------------------------------------------------------
-      ! Set file indexes
-      !---------------------------------------------------------------------
-      DO ji = 1, inpfile%nobs
-         inpfile%kindex(ji) = ji
-      END DO
-      
-      !---------------------------------------------------------------------
-      !  Coriolis data conversion from insitu to potential temperature
-      !---------------------------------------------------------------------
-      !---------------------------------------------------------------------
-      !  Convert pressure to depth if depth not present
-      !---------------------------------------------------------------------
-      DO ji = 1, inpfile%nobs
-         IF ( inpfile%pphi(ji) < 9999.0 ) THEN
-            DO jk = 1, inpfile%nlev
-               IF ( inpfile%pdep(jk,ji) >= 9999.0 ) THEN
-                  IF ( zpres(jk,ji) < 9999.0 ) THEN
-                     inpfile%pdep(jk,ji) = &
-                        & p_to_dep( REAL(zpres(jk,ji),wp), REAL(inpfile%pphi(ji),wp) )
-                     inpfile%idqc(jk,ji) = ipresqc(jk,ji)
-                  ENDIF
-               ENDIF
-            END DO
-         ENDIF
-      END DO
-      
-      !---------------------------------------------------------------------
-      !  Convert depth to pressure if pressure not present
-      !---------------------------------------------------------------------
-      DO ji = 1, inpfile%nobs
-         IF ( inpfile%pphi(ji) < 9999.0 ) THEN
-            DO jk = 1, inpfile%nlev
-               IF ( zpres(jk,ji) >= 9999.0 ) THEN
-                  IF ( inpfile%pdep(jk,ji) < 9999.0 ) THEN
-                     zpres(jk,ji) = dep_to_p( REAL(inpfile%pdep(jk,ji),wp), &
-                        &                            REAL(inpfile%pphi(ji),wp) )
-                     ipresqc(jk,ji) = inpfile%idqc(jk,ji)
-                  ENDIF
-               ENDIF
-            END DO
-         ENDIF
-      END DO
-      
-      !---------------------------------------------------------------------
-      !  Convert insitu temperature to potential temperature if
-      !  salinity, insitu temperature and pressure are present
-      !---------------------------------------------------------------------
-      DO ji = 1, inpfile%nobs
-         DO jk = 1, inpfile%nlev
-            IF (( inpfile%pob(jk,ji,2) < 9999.0 ) .AND. &
-               &( inpfile%pext(jk,ji,1) < 9999.0 ) .AND. &
-               &( zpres(jk,ji) < 9999.0 ) ) THEN
-               inpfile%pob(jk,ji,1) = potemp( REAL(inpfile%pob(jk,ji,2), wp),  &
-                  &                           REAL(inpfile%pext(jk,ji,1), wp), &
-                  &                           REAL(zpres(jk,ji),wp),  &
-                  &                           0.0_wp )
-            ELSE
-               inpfile%pob(jk,ji,1) = fbrmdi
-            ENDIF
-         END DO
-      END DO
-
-      !---------------------------------------------------------------------
-      !  Initialize flags since they are not in the CORIOLIS input files
-      !---------------------------------------------------------------------
-
-      inpfile%ioqcf(:,:)      = 0
-      inpfile%ipqcf(:,:)      = 0
-      inpfile%itqcf(:,:)      = 0
-      inpfile%idqcf(:,:,:)    = 0
-      inpfile%ivqcf(:,:,:)    = 0
-      inpfile%ivlqcf(:,:,:,:) = 0
-
-   END SUBROUTINE read_coriofile
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsseaice_io.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsseaice_io.h90	(revision 10246)
+++ 	(revision )
@@ -1,270 +1,0 @@
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   SUBROUTINE read_seaice( cdfilename, inpfile, kunit, ldwp, ldgrid )
-      !!---------------------------------------------------------------------
-      !!
-      !!                     ** ROUTINE read_seaice **
-      !!
-      !! ** Purpose : Read from file the SEAICE observations.
-      !!
-      !! ** Method  : The data file is a NetCDF file. 
-      !!
-      !! ** Action  :
-      !!
-      !! References : 
-      !!
-      !! History : 
-      !!          ! 09-01 (K. Mogensen) Original based on old versions
-      !!----------------------------------------------------------------------
-      !! * Arguments
-      CHARACTER(LEN=*) :: cdfilename ! Input filename
-      TYPE(obfbdata)   :: inpfile    ! Output obfbdata structure
-      INTEGER          :: kunit      ! Unit for output
-      LOGICAL          :: ldwp       ! Print info
-      LOGICAL          :: ldgrid     ! Save grid info in data structure
-      !! * Local declarations
-      CHARACTER(LEN=12),PARAMETER :: cpname = 'read_seaice'
-      INTEGER :: i_file_id    ! netcdf IDS
-      INTEGER :: i_time_id
-      INTEGER :: i_ni_id
-      INTEGER :: i_data_id
-      INTEGER :: i_var_id
-      INTEGER :: i_data       ! Number of data per parameter in current file
-      INTEGER :: i_time       ! Number of reference times in file
-      INTEGER, DIMENSION(:), POINTER :: &
-         & i_reftime        ! Reference time in file in seconds since 1/1/1981.
-      INTEGER, DIMENSION(:,:), POINTER :: &
-         & i_dtime, &       ! Offset in seconds since reference time
-         & i_qc,    &       ! Quality control flag.
-         & i_type           ! Type of seaice measurement.            
-      REAL(wp), DIMENSION(:), POINTER :: &
-         & z_phi,   &       ! Latitudes
-         & z_lam            ! Longitudes
-      REAL(wp), DIMENSION(:,:), POINTER :: &
-         & z_seaice         ! Seaice data     
-      INTEGER, PARAMETER :: imaxdim = 2    ! Assumed maximum for no. dims. in file
-      INTEGER, DIMENSION(2) :: idims       ! Dimensions in file
-      INTEGER :: iilen          ! Length of netCDF attributes
-      INTEGER :: itype          ! Typeof netCDF attributes
-      REAL(KIND=wp) :: zsca      ! Scale factor
-      REAL(KIND=wp) :: zoff      ! Offset for data in netcdf file
-      REAL(KIND=wp) :: z_offset  ! Offset for time conversion
-      REAL(KIND=wp) :: zfill     ! Fill value in netcdf file
-      CHARACTER (len=33) ::creftime     ! Reference time of file
-      INTEGER :: i_refyear       ! Integer version of reference time
-      INTEGER :: i_refmonth
-      INTEGER :: i_refday
-      INTEGER :: i_refhour
-      INTEGER :: i_refmin
-      INTEGER :: i_refsec
-      INTEGER :: ichunk
-      INTEGER :: jtim
-      INTEGER :: jobs
-      INTEGER :: iobs
-
-      CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, &
-         &                i_file_id, chunksize=ichunk), cpname, __LINE__ )
-      
-      ! Get the netCDF dimensions
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'time', i_time_id ),  &
-         &       cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_time_id, &
-         &                              len = i_time ),  &
-         &      cpname, __LINE__ )
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'ni', i_ni_id ),  &
-         &       cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_ni_id, &
-         &                              len = i_data ),  &
-         &      cpname, __LINE__ )
-      
-      
-      ! Allocate NetCDF variables
-      
-      ALLOCATE( &
-         & i_reftime    ( i_time                 ), &
-         & i_dtime      ( i_data,i_time  ), &      
-         & i_qc         ( i_data,i_time  ), & 
-         & i_type       ( i_data,i_time  ), &     
-         & z_phi        ( i_data                 ), &   
-         & z_lam        ( i_data                 ), &  
-         & z_seaice        ( i_data,i_time  )  &
-         & )
-      
-      ! Get reference time of file which is in seconds since 1981/1/1 00:00. 
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'time', i_var_id ), & 
-         &       cpname, __LINE__ )
-      idims(1) = i_time
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_reftime),&
-         &       cpname, __LINE__ )
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "units") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "units",creftime), cpname,  __LINE__ )
-      ELSE
-         creftime = "seconds since 1981-01-01 00:00:00"
-      ENDIF
-      READ(creftime(15:18),*)i_refyear
-      READ(creftime(20:21),*)i_refmonth
-      READ(creftime(23:24),*)i_refday
-      READ(creftime(26:27),*)i_refhour
-      READ(creftime(29:30),*)i_refmin
-      READ(creftime(32:33),*)i_refsec
-      !Work out offset in days between reference time and 1/1/1950.
-      CALL greg2jul( i_refsec, i_refmin, i_refhour, i_refday, &
-         &           i_refmonth, i_refyear, z_offset)
-      
-      ! Get list of times for each ob in seconds relative to reference time
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'SeaIce_dtime', i_var_id ), & 
-         &       cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_dtime),&
-         &       cpname, __LINE__ )
-      zsca = 1.0      
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "scale_factor") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "scale_factor",zsca), cpname,  __LINE__ )
-      ENDIF
-      zoff = 0.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "add_offset") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "add_offset",zoff), cpname,  __LINE__ )
-      ENDIF
-      i_dtime(:,:) = NINT((zsca * FLOAT(i_dtime(:,:))) &
-         &                 + zoff)
-      
-      ! Get longitudes
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'lon', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, z_lam),   &
-         &         cpname, __LINE__ )
-      
-      ! Get latitudes
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'lat', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, z_phi),   &
-         &         cpname, __LINE__ )
-      
-      ! Get seaice data
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'sea_ice_concentration', &
-         &                         i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, z_seaice), &
-         &       cpname, __LINE__ )
-      zoff = 0.
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "scale_factor") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "scale_factor",zsca), cpname, __LINE__ )
-      ENDIF
-      zsca = 1.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "scale_factor") &
-         &                       == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                       "scale_factor",zsca), cpname, __LINE__ )
-      ENDIF
-      zfill = 0.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "_FillValue") &
-         &                       == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                       "_FillValue",zfill), cpname, __LINE__ )
-      ENDIF
-      WHERE(z_seaice(:,:) /=  zfill)
-         z_seaice(:,:) = (zsca * z_seaice(:,:)) + zoff
-      ELSEWHERE
-         z_seaice(:,:) = fbrmdi
-      END WHERE
-      
-      ! Get QC flag
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'confidence_flag', i_var_id ), & 
-         &       cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_qc),   &
-            &       cpname, __LINE__ )
-      
-      ! Get seaice obs type
-      
-      i_type(:,:)=1
-      
-      ! Close the file
-      
-      CALL chkerr( nf90_close( i_file_id ), cpname, __LINE__ )
-
-      ! Fill the obfbdata structure
-
-      ! Allocate obfbdata
-      
-      iobs = i_data * i_time
-      CALL init_obfbdata( inpfile )
-      CALL alloc_obfbdata( inpfile, 1, iobs, 1, 0, 0, ldgrid )
-      inpfile%cname(1) = 'SEAICE'
-
-      ! Fill the obfbdata structure from input data
-
-      inpfile%cdjuldref = "19500101000000"
-      iobs = 0
-      DO jtim = 1, i_time
-         DO jobs = 1, i_data
-            iobs = iobs + 1
-            ! Characters
-            WRITE(inpfile%cdwmo(iobs),'(A6,A2)') 'seaice','  '
-            WRITE(inpfile%cdtyp(iobs),'(I4)') i_type(jobs,jtim)
-            ! Real values
-            inpfile%plam(iobs)         = z_lam(jobs)
-            inpfile%pphi(iobs)         = z_phi(jobs)
-            inpfile%pob(1,iobs,1)      = z_seaice(jobs,jtim)
-            inpfile%ptim(iobs)         = &
-               & REAL(i_reftime(jtim))/(60.*60.*24.) + &
-               & z_offset + REAL(i_dtime(jobs,jtim))/(60.*60.*24.)
-            inpfile%pdep(1,iobs)       = 0.0
-            ! Integers
-            inpfile%kindex(iobs)       = iobs
-            IF ( z_seaice(jobs,jtim) == fbrmdi ) THEN
-               inpfile%ioqc(iobs)      = 4
-               inpfile%ivqc(iobs,1)    = 4 
-               inpfile%ivlqc(1,iobs,1) = 4
-            ELSE 
-               inpfile%ioqc(iobs)      = i_qc(jobs,jtim)
-               inpfile%ivqc(iobs,1)    = i_qc(jobs,jtim)
-               inpfile%ivlqc(1,iobs,1) = 1
-            ENDIF
-            inpfile%ipqc(iobs)         = 0 
-            inpfile%ipqcf(:,iobs)      = 0
-            inpfile%itqc(iobs)         = 0
-            inpfile%itqcf(:,iobs)      = 0
-            inpfile%ivqcf(:,iobs,1)    = 0
-            inpfile%ioqcf(:,iobs)      = 0
-            inpfile%idqc(1,iobs)       = 0
-            inpfile%idqcf(1,1,iobs)    = 0
-            inpfile%ivlqcf(:,1,iobs,1) = 0
-         END DO
-      END DO
-
-   END SUBROUTINE read_seaice
-
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obssla_io.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obssla_io.h90	(revision 10246)
+++ 	(revision )
@@ -1,378 +1,0 @@
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   SUBROUTINE read_avisofile( cdfilename, inpfile, kunit, ldwp, ldgrid )
-      !!---------------------------------------------------------------------
-      !!
-      !!                     ** ROUTINE read_avisofile **
-      !!
-      !! ** Purpose : Read from file the AVISO SLA observations.
-      !!
-      !! ** Method  : The data file is a NetCDF file. 
-      !!
-      !! ** Action  :
-      !!
-      !! References : http://www.aviso.oceanobs.com
-      !!
-      !! History : 
-      !!          ! 09-01 (K. Mogensen) Original based on old versions
-      !!----------------------------------------------------------------------
-      !! * Arguments
-      CHARACTER(LEN=*) :: cdfilename ! Input filename
-      TYPE(obfbdata)   :: inpfile    ! Output obfbdata structure
-      INTEGER          :: kunit      ! Unit for output
-      LOGICAL          :: ldwp       ! Print info
-      LOGICAL          :: ldgrid     ! Save grid info in data structure
-      !! * Local declarations
-      CHARACTER(LEN=14),PARAMETER :: cpname = 'read_avisofile'
-      INTEGER :: i_file_id     ! netcdf IDS
-      INTEGER :: i_tracks_id
-      INTEGER :: i_cycles_id
-      INTEGER :: i_data_id
-      INTEGER :: i_var_id
-      INTEGER, PARAMETER :: imaxdim = 2    ! Assumed maximum for no. dims. in file
-      INTEGER, DIMENSION(2) :: idims       ! Dimensions in file
-      INTEGER :: iilen         ! Length of netCDF attributes
-      INTEGER :: itype         ! Typeof netCDF attributes
-      REAL(fbdp) :: zsca       ! Scale factor
-      REAL(fbdp) :: zfill      ! Fill value
-      CHARACTER(len=3) ::  cmission      ! Mission global attribute
-      INTEGER :: itracks       ! Maximum number of passes in file
-      INTEGER :: icycles       ! Maximum number of cycles for each pass
-      INTEGER :: idata         ! Number of data per parameter in current file
-      REAL(fbdp) :: zdeltat    ! Time gap getween two measurements in seconds
-      INTEGER, DIMENSION(:), POINTER :: & 
-         & iptracks,     &  ! List of passes contained in current file
-         & ipnbpoints,   &  ! Number of points per pass
-         & ipdataindexes    ! Index of data in theoretical profile
-      INTEGER, DIMENSION(:,:), POINTER :: & 
-         & ipcycles         ! List of cycles per pass
-      REAL(fbdp), DIMENSION(:), POINTER :: &
-         & zphi,   &        ! Latitudes
-         & zlam             ! Longitudes
-      REAL(fbdp), DIMENSION(:,:), POINTER :: &
-         & zbegindates      ! Date of point with index 0
-      REAL(fbdp) :: zbeginmiss    ! Missing data for dates
-      REAL(fbsp), DIMENSION(:,:), POINTER :: &
-         & zsla             ! SLA data
-      REAL(fbdp), DIMENSION(:), POINTER :: &
-         & zjuld            ! Julian date
-      LOGICAL, DIMENSION(:), POINTER :: &
-         & llskip           ! Skip observation
-      CHARACTER(len=14) :: cdjuldref    ! Julian data reference
-      INTEGER :: imission   ! Mission number converted from Mission global 
-                            ! netCDF atttribute.
-      CHARACTER(len=255) :: ctmp
-      INTEGER :: iobs
-      INTEGER :: jl
-      INTEGER :: jm
-      INTEGER :: jj
-      INTEGER :: ji
-      INTEGER :: jk
-      INTEGER :: jobs
-      INTEGER :: jcycle
-
-      ! Open the file
-
-      CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, i_file_id ), &
-         &         cpname, __LINE__ )
-
-      ! Get the netCDF dimensions
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'Tracks', i_tracks_id ),  &
-         &         cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_tracks_id, &
-         &                                 len = itracks ),  &
-         &         cpname, __LINE__ )
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'Cycles', i_cycles_id ),  &
-         &         cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_cycles_id, &
-         &                                 len = icycles ),  &
-         &      cpname, __LINE__ )
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'Data', i_data_id ),  &
-         &         cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_data_id, &
-         &                                 len = idata ),  &
-         &         cpname, __LINE__ )
-
-      ! Allocate memory for input data
-
-      ALLOCATE( &
-         & iptracks     ( itracks          ), &  
-         & ipnbpoints   ( itracks          ), &  
-         & ipcycles     ( icycles, itracks ), &
-         & zphi         ( idata            ), &   
-         & zlam         ( idata            ), &  
-         & zbegindates  ( icycles, itracks ), &
-         & ipdataindexes( idata            ), & 
-         & zsla         ( icycles, idata   ), &
-         & zjuld        ( idata*icycles    ), &
-         & llskip       ( idata*icycles    )  &
-         & )
-
-      ! Get time gap getween two measurements in seconds
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'DeltaT', i_var_id ), & 
-         &         cpname, __LINE__ )
-      CALL chkdim( i_file_id, i_var_id, 0, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zdeltat), &
-         &         cpname, __LINE__ )
-      zsca = 1.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, 'scale_factor') &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     'scale_factor',zsca), cpname,  __LINE__)
-      ENDIF
-      zdeltat = zsca * zdeltat
-         
-      ! Get List of passes contained in current file      
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'Tracks', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = itracks
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, iptracks), &
-         &         cpname, __LINE__ )
-      
-      ! Get Number of points per pass
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'NbPoints', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = itracks
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, ipnbpoints),&
-         &         cpname, __LINE__ )
-      
-      ! Get list of cycles per pass
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'Cycles', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = icycles
-      idims(2) = itracks
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, ipcycles),   &
-         &         cpname, __LINE__ )
-
-      ! Get longitudes
-
-      CALL chkerr( nf90_inq_varid( i_file_id, 'Longitudes', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = idata
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zlam),   &
-         &         cpname, __LINE__ )
-      zsca = 1.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, 'scale_factor') &
-         &                         == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     'scale_factor',zsca), cpname,  __LINE__)
-      ENDIF
-      zlam(:) = zsca * zlam(:)
-      
-      ! Get latitudes
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'Latitudes', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = idata
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zphi),   &
-         &         cpname, __LINE__ )
-      zsca = 1.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, 'scale_factor') &
-         &                       == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     'scale_factor',zsca), cpname,  __LINE__)
-      ENDIF
-      zphi(:) = zsca * zphi(:)
-      
-      ! Get date of point with index 0
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'BeginDates', i_var_id ), & 
-         &        cpname, __LINE__ )
-      idims(1) = icycles
-      idims(2) = itracks
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zbegindates), &
-         &         cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_attribute( i_file_id, i_var_id, &
-         &                                 'units', len = iilen,  &
-         &                                  xtype = itype), cpname, __LINE__ )
-      IF (( itype /= NF90_CHAR ) .OR. ( iilen > 255 )) THEN
-         CALL fatal_error('Error decoding BeginDates unit', __LINE__ )
-      ENDIF
-      CALL chkerr( nf90_get_att( i_file_id, i_var_id, 'units', &
-         &                       ctmp ), cpname, __LINE__ )
-      jl=1
-      DO jm = 1, LEN(TRIM(ctmp))
-         IF ((ctmp(jm:jm)>='0').AND.(ctmp(jm:jm)<='9')) THEN
-            cdjuldref(jl:jl) = ctmp(jm:jm)
-            jl=jl+1
-         ENDIF
-         IF (jl>14) EXIT
-      END DO
-      CALL chkerr( nf90_inquire_attribute( i_file_id, i_var_id, '_FillValue', &
-         &                                  xtype = itype), cpname, __LINE__ )
-      IF ( itype /= NF90_DOUBLE ) THEN
-         CALL fatal_error('Error decoding BeginDates missing data', __LINE__ )
-      ENDIF
-      CALL chkerr( nf90_get_att( i_file_id, i_var_id, '_FillValue', &
-         &                       zbeginmiss ), cpname, __LINE__ )
-
-      ! Get indices of data in theoretical profile
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'DataIndexes', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = idata
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, ipdataindexes),   &
-         &       cpname, __LINE__ )
-      
-      ! Get SLA data
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'SLA', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = icycles
-      idims(2) = idata
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zsla),   &
-         &         cpname, __LINE__ )
-      zsca = 1.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, 'scale_factor') &
-         &                        == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                       'scale_factor',zsca), cpname, __LINE__ )
-      ENDIF
-      zfill = 0.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, '_FillValue') &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     '_FillValue',zfill), cpname,  __LINE__ )
-      ENDIF
-      WHERE(zsla(:,:) /=  zfill)
-         zsla(:,:) = zsca * zsla(:,:)
-      ELSEWHERE
-         zsla(:,:) = fbrmdi
-      END WHERE
-      
-      ! Get the global Mission netCDF attribute
-      
-      cmission='   '
-      CALL chkerr( nf90_inquire_attribute( i_file_id, nf90_global, &
-         &                                 'Mission', len = iilen,  &
-         &                                 xtype = itype), cpname, __LINE__ )
-      IF (( itype /= NF90_CHAR ) .OR. ( iilen > 3 )) THEN
-         CALL fatal_error('Error decoding Mission global attribute', __LINE__ )
-      ENDIF
-      CALL chkerr( nf90_get_att( i_file_id, nf90_global, 'Mission', &
-         &                       cmission ), cpname, __LINE__ )
-      
-      ! Convert it to an integer
-      imission = 0
-      DO jm = 1, imaxmissions
-         IF (cmission==cmissions(jm)) THEN
-            imission = jm
-            EXIT
-         ENDIF
-      END DO
-      
-      ! Close the file
-      
-      CALL chkerr( nf90_close( i_file_id ), cpname, __LINE__ )
-
-      ! Compute Julian dates for all observations
-      
-      jm = 0
-      jl = 0
-      DO jj = 1, itracks
-         DO ji = 1, ipnbpoints(jj)
-            jl = jl + 1
-            DO jk = 1, icycles
-               jm = jm + 1
-               IF (zbegindates(jk,jj)==zbeginmiss) THEN
-                  llskip(jm) = .TRUE.
-                  zjuld(jm)  = fbrmdi
-               ELSE
-                  llskip(jm) = .FALSE.
-                  zjuld(jm)  = zbegindates(jk,jj) + &
-                     &         (ipdataindexes(jl) * zdeltat / 86400._wp )
-               ENDIF
-            END DO
-         END DO
-      END DO
-
-      ! Get rid of missing data
-
-      jm = 0
-      DO jobs = 1, idata
-         DO jcycle = 1, icycles
-            jm = jm + 1
-            IF (zsla(jcycle,jobs) == fbrmdi) llskip(jm) = .TRUE.
-         END DO
-      END DO
-      
-      ! Allocate obfbdata
-
-      iobs = COUNT( .NOT.llskip(:) )
-      CALL init_obfbdata( inpfile )
-      CALL alloc_obfbdata( inpfile, 1, iobs, 1, 0, 0, ldgrid )
-      inpfile%cname(1) = 'SLA'
-
-      ! Fill the obfbdata structure from input data
-
-      inpfile%cdjuldref = cdjuldref
-      iobs = 0
-      jm = 0
-      DO jobs = 1, idata
-         DO jcycle = 1, icycles
-            jm = jm + 1
-            IF (llskip(jm)) CYCLE
-            iobs = iobs + 1
-            ! Characters
-            WRITE(inpfile%cdwmo(iobs),'(A3,A5)') cmissions(imission), '     '
-            WRITE(inpfile%cdtyp(iobs),'(I4)') imission
-            ! Real values
-            inpfile%plam(iobs)         = zlam(jobs)
-            inpfile%pphi(iobs)         = zphi(jobs)
-            inpfile%pob(1,iobs,1)      = zsla(jcycle,jobs)
-            inpfile%ptim(iobs)         = zjuld(jm)
-            inpfile%pdep(1,iobs)       = 0.0
-            ! Integers
-            inpfile%kindex(iobs)       = iobs
-            inpfile%ioqc(iobs)      = 1
-            inpfile%ivqc(iobs,1)    = 1
-            inpfile%ivlqc(1,iobs,1) = 1
-            inpfile%ipqc(iobs)         = 0 
-            inpfile%ipqcf(:,iobs)      = 0
-            inpfile%itqc(iobs)         = 0
-            inpfile%itqcf(:,iobs)      = 0
-            inpfile%ivqcf(:,iobs,1)    = 0
-            inpfile%ioqcf(:,iobs)      = 0
-            inpfile%idqc(1,iobs)       = 0
-            inpfile%idqcf(1,1,iobs)    = 0
-            inpfile%ivlqcf(:,1,iobs,1) = 0
-         END DO
-      END DO
-
-
-      ! Deallocate memory for input data
-
-      DEALLOCATE( &
-         & iptracks,      &
-         & ipnbpoints,    &
-         & ipcycles,      &
-         & zphi,          &
-         & zlam,          &  
-         & zbegindates,   &
-         & ipdataindexes, &
-         & zsla,          &
-         & zjuld,         &
-         & llskip         &
-         & )
-
-   END SUBROUTINE read_avisofile
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obssla_types.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obssla_types.h90	(revision 10246)
+++ 	(revision )
@@ -1,9 +1,0 @@
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   INTEGER, PARAMETER :: imaxmissions=8
-   CHARACTER(len=3) :: cmissions(0:imaxmissions) = &
-      & (/ 'XXX', 'E1 ', 'E2 ', 'TP ', 'TPM', 'G2 ', 'J1 ', 'EN ', 'J2 ' /)
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obssst_io.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obssst_io.h90	(revision 10246)
+++ 	(revision )
@@ -1,286 +1,0 @@
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   SUBROUTINE read_ghrsst( cdfilename, inpfile, kunit, ldwp, ldgrid )
-      !!---------------------------------------------------------------------
-      !!
-      !!                     ** ROUTINE read_ghrsst **
-      !!
-      !! ** Purpose : Read from file the GHRSST observations.
-      !!
-      !! ** Method  : The data file is a NetCDF file. 
-      !!
-      !! ** Action  :
-      !!
-      !! References : 
-      !!
-      !! History : 
-      !!          ! 09-01 (K. Mogensen) Original based on old versions
-      !!----------------------------------------------------------------------
-      !! * Arguments
-      CHARACTER(LEN=*) :: cdfilename ! Input filename
-      TYPE(obfbdata)   :: inpfile    ! Output obfbdata structure
-      INTEGER          :: kunit      ! Unit for output
-      LOGICAL          :: ldwp       ! Print info
-      LOGICAL          :: ldgrid     ! Save grid info in data structure
-      !! * Local declarations
-      CHARACTER(LEN=12),PARAMETER :: cpname = 'read_ghrsst'
-      INTEGER :: i_file_id        ! netcdf IDS
-      INTEGER :: i_time_id
-      INTEGER :: i_ni_id
-      INTEGER :: i_data_id
-      INTEGER :: i_var_id
-      INTEGER :: i_data           ! Number of data per parameter in current file
-      INTEGER :: i_time           ! Number of reference times in file
-      INTEGER, DIMENSION(:), POINTER :: &
-         & i_reftime        ! Reference time in file in seconds since 1/1/1981.
-      INTEGER, DIMENSION(:,:), POINTER :: &
-         & i_dtime, &       ! Offset in seconds since reference time
-         & i_qc,    &       ! Quality control flag.
-         & i_type           ! Type of SST measurement.            
-      REAL(wp), DIMENSION(:), POINTER :: &
-         & z_phi,   &       ! Latitudes
-         & z_lam            ! Longitudes
-      REAL(wp), DIMENSION(:,:), POINTER :: &
-         & z_sst            ! SST data     
-      INTEGER, PARAMETER :: imaxdim = 2      ! Assumed maximum for no. dims. in file
-      INTEGER, DIMENSION(2) :: idims         ! Dimensions in file
-      INTEGER :: iilen            ! Length of netCDF attributes
-      INTEGER :: itype            ! Typeof netCDF attributes
-      REAL(KIND=wp) :: zsca           ! Scale factor
-      REAL(KIND=wp) :: zoff           ! Offset for data in netcdf file
-      REAL(KIND=wp) :: z_offset       ! Offset for time conversion
-      REAL(KIND=wp) :: zfill          ! Fill value in netcdf file
-      CHARACTER (len=33) :: creftime  ! Reference time of file
-      INTEGER :: i_refyear            ! Integer version of reference time
-      INTEGER :: i_refmonth
-      INTEGER :: i_refday
-      INTEGER :: i_refhour
-      INTEGER :: i_refmin
-      INTEGER :: i_refsec
-      INTEGER :: ichunk
-      INTEGER :: jtim
-      INTEGER :: jobs
-      INTEGER :: iobs
-
-      CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, &
-         &                i_file_id, chunksize=ichunk), cpname, __LINE__ )
-      
-      ! Get the netCDF dimensions
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'time', i_time_id ),  &
-         &       cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_time_id, &
-         &                              len = i_time ),  &
-         &      cpname, __LINE__ )
-      
-      CALL chkerr( nf90_inq_dimid( i_file_id, 'ni', i_ni_id ),  &
-         &       cpname, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_ni_id, &
-         &                              len = i_data ),  &
-         &      cpname, __LINE__ )
-      
-      
-      ! Allocate NetCDF variables
-      
-      ALLOCATE( &
-         & i_reftime    ( i_time                 ), &
-         & i_dtime      ( i_data,i_time  ), &      
-         & i_qc         ( i_data,i_time  ), & 
-         & i_type       ( i_data,i_time  ), &     
-         & z_phi        ( i_data                 ), &   
-         & z_lam        ( i_data                 ), &  
-         & z_sst        ( i_data,i_time  )  &
-         & )
-      
-      ! Get reference time of file which is in seconds since 1981/1/1 00:00. 
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'time', i_var_id ), & 
-         &       cpname, __LINE__ )
-      idims(1) = i_time
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_reftime),&
-         &       cpname, __LINE__ )
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "units") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "units",creftime), cpname,  __LINE__ )
-      ELSE
-         creftime = "seconds since 1981-01-01 00:00:00"
-      ENDIF
-      READ(creftime(15:18),*)i_refyear
-      READ(creftime(20:21),*)i_refmonth
-      READ(creftime(23:24),*)i_refday
-      READ(creftime(26:27),*)i_refhour
-      READ(creftime(29:30),*)i_refmin
-      READ(creftime(32:33),*)i_refsec
-      !Work out offset in days between reference time and 1/1/1950.
-      CALL greg2jul( i_refsec, i_refmin, i_refhour, i_refday, &
-         &           i_refmonth, i_refyear, z_offset)
-      
-      ! Get list of times for each ob in seconds relative to reference time
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'sst_dtime', i_var_id ), & 
-         &       cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_dtime),&
-         &       cpname, __LINE__ )
-      zsca = 1.0      
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "scale_factor") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "scale_factor",zsca), cpname,  __LINE__ )
-      ENDIF
-      zoff = 0.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "add_offset") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "add_offset",zoff), cpname,  __LINE__ )
-      ENDIF
-      i_dtime(:,:) = NINT((zsca * FLOAT(i_dtime(:,:))) &
-         &                 + zoff)
-      
-      ! Get longitudes
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'lon', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, z_lam),   &
-         &         cpname, __LINE__ )
-      
-      ! Get latitudes
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'lat', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      CALL chkdim( i_file_id, i_var_id, 1, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, z_phi),   &
-         &         cpname, __LINE__ )
-      
-      ! Get SST data
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'sea_surface_temperature', &
-         &                         i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, z_sst), &
-         &       cpname, __LINE__ )
-      zoff = 0.
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "scale_factor") &
-         &                      == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                     "scale_factor",zsca), cpname, __LINE__ )
-      ENDIF
-      zsca = 1.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "scale_factor") &
-         &                       == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                       "scale_factor",zsca), cpname, __LINE__ )
-      ENDIF
-      zfill = 0.0
-      IF (nf90_inquire_attribute( i_file_id, i_var_id, "_FillValue") &
-         &                       == nf90_noerr) THEN
-         CALL chkerr( nf90_get_att( i_file_id, i_var_id, &
-            &                       "_FillValue",zfill), cpname, __LINE__ )
-      ENDIF
-      WHERE(z_sst(:,:) /=  zfill)
-         z_sst(:,:) = (zsca * z_sst(:,:)) + zoff
-      ELSEWHERE
-         z_sst(:,:) = fbrmdi
-      END WHERE
-      
-      ! Get QC flag
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'confidence_flag', i_var_id ), & 
-         &       cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_qc),   &
-            &       cpname, __LINE__ )
-      
-      ! Get SST obs type
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, 'data_source', i_var_id ), & 
-         &         cpname, __LINE__ )
-      idims(1) = i_data
-      idims(2) = i_time
-      CALL chkdim( i_file_id, i_var_id, 2, idims, cpname, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, i_type),   &
-         &       cpname, __LINE__ )
-      
-      ! Close the file
-      
-      CALL chkerr( nf90_close( i_file_id ), cpname, __LINE__ )
-
-      ! Fill the obfbdata structure
-
-      ! Allocate obfbdata
-      
-      iobs = i_data * i_time
-      CALL init_obfbdata( inpfile )
-      CALL alloc_obfbdata( inpfile, 1, iobs, 1, 0, 0, ldgrid )
-      inpfile%cname(1) = 'SST'
-
-      ! Fill the obfbdata structure from input data
-
-      inpfile%cdjuldref = "19500101000000"
-      iobs = 0
-      DO jtim = 1, i_time
-         DO jobs = 1, i_data
-            iobs = iobs + 1
-            ! Characters
-            WRITE(inpfile%cdwmo(iobs),'(A6,A2)') 'ghrsst','  '
-            WRITE(inpfile%cdtyp(iobs),'(I4)') i_type(jobs,jtim)
-            ! Real values
-            inpfile%plam(iobs)         = z_lam(jobs)
-            inpfile%pphi(iobs)         = z_phi(jobs)
-            inpfile%pob(1,iobs,1)      = z_sst(jobs,jtim)
-            inpfile%ptim(iobs)         = &
-               & REAL(i_reftime(jtim))/(60.*60.*24.) + &
-               & z_offset + REAL(i_dtime(jobs,jtim))/(60.*60.*24.)
-            inpfile%pdep(1,iobs)       = 0.0
-            ! Integers
-            inpfile%kindex(iobs)       = iobs
-            IF ( z_sst(jobs,jtim) == fbrmdi ) THEN
-               inpfile%ioqc(iobs)      = 4
-               inpfile%ivqc(iobs,1)    = 4 
-               inpfile%ivlqc(1,iobs,1) = 4
-            ELSE 
-               inpfile%ioqc(iobs)      = i_qc(jobs,jtim)
-               inpfile%ivqc(iobs,1)    = i_qc(jobs,jtim)
-               inpfile%ivlqc(1,iobs,1) = 1
-            ENDIF
-            inpfile%ipqc(iobs)         = 0 
-            inpfile%ipqcf(:,iobs)      = 0
-            inpfile%itqc(iobs)         = 0
-            inpfile%itqcf(:,iobs)      = 0
-            inpfile%ivqcf(:,iobs,1)    = 0
-            inpfile%ioqcf(:,iobs)      = 0
-            inpfile%idqc(1,iobs)       = 0
-            inpfile%idqcf(1,1,iobs)    = 0
-            inpfile%ivlqcf(:,1,iobs,1) = 0
-         END DO
-      END DO
-
-      DEALLOCATE( &
-         & i_reftime, &
-         & i_dtime,   &
-         & i_qc,      &
-         & i_type,    &
-         & z_phi,     &
-         & z_lam,     &
-         & z_sst      &
-         & )
-
-   END SUBROUTINE read_ghrsst
-
-
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsvel_io.h90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/OBS/obsvel_io.h90	(revision 10246)
+++ 	(revision )
@@ -1,360 +1,0 @@
-   !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
-   !! $Id$
-   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
-   !!----------------------------------------------------------------------
-
-   SUBROUTINE read_taondbc( cdfilename, inpfile, kunit, ldwp, ldgrid )
-      !!---------------------------------------------------------------------
-      !!
-      !!                     ** ROUTINE read_enactfile **
-      !!
-      !! ** Purpose : Read from file the TAO data fro NDBC.
-      !!
-      !! ** Method  : The data file is a NetCDF file. 
-      !!
-      !! ** Action  :
-      !!
-      !! ** Reference : http://tao.noaa.gov/tao/data_deliv/deliv_ndbc.shtml
-      !! History : 
-      !!          ! 09-01 (K. Mogensen) Original version.
-      !!----------------------------------------------------------------------
-      !! * Arguments
-      CHARACTER(LEN=*) :: cdfilename ! Input filename
-      TYPE(obfbdata)   :: inpfile    ! Output obfbdata structure
-      INTEGER          :: kunit      ! Unit for output
-      LOGICAL          :: ldwp       ! Print info
-      LOGICAL          :: ldgrid     ! Save grid info in data structure
-      !! * Local declarations
-      INTEGER :: iobs                ! Number of observations
-      INTEGER :: ilev                ! Number of levels
-      INTEGER :: ilat                ! Number of latitudes
-      INTEGER :: ilon                ! Number of longtudes
-      INTEGER :: itim                ! Number of obs. times
-      INTEGER :: i_file_id
-      INTEGER :: i_dimid_id
-      INTEGER :: i_phi_id
-      INTEGER :: i_lam_id
-      INTEGER :: i_depth_id
-      INTEGER :: i_var_id
-      INTEGER :: i_time_id
-      INTEGER :: i_time2_id
-      INTEGER :: i_qc_var_id
-      CHARACTER(LEN=40) :: cl_fld_lam
-      CHARACTER(LEN=40) :: cl_fld_phi
-      CHARACTER(LEN=40) :: cl_fld_depth
-      CHARACTER(LEN=40) :: cl_fld_var_u
-      CHARACTER(LEN=40) :: cl_fld_var_v
-      CHARACTER(LEN=40) :: cl_fld_var_qc_uv1
-      CHARACTER(LEN=40) :: cl_fld_var_qc_uv2
-      CHARACTER(LEN=40) :: cl_fld_time
-      CHARACTER(LEN=40) :: cl_fld_time2
-      INTEGER :: ja
-      INTEGER :: jo
-      INTEGER :: jk
-      INTEGER :: jt
-      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: &
-         & zv,     &
-         & zu,     &
-         & zuv1qc, &
-         & zuv2qc
-      REAL(wp), ALLOCATABLE, DIMENSION(:) :: &
-         & zdep, &
-         & zlat, &
-         & zlon, &
-         & zjuld
-      REAL(wp) :: zl
-      INTEGER, ALLOCATABLE, DIMENSION(:) :: &
-         & itime, &
-         & itime2
-      CHARACTER(LEN=50) :: cdjulref
-      CHARACTER(LEN=12), PARAMETER :: cl_name = 'read_taondbc'
-      CHARACTER(len=1) :: cns, cew
-
-      !-----------------------------------------------------------------------
-      ! Initialization
-      !-----------------------------------------------------------------------
-      cl_fld_lam                 = 'lon'
-      cl_fld_phi                 = 'lat'
-      cl_fld_depth               = 'depth'
-      cl_fld_time                = 'time'
-      cl_fld_time2               = 'time2'
-
-      !-----------------------------------------------------------------------
-      ! Open file
-      !-----------------------------------------------------------------------
-
-      CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, &
-            &      i_file_id ),           cl_name, __LINE__ )
-
-      !-----------------------------------------------------------------------
-      ! Read the heading of the file
-      !-----------------------------------------------------------------------
-      IF(ldwp) WRITE(kunit,*)
-      IF(ldwp) WRITE(kunit,*) ' read_taondbc :' 
-      IF(ldwp) WRITE(kunit,*) ' ~~~~~~~~~~~~'
-      
-      !---------------------------------------------------------------------
-      ! Read the number of observations and of levels to allocate array
-      !---------------------------------------------------------------------
-      CALL chkerr( nf90_inq_dimid        ( i_file_id, 'time', i_dimid_id ),        &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = itim ),    &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inq_dimid        ( i_file_id, 'depth', i_dimid_id ),       &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = ilev ),    &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inq_dimid        ( i_file_id, 'lat', i_dimid_id ),           &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = ilat ),    &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inq_dimid        ( i_file_id, 'lon', i_dimid_id ),         &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = ilon ),    &
-         &         cl_name, __LINE__ ) 
-
-      iobs = itim * ilat * ilon
-      IF(ldwp)WRITE(kunit,*) '         No. of data records = ', iobs
-      IF(ldwp)WRITE(kunit,*) '         No. of levels       = ', ilev
-      IF(ldwp)WRITE(kunit,*) 
-
-      !---------------------------------------------------------------------
-      ! Allocate arrays
-      !---------------------------------------------------------------------
-
-      CALL init_obfbdata( inpfile )
-      CALL alloc_obfbdata( inpfile, 2, iobs, ilev, 0, 0, ldgrid )
-      inpfile%cname(1) = 'UVEL'
-      inpfile%cname(2) = 'VVEL'
-      inpfile%coblong(1) = 'Zonal current'
-      inpfile%coblong(2) = 'Meridional current'
-      inpfile%cobunit(1) = 'Meters per second'
-      inpfile%cobunit(2) = 'Meters per second'
-
-      ALLOCATE( &
-         & zu(ilon,ilat,ilev,itim),     &
-         & zv(ilon,ilat,ilev,itim),     &
-         & zdep(ilev),                  &
-         & zuv1qc(ilon,ilat,ilev,itim), &
-         & zuv2qc(ilon,ilat,ilev,itim), &
-         & itime(itim),                 &
-         & itime2(itim),                &
-         & zlat(ilat),                  &
-         & zlon(ilon),                  &
-         & zjuld(itim)                  &
-         & )
-
-      !---------------------------------------------------------------------
-      ! Read the time/position variables 
-      !---------------------------------------------------------------------
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_time, i_time_id ),                               &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_time_id, itime ),                                     &
-         &         cl_name, __LINE__ )
-
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_time2, i_time2_id ),                             &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_time2_id, itime2 ),                                   &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_depth, i_depth_id ),                             &
-            &         cl_name, __LINE__ )         
-      CALL chkerr( nf90_get_var  ( i_file_id, i_depth_id, zdep ),                                     &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_phi, i_phi_id ),                                 &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_phi_id, zlat ),                                       &
-         &         cl_name, __LINE__ )
-      
-      CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_lam, i_lam_id ),                                 &
-         &         cl_name, __LINE__ )
-      CALL chkerr( nf90_get_var  ( i_file_id, i_lam_id, zlon ),                                       &
-         &         cl_name, __LINE__ )
-      
-      !---------------------------------------------------------------------
-      ! Read the variables
-      !---------------------------------------------------------------------
-
-      ! ADCP format assumed
-      cl_fld_var_u = 'u_1205'
-      IF ( nf90_inq_varid( i_file_id, cl_fld_var_u, i_var_id ) /= nf90_noerr ) THEN
-         ! Try again with current meter format
-         cl_fld_var_u = 'U_320'
-         IF ( nf90_inq_varid( i_file_id, cl_fld_var_u, i_var_id ) /= nf90_noerr ) THEN
-            CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
-         ENDIF
-      ENDIF
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zu ),                                         &
-         &         cl_name, __LINE__ )
-      
-      ! ADCP format assumed
-      cl_fld_var_v = 'v_1206'
-      IF ( nf90_inq_varid( i_file_id, cl_fld_var_v, i_var_id ) /= nf90_noerr ) THEN
-         ! Try again with current meter format
-         cl_fld_var_v = 'V_321'
-         IF ( nf90_inq_varid( i_file_id, cl_fld_var_v, i_var_id ) /= nf90_noerr ) THEN
-            CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
-         ENDIF
-      ENDIF
-      CALL chkerr( nf90_get_var  ( i_file_id, i_var_id, zv ),                                         &
-         &         cl_name, __LINE__ )
-
-      !---------------------------------------------------------------------
-      ! Read the QC attributes
-      !---------------------------------------------------------------------
-      
-      ! ADCP format assumed
-      cl_fld_var_qc_uv1 = 'QU_5205'
-      IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv1, i_qc_var_id ) /= nf90_noerr ) THEN
-         ! Try again with current meter format
-         cl_fld_var_qc_uv1 = 'QCS_5300'
-         IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv1, i_qc_var_id ) /= nf90_noerr ) THEN
-            ! Try again with high freq. current meter format
-            cl_fld_var_qc_uv1 = 'QCU_5320'
-            IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv1, i_qc_var_id ) /= nf90_noerr ) THEN
-               CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
-            ENDIF
-         ENDIF
-      ENDIF
-      CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, zuv1qc),                                   &
-         &         cl_name, __LINE__ )
-
-      ! ADCP format assumed
-      cl_fld_var_qc_uv2 = 'QV_5206'
-      IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv2, i_qc_var_id ) /= nf90_noerr ) THEN
-         ! Try again with current meter format
-         cl_fld_var_qc_uv2 = 'QCD_5310'
-         IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv2, i_qc_var_id ) /= nf90_noerr ) THEN
-            ! Try again with high freq. current meter format
-            cl_fld_var_qc_uv2 = 'QCV_5321'
-            IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv2, i_qc_var_id ) /= nf90_noerr ) THEN
-               CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
-            ENDIF
-         ENDIF
-      ENDIF
-      CALL chkerr( nf90_get_var  ( i_file_id, i_qc_var_id, zuv2qc),                                   &
-         &         cl_name, __LINE__ )
-
-      !---------------------------------------------------------------------
-      ! Close file
-      !---------------------------------------------------------------------
-
-      CALL chkerr( nf90_close( i_file_id ),           cl_name, __LINE__ )
-
-      !---------------------------------------------------------------------
-      ! Convert to to 19500101 based Julian date
-      !---------------------------------------------------------------------
-      DO jt = 1, itim
-         zjuld(jt) = REAL(itime(jt),wp) + REAL(itime2(jt),wp)/86400000.0_wp &
-            &           - 2433283.0_wp
-      END DO
-      inpfile%cdjuldref = '19500101000000'
-
-      !---------------------------------------------------------------------
-      ! Copy info to obfbdata structure
-      !---------------------------------------------------------------------
-
-      iobs = 0
-      DO jt = 1, itim
-         DO ja = 1, ilat
-            DO jo = 1, ilon
-               iobs = iobs + 1
-               zl = zlon(jo)
-               IF ( zl > 180.0_wp ) zl = zl - 360.0_wp
-               IF ( zl < 0 ) THEN
-                  cew = 'w'
-               ELSE
-                  cew = 'e'
-               ENDIF
-               IF ( zlat(jo) < 0 ) THEN
-                  cns = 's'
-               ELSE
-                  cns = 'n'
-               ENDIF
-               WRITE(inpfile%cdwmo(iobs),'(A1,I2.2,A1,I3.3)') &
-                  & cns, ABS(NINT(zlat(ja))), cew, ABS(NINT(zl))
-               DO jk = 1, ilev
-                  inpfile%pob(jk,iobs,1)     = zu(jo,ja,jk,jt)
-                  inpfile%pob(jk,iobs,2)     = zv(jo,ja,jk,jt)
-                  inpfile%pdep(jk,iobs)      = zdep(jk)
-                  inpfile%ivlqc(jk,iobs,1:2) = INT( MAX( zuv1qc(jo,ja,jk,jt), zuv2qc(jo,ja,jk,jt) ) )
-               END DO
-               inpfile%plam(iobs) = zlon(jo)
-               inpfile%pphi(iobs) = zlat(ja)
-               inpfile%ptim(iobs) = zjuld(jt)
-            END DO
-         END DO
-      END DO
-
-      ! No position, time, depth and variable QC in input files
-      DO jo = 1, iobs
-         inpfile%ipqc(jo) = 1
-         inpfile%itqc(jo) = 1
-         inpfile%ivqc(jo,1:2) = 1
-         DO jk = 1, ilev
-            inpfile%idqc(jk,jo) = 1
-         END DO
-      END DO
-
-      !---------------------------------------------------------------------
-      ! Set the platform information
-      !---------------------------------------------------------------------
-      inpfile%cdtyp(:)=' 820'
-
-      !---------------------------------------------------------------------
-      ! Set QC flags for missing data and rescale to m/s
-      !---------------------------------------------------------------------
-
-      DO jo = 1, iobs
-         DO jk = 1, ilev
-            IF ( ( ABS(inpfile%pob(jk,jo,1)) > 10000.0_wp ) .OR. &
-               & ( ABS(inpfile%pob(jk,jo,2)) > 10000.0_wp ) ) THEN
-               inpfile%ivlqc(jk,jo,:) = 4
-               inpfile%pob(jk,jo,1) = fbrmdi
-               inpfile%pob(jk,jo,2) = fbrmdi
-            ELSE
-               inpfile%pob(jk,jo,1) = 0.01 * inpfile%pob(jk,jo,1)
-               inpfile%pob(jk,jo,2) = 0.01 * inpfile%pob(jk,jo,2)
-            ENDIF
-         END DO
-      END DO
-
-      !---------------------------------------------------------------------
-      ! Set file indexes
-      !---------------------------------------------------------------------
-
-      DO jo = 1, inpfile%nobs
-         inpfile%kindex(jo) = jo
-      END DO
-
-      !---------------------------------------------------------------------
-      ! Initialize flags since they are not in the TAO input files
-      !---------------------------------------------------------------------
-
-      inpfile%ioqcf(:,:)      = 0
-      inpfile%ipqcf(:,:)      = 0
-      inpfile%itqcf(:,:)      = 0
-      inpfile%idqcf(:,:,:)    = 0
-      inpfile%ivqcf(:,:,:)    = 0
-      inpfile%ivlqcf(:,:,:,:) = 0
-
-      !---------------------------------------------------------------------
-      ! Deallocate data
-      !---------------------------------------------------------------------
-      DEALLOCATE( &
-         & zu,     &
-         & zv,     &
-         & zdep,   &
-         & zuv1qc, &
-         & zuv2qc, &
-         & itime,  &
-         & itime2, &
-         & zlat,   &
-         & zlon,   &
-         & zjuld   &
-         & )
-
-   END SUBROUTINE read_taondbc
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdf_oce.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdf_oce.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdf_oce.F90	(revision 10247)
@@ -43,4 +43,7 @@
    REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:,:,:) ::   avmu , avmv    !: vertical viscosity coef at uw- & vw-pts       [m2/s]
    REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:,:,:) ::   avm  , avt     !: vertical viscosity & diffusivity coef at w-pt [m2/s]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avt_k , avm_k  ! not enhanced Kz
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avmu_k, avmv_k ! not enhanced Kz
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   en              !: now turbulent kinetic energy   [m2/s2]
  
    !!----------------------------------------------------------------------
@@ -60,5 +63,8 @@
          &     tfrua(jpi, jpj), tfrva(jpi, jpj)              ,      &
          &     avmu(jpi,jpj,jpk), avm(jpi,jpj,jpk)           ,      &
-         &     avmv(jpi,jpj,jpk), avt(jpi,jpj,jpk)           , STAT = zdf_oce_alloc )
+         &     avmv  (jpi,jpj,jpk), avt   (jpi,jpj,jpk)      ,      &
+         &     avt_k (jpi,jpj,jpk), avm_k (jpi,jpj,jpk)      ,      & 
+         &     avmu_k(jpi,jpj,jpk), avmv_k(jpi,jpj,jpk)      ,      &
+         &     en    (jpi,jpj,jpk), STAT = zdf_oce_alloc )
          !
       IF( zdf_oce_alloc /= 0 )   CALL ctl_warn('zdf_oce_alloc: failed to allocate arrays')
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfgls.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfgls.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfgls.F90	(revision 10247)
@@ -42,11 +42,6 @@
    LOGICAL , PUBLIC, PARAMETER ::   lk_zdfgls = .TRUE.   !: TKE vertical mixing flag
    !
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   en      !: now turbulent kinetic energy
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   mxln    !: now mixing length
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   zwall   !: wall function
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avt_k   ! not enhanced Kz
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avm_k   ! not enhanced Kz
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avmu_k  ! not enhanced Kz
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avmv_k  ! not enhanced Kz
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ustars2 !: Squared surface velocity scale at T-points
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ustarb2 !: Squared bottom  velocity scale at T-points
@@ -120,8 +115,6 @@
       !!                ***  FUNCTION zdf_gls_alloc  ***
       !!----------------------------------------------------------------------
-      ALLOCATE( en(jpi,jpj,jpk),  mxln(jpi,jpj,jpk), zwall(jpi,jpj,jpk) ,     &
-         &      avt_k (jpi,jpj,jpk) , avm_k (jpi,jpj,jpk),                    &
-         &      avmu_k(jpi,jpj,jpk) , avmv_k(jpi,jpj,jpk),                    &
-         &      ustars2(jpi,jpj), ustarb2(jpi,jpj)                      , STAT= zdf_gls_alloc )
+      ALLOCATE( mxln(jpi,jpj,jpk), zwall(jpi,jpj,jpk) ,     &
+         &      ustars2(jpi,jpj) , ustarb2(jpi,jpj)   , STAT= zdf_gls_alloc )
          !
       IF( lk_mpp             )   CALL mpp_sum ( zdf_gls_alloc )
@@ -329,5 +322,6 @@
       ! 
       ! One level below
-      en(:,:,2) = rc02r * ustars2(:,:) * (1._wp + rsbc_tke1 * ((zhsro(:,:)+fsdepw(:,:,2))/zhsro(:,:) )**(1.5_wp*ra_sf))**(2._wp/3._wp)
+      en(:,:,2) = rc02r * ustars2(:,:) * (1._wp + rsbc_tke1 * ((zhsro(:,:)+fsdepw(:,:,2)) &
+          &            / zhsro(:,:) )**(1.5_wp*ra_sf))**(2._wp/3._wp)
       en(:,:,2) = MAX(en(:,:,2), rn_emin )
       z_elem_a(:,:,2) = 0._wp 
@@ -350,5 +344,6 @@
       z_elem_a(:,:,2) = 0._wp
       zkar(:,:)       = (rl_sf + (vkarmn-rl_sf)*(1.-exp(-rtrans*fsdept(:,:,1)/zhsro(:,:)) ))
-      zflxs(:,:)      = rsbc_tke2 * ustars2(:,:)**1.5_wp * zkar(:,:) * ((zhsro(:,:)+fsdept(:,:,1))/zhsro(:,:) )**(1.5_wp*ra_sf)
+      zflxs(:,:)      = rsbc_tke2 * ustars2(:,:)**1.5_wp * zkar(:,:) &
+           &                      * ((zhsro(:,:)+fsdept(:,:,1))/zhsro(:,:) )**(1.5_wp*ra_sf)
 
       en(:,:,2) = en(:,:,2) + zflxs(:,:)/fse3w(:,:,2)
Index: branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdftke.F90
===================================================================
--- branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdftke.F90	(revision 10246)
+++ branches/UKMO/dev_r5518_AMM15_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdftke.F90	(revision 10247)
@@ -85,9 +85,6 @@
    REAL(wp) ::   rhftau_scl = 1.0_wp       ! scale factor applied to HF part of taum  (nn_etau=3)
 
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   en             !: now turbulent kinetic energy   [m2/s2]
    REAL(wp)        , ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   htau           ! depth of tke penetration (nn_htau)
    REAL(wp)        , ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   dissl          ! now mixing lenght of dissipation
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avt_k , avm_k  ! not enhanced Kz
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   avmu_k, avmv_k ! not enhanced Kz
 #if defined key_c1d
    !                                                                        !!** 1D cfg only  **   ('key_c1d')
@@ -115,7 +112,5 @@
          &      e_pdl(jpi,jpj,jpk) , e_ric(jpi,jpj,jpk) ,                          &
 #endif
-         &      en    (jpi,jpj,jpk) , htau  (jpi,jpj)    , dissl(jpi,jpj,jpk) ,     & 
-         &      avt_k (jpi,jpj,jpk) , avm_k (jpi,jpj,jpk),                          &
-         &      avmu_k(jpi,jpj,jpk) , avmv_k(jpi,jpj,jpk), STAT= zdf_tke_alloc      )
+         &      htau  (jpi,jpj)    , dissl(jpi,jpj,jpk) , STAT= zdf_tke_alloc      )
          !
       IF( lk_mpp             )   CALL mpp_sum ( zdf_tke_alloc )
