SUBROUTINE GF_DCOD ( cldt, bufrta, bufrtn, bufrfn, * nhours, iret ) C************************************************************************ C* GF_DCOD * C* * C* This routine decodes bulletins containing GFO Fast Delivery and * C* ENVISAT BUFR messages into NCEP BUFR format. * C* * C* GF_DCOD ( CLDT, BUFRTA, BUFRTN, BUFRFN, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* BUFRTA CHAR* GFO FD BUFR table file * C* BUFRTN CHAR* NCEP BUFR table file * C* BUFRFN CHAR* GFO FD BUFR data 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 05/06 * C* C. Caruso Magee/NCEP 08/06 Modify to use update sequence number in * C* place of hardcoded byte 7 of Sec. 1. * C* L. Sager/NCEP 04/07 Added ENVISAT bufr type 031/108 * C* C. Caruso Magee/NCEP 05/07 Added ENVISAT filename 'enf_' to be * C* stored into b031/xx108. * C* C. Caruso Magee/NCEP 06/07 Added JASON-1 filename 'jso_' to be * C* stored into b031/xx110. * C* C. Caruso Magee/NCEP 06/07 correct how filename is searched for * C* particular patterns (since full path is * C* included, not just filename itself). * C* S. Guan/NCEP 02/09 Added JASON-2 filename 'js2_' to be * C* stored into b031/xx114. * C S. Guan/NCEP 09/09 Adopting new BUFR4 formatted wind/wave. * C* J. Ator/NCEP 12/12 Use IO='INUL' in OPENBF call to * C* preclude use of .dummy file * C* J. Ator/NCEP 08/13 Added cr2,atk as b031/xx120,121 * C* J. Ator/NCEP 08/16 Added js3 as b031/xx127 * C* M. Weiss/NCEP IMSG 07/17 Added s3a Sentinel 3a Significant Wave * C* Height and Marine Wind Speed. * C* J. Ator/NCEP 03/20 Added s3b as b031/xx133 * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'gfcmn.cmn' C* PARAMETER ( mxbufr = 600000 ) PARAMETER ( mxbufrd4 = mxbufr/4 ) INTEGER DCMXBF2 PARAMETER ( DCMXBF2 = 600000 ) C* CHARACTER*(*) cldt, bufrta, bufrtn, bufrfn C* CHARACTER bull*(DCMXBF2), cbull*(DCMXBF2), bfstyp*8, + rundt*12, sysdt*12, cbf, bfstmf*8, + rimnem(NRIMN)*8, + bufrtf*(DCMXLN), + bufrfnd*(DCMXLN), bufrfnb*(DCMXLN) C* CHARACTER*80 bfile CHARACTER*1 bufr(mxbufr) DIMENSION mbay(mxbufrd4) REAL corn C* INTEGER irundt ( 5 ), irptdt ( 5 ), + iubfmf, iubftf, + nxdsc, + ibull ( DCMXBF2 / 4 ) C* LOGICAL bullok C* EQUIVALENCE ( cbull (1:4), ibull (1) ) EQUIVALENCE ( bufr(1), mbay(1) ) C* C* Number of expected descriptors within Section 3 of each C* type of non-NCEP BUFR message. C* PARAMETER ( NXDSCA = 19 ) C* C* The following array will hold the list of expected descriptors C* within Section 3 of each type of non-NCEP BUFR message. C* The first dimension of this array must be at least as large C* as the largest of the above NXDSC values. C* CHARACTER cxdsc( NXDSCA )*6 C* C* Expected descriptors within Section 3 of an IGDR BUFR message. C* DATA ( cxdsc ( ii ), ii = 1, NXDSCA ) + / '001007', '004001', '004002', '004003', '004004', '004005', + '004006', '005002', '006002', '011012', '022021', '022026', + '010033', '021071', '021077', '021078', '021079', '021082', + '021062' / C* INCLUDE 'ERMISS.FNC' C*----------------------------------------------------------------------- iret = 0 C C* Get the path of the master table file in /fix. C CALL FL_PATH ( bufrfn, bufrfnd, bufrfnb, ierpth ) logmsg = 'GFO FD Filename: '// bufrfnb CALL DC_WLOG ( 0, 'DC', 2, logmsg, ierwlg ) C C* Verify that this is a file we know how to process. C IF ( ( bufrfnb (1:3) .eq. 'env' ) .or. + ( bufrfnb (1:3) .eq. 'enf' ) ) THEN bfstyp = 'NC031108' ELSEIF ( bufrfnb (1:3) .eq. 'jso' ) THEN bfstyp = 'NC031110' ELSEIF ( bufrfnb (1:3) .eq. 'js2' ) THEN bfstyp = 'NC031114' ELSEIF ( bufrfnb (1:3) .eq. 'cr2' ) THEN bfstyp = 'NC031120' ELSEIF ( bufrfnb (1:3) .eq. 'atk' ) THEN bfstyp = 'NC031121' ELSEIF ( bufrfnb (1:3) .eq. 'js3' ) THEN bfstyp = 'NC031127' ELSEIF ( bufrfnb (1:3) .eq. 's3a' ) THEN bfstyp = 'NC031130' ELSEIF ( bufrfnb (1:3) .eq. 's3b' ) THEN bfstyp = 'NC031133' ELSE logmsg = 'DID NOT RECOGNIZE THIS GFFD DATA' CALL DC_WLOG ( 0, 'DC', 2, logmsg, ierwlg ) logmsg = 'NO REPORTS DECODED !!!' CALL DC_WLOG ( 0, 'DC', 2, logmsg, ierwlg ) RETURN END IF C bufrtf = bufrta nxdsc = NXDSCA C C* Set the pointers for the interface arrays. C CALL GF_IFSP ( rimnem, ierfsp ) IF ( ierfsp .ne. 0 ) THEN RETURN END IF C C* Open the tables file. C CALL FL_SOPN ( bufrtf, iubftf, ierspn ) IF ( ierspn .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', ierspn, bufrtf, ierwlg ) RETURN END IF C C* Open the messages file. C CALL FL_GLUN ( iubfmf, iergln ) IF ( iergln .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iergln, ' ', ierwlg ) RETURN END IF C C* Connect the tables and messages files. C CALL OPENBF ( iubfmf, 'INUL', iubftf ) C C* Close the tables file. C CALL FL_CLOS ( iubftf, 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* 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 C* Read the input filename C CALL COBFL ( bufrfn, 'r' ) C C* Get a new bufr message from the input file. C CALL CRBMG ( bufr, mxbufr, nbyt, ierr ) DO WHILE ( ierr .ge. 0 ) IF ( ierr .eq. 0 ) THEN C C* Pad the end of the message with zeroed-out bytes up to the C* next 8-byte boundary. C CALL PADMSG ( mbay, mxbufrd4, npbyt ) lenb = nbyt + npbyt C C* Copy integer bufr array into character string C DO i = 1, lenb bull ( i:i ) = bufr ( i )(1:1) END DO ELSE WRITE ( unit = logmsg, fmt = '(a,i4,a)') 'return'// + 'code from crbmg was ',ierr,' - message cannot be used' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) CALL CLOSBF ( iubfmf ) CALL CLOSBF ( iubfmn ) CALL FL_CLAL ( iercal ) CALL CCBFL RETURN END IF C bullok = .true. 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 ( 1 : 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 CRBMG and getting a new bufr message C* from the input file. C CALL UT_WBFR ( iubfmn, 'gfofd', 1, ierwbf ) C ELSE istart = ipt1 ibptr = istart + 4 cbull = bull ( istart : lenb ) C nrept = 0 C C* Retrieve the Section 3 descriptors from this IGDR C* BUFR message and compare it with the list of C* expected descriptors C CALL UT_CBS3 ( 3, ibull, cxdsc, nxdsc, iercs3 ) IF ( iercs3 .ne. 0 ) THEN bullok = .false. logmsg = 'message has unknown format' CALL DC_WLOG ( 3, 'DC', 2, logmsg, ierwlg ) END IF C IF ( bullok ) THEN C C* Open this BUFR message. C CALL READERME ( ibull, iubfmf, + bfstmf, ibfdt, ierrme ) IF ( ierrme .ne. 0 ) THEN bullok = .false. ELSE C C* Check update sequence number in 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 GF_BUFR. C corn = FLOAT ( IUPBS01 ( ibull, 'USN' ) ) IF ( corn .gt. 0.0 ) corn = 1.0 C END IF ELSE logmsg = 'message has unknown format' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) END IF C DO WHILE ( bullok ) C C* Get the next report from this BUFR message. C CALL READSB ( iubfmf , 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, I6, A )' ) + 'contained ', nrept, ' reports' CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) C ELSE nrept = nrept + 1 C C* Initialize the interface arrays. C CALL GF_IFIV ( ierifi ) C C* Decode the report into the interface arrays. C CALL GF_BFIF ( iubfmf , ierbif ) C C* Write data for this report to the decoder log. C CALL GF_IFPT ( 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 GF_BUFR ( iubfmn, irundt, corn, bfstyp, ierbfr) END IF C logmsg = '-----------------------------------' CALL DC_WLOG ( 3, 'DC', 2, logmsg, ierwlg ) END IF END DO END IF END DO CALL CRBMG ( bufr, mxbufr, nbyt, ierr ) IF ( ierr. lt. 0 ) THEN C C* Make sure that all BUFR output has been written before C* exiting. C CALL UT_WBFR ( iubfmn, 'gfofd', 1, ierwbf ) C CALL CCBFL RETURN END IF END DO C C* close input gfo fast-delivery bufr file C CALL CCBFL C* RETURN END