SUBROUTINE GP_DCOD ( cldt, bufrta, bufrtn, nhours, iret ) C************************************************************************ C* GP_DCOD * C* * C* This routine decodes bulletins containing GPS Precipitable Water * C* BUFR messages into NCEP BUFR format. * C* * C* GP_DCOD ( CLDT, BUFRTA, BUFRTN, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* BUFRTA CHAR* GPS PW BUFR tables file * C* BUFRTN CHAR* NCEP GPS PW BUFR tables file * C* NHOURS INTEGER Max # of hours before run time * C* for creating BUFR output * C* * C* Output parameters: * C* IRET INTEGER Return code: * C* 0 = normal return * C* * C** * C* Log: * C* C. Caruso Magee/NCEP 03/01 Modifying for dcgpsw. * C* C. Caruso Magee/NCEP 06/01 Replace calls to STATUS, WRITSA, and * C* DBN_BUFR with new s/r UT_WBFR. * C* J. Ator/NCEP 06/01 Use 'NUL' in call to OPENBF * C* C. Caruso Magee/NCEP 11/01 Added logmsg if bad input BUFR format * C* message was received. * C* J. Ator/NCEP 01/02 Remove gpcmn_bufr.cmn * C* J. Ator/NCEP 08/02 Create .dummy subdirectory for OPENBF * C* C. Caruso Magee/NCEP 01/04 Replace old s/r READERS with READSB * C* J. Ator/NCEP 08/04 SS_GTIM -> CSS_GTIM * C* C. Caruso Magee/NCEP 02/06 Replace IUPBS1 with IUPBS01 and modify * C* input args appropriately. * C* J. Ator/NCEP 12/12 Use IO='INUL' in OPENBF call to * C* preclude use of .dummy file * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'gpcmn.cmn' C* CHARACTER*(*) cldt, bufrta, bufrtn C* CHARACTER bull*(DCMXBF), cbull*(DCMXBF), bfstyp*8, + seqnum*8, buhd*8, cborg*8, bulldt*8, bbb*8, + rundt*12, sysdt*12, + rimnem(NRIMN)*8, cimnem(NCIMN)*8 C* INTEGER irundt (5), irptdt (5), ibull ( DCMXBF / 4 ) C* REAL corn C* LOGICAL bullok C* EQUIVALENCE ( cbull (1:4), ibull (1) ) C* C* Expected descriptors within Section 3 of an C* GPS PW BUFR message. C* PARAMETER ( NXDESC = 25 ) CHARACTER cxdesc(NXDESC)*6 C* DATA cxdesc + / '206032', '001194', '301022', '301011', + '301012', '010004', '012001', '013003', + '206016', '025220', '206009', '025221', + '206016', '025222', '206009', '025223', + '202131', '201138', '013016', '201000', + '202000', '206016', '025224', '206013', + '025225' / C* INCLUDE 'ERMISS.FNC' C*----------------------------------------------------------------------- iret = 0 CALL UT_PRVS ( 'DECOD_DCGPSW v3.0.0' ) C C* Set the pointers for the interface arrays. C CALL GP_IFSP ( rimnem, cimnem, ierfsp ) IF ( ierfsp .ne. 0 ) THEN RETURN ENDIF C C* Open the GPS PW BUFR tables file. C CALL FL_SOPN ( bufrta, iubfta, ierspn ) IF ( ierspn .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', ierspn, bufrta, ierwlg ) RETURN END IF C C* Open the GPS PW BUFR messages file. C CALL FL_GLUN ( iubfma, iergln ) IF ( iergln .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iergln, ' ', ierwlg ) RETURN END IF C C* Connect the GPS PW BUFR tables and messages files. C CALL OPENBF ( iubfma, 'INUL', iubfta ) C C* Close the GPS PW BUFR tables file. C CALL FL_CLOS ( iubfta, iercls ) IF ( iercls .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iercls, ' ', ierwlg ) END IF C C* Open the tables file for the NCEP GPS PW BUFR C* (i.e. output) stream. C CALL FL_SOPN ( bufrtn, iubftn, ierspn ) IF ( ierspn .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', ierspn, bufrtn, ierwlg ) RETURN END IF C C* Open the messages file for the NCEP GPS PW BUFR C* (i.e. output) stream. C CALL FL_GLUN ( iubfmn, iergln ) IF ( iergln .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iergln, ' ', ierwlg ) RETURN END IF C C* Connect the tables and messages files for the C* NCEP GPS PW BUFR (i.e. output) stream. C CALL OPENBF ( iubfmn, 'NUL', iubftn ) C C* Close the tables file for the NCEP GPS PW BUFR C* (i.e. output) stream. C CALL FL_CLOS ( iubftn, iercls ) IF ( iercls .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iercls, ' ', ierwlg ) END IF C DO WHILE ( .true. ) C C* Get a new bulletin from the input pipe. C CALL DC_GBUL ( bull, lenb, ifdtyp, iergbl ) IF ( iergbl .ne. 0 ) THEN C C* A time-out occurred while waiting for a new bulletin C* on the input pipe. Shut down the decoder and exit. C CALL DC_WLOG ( 0, 'DC', iergbl, ' ', ierwlg ) CALL CLOSBF ( iubfma ) CALL CLOSBF ( iubfmn ) CALL FL_CLAL ( iercal ) RETURN END IF bullok = .true. nrept = 0 C C* Decode the header information from this bulletin. C IF ( ifdtyp .eq. 0 ) THEN C C* Decode WMO products. C CALL DC_GHDR ( bull, lenb, seqnum, buhd, cborg, + bulldt, bbb, ibptr, ierghd ) IF ( ierghd .ne. 0 ) THEN CALL DC_WLOG ( 2, 'DC', ierghd, ' ', ierwlg ) bullok = .false. ELSE C C* Start an entry for this bulletin in the decoder log. C logmsg = '####################' // + '####################' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) logmsg = seqnum // buhd // cborg // bulldt // bbb CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) END IF ELSE C C* Do not decode AFOS products. C bullok = .false. END IF IF ( bullok ) THEN C C* Get the system time. C itype = 1 CALL CSS_GTIM ( itype, sysdt, iergtm ) IF ( iergtm .ne. 0 ) THEN CALL DC_WLOG ( 2, 'SS', iergtm, ' ', ierwlg ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* If a date-time was entered on the command line, then C* use it as the run date-time. Otherwise, use the C* system time as the run date-time. C IF ( cldt .eq. 'SYSTEM' ) THEN rundt = sysdt ELSE CALL TI_STAN ( cldt, sysdt, rundt, ierstn ) IF ( ierstn .ne. 0 ) THEN CALL DC_WLOG ( 2, 'TI', ierstn, ' ', ierwlg ) bullok = .false. END IF END IF END IF IF ( bullok ) THEN C C* Convert the run date-time to integer. C CALL TI_CTOI ( rundt, irundt, iercto ) IF ( iercto .ne. 0 ) THEN CALL DC_WLOG ( 2, 'TI', iercto, ' ', ierwlg ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Locate the GPS PW BUFR message within the bulletin, C* and store it within an equivalenced integer array. C ipt1 = INDEX ( bull ( ibptr : lenb ), 'BUFR' ) IF ( ipt1 .ne. 0 ) THEN istart = ibptr + ipt1 - 1 cbull = bull ( istart : lenb ) ELSE bullok = .false. END IF END IF IF ( bullok ) THEN C C* Open the GPS PW BUFR message. C CALL READERME ( ibull, iubfma, bfstyp, ibfdt, ierrme ) IF ( ierrme .ne. 0 ) THEN bullok = .false. ELSE C C* Check update sequence number of Section 1 to see C* if correction is indicated. If this bulletin is C* a correction, 'corn' will be set to a non-zero C* value so CORN may be set within GP_BUFR. C corn = FLOAT ( IUPBS01 ( ibull, 'USN' ) ) IF ( corn .gt. 0.0 ) corn = 1.0 C C* Retrieve the Section 3 descriptors from this GPS C* PW BUFR message and compare it with the list of C* expected descriptors. C CALL UT_CBS3 ( 2, ibull, cxdesc, NXDESC, iercs3 ) IF ( iercs3 .ne. 0 ) THEN bullok = .false. logmsg = 'message has unknown format' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) END IF END IF END IF C DO WHILE ( bullok ) C C* Get the next report from this GPS PW BUFR message. C CALL READSB ( iubfma, ierrsb ) IF ( ierrsb .ne. 0 ) THEN C C* There are no more reports in this message. C bullok = .false. C C* Print a count of the number of reports processed. C WRITE ( UNIT = logmsg, FMT = '( A, I4, A )' ) + 'contained ', nrept, ' GPS PW reports' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) C C* Make sure that all BUFR output for this bulletin C* has been written to the BUFR output stream before C* going back to DC_GBUL and waiting for a new bulletin C* on the input pipe. C CALL UT_WBFR ( iubfmn, 'gpspw', 1, ierdbf ) ELSE nrept = nrept + 1 C C* Initialize the interface arrays. C CALL GP_IFIV ( ierifi ) C C* Decode the report into the interface arrays. C CALL GP_BFIF ( iubfma, ierbif ) C C* Write data for this report to the decoder log. C CALL GP_IFPT ( rimnem, cimnem, ierifp ) C C* Do not create BUFR output for reports that are C* more than NHOURS before or more than 3 hours C* after the run time. C IF ( ( ERMISS ( rivals ( iryear ) ) ) .or. + ( ERMISS ( rivals ( irmnth ) ) ) .or. + ( ERMISS ( rivals ( irdays ) ) ) .or. + ( ERMISS ( rivals ( irhour ) ) ) .or. + ( ERMISS ( rivals ( irminu ) ) ) ) THEN iertmk = -1 ELSE irptdt (1) = INT ( rivals ( iryear ) ) irptdt (2) = INT ( rivals ( irmnth ) ) irptdt (3) = INT ( rivals ( irdays ) ) irptdt (4) = INT ( rivals ( irhour ) ) irptdt (5) = INT ( rivals ( irminu ) ) CALL DC_TMCK ( 2, irundt, irptdt, nhours, 180, + iertmk ) END IF IF ( iertmk .eq. 0 ) THEN C C* Convert interface-format data for this report C* into BUFR output and then write the BUFR output C* to the BUFR output stream. C CALL GP_BUFR ( iubfmn, irundt, seqnum, buhd, + cborg, bulldt, bbb, corn, ierbfr ) ENDIF C logmsg = '-----------------------------------' CALL DC_WLOG ( 3, 'DC', 2, logmsg, ierwlg ) END IF END DO END DO C* RETURN END