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 8667 for branches/2017/dev_r8657_UKMO_OBSoper/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prep.F90 – NEMO

Ignore:
Timestamp:
2017-10-30T10:28:45+01:00 (6 years ago)
Author:
timgraham
Message:

Update of OBS code from local v3.6 branch to head of trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2017/dev_r8657_UKMO_OBSoper/NEMOGCM/NEMO/OPA_SRC/OBS/obs_prep.F90

    r7646 r8667  
    2323   USE obs_oper           ! Observation operators 
    2424   USE lib_mpp, ONLY :   ctl_warn, ctl_stop 
     25   USE bdy_oce, ONLY : &        ! Boundary information 
     26      idx_bdy, nb_bdy, ln_bdy 
    2527 
    2628   IMPLICIT NONE 
     
    4042CONTAINS 
    4143 
    42    SUBROUTINE obs_pre_surf( surfdata, surfdataqc, ld_nea ) 
     44   SUBROUTINE obs_pre_surf( surfdata, surfdataqc, ld_nea, ld_bound_reject, & 
     45                            kqc_cutoff ) 
    4346      !!---------------------------------------------------------------------- 
    4447      !!                    ***  ROUTINE obs_pre_sla  *** 
     
    5760      !!        !  2015-02  (M. Martin) Combined routine for surface types. 
    5861      !!---------------------------------------------------------------------- 
     62      !! * Modules used 
     63      USE domstp              ! Domain: set the time-step 
    5964      USE par_oce             ! Ocean parameters 
    6065      USE dom_oce, ONLY       :   glamt, gphit, tmask, nproc   ! Geographical information 
     
    6368      TYPE(obs_surf), INTENT(INOUT) :: surfdataqc   ! Subset of surface data not failing screening 
    6469      LOGICAL, INTENT(IN) :: ld_nea         ! Switch for rejecting observation near land 
    65       ! 
     70      LOGICAL, INTENT(IN) :: ld_bound_reject       ! Switch for rejecting obs near the boundary 
     71      INTEGER, INTENT(IN), OPTIONAL :: kqc_cutoff   ! cut off for QC value 
     72      !! * Local declarations 
     73      INTEGER :: iqc_cutoff = 255   ! cut off for QC value 
    6674      INTEGER :: iyea0        ! Initial date 
    6775      INTEGER :: imon0        !  - (year, month, day, hour, minute) 
     
    7684      INTEGER :: inlasobs     !  - close to land 
    7785      INTEGER :: igrdobs      !  - fail the grid search 
     86      INTEGER :: ibdysobs     !  - close to open boundary 
    7887                              ! Global counters for observations that 
    7988      INTEGER :: iotdobsmpp     !  - outside time domain 
     
    8291      INTEGER :: inlasobsmpp    !  - close to land 
    8392      INTEGER :: igrdobsmpp     !  - fail the grid search 
    84       LOGICAL, DIMENSION(:), ALLOCATABLE ::   llvalid            ! SLA data selection 
     93      INTEGER :: ibdysobsmpp  !  - close to open boundary 
     94      LOGICAL, DIMENSION(:), ALLOCATABLE :: &  
     95         & llvalid            ! SLA data selection 
    8596      INTEGER :: jobs         ! Obs. loop variable 
    8697      INTEGER :: jstp         ! Time loop variable 
     
    107118      ilansobs = 0 
    108119      inlasobs = 0 
     120      ibdysobs = 0  
     121 
     122      ! Set QC cutoff to optional value if provided 
     123      IF ( PRESENT(kqc_cutoff) ) iqc_cutoff=kqc_cutoff 
    109124 
    110125      ! ----------------------------------------------------------------------- 
     
    140155         &                 tmask(:,:,1), surfdata%nqc,  & 
    141156         &                 iosdsobs,     ilansobs,     & 
    142          &                 inlasobs,     ld_nea        ) 
     157         &                 inlasobs,     ld_nea,       & 
     158         &                 ibdysobs,     ld_bound_reject, & 
     159         &                 iqc_cutoff                     ) 
    143160 
    144161      CALL obs_mpp_sum_integer( iosdsobs, iosdsobsmpp ) 
    145162      CALL obs_mpp_sum_integer( ilansobs, ilansobsmpp ) 
    146163      CALL obs_mpp_sum_integer( inlasobs, inlasobsmpp ) 
     164      CALL obs_mpp_sum_integer( ibdysobs, ibdysobsmpp ) 
    147165 
    148166      ! ----------------------------------------------------------------------- 
     
    155173      ALLOCATE( llvalid(surfdata%nsurf) ) 
    156174       
    157       ! We want all data which has qc flags <= 10 
    158  
    159       llvalid(:)  = ( surfdata%nqc(:)  <= 10 ) 
     175      ! We want all data which has qc flags <= iqc_cutoff 
     176 
     177      llvalid(:)  = ( surfdata%nqc(:)  <= iqc_cutoff ) 
    160178 
    161179      ! The actual copying 
     
    190208               &            inlasobsmpp 
    191209         ENDIF 
     210         WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data near open boundary (removed) = ', & 
     211            &            ibdysobsmpp   
    192212         WRITE(numout,*) ' '//surfdataqc%cvars(1)//' data accepted                             = ', & 
    193213            &            surfdataqc%nsurfmpp 
     
    225245      &                     kpi, kpj, kpk, & 
    226246      &                     zmask1, pglam1, pgphi1, zmask2, pglam2, pgphi2,  & 
    227       &                     ld_nea, kdailyavtypes ) 
     247      &                     ld_nea, ld_bound_reject, kdailyavtypes,  kqc_cutoff ) 
    228248 
    229249!!---------------------------------------------------------------------- 
     
    241261      !! 
    242262      !!---------------------------------------------------------------------- 
    243       USE par_oce           ! Ocean parameters 
    244       USE dom_oce, ONLY :   gdept_1d, nproc   ! Geographical information 
     263      !! * Modules used 
     264      USE domstp              ! Domain: set the time-step 
     265      USE par_oce             ! Ocean parameters 
     266      USE dom_oce, ONLY : &   ! Geographical information 
     267         & gdept_1d,             & 
     268         & nproc 
    245269 
    246270      !! * Arguments 
     
    250274      LOGICAL, INTENT(IN) :: ld_var2 
    251275      LOGICAL, INTENT(IN) :: ld_nea               ! Switch for rejecting observation near land 
     276      LOGICAL, INTENT(IN) :: ld_bound_reject      ! Switch for rejecting observations near the boundary 
    252277      INTEGER, INTENT(IN) :: kpi, kpj, kpk        ! Local domain sizes 
    253278      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: & 
     
    261286         & pgphi1, & 
    262287         & pgphi2 
     288      INTEGER, INTENT(IN), OPTIONAL :: kqc_cutoff   ! cut off for QC value 
    263289 
    264290      !! * Local declarations 
     291      INTEGER :: iqc_cutoff = 255   ! cut off for QC value 
    265292      INTEGER :: iyea0        ! Initial date 
    266293      INTEGER :: imon0        !  - (year, month, day, hour, minute) 
     
    277304      INTEGER :: inlav1obs    !  - close to land (variable 1) 
    278305      INTEGER :: inlav2obs    !  - close to land (variable 2) 
     306      INTEGER :: ibdyv1obs    !  - boundary (variable 1)  
     307      INTEGER :: ibdyv2obs    !  - boundary (variable 2)       
    279308      INTEGER :: igrdobs      !  - fail the grid search 
    280309      INTEGER :: iuvchku      !  - reject u if v rejected and vice versa 
     
    288317      INTEGER :: inlav1obsmpp !  - close to land (variable 1) 
    289318      INTEGER :: inlav2obsmpp !  - close to land (variable 2) 
     319      INTEGER :: ibdyv1obsmpp !  - boundary (variable 1)  
     320      INTEGER :: ibdyv2obsmpp !  - boundary (variable 2)       
    290321      INTEGER :: igrdobsmpp   !  - fail the grid search 
    291322      INTEGER :: iuvchkumpp   !  - reject var1 if var2 rejected and vice versa 
     
    322353      inlav1obs = 0 
    323354      inlav2obs = 0 
    324       iuvchku  = 0 
    325       iuvchkv = 0 
     355      ibdyv1obs = 0 
     356      ibdyv2obs = 0 
     357      iuvchku   = 0 
     358      iuvchkv   = 0 
     359 
     360 
     361      ! Set QC cutoff to optional value if provided 
     362      IF ( PRESENT(kqc_cutoff) ) iqc_cutoff=kqc_cutoff 
    326363 
    327364      ! ----------------------------------------------------------------------- 
     
    335372            &              profdata%nday,    profdata%nhou, profdata%nmin, & 
    336373            &              profdata%ntyp,    profdata%nqc,  profdata%mstp, & 
    337             &              iotdobs, kdailyavtypes = kdailyavtypes ) 
     374            &              iotdobs, kdailyavtypes = kdailyavtypes,         & 
     375            &              kqc_cutoff = iqc_cutoff ) 
    338376      ELSE 
    339377         CALL obs_coo_tim_prof( icycle, & 
     
    342380            &              profdata%nday,    profdata%nhou, profdata%nmin, & 
    343381            &              profdata%ntyp,    profdata%nqc,  profdata%mstp, & 
    344             &              iotdobs ) 
     382            &              iotdobs,          kqc_cutoff = iqc_cutoff ) 
    345383      ENDIF 
    346384 
     
    359397 
    360398      ! ----------------------------------------------------------------------- 
    361       ! Reject all observations for profiles with nqc > 10 
    362       ! ----------------------------------------------------------------------- 
    363  
    364       CALL obs_pro_rej( profdata ) 
     399      ! Reject all observations for profiles with nqc > iqc_cutoff 
     400      ! ----------------------------------------------------------------------- 
     401 
     402      CALL obs_pro_rej( profdata, kqc_cutoff = iqc_cutoff ) 
    365403 
    366404      ! ----------------------------------------------------------------------- 
     
    381419         &                 gdept_1d,              zmask1,               & 
    382420         &                 profdata%nqc,          profdata%var(1)%nvqc, & 
    383          &                 iosdv1obs,              ilanv1obs,           & 
    384          &                 inlav1obs,              ld_nea                ) 
     421         &                 iosdv1obs,             ilanv1obs,            & 
     422         &                 inlav1obs,             ld_nea,               & 
     423         &                 ibdyv1obs,             ld_bound_reject,      & 
     424         &                 iqc_cutoff       ) 
    385425 
    386426      CALL obs_mpp_sum_integer( iosdv1obs, iosdv1obsmpp ) 
    387427      CALL obs_mpp_sum_integer( ilanv1obs, ilanv1obsmpp ) 
    388428      CALL obs_mpp_sum_integer( inlav1obs, inlav1obsmpp ) 
     429      CALL obs_mpp_sum_integer( ibdyv1obs, ibdyv1obsmpp ) 
    389430 
    390431      ! Variable 2 
     
    400441         &                 gdept_1d,              zmask2,               & 
    401442         &                 profdata%nqc,          profdata%var(2)%nvqc, & 
    402          &                 iosdv2obs,              ilanv2obs,           & 
    403          &                 inlav2obs,              ld_nea                ) 
     443         &                 iosdv2obs,             ilanv2obs,            & 
     444         &                 inlav2obs,             ld_nea,               & 
     445         &                 ibdyv2obs,             ld_bound_reject,      & 
     446         &                 iqc_cutoff       ) 
    404447 
    405448      CALL obs_mpp_sum_integer( iosdv2obs, iosdv2obsmpp ) 
    406449      CALL obs_mpp_sum_integer( ilanv2obs, ilanv2obsmpp ) 
    407450      CALL obs_mpp_sum_integer( inlav2obs, inlav2obsmpp ) 
     451      CALL obs_mpp_sum_integer( ibdyv2obs, ibdyv2obsmpp ) 
    408452 
    409453      ! ----------------------------------------------------------------------- 
     
    412456 
    413457      IF ( TRIM(profdata%cvars(1)) == 'UVEL' ) THEN 
    414          CALL obs_uv_rej( profdata, iuvchku, iuvchkv ) 
     458         CALL obs_uv_rej( profdata, iuvchku, iuvchkv, iqc_cutoff ) 
    415459         CALL obs_mpp_sum_integer( iuvchku, iuvchkumpp ) 
    416460         CALL obs_mpp_sum_integer( iuvchkv, iuvchkvmpp ) 
     
    429473      END DO 
    430474 
    431       ! We want all data which has qc flags = 0 
    432  
    433       llvalid%luse(:) = ( profdata%nqc(:)  <= 10 ) 
     475      ! We want all data which has qc flags <= iqc_cutoff 
     476 
     477      llvalid%luse(:) = ( profdata%nqc(:)  <= iqc_cutoff ) 
    434478      DO jvar = 1,profdata%nvar 
    435          llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= 10 ) 
     479         llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= iqc_cutoff ) 
    436480      END DO 
    437481 
     
    475519               &            iuvchku 
    476520         ENDIF 
     521         WRITE(numout,*) ' Remaining '//prodatqc%cvars(1)//' data near open boundary (removed) = ',& 
     522               &            ibdyv1obsmpp 
    477523         WRITE(numout,*) ' '//prodatqc%cvars(1)//' data accepted                             = ', & 
    478524            &            prodatqc%nvprotmpp(1) 
     
    492538               &            iuvchkv 
    493539         ENDIF 
     540         WRITE(numout,*) ' Remaining '//prodatqc%cvars(2)//' data near open boundary (removed) = ',& 
     541               &            ibdyv2obsmpp 
    494542         WRITE(numout,*) ' '//prodatqc%cvars(2)//' data accepted                             = ', & 
    495543            &            prodatqc%nvprotmpp(2) 
     
    644692            &        .AND. ( kobsmin(jobs) <= kmin0 ) ) ) THEN 
    645693            kobsstp(jobs) = -1 
    646             kobsqc(jobs)  = kobsqc(jobs) + 11 
     694            kobsqc(jobs)  = IBSET(kobsqc(jobs),13) 
    647695            kotdobs       = kotdobs + 1 
    648696            CYCLE 
     
    695743         IF ( ( kobsstp(jobs) < ( nit000 - 1 ) ) & 
    696744            & .OR.( kobsstp(jobs) > nitend ) ) THEN 
    697             kobsqc(jobs) = kobsqc(jobs) + 12 
     745            kobsqc(jobs) = IBSET(kobsqc(jobs),13) 
    698746            kotdobs = kotdobs + 1 
    699747            CYCLE 
     
    739787      &                    kobsno,                                        & 
    740788      &                    kobsyea, kobsmon, kobsday, kobshou, kobsmin,   & 
    741       &                    ktyp,    kobsqc,  kobsstp, kotdobs, kdailyavtypes ) 
     789      &                    ktyp,    kobsqc,  kobsstp, kotdobs, kdailyavtypes, & 
     790      &                    kqc_cutoff ) 
    742791      !!---------------------------------------------------------------------- 
    743792      !!                    ***  ROUTINE obs_coo_tim *** 
     
    783832      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: & 
    784833         & kdailyavtypes    ! Types for daily averages 
     834      INTEGER, OPTIONAL, INTENT(IN) :: kqc_cutoff           ! QC cutoff value 
     835 
    785836      !! * Local declarations 
    786837      INTEGER :: jobs 
     838      INTEGER :: iqc_cutoff=255 
    787839 
    788840      !----------------------------------------------------------------------- 
     
    803855         DO jobs = 1, kobsno 
    804856             
    805             IF ( kobsqc(jobs) <= 10 ) THEN 
     857            IF ( kobsqc(jobs) <= iqc_cutoff ) THEN 
    806858                
    807859               IF ( ( kobsstp(jobs) == (nit000 - 1) ).AND.& 
    808860                  & ( ANY (kdailyavtypes(:) == ktyp(jobs)) ) ) THEN 
    809                   kobsqc(jobs) = kobsqc(jobs) + 14 
     861                  kobsqc(jobs) = IBSET(kobsqc(jobs),13) 
    810862                  kotdobs      = kotdobs + 1 
    811863                  CYCLE 
     
    850902      DO jobs = 1, kobsno 
    851903         IF ( ( kobsi(jobs) <= 0 ) .AND. ( kobsj(jobs) <= 0 ) ) THEN 
    852             kobsqc(jobs) = kobsqc(jobs) + 18 
     904            kobsqc(jobs) = IBSET(kobsqc(jobs),12) 
    853905            kgrdobs = kgrdobs + 1 
    854906         ENDIF 
     
    861913      &                       plam,   pphi,    pmask,            & 
    862914      &                       kobsqc, kosdobs, klanobs,          & 
    863       &                       knlaobs,ld_nea                     ) 
     915      &                       knlaobs,ld_nea,                    & 
     916      &                       kbdyobs,ld_bound_reject,           & 
     917      &                       kqc_cutoff                         ) 
    864918      !!---------------------------------------------------------------------- 
    865919      !!                    ***  ROUTINE obs_coo_spc_2d  *** 
     
    894948      INTEGER, DIMENSION(kobsno), INTENT(INOUT) :: & 
    895949         & kobsqc             ! Observation quality control 
    896       INTEGER, INTENT(INOUT) :: kosdobs   ! Observations outside space domain 
    897       INTEGER, INTENT(INOUT) :: klanobs   ! Observations within a model land cell 
    898       INTEGER, INTENT(INOUT) :: knlaobs   ! Observations near land 
    899       LOGICAL, INTENT(IN) :: ld_nea       ! Flag observations near land 
     950      INTEGER, INTENT(INOUT) :: kosdobs          ! Observations outside space domain 
     951      INTEGER, INTENT(INOUT) :: klanobs          ! Observations within a model land cell 
     952      INTEGER, INTENT(INOUT) :: knlaobs          ! Observations near land 
     953      INTEGER, INTENT(INOUT) :: kbdyobs          ! Observations near boundary 
     954      LOGICAL, INTENT(IN)    :: ld_nea           ! Flag observations near land 
     955      LOGICAL, INTENT(IN)    :: ld_bound_reject  ! Flag observations near open boundary  
     956      INTEGER, INTENT(IN)    :: kqc_cutoff       ! Cutoff QC value 
     957 
    900958      !! * Local declarations 
    901959      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: & 
    902960         & zgmsk              ! Grid mask 
     961 
     962      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: & 
     963         & zbmsk              ! Boundary mask 
     964      REAL(KIND=wp), DIMENSION(jpi,jpj) :: zbdymask 
    903965      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: & 
    904966         & zglam, &           ! Model longitude at grid points 
     
    917979         ! For invalid points use 2,2 
    918980 
    919          IF ( kobsqc(jobs) >= 10 ) THEN 
     981         IF ( kobsqc(jobs) >= kqc_cutoff ) THEN 
    920982 
    921983            igrdi(1,1,jobs) = 1 
     
    9421004 
    9431005      END DO 
     1006 
     1007      IF (ln_bdy) THEN 
     1008        ! Create a mask grid points in boundary rim 
     1009        IF (ld_bound_reject) THEN 
     1010           zbdymask(:,:) = 1.0_wp 
     1011           DO ji = 1, nb_bdy 
     1012              DO jj = 1, idx_bdy(ji)%nblen(1) 
     1013                 zbdymask(idx_bdy(ji)%nbi(jj,1),idx_bdy(ji)%nbj(jj,1)) = 0.0_wp 
     1014              ENDDO 
     1015           ENDDO 
     1016 
     1017           CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, zbdymask, zbmsk ) 
     1018        ENDIF 
     1019      ENDIF 
     1020 
    9441021       
    9451022      CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, pmask, zgmsk ) 
     
    9501027 
    9511028         ! Skip bad observations 
    952          IF ( kobsqc(jobs) >= 10 ) CYCLE 
     1029         IF ( kobsqc(jobs) >= kqc_cutoff ) CYCLE 
    9531030 
    9541031         ! Flag if the observation falls outside the model spatial domain 
     
    9571034            &  .OR. ( pobsphi(jobs) <  -90. ) & 
    9581035            &  .OR. ( pobsphi(jobs) >   90. ) ) THEN 
    959             kobsqc(jobs) = kobsqc(jobs) + 11 
     1036            kobsqc(jobs) = IBSET(kobsqc(jobs),11) 
    9601037            kosdobs = kosdobs + 1 
    9611038            CYCLE 
     
    9641041         ! Flag if the observation falls with a model land cell 
    9651042         IF ( SUM( zgmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN 
    966             kobsqc(jobs) = kobsqc(jobs)  + 12 
     1043            kobsqc(jobs) = IBSET(kobsqc(jobs),10) 
    9671044            klanobs = klanobs + 1 
    9681045            CYCLE 
     
    9781055               IF ( ( ABS( zgphi(ji,jj,jobs) - pobsphi(jobs) ) < 1.0e-6_wp ) & 
    9791056                  & .AND. & 
    980                   & ( ABS( zglam(ji,jj,jobs) - pobslam(jobs) ) < 1.0e-6_wp ) & 
    981                   & ) THEN 
     1057                  & ( ABS( MOD( zglam(ji,jj,jobs) - pobslam(jobs),360.0) ) & 
     1058                  & < 1.0e-6_wp ) ) THEN 
    9821059                  lgridobs = .TRUE. 
    9831060                  iig = ji 
     
    9921069         IF (lgridobs) THEN 
    9931070            IF (zgmsk(iig,ijg,jobs) == 0.0_wp ) THEN 
    994                kobsqc(jobs) = kobsqc(jobs) + 12 
     1071               kobsqc(jobs) = IBSET(kobsqc(jobs),10) 
    9951072               klanobs = klanobs + 1 
    9961073               CYCLE 
     
    10001077         ! Flag if the observation falls is close to land 
    10011078         IF ( MINVAL( zgmsk(1:2,1:2,jobs) ) == 0.0_wp) THEN 
    1002             IF (ld_nea) kobsqc(jobs) = kobsqc(jobs) + 14 
    10031079            knlaobs = knlaobs + 1 
    1004             CYCLE 
     1080            IF (ld_nea) THEN 
     1081               kobsqc(jobs) = IBSET(kobsqc(jobs),9) 
     1082               CYCLE 
     1083            ENDIF 
     1084         ENDIF 
     1085 
     1086         IF (ln_bdy) THEN 
     1087         ! Flag if the observation falls close to the boundary rim 
     1088           IF (ld_bound_reject) THEN 
     1089              IF ( MINVAL( zbmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN 
     1090                 kobsqc(jobs) = IBSET(kobsqc(jobs),8) 
     1091                 kbdyobs = kbdyobs + 1 
     1092                 CYCLE 
     1093              ENDIF 
     1094              ! for observations on the grid... 
     1095              IF (lgridobs) THEN 
     1096                 IF (zbmsk(iig,ijg,jobs) == 0.0_wp ) THEN 
     1097                    kobsqc(jobs) = IBSET(kobsqc(jobs),8) 
     1098                    kbdyobs = kbdyobs + 1 
     1099                    CYCLE 
     1100                 ENDIF 
     1101              ENDIF 
     1102            ENDIF 
    10051103         ENDIF 
    10061104             
     
    10151113      &                       plam,    pphi,    pdep,    pmask, & 
    10161114      &                       kpobsqc, kobsqc,  kosdobs,        & 
    1017       &                       klanobs, knlaobs, ld_nea          ) 
     1115      &                       klanobs, knlaobs, ld_nea,         & 
     1116      &                       kbdyobs, ld_bound_reject,         & 
     1117      &                       kqc_cutoff                        ) 
    10181118      !!---------------------------------------------------------------------- 
    10191119      !!                    ***  ROUTINE obs_coo_spc_3d  *** 
     
    10771177      INTEGER, INTENT(INOUT) :: klanobs     ! Observations within a model land cell 
    10781178      INTEGER, INTENT(INOUT) :: knlaobs     ! Observations near land 
     1179      INTEGER, INTENT(INOUT) :: kbdyobs     ! Observations near boundary 
    10791180      LOGICAL, INTENT(IN) :: ld_nea         ! Flag observations near land 
     1181      LOGICAL, INTENT(IN) :: ld_bound_reject  ! Flag observations near open boundary 
     1182      INTEGER, INTENT(IN) :: kqc_cutoff     ! Cutoff QC value 
     1183 
    10801184      !! * Local declarations 
    10811185      REAL(KIND=wp), DIMENSION(2,2,kpk,kprofno) :: & 
    10821186         & zgmsk              ! Grid mask 
     1187      REAL(KIND=wp), DIMENSION(2,2,kprofno) :: & 
     1188         & zbmsk              ! Boundary mask 
     1189      REAL(KIND=wp), DIMENSION(jpi,jpj) :: zbdymask 
    10831190      REAL(KIND=wp), DIMENSION(2,2,kpk,kprofno) :: & 
    10841191         & zgdepw 
     
    11001207         ! For invalid points use 2,2 
    11011208 
    1102          IF ( kpobsqc(jobs) >= 10 ) THEN 
     1209         IF ( kpobsqc(jobs) >= kqc_cutoff ) THEN 
    11031210             
    11041211            igrdi(1,1,jobs) = 1 
     
    11251232          
    11261233      END DO 
     1234 
     1235      IF (ln_bdy) THEN 
     1236        ! Create a mask grid points in boundary rim 
     1237        IF (ld_bound_reject) THEN            
     1238           zbdymask(:,:) = 1.0_wp 
     1239           DO ji = 1, nb_bdy 
     1240              DO jj = 1, idx_bdy(ji)%nblen(1) 
     1241                 zbdymask(idx_bdy(ji)%nbi(jj,1),idx_bdy(ji)%nbj(jj,1)) = 0.0_wp 
     1242              ENDDO 
     1243           ENDDO 
     1244        ENDIF 
     1245    
     1246        CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, zbdymask, zbmsk ) 
     1247      ENDIF 
    11271248       
    11281249      CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, pmask, zgmsk ) 
    11291250      CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, plam, zglam ) 
    11301251      CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, pphi, zgphi ) 
    1131       IF ( .NOT.( ln_zps .OR. ln_zco ) ) THEN 
    1132         ! Need to know the bathy depth for each observation for sco 
    1133         CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, gdepw_n(:,:,:), & 
     1252      CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, gdepw_n(:,:,:), & 
    11341253        &                     zgdepw ) 
    1135       ENDIF 
    11361254 
    11371255      DO jobs = 1, kprofno 
    11381256 
    11391257         ! Skip bad profiles 
    1140          IF ( kpobsqc(jobs) >= 10 ) CYCLE 
     1258         IF ( kpobsqc(jobs) >= kqc_cutoff ) CYCLE 
    11411259 
    11421260         ! Check if this observation is on a grid point 
     
    11491267               IF ( ( ABS( zgphi(ji,jj,jobs) - pobsphi(jobs) ) < 1.0e-6_wp ) & 
    11501268                  & .AND. & 
    1151                   & ( ABS( zglam(ji,jj,jobs) - pobslam(jobs) ) < 1.0e-6_wp ) & 
     1269                  & ( ABS( MOD( zglam(ji,jj,jobs) - pobslam(jobs),360.0) ) < 1.0e-6_wp ) & 
    11521270                  & ) THEN 
    11531271                  lgridobs = .TRUE. 
     
    11761294               &  .OR. ( pobsdep(jobsp) < 0.0          )       & 
    11771295               &  .OR. ( pobsdep(jobsp) > gdepw_1d(kpk)) ) THEN 
    1178                kobsqc(jobsp) = kobsqc(jobsp) + 11 
     1296               kobsqc(jobsp) = IBSET(kobsqc(jobsp),11) 
    11791297               kosdobs = kosdobs + 1 
    11801298               CYCLE 
    11811299            ENDIF 
    11821300 
    1183             ! To check if an observations falls within land there are two cases: 
    1184             ! 1: z-coordibnates, where the check uses the mask 
    1185             ! 2: terrain following (eg s-coordinates),  
    1186             !    where we use the depth of the bottom cell to mask observations 
     1301            ! To check if an observations falls within land: 
    11871302              
    1188             IF( ln_zps .OR. ln_zco ) THEN !(CASE 1) 
     1303            ! Flag if the observation is deeper than the bathymetry 
     1304            ! Or if it is within the mask 
     1305            IF ( ALL( zgdepw(1:2,1:2,kpk,jobs) < pobsdep(jobsp) ) & 
     1306               &     .OR. & 
     1307               &  ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) & 
     1308               &  == 0.0_wp) ) THEN 
     1309               kobsqc(jobsp) = IBSET(kobsqc(jobsp),10) 
     1310               klanobs = klanobs + 1 
     1311               CYCLE 
     1312            ENDIF 
    11891313                
    1190                ! Flag if the observation falls with a model land cell 
    1191                IF ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) & 
    1192                   &  == 0.0_wp ) THEN 
    1193                   kobsqc(jobsp) = kobsqc(jobsp) + 12 
    1194                   klanobs = klanobs + 1 
    1195                   CYCLE 
    1196                ENDIF 
    1197               
    1198                ! Flag if the observation is close to land 
    1199               IF ( MINVAL( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) == & 
    1200                   &  0.0_wp) THEN 
    1201                   knlaobs = knlaobs + 1 
    1202                   IF (ld_nea) THEN    
    1203                      kobsqc(jobsp) = kobsqc(jobsp) + 14  
    1204                   ENDIF  
    1205                ENDIF 
    1206               
    1207             ELSE ! Case 2 
    1208   
    1209                ! Flag if the observation is deeper than the bathymetry 
    1210                ! Or if it is within the mask 
    1211                IF ( ALL( zgdepw(1:2,1:2,kpk,jobs) < pobsdep(jobsp) ) & 
    1212                   &     .OR. & 
    1213                   &  ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) & 
    1214                   &  == 0.0_wp) ) THEN 
    1215                   kobsqc(jobsp) = kobsqc(jobsp) + 12 
    1216                   klanobs = klanobs + 1 
    1217                   CYCLE 
    1218                ENDIF 
    1219                 
    1220                ! Flag if the observation is close to land 
    1221                IF ( ll_next_to_land ) THEN 
    1222                   knlaobs = knlaobs + 1 
    1223                   IF (ld_nea) THEN    
    1224                      kobsqc(jobsp) = kobsqc(jobsp) + 14  
    1225                   ENDIF  
    1226                ENDIF 
     1314            ! Flag if the observation is close to land 
     1315            IF ( ll_next_to_land ) THEN 
     1316               knlaobs = knlaobs + 1 
     1317               IF (ld_nea) THEN    
     1318                  kobsqc(jobsp) = IBSET(kobsqc(jobsp),10) 
     1319               ENDIF  
    12271320            ENDIF 
    12281321             
     
    12321325            IF (lgridobs) THEN 
    12331326               IF (zgmsk(iig,ijg,kobsk(jobsp)-1,jobs) == 0.0_wp ) THEN 
    1234                   kobsqc(jobsp) = kobsqc(jobsp) + 12 
     1327                  kobsqc(jobsp) = IBSET(kobsqc(jobs),10) 
    12351328                  klanobs = klanobs + 1 
    12361329                  CYCLE 
     
    12501343            ENDIF 
    12511344             
     1345            IF (ln_bdy) THEN 
     1346               ! Flag if the observation falls close to the boundary rim 
     1347               IF (ld_bound_reject) THEN 
     1348                  IF ( MINVAL( zbmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN 
     1349                     kobsqc(jobsp) = IBSET(kobsqc(jobs),8) 
     1350                     kbdyobs = kbdyobs + 1 
     1351                     CYCLE 
     1352                  ENDIF 
     1353                  ! for observations on the grid... 
     1354                  IF (lgridobs) THEN 
     1355                     IF (zbmsk(iig,ijg,jobs) == 0.0_wp ) THEN 
     1356                        kobsqc(jobsp) = IBSET(kobsqc(jobs),8) 
     1357                        kbdyobs = kbdyobs + 1 
     1358                        CYCLE 
     1359                     ENDIF 
     1360                  ENDIF 
     1361               ENDIF 
     1362            ENDIF 
     1363             
    12521364         END DO 
    12531365      END DO 
     
    12551367   END SUBROUTINE obs_coo_spc_3d 
    12561368 
    1257    SUBROUTINE obs_pro_rej( profdata ) 
     1369   SUBROUTINE obs_pro_rej( profdata, kqc_cutoff ) 
    12581370      !!---------------------------------------------------------------------- 
    12591371      !!                    ***  ROUTINE obs_pro_rej *** 
     
    12731385      !! * Arguments 
    12741386      TYPE(obs_prof), INTENT(INOUT) :: profdata     ! Profile data 
     1387      INTEGER, INTENT(IN) :: kqc_cutoff             ! QC cutoff value 
     1388 
    12751389      !! * Local declarations 
    12761390      INTEGER :: jprof 
     
    12821396      DO jprof = 1, profdata%nprof 
    12831397 
    1284          IF ( profdata%nqc(jprof) > 10 ) THEN 
     1398         IF ( profdata%nqc(jprof) > kqc_cutoff ) THEN 
    12851399             
    12861400            DO jvar = 1, profdata%nvar 
     
    12901404                   
    12911405                  profdata%var(jvar)%nvqc(jobs) = & 
    1292                      & profdata%var(jvar)%nvqc(jobs) + 26 
     1406                     & IBSET(profdata%var(jvar)%nvqc(jobs),14) 
    12931407 
    12941408               END DO 
     
    13021416   END SUBROUTINE obs_pro_rej 
    13031417 
    1304    SUBROUTINE obs_uv_rej( profdata, knumu, knumv ) 
     1418   SUBROUTINE obs_uv_rej( profdata, knumu, knumv, kqc_cutoff ) 
    13051419      !!---------------------------------------------------------------------- 
    13061420      !!                    ***  ROUTINE obs_uv_rej *** 
     
    13221436      INTEGER, INTENT(INOUT) :: knumu             ! Number of u rejected 
    13231437      INTEGER, INTENT(INOUT) :: knumv             ! Number of v rejected 
     1438      INTEGER, INTENT(IN) :: kqc_cutoff           ! QC cutoff value 
     1439 
    13241440      !! * Local declarations 
    13251441      INTEGER :: jprof 
     
    13411457         DO jobs = profdata%npvsta(jprof,1), profdata%npvend(jprof,1) 
    13421458             
    1343             IF ( ( profdata%var(1)%nvqc(jobs) > 10 ) .AND. & 
    1344                & ( profdata%var(2)%nvqc(jobs) <= 10) ) THEN 
    1345                profdata%var(2)%nvqc(jobs) = profdata%var(2)%nvqc(jobs) + 42 
     1459            IF ( ( profdata%var(1)%nvqc(jobs) >  kqc_cutoff ) .AND. & 
     1460               & ( profdata%var(2)%nvqc(jobs) <=  kqc_cutoff) ) THEN 
     1461               profdata%var(2)%nvqc(jobs) = IBSET(profdata%var(1)%nvqc(jobs),15) 
    13461462               knumv = knumv + 1 
    13471463            ENDIF 
    1348             IF ( ( profdata%var(2)%nvqc(jobs) > 10 ) .AND. & 
    1349                & ( profdata%var(1)%nvqc(jobs) <= 10) ) THEN 
    1350                profdata%var(1)%nvqc(jobs) = profdata%var(1)%nvqc(jobs) + 42 
     1464            IF ( ( profdata%var(2)%nvqc(jobs) >  kqc_cutoff ) .AND. & 
     1465               & ( profdata%var(1)%nvqc(jobs) <=  kqc_cutoff) ) THEN 
     1466               profdata%var(1)%nvqc(jobs) = IBSET(profdata%var(1)%nvqc(jobs),15) 
    13511467               knumu = knumu + 1 
    13521468            ENDIF 
Note: See TracChangeset for help on using the changeset viewer.