224
  225
  226
  227
  228      integer, intent(in)  :: ng, tile, model
  229      integer, intent(in)  :: LBi, UBi, LBj, UBj
  230 
  231      integer, intent(out) :: Mstr, Mend
  232
  233
  234
  235      integer :: i, ic, iobs, itrc
  236# ifdef SOLVE3D
  237      integer :: j, k
  238# endif
  239# ifdef DISTRIBUTE
  240      integer :: Ncollect
  241# endif
  242
  243      real(r8), parameter :: IniVal = 0.0_r8
  244 
  245      real(r8) :: angle
  246# ifdef BGQC
  247      real(r8) :: df1, df2, Thresh
  248# endif
  249      real(r8) :: misfit(Mobs), unvetted(Mobs)
  250      real(r8) :: uradial(Mobs), vradial(Mobs)
  251# ifndef VERIFICATION
  252      real(r8) :: uBgErr(Mobs), vBgErr(Mobs)
  253# endif
  254
  255      character (len=*), parameter :: MyFile =                          &
  256     &  __FILE__//", obs_operator"
  257 
  258# include "set_bounds.h"
  259
  260      sourcefile=myfile
  261
  262
  263
  264
  265
  266# ifdef WEAK_CONSTRAINT
  267
  268
  269
  270
  271
  272
  273      mstr=nstrobs(ng)
  274      mend=nendobs(ng)
  275# else
  276
  277
  278
  279
  280
  281
  282      mstr=1
  283      mend=nobs(ng)
  284# endif
  285
  286
  287
  288      DO iobs=mstr,mend
  289        unvetted(iobs)=inival
  290        obsvetting(iobs)=inival
  291      END DO
  292 
  293# ifndef I4DVAR_ANA_SENSITIVITY
  294
  295
  296
  297#  ifdef DISTRIBUTE
  298
  299
  300#  endif
  301
  302      IF (wrtnlmod(ng)) THEN
  303        DO iobs=mstr,mend
  304          nlmodval(iobs)=inival
  305#  ifndef VERIFICATION
  306          bgerr(iobs)=inival
  307          ubgerr(iobs)=inival
  308          vbgerr(iobs)=inival
  309#  endif
  310        END DO
  311 
  312#  ifdef BGQC
  313
  314
  315
  316
  317
  318        IF (bgqc_type(ng).eq.1) THEN          
  319          DO iobs=mstr,mend
  320            DO i=1,mstatevar
  321              IF (obstype(iobs).eq.obsstate2type(i)) THEN
  322                bgthresh(iobs)=s_bgqc(i,ng)
  323                EXIT
  324              END IF
  325            END DO
  326          END DO
  327        ELSE IF (bgqc_type(ng).eq.2) THEN     
  328          DO iobs=mstr,mend
  329            bgthresh(iobs)=bgqc_large         
  330            DO i=1,nprovenance(ng)
  331              IF (obsprov(iobs).eq.iprovenance(i,ng)) THEN
  332                bgthresh(iobs)=p_bgqc(i,ng)
  333                EXIT
  334              END IF
  335            END DO
  336          END DO
  337        END IF
  338#  endif
  339      END IF
  340 
  341#  if defined TLM_OBS && !defined SP4DVAR
  342      IF (wrttlmod(ng).or.wrtrpmod(ng)) THEN
  343        DO iobs=mstr,mend
  344          tlmodval(iobs)=inival
  345        END DO
  346      END IF
  347#  endif
  348# endif
  349
  350
  351
  352
  353
  354# ifndef I4DVAR_ANA_SENSITIVITY
  355
  356
  357      IF (wrtnlmod(ng).and.                                             &
  358     &    (fourdvar(ng)%ObsCount(isfsur).gt.0)) THEN
  359        CALL extract_obs2d (ng, 0, lm(ng)+1, 0, mm(ng)+1,               &
  360     &                      lbi, ubi, lbj, ubj,                         &
  361     &                      obsstate2type(isfsur),                      &
  362     &                      mobs, mstr, mend,                           &
  363     &                      rxmin(ng), rxmax(ng),                       &
  364     &                      rymin(ng), rymax(ng),                       &
  365     &                      time(ng), dt(ng),                           &
  366     &                      obstype, obsvetting,                        &
  367     &                      tobs, xobs, yobs,                           &
  368     &                      ocean(ng)%zeta(:,:,kout),                   &
  369#  ifdef MASKING
  370     &                      grid(ng)%rmask,                             &
  371#  endif
  372     &                      nlmodval)
  373#  ifndef VERIFICATION
  374
  375
  376
  377
  378        CALL extract_obs2d (ng, 0, lm(ng)+1, 0, mm(ng)+1,               &
  379     &                      lbi, ubi, lbj, ubj,                         &
  380     &                      obsstate2type(isfsur),                      &
  381     &                      mobs, mstr, mend,                           &
  382     &                      rxmin(ng), rxmax(ng),                       &
  383     &                      rymin(ng), rymax(ng),                       &
  384     &                      time(ng), dt(ng),                           &
  385     &                      obstype, obsvetting,                        &
  386     &                      tobs, xobs, yobs,                           &
  387     &                      ocean(ng)%e_zeta(:,:,1),                    &
  388#   ifdef MASKING
  389     &                      grid(ng)%rmask,                             &
  390#   endif
  391     &                      bgerr)
  392#  endif
  393      END IF
  394# endif
  395 
  396# ifdef TLM_OBS
  397
  398
  399
  400      IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                         &
  401     &    (fourdvar(ng)%ObsCount(isfsur).gt.0)) THEN
  402        CALL extract_obs2d (ng, 0, lm(ng)+1, 0, mm(ng)+1,               &
  403     &                      lbi, ubi, lbj, ubj,                         &
  404     &                      obsstate2type(isfsur),                      &
  405     &                      mobs, mstr, mend,                           &
  406     &                      rxmin(ng), rxmax(ng),                       &
  407     &                      rymin(ng), rymax(ng),                       &
  408     &                      time(ng), dt(ng),                           &
  409     &                      obstype, obsvetting,                        &
  410     &                      tobs, xobs, yobs,                           &
  411     &                      ocean(ng)%tl_zeta(:,:,kout),                &
  412#  ifdef MASKING
  413     &                      grid(ng)%rmask,                             &
  414#  endif
  415     &                      tlmodval)
  416      END IF
  417# endif
  418
  419
  420
  421
  422
  423# ifndef I4DVAR_ANA_SENSITIVITY
  424
  425
  426      IF (wrtnlmod(ng).and.                                             &
  427     &    (fourdvar(ng)%ObsCount(isubar).gt.0)) THEN
  428        CALL extract_obs2d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  429     &                      lbi, ubi, lbj, ubj,                         &
  430     &                      obsstate2type(isubar),                      &
  431     &                      mobs, mstr, mend,                           &
  432     &                      uxmin(ng), uxmax(ng),                       &
  433     &                      uymin(ng), uymax(ng),                       &
  434     &                      time(ng), dt(ng),                           &
  435     &                      obstype, obsvetting,                        &
  436     &                      tobs, xobs, yobs,                           &
  437     &                      ocean(ng)%ubar(:,:,kout),                   &
  438#  ifdef MASKING
  439     &                      grid(ng)%umask,                             &
  440#  endif
  441     &                      nlmodval)
  442 
  443#  ifndef VERIFICATION
  444
  445
  446
  447
  448        CALL extract_obs2d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  449     &                      lbi, ubi, lbj, ubj,                         &
  450     &                      obsstate2type(isubar),                      &
  451     &                      mobs, mstr, mend,                           &
  452     &                      uxmin(ng), uxmax(ng),                       &
  453     &                      uymin(ng), uymax(ng),                       &
  454     &                      time(ng), dt(ng),                           &
  455     &                      obstype, obsvetting,                        &
  456     &                      tobs, xobs, yobs,                           &
  457     &                      ocean(ng)%e_ubar(:,:,1),                    &
  458#   ifdef MASKING
  459     &                      grid(ng)%umask,                             &
  460#   endif
  461     &                      bgerr)
  462#  endif
  463      END IF
  464# endif
  465 
  466# ifdef TLM_OBS
  467
  468
  469
  470      IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                         &
  471     &    (fourdvar(ng)%ObsCount(isubar).gt.0)) THEN
  472        CALL extract_obs2d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  473     &                      lbi, ubi, lbj, ubj,                         &
  474     &                      obsstate2type(isubar),                      &
  475     &                      mobs, mstr, mend,                           &
  476     &                      uxmin(ng), uxmax(ng),                       &
  477     &                      uymin(ng), uymax(ng),                       &
  478     &                      time(ng), dt(ng),                           &
  479     &                      obstype, obsvetting,                        &
  480     &                      tobs, xobs, yobs,                           &
  481     &                      ocean(ng)%tl_ubar(:,:,kout),                &
  482#  ifdef MASKING
  483     &                      grid(ng)%umask,                             &
  484#  endif
  485     &                      tlmodval)
  486        END IF
  487# endif
  488
  489
  490
  491
  492
  493# ifndef I4DVAR_ANA_SENSITIVITY
  494
  495
  496      IF (wrtnlmod(ng).and.                                             &
  497     &    (fourdvar(ng)%ObsCount(isvbar).gt.0)) THEN
  498        CALL extract_obs2d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  499     &                      lbi, ubi, lbj, ubj,                         &
  500     &                      obsstate2type(isvbar),                      &
  501     &                      mobs, mstr, mend,                           &
  502     &                      vxmin(ng), vxmax(ng),                       &
  503     &                      vymin(ng), vymax(ng),                       &
  504     &                      time(ng), dt(ng),                           &
  505     &                      obstype, obsvetting,                        &
  506     &                      tobs, xobs, yobs,                           &
  507     &                      ocean(ng)%vbar(:,:,kout),                   &
  508#  ifdef MASKING
  509     &                      grid(ng)%vmask,                             &
  510#  endif
  511     &                      nlmodval)
  512 
  513#  ifndef VERIFICATION
  514
  515
  516
  517
  518        CALL extract_obs2d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  519     &                      lbi, ubi, lbj, ubj,                         &
  520     &                      obsstate2type(isvbar),                      &
  521     &                      mobs, mstr, mend,                           &
  522     &                      vxmin(ng), vxmax(ng),                       &
  523     &                      vymin(ng), vymax(ng),                       &
  524     &                      time(ng), dt(ng),                           &
  525     &                      obstype, obsvetting,                        &
  526     &                      tobs, xobs, yobs,                           &
  527     &                      ocean(ng)%e_vbar(:,:,1),                    &
  528#   ifdef MASKING
  529     &                      grid(ng)%vmask,                             &
  530#   endif
  531     &                      bgerr)
  532#  endif
  533      END IF
  534# endif
  535 
  536# ifdef TLM_OBS
  537
  538
  539
  540      IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                         &
  541     &    (fourdvar(ng)%ObsCount(isvbar).gt.0)) THEN
  542        CALL extract_obs2d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  543     &                      lbi, ubi, lbj, ubj,                         &
  544     &                      obsstate2type(isvbar),                      &
  545     &                      mobs, mstr, mend,                           &
  546     &                      vxmin(ng), vxmax(ng),                       &
  547     &                      vymin(ng), vymax(ng),                       &
  548     &                      time(ng), dt(ng),                           &
  549     &                      obstype, obsvetting,                        &
  550     &                      tobs, xobs, yobs,                           &
  551     &                      ocean(ng)%tl_vbar(:,:,kout),                &
  552#  ifdef MASKING
  553     &                      grid(ng)%vmask,                             &
  554#  endif
  555     &                      tlmodval)
  556      END IF
  557# endif
  558 
  559# ifdef SOLVE3D
  560
  561
  562
  563
  564
  565#  ifndef I4DVAR_ANA_SENSITIVITY
  566
  567
  568      IF (wrtnlmod(ng).and.                                             &
  569     &    (fourdvar(ng)%ObsCount(isuvel).gt.0)) THEN
  570        DO k=1,n(ng)
  571          DO j=jstr-1,jend+1
  572            DO i=istru-1,iend+1
  573              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i-1,j,k)+        &
  574     &                                    grid(ng)%z_r(i  ,j,k))
  575            END DO
  576          END DO
  577        END DO
  578        CALL extract_obs3d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  579     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  580     &                      obsstate2type(isuvel),                      &
  581     &                      mobs, mstr, mend,                           &
  582     &                      uxmin(ng), uxmax(ng),                       &
  583     &                      uymin(ng), uymax(ng),                       &
  584     &                      time(ng), dt(ng),                           &
  585     &                      obstype, obsvetting,                        &
  586     &                      tobs, xobs, yobs, zobs,                     &
  587     &                      ocean(ng)%u(:,:,:,nout),                    &
  588     &                      grid(ng)%z_v,                               &
  589#   ifdef MASKING
  590     &                      grid(ng)%umask,                             &
  591#   endif
  592     &                      nlmodval)
  593 
  594#   ifndef VERIFICATION
  595
  596
  597
  598
  599        CALL extract_obs3d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  600     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  601     &                      obsstate2type(isuvel),                      &
  602     &                      mobs, mstr, mend,                           &
  603     &                      uxmin(ng), uxmax(ng),                       &
  604     &                      uymin(ng), uymax(ng),                       &
  605     &                      time(ng), dt(ng),                           &
  606     &                      obstype,  obsvetting,                       &
  607     &                      tobs, xobs, yobs, zobs,                     &
  608     &                      ocean(ng)%e_u(:,:,:,1),                     &
  609     &                      grid(ng)%z_v,                               &
  610#    ifdef MASKING
  611     &                      grid(ng)%umask,                             &
  612#    endif
  613     &                      bgerr)
  614#   endif
  615      END IF
  616#  endif
  617 
  618#  ifdef TLM_OBS
  619
  620
  621
  622      IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                         &
  623     &    (fourdvar(ng)%ObsCount(isuvel).gt.0)) THEN
  624        DO k=1,n(ng)
  625          DO j=jstr-1,jend+1
  626            DO i=istru-1,iend+1
  627              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i-1,j,k)+        &
  628     &                                    grid(ng)%z_r(i  ,j,k))
  629            END DO
  630          END DO
  631        END DO
  632        CALL extract_obs3d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  633     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  634     &                      obsstate2type(isuvel),                      &
  635     &                      mobs, mstr, mend,                           &
  636     &                      uxmin(ng), uxmax(ng),                       &
  637     &                      uymin(ng), uymax(ng),                       &
  638     &                      time(ng), dt(ng),                           &
  639     &                      obstype, obsvetting,                        &
  640     &                      tobs, xobs, yobs, zobs,                     &
  641     &                      ocean(ng)%tl_u(:,:,:,nout),                 &
  642     &                      grid(ng)%z_v,                               &
  643#   ifdef MASKING
  644     &                      grid(ng)%umask,                             &
  645#   endif
  646     &                      tlmodval)
  647      END IF
  648#  endif
  649
  650
  651
  652
  653
  654#  ifndef I4DVAR_ANA_SENSITIVITY
  655
  656
  657      IF (wrtnlmod(ng).and.                                             &
  658     &    (fourdvar(ng)%ObsCount(isvvel).gt.0)) THEN
  659        DO k=1,n(ng)
  660          DO j=jstrv-1,jend+1
  661            DO i=istr-1,iend+1
  662              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i,j-1,k)+        &
  663     &                                    grid(ng)%z_r(i,j  ,k))
  664            END DO
  665          END DO
  666        END DO
  667        CALL extract_obs3d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  668     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  669     &                      obsstate2type(isvvel),                      &
  670     &                      mobs, mstr, mend,                           &
  671     &                      vxmin(ng), vxmax(ng),                       &
  672     &                      vymin(ng), vymax(ng),                       &
  673     &                      time(ng), dt(ng),                           &
  674     &                      obstype, obsvetting,                        &
  675     &                      tobs, xobs, yobs, zobs,                     &
  676     &                      ocean(ng)%v(:,:,:,nout),                    &
  677     &                      grid(ng)%z_v,                               &
  678#   ifdef MASKING
  679     &                      grid(ng)%vmask,                             &
  680#   endif
  681     &                      nlmodval)
  682 
  683#   ifndef VERIFICATION
  684
  685
  686
  687
  688        CALL extract_obs3d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  689     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  690     &                      obsstate2type(isvvel),                      &
  691     &                      mobs, mstr, mend,                           &
  692     &                      vxmin(ng), vxmax(ng),                       &
  693     &                      vymin(ng), vymax(ng),                       &
  694     &                      time(ng), dt(ng),                           &
  695     &                      obstype, obsvetting,                        &
  696     &                      tobs, xobs, yobs, zobs,                     &
  697     &                      ocean(ng)%e_v(:,:,:,1),                     &
  698     &                      grid(ng)%z_v,                               &
  699#    ifdef MASKING
  700     &                      grid(ng)%vmask,                             &
  701#    endif
  702     &                      bgerr)
  703#   endif
  704      END IF
  705#  endif
  706 
  707#  ifdef TLM_OBS
  708
  709
  710
  711      IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                         &
  712     &    (fourdvar(ng)%ObsCount(isvvel).gt.0)) THEN
  713        DO k=1,n(ng)
  714          DO j=jstrv-1,jend+1
  715            DO i=istr-1,iend+1
  716              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i,j-1,k)+        &
  717     &                                    grid(ng)%z_r(i,j  ,k))
  718            END DO
  719          END DO
  720        END DO
  721        CALL extract_obs3d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  722     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  723     &                      obsstate2type(isvvel),                      &
  724     &                      mobs, mstr, mend,                           &
  725     &                      vxmin(ng), vxmax(ng),                       &
  726     &                      vymin(ng), vymax(ng),                       &
  727     &                      time(ng), dt(ng),                           &
  728     &                      obstype, obsvetting,                        &
  729     &                      tobs, xobs, yobs, zobs,                     &
  730     &                      ocean(ng)%tl_v(:,:,:,nout),                 &
  731     &                      grid(ng)%z_v,                               &
  732#   ifdef MASKING
  733     &                      grid(ng)%vmask,                             &
  734#   endif
  735     &                      tlmodval)
  736      END IF
  737#  endif
  738
  739
  740
  741
  742
  743#  ifdef RADIAL_ANGLE_CCW_EAST
  744
  745
  746
  747
  748
  749
  750
  751#  else
  752
  753
  754
  755
  756
  757
  758
  759#  endif
  760
  761
  762#  ifndef I4DVAR_ANA_SENSITIVITY
  763      IF (wrtnlmod(ng).and.                                             &
  764     &    (fourdvar(ng)%ObsCount(isradial).gt.0)) THEN
  765        DO iobs=mstr,mend
  766          uradial(iobs)=inival
  767          vradial(iobs)=inival
  768        END DO
  769 
  770#   ifdef CURVGRID
  771
  772
  773
  774
  775        CALL extract_obs2d (ng, 0, lm(ng)+1, 0, mm(ng)+1,               &
  776     &                      lbi, ubi, lbj, ubj,                         &
  777     &                      obsstate2type(isradial),                    &
  778     &                      mobs, mstr, mend,                           &
  779     &                      rxmin(ng), rxmax(ng),                       &
  780     &                      rymin(ng), rymax(ng),                       &
  781     &                      time(ng), dt(ng),                           &
  782     &                      obstype, obsvetting,                        &
  783     &                      tobs, xobs, yobs,                           &
  784     &                      grid(ng)%angler,                            &
  785#    ifdef MASKING
  786     &                      grid(ng)%rmask,                             &
  787#    endif
  788     &                      obsangler)
  789#   endif
  790
  791
  792
  793        DO k=1,n(ng)
  794          DO j=jstr-1,jend+1
  795            DO i=istru-1,iend+1
  796              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i-1,j,k)+        &
  797     &                                    grid(ng)%z_r(i  ,j,k))
  798            END DO
  799          END DO
  800        END DO
  801        CALL extract_obs3d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  802     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  803     &                      obsstate2type(isradial),                    &
  804     &                      mobs, mstr, mend,                           &
  805     &                      uxmin(ng), uxmax(ng),                       &
  806     &                      uymin(ng), uymax(ng),                       &
  807     &                      time(ng), dt(ng),                           &
  808     &                      obstype,  obsvetting,                       &
  809     &                      tobs, xobs, yobs, zobs,                     &
  810     &                      ocean(ng)%u(:,:,:,nout),                    &
  811     &                      grid(ng)%z_v,                               &
  812#   ifdef MASKING
  813     &                      grid(ng)%umask,                             &
  814#   endif
  815     &                      uradial)
  816 
  817#   ifndef VERIFICATION
  818
  819
  820
  821
  822        CALL extract_obs3d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  823     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  824     &                      obsstate2type(isradial),                    &
  825     &                      mobs, mstr, mend,                           &
  826     &                      uxmin(ng), uxmax(ng),                       &
  827     &                      uymin(ng), uymax(ng),                       &
  828     &                      time(ng), dt(ng),                           &
  829     &                      obstype, obsvetting,                        &
  830     &                      tobs, xobs, yobs, zobs,                     &
  831     &                      ocean(ng)%e_u(:,:,:,1),                     &
  832     &                      grid(ng)%z_v,                               &
  833#    ifdef MASKING
  834     &                      grid(ng)%umask,                             &
  835#    endif
  836     &                      ubgerr)
  837#   endif
  838
  839
  840
  841        DO k=1,n(ng)
  842          DO j=jstrv-1,jend+1
  843            DO i=istr-1,iend+1
  844              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i,j-1,k)+        &
  845     &                                    grid(ng)%z_r(i,j  ,k))
  846            END DO
  847          END DO
  848        END DO
  849        CALL extract_obs3d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  850     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  851     &                      obsstate2type(isradial),                    &
  852     &                      mobs, mstr, mend,                           &
  853     &                      vxmin(ng), vxmax(ng),                       &
  854     &                      vymin(ng), vymax(ng),                       &
  855     &                      time(ng), dt(ng),                           &
  856     &                      obstype, obsvetting,                        &
  857     &                      tobs, xobs, yobs, zobs,                     &
  858     &                      ocean(ng)%v(:,:,:,nout),                    &
  859     &                      grid(ng)%z_v,                               &
  860#   ifdef MASKING
  861     &                      grid(ng)%vmask,                             &
  862#   endif
  863     &                      vradial)
  864 
  865#   ifndef VERIFICATION
  866
  867
  868
  869
  870        CALL extract_obs3d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  871     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  872     &                      obsstate2type(isradial),                    &
  873     &                      mobs, mstr, mend,                           &
  874     &                      vxmin(ng), vxmax(ng),                       &
  875     &                      vymin(ng), vymax(ng),                       &
  876     &                      time(ng), dt(ng),                           &
  877     &                      obstype, obsvetting,                        &
  878     &                      tobs, xobs, yobs, zobs,                     &
  879     &                      ocean(ng)%e_v(:,:,:,1),                     &
  880     &                      grid(ng)%z_v,                               &
  881#    ifdef MASKING
  882     &                      grid(ng)%vmask,                             &
  883#    endif
  884     &                      vbgerr)
  885#   endif
  886
  887
  888
  889        DO iobs=mstr,mend
  890          IF (obstype(iobs).eq.obsstate2type(isradial)) THEN
  891#   ifdef RADIAL_ANGLE_CCW_EAST
  892#    ifdef CURVGRID
  893            angle=obsmeta(iobs)-obsangler(iobs)
  894            nlmodval(iobs)=uradial(iobs)*cos(angle)+                    &
  895     &                     vradial(iobs)*sin(angle)
  896#    else
  897            nlmodval(iobs)=uradial(iobs)*cos(obsmeta(iobs))+            &
  898     &                     vradial(iobs)*sin(obsmeta(iobs))
  899#    endif
  900#   else
  901#    ifdef CURVGRID
  902            angle=obsmeta(iobs)+obsangler(iobs)
  903            nlmodval(iobs)=uradial(iobs)*sin(angle)+                    &
  904     &                     vradial(iobs)*cos(angle)
  905#    else
  906            nlmodval(iobs)=uradial(iobs)*sin(obsmeta(iobs))+            &
  907     &                     vradial(iobs)*cos(obsmeta(iobs))
  908#    endif
  909#   endif
  910#   ifndef VERIFICATION
  911            bgerr(iobs)=max(ubgerr(iobs), vbgerr(iobs))
  912#   endif
  913          END IF
  914        END DO
  915      END IF
  916#  endif
  917 
  918#  ifdef TLM_OBS
  919
  920
  921
  922      IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                         &
  923     &    (fourdvar(ng)%ObsCount(isradial).gt.0)) THEN
  924        DO iobs=mstr,mend
  925          uradial(iobs)=inival
  926          vradial(iobs)=inival
  927        END DO
  928 
  929#   ifdef CURVGRID
  930
  931
  932
  933
  934        CALL extract_obs2d (ng, 0, lm(ng)+1, 0, mm(ng)+1,               &
  935     &                      lbi, ubi, lbj, ubj,                         &
  936     &                      obsstate2type(isradial),                    &
  937     &                      mobs, mstr, mend,                           &
  938     &                      rxmin(ng), rxmax(ng),                       &
  939     &                      rymin(ng), rymax(ng),                       &
  940     &                      time(ng), dt(ng),                           &
  941     &                      obstype, obsvetting,                        &
  942     &                      tobs, xobs, yobs,                           &
  943     &                      grid(ng)%angler,                            &
  944#    ifdef MASKING
  945     &                      grid(ng)%rmask,                             &
  946#    endif
  947     &                      obsangler)
  948#   endif
  949
  950
  951
  952        DO k=1,n(ng)
  953          DO j=jstr-1,jend+1
  954            DO i=istru-1,iend+1
  955              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i-1,j,k)+        &
  956     &                                    grid(ng)%z_r(i  ,j,k))
  957            END DO
  958          END DO
  959        END DO
  960        CALL extract_obs3d (ng, 1, lm(ng)+1, 0, mm(ng)+1,               &
  961     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  962     &                      obsstate2type(isradial),                    &
  963     &                      mobs, mstr, mend,                           &
  964     &                      uxmin(ng), uxmax(ng),                       &
  965     &                      uymin(ng), uymax(ng),                       &
  966     &                      time(ng), dt(ng),                           &
  967     &                      obstype,  obsvetting,                       &
  968     &                      tobs, xobs, yobs, zobs,                     &
  969     &                      ocean(ng)%tl_u(:,:,:,nout),                 &
  970     &                      grid(ng)%z_v,                               &
  971#   ifdef MASKING
  972     &                      grid(ng)%umask,                             &
  973#   endif
  974     &                      uradial)
  975
  976
  977
  978        DO k=1,n(ng)
  979          DO j=jstrv-1,jend+1
  980            DO i=istr-1,iend+1
  981              grid(ng)%z_v(i,j,k)=0.5_r8*(grid(ng)%z_r(i,j-1,k)+        &
  982     &                                    grid(ng)%z_r(i,j  ,k))
  983            END DO
  984          END DO
  985        END DO
  986        CALL extract_obs3d (ng, 0, lm(ng)+1, 1, mm(ng)+1,               &
  987     &                      lbi, ubi, lbj, ubj, 1, n(ng),               &
  988     &                      obsstate2type(isradial),                    &
  989     &                      mobs, mstr, mend,                           &
  990     &                      vxmin(ng), vxmax(ng),                       &
  991     &                      vymin(ng), vymax(ng),                       &
  992     &                      time(ng), dt(ng),                           &
  993     &                      obstype, obsvetting,                        &
  994     &                      tobs, xobs, yobs, zobs,                     &
  995     &                      ocean(ng)%tl_v(:,:,:,nout),                 &
  996     &                      grid(ng)%z_v,                               &
  997#   ifdef MASKING
  998     &                      grid(ng)%vmask,                             &
  999#   endif
 1000     &                      vradial)
 1001
 1002
 1003
 1004        DO iobs=mstr,mend
 1005          IF (obstype(iobs).eq.obsstate2type(isradial)) THEN
 1006#   ifdef RADIAL_ANGLE_CCW_EAST
 1007#    ifdef CURVGRID
 1008            angle=obsmeta(iobs)-obsangler(iobs)
 1009            tlmodval(iobs)=uradial(iobs)*cos(angle)+                    &
 1010     &                     vradial(iobs)*sin(angle)
 1011#    else
 1012            tlmodval(iobs)=uradial(iobs)*cos(obsmeta(iobs))+            &
 1013     &                     vradial(iobs)*sin(obsmeta(iobs))
 1014#    endif
 1015#   else
 1016#    ifdef CURVGRID
 1017            angle=obsmeta(iobs)+obsangler(iobs)
 1018            tlmodval(iobs)=uradial(iobs)*sin(angle)+                    &
 1019     &                     vradial(iobs)*cos(angle)
 1020#    else
 1021            tlmodval(iobs)=uradial(iobs)*sin(obsmeta(iobs))+            &
 1022     &                     vradial(iobs)*cos(obsmeta(iobs))
 1023#    endif
 1024#   endif
 1025          END IF
 1026        END DO
 1027      END IF
 1028#  endif
 1029
 1030
 1031
 1032
 1033
 1034      DO itrc=1,nt(ng)
 1035 
 1036#  ifndef I4DVAR_ANA_SENSITIVITY
 1037
 1038
 1039 
 1040        IF (wrtnlmod(ng).and.                                           &
 1041     &      (fourdvar(ng)%ObsCount(istvar(itrc)).gt.0)) THEN
 1042          CALL extract_obs3d (ng, 0, lm(ng)+1, 0, mm(ng)+1,             &
 1043     &                        lbi, ubi, lbj, ubj, 1, n(ng),             &
 1044     &                        obsstate2type(istvar(itrc)),              &
 1045     &                        mobs, mstr, mend,                         &
 1046     &                        rxmin(ng), rxmax(ng),                     &
 1047     &                        rymin(ng), rymax(ng),                     &
 1048     &                        time(ng), dt(ng),                         &
 1049     &                        obstype, obsvetting,                      &
 1050     &                        tobs, xobs, yobs, zobs,                   &
 1051     &                        ocean(ng)%t(:,:,:,nout,itrc),             &
 1052     &                        grid(ng)%z_r,                             &
 1053#   ifdef MASKING
 1054     &                        grid(ng)%rmask,                           &
 1055#   endif
 1056     &                        nlmodval)
 1057 
 1058#   ifndef VERIFICATION
 1059
 1060
 1061
 1062          CALL extract_obs3d (ng, 0, lm(ng)+1, 0, mm(ng)+1,             &
 1063     &                        lbi, ubi, lbj, ubj, 1, n(ng),             &
 1064     &                        obsstate2type(istvar(itrc)),              &
 1065     &                        mobs, mstr, mend,                         &
 1066     &                        rxmin(ng), rxmax(ng),                     &
 1067     &                        rymin(ng), rymax(ng),                     &
 1068     &                        time(ng), dt(ng),                         &
 1069     &                        obstype, obsvetting,                      &
 1070     &                        tobs, xobs, yobs, zobs,                   &
 1071     &                        ocean(ng)%e_t(:,:,:,1,itrc),              &
 1072     &                        grid(ng)%z_r,                             &
 1073#    ifdef MASKING
 1074     &                        grid(ng)%rmask,                           &
 1075#    endif
 1076     &                        bgerr)
 1077#   endif
 1078        END IF
 1079#  endif
 1080 
 1081#  ifdef TLM_OBS
 1082
 1083
 1084
 1085        IF ((wrttlmod(ng).or.(wrtrpmod(ng))).and.                       &
 1086     &      (fourdvar(ng)%ObsCount(istvar(itrc)).gt.0)) THEN
 1087          CALL extract_obs3d (ng, 0, lm(ng)+1, 0, mm(ng)+1,             &
 1088     &                        lbi, ubi, lbj, ubj, 1, n(ng),             &
 1089     &                        obsstate2type(istvar(itrc)),              &
 1090     &                        mobs, mstr, mend,                         &
 1091     &                        rxmin(ng), rxmax(ng),                     &
 1092     &                        rymin(ng), rymax(ng),                     &
 1093     &                        time(ng), dt(ng),                         &
 1094     &                        obstype, obsvetting,                      &
 1095     &                        tobs, xobs, yobs, zobs,                   &
 1096     &                        ocean(ng)%tl_t(:,:,:,nout,itrc),          &
 1097     &                        grid(ng)%z_r,                             &
 1098#   ifdef MASKING
 1099     &                        grid(ng)%rmask,                           &
 1100#   endif
 1101     &                        tlmodval)
 1102        END IF
 1103#  endif
 1104      END DO
 1105# endif
 1106
 1107
 1108
 1109
 1110
 1111
 1112
 1113
 1114
 1115      IF (wrtobsscale(ng).and.wrtnlmod(ng)) THEN
 1116        DO iobs=mstr,mend
 1117          obsscale(iobs)=obsvetting(iobs)
 1118        END DO
 1119      END IF
 1120 
 1121# if defined BGQC && !defined I4DVAR_ANA_SENSITIVITY
 1122
 1123
 1124
 1125
 1126
 1127
 1128
 1129      IF (wrtobsscale(ng).and.wrtnlmod(ng)) THEN
 1130        DO iobs=mstr,mend
 1131          IF (obsscale(iobs).ne.inival) THEN
 1132#  if defined I4DVAR
 1133            df1=(obsval(iobs)-nlmodval(iobs))/bgerr(iobs)
 1134            df2=(1.0_r8/obserr(iobs))/(bgerr(iobs)*bgerr(iobs))
 1135#  elif defined WEAK_CONSTRAINT
 1136#    ifdef R4DVAR
 1137            df1=(obsval(iobs)-tlmodval(iobs))/bgerr(iobs)
 1138            df2=obserr(iobs)/(bgerr(iobs)*bgerr(iobs))
 1139#    else
 1140            df1=(obsval(iobs)-nlmodval(iobs))/bgerr(iobs)
 1141            df2=obserr(iobs)/(bgerr(iobs)*bgerr(iobs))
 1142#    endif
 1143#  endif
 1144            thresh=bgthresh(iobs)*(1.0_r8+df2)
 1145            IF (df1*df1.gt.thresh) THEN
 1146              obsscale(iobs)=0.0_r8
 1147            END IF
 1148          END IF
 1149        END DO
 1150      END IF
 1151# endif
 1152 
 1153# ifdef DISTRIBUTE
 1154
 1155
 1156
 1157
 1158
 1159#  ifdef WEAK_CONSTRAINT
 1160      ncollect=mend-mstr+1
 1161#  else
 1162      ncollect=mobs
 1163#  endif
 1164      IF (wrtobsscale(ng).and.wrtnlmod(ng)) THEN
 1165        CALL mp_collect (ng, model, ncollect, inival,                   &
 1166#  ifdef WEAK_CONSTRAINT
 1167     &                   obsscale(mstr:))
 1168#  else
 1169     &                   obsscale)
 1170#  endif
 1171      END IF
 1172# endif
 1173 
 1174# ifndef WEAK_CONSTRAINT
 1175
 1176
 1177
 1178
 1179
 1180
 1181
 1182
 1183
 1184
 1185
 1186
 1187
 1188
 1189      IF (wrtobsscale(ng).and.wrtnlmod(ng)) THEN
 1190        ic=0
 1191        DO iobs=nstrobs(ng),nendobs(ng)
 1192          ic=ic+1
 1193          obsscaleglobal(iobs)=obsscale(ic)
 1194        END DO
 1195      ELSE
 1196        ic=0
 1197        DO iobs=nstrobs(ng),nendobs(ng)
 1198          ic=ic+1
 1199          obsscale(ic)=obsscaleglobal(iobs)
 1200        END DO
 1201      END IF
 1202# endif
 1203
 1204
 1205
 1206
 1207
 1208
 1209
 1210
 1211
 1212
 1213      IF (wrtnlmod(ng)) THEN
 1214        DO iobs=mstr,mend
 1215          unvetted(iobs)=nlmodval(iobs)
 1216          nlmodval(iobs)=obsscale(iobs)*nlmodval(iobs)
 1217        END DO
 1218      END IF
 1219 
 1220# ifdef TLM_OBS
 1221
 1222
 1223
 1224      IF (wrttlmod(ng).or.wrtrpmod(ng)) THEN
 1225        DO iobs=mstr,mend
 1226#  ifdef I4DVAR_ANA_SENSITIVITY
 1227          tlmodval(iobs)=obsscale(iobs)*tlmodval(iobs)*obserr(iobs)
 1228#  else
 1229          tlmodval(iobs)=obsscale(iobs)*tlmodval(iobs)
 1230#  endif
 1231        END DO
 1232      END IF
 1233# endif
 1234 
 1235# ifdef DISTRIBUTE
 1236
 1237
 1238
 1239
 1240
 1241#  ifndef I4DVAR_ANA_SENSITIVITY
 1242
 1243
 1244
 1245      IF (wrtnlmod(ng)) THEN
 1246        CALL mp_collect (ng, model, ncollect, inival,                   &
 1247#   if defined WEAK_CONSTRAINT
 1248     &                   nlmodval(mstr:))
 1249#   else
 1250     &                   nlmodval)
 1251#   endif
 1252
 1253        CALL mp_collect (ng, model, ncollect, inival,                   &
 1254#   if defined WEAK_CONSTRAINT
 1255     &                   unvetted(mstr:))
 1256#   else
 1257     &                   unvetted)
 1258#   endif
 1259      END IF
 1260 
 1261#   ifndef VERIFICATION
 1262
 1263
 1264
 1265      IF (wrtobsscale(ng).and.wrtnlmod(ng)) THEN
 1266        CALL mp_collect (ng, model, ncollect, inival,                   &
 1267#    if defined WEAK_CONSTRAINT
 1268     &                   bgerr(mstr:))
 1269#    else
 1270     &                   bgerr)
 1271#    endif
 1272      END IF
 1273#   endif
 1274#  endif
 1275 
 1276#  ifdef TLM_OBS
 1277
 1278
 1279
 1280      IF (wrttlmod(ng).or.wrtrpmod(ng)) THEN
 1281        CALL mp_collect (ng, model, ncollect, inival,                   &
 1282#   if defined WEAK_CONSTRAINT
 1283     &                   tlmodval(mstr:))
 1284#   else
 1285     &                   tlmodval)
 1286#   endif
 1287      END IF
 1288#  endif
 1289 
 1290#  ifdef SOLVE3D
 1291
 1292
 1293
 1294      IF (load_zobs(ng)) THEN
 1295        CALL mp_collect (ng, model, ncollect, inival,                   &
 1296#   ifdef WEAK_CONSTRAINT
 1297     &                   zobs(mstr:))
 1298#   else
 1299     &                   zobs)
 1300#   endif
 1301      END IF
 1302#  endif
 1303# endif
 1304 
 1305      RETURN