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

Ignore:
Timestamp:
2017-12-13T18:08:50+01:00 (6 years ago)
Author:
timgraham
Message:

Merged METO_MERCATOR branch and resolved all conflicts in OPA_SRC

File:
1 edited

Legend:

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

    r7646 r9023  
    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 
    5963      USE par_oce             ! Ocean parameters 
    6064      USE dom_oce, ONLY       :   glamt, gphit, tmask, nproc   ! Geographical information 
     
    6367      TYPE(obs_surf), INTENT(INOUT) :: surfdataqc   ! Subset of surface data not failing screening 
    6468      LOGICAL, INTENT(IN) :: ld_nea         ! Switch for rejecting observation near land 
    65       ! 
     69      LOGICAL, INTENT(IN) :: ld_bound_reject       ! Switch for rejecting obs near the boundary 
     70      INTEGER, INTENT(IN), OPTIONAL :: kqc_cutoff   ! cut off for QC value 
     71      !! * Local declarations 
     72      INTEGER :: iqc_cutoff = 255   ! cut off for QC value 
    6673      INTEGER :: iyea0        ! Initial date 
    6774      INTEGER :: imon0        !  - (year, month, day, hour, minute) 
     
    7683      INTEGER :: inlasobs     !  - close to land 
    7784      INTEGER :: igrdobs      !  - fail the grid search 
     85      INTEGER :: ibdysobs     !  - close to open boundary 
    7886                              ! Global counters for observations that 
    7987      INTEGER :: iotdobsmpp     !  - outside time domain 
     
    8290      INTEGER :: inlasobsmpp    !  - close to land 
    8391      INTEGER :: igrdobsmpp     !  - fail the grid search 
    84       LOGICAL, DIMENSION(:), ALLOCATABLE ::   llvalid            ! SLA data selection 
     92      INTEGER :: ibdysobsmpp  !  - close to open boundary 
     93      LOGICAL, DIMENSION(:), ALLOCATABLE :: &  
     94         & llvalid            ! SLA data selection 
    8595      INTEGER :: jobs         ! Obs. loop variable 
    8696      INTEGER :: jstp         ! Time loop variable 
     
    107117      ilansobs = 0 
    108118      inlasobs = 0 
     119      ibdysobs = 0  
     120 
     121      ! Set QC cutoff to optional value if provided 
     122      IF ( PRESENT(kqc_cutoff) ) iqc_cutoff=kqc_cutoff 
    109123 
    110124      ! ----------------------------------------------------------------------- 
     
    140154         &                 tmask(:,:,1), surfdata%nqc,  & 
    141155         &                 iosdsobs,     ilansobs,     & 
    142          &                 inlasobs,     ld_nea        ) 
     156         &                 inlasobs,     ld_nea,       & 
     157         &                 ibdysobs,     ld_bound_reject, & 
     158         &                 iqc_cutoff                     ) 
    143159 
    144160      CALL obs_mpp_sum_integer( iosdsobs, iosdsobsmpp ) 
    145161      CALL obs_mpp_sum_integer( ilansobs, ilansobsmpp ) 
    146162      CALL obs_mpp_sum_integer( inlasobs, inlasobsmpp ) 
     163      CALL obs_mpp_sum_integer( ibdysobs, ibdysobsmpp ) 
    147164 
    148165      ! ----------------------------------------------------------------------- 
     
    155172      ALLOCATE( llvalid(surfdata%nsurf) ) 
    156173       
    157       ! We want all data which has qc flags <= 10 
    158  
    159       llvalid(:)  = ( surfdata%nqc(:)  <= 10 ) 
     174      ! We want all data which has qc flags <= iqc_cutoff 
     175 
     176      llvalid(:)  = ( surfdata%nqc(:)  <= iqc_cutoff ) 
    160177 
    161178      ! The actual copying 
     
    190207               &            inlasobsmpp 
    191208         ENDIF 
     209         WRITE(numout,*) ' Remaining '//surfdataqc%cvars(1)//' data near open boundary (removed) = ', & 
     210            &            ibdysobsmpp   
    192211         WRITE(numout,*) ' '//surfdataqc%cvars(1)//' data accepted                             = ', & 
    193212            &            surfdataqc%nsurfmpp 
     
    225244      &                     kpi, kpj, kpk, & 
    226245      &                     zmask1, pglam1, pgphi1, zmask2, pglam2, pgphi2,  & 
    227       &                     ld_nea, kdailyavtypes ) 
     246      &                     ld_nea, ld_bound_reject, kdailyavtypes,  kqc_cutoff ) 
    228247 
    229248!!---------------------------------------------------------------------- 
     
    241260      !! 
    242261      !!---------------------------------------------------------------------- 
    243       USE par_oce           ! Ocean parameters 
    244       USE dom_oce, ONLY :   gdept_1d, nproc   ! Geographical information 
     262      !! * Modules used 
     263      USE par_oce             ! Ocean parameters 
     264      USE dom_oce, ONLY : &   ! Geographical information 
     265         & gdept_1d,             & 
     266         & nproc 
    245267 
    246268      !! * Arguments 
     
    250272      LOGICAL, INTENT(IN) :: ld_var2 
    251273      LOGICAL, INTENT(IN) :: ld_nea               ! Switch for rejecting observation near land 
     274      LOGICAL, INTENT(IN) :: ld_bound_reject      ! Switch for rejecting observations near the boundary 
    252275      INTEGER, INTENT(IN) :: kpi, kpj, kpk        ! Local domain sizes 
    253276      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: & 
     
    261284         & pgphi1, & 
    262285         & pgphi2 
     286      INTEGER, INTENT(IN), OPTIONAL :: kqc_cutoff   ! cut off for QC value 
    263287 
    264288      !! * Local declarations 
     289      INTEGER :: iqc_cutoff = 255   ! cut off for QC value 
    265290      INTEGER :: iyea0        ! Initial date 
    266291      INTEGER :: imon0        !  - (year, month, day, hour, minute) 
     
    277302      INTEGER :: inlav1obs    !  - close to land (variable 1) 
    278303      INTEGER :: inlav2obs    !  - close to land (variable 2) 
     304      INTEGER :: ibdyv1obs    !  - boundary (variable 1)  
     305      INTEGER :: ibdyv2obs    !  - boundary (variable 2)       
    279306      INTEGER :: igrdobs      !  - fail the grid search 
    280307      INTEGER :: iuvchku      !  - reject u if v rejected and vice versa 
     
    288315      INTEGER :: inlav1obsmpp !  - close to land (variable 1) 
    289316      INTEGER :: inlav2obsmpp !  - close to land (variable 2) 
     317      INTEGER :: ibdyv1obsmpp !  - boundary (variable 1)  
     318      INTEGER :: ibdyv2obsmpp !  - boundary (variable 2)       
    290319      INTEGER :: igrdobsmpp   !  - fail the grid search 
    291320      INTEGER :: iuvchkumpp   !  - reject var1 if var2 rejected and vice versa 
     
    322351      inlav1obs = 0 
    323352      inlav2obs = 0 
    324       iuvchku  = 0 
    325       iuvchkv = 0 
     353      ibdyv1obs = 0 
     354      ibdyv2obs = 0 
     355      iuvchku   = 0 
     356      iuvchkv   = 0 
     357 
     358 
     359      ! Set QC cutoff to optional value if provided 
     360      IF ( PRESENT(kqc_cutoff) ) iqc_cutoff=kqc_cutoff 
    326361 
    327362      ! ----------------------------------------------------------------------- 
     
    335370            &              profdata%nday,    profdata%nhou, profdata%nmin, & 
    336371            &              profdata%ntyp,    profdata%nqc,  profdata%mstp, & 
    337             &              iotdobs, kdailyavtypes = kdailyavtypes ) 
     372            &              iotdobs, kdailyavtypes = kdailyavtypes,         & 
     373            &              kqc_cutoff = iqc_cutoff ) 
    338374      ELSE 
    339375         CALL obs_coo_tim_prof( icycle, & 
     
    342378            &              profdata%nday,    profdata%nhou, profdata%nmin, & 
    343379            &              profdata%ntyp,    profdata%nqc,  profdata%mstp, & 
    344             &              iotdobs ) 
     380            &              iotdobs,          kqc_cutoff = iqc_cutoff ) 
    345381      ENDIF 
    346382 
     
    359395 
    360396      ! ----------------------------------------------------------------------- 
    361       ! Reject all observations for profiles with nqc > 10 
    362       ! ----------------------------------------------------------------------- 
    363  
    364       CALL obs_pro_rej( profdata ) 
     397      ! Reject all observations for profiles with nqc > iqc_cutoff 
     398      ! ----------------------------------------------------------------------- 
     399 
     400      CALL obs_pro_rej( profdata, kqc_cutoff = iqc_cutoff ) 
    365401 
    366402      ! ----------------------------------------------------------------------- 
     
    381417         &                 gdept_1d,              zmask1,               & 
    382418         &                 profdata%nqc,          profdata%var(1)%nvqc, & 
    383          &                 iosdv1obs,              ilanv1obs,           & 
    384          &                 inlav1obs,              ld_nea                ) 
     419         &                 iosdv1obs,             ilanv1obs,            & 
     420         &                 inlav1obs,             ld_nea,               & 
     421         &                 ibdyv1obs,             ld_bound_reject,      & 
     422         &                 iqc_cutoff       ) 
    385423 
    386424      CALL obs_mpp_sum_integer( iosdv1obs, iosdv1obsmpp ) 
    387425      CALL obs_mpp_sum_integer( ilanv1obs, ilanv1obsmpp ) 
    388426      CALL obs_mpp_sum_integer( inlav1obs, inlav1obsmpp ) 
     427      CALL obs_mpp_sum_integer( ibdyv1obs, ibdyv1obsmpp ) 
    389428 
    390429      ! Variable 2 
     
    400439         &                 gdept_1d,              zmask2,               & 
    401440         &                 profdata%nqc,          profdata%var(2)%nvqc, & 
    402          &                 iosdv2obs,              ilanv2obs,           & 
    403          &                 inlav2obs,              ld_nea                ) 
     441         &                 iosdv2obs,             ilanv2obs,            & 
     442         &                 inlav2obs,             ld_nea,               & 
     443         &                 ibdyv2obs,             ld_bound_reject,      & 
     444         &                 iqc_cutoff       ) 
    404445 
    405446      CALL obs_mpp_sum_integer( iosdv2obs, iosdv2obsmpp ) 
    406447      CALL obs_mpp_sum_integer( ilanv2obs, ilanv2obsmpp ) 
    407448      CALL obs_mpp_sum_integer( inlav2obs, inlav2obsmpp ) 
     449      CALL obs_mpp_sum_integer( ibdyv2obs, ibdyv2obsmpp ) 
    408450 
    409451      ! ----------------------------------------------------------------------- 
     
    412454 
    413455      IF ( TRIM(profdata%cvars(1)) == 'UVEL' ) THEN 
    414          CALL obs_uv_rej( profdata, iuvchku, iuvchkv ) 
     456         CALL obs_uv_rej( profdata, iuvchku, iuvchkv, iqc_cutoff ) 
    415457         CALL obs_mpp_sum_integer( iuvchku, iuvchkumpp ) 
    416458         CALL obs_mpp_sum_integer( iuvchkv, iuvchkvmpp ) 
     
    429471      END DO 
    430472 
    431       ! We want all data which has qc flags = 0 
    432  
    433       llvalid%luse(:) = ( profdata%nqc(:)  <= 10 ) 
     473      ! We want all data which has qc flags <= iqc_cutoff 
     474 
     475      llvalid%luse(:) = ( profdata%nqc(:)  <= iqc_cutoff ) 
    434476      DO jvar = 1,profdata%nvar 
    435          llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= 10 ) 
     477         llvvalid(jvar)%luse(:) = ( profdata%var(jvar)%nvqc(:) <= iqc_cutoff ) 
    436478      END DO 
    437479 
     
    475517               &            iuvchku 
    476518         ENDIF 
     519         WRITE(numout,*) ' Remaining '//prodatqc%cvars(1)//' data near open boundary (removed) = ',& 
     520               &            ibdyv1obsmpp 
    477521         WRITE(numout,*) ' '//prodatqc%cvars(1)//' data accepted                             = ', & 
    478522            &            prodatqc%nvprotmpp(1) 
     
    492536               &            iuvchkv 
    493537         ENDIF 
     538         WRITE(numout,*) ' Remaining '//prodatqc%cvars(2)//' data near open boundary (removed) = ',& 
     539               &            ibdyv2obsmpp 
    494540         WRITE(numout,*) ' '//prodatqc%cvars(2)//' data accepted                             = ', & 
    495541            &            prodatqc%nvprotmpp(2) 
     
    644690            &        .AND. ( kobsmin(jobs) <= kmin0 ) ) ) THEN 
    645691            kobsstp(jobs) = -1 
    646             kobsqc(jobs)  = kobsqc(jobs) + 11 
     692            kobsqc(jobs)  = IBSET(kobsqc(jobs),13) 
    647693            kotdobs       = kotdobs + 1 
    648694            CYCLE 
     
    695741         IF ( ( kobsstp(jobs) < ( nit000 - 1 ) ) & 
    696742            & .OR.( kobsstp(jobs) > nitend ) ) THEN 
    697             kobsqc(jobs) = kobsqc(jobs) + 12 
     743            kobsqc(jobs) = IBSET(kobsqc(jobs),13) 
    698744            kotdobs = kotdobs + 1 
    699745            CYCLE 
     
    739785      &                    kobsno,                                        & 
    740786      &                    kobsyea, kobsmon, kobsday, kobshou, kobsmin,   & 
    741       &                    ktyp,    kobsqc,  kobsstp, kotdobs, kdailyavtypes ) 
     787      &                    ktyp,    kobsqc,  kobsstp, kotdobs, kdailyavtypes, & 
     788      &                    kqc_cutoff ) 
    742789      !!---------------------------------------------------------------------- 
    743790      !!                    ***  ROUTINE obs_coo_tim *** 
     
    783830      INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: & 
    784831         & kdailyavtypes    ! Types for daily averages 
     832      INTEGER, OPTIONAL, INTENT(IN) :: kqc_cutoff           ! QC cutoff value 
     833 
    785834      !! * Local declarations 
    786835      INTEGER :: jobs 
     836      INTEGER :: iqc_cutoff=255 
    787837 
    788838      !----------------------------------------------------------------------- 
     
    803853         DO jobs = 1, kobsno 
    804854             
    805             IF ( kobsqc(jobs) <= 10 ) THEN 
     855            IF ( kobsqc(jobs) <= iqc_cutoff ) THEN 
    806856                
    807857               IF ( ( kobsstp(jobs) == (nit000 - 1) ).AND.& 
    808858                  & ( ANY (kdailyavtypes(:) == ktyp(jobs)) ) ) THEN 
    809                   kobsqc(jobs) = kobsqc(jobs) + 14 
     859                  kobsqc(jobs) = IBSET(kobsqc(jobs),13) 
    810860                  kotdobs      = kotdobs + 1 
    811861                  CYCLE 
     
    850900      DO jobs = 1, kobsno 
    851901         IF ( ( kobsi(jobs) <= 0 ) .AND. ( kobsj(jobs) <= 0 ) ) THEN 
    852             kobsqc(jobs) = kobsqc(jobs) + 18 
     902            kobsqc(jobs) = IBSET(kobsqc(jobs),12) 
    853903            kgrdobs = kgrdobs + 1 
    854904         ENDIF 
     
    861911      &                       plam,   pphi,    pmask,            & 
    862912      &                       kobsqc, kosdobs, klanobs,          & 
    863       &                       knlaobs,ld_nea                     ) 
     913      &                       knlaobs,ld_nea,                    & 
     914      &                       kbdyobs,ld_bound_reject,           & 
     915      &                       kqc_cutoff                         ) 
    864916      !!---------------------------------------------------------------------- 
    865917      !!                    ***  ROUTINE obs_coo_spc_2d  *** 
     
    894946      INTEGER, DIMENSION(kobsno), INTENT(INOUT) :: & 
    895947         & 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 
     948      INTEGER, INTENT(INOUT) :: kosdobs          ! Observations outside space domain 
     949      INTEGER, INTENT(INOUT) :: klanobs          ! Observations within a model land cell 
     950      INTEGER, INTENT(INOUT) :: knlaobs          ! Observations near land 
     951      INTEGER, INTENT(INOUT) :: kbdyobs          ! Observations near boundary 
     952      LOGICAL, INTENT(IN)    :: ld_nea           ! Flag observations near land 
     953      LOGICAL, INTENT(IN)    :: ld_bound_reject  ! Flag observations near open boundary  
     954      INTEGER, INTENT(IN)    :: kqc_cutoff       ! Cutoff QC value 
     955 
    900956      !! * Local declarations 
    901957      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: & 
    902958         & zgmsk              ! Grid mask 
     959 
     960      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: & 
     961         & zbmsk              ! Boundary mask 
     962      REAL(KIND=wp), DIMENSION(jpi,jpj) :: zbdymask 
    903963      REAL(KIND=wp), DIMENSION(2,2,kobsno) :: & 
    904964         & zglam, &           ! Model longitude at grid points 
     
    917977         ! For invalid points use 2,2 
    918978 
    919          IF ( kobsqc(jobs) >= 10 ) THEN 
     979         IF ( kobsqc(jobs) >= kqc_cutoff ) THEN 
    920980 
    921981            igrdi(1,1,jobs) = 1 
     
    9421002 
    9431003      END DO 
     1004 
     1005      IF (ln_bdy) THEN 
     1006        ! Create a mask grid points in boundary rim 
     1007        IF (ld_bound_reject) THEN 
     1008           zbdymask(:,:) = 1.0_wp 
     1009           DO ji = 1, nb_bdy 
     1010              DO jj = 1, idx_bdy(ji)%nblen(1) 
     1011                 zbdymask(idx_bdy(ji)%nbi(jj,1),idx_bdy(ji)%nbj(jj,1)) = 0.0_wp 
     1012              ENDDO 
     1013           ENDDO 
     1014 
     1015           CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, zbdymask, zbmsk ) 
     1016        ENDIF 
     1017      ENDIF 
     1018 
    9441019       
    9451020      CALL obs_int_comm_2d( 2, 2, kobsno, kpi, kpj, igrdi, igrdj, pmask, zgmsk ) 
     
    9501025 
    9511026         ! Skip bad observations 
    952          IF ( kobsqc(jobs) >= 10 ) CYCLE 
     1027         IF ( kobsqc(jobs) >= kqc_cutoff ) CYCLE 
    9531028 
    9541029         ! Flag if the observation falls outside the model spatial domain 
     
    9571032            &  .OR. ( pobsphi(jobs) <  -90. ) & 
    9581033            &  .OR. ( pobsphi(jobs) >   90. ) ) THEN 
    959             kobsqc(jobs) = kobsqc(jobs) + 11 
     1034            kobsqc(jobs) = IBSET(kobsqc(jobs),11) 
    9601035            kosdobs = kosdobs + 1 
    9611036            CYCLE 
     
    9641039         ! Flag if the observation falls with a model land cell 
    9651040         IF ( SUM( zgmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN 
    966             kobsqc(jobs) = kobsqc(jobs)  + 12 
     1041            kobsqc(jobs) = IBSET(kobsqc(jobs),10) 
    9671042            klanobs = klanobs + 1 
    9681043            CYCLE 
     
    9781053               IF ( ( ABS( zgphi(ji,jj,jobs) - pobsphi(jobs) ) < 1.0e-6_wp ) & 
    9791054                  & .AND. & 
    980                   & ( ABS( zglam(ji,jj,jobs) - pobslam(jobs) ) < 1.0e-6_wp ) & 
    981                   & ) THEN 
     1055                  & ( ABS( MOD( zglam(ji,jj,jobs) - pobslam(jobs),360.0) ) & 
     1056                  & < 1.0e-6_wp ) ) THEN 
    9821057                  lgridobs = .TRUE. 
    9831058                  iig = ji 
     
    9921067         IF (lgridobs) THEN 
    9931068            IF (zgmsk(iig,ijg,jobs) == 0.0_wp ) THEN 
    994                kobsqc(jobs) = kobsqc(jobs) + 12 
     1069               kobsqc(jobs) = IBSET(kobsqc(jobs),10) 
    9951070               klanobs = klanobs + 1 
    9961071               CYCLE 
     
    10001075         ! Flag if the observation falls is close to land 
    10011076         IF ( MINVAL( zgmsk(1:2,1:2,jobs) ) == 0.0_wp) THEN 
    1002             IF (ld_nea) kobsqc(jobs) = kobsqc(jobs) + 14 
    10031077            knlaobs = knlaobs + 1 
    1004             CYCLE 
     1078            IF (ld_nea) THEN 
     1079               kobsqc(jobs) = IBSET(kobsqc(jobs),9) 
     1080               CYCLE 
     1081            ENDIF 
     1082         ENDIF 
     1083 
     1084         IF (ln_bdy) THEN 
     1085         ! Flag if the observation falls close to the boundary rim 
     1086           IF (ld_bound_reject) THEN 
     1087              IF ( MINVAL( zbmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN 
     1088                 kobsqc(jobs) = IBSET(kobsqc(jobs),8) 
     1089                 kbdyobs = kbdyobs + 1 
     1090                 CYCLE 
     1091              ENDIF 
     1092              ! for observations on the grid... 
     1093              IF (lgridobs) THEN 
     1094                 IF (zbmsk(iig,ijg,jobs) == 0.0_wp ) THEN 
     1095                    kobsqc(jobs) = IBSET(kobsqc(jobs),8) 
     1096                    kbdyobs = kbdyobs + 1 
     1097                    CYCLE 
     1098                 ENDIF 
     1099              ENDIF 
     1100            ENDIF 
    10051101         ENDIF 
    10061102             
     
    10151111      &                       plam,    pphi,    pdep,    pmask, & 
    10161112      &                       kpobsqc, kobsqc,  kosdobs,        & 
    1017       &                       klanobs, knlaobs, ld_nea          ) 
     1113      &                       klanobs, knlaobs, ld_nea,         & 
     1114      &                       kbdyobs, ld_bound_reject,         & 
     1115      &                       kqc_cutoff                        ) 
    10181116      !!---------------------------------------------------------------------- 
    10191117      !!                    ***  ROUTINE obs_coo_spc_3d  *** 
     
    10771175      INTEGER, INTENT(INOUT) :: klanobs     ! Observations within a model land cell 
    10781176      INTEGER, INTENT(INOUT) :: knlaobs     ! Observations near land 
     1177      INTEGER, INTENT(INOUT) :: kbdyobs     ! Observations near boundary 
    10791178      LOGICAL, INTENT(IN) :: ld_nea         ! Flag observations near land 
     1179      LOGICAL, INTENT(IN) :: ld_bound_reject  ! Flag observations near open boundary 
     1180      INTEGER, INTENT(IN) :: kqc_cutoff     ! Cutoff QC value 
     1181 
    10801182      !! * Local declarations 
    10811183      REAL(KIND=wp), DIMENSION(2,2,kpk,kprofno) :: & 
    10821184         & zgmsk              ! Grid mask 
     1185      REAL(KIND=wp), DIMENSION(2,2,kprofno) :: & 
     1186         & zbmsk              ! Boundary mask 
     1187      REAL(KIND=wp), DIMENSION(jpi,jpj) :: zbdymask 
    10831188      REAL(KIND=wp), DIMENSION(2,2,kpk,kprofno) :: & 
    10841189         & zgdepw 
     
    11001205         ! For invalid points use 2,2 
    11011206 
    1102          IF ( kpobsqc(jobs) >= 10 ) THEN 
     1207         IF ( kpobsqc(jobs) >= kqc_cutoff ) THEN 
    11031208             
    11041209            igrdi(1,1,jobs) = 1 
     
    11251230          
    11261231      END DO 
     1232 
     1233      IF (ln_bdy) THEN 
     1234        ! Create a mask grid points in boundary rim 
     1235        IF (ld_bound_reject) THEN            
     1236           zbdymask(:,:) = 1.0_wp 
     1237           DO ji = 1, nb_bdy 
     1238              DO jj = 1, idx_bdy(ji)%nblen(1) 
     1239                 zbdymask(idx_bdy(ji)%nbi(jj,1),idx_bdy(ji)%nbj(jj,1)) = 0.0_wp 
     1240              ENDDO 
     1241           ENDDO 
     1242        ENDIF 
     1243    
     1244        CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, zbdymask, zbmsk ) 
     1245      ENDIF 
    11271246       
    11281247      CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, pmask, zgmsk ) 
    11291248      CALL obs_int_comm_2d( 2, 2, kprofno, kpi, kpj, igrdi, igrdj, plam, zglam ) 
    11301249      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(:,:,:), & 
     1250      CALL obs_int_comm_3d( 2, 2, kprofno, kpi, kpj, kpk, igrdi, igrdj, gdepw_n(:,:,:), & 
    11341251        &                     zgdepw ) 
    1135       ENDIF 
    11361252 
    11371253      DO jobs = 1, kprofno 
    11381254 
    11391255         ! Skip bad profiles 
    1140          IF ( kpobsqc(jobs) >= 10 ) CYCLE 
     1256         IF ( kpobsqc(jobs) >= kqc_cutoff ) CYCLE 
    11411257 
    11421258         ! Check if this observation is on a grid point 
     
    11491265               IF ( ( ABS( zgphi(ji,jj,jobs) - pobsphi(jobs) ) < 1.0e-6_wp ) & 
    11501266                  & .AND. & 
    1151                   & ( ABS( zglam(ji,jj,jobs) - pobslam(jobs) ) < 1.0e-6_wp ) & 
     1267                  & ( ABS( MOD( zglam(ji,jj,jobs) - pobslam(jobs),360.0) ) < 1.0e-6_wp ) & 
    11521268                  & ) THEN 
    11531269                  lgridobs = .TRUE. 
     
    11761292               &  .OR. ( pobsdep(jobsp) < 0.0          )       & 
    11771293               &  .OR. ( pobsdep(jobsp) > gdepw_1d(kpk)) ) THEN 
    1178                kobsqc(jobsp) = kobsqc(jobsp) + 11 
     1294               kobsqc(jobsp) = IBSET(kobsqc(jobsp),11) 
    11791295               kosdobs = kosdobs + 1 
    11801296               CYCLE 
    11811297            ENDIF 
    11821298 
    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 
     1299            ! To check if an observations falls within land: 
    11871300              
    1188             IF( ln_zps .OR. ln_zco ) THEN !(CASE 1) 
     1301            ! Flag if the observation is deeper than the bathymetry 
     1302            ! Or if it is within the mask 
     1303            IF ( ALL( zgdepw(1:2,1:2,kpk,jobs) < pobsdep(jobsp) ) & 
     1304               &     .OR. & 
     1305               &  ( SUM( zgmsk(1:2,1:2,kobsk(jobsp)-1:kobsk(jobsp),jobs) ) & 
     1306               &  == 0.0_wp) ) THEN 
     1307               kobsqc(jobsp) = IBSET(kobsqc(jobsp),10) 
     1308               klanobs = klanobs + 1 
     1309               CYCLE 
     1310            ENDIF 
    11891311                
    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 
     1312            ! Flag if the observation is close to land 
     1313            IF ( ll_next_to_land ) THEN 
     1314               knlaobs = knlaobs + 1 
     1315               IF (ld_nea) THEN    
     1316                  kobsqc(jobsp) = IBSET(kobsqc(jobsp),10) 
     1317               ENDIF  
    12271318            ENDIF 
    12281319             
     
    12321323            IF (lgridobs) THEN 
    12331324               IF (zgmsk(iig,ijg,kobsk(jobsp)-1,jobs) == 0.0_wp ) THEN 
    1234                   kobsqc(jobsp) = kobsqc(jobsp) + 12 
     1325                  kobsqc(jobsp) = IBSET(kobsqc(jobs),10) 
    12351326                  klanobs = klanobs + 1 
    12361327                  CYCLE 
     
    12501341            ENDIF 
    12511342             
     1343            IF (ln_bdy) THEN 
     1344               ! Flag if the observation falls close to the boundary rim 
     1345               IF (ld_bound_reject) THEN 
     1346                  IF ( MINVAL( zbmsk(1:2,1:2,jobs) ) == 0.0_wp ) THEN 
     1347                     kobsqc(jobsp) = IBSET(kobsqc(jobs),8) 
     1348                     kbdyobs = kbdyobs + 1 
     1349                     CYCLE 
     1350                  ENDIF 
     1351                  ! for observations on the grid... 
     1352                  IF (lgridobs) THEN 
     1353                     IF (zbmsk(iig,ijg,jobs) == 0.0_wp ) THEN 
     1354                        kobsqc(jobsp) = IBSET(kobsqc(jobs),8) 
     1355                        kbdyobs = kbdyobs + 1 
     1356                        CYCLE 
     1357                     ENDIF 
     1358                  ENDIF 
     1359               ENDIF 
     1360            ENDIF 
     1361             
    12521362         END DO 
    12531363      END DO 
     
    12551365   END SUBROUTINE obs_coo_spc_3d 
    12561366 
    1257    SUBROUTINE obs_pro_rej( profdata ) 
     1367   SUBROUTINE obs_pro_rej( profdata, kqc_cutoff ) 
    12581368      !!---------------------------------------------------------------------- 
    12591369      !!                    ***  ROUTINE obs_pro_rej *** 
     
    12731383      !! * Arguments 
    12741384      TYPE(obs_prof), INTENT(INOUT) :: profdata     ! Profile data 
     1385      INTEGER, INTENT(IN) :: kqc_cutoff             ! QC cutoff value 
     1386 
    12751387      !! * Local declarations 
    12761388      INTEGER :: jprof 
     
    12821394      DO jprof = 1, profdata%nprof 
    12831395 
    1284          IF ( profdata%nqc(jprof) > 10 ) THEN 
     1396         IF ( profdata%nqc(jprof) > kqc_cutoff ) THEN 
    12851397             
    12861398            DO jvar = 1, profdata%nvar 
     
    12901402                   
    12911403                  profdata%var(jvar)%nvqc(jobs) = & 
    1292                      & profdata%var(jvar)%nvqc(jobs) + 26 
     1404                     & IBSET(profdata%var(jvar)%nvqc(jobs),14) 
    12931405 
    12941406               END DO 
     
    13021414   END SUBROUTINE obs_pro_rej 
    13031415 
    1304    SUBROUTINE obs_uv_rej( profdata, knumu, knumv ) 
     1416   SUBROUTINE obs_uv_rej( profdata, knumu, knumv, kqc_cutoff ) 
    13051417      !!---------------------------------------------------------------------- 
    13061418      !!                    ***  ROUTINE obs_uv_rej *** 
     
    13221434      INTEGER, INTENT(INOUT) :: knumu             ! Number of u rejected 
    13231435      INTEGER, INTENT(INOUT) :: knumv             ! Number of v rejected 
     1436      INTEGER, INTENT(IN) :: kqc_cutoff           ! QC cutoff value 
     1437 
    13241438      !! * Local declarations 
    13251439      INTEGER :: jprof 
     
    13411455         DO jobs = profdata%npvsta(jprof,1), profdata%npvend(jprof,1) 
    13421456             
    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 
     1457            IF ( ( profdata%var(1)%nvqc(jobs) >  kqc_cutoff ) .AND. & 
     1458               & ( profdata%var(2)%nvqc(jobs) <=  kqc_cutoff) ) THEN 
     1459               profdata%var(2)%nvqc(jobs) = IBSET(profdata%var(1)%nvqc(jobs),15) 
    13461460               knumv = knumv + 1 
    13471461            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 
     1462            IF ( ( profdata%var(2)%nvqc(jobs) >  kqc_cutoff ) .AND. & 
     1463               & ( profdata%var(1)%nvqc(jobs) <=  kqc_cutoff) ) THEN 
     1464               profdata%var(1)%nvqc(jobs) = IBSET(profdata%var(1)%nvqc(jobs),15) 
    13511465               knumu = knumu + 1 
    13521466            ENDIF 
Note: See TracChangeset for help on using the changeset viewer.