!--------------------------------------- LICENCE BEGIN -----------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
! version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
SUBROUTINE BGCDATA(PJO,CDFAM,lobsSpaceData) 9,42
!*
!***s/r BGCDATA - Computation OF BACKGROUND CHECK FLAGS
!*
!*Author : P. Koclas *CMC/CMDA January 1999
!*
!** Purpose: -Calculate a background check for a data family
!* AND SET the appropriate quality control flags in
!* the CMA
!*
use MathPhysConstants_mod
use bufr
use obsSpaceData_mod
use modgpsztd_mod
IMPLICIT NONE
!*
!C NOTE 1: YSFERRWGT IN MODGPSZTD_MOD (FROM NML FILE) IS USED HERE FOR ERROR WEIGHTING
!C OF TIME SERIES (FGAT) GPS MET OBSERVATIONS PS, TS, DPDS. IT IS APPLIED
!C (ALONG WITH YZDERRWGT FOR ZTD) IN S/R SETERR AS A MULT. FACTOR TO ERRORS.
!C YZDERRWGT AND YSFERRWGT = 1 FOR NORMAL 3D-VAR (3D-THINNING).
!C
!C NOTE 2: GPS ZTD OBS ERROR SIGMAO IS BASED ON STD(O-P) SO INCLUDES CONTRIBUTION FROM
!C BACKGROUND ERROR SIGMAP. THUS A MAX LIMIT IS PLACED ON SIGMAO (12 MM).
!C
!C
type(struct_obs) :: lobsSpaceData
REAL*8 PJO,zsum,zsumo
CHARACTER*2 CDFAM
INTEGER IFLAG,INAM,ISETFLAG,INDEX_HEADER,IDBURP
INTEGER IBEGIN,ILAST,ierr,fclos,fnom,ITYP
INTEGER J,J2,JJ,JD,INDEX_BODY,icoun
INTEGER INOBS, INREJ, INZOBS, INZREJ
INTEGER INPOBS, INTOBS, INDOBS, INPREJ, INTREJ, INDREJ
REAL*8 ZOER,ZOMP,ZFGE,ZBGCHK,ZVAR,ZLEV,ZLAT,ZLON,ZSOP
LOGICAL LLOK, LLZD, LMODIF1020
! MAX LIMIT IS PLACED ON ZTD SIGMAO (12 MM)
REAL*8 ZDSIGMAO
DATA ZDSIGMAO / 0.012D0 /
lmodif1020=.false.
WRITE(*,*)' '
WRITE(*,*)' ------------------------------'
WRITE(*,*)' BACKGROUND CHECK FOR'
WRITE(*,*)' ',CDFAM, ' DATA'
WRITE(*,*)' ------------------------------'
WRITE(*,*)' '
WRITE(*,'(a55,a74)')' STNID LATITU LONGITU ID Elem Level ', &
' Value Sigmao Sigmap O-P SigmaOP qcflag '
WRITE(*,'(a55,a74)')' ----- ------ ------- -- ---- ----- ', &
' ----- ------ ------ --- ------- ------ '
icoun=0
zsum=0.D0
zsumo=0.D0
PJO=-99.99D0
INOBS=0
INREJ=0
!C
!C* Initialize counters for GP family observations
!C
IF (CDFAM .EQ. 'GP') THEN
INZOBS=0
INPOBS=0
INTOBS=0
INDOBS=0
INZREJ=0
INPREJ=0
INTREJ=0
INDREJ=0
ENDIF
! loop over all header indices of the CDFAM family
call obs_set_current_header_list
(lobsSpaceData,CDFAM)
HEADER: do
index_header = obs_getHeaderIndex
(lobsSpaceData)
if (index_header < 0) exit HEADER
!C
!C* 1. Computation of (HX - Z)**2/(SIGMAo**2 +SIGMAp**2)
!C . ----------------------------------------------------
!C
! loop over all body indices for this index_header
call obs_set_current_body_list
(lobsSpaceData, index_header)
BODY: do
index_body = obs_getBodyIndex(lobsSpaceData)
if (index_body < 0) exit BODY
ITYP = obs_bodyElem_i
(lobsSpaceData,OBS_VNM,index_body)
LLOK=( obs_bodyElem_i
(lobsSpaceData,OBS_ASS,index_body) .EQ. 1)
IF ( LLOK ) THEN
INOBS = INOBS + 1
IF (CDFAM .EQ. 'GP') THEN
IF (ITYP .EQ. BUFR_NEZD) INZOBS = INZOBS+1
IF (ITYP .EQ. BUFR_NEPS) INPOBS = INPOBS+1
IF (ITYP .EQ. BUFR_NETS) INTOBS = INTOBS+1
IF (ITYP .EQ. BUFR_NESS) INDOBS = INDOBS+1
ENDIF
ZVAR = obs_bodyElem_r
(lobsSpaceData,OBS_VAR,index_body)
ZLEV = obs_bodyElem_r
(lobsSpaceData,OBS_PPP,index_body)
ZOER = obs_bodyElem_r
(lobsSpaceData,OBS_OER,index_body)
ZLAT = obs_headElem_r
(lobsSpaceData,OBS_LAT,index_header) &
* MPC_DEGREES_PER_RADIAN_R8
ZLON = obs_headElem_r
(lobsSpaceData,OBS_LON,index_header) &
* MPC_DEGREES_PER_RADIAN_R8
!C
!C BACK GROUND CHECK
!C
ZOMP = obs_bodyElem_r
(lobsSpaceData,OBS_OMP,index_body)
ZFGE = obs_bodyElem_r
(lobsSpaceData,OBS_HPHT,index_body)
IF ( CDFAM .EQ. 'GP' ) THEN
IF (ITYP .EQ. BUFR_NEZD) THEN
ZOER = ZOER/YZDERRWGT
!C IF YZTDERR (FROM modgpsztd_mod) = 0 THEN ZTD ERROR MODEL IS REGRESSION-BASED
!C (WHERE ERROR IS A FUNCTION OF ZWD) SO WE LIMIT THE OBSERVATION ERROR
IF (YZTDERR .EQ. 0.0D0) THEN
ZOER = MIN(ZDSIGMAO, ZOER)
ENDIF
ELSE
ZOER = ZOER/YSFERRWGT
ENDIF
IF (ZFGE .LT. 1.D-3 .OR. ZOER .LT. 1.D-3 ) THEN
WRITE(*,*)' Problem for STNID FGE ZOER=', &
obs_elem_c
(lobsSpaceData,'STID',index_header),ZFGE,ZOER
CALL ABORT3D
('BGCDATA: PROBLEM WITH FGE, OER.')
ENDIF
ELSE
IF ( ZFGE**2 + ZOER**2 .LT. 1.D-5)THEN
WRITE(*,*)' Problem for STNID FGE ZOER=', &
obs_elem_c
(lobsSpaceData,'STID',index_header),ZFGE,ZOER
ZFGE=1.D-5
ZOER=1.D-5
ENDIF
ENDIF
ZBGCHK=(ZOMP)**2/(ZFGE**2 + ZOER**2)
ZSOP = SQRT(ZFGE**2 + ZOER**2)
!C
!C UPDATE QUALITY CONTROL FLAGS
!C ( ELEMENT FLAGS + GLOBAL HEADER FLAGS)
!C
INAM =obs_bodyElem_i
(lobsSpaceData,OBS_VNM,index_body)
if( inam.eq.12192 .and. obs_bodyElem_i
(lobsSpaceData,OBS_XTR,index_body).eq.0)then
zsum=zsum+zfge*zfge
zsumo=zsumo+zoer*zoer
icoun=icoun+1
endif
IDBURP=obs_headElem_i
(lobsSpaceData,OBS_ITY,INDEX_HEADER)
IFLAG=ISETFLAG
(CDFAM,IDBURP,INAM,ZLEV,ZBGCHK,LMODIF1020)
!C
!C CONVERT ZTD VALUES FROM M TO MM FOR PRINTOUT
!C
LLZD = .FALSE.
IF ( CDFAM .EQ. 'GP' .AND. ITYP .EQ. BUFR_NEZD) THEN
ZVAR = ZVAR * 1000.0D0
ZOER = ZOER * 1000.0D0
ZFGE = ZFGE * 1000.0D0
ZOMP = ZOMP * 1000.0D0
ZSOP = ZSOP * 1000.0D0
LLZD = .TRUE.
ENDIF
IF (IFLAG .GE. 2 .OR. (LLZD .AND. LTESTOP)) THEN
WRITE(*,122) &
obs_elem_c
(lobsSpaceData,'STID',index_header), &
zlat,zlon,IDBURP,INAM,ZLEV,ZVAR,ZOER &
,ZFGE,ZOMP,ZSOP,ZBGCHK,IFLAG
IF (IFLAG .GE. 2) INREJ = INREJ + 1
IF (IFLAG .GE. 2 .AND. CDFAM .EQ. 'GP') THEN
IF (ITYP .EQ. BUFR_NEZD) INZREJ = INZREJ+1
IF (ITYP .EQ. BUFR_NEPS) INPREJ = INPREJ+1
IF (ITYP .EQ. BUFR_NETS) INTREJ = INTREJ+1
IF (ITYP .EQ. BUFR_NESS) INDREJ = INDREJ+1
ENDIF
ENDIF
IF ( IFLAG .EQ. 1 ) THEN
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),13))
ELSEIF ( IFLAG .EQ. 2 ) THEN
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),14))
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),16))
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),09))
call obs_headSet_i
(lobsSpaceData,OBS_ST1,index_header,ibset(obs_headElem_i
(lobsSpaceData,OBS_ST1,index_header),06))
ELSEIF ( IFLAG .EQ. 3 ) THEN
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),15))
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),16))
call obs_bodySet_i
(lobsSpaceData,OBS_FLG,index_body,IBSET(obs_bodyElem_i
(lobsSpaceData,OBS_FLG,index_body),09))
call obs_headSet_i
(lobsSpaceData,OBS_ST1,index_header,ibset(obs_headElem_i
(lobsSpaceData,OBS_ST1,index_header),06))
ENDIF
ENDIF
ENDDO BODY
122 FORMAT(2x,a9,1x,f6.2,1x,f7.2,1x,I3,1x,I5,7(2x,F11.2),I3 )
ENDDO HEADER
IF ( INOBS .GT. 0 ) THEN
WRITE(*,*)' '
WRITE(*,*) ' BGCDATA: FINISHED BGCHECK OF ',CDFAM, ' DATA'
WRITE(*,123) 'BGCDATA: ',INREJ, ' OBSERVATIONS REJECTED OUT OF ', INOBS
WRITE(*,*)' '
ENDIF
IF ( (INOBS .GT. 0) .AND. (CDFAM .EQ. 'GP') ) THEN
WRITE(*,*)' '
WRITE(*,*) ' BGCDATA: REPORT FOR GP FAMILY OF OBSERVATIONS'
WRITE(*,123) 'BGCDATA: ',INZREJ, ' ZTD OBSERVATIONS REJECTED OUT OF ', INZOBS
WRITE(*,123) 'BGCDATA: ',INPREJ, ' PSFC OBSERVATIONS REJECTED OUT OF ', INPOBS
WRITE(*,123) 'BGCDATA: ',INTREJ, ' TSFC OBSERVATIONS REJECTED OUT OF ', INTOBS
WRITE(*,123) 'BGCDATA: ',INDREJ, ' DPDS OBSERVATIONS REJECTED OUT OF ', INDOBS
WRITE(*,*)' '
ENDIF
123 FORMAT(2X,A,I0,A,I0)
WRITE(*,*)' '
WRITE(*,*)' ---------------------------'
WRITE(*,*)' DONE BGCDATA '
WRITE(*,*)' ---------------------------'
WRITE(*,*)' '
if ( icoun .gt. 0) then
write(*,*) ' icoun meanfge=',icoun,zsum/icoun
write(*,*) ' icoun meanzoer',icoun,zsumo/icoun
endif
RETURN
END SUBROUTINE BGCDATA