SUBROUTINE AS_DCOD ( cldt, bufrta, bufrtn, nhours, iret ) C************************************************************************ C* AS_DCOD * C* * C* This routine decodes bulletins containing EUMETSAT ASR SEVIRI * C* BUFR messages into NCEP BUFR format. * C* * C* AS_DCOD ( CLDT, BUFRTA, BUFRTN, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* BUFRTA CHAR* EUMETSAT ASR SEVIRI * 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 10/15 * C* J. Ator/NCEP 04/16 Updated in response to EUMETSAT changes * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' C* CHARACTER*(*) cldt, bufrta, bufrtn C* C* Number of expected descriptors within Section 3 for each C* EUMETSAT ASR SEVIRI BUFR message. C* PARAMETER ( NXDSC = 26 ) C* C* The following array will hold the list of expected descriptors C* within Section 3 for each EUMETSAT ASR SEVIRI BUFR message. C* CHARACTER cxdsc( NXDSC )*6 C* CHARACTER bull*(DCMXBF), cbull*(DCMXBF), bfstyp*8, + seqnum*8, buhd*8, cborg*8, bulldt*8, bbb*8, + rundt*12, sysdt*12, + logmsg*200 C* INTEGER irundt ( 5 ), irptdt ( 5 ), + ibull ( DCMXBF / 4 ) C* LOGICAL bullok C* PARAMETER ( MXMN = 30 ) PARAMETER ( MXLV = 11 ) C* REAL*8 r8in ( MXMN, MXLV ), r8out ( MXMN, MXLV ), + r8wk ( 66 ), r8bfms, GETBMISS C* EQUIVALENCE ( cbull (1:4), ibull (1) ) C* C* DATA ( cxdsc ( ii ), ii = 1, NXDSC ) + / '301072', + '030021', '030022', '007024', '007025', '010002', + '304036', '002152', '002167', '101011', '304037', + '222000', '236000', '101186', '031031', + '001031', '001032', '101066', '033007', + '224000', '237000', + '001031', '001032', '008023', '101066', '224255' / C* INCLUDE 'ERMISS.FNC' C*----------------------------------------------------------------------- iret = 0 C C* Open the EUMETSAT ASR SEVIRI 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 EUMETSAT ASR SEVIRI 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 EUMETSAT ASR SEVIRI BUFR tables and C* messages files. C CALL OPENBF ( iubfma, 'INUL', iubfta ) r8bfms = GETBMISS() C C* Close the EUMETSAT ASR SEVIRI 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 ) C C* Specify that NCEP BUFR (i.e. output) messages are to be C* compressed, edition 4, and up to 80K bytes in size. C CALL CMPMSG ( 'Y' ) C CALL PKVS01 ( 'BEN', 4 ) C CALL MAXOUT ( 80000 ) 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 ) CALL CLOSBF ( iubfma ) 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 IF ( bullok ) THEN 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 .ne. 0 ) THEN istart = ibptr + ipt1 - 1 cbull = bull ( istart : lenb ) ELSE bullok = .false. END IF END IF IF ( bullok ) THEN C C* Check for a corrupt BUFR message. C msglen = IUPBS01 ( ibull, 'LENM' ) IF ( ( msglen .gt. lenb ) .or. + ( cbull ( msglen-3 : msglen ) .ne. '7777' ) ) THEN bullok = .false. logmsg = 'ERROR: corrupt BUFR message' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) END IF END IF IF ( bullok ) THEN C C* Retrieve the Section 3 descriptors from the message C* and compare it with the list of expected descriptors. C CALL UT_CBS3 ( 2, ibull, cxdsc, NXDSC, 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 IF ( bullok ) THEN C C* Open the BUFR message. C CALL READERME ( ibull, iubfma, bfstyp, ibfdt, ierrme ) IF ( ierrme .ne. 0 ) THEN bullok = .false. END IF END IF C nrept = 0 C DO WHILE ( bullok ) 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 bullok = .false. C C* Print a count of the number of reports processed. C WRITE ( UNIT = logmsg, FMT = '( A, I6, A )' ) + 'contained ', nrept, ' 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, 'aseviri', 1, ierwbf ) ELSE nrept = nrept + 1 C CALL UFBSEQ ( iubfma, r8in, MXMN, MXLV, ier, + 'SIDENSEQ' ) 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 rptyr = UT_BMRI ( r8in ( 6, 1 ) ) rptmo = UT_BMRI ( r8in ( 7, 1 ) ) rptdy = UT_BMRI ( r8in ( 8, 1 ) ) rpthr = UT_BMRI ( r8in ( 9, 1 ) ) rptmi = UT_BMRI ( r8in (10, 1 ) ) IF ( ( ERMISS ( rptyr ) ) .or. + ( ERMISS ( rptmo ) ) .or. + ( ERMISS ( rptdy ) ) .or. + ( ERMISS ( rpthr ) ) .or. + ( ERMISS ( rptmi ) ) ) THEN iertmk = -1 ELSE irptdt (1) = INT ( rptyr ) irptdt (2) = INT ( rptmo ) irptdt (3) = INT ( rptdy ) irptdt (4) = INT ( rpthr ) irptdt (5) = INT ( rptmi ) CALL DC_TMCK ( 2, irundt, irptdt, nhours, 180, + iertmk ) END IF C IF ( iertmk .eq. 0 ) THEN C C* Open a BUFR message for output. C ibfdt = ( irptdt (1) * 1000000 ) + + ( irptdt (2) * 10000 ) + + ( irptdt (3) * 100 ) + irptdt (4) CALL OPENMB ( iubfmn, 'NC021042', ibfdt ) C C* Write all of the data values for this report. C C* Satellite identification, date and location. C CALL UFBSEQ ( iubfmn, r8in, MXMN, 1, ier, + 'SIDENSEQ') C C* Cloud coverage. C CALL UFBSEQ ( iubfma, r8in, MXMN, MXLV, ier, + 'CLOUDCOV' ) CALL UFBSEQ ( iubfmn, r8in, MXMN, 1, ier, + 'CLOUDCOV') C C* Pixel counts, geopotential, etc. C CALL UFBINT ( iubfma, r8in, MXMN, MXLV, ier, + 'NPPR NPPC SAZA SOZA HITE SIDP RDCM GNAP' ) CALL UFBINT ( iubfmn, r8in, MXMN, 1, ier, + 'NPPR NPPC SAZA SOZA HITE SIDP RDCM GNAP' ) C C* Brightness temperatures, standard deviations C* and percent confidences. C CALL UFBSEQ ( iubfma, r8in, MXMN, MXLV, ier, + 'ALLSKYRC' ) DO jj = 1, 11 r8out ( 1, jj ) = r8in ( 1, jj ) r8out ( 2, jj ) = r8in ( 2, jj ) r8out ( 3, jj ) = r8in ( 3, jj ) r8out ( 6, jj ) = r8in ( 4, jj ) r8out ( 7, jj ) = r8in ( 5, jj ) r8out (10, jj ) = r8in ( 6, jj ) r8out (11, jj ) = r8in ( 7, jj ) r8out (14, jj ) = r8in ( 8, jj ) r8out (15, jj ) = r8in ( 9, jj ) r8out (16, jj ) = r8in (10, jj ) r8out (19, jj ) = r8in (11, jj ) r8out (20, jj ) = r8in (12, jj ) r8out (23, jj ) = r8in (13, jj ) r8out (24, jj ) = r8in (14, jj ) r8out (27, jj ) = r8bfms END DO CALL UFBSEQ ( iubfma, r8wk, 1, 66, ier, + 'RPSEQ4' ) DO jj = 1, 11 r8out ( 5, jj ) = r8wk ( (jj-1)*6 + 1 ) r8out ( 9, jj ) = r8wk ( (jj-1)*6 + 2 ) r8out (13, jj ) = r8wk ( (jj-1)*6 + 3 ) r8out (18, jj ) = r8wk ( (jj-1)*6 + 4 ) r8out (22, jj ) = r8wk ( (jj-1)*6 + 5 ) r8out (26, jj ) = r8wk ( (jj-1)*6 + 6 ) END DO CALL UFBSEQ ( iubfma, r8wk, 1, 66, ier, + 'RPSEQ9' ) DO jj = 1, 11 r8out ( 4, jj ) = r8wk ( (jj-1)*6 + 1 ) r8out ( 8, jj ) = r8wk ( (jj-1)*6 + 2 ) r8out (12, jj ) = r8wk ( (jj-1)*6 + 3 ) r8out (17, jj ) = r8wk ( (jj-1)*6 + 4 ) r8out (21, jj ) = r8wk ( (jj-1)*6 + 5 ) r8out (25, jj ) = r8wk ( (jj-1)*6 + 6 ) END DO CALL UFBSEQ ( iubfmn, r8out, MXMN, 11, ier, + 'RPSEQ10' ) C C* Bulletin header. C CALL UT_CIBF ( iubfmn, 'SEQNUM', seqnum, 8, ier) CALL UT_CIBF ( iubfmn, 'BUHD', buhd, 8, ier ) CALL UT_CIBF ( iubfmn, 'BORG', cborg, 8, ier ) CALL UT_CIBF ( iubfmn, 'BULTIM', bulldt, 8, ier) CALL UT_CIBF ( iubfmn, 'BBB', bbb, 8, ier ) C C* Receipt time. C CALL UT_RIBF ( iubfmn, 'RCTS', FLOAT (0), ier ) CALL UT_RIBF ( iubfmn, 'RCYR', + FLOAT ( irundt (1) ), ier ) CALL UT_RIBF ( iubfmn, 'RCMO', + FLOAT ( irundt (2) ), ier ) CALL UT_RIBF ( iubfmn, 'RCDY', + FLOAT ( irundt (3) ), ier ) CALL UT_RIBF ( iubfmn, 'RCHR', + FLOAT ( irundt (4) ), ier ) CALL UT_RIBF ( iubfmn, 'RCMI', + FLOAT ( irundt (5) ), ier ) C C* Write the BUFR output to the BUFR output C* stream. C CALL UT_WBFR ( iubfmn, 'aseviri', 0, ierwbf ) END IF END IF END DO END DO C* RETURN END