SUBROUTINE AX_DCOD ( cldt, bufrtb, nhours, iret ) C************************************************************************ C* AX_DCOD * C* * C* This routine decodes AXBT bulletins into BUFR format. * C* * C* AX_DCOD ( CLDT, BUFRTB, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* BUFRTB CHAR* 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 11/10 * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'axcmn.cmn' C* CHARACTER*(*) cldt, bufrtb C* CHARACTER bull*(DCMXBF), bullx*(DCMXBF), + seqnum*8, buhd*8, cborg*8, bulldt*8, bbb*8, + rundt*12, sysdt*12, field*(MXLENF), + acid*(MXLENF), stid*(MXLENF), ptid*(MXLENF) C* INTEGER irundt (5) C* REAL rdep (MXNLEV), rtemp (MXNLEV), rtempe (MXNLEV) C* LOGICAL bullok, levlok C----------------------------------------------------------------------- iret = 0 C C* Open the BUFR tables file. C CALL FL_SOPN ( bufrtb, iunbft, ierspn ) IF ( ierspn .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', ierspn, bufrtb, ierwlg ) RETURN END IF C C* Open the BUFR output file. C CALL FL_GLUN ( iunbfo, iergln ) IF ( iergln .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iergln, ' ', ierwlg ) RETURN END IF C C* Connect the BUFR tables and output files to the C* BUFR interface. Use BUFR edition 4 for the output, and C* allow the BUFR messages to be up to 20000 bytes long. C CALL OPENBF ( iunbfo, 'NUL', iunbft ) CALL PKVS01 ( 'BEN', 4 ) CALL MAXOUT ( 20000 ) C C* Close the BUFR tables file. C CALL FL_CLOS ( iunbft, 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 ( iunbfo ) CALL FL_CLAL ( iercal ) RETURN END IF bullok = .true. nlev = 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* Remove unprintable characters from this bulletin. C lenbxo = lenb - ibptr CALL ST_UNPR ( bull ( ibptr + 1 : lenb ), lenbxo, + bullx, lenbxn, ierunp ) lenbx = lenbxn ibxptr = 1 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* Get and decode the date group. C CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_INTG ( field(1:lenf), idate, ieri ) IF ( ieri .ne. 0 ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the time group. C CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_INTG ( field(1:lenf), itime, ieri ) IF ( ieri .ne. 0 ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the latitude group. C CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_CRNM ( field(1:lenf), rlat, ierr ) IF ( ierr .ne. 0 ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the longitude group. C CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_CRNM ( field(1:lenf), rlon, ierr ) IF ( ierr .ne. 0 ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the aircraft ID. C CALL AX_GFLD ( bullx, lenbx, ibxptr, acid, lacid, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the storm ID. C CALL AX_GFLD ( bullx, lenbx, ibxptr, stid, lstid, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the channel number. C CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_INTG ( field(1:lenf), ichnm, ieri ) IF ( ieri .ne. 0 ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the platform transmitter ID. C CALL AX_GFLD ( bullx, lenbx, ibxptr, ptid, lptid, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. END IF END IF IF ( bullok ) THEN logmsg = 'Successfully decoded header: ' // + bullx(1:ibxptr-1) CALL DC_WLOG ( 2, 'DC', 2, logmsg, ierwlg ) END IF DO WHILE ( bullok ) C C* Get and decode the data levels. Each level has a C* depth, temperature and temperature error. C levlok = .true. C CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_CRNM ( field(1:lenf), rdep(nlev+1), ierr ) IF ( ierr .ne. 0 ) levlok = .false. END IF IF ( bullok ) THEN CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, + ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_CRNM ( field(1:lenf), rtemp(nlev+1), + ierr ) IF ( ierr .ne. 0 ) levlok = .false. END IF END IF IF ( bullok ) THEN CALL AX_GFLD ( bullx, lenbx, ibxptr, field, lenf, + ierg ) IF ( ierg .ne. 0 ) THEN bullok = .false. ELSE CALL ST_CRNM ( field(1:lenf), rtempe(nlev+1), + ierr ) IF ( ierr .ne. 0 ) levlok = .false. END IF END IF IF ( bullok .and. levlok ) nlev = nlev + 1 END DO IF ( nlev .gt. 0 ) THEN CALL AX_BUFR ( iunbfo, irundt, seqnum, buhd, cborg, + bulldt, bbb, idate, itime, rlat, rlon, + ichnm, acid, lacid, stid, lstid, + ptid, lptid, rdep, rtemp, rtempe, nlev, + ierbfr ) END IF C END DO C* RETURN END