SUBROUTINE EP_DCOD ( cldt, bufrta, bufrtn, nhours, iret ) C************************************************************************ C* EP_DCOD * C* * C* This routine decodes bulletins containing European wind profiler * C* BUFR messages into NCEP BUFR format. * C* * C* EP_DCOD ( CLDT, BUFRTA, BUFRTN, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* BUFRTA CHAR* European wind profiler * C* BUFR tables file * C* BUFRTN CHAR* NCEP 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* J. Ator/NCEP 03/06 * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'epcmn.cmn' C* CHARACTER*(*) cldt, bufrta, bufrtn C* C* Number of European wind profiler BUFR message formats. C* PARAMETER ( NBUFRF = 7 ) C* C* Number of expected descriptors within Section 3 for each C* European wind profiler BUFR message format. C* PARAMETER ( NXDSC01 = 33, NXDSC02 = 19, NXDSC03 = 9, + NXDSC04 = 31, NXDSC05 = 31, NXDSC06 = 33, + NXDSC07 = 31 ) C* C* The following array will hold the list of expected descriptors C* within Section 3 for each European wind profiler BUFR message C* format. The first dimension of this array must be at least as C* large as the largest of the above NXDSC values. C* CHARACTER cxdsc( NXDSC01, NBUFRF )*6 C* CHARACTER bull*(DCMXBF), cbull*(DCMXBF), bfstyp*8, + seqnum*8, buhd*8, cborg*8, bulldt*8, bbb*8, + rundt*12, sysdt*12, + r8mnem(NR8IMN)*8, rimnem(NRIMN)*8 C* INTEGER irundt ( 5 ), irptdt ( 5 ), + nxdsc ( NBUFRF ), + ibull ( DCMXBF / 4 ) C* LOGICAL bullok, msgok, corr, corm C* REAL*8 GETBMISS C* EQUIVALENCE ( cbull (1:4), ibull (1) ) C* DATA ( nxdsc ( ii ), ii = 1, NBUFRF ) + / NXDSC01, NXDSC02, NXDSC03, + NXDSC04, NXDSC05, NXDSC06, + NXDSC07 / C* DATA ( cxdsc ( ii, 1 ), ii = 1, NXDSC01 ) + / '301032', '002003', '002101', '201130', '002106', + '201000', '201132', '202130', '002121', '202000', + '201000', '201133', '202129', '025001', '202000', + '201000', '025020', '025021', '008021', '004025', + '111000', '031001', '007007', '204001', '031021', + '011001', '204000', '011002', '204001', '031021', + '011006', '204000', '021030' / C* DATA ( cxdsc ( ii, 2 ), ii = 1, NXDSC02 ) + / '301032', '321021', '025020', '025021', '008021', + '004025', '111000', '031001', '007007', '204001', + '031021', '011001', '204000', '011002', '204001', + '031021', '011006', '204000', '021030' / C* DATA ( cxdsc ( ii, 3 ), ii = 1, NXDSC03 ) + / '301032', '321021', '025020', '025021', '008021', + '004025', '101000', '031001', '321022' / C* DATA ( cxdsc ( ii, 4 ), ii = 1, NXDSC04 ) + / '301032', '002003', '002101', '002106', '201132', + '202130', '002121', '202000', '201000', '201133', + '202129', '025001', '202000', '201000', '025020', + '025021', '008021', '004025', '111000', '031001', + '007007', '204001', '031021', '011001', '204000', + '011002', '204001', '031021', '011006', '204000', + '021030' / C* DATA ( cxdsc ( ii, 5 ), ii = 1, NXDSC05 ) + / '301032', '002003', '002101', '002106', '201130', + '202131', '002121', '202000', '201000', '201133', + '202129', '025001', '202000', '201000', '025020', + '025021', '008021', '004025', '111000', '031001', + '007007', '204001', '031021', '011001', '204000', + '011002', '204001', '031021', '011006', '204000', + '021030' / C* DATA ( cxdsc ( ii, 6 ), ii = 1, NXDSC06 ) + / '301032', '002003', '002101', '201130', '002106', + '201000', '201129', '202135', '002121', '202000', + '201000', '201129', '202129', '025001', '202000', + '201000', '025020', '025021', '008021', '004025', + '111000', '031001', '007007', '204001', '031021', + '011001', '204000', '011002', '204001', '031021', + '011006', '204000', '021030' / C* DATA ( cxdsc ( ii, 7 ), ii = 1, NXDSC07 ) + / '301032', '002003', '002101', '002106', '201132', + '202130', '002121', '202000', '201000', '201133', + '202129', '025001', '202000', '201000', '025020', + '025021', '008021', '004025', '111000', '031001', + '010007', '204001', '031021', '011001', '204000', + '011002', '204001', '031021', '011006', '204000', + '021030' / C* INCLUDE 'ERMISS.FNC' C*----------------------------------------------------------------------- iret = 0 CALL UT_PRVS ( 'DECOD_DCEPFL v3.0.0' ) C C* Set the pointers for the interface arrays. C CALL EP_IFSP ( r8mnem, rimnem, ierfsp ) IF ( ierfsp .ne. 0 ) THEN RETURN END IF C C* Open the European wind profiler 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 European wind profiler 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 European wind profiler BUFR tables and C* messages files. C CALL OPENBF ( iubfma, 'INUL', iubfta ) C C* Close the European wind profiler 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 BUFR (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 BUFR (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 BUFR (i.e. output) stream. C CALL OPENBF ( iubfmn, 'NUL', iubftn ) r8bfms = GETBMISS() C C* Close the tables file for the NCEP BUFR (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 ) DO ii = 1, NBUFRF CALL CLOSBF ( iubfma ) END DO CALL CLOSBF ( iubfmn ) CALL FL_CLAL ( iercal ) RETURN END IF C bullok = .true. 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 DO WHILE ( bullok ) C C* Locate the next BUFR message within the bulletin, C* and store it within an equivalenced integer array. C ipt1 = INDEX ( bull ( ibptr : lenb ), 'BUFR' ) IF ( ipt1 .eq. 0 ) THEN C C* There are no more BUFR messages within the bulletin. C bullok = .false. 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, 'epflr', 1, ierwbf ) C ELSE istart = ibptr + ipt1 - 1 ibptr = istart + 4 cbull = bull ( istart : lenb ) C nrept = 0 C C* Determine which format this BUFR message corresponds C* to, and then overwrite the message subtype in order C* to match the correct corresponding subtype within C* the European wind profiler BUFR tables file. C ii = 1 msgok = .false. DO WHILE ( ( .not. msgok ) .and. + ( ii .le. NBUFRF ) ) CALL UT_CBS3 ( 4, ibull, cxdsc ( 1, ii ), + nxdsc ( ii ), iercs3 ) IF ( iercs3 .eq. 0 ) THEN msgok = .true. IF ( ( ii .ge. 1 ) .and. ( ii .le. 3 ) ) THEN nstyp = 1 ELSE IF ( ii .eq. 7 ) THEN nstyp = 2 ELSE nstyp = ii - 2 END IF WRITE ( UNIT = logmsg, + FMT = '( 2A, I3.3, 2A )' ) + 'message format corresponds to BUFR ', + 'subtype ', nstyp, ' within ', bufrta CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) CALL PKBS1 ( nstyp, ibull, 'MSBT' ) ELSE ii = ii + 1 END IF END DO C IF ( msgok ) THEN C C* Open this BUFR message. C CALL READERME ( ibull, iubfma, + bfstyp, ibfdt, ierrme ) IF ( ierrme .eq. 0 ) THEN corm = ( IUPBS01 ( ibull, 'USN' ) .gt. 0 ) + .or. ( bbb (1:1) .eq. 'C' ) ELSE msgok = .false. END IF ELSE logmsg = 'message has unknown format' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) END IF C DO WHILE ( msgok ) C C* Get the next report from this BUFR message. C IF ( IREADSB ( iubfma ) .ne. 0 ) THEN C C* There are no more reports in this message. C msgok = .false. C C* Print a count of the number of reports processed. C WRITE ( UNIT = logmsg, FMT = '( A, I4, A )' ) + 'contained ', nrept, ' reports' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) C ELSE nrept = nrept + 1 C logmsg = '-----------------------------------' CALL DC_WLOG ( 3, 'DC', 2, logmsg, ierwlg ) C C* Initialize the interface arrays. C CALL EP_IFIV ( ierifi ) C C* Decode the report into the interface arrays. C corr = .false. CALL EP_BFIF ( iubfma, corr, ierbif ) C C* Write data for this report to the decoder log. C CALL EP_IFPT ( 3, r8mnem, rimnem, 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 C* report into BUFR output and then write the C* BUFR output to the BUFR output stream. C CALL EP_BUFR ( iubfmn, irundt, seqnum, + buhd, cborg, bulldt, bbb, + corr, corm, ierbfr ) END IF C END IF END DO END IF END DO END DO C* RETURN END