New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 5998 for branches/2015/dev_MetOffice_merge_2015/NEMOGCM/NEMO/OPA_SRC/OBS/obs_oper.F90 – NEMO

Ignore:
Timestamp:
2015-12-04T11:56:46+01:00 (8 years ago)
Author:
timgraham
Message:

Merge in changes from OBS simplification branch (branches/2015/dev_r5072_UKMO2_OBS_simplification)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2015/dev_MetOffice_merge_2015/NEMOGCM/NEMO/OPA_SRC/OBS/obs_oper.F90

    r5990 r5998  
    77 
    88   !!---------------------------------------------------------------------- 
    9    !!   obs_pro_opt :    Compute the model counterpart of temperature and 
    10    !!                    salinity observations from profiles 
     9   !!   obs_prof_opt :    Compute the model counterpart of profile data 
     10   !!   obs_surf_opt :    Compute the model counterpart of surface data 
    1111   !!   obs_pro_sco_opt: Compute the model counterpart of temperature and  
    1212   !!                    salinity observations from profiles in generalised  
    1313   !!                    vertical coordinates  
    14    !!   obs_sla_opt :    Compute the model counterpart of sea level anomaly 
    15    !!                    observations 
    16    !!   obs_sst_opt :    Compute the model counterpart of sea surface temperature 
    17    !!                    observations 
    18    !!   obs_sss_opt :    Compute the model counterpart of sea surface salinity 
    19    !!                    observations 
    20    !!   obs_seaice_opt : Compute the model counterpart of sea ice concentration 
    21    !!                    observations 
    22    !! 
    23    !!   obs_vel_opt :    Compute the model counterpart of zonal and meridional 
    24    !!                    components of velocity from observations. 
    2514   !!---------------------------------------------------------------------- 
    2615 
    27    !! * Modules used    
     16   !! * Modules used 
    2817   USE par_kind, ONLY : &         ! Precision variables 
    2918      & wp 
    3019   USE in_out_manager             ! I/O manager 
    3120   USE obs_inter_sup              ! Interpolation support 
    32    USE obs_inter_h2d, ONLY : &    ! Horizontal interpolation to the observation pt 
     21   USE obs_inter_h2d, ONLY : &    ! Horizontal interpolation to the obs pt 
    3322      & obs_int_h2d, & 
    3423      & obs_int_h2d_init 
    35    USE obs_inter_z1d, ONLY : &    ! Vertical interpolation to the observation pt 
     24   USE obs_inter_z1d, ONLY : &    ! Vertical interpolation to the obs pt 
    3625      & obs_int_z1d,    & 
    3726      & obs_int_z1d_spl 
     
    5039   USE obs_grid,      ONLY : &  
    5140      & obs_level_search      
    52        
     41   USE sbcdcy,        ONLY : &    ! For calculation of where it is night-time 
     42      & sbc_dcy, nday_qsr 
     43 
    5344   IMPLICIT NONE 
    5445 
     
    5647   PRIVATE 
    5748 
    58    PUBLIC obs_pro_opt, &  ! Compute the model counterpart of profile observations 
     49   PUBLIC obs_prof_opt, &  ! Compute the model counterpart of profile obs 
    5950      &   obs_pro_sco_opt, &  ! Compute the model counterpart of profile observations  
    60                               ! in generalised vertical coordinates  
    61       &   obs_sla_opt, &  ! Compute the model counterpart of SLA observations 
    62       &   obs_sst_opt, &  ! Compute the model counterpart of SST observations 
    63       &   obs_sss_opt, &  ! Compute the model counterpart of SSS observations 
    64       &   obs_seaice_opt, & 
    65       &   obs_vel_opt     ! Compute the model counterpart of velocity profile data 
    66  
    67    INTEGER, PARAMETER, PUBLIC :: imaxavtypes = 20 ! Max number of daily avgd obs types 
     51      &   obs_surf_opt     ! Compute the model counterpart of surface obs 
     52 
     53   INTEGER, PARAMETER, PUBLIC :: & 
     54      & imaxavtypes = 20   ! Max number of daily avgd obs types 
    6855 
    6956   !!---------------------------------------------------------------------- 
     
    7764CONTAINS 
    7865 
    79    SUBROUTINE obs_pro_opt( prodatqc, kt, kpi, kpj, kpk, kit000, kdaystp, & 
    80       &                    ptn, psn, pgdept, ptmask, k1dint, k2dint, & 
    81       &                    kdailyavtypes ) 
     66   SUBROUTINE obs_prof_opt( prodatqc, kt, kpi, kpj, kpk,          & 
     67      &                     kit000, kdaystp,                      & 
     68      &                     pvar1, pvar2, pgdept, pmask1, pmask2, & 
     69      &                     plam1, plam2, pphi1, pphi2,           & 
     70      &                     k1dint, k2dint, kdailyavtypes ) 
     71 
    8272      !!----------------------------------------------------------------------- 
    8373      !! 
     
    9282      !! 
    9383      !!    First, a vertical profile of horizontally interpolated model 
    94       !!    now temperatures is computed at the obs (lon, lat) point. 
     84      !!    now values is computed at the obs (lon, lat) point. 
    9585      !!    Several horizontal interpolation schemes are available: 
    9686      !!        - distance-weighted (great circle) (k2dint = 0) 
     
    10090      !!        - polynomial (quadrilateral grid)  (k2dint = 4) 
    10191      !! 
    102       !!    Next, the vertical temperature profile is interpolated to the 
     92      !!    Next, the vertical profile is interpolated to the 
    10393      !!    data depth points. Two vertical interpolation schemes are 
    10494      !!    available: 
     
    110100      !!    routine. 
    111101      !! 
    112       !!    For ENACT moored buoy data (e.g., TAO), the model equivalent is 
     102      !!    If the logical is switched on, the model equivalent is 
    113103      !!    a daily mean model temperature field. So, we first compute 
    114104      !!    the mean, then interpolate only at the end of the day. 
    115105      !! 
    116       !!    Note: the in situ temperature observations must be converted 
     106      !!    Note: in situ temperature observations must be converted 
    117107      !!    to potential temperature (the model variable) prior to 
    118108      !!    assimilation.  
    119       !!?????????????????????????????????????????????????????????????? 
    120       !!    INCLUDE POTENTIAL TEMP -> IN SITU TEMP IN OBS OPERATOR??? 
    121       !!?????????????????????????????????????????????????????????????? 
    122109      !! 
    123110      !! ** Action  : 
     
    129116      !!      ! 07-01 (K. Mogensen) Merge of temperature and salinity 
    130117      !!      ! 07-03 (K. Mogensen) General handling of profiles 
     118      !!      ! 15-02 (M. Martin) Combined routine for all profile types 
    131119      !!----------------------------------------------------------------------- 
    132    
     120 
    133121      !! * Modules used 
    134122      USE obs_profiles_def ! Definition of storage space for profile obs. 
     
    137125 
    138126      !! * Arguments 
    139       TYPE(obs_prof), INTENT(INOUT) :: prodatqc  ! Subset of profile data not failing screening 
    140       INTEGER, INTENT(IN) :: kt        ! Time step 
    141       INTEGER, INTENT(IN) :: kpi       ! Model grid parameters 
     127      TYPE(obs_prof), INTENT(INOUT) :: & 
     128         & prodatqc                  ! Subset of profile data passing QC 
     129      INTEGER, INTENT(IN) :: kt      ! Time step 
     130      INTEGER, INTENT(IN) :: kpi     ! Model grid parameters 
    142131      INTEGER, INTENT(IN) :: kpj 
    143132      INTEGER, INTENT(IN) :: kpk 
    144       INTEGER, INTENT(IN) :: kit000    ! Number of the first time step  
    145                                        !   (kit000-1 = restart time) 
    146       INTEGER, INTENT(IN) :: k1dint    ! Vertical interpolation type (see header) 
    147       INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header) 
    148       INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day                     
     133      INTEGER, INTENT(IN) :: kit000  ! Number of the first time step 
     134                                     !   (kit000-1 = restart time) 
     135      INTEGER, INTENT(IN) :: k1dint  ! Vertical interpolation type (see header) 
     136      INTEGER, INTENT(IN) :: k2dint  ! Horizontal interpolation type (see header) 
     137      INTEGER, INTENT(IN) :: kdaystp ! Number of time steps per day 
    149138      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj,kpk) :: & 
    150          & ptn,    &    ! Model temperature field 
    151          & psn,    &    ! Model salinity field 
    152          & ptmask       ! Land-sea mask 
     139         & pvar1,    &               ! Model field 1 
     140         & pvar2,    &               ! Model field 2 
     141         & pmask1,   &               ! Land-sea mask 1 
     142         & pmask2                    ! Land-sea mask 2 
     143      REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: & 
     144         & plam1,    &               ! Model longitudes for variable 1 
     145         & plam2,    &               ! Model longitudes for variable 2 
     146         & pphi1,    &               ! Model latitudes for variable 1 
     147         & pphi2                     ! Model latitudes for variable 2 
    153148      REAL(KIND=wp), INTENT(IN), DIMENSION(kpk) :: & 
    154          & pgdept       ! Model array of depth levels 
     149         & pgdept                    ! Model array of depth levels 
    155150      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: & 
    156          & kdailyavtypes! Types for daily averages 
     151         & kdailyavtypes             ! Types for daily averages 
     152 
    157153      !! * Local declarations 
    158154      INTEGER ::   ji 
     
    168164      INTEGER, DIMENSION(imaxavtypes) :: & 
    169165         & idailyavtypes 
     166      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: & 
     167         & igrdi1, & 
     168         & igrdi2, & 
     169         & igrdj1, & 
     170         & igrdj2 
    170171      REAL(KIND=wp) :: zlam 
    171172      REAL(KIND=wp) :: zphi 
    172173      REAL(KIND=wp) :: zdaystp 
    173174      REAL(KIND=wp), DIMENSION(kpk) :: & 
    174          & zobsmask, & 
     175         & zobsmask1, & 
     176         & zobsmask2, & 
    175177         & zobsk,    & 
    176178         & zobs2k 
    177179      REAL(KIND=wp), DIMENSION(2,2,kpk) :: & 
    178          & zweig 
     180         & zweig1, & 
     181         & zweig2 
    179182      REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE :: & 
    180          & zmask, & 
    181          & zintt, & 
    182          & zints, & 
    183          & zinmt, & 
    184          & zinms 
     183         & zmask1, & 
     184         & zmask2, & 
     185         & zint1, & 
     186         & zint2, & 
     187         & zinm1, & 
     188         & zinm2 
    185189      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 
    186          & zglam, & 
    187          & zgphi 
    188       INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: & 
    189          & igrdi, & 
    190          & igrdj 
     190         & zglam1, & 
     191         & zglam2, & 
     192         & zgphi1, & 
     193         & zgphi2 
     194      LOGICAL :: ld_dailyav 
    191195 
    192196      !------------------------------------------------------------------------ 
    193197      ! Local initialization  
    194198      !------------------------------------------------------------------------ 
    195       ! ... Record and data counters 
     199      ! Record and data counters 
    196200      inrc = kt - kit000 + 2 
    197201      ipro = prodatqc%npstp(inrc) 
    198   
     202 
    199203      ! Daily average types 
     204      ld_dailyav = .FALSE. 
    200205      IF ( PRESENT(kdailyavtypes) ) THEN 
    201206         idailyavtypes(:) = kdailyavtypes(:) 
     207         IF ( ANY (idailyavtypes(:) /= -1) ) ld_dailyav = .TRUE. 
    202208      ELSE 
    203209         idailyavtypes(:) = -1 
    204210      ENDIF 
    205211 
    206       ! Initialize daily mean for first timestep 
     212      ! Daily means are calculated for values over timesteps: 
     213      !  [1 <= kt <= kdaystp], [kdaystp+1 <= kt <= 2*kdaystp], ... 
    207214      idayend = MOD( kt - kit000 + 1, kdaystp ) 
    208215 
    209       ! Added kt == 0 test to catch restart case  
    210       IF ( idayend == 1 .OR. kt == 0) THEN 
    211          IF (lwp) WRITE(numout,*) 'Reset prodatqc%vdmean on time-step: ',kt 
     216      IF ( ld_dailyav ) THEN 
     217 
     218         ! Initialize daily mean for first timestep of the day 
     219         IF ( idayend == 1 .OR. kt == 0 ) THEN 
     220            DO jk = 1, jpk 
     221               DO jj = 1, jpj 
     222                  DO ji = 1, jpi 
     223                     prodatqc%vdmean(ji,jj,jk,1) = 0.0 
     224                     prodatqc%vdmean(ji,jj,jk,2) = 0.0 
     225                  END DO 
     226               END DO 
     227            END DO 
     228         ENDIF 
     229 
    212230         DO jk = 1, jpk 
    213231            DO jj = 1, jpj 
    214232               DO ji = 1, jpi 
    215                   prodatqc%vdmean(ji,jj,jk,1) = 0.0 
    216                   prodatqc%vdmean(ji,jj,jk,2) = 0.0 
     233                  ! Increment field 1 for computing daily mean 
     234                  prodatqc%vdmean(ji,jj,jk,1) = prodatqc%vdmean(ji,jj,jk,1) & 
     235                     &                        + pvar1(ji,jj,jk) 
     236                  ! Increment field 2 for computing daily mean 
     237                  prodatqc%vdmean(ji,jj,jk,2) = prodatqc%vdmean(ji,jj,jk,2) & 
     238                     &                        + pvar2(ji,jj,jk) 
    217239               END DO 
    218240            END DO 
    219241         END DO 
    220       ENDIF 
    221  
    222       DO jk = 1, jpk 
    223          DO jj = 1, jpj 
    224             DO ji = 1, jpi 
    225                ! Increment the temperature field for computing daily mean 
    226                prodatqc%vdmean(ji,jj,jk,1) = prodatqc%vdmean(ji,jj,jk,1) & 
    227                   &                        + ptn(ji,jj,jk) 
    228                ! Increment the salinity field for computing daily mean 
    229                prodatqc%vdmean(ji,jj,jk,2) = prodatqc%vdmean(ji,jj,jk,2) & 
    230                   &                        + psn(ji,jj,jk) 
    231             END DO 
    232          END DO 
    233       END DO 
    234     
    235       ! Compute the daily mean at the end of day 
    236       zdaystp = 1.0 / REAL( kdaystp ) 
    237       IF ( idayend == 0 ) THEN 
    238          DO jk = 1, jpk 
    239             DO jj = 1, jpj 
    240                DO ji = 1, jpi 
    241                   prodatqc%vdmean(ji,jj,jk,1) = prodatqc%vdmean(ji,jj,jk,1) & 
    242                      &                        * zdaystp 
    243                   prodatqc%vdmean(ji,jj,jk,2) = prodatqc%vdmean(ji,jj,jk,2) & 
    244                   &                           * zdaystp 
     242 
     243         ! Compute the daily mean at the end of day 
     244         zdaystp = 1.0 / REAL( kdaystp ) 
     245         IF ( idayend == 0 ) THEN 
     246            IF (lwp) WRITE(numout,*) 'Calculating prodatqc%vdmean on time-step: ',kt 
     247            CALL FLUSH(numout) 
     248            DO jk = 1, jpk 
     249               DO jj = 1, jpj 
     250                  DO ji = 1, jpi 
     251                     prodatqc%vdmean(ji,jj,jk,1) = prodatqc%vdmean(ji,jj,jk,1) & 
     252                        &                        * zdaystp 
     253                     prodatqc%vdmean(ji,jj,jk,2) = prodatqc%vdmean(ji,jj,jk,2) & 
     254                        &                        * zdaystp 
     255                  END DO 
    245256               END DO 
    246257            END DO 
    247          END DO 
     258         ENDIF 
     259 
    248260      ENDIF 
    249261 
    250262      ! Get the data for interpolation 
    251263      ALLOCATE( & 
    252          & igrdi(2,2,ipro),      & 
    253          & igrdj(2,2,ipro),      & 
    254          & zglam(2,2,ipro),      & 
    255          & zgphi(2,2,ipro),      & 
    256          & zmask(2,2,kpk,ipro),  & 
    257          & zintt(2,2,kpk,ipro),  & 
    258          & zints(2,2,kpk,ipro)   & 
     264         & igrdi1(2,2,ipro),      & 
     265         & igrdi2(2,2,ipro),      & 
     266         & igrdj1(2,2,ipro),      & 
     267         & igrdj2(2,2,ipro),      & 
     268         & zglam1(2,2,ipro),      & 
     269         & zglam2(2,2,ipro),      & 
     270         & zgphi1(2,2,ipro),      & 
     271         & zgphi2(2,2,ipro),      & 
     272         & zmask1(2,2,kpk,ipro),  & 
     273         & zmask2(2,2,kpk,ipro),  & 
     274         & zint1(2,2,kpk,ipro),  & 
     275         & zint2(2,2,kpk,ipro)   & 
    259276         & ) 
    260277 
    261278      DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro 
    262279         iobs = jobs - prodatqc%nprofup 
    263          igrdi(1,1,iobs) = prodatqc%mi(jobs,1)-1 
    264          igrdj(1,1,iobs) = prodatqc%mj(jobs,1)-1 
    265          igrdi(1,2,iobs) = prodatqc%mi(jobs,1)-1 
    266          igrdj(1,2,iobs) = prodatqc%mj(jobs,1) 
    267          igrdi(2,1,iobs) = prodatqc%mi(jobs,1) 
    268          igrdj(2,1,iobs) = prodatqc%mj(jobs,1)-1 
    269          igrdi(2,2,iobs) = prodatqc%mi(jobs,1) 
    270          igrdj(2,2,iobs) = prodatqc%mj(jobs,1) 
     280         igrdi1(1,1,iobs) = prodatqc%mi(jobs,1)-1 
     281         igrdj1(1,1,iobs) = prodatqc%mj(jobs,1)-1 
     282         igrdi1(1,2,iobs) = prodatqc%mi(jobs,1)-1 
     283         igrdj1(1,2,iobs) = prodatqc%mj(jobs,1) 
     284         igrdi1(2,1,iobs) = prodatqc%mi(jobs,1) 
     285         igrdj1(2,1,iobs) = prodatqc%mj(jobs,1)-1 
     286         igrdi1(2,2,iobs) = prodatqc%mi(jobs,1) 
     287         igrdj1(2,2,iobs) = prodatqc%mj(jobs,1) 
     288         igrdi2(1,1,iobs) = prodatqc%mi(jobs,2)-1 
     289         igrdj2(1,1,iobs) = prodatqc%mj(jobs,2)-1 
     290         igrdi2(1,2,iobs) = prodatqc%mi(jobs,2)-1 
     291         igrdj2(1,2,iobs) = prodatqc%mj(jobs,2) 
     292         igrdi2(2,1,iobs) = prodatqc%mi(jobs,2) 
     293         igrdj2(2,1,iobs) = prodatqc%mj(jobs,2)-1 
     294         igrdi2(2,2,iobs) = prodatqc%mi(jobs,2) 
     295         igrdj2(2,2,iobs) = prodatqc%mj(jobs,2) 
    271296      END DO 
    272297 
    273       CALL obs_int_comm_2d( 2, 2, ipro, igrdi, igrdj, glamt, zglam ) 
    274       CALL obs_int_comm_2d( 2, 2, ipro, igrdi, igrdj, gphit, zgphi ) 
    275       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, ptmask,zmask ) 
    276       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, ptn,   zintt ) 
    277       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, psn,   zints ) 
     298      CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi1, igrdj1, plam1, zglam1 ) 
     299      CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi1, igrdj1, pphi1, zgphi1 ) 
     300      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi1, igrdj1, pmask1, zmask1 ) 
     301      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi1, igrdj1, pvar1,   zint1 ) 
     302       
     303      CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi2, igrdj2, plam2, zglam2 ) 
     304      CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi2, igrdj2, pphi2, zgphi2 ) 
     305      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi2, igrdj2, pmask2, zmask2 ) 
     306      CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi2, igrdj2, pvar2,   zint2 ) 
    278307 
    279308      ! At the end of the day also get interpolated means 
    280       IF ( idayend == 0 ) THEN 
     309      IF ( ld_dailyav .AND. idayend == 0 ) THEN 
    281310 
    282311         ALLOCATE( & 
    283             & zinmt(2,2,kpk,ipro),  & 
    284             & zinms(2,2,kpk,ipro)   & 
     312            & zinm1(2,2,kpk,ipro),  & 
     313            & zinm2(2,2,kpk,ipro)   & 
    285314            & ) 
    286315 
    287          CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, & 
    288             &                  prodatqc%vdmean(:,:,:,1), zinmt ) 
    289          CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdi, igrdj, & 
    290             &                  prodatqc%vdmean(:,:,:,2), zinms ) 
     316         CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi1, igrdj1, & 
     317            &                  prodatqc%vdmean(:,:,:,1), zinm1 ) 
     318         CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi2, igrdj2, & 
     319            &                  prodatqc%vdmean(:,:,:,2), zinm2 ) 
    291320 
    292321      ENDIF 
     
    297326 
    298327         IF ( kt /= prodatqc%mstp(jobs) ) THEN 
    299              
     328 
    300329            IF(lwp) THEN 
    301330               WRITE(numout,*) 
     
    312341            CALL ctl_stop( 'obs_pro_opt', 'Inconsistent time' ) 
    313342         ENDIF 
    314           
     343 
    315344         zlam = prodatqc%rlam(jobs) 
    316345         zphi = prodatqc%rphi(jobs) 
    317           
     346 
    318347         ! Horizontal weights and vertical mask 
    319348 
    320          IF ( ( prodatqc%npvend(jobs,1) > 0 ) .OR. & 
    321             & ( prodatqc%npvend(jobs,2) > 0 ) ) THEN 
     349         IF ( prodatqc%npvend(jobs,1) > 0 ) THEN 
    322350 
    323351            CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     & 
    324                &                   zglam(:,:,iobs), zgphi(:,:,iobs), & 
    325                &                   zmask(:,:,:,iobs), zweig, zobsmask ) 
     352               &                   zglam1(:,:,iobs), zgphi1(:,:,iobs), & 
     353               &                   zmask1(:,:,:,iobs), zweig1, zobsmask1 ) 
    326354 
    327355         ENDIF 
    328356 
     357         IF ( prodatqc%npvend(jobs,2) > 0 ) THEN 
     358 
     359            CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     & 
     360               &                   zglam2(:,:,iobs), zgphi2(:,:,iobs), & 
     361               &                   zmask2(:,:,:,iobs), zweig2, zobsmask2 ) 
     362  
     363         ENDIF 
     364 
    329365         IF ( prodatqc%npvend(jobs,1) > 0 ) THEN 
    330366 
    331367            zobsk(:) = obfillflt 
    332368 
    333          IF ( ANY (idailyavtypes(:) == prodatqc%ntyp(jobs)) ) THEN 
     369            IF ( ANY (idailyavtypes(:) == prodatqc%ntyp(jobs)) ) THEN 
    334370 
    335371               IF ( idayend == 0 )  THEN 
    336                    
    337                   ! Daily averaged moored buoy (MRB) data 
    338                    
     372                  ! Daily averaged data 
    339373                  CALL obs_int_h2d( kpk, kpk,      & 
    340                      &              zweig, zinmt(:,:,:,iobs), zobsk ) 
    341                    
    342                    
    343                ELSE 
    344                 
    345                   CALL ctl_stop( ' A nonzero' //     & 
    346                      &           ' number of profile T BUOY data should' // & 
    347                      &           ' only occur at the end of a given day' ) 
     374                     &              zweig1, zinm1(:,:,:,iobs), zobsk ) 
    348375 
    349376               ENDIF 
    350            
     377 
    351378            ELSE  
    352                 
     379 
    353380               ! Point data 
    354  
    355381               CALL obs_int_h2d( kpk, kpk,      & 
    356                   &              zweig, zintt(:,:,:,iobs), zobsk ) 
     382                  &              zweig1, zint1(:,:,:,iobs), zobsk ) 
    357383 
    358384            ENDIF 
     
    362388            ! polynomial at obs points 
    363389            !------------------------------------------------------------- 
    364              
     390 
    365391            IF ( k1dint == 1 ) THEN 
    366392               CALL obs_int_z1d_spl( kpk, zobsk, zobs2k,   & 
    367                   &                  pgdept, zobsmask ) 
     393                  &                  pgdept, zobsmask1 ) 
    368394            ENDIF 
    369              
     395 
    370396            !----------------------------------------------------------------- 
    371397            !  Vertical interpolation to the observation point 
     
    379405               & zobsk, zobs2k,                   & 
    380406               & prodatqc%var(1)%vmod(ista:iend), & 
    381                & pgdept, zobsmask ) 
     407               & pgdept, zobsmask1 ) 
    382408 
    383409         ENDIF 
     
    391417               IF ( idayend == 0 )  THEN 
    392418 
    393                   ! Daily averaged moored buoy (MRB) data 
    394                    
     419                  ! Daily averaged data 
    395420                  CALL obs_int_h2d( kpk, kpk,      & 
    396                      &              zweig, zinms(:,:,:,iobs), zobsk ) 
    397                    
    398                ELSE 
    399  
    400                   CALL ctl_stop( ' A nonzero' //     & 
    401                      &           ' number of profile S BUOY data should' // & 
    402                      &           ' only occur at the end of a given day' ) 
     421                     &              zweig2, zinm2(:,:,:,iobs), zobsk ) 
    403422 
    404423               ENDIF 
    405424 
    406425            ELSE 
    407                 
     426 
    408427               ! Point data 
    409  
    410428               CALL obs_int_h2d( kpk, kpk,      & 
    411                   &              zweig, zints(:,:,:,iobs), zobsk ) 
     429                  &              zweig2, zint2(:,:,:,iobs), zobsk ) 
    412430 
    413431            ENDIF 
     
    418436            ! polynomial at obs points 
    419437            !------------------------------------------------------------- 
    420              
     438 
    421439            IF ( k1dint == 1 ) THEN 
    422440               CALL obs_int_z1d_spl( kpk, zobsk, zobs2k, & 
    423                   &                  pgdept, zobsmask ) 
     441                  &                  pgdept, zobsmask2 ) 
    424442            ENDIF 
    425              
     443 
    426444            !---------------------------------------------------------------- 
    427445            !  Vertical interpolation to the observation point 
     
    435453               & zobsk, zobs2k, & 
    436454               & prodatqc%var(2)%vmod(ista:iend),& 
    437                & pgdept, zobsmask ) 
     455               & pgdept, zobsmask2 ) 
    438456 
    439457         ENDIF 
    440458 
    441459      END DO 
    442   
     460 
    443461      ! Deallocate the data for interpolation 
    444462      DEALLOCATE( & 
    445          & igrdi, & 
    446          & igrdj, & 
    447          & zglam, & 
    448          & zgphi, & 
    449          & zmask, & 
    450          & zintt, & 
    451          & zints  & 
     463         & igrdi1, & 
     464         & igrdi2, & 
     465         & igrdj1, & 
     466         & igrdj2, & 
     467         & zglam1, & 
     468         & zglam2, & 
     469         & zgphi1, & 
     470         & zgphi2, & 
     471         & zmask1, & 
     472         & zmask2, & 
     473         & zint1,  & 
     474         & zint2   & 
    452475         & ) 
     476 
    453477      ! At the end of the day also get interpolated means 
    454       IF ( idayend == 0 ) THEN 
     478      IF ( ld_dailyav .AND. idayend == 0 ) THEN 
    455479         DEALLOCATE( & 
    456             & zinmt,  & 
    457             & zinms   & 
     480            & zinm1,  & 
     481            & zinm2   & 
    458482            & ) 
    459483      ENDIF 
    460484 
    461485      prodatqc%nprofup = prodatqc%nprofup + ipro  
    462        
    463    END SUBROUTINE obs_pro_opt 
     486 
     487   END SUBROUTINE obs_prof_opt 
    464488 
    465489   SUBROUTINE obs_pro_sco_opt( prodatqc, kt, kpi, kpj, kpk, kit000, kdaystp, &  
     
    10541078   END SUBROUTINE obs_pro_sco_opt  
    10551079  
    1056    SUBROUTINE obs_sla_opt( sladatqc, kt, kpi, kpj, kit000, & 
    1057       &                    psshn, psshmask, k2dint ) 
     1080   SUBROUTINE obs_surf_opt( surfdataqc, kt, kpi, kpj,         & 
     1081      &                    kit000, kdaystp, psurf, psurfmask, & 
     1082      &                    k2dint, ldnightav ) 
     1083 
    10581084      !!----------------------------------------------------------------------- 
    10591085      !! 
    1060       !!                     ***  ROUTINE obs_sla_opt  *** 
    1061       !! 
    1062       !! ** Purpose : Compute the model counterpart of sea level anomaly 
     1086      !!                     ***  ROUTINE obs_surf_opt  *** 
     1087      !! 
     1088      !! ** Purpose : Compute the model counterpart of surface 
    10631089      !!              data by interpolating from the model grid to the  
    10641090      !!              observation point. 
     
    10671093      !!              the model values at the corners of the surrounding grid box. 
    10681094      !! 
    1069       !!    The now model SSH is first computed at the obs (lon, lat) point. 
     1095      !!    The new model value is first computed at the obs (lon, lat) point. 
    10701096      !! 
    10711097      !!    Several horizontal interpolation schemes are available: 
     
    10751101      !!        - bilinear (quadrilateral grid)    (k2dint = 3) 
    10761102      !!        - polynomial (quadrilateral grid)  (k2dint = 4) 
    1077       !!   
    1078       !!    The sea level anomaly at the observation points is then computed  
    1079       !!    by removing a mean dynamic topography (defined at the obs. point). 
     1103      !! 
    10801104      !! 
    10811105      !! ** Action  : 
     
    10831107      !! History : 
    10841108      !!      ! 07-03 (A. Weaver) 
     1109      !!      ! 15-02 (M. Martin) Combined routine for surface types 
    10851110      !!----------------------------------------------------------------------- 
    1086    
     1111 
    10871112      !! * Modules used 
    10881113      USE obs_surf_def  ! Definition of storage space for surface observations 
     
    10911116 
    10921117      !! * Arguments 
    1093       TYPE(obs_surf), INTENT(INOUT) :: sladatqc     ! Subset of surface data not failing screening 
    1094       INTEGER, INTENT(IN) :: kt      ! Time step 
    1095       INTEGER, INTENT(IN) :: kpi     ! Model grid parameters 
     1118      TYPE(obs_surf), INTENT(INOUT) :: & 
     1119         & surfdataqc                  ! Subset of surface data passing QC 
     1120      INTEGER, INTENT(IN) :: kt        ! Time step 
     1121      INTEGER, INTENT(IN) :: kpi       ! Model grid parameters 
    10961122      INTEGER, INTENT(IN) :: kpj 
    1097       INTEGER, INTENT(IN) :: kit000   ! Number of the first time step  
    1098                                       !   (kit000-1 = restart time) 
    1099       INTEGER, INTENT(IN) :: k2dint   ! Horizontal interpolation type (see header) 
    1100       REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: & 
    1101          & psshn,  &    ! Model SSH field 
    1102          & psshmask     ! Land-sea mask 
    1103           
     1123      INTEGER, INTENT(IN) :: kit000    ! Number of the first time step  
     1124                                       !   (kit000-1 = restart time) 
     1125      INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day 
     1126      INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header) 
     1127      REAL(wp), INTENT(IN), DIMENSION(kpi,kpj) :: & 
     1128         & psurf,  &                   ! Model surface field 
     1129         & psurfmask                   ! Land-sea mask 
     1130      LOGICAL, INTENT(IN) :: ldnightav ! Logical for averaging night-time data 
     1131 
    11041132      !! * Local declarations 
    11051133      INTEGER :: ji 
     
    11071135      INTEGER :: jobs 
    11081136      INTEGER :: inrc 
    1109       INTEGER :: isla 
     1137      INTEGER :: isurf 
    11101138      INTEGER :: iobs 
    1111       REAL(KIND=wp) :: zlam 
    1112       REAL(KIND=wp) :: zphi 
    1113       REAL(KIND=wp) :: zext(1), zobsmask(1) 
    1114       REAL(kind=wp), DIMENSION(2,2,1) :: & 
    1115          & zweig 
    1116       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 
    1117          & zmask, & 
    1118          & zsshl, & 
    1119          & zglam, & 
    1120          & zgphi 
     1139      INTEGER :: idayend 
    11211140      INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: & 
    11221141         & igrdi, & 
    11231142         & igrdj 
     1143      INTEGER, DIMENSION(:,:), SAVE, ALLOCATABLE :: & 
     1144         & icount_night,      & 
     1145         & imask_night 
     1146      REAL(wp) :: zlam 
     1147      REAL(wp) :: zphi 
     1148      REAL(wp), DIMENSION(1) :: zext, zobsmask 
     1149      REAL(wp) :: zdaystp 
     1150      REAL(wp), DIMENSION(2,2,1) :: & 
     1151         & zweig 
     1152      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 
     1153         & zmask,  & 
     1154         & zsurf,  & 
     1155         & zsurfm, & 
     1156         & zglam,  & 
     1157         & zgphi 
     1158      REAL(wp), DIMENSION(:,:), SAVE, ALLOCATABLE :: & 
     1159         & zintmp,  & 
     1160         & zouttmp, & 
     1161         & zmeanday    ! to compute model sst in region of 24h daylight (pole) 
    11241162 
    11251163      !------------------------------------------------------------------------ 
    11261164      ! Local initialization  
    11271165      !------------------------------------------------------------------------ 
    1128       ! ... Record and data counters 
     1166      ! Record and data counters 
    11291167      inrc = kt - kit000 + 2 
    1130       isla = sladatqc%nsstp(inrc) 
     1168      isurf = surfdataqc%nsstp(inrc) 
     1169 
     1170      IF ( ldnightav ) THEN 
     1171 
     1172      ! Initialize array for night mean 
     1173         IF ( kt == 0 ) THEN 
     1174            ALLOCATE ( icount_night(kpi,kpj) ) 
     1175            ALLOCATE ( imask_night(kpi,kpj) ) 
     1176            ALLOCATE ( zintmp(kpi,kpj) ) 
     1177            ALLOCATE ( zouttmp(kpi,kpj) ) 
     1178            ALLOCATE ( zmeanday(kpi,kpj) ) 
     1179            nday_qsr = -1   ! initialisation flag for nbc_dcy 
     1180         ENDIF 
     1181 
     1182         ! Night-time means are calculated for night-time values over timesteps: 
     1183         !  [1 <= kt <= kdaystp], [kdaystp+1 <= kt <= 2*kdaystp], ..... 
     1184         idayend = MOD( kt - kit000 + 1, kdaystp ) 
     1185 
     1186         ! Initialize night-time mean for first timestep of the day 
     1187         IF ( idayend == 1 .OR. kt == 0 ) THEN 
     1188            DO jj = 1, jpj 
     1189               DO ji = 1, jpi 
     1190                  surfdataqc%vdmean(ji,jj) = 0.0 
     1191                  zmeanday(ji,jj) = 0.0 
     1192                  icount_night(ji,jj) = 0 
     1193               END DO 
     1194            END DO 
     1195         ENDIF 
     1196 
     1197         zintmp(:,:) = 0.0 
     1198         zouttmp(:,:) = sbc_dcy( zintmp(:,:), .TRUE. ) 
     1199         imask_night(:,:) = INT( zouttmp(:,:) ) 
     1200 
     1201         DO jj = 1, jpj 
     1202            DO ji = 1, jpi 
     1203               ! Increment the temperature field for computing night mean and counter 
     1204               surfdataqc%vdmean(ji,jj) = surfdataqc%vdmean(ji,jj)  & 
     1205                      &                    + psurf(ji,jj) * REAL( imask_night(ji,jj) ) 
     1206               zmeanday(ji,jj)          = zmeanday(ji,jj) + psurf(ji,jj) 
     1207               icount_night(ji,jj)      = icount_night(ji,jj) + imask_night(ji,jj) 
     1208            END DO 
     1209         END DO 
     1210 
     1211         ! Compute the night-time mean at the end of the day 
     1212         zdaystp = 1.0 / REAL( kdaystp ) 
     1213         IF ( idayend == 0 ) THEN 
     1214            IF (lwp) WRITE(numout,*) 'Calculating surfdataqc%vdmean on time-step: ',kt 
     1215            DO jj = 1, jpj 
     1216               DO ji = 1, jpi 
     1217                  ! Test if "no night" point 
     1218                  IF ( icount_night(ji,jj) > 0 ) THEN 
     1219                     surfdataqc%vdmean(ji,jj) = surfdataqc%vdmean(ji,jj) & 
     1220                       &                        / REAL( icount_night(ji,jj) ) 
     1221                  ELSE 
     1222                     !At locations where there is no night (e.g. poles), 
     1223                     ! calculate daily mean instead of night-time mean. 
     1224                     surfdataqc%vdmean(ji,jj) = zmeanday(ji,jj) * zdaystp 
     1225                  ENDIF 
     1226               END DO 
     1227            END DO 
     1228         ENDIF 
     1229 
     1230      ENDIF 
    11311231 
    11321232      ! Get the data for interpolation 
    11331233 
    11341234      ALLOCATE( & 
    1135          & igrdi(2,2,isla), & 
    1136          & igrdj(2,2,isla), & 
    1137          & zglam(2,2,isla), & 
    1138          & zgphi(2,2,isla), & 
    1139          & zmask(2,2,isla), & 
    1140          & zsshl(2,2,isla)  & 
     1235         & igrdi(2,2,isurf), & 
     1236         & igrdj(2,2,isurf), & 
     1237         & zglam(2,2,isurf), & 
     1238         & zgphi(2,2,isurf), & 
     1239         & zmask(2,2,isurf), & 
     1240         & zsurf(2,2,isurf)  & 
    11411241         & ) 
    1142        
    1143       DO jobs = sladatqc%nsurfup + 1, sladatqc%nsurfup + isla 
    1144          iobs = jobs - sladatqc%nsurfup 
    1145          igrdi(1,1,iobs) = sladatqc%mi(jobs)-1 
    1146          igrdj(1,1,iobs) = sladatqc%mj(jobs)-1 
    1147          igrdi(1,2,iobs) = sladatqc%mi(jobs)-1 
    1148          igrdj(1,2,iobs) = sladatqc%mj(jobs) 
    1149          igrdi(2,1,iobs) = sladatqc%mi(jobs) 
    1150          igrdj(2,1,iobs) = sladatqc%mj(jobs)-1 
    1151          igrdi(2,2,iobs) = sladatqc%mi(jobs) 
    1152          igrdj(2,2,iobs) = sladatqc%mj(jobs) 
     1242 
     1243      DO jobs = surfdataqc%nsurfup + 1, surfdataqc%nsurfup + isurf 
     1244         iobs = jobs - surfdataqc%nsurfup 
     1245         igrdi(1,1,iobs) = surfdataqc%mi(jobs)-1 
     1246         igrdj(1,1,iobs) = surfdataqc%mj(jobs)-1 
     1247         igrdi(1,2,iobs) = surfdataqc%mi(jobs)-1 
     1248         igrdj(1,2,iobs) = surfdataqc%mj(jobs) 
     1249         igrdi(2,1,iobs) = surfdataqc%mi(jobs) 
     1250         igrdj(2,1,iobs) = surfdataqc%mj(jobs)-1 
     1251         igrdi(2,2,iobs) = surfdataqc%mi(jobs) 
     1252         igrdj(2,2,iobs) = surfdataqc%mj(jobs) 
    11531253      END DO 
    11541254 
    1155       CALL obs_int_comm_2d( 2, 2, isla, & 
     1255      CALL obs_int_comm_2d( 2, 2, isurf, kpi, kpj, & 
    11561256         &                  igrdi, igrdj, glamt, zglam ) 
    1157       CALL obs_int_comm_2d( 2, 2, isla, & 
     1257      CALL obs_int_comm_2d( 2, 2, isurf, kpi, kpj, & 
    11581258         &                  igrdi, igrdj, gphit, zgphi ) 
    1159       CALL obs_int_comm_2d( 2, 2, isla, & 
    1160          &                  igrdi, igrdj, psshmask, zmask ) 
    1161       CALL obs_int_comm_2d( 2, 2, isla, & 
    1162          &                  igrdi, igrdj, psshn, zsshl ) 
     1259      CALL obs_int_comm_2d( 2, 2, isurf, kpi, kpj, & 
     1260         &                  igrdi, igrdj, psurfmask, zmask ) 
     1261      CALL obs_int_comm_2d( 2, 2, isurf, kpi, kpj, & 
     1262         &                  igrdi, igrdj, psurf, zsurf ) 
     1263 
     1264      ! At the end of the day get interpolated means 
     1265      IF ( idayend == 0 .AND. ldnightav ) THEN 
     1266 
     1267         ALLOCATE( & 
     1268            & zsurfm(2,2,isurf)  & 
     1269            & ) 
     1270 
     1271         CALL obs_int_comm_2d( 2, 2, isurf, kpi, kpj, igrdi, igrdj, & 
     1272            &               surfdataqc%vdmean(:,:), zsurfm ) 
     1273 
     1274      ENDIF 
    11631275 
    11641276      ! Loop over observations 
    1165  
    1166       DO jobs = sladatqc%nsurfup + 1, sladatqc%nsurfup + isla 
    1167  
    1168          iobs = jobs - sladatqc%nsurfup 
    1169  
    1170          IF ( kt /= sladatqc%mstp(jobs) ) THEN 
    1171              
     1277      DO jobs = surfdataqc%nsurfup + 1, surfdataqc%nsurfup + isurf 
     1278 
     1279         iobs = jobs - surfdataqc%nsurfup 
     1280 
     1281         IF ( kt /= surfdataqc%mstp(jobs) ) THEN 
     1282 
    11721283            IF(lwp) THEN 
    11731284               WRITE(numout,*) 
     
    11791290               WRITE(numout,*) ' Record  = ', jobs,                & 
    11801291                  &            ' kt      = ', kt,                  & 
    1181                   &            ' mstp    = ', sladatqc%mstp(jobs), & 
    1182                   &            ' ntyp    = ', sladatqc%ntyp(jobs) 
     1292                  &            ' mstp    = ', surfdataqc%mstp(jobs), & 
     1293                  &            ' ntyp    = ', surfdataqc%ntyp(jobs) 
    11831294            ENDIF 
    1184             CALL ctl_stop( 'obs_sla_opt', 'Inconsistent time' ) 
    1185              
     1295            CALL ctl_stop( 'obs_surf_opt', 'Inconsistent time' ) 
     1296 
    11861297         ENDIF 
    1187           
    1188          zlam = sladatqc%rlam(jobs) 
    1189          zphi = sladatqc%rphi(jobs) 
    1190  
    1191          ! Get weights to interpolate the model SSH to the observation point 
     1298 
     1299         zlam = surfdataqc%rlam(jobs) 
     1300         zphi = surfdataqc%rphi(jobs) 
     1301 
     1302         ! Get weights to interpolate the model value to the observation point 
    11921303         CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         & 
    11931304            &                   zglam(:,:,iobs), zgphi(:,:,iobs), & 
    11941305            &                   zmask(:,:,iobs), zweig, zobsmask ) 
    1195           
    1196  
    1197          ! Interpolate the model SSH to the observation point 
    1198          CALL obs_int_h2d( 1, 1,      & 
    1199             &              zweig, zsshl(:,:,iobs),  zext ) 
    1200           
    1201          sladatqc%rext(jobs,1) = zext(1) 
    1202          ! ... Remove the MDT at the observation point 
    1203          sladatqc%rmod(jobs,1) = sladatqc%rext(jobs,1) - sladatqc%rext(jobs,2) 
     1306 
     1307         ! Interpolate the model field to the observation point 
     1308         IF ( ldnightav .AND. idayend == 0 ) THEN 
     1309            ! Night-time averaged data 
     1310            CALL obs_int_h2d( 1, 1, zweig, zsurfm(:,:,iobs), zext ) 
     1311         ELSE 
     1312            CALL obs_int_h2d( 1, 1, zweig, zsurf(:,:,iobs),  zext ) 
     1313         ENDIF 
     1314 
     1315         IF ( TRIM(surfdataqc%cvars(1)) == 'SLA' .AND. surfdataqc%nextra == 2 ) THEN 
     1316            ! ... Remove the MDT from the SSH at the observation point to get the SLA 
     1317            surfdataqc%rext(jobs,1) = zext(1) 
     1318            surfdataqc%rmod(jobs,1) = surfdataqc%rext(jobs,1) - surfdataqc%rext(jobs,2) 
     1319         ELSE 
     1320            surfdataqc%rmod(jobs,1) = zext(1) 
     1321         ENDIF 
    12041322 
    12051323      END DO 
     
    12121330         & zgphi, & 
    12131331         & zmask, & 
    1214          & zsshl  & 
     1332         & zsurf  & 
    12151333         & ) 
    12161334 
    1217       sladatqc%nsurfup = sladatqc%nsurfup + isla 
    1218  
    1219    END SUBROUTINE obs_sla_opt 
    1220  
    1221    SUBROUTINE obs_sst_opt( sstdatqc, kt, kpi, kpj, kit000, kdaystp, & 
    1222       &                    psstn, psstmask, k2dint, ld_nightav ) 
    1223       !!----------------------------------------------------------------------- 
    1224       !! 
    1225       !!                     ***  ROUTINE obs_sst_opt  *** 
    1226       !! 
    1227       !! ** Purpose : Compute the model counterpart of surface temperature 
    1228       !!              data by interpolating from the model grid to the  
    1229       !!              observation point. 
    1230       !! 
    1231       !! ** Method  : Linearly interpolate to each observation point using  
    1232       !!              the model values at the corners of the surrounding grid box. 
    1233       !! 
    1234       !!    The now model SST is first computed at the obs (lon, lat) point. 
    1235       !! 
    1236       !!    Several horizontal interpolation schemes are available: 
    1237       !!        - distance-weighted (great circle) (k2dint = 0) 
    1238       !!        - distance-weighted (small angle)  (k2dint = 1) 
    1239       !!        - bilinear (geographical grid)     (k2dint = 2) 
    1240       !!        - bilinear (quadrilateral grid)    (k2dint = 3) 
    1241       !!        - polynomial (quadrilateral grid)  (k2dint = 4) 
    1242       !! 
    1243       !! 
    1244       !! ** Action  : 
    1245       !! 
    1246       !! History : 
    1247       !!        !  07-07  (S. Ricci ) : Original 
    1248       !!       
    1249       !!----------------------------------------------------------------------- 
    1250  
    1251       !! * Modules used 
    1252       USE obs_surf_def  ! Definition of storage space for surface observations 
    1253       USE sbcdcy 
    1254  
    1255       IMPLICIT NONE 
    1256  
    1257       !! * Arguments 
    1258       TYPE(obs_surf), INTENT(INOUT) :: & 
    1259          & sstdatqc     ! Subset of surface data not failing screening 
    1260       INTEGER, INTENT(IN) :: kt        ! Time step 
    1261       INTEGER, INTENT(IN) :: kpi       ! Model grid parameters 
    1262       INTEGER, INTENT(IN) :: kpj 
    1263       INTEGER, INTENT(IN) :: kit000    ! Number of the first time step  
    1264                                        !   (kit000-1 = restart time) 
    1265       INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header) 
    1266       INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day   
    1267       REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: & 
    1268          & psstn,  &    ! Model SST field 
    1269          & psstmask     ! Land-sea mask 
    1270  
    1271       !! * Local declarations 
    1272       INTEGER :: ji 
    1273       INTEGER :: jj 
    1274       INTEGER :: jobs 
    1275       INTEGER :: inrc 
    1276       INTEGER :: isst 
    1277       INTEGER :: iobs 
    1278       INTEGER :: idayend 
    1279       REAL(KIND=wp) :: zlam 
    1280       REAL(KIND=wp) :: zphi 
    1281       REAL(KIND=wp) :: zext(1), zobsmask(1) 
    1282       REAL(KIND=wp) :: zdaystp 
    1283       INTEGER, DIMENSION(:,:), SAVE, ALLOCATABLE :: & 
    1284          & icount_sstnight,      & 
    1285          & imask_night 
    1286       REAL(kind=wp), DIMENSION(:,:), SAVE, ALLOCATABLE :: & 
    1287          & zintmp, & 
    1288          & zouttmp, &  
    1289          & zmeanday    ! to compute model sst in region of 24h daylight (pole) 
    1290       REAL(kind=wp), DIMENSION(2,2,1) :: & 
    1291          & zweig 
    1292       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 
    1293          & zmask, & 
    1294          & zsstl, & 
    1295          & zsstm, & 
    1296          & zglam, & 
    1297          & zgphi 
    1298       INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: & 
    1299          & igrdi, & 
    1300          & igrdj 
    1301       LOGICAL, INTENT(IN) :: ld_nightav 
    1302  
    1303       !----------------------------------------------------------------------- 
    1304       ! Local initialization  
    1305       !----------------------------------------------------------------------- 
    1306       ! ... Record and data counters 
    1307       inrc = kt - kit000 + 2 
    1308       isst = sstdatqc%nsstp(inrc) 
    1309  
    1310       IF ( ld_nightav ) THEN 
    1311  
    1312       ! Initialize array for night mean 
    1313  
    1314       IF ( kt .EQ. 0 ) THEN 
    1315          ALLOCATE ( icount_sstnight(kpi,kpj) ) 
    1316          ALLOCATE ( imask_night(kpi,kpj) ) 
    1317          ALLOCATE ( zintmp(kpi,kpj) ) 
    1318          ALLOCATE ( zouttmp(kpi,kpj) ) 
    1319          ALLOCATE ( zmeanday(kpi,kpj) ) 
    1320          nday_qsr = -1   ! initialisation flag for nbc_dcy 
    1321       ENDIF 
    1322  
    1323       ! Initialize daily mean for first timestep 
    1324       idayend = MOD( kt - kit000 + 1, kdaystp ) 
    1325  
    1326       ! Added kt == 0 test to catch restart case  
    1327       IF ( idayend == 1 .OR. kt == 0) THEN 
    1328          IF (lwp) WRITE(numout,*) 'Reset sstdatqc%vdmean on time-step: ',kt 
    1329          DO jj = 1, jpj 
    1330             DO ji = 1, jpi 
    1331                sstdatqc%vdmean(ji,jj) = 0.0 
    1332                zmeanday(ji,jj) = 0.0 
    1333                icount_sstnight(ji,jj) = 0 
    1334             END DO 
    1335          END DO 
    1336       ENDIF 
    1337  
    1338       zintmp(:,:) = 0.0 
    1339       zouttmp(:,:) = sbc_dcy( zintmp(:,:), .TRUE. ) 
    1340       imask_night(:,:) = INT( zouttmp(:,:) ) 
    1341  
    1342       DO jj = 1, jpj 
    1343          DO ji = 1, jpi 
    1344             ! Increment the temperature field for computing night mean and counter 
    1345             sstdatqc%vdmean(ji,jj) = sstdatqc%vdmean(ji,jj)  & 
    1346                    &                        + psstn(ji,jj)*imask_night(ji,jj) 
    1347             zmeanday(ji,jj)        = zmeanday(ji,jj) + psstn(ji,jj) 
    1348             icount_sstnight(ji,jj) = icount_sstnight(ji,jj) + imask_night(ji,jj) 
    1349          END DO 
    1350       END DO 
    1351     
    1352       ! Compute the daily mean at the end of day 
    1353  
    1354       zdaystp = 1.0 / REAL( kdaystp ) 
    1355  
    1356       IF ( idayend == 0 ) THEN  
    1357          DO jj = 1, jpj 
    1358             DO ji = 1, jpi 
    1359                ! Test if "no night" point 
    1360                IF ( icount_sstnight(ji,jj) .NE. 0 ) THEN 
    1361                   sstdatqc%vdmean(ji,jj) = sstdatqc%vdmean(ji,jj) & 
    1362                     &                        / icount_sstnight(ji,jj)  
    1363                ELSE 
    1364                   sstdatqc%vdmean(ji,jj) = zmeanday(ji,jj) * zdaystp 
    1365                ENDIF 
    1366             END DO 
    1367          END DO 
    1368       ENDIF 
    1369  
    1370       ENDIF 
    1371  
    1372       ! Get the data for interpolation 
    1373        
    1374       ALLOCATE( & 
    1375          & igrdi(2,2,isst), & 
    1376          & igrdj(2,2,isst), & 
    1377          & zglam(2,2,isst), & 
    1378          & zgphi(2,2,isst), & 
    1379          & zmask(2,2,isst), & 
    1380          & zsstl(2,2,isst)  & 
    1381          & ) 
    1382        
    1383       DO jobs = sstdatqc%nsurfup + 1, sstdatqc%nsurfup + isst 
    1384          iobs = jobs - sstdatqc%nsurfup 
    1385          igrdi(1,1,iobs) = sstdatqc%mi(jobs)-1 
    1386          igrdj(1,1,iobs) = sstdatqc%mj(jobs)-1 
    1387          igrdi(1,2,iobs) = sstdatqc%mi(jobs)-1 
    1388          igrdj(1,2,iobs) = sstdatqc%mj(jobs) 
    1389          igrdi(2,1,iobs) = sstdatqc%mi(jobs) 
    1390          igrdj(2,1,iobs) = sstdatqc%mj(jobs)-1 
    1391          igrdi(2,2,iobs) = sstdatqc%mi(jobs) 
    1392          igrdj(2,2,iobs) = sstdatqc%mj(jobs) 
    1393       END DO 
    1394        
    1395       CALL obs_int_comm_2d( 2, 2, isst, & 
    1396          &                  igrdi, igrdj, glamt, zglam ) 
    1397       CALL obs_int_comm_2d( 2, 2, isst, & 
    1398          &                  igrdi, igrdj, gphit, zgphi ) 
    1399       CALL obs_int_comm_2d( 2, 2, isst, & 
    1400          &                  igrdi, igrdj, psstmask, zmask ) 
    1401       CALL obs_int_comm_2d( 2, 2, isst, & 
    1402          &                  igrdi, igrdj, psstn, zsstl ) 
    1403  
    1404       ! At the end of the day get interpolated means 
    1405       IF ( idayend == 0 .AND. ld_nightav ) THEN 
    1406  
    1407          ALLOCATE( & 
    1408             & zsstm(2,2,isst)  & 
    1409             & ) 
    1410  
    1411          CALL obs_int_comm_2d( 2, 2, isst, igrdi, igrdj, & 
    1412             &               sstdatqc%vdmean(:,:), zsstm ) 
    1413  
    1414       ENDIF 
    1415  
    1416       ! Loop over observations 
    1417  
    1418       DO jobs = sstdatqc%nsurfup + 1, sstdatqc%nsurfup + isst 
    1419           
    1420          iobs = jobs - sstdatqc%nsurfup 
    1421           
    1422          IF ( kt /= sstdatqc%mstp(jobs) ) THEN 
    1423              
    1424             IF(lwp) THEN 
    1425                WRITE(numout,*) 
    1426                WRITE(numout,*) ' E R R O R : Observation',              & 
    1427                   &            ' time step is not consistent with the', & 
    1428                   &            ' model time step' 
    1429                WRITE(numout,*) ' =========' 
    1430                WRITE(numout,*) 
    1431                WRITE(numout,*) ' Record  = ', jobs,                & 
    1432                   &            ' kt      = ', kt,                  & 
    1433                   &            ' mstp    = ', sstdatqc%mstp(jobs), & 
    1434                   &            ' ntyp    = ', sstdatqc%ntyp(jobs) 
    1435             ENDIF 
    1436             CALL ctl_stop( 'obs_sst_opt', 'Inconsistent time' ) 
    1437              
    1438          ENDIF 
    1439           
    1440          zlam = sstdatqc%rlam(jobs) 
    1441          zphi = sstdatqc%rphi(jobs) 
    1442           
    1443          ! Get weights to interpolate the model SST to the observation point 
    1444          CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         & 
    1445             &                   zglam(:,:,iobs), zgphi(:,:,iobs), & 
    1446             &                   zmask(:,:,iobs), zweig, zobsmask ) 
    1447              
    1448          ! Interpolate the model SST to the observation point  
    1449  
    1450          IF ( ld_nightav ) THEN 
    1451  
    1452            IF ( idayend == 0 )  THEN 
    1453                ! Daily averaged/diurnal cycle of SST  data 
    1454                CALL obs_int_h2d( 1, 1,      &  
    1455                      &              zweig, zsstm(:,:,iobs), zext ) 
    1456             ELSE  
    1457                CALL ctl_stop( ' ld_nightav is set to true: a nonzero' //     & 
    1458                      &           ' number of night SST data should' // & 
    1459                      &           ' only occur at the end of a given day' ) 
    1460             ENDIF 
    1461  
    1462          ELSE 
    1463  
    1464             CALL obs_int_h2d( 1, 1,      & 
    1465             &              zweig, zsstl(:,:,iobs),  zext ) 
    1466  
    1467          ENDIF 
    1468          sstdatqc%rmod(jobs,1) = zext(1) 
    1469           
    1470       END DO 
    1471        
    1472       ! Deallocate the data for interpolation 
    1473       DEALLOCATE( & 
    1474          & igrdi, & 
    1475          & igrdj, & 
    1476          & zglam, & 
    1477          & zgphi, & 
    1478          & zmask, & 
    1479          & zsstl  & 
    1480          & ) 
    1481  
    1482       ! At the end of the day also get interpolated means 
    1483       IF ( idayend == 0 .AND. ld_nightav ) THEN 
     1335      ! At the end of the day also deallocate night-time mean array 
     1336      IF ( idayend == 0 .AND. ldnightav ) THEN 
    14841337         DEALLOCATE( & 
    1485             & zsstm  & 
     1338            & zsurfm  & 
    14861339            & ) 
    14871340      ENDIF 
    1488        
    1489       sstdatqc%nsurfup = sstdatqc%nsurfup + isst 
    1490  
    1491    END SUBROUTINE obs_sst_opt 
    1492  
    1493    SUBROUTINE obs_sss_opt 
    1494       !!----------------------------------------------------------------------- 
    1495       !! 
    1496       !!                     ***  ROUTINE obs_sss_opt  *** 
    1497       !! 
    1498       !! ** Purpose : Compute the model counterpart of sea surface salinity 
    1499       !!              data by interpolating from the model grid to the  
    1500       !!              observation point. 
    1501       !! 
    1502       !! ** Method  :  
    1503       !! 
    1504       !! ** Action  : 
    1505       !! 
    1506       !! History : 
    1507       !!      ! ??-??  
    1508       !!----------------------------------------------------------------------- 
    1509  
    1510       IMPLICIT NONE 
    1511  
    1512    END SUBROUTINE obs_sss_opt 
    1513  
    1514    SUBROUTINE obs_seaice_opt( seaicedatqc, kt, kpi, kpj, kit000, & 
    1515       &                    pseaicen, pseaicemask, k2dint ) 
    1516  
    1517       !!----------------------------------------------------------------------- 
    1518       !! 
    1519       !!                     ***  ROUTINE obs_seaice_opt  *** 
    1520       !! 
    1521       !! ** Purpose : Compute the model counterpart of surface temperature 
    1522       !!              data by interpolating from the model grid to the  
    1523       !!              observation point. 
    1524       !! 
    1525       !! ** Method  : Linearly interpolate to each observation point using  
    1526       !!              the model values at the corners of the surrounding grid box. 
    1527       !! 
    1528       !!    The now model sea ice is first computed at the obs (lon, lat) point. 
    1529       !! 
    1530       !!    Several horizontal interpolation schemes are available: 
    1531       !!        - distance-weighted (great circle) (k2dint = 0) 
    1532       !!        - distance-weighted (small angle)  (k2dint = 1) 
    1533       !!        - bilinear (geographical grid)     (k2dint = 2) 
    1534       !!        - bilinear (quadrilateral grid)    (k2dint = 3) 
    1535       !!        - polynomial (quadrilateral grid)  (k2dint = 4) 
    1536       !! 
    1537       !! 
    1538       !! ** Action  : 
    1539       !! 
    1540       !! History : 
    1541       !!        !  07-07  (S. Ricci ) : Original 
    1542       !!       
    1543       !!----------------------------------------------------------------------- 
    1544  
    1545       !! * Modules used 
    1546       USE obs_surf_def  ! Definition of storage space for surface observations 
    1547  
    1548       IMPLICIT NONE 
    1549  
    1550       !! * Arguments 
    1551       TYPE(obs_surf), INTENT(INOUT) :: seaicedatqc     ! Subset of surface data not failing screening 
    1552       INTEGER, INTENT(IN) :: kt       ! Time step 
    1553       INTEGER, INTENT(IN) :: kpi      ! Model grid parameters 
    1554       INTEGER, INTENT(IN) :: kpj 
    1555       INTEGER, INTENT(IN) :: kit000   ! Number of the first time step  
    1556                                       !   (kit000-1 = restart time) 
    1557       INTEGER, INTENT(IN) :: k2dint   ! Horizontal interpolation type (see header) 
    1558       REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj) :: & 
    1559          & pseaicen,  &    ! Model sea ice field 
    1560          & pseaicemask     ! Land-sea mask 
    1561           
    1562       !! * Local declarations 
    1563       INTEGER :: ji 
    1564       INTEGER :: jj 
    1565       INTEGER :: jobs 
    1566       INTEGER :: inrc 
    1567       INTEGER :: iseaice 
    1568       INTEGER :: iobs 
    1569         
    1570       REAL(KIND=wp) :: zlam 
    1571       REAL(KIND=wp) :: zphi 
    1572       REAL(KIND=wp) :: zext(1), zobsmask(1) 
    1573       REAL(kind=wp), DIMENSION(2,2,1) :: & 
    1574          & zweig 
    1575       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 
    1576          & zmask, & 
    1577          & zseaicel, & 
    1578          & zglam, & 
    1579          & zgphi 
    1580       INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: & 
    1581          & igrdi, & 
    1582          & igrdj 
    1583  
    1584       !------------------------------------------------------------------------ 
    1585       ! Local initialization  
    1586       !------------------------------------------------------------------------ 
    1587       ! ... Record and data counters 
    1588       inrc = kt - kit000 + 2 
    1589       iseaice = seaicedatqc%nsstp(inrc) 
    1590  
    1591       ! Get the data for interpolation 
    1592        
    1593       ALLOCATE( & 
    1594          & igrdi(2,2,iseaice), & 
    1595          & igrdj(2,2,iseaice), & 
    1596          & zglam(2,2,iseaice), & 
    1597          & zgphi(2,2,iseaice), & 
    1598          & zmask(2,2,iseaice), & 
    1599          & zseaicel(2,2,iseaice)  & 
    1600          & ) 
    1601        
    1602       DO jobs = seaicedatqc%nsurfup + 1, seaicedatqc%nsurfup + iseaice 
    1603          iobs = jobs - seaicedatqc%nsurfup 
    1604          igrdi(1,1,iobs) = seaicedatqc%mi(jobs)-1 
    1605          igrdj(1,1,iobs) = seaicedatqc%mj(jobs)-1 
    1606          igrdi(1,2,iobs) = seaicedatqc%mi(jobs)-1 
    1607          igrdj(1,2,iobs) = seaicedatqc%mj(jobs) 
    1608          igrdi(2,1,iobs) = seaicedatqc%mi(jobs) 
    1609          igrdj(2,1,iobs) = seaicedatqc%mj(jobs)-1 
    1610          igrdi(2,2,iobs) = seaicedatqc%mi(jobs) 
    1611          igrdj(2,2,iobs) = seaicedatqc%mj(jobs) 
    1612       END DO 
    1613        
    1614       CALL obs_int_comm_2d( 2, 2, iseaice, & 
    1615          &                  igrdi, igrdj, glamt, zglam ) 
    1616       CALL obs_int_comm_2d( 2, 2, iseaice, & 
    1617          &                  igrdi, igrdj, gphit, zgphi ) 
    1618       CALL obs_int_comm_2d( 2, 2, iseaice, & 
    1619          &                  igrdi, igrdj, pseaicemask, zmask ) 
    1620       CALL obs_int_comm_2d( 2, 2, iseaice, & 
    1621          &                  igrdi, igrdj, pseaicen, zseaicel ) 
    1622        
    1623       DO jobs = seaicedatqc%nsurfup + 1, seaicedatqc%nsurfup + iseaice 
    1624           
    1625          iobs = jobs - seaicedatqc%nsurfup 
    1626           
    1627          IF ( kt /= seaicedatqc%mstp(jobs) ) THEN 
    1628              
    1629             IF(lwp) THEN 
    1630                WRITE(numout,*) 
    1631                WRITE(numout,*) ' E R R O R : Observation',              & 
    1632                   &            ' time step is not consistent with the', & 
    1633                   &            ' model time step' 
    1634                WRITE(numout,*) ' =========' 
    1635                WRITE(numout,*) 
    1636                WRITE(numout,*) ' Record  = ', jobs,                & 
    1637                   &            ' kt      = ', kt,                  & 
    1638                   &            ' mstp    = ', seaicedatqc%mstp(jobs), & 
    1639                   &            ' ntyp    = ', seaicedatqc%ntyp(jobs) 
    1640             ENDIF 
    1641             CALL ctl_stop( 'obs_seaice_opt', 'Inconsistent time' ) 
    1642              
    1643          ENDIF 
    1644           
    1645          zlam = seaicedatqc%rlam(jobs) 
    1646          zphi = seaicedatqc%rphi(jobs) 
    1647           
    1648          ! Get weights to interpolate the model sea ice to the observation point 
    1649          CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi,         & 
    1650             &                   zglam(:,:,iobs), zgphi(:,:,iobs), & 
    1651             &                   zmask(:,:,iobs), zweig, zobsmask ) 
    1652           
    1653          ! ... Interpolate the model sea ice to the observation point 
    1654          CALL obs_int_h2d( 1, 1,      & 
    1655             &              zweig, zseaicel(:,:,iobs),  zext ) 
    1656           
    1657          seaicedatqc%rmod(jobs,1) = zext(1) 
    1658           
    1659       END DO 
    1660        
    1661       ! Deallocate the data for interpolation 
    1662       DEALLOCATE( & 
    1663          & igrdi,    & 
    1664          & igrdj,    & 
    1665          & zglam,    & 
    1666          & zgphi,    & 
    1667          & zmask,    & 
    1668          & zseaicel  & 
    1669          & ) 
    1670        
    1671       seaicedatqc%nsurfup = seaicedatqc%nsurfup + iseaice 
    1672  
    1673    END SUBROUTINE obs_seaice_opt 
    1674  
    1675    SUBROUTINE obs_vel_opt( prodatqc, kt, kpi, kpj, kpk, kit000, kdaystp, & 
    1676       &                    pun, pvn, pgdept, pumask, pvmask, k1dint, k2dint, & 
    1677       &                    ld_dailyav ) 
    1678       !!----------------------------------------------------------------------- 
    1679       !! 
    1680       !!                     ***  ROUTINE obs_vel_opt  *** 
    1681       !! 
    1682       !! ** Purpose : Compute the model counterpart of velocity profile 
    1683       !!              data by interpolating from the model grid to the  
    1684       !!              observation point. 
    1685       !! 
    1686       !! ** Method  : Linearly interpolate zonal and meridional components of velocity  
    1687       !!              to each observation point using the model values at the corners of  
    1688       !!              the surrounding grid box. The model velocity components are on a  
    1689       !!              staggered C- grid. 
    1690       !! 
    1691       !!    For velocity data from the TAO array, the model equivalent is 
    1692       !!    a daily mean velocity field. So, we first compute 
    1693       !!    the mean, then interpolate only at the end of the day. 
    1694       !! 
    1695       !! ** Action  : 
    1696       !! 
    1697       !! History : 
    1698       !!    ! 07-03 (K. Mogensen)      : Temperature and Salinity profiles 
    1699       !!    ! 08-10 (Maria Valdivieso) : Velocity component (U,V) profiles 
    1700       !!----------------------------------------------------------------------- 
    1701      
    1702       !! * Modules used 
    1703       USE obs_profiles_def ! Definition of storage space for profile obs. 
    1704  
    1705       IMPLICIT NONE 
    1706  
    1707       !! * Arguments 
    1708       TYPE(obs_prof), INTENT(INOUT) :: & 
    1709          & prodatqc        ! Subset of profile data not failing screening 
    1710       INTEGER, INTENT(IN) :: kt        ! Time step 
    1711       INTEGER, INTENT(IN) :: kpi       ! Model grid parameters 
    1712       INTEGER, INTENT(IN) :: kpj 
    1713       INTEGER, INTENT(IN) :: kpk  
    1714       INTEGER, INTENT(IN) :: kit000    ! Number of the first time step  
    1715                                        !   (kit000-1 = restart time) 
    1716       INTEGER, INTENT(IN) :: k1dint    ! Vertical interpolation type (see header) 
    1717       INTEGER, INTENT(IN) :: k2dint    ! Horizontal interpolation type (see header) 
    1718       INTEGER, INTENT(IN) :: kdaystp   ! Number of time steps per day                     
    1719       REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj,kpk) :: & 
    1720          & pun,    &    ! Model zonal component of velocity 
    1721          & pvn,    &    ! Model meridional component of velocity 
    1722          & pumask, &    ! Land-sea mask 
    1723          & pvmask       ! Land-sea mask 
    1724       REAL(KIND=wp), INTENT(IN), DIMENSION(kpk) :: & 
    1725          & pgdept       ! Model array of depth levels 
    1726       LOGICAL, INTENT(IN) :: ld_dailyav 
    1727           
    1728       !! * Local declarations 
    1729       INTEGER :: ji 
    1730       INTEGER :: jj 
    1731       INTEGER :: jk 
    1732       INTEGER :: jobs 
    1733       INTEGER :: inrc 
    1734       INTEGER :: ipro 
    1735       INTEGER :: idayend 
    1736       INTEGER :: ista 
    1737       INTEGER :: iend 
    1738       INTEGER :: iobs 
    1739       INTEGER, DIMENSION(imaxavtypes) :: & 
    1740          & idailyavtypes 
    1741       REAL(KIND=wp) :: zlam 
    1742       REAL(KIND=wp) :: zphi 
    1743       REAL(KIND=wp) :: zdaystp 
    1744       REAL(KIND=wp), DIMENSION(kpk) :: & 
    1745          & zobsmasku, & 
    1746          & zobsmaskv, & 
    1747          & zobsmask,  & 
    1748          & zobsk,     & 
    1749          & zobs2k 
    1750       REAL(KIND=wp), DIMENSION(2,2,kpk) :: & 
    1751          & zweigu,zweigv 
    1752       REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE :: & 
    1753          & zumask, zvmask, & 
    1754          & zintu, & 
    1755          & zintv, & 
    1756          & zinmu, & 
    1757          & zinmv 
    1758       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 
    1759          & zglamu, zglamv, & 
    1760          & zgphiu, zgphiv 
    1761       INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: & 
    1762          & igrdiu, & 
    1763          & igrdju, & 
    1764          & igrdiv, & 
    1765          & igrdjv 
    1766  
    1767       !------------------------------------------------------------------------ 
    1768       ! Local initialization  
    1769       !------------------------------------------------------------------------ 
    1770       ! ... Record and data counters 
    1771       inrc = kt - kit000 + 2 
    1772       ipro = prodatqc%npstp(inrc) 
    1773  
    1774       ! Initialize daily mean for first timestep 
    1775       idayend = MOD( kt - kit000 + 1, kdaystp ) 
    1776  
    1777       ! Added kt == 0 test to catch restart case  
    1778       IF ( idayend == 1 .OR. kt == 0) THEN 
    1779          IF (lwp) WRITE(numout,*) 'Reset prodatqc%vdmean on time-step: ',kt 
    1780          prodatqc%vdmean(:,:,:,1) = 0.0 
    1781          prodatqc%vdmean(:,:,:,2) = 0.0 
    1782       ENDIF 
    1783  
    1784       ! Increment the zonal velocity field for computing daily mean 
    1785       prodatqc%vdmean(:,:,:,1) = prodatqc%vdmean(:,:,:,1) + pun(:,:,:) 
    1786       ! Increment the meridional velocity field for computing daily mean 
    1787       prodatqc%vdmean(:,:,:,2) = prodatqc%vdmean(:,:,:,2) + pvn(:,:,:) 
    1788     
    1789       ! Compute the daily mean at the end of day 
    1790       zdaystp = 1.0 / REAL( kdaystp ) 
    1791       IF ( idayend == 0 ) THEN 
    1792          prodatqc%vdmean(:,:,:,1) = prodatqc%vdmean(:,:,:,1) * zdaystp 
    1793          prodatqc%vdmean(:,:,:,2) = prodatqc%vdmean(:,:,:,2) * zdaystp 
    1794       ENDIF 
    1795  
    1796       ! Get the data for interpolation 
    1797       ALLOCATE( & 
    1798          & igrdiu(2,2,ipro),      & 
    1799          & igrdju(2,2,ipro),      & 
    1800          & igrdiv(2,2,ipro),      & 
    1801          & igrdjv(2,2,ipro),      & 
    1802          & zglamu(2,2,ipro), zglamv(2,2,ipro), & 
    1803          & zgphiu(2,2,ipro), zgphiv(2,2,ipro), & 
    1804          & zumask(2,2,kpk,ipro), zvmask(2,2,kpk,ipro), & 
    1805          & zintu(2,2,kpk,ipro),  & 
    1806          & zintv(2,2,kpk,ipro)   & 
    1807          & ) 
    1808  
    1809       DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro 
    1810          iobs = jobs - prodatqc%nprofup 
    1811          igrdiu(1,1,iobs) = prodatqc%mi(jobs,1)-1 
    1812          igrdju(1,1,iobs) = prodatqc%mj(jobs,1)-1 
    1813          igrdiu(1,2,iobs) = prodatqc%mi(jobs,1)-1 
    1814          igrdju(1,2,iobs) = prodatqc%mj(jobs,1) 
    1815          igrdiu(2,1,iobs) = prodatqc%mi(jobs,1) 
    1816          igrdju(2,1,iobs) = prodatqc%mj(jobs,1)-1 
    1817          igrdiu(2,2,iobs) = prodatqc%mi(jobs,1) 
    1818          igrdju(2,2,iobs) = prodatqc%mj(jobs,1) 
    1819          igrdiv(1,1,iobs) = prodatqc%mi(jobs,2)-1 
    1820          igrdjv(1,1,iobs) = prodatqc%mj(jobs,2)-1 
    1821          igrdiv(1,2,iobs) = prodatqc%mi(jobs,2)-1 
    1822          igrdjv(1,2,iobs) = prodatqc%mj(jobs,2) 
    1823          igrdiv(2,1,iobs) = prodatqc%mi(jobs,2) 
    1824          igrdjv(2,1,iobs) = prodatqc%mj(jobs,2)-1 
    1825          igrdiv(2,2,iobs) = prodatqc%mi(jobs,2) 
    1826          igrdjv(2,2,iobs) = prodatqc%mj(jobs,2) 
    1827       END DO 
    1828  
    1829       CALL obs_int_comm_2d( 2, 2, ipro, igrdiu, igrdju, glamu, zglamu ) 
    1830       CALL obs_int_comm_2d( 2, 2, ipro, igrdiu, igrdju, gphiu, zgphiu ) 
    1831       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiu, igrdju, pumask, zumask ) 
    1832       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiu, igrdju, pun, zintu ) 
    1833  
    1834       CALL obs_int_comm_2d( 2, 2, ipro, igrdiv, igrdjv, glamv, zglamv ) 
    1835       CALL obs_int_comm_2d( 2, 2, ipro, igrdiv, igrdjv, gphiv, zgphiv ) 
    1836       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiv, igrdjv, pvmask, zvmask ) 
    1837       CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiv, igrdjv, pvn, zintv ) 
    1838  
    1839       ! At the end of the day also get interpolated means 
    1840       IF ( idayend == 0 ) THEN 
    1841  
    1842          ALLOCATE( & 
    1843             & zinmu(2,2,kpk,ipro),  & 
    1844             & zinmv(2,2,kpk,ipro)   & 
    1845             & ) 
    1846  
    1847          CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiu, igrdju, & 
    1848             &                  prodatqc%vdmean(:,:,:,1), zinmu ) 
    1849          CALL obs_int_comm_3d( 2, 2, ipro, kpk, igrdiv, igrdjv, & 
    1850             &                  prodatqc%vdmean(:,:,:,2), zinmv ) 
    1851  
    1852       ENDIF 
    1853  
    1854 ! loop over observations 
    1855  
    1856       DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro 
    1857  
    1858          iobs = jobs - prodatqc%nprofup 
    1859  
    1860          IF ( kt /= prodatqc%mstp(jobs) ) THEN 
    1861              
    1862             IF(lwp) THEN 
    1863                WRITE(numout,*) 
    1864                WRITE(numout,*) ' E R R O R : Observation',              & 
    1865                   &            ' time step is not consistent with the', & 
    1866                   &            ' model time step' 
    1867                WRITE(numout,*) ' =========' 
    1868                WRITE(numout,*) 
    1869                WRITE(numout,*) ' Record  = ', jobs,                    & 
    1870                   &            ' kt      = ', kt,                      & 
    1871                   &            ' mstp    = ', prodatqc%mstp(jobs), & 
    1872                   &            ' ntyp    = ', prodatqc%ntyp(jobs) 
    1873             ENDIF 
    1874             CALL ctl_stop( 'obs_pro_opt', 'Inconsistent time' ) 
    1875          ENDIF 
    1876           
    1877          zlam = prodatqc%rlam(jobs) 
    1878          zphi = prodatqc%rphi(jobs) 
    1879  
    1880          ! Initialize observation masks 
    1881  
    1882          zobsmasku(:) = 0.0 
    1883          zobsmaskv(:) = 0.0 
    1884           
    1885          ! Horizontal weights and vertical mask 
    1886  
    1887          IF  ( prodatqc%npvend(jobs,1) > 0 ) THEN 
    1888  
    1889             CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     & 
    1890                &                   zglamu(:,:,iobs), zgphiu(:,:,iobs), & 
    1891                &                   zumask(:,:,:,iobs), zweigu, zobsmasku ) 
    1892  
    1893          ENDIF 
    1894  
    1895           
    1896          IF ( prodatqc%npvend(jobs,2) > 0 ) THEN 
    1897  
    1898             CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi,     & 
    1899                &                   zglamv(:,:,iobs), zgphiv(:,:,iobs), & 
    1900                &                   zvmask(:,:,:,iobs), zweigv, zobsmaskv ) 
    1901  
    1902          ENDIF 
    1903  
    1904          ! Ensure that the vertical mask on u and v are consistent. 
    1905  
    1906          zobsmask(:) = MIN( zobsmasku(:), zobsmaskv(:) ) 
    1907  
    1908          IF ( prodatqc%npvend(jobs,1) > 0 ) THEN 
    1909  
    1910             zobsk(:) = obfillflt 
    1911  
    1912        IF ( ld_dailyav ) THEN 
    1913  
    1914                IF ( idayend == 0 )  THEN 
    1915                    
    1916                   ! Daily averaged data 
    1917                    
    1918                   CALL obs_int_h2d( kpk, kpk,      & 
    1919                      &              zweigu, zinmu(:,:,:,iobs), zobsk ) 
    1920                    
    1921                    
    1922                ELSE 
    1923                 
    1924                   CALL ctl_stop( ' A nonzero' //     & 
    1925                      &           ' number of U profile data should' // & 
    1926                      &           ' only occur at the end of a given day' ) 
    1927  
    1928                ENDIF 
    1929            
    1930             ELSE  
    1931                 
    1932                ! Point data 
    1933  
    1934                CALL obs_int_h2d( kpk, kpk,      & 
    1935                   &              zweigu, zintu(:,:,:,iobs), zobsk ) 
    1936  
    1937             ENDIF 
    1938  
    1939             !------------------------------------------------------------- 
    1940             ! Compute vertical second-derivative of the interpolating  
    1941             ! polynomial at obs points 
    1942             !------------------------------------------------------------- 
    1943              
    1944             IF ( k1dint == 1 ) THEN 
    1945                CALL obs_int_z1d_spl( kpk, zobsk, zobs2k,   & 
    1946                   &                  pgdept, zobsmask ) 
    1947             ENDIF 
    1948              
    1949             !----------------------------------------------------------------- 
    1950             !  Vertical interpolation to the observation point 
    1951             !----------------------------------------------------------------- 
    1952             ista = prodatqc%npvsta(jobs,1) 
    1953             iend = prodatqc%npvend(jobs,1) 
    1954             CALL obs_int_z1d( kpk,                & 
    1955                & prodatqc%var(1)%mvk(ista:iend),  & 
    1956                & k1dint, iend - ista + 1,         & 
    1957                & prodatqc%var(1)%vdep(ista:iend), & 
    1958                & zobsk, zobs2k,                   & 
    1959                & prodatqc%var(1)%vmod(ista:iend), & 
    1960                & pgdept, zobsmask ) 
    1961  
    1962          ENDIF 
    1963  
    1964          IF ( prodatqc%npvend(jobs,2) > 0 ) THEN 
    1965  
    1966             zobsk(:) = obfillflt 
    1967  
    1968             IF ( ld_dailyav ) THEN 
    1969  
    1970                IF ( idayend == 0 )  THEN 
    1971  
    1972                   ! Daily averaged data 
    1973                    
    1974                   CALL obs_int_h2d( kpk, kpk,      & 
    1975                      &              zweigv, zinmv(:,:,:,iobs), zobsk ) 
    1976                    
    1977                ELSE 
    1978  
    1979                   CALL ctl_stop( ' A nonzero' //     & 
    1980                      &           ' number of V profile data should' // & 
    1981                      &           ' only occur at the end of a given day' ) 
    1982  
    1983                ENDIF 
    1984  
    1985             ELSE 
    1986                 
    1987                ! Point data 
    1988  
    1989                CALL obs_int_h2d( kpk, kpk,      & 
    1990                   &              zweigv, zintv(:,:,:,iobs), zobsk ) 
    1991  
    1992             ENDIF 
    1993  
    1994  
    1995             !------------------------------------------------------------- 
    1996             ! Compute vertical second-derivative of the interpolating  
    1997             ! polynomial at obs points 
    1998             !------------------------------------------------------------- 
    1999              
    2000             IF ( k1dint == 1 ) THEN 
    2001                CALL obs_int_z1d_spl( kpk, zobsk, zobs2k, & 
    2002                   &                  pgdept, zobsmask ) 
    2003             ENDIF 
    2004              
    2005             !---------------------------------------------------------------- 
    2006             !  Vertical interpolation to the observation point 
    2007             !---------------------------------------------------------------- 
    2008             ista = prodatqc%npvsta(jobs,2) 
    2009             iend = prodatqc%npvend(jobs,2) 
    2010             CALL obs_int_z1d( kpk, & 
    2011                & prodatqc%var(2)%mvk(ista:iend),& 
    2012                & k1dint, iend - ista + 1, & 
    2013                & prodatqc%var(2)%vdep(ista:iend),& 
    2014                & zobsk, zobs2k, & 
    2015                & prodatqc%var(2)%vmod(ista:iend),& 
    2016                & pgdept, zobsmask ) 
    2017  
    2018          ENDIF 
    2019  
    2020       END DO 
    2021   
    2022       ! Deallocate the data for interpolation 
    2023       DEALLOCATE( & 
    2024          & igrdiu, & 
    2025          & igrdju, & 
    2026          & igrdiv, & 
    2027          & igrdjv, & 
    2028          & zglamu, zglamv, & 
    2029          & zgphiu, zgphiv, & 
    2030          & zumask, zvmask, & 
    2031          & zintu, & 
    2032          & zintv  & 
    2033          & ) 
    2034       ! At the end of the day also get interpolated means 
    2035       IF ( idayend == 0 ) THEN 
    2036          DEALLOCATE( & 
    2037             & zinmu,  & 
    2038             & zinmv   & 
    2039             & ) 
    2040       ENDIF 
    2041  
    2042       prodatqc%nprofup = prodatqc%nprofup + ipro  
    2043        
    2044    END SUBROUTINE obs_vel_opt 
     1341 
     1342      surfdataqc%nsurfup = surfdataqc%nsurfup + isurf 
     1343 
     1344   END SUBROUTINE obs_surf_opt 
    20451345 
    20461346END MODULE obs_oper 
    2047  
Note: See TracChangeset for help on using the changeset viewer.