SUBROUTINE UA_DCOD ( cldt, lndtbl, shptbl, bufrtb, nhours, + iret ) C************************************************************************ C* UA_DCOD * C* * C* This routine reads raob bulletins from the LDM and decodes them into * C* BUFR formats. * C* * C* UA_DCOD ( CLDT, LNDTBL, SHPTBL, BUFRTB, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* LNDTBL CHAR* Land station table * C* SHPTBL CHAR* Ship station table * 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* CIVALS (ICSTID) CHAR* Station ID * C* CIVALS (ICCOUN) CHAR* Country ID * C* RIVALS (IRWMOR) REAL Region number * C* IRET INTEGER Return code: * C* 0 = normal return * C* * C** * C* Log: * C* J. Ator/NCEP 03/96 * C* S. Jacobs/NCEP 04/96 Added check for decoding of AFOS prods * C* J. Ator/NCEP 05/96 DCUDCD -> UA_DCOD, unknpfil -> funknp, * C* unkrpfil -> funkrp * C* J. Ator/NCEP 06/96 Add ndays to TI_RTIM call list, * C* add check for bad return from TI_RTIM * C* J. Ator/NCEP 07/96 Use DCMXBF instead of MXSTRL * C* J. Ator/NCEP 07/96 TI_RTIM -> UT_RTIM * C* J. Ator/NCEP 01/97 Create BUFR only for report <= 5 days * C* old, reduce decoder log output * C* J. Ator/NCEP 10/97 Don't decode DROP reports from KAWN * C* J. Ator/NCEP 12/97 New interface format, style changes * C* J. Ator/NCEP 03/98 Set WMOR and COUN for U.S. DROP reports,* C* add calls to UA_SDGE and UA_LDGE * C* J. Ator/NCEP 04/98 UA_TMCK -> DC_TMCK * C* J. Ator/NCEP 10/98 Print STNM as I5.5 in logmsg, add call * C* to UA_RNIT, don't use '55555' as UA_RPID* C* nor '66666' as UA_NPID * C* D. Kidwell/NCEP 10/98 Added intf mnemonics to call sequences * C* J. Ator/NCEP 12/98 Move init. of mbstr, lmbstr into code, * C* add YEAR, MNTH to /INTF/ * C* J. Ator/NCEP 08/99 Use verbosity 2 in UA_IFPT for SDM bulls* C* J. Ator/NCEP 08/99 No longer need special IF test to * C* identify SDM bulls * C* J. Ator/NCEP 10/99 Clean up function declarations * C* J. Ator/NCEP 01/01 Set COUN and WMOR for U.K. dropsondes * C* J. Ator/NCEP 06/01 Use UT_WBFR, use 'NUL' in call to OPENBF* C* J. Ator/NCEP 08/04 SS_GTIM -> CSS_GTIM * C* C. Caruso Magee/NCEP 03/06 Corrected comments in docblock. * C* C. Caruso Magee/NCEP 04/07 Added Biloxi (KBIX) to list of those * C* drops whose IDs are reset from DRP99A. * C* J. Ator/NCEP 02/10 Set COUN and WMOR for French dropsondes * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'uacmn.cmn' C* CHARACTER bull*(DCMXBF), bullx*(DCMXBF), report*(DCMXBF), + seqnum*8, buhd*8, cborg*8, bulldt*8, bbb*8, + rundt*12, sysdt*12, + rimnem(NRIMN)*8, cimnem(NCIMN)*8 C* CHARACTER*(*) cldt, lndtbl, shptbl, bufrtb C* INTEGER irundt (5), irptdt (5) C* REAL*8 GETBMISS C* LOGICAL bullok, rptok C------------------------------------------------------------------------ iret = 0 C C* Set the pointers for the interface arrays. C CALL UA_IFSP ( rimnem, cimnem, ierfsp ) IF ( ierfsp .ne. 0 ) THEN RETURN END IF C C* Initialize the regional and national practice data indicators. C CALL UA_RNIT ( ierrnt ) C C* Open and read the land station table. C CALL UA_LDOR ( lndtbl, ierlst ) C C* Open and read the ship station table. C CALL UA_SDOR ( shptbl, iersst ) C C* Exit if there was a problem opening or reading either of the C* station tables. C IF ( ( ierlst .ne. 0 ) .or. ( iersst .ne. 0 ) ) THEN RETURN END IF 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 BUFR interface. C CALL OPENBF ( iunbfo, 'NUL', iunbft ) r8bfms = GETBMISS() 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. 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. 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 C DO WHILE ( bullok ) CALL UA_IFIV ( ierifi ) C C* Get the next report from this bulletin. C CALL UA_GRPT ( bullx, lenbx, ibxptr, report, lenr, + ierrpt ) IF ( ierrpt .ne. 0 ) THEN C C* There are no more reports in this bulletin. C bullok = .false. C C* Make sure that all BUFR output for this bulletin C* has been written out before going back to DC_GBUL C* and waiting for a new bulletin on the input pipe. C CALL UT_WBFR ( iunbfo, 'raob', 1, ierwbf ) ELSE C C* Initialize variables for this report. C rptok = .true. irptr = 5 C C* Start an entry for this report in the decoder log. C logmsg = '####################' // + '####################' CALL DC_WLOG ( 2, 'UA', 1, logmsg, ierwlg ) logmsg = seqnum // buhd // cborg // bulldt // bbb CALL DC_WLOG ( 2, 'UA', 1, logmsg, ierwlg ) C C* Write the report to the decoder log. C CALL DC_WLOG ( 2, ' ', 1, report (1:lenr), ierwlg ) C C* Check for a 'NIL' indicator in this report. C ilnil = INDEX ( report (1:lenr), 'NIL' ) IF ( ilnil .ne. 0 ) THEN logmsg = 'Report contains ''NIL'' indicator' CALL DC_WLOG ( 2, 'UA', 1, logmsg, ierwlg ) rptok = .false. END IF IF ( rptok ) THEN C C* Decode the header information from this report. C CALL UA_SHDR ( report, lenr, irptr, iershd ) IF ( iershd .ne. 0 ) THEN rptok = .false. END IF END IF IF ( rptok ) THEN IF ( stntyp .eq. LAND ) THEN C C* Decode and store data for this land station C* from the land station table. C CALL UA_LDGE ( rivals ( irstnm ), ierldg ) IF ( ierldg .ne. 0 ) THEN WRITE ( UNIT = logmsg, FMT = '( I5.5, A )') + INT ( rivals ( irstnm ) ), + ' not in land station table' CALL DC_WLOG ( 2, 'UA', -1, logmsg, ierwlg ) rptok = .false. END IF C ELSE IF ( stntyp .eq. SHIP ) THEN C C* Decode and store data for this ship from the C* ship station table. C CALL UA_SDGE ( civals ( icstid ), iersdg ) IF ( iersdg .ne. 0 ) THEN logmsg = civals ( icstid ) // + ' not in ship station table' CALL DC_WLOG ( 2, 'UA', 1, logmsg, ierwlg ) END IF C ELSE IF ( stntyp .eq. DROP ) THEN C C* Set a default value for the dropwinsonde ID. C civals ( icstid ) = 'DRP99A' C IF ( cborg (1:4) .eq. 'KAWN' ) THEN C C* Don't decode DROP reports from KAWN. C logmsg = 'This is a DROP report from KAWN' CALL DC_WLOG ( 2, 'UA', 1, logmsg, ierwlg ) rptok = .false. ELSE IF ( ( cborg (1:4) .eq. 'KNHC' ) .or. + ( cborg (1:4) .eq. 'KWBC' ) .or. + ( cborg (1:4) .eq. 'KBIX' ) ) THEN C C* This is a U.S. DROP report, so set the C* country ID and region number accordingly. C civals ( iccoun ) (1:2) = 'US' rivals ( irwmor ) = 4 ELSE IF ( cborg (1:4) .eq. 'EGRR' ) THEN C C* This is a U.K. DROP report, so set the C* country ID and region number accordingly. C civals ( iccoun ) (1:2) = 'UK' rivals ( irwmor ) = 6 ELSE IF ( cborg (1:4) .eq. 'LFPW' ) THEN C C* This is a French DROP report, so set the C* country ID and region number accordingly. C civals ( iccoun ) (1:2) = 'FR' rivals ( irwmor ) = 6 END IF C END IF END IF IF ( rptok ) THEN irptdy = INT ( rivals ( irdays ) ) irpthr = INT ( rivals ( irhour ) ) C C* Use the run date-time, the report day, and the C* report hour to construct a report date-time. C CALL DC_RTIM ( irundt, irptdy, irpthr, 0, 10, + irptdt, ierrtm ) IF ( ierrtm .ne. 0 ) THEN CALL UT_EMSG ( 2, 'DC_RTIM', ierrtm ) rptok = .false. ELSE rivals ( iryear ) = FLOAT ( irptdt (1) ) rivals ( irmnth ) = FLOAT ( irptdt (2) ) END IF END IF IF ( rptok ) THEN C C* Based upon the part type and code form type, C* decode the report. C IF ( cftyp .eq. TEMP ) THEN IF ( ( prttyp .eq. AA ) .or. + ( prttyp .eq. CC ) ) THEN CALL UA_DTAC ( report, lenr, irptr, + iertac ) ELSE IF ( ( prttyp .eq. BB ) .or. + ( prttyp .eq. DD ) ) THEN CALL UA_DTBD ( report, lenr, irptr, + iertbd ) END IF ELSE IF ( cftyp .eq. PILOT ) THEN IF ( ( prttyp .eq. AA ) .or. + ( prttyp .eq. CC ) ) THEN CALL UA_DPAC ( report, lenr, irptr, + ierpac ) ELSE IF ( ( prttyp .eq. BB ) .or. + ( prttyp .eq. DD ) ) THEN CALL UA_DPBD ( report, lenr, irptr, + ierpbd ) END IF END IF C C* Write data for this report to the decoder log. C CALL UA_IFPT ( 3, rimnem, cimnem, ierifp ) C C* Do not create BUFR output for reports that C* are more than NHOURS hours before or more C* than 3 hours after the run time. C CALL DC_TMCK ( 2, irundt, irptdt, nhours, 180, + iertmk ) IF ( iertmk .eq. 0 ) THEN C C* Convert data for this report to BUFR format C* and then write it to the BUFR output file. C CALL UA_BUFR ( iunbfo, irundt, irptdt, + seqnum, buhd, cborg, bulldt, bbb, + report, lenr, ierbfr ) END IF END IF END IF END DO C END DO C* RETURN END