SUBROUTINE UA_TSLV ( report, lenr, irptr, iret ) C************************************************************************ C* UA_TSLV * C* * C* This subroutine decodes all significant level temperature data of * C* the form NNPPP TTTDD and/or significant level wind data of the form * C* NNPPP DDFFF from temp BB, temp DD, pilot BB, and pilot DD reports. * C* * C* UA_TSLV ( REPORT, LENR, IRPTR, IRET ) * C* * C* Input parameters: * C* REPORT CHAR* Report * C* LENR INTEGER Length of REPORT * C* * C* Input and output parameters: * C* IRPTR INTEGER Pointer within REPORT * C* * C* Output parameters: * C* IRET INTEGER Return code: * C* 0 = normal return * C* -1 = critical error in REPORT * C* or reached end of REPORT * C** * C* Log: * C* J. Ator/NCEP 03/96 * C* J. Ator/NCEP 10/96 ERRGRP -> UA_EGRP, removed ERRRPT * C* J. Ator/NCEP 12/97 New interface format, style changes * C* J. Ator/NCEP 10/98 REGPID -> UA_RPID, NATPID -> UA_NPID * C* J. Ator/NCEP 12/98 Initialize siglev via DATA statement * C* J. Ator/NCEP 10/99 Use UA_PAHD to peek ahead in report, * C* clean up function declarations * C* J. Ator/NCEP 03/00 Allow UA_SDID or UA_CDID exit iff temp * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'uacmn.cmn' C* CHARACTER*(*) report C* CHARACTER siglev ( 10 )*2, field*(MXLENF) C* LOGICAL UA_EGRP, UA_SDID, UA_CDID, UA_RPID, UA_NPID, + ENDSLV, wind, lost C* DATA siglev + / '00', '11', '22', '33', '44', + '55', '66', '77', '88', '99' / C* INCLUDE 'ERMISS.FNC' C* C* Function to check for end of significant level data. C* ENDSLV ( field ) = + ( ( ( cftyp .eq. TEMP ) .and. + ( ( UA_SDID ( field ) ) .or. + ( UA_CDID ( field ) ) ) ) + .or. + ( UA_RPID ( field ) ) + .or. + ( UA_NPID ( field ) ) ) C------------------------------------------------------------------------ C C* Initialize variables. C iret = 0 iskpct = 0 wind = .false. prevpr = RMXPRS IF ( prttyp .eq. BB ) THEN level = 1 ELSE level = 2 END IF C C* Loop through the data one significant level at a time. C DO WHILE ( .true. ) C C* Get the first group of this significant level; C* it contains the pressure. C ipt1 = irptr CALL UA_GFLD ( report, lenr, irptr, field, lenf, ier ) IF ( ier .ne. 0 ) THEN iret = -1 RETURN ELSE IF ( ENDSLV ( field ) ) THEN irptr = ipt1 RETURN END IF C C* Check if this group contains the expected significant C* level marker. C IF ( field (1:2) .eq. siglev ( level ) ) THEN C C* Initialize all output values for this significant level. C IF ( level .eq. 1 ) THEN vsig = 64.0 ELSE IF ( wind ) THEN vsig = 2.0 ELSE vsig = 4.0 END IF pres = RMISSD tmpc = RMISSD dwpc = RMISSD drct = RMISSD sped = RMISSD C IF ( .not. UA_EGRP ( field, lenf ) ) THEN C C* Compute the pressure. C CALL UA_PRS3 ( field (3:5), pres, ier ) END IF C C* Get and decode the next group. C CALL UA_GFLD ( report, lenr, irptr, field, lenf, + ier ) IF ( ier .ne. 0 ) THEN iret = -1 ELSE IF ( .not. UA_EGRP ( field, lenf ) ) THEN IF ( wind ) THEN CALL UA_WIND ( field, drct, sped, ier ) ELSE CALL UA_TEMP ( field, tmpc, dwpc, ier ) END IF END IF C C* If the pressure exists and is less than the pressure C* at the previous valid significant level, then store all C* output values for this level into the interface arrays. C IF ( ( .not. ERMISS ( pres ) ) .and. + ( pres .lt. prevpr ) ) THEN CALL UA_STLV ( vsig, pres, RMISSD, tmpc, dwpc, + drct, sped, RMISSD, RMISSD, ierstv ) IF ( ierstv .lt. 0 ) THEN iret = -1 RETURN END IF prevpr = pres END IF C C* Determine the next expected significant level marker. C level = level + 1 IF ( level .eq. 11 ) THEN level = 2 END IF C C* Stop if the end of the report was encountered during C* processing of this significant level. C IF ( iret .lt. 0 ) THEN RETURN END IF ELSE IF ( field (1:5) .eq. '21212' ) THEN wind = .true. prevpr = RMXPRS IF ( prttyp .eq. BB ) THEN level = 1 ELSE level = 2 END IF ELSE logmsg = 'temp siglev marker ' // field (1:2) // + ' (expected ' // siglev ( level ) // ')' CALL DC_WLOG ( 2, 'UA', 2, logmsg, ierwlg ) CALL UA_RDCS ( 112, ierrdc ) C C* Try to find valid significant level data further along C* in the report. C irptr = ipt1 lost = .true. DO WHILE ( lost ) C C* Get the next group in the report. C ipt1 = irptr CALL UA_GFLD ( report, lenr, irptr, field, lenf,ier ) IF ( ier .ne. 0 ) THEN iret = -1 RETURN ELSE IF ( ENDSLV ( field ) ) THEN irptr = ipt1 RETURN ELSE IF ( field (1:5) .eq. '21212' ) THEN irptr = ipt1 lost = .false. END IF C IF ( .not. UA_EGRP ( field, lenf ) ) THEN C C* Determine if the first two digits of this C* group match one of the significant level C* markers. C ilev = 2 DO WHILE ( ( lost ) .and. ( ilev .le. 10 ) ) IF ( field (1:2) .eq. siglev ( ilev ) ) THEN C C* The first two digits of this group match one C* of the significant level markers. Before C* accepting this as a valid significant level, C* peek further ahead in the report to see if C* the significant level marker after this one C* is in the expected location. C ipt2 = irptr CALL UA_PAHD ( report, lenr, 2, ipt2, + field, lenf, ierphd ) IF ( ierphd .ne. 0 ) THEN iret = -1 RETURN END IF C IF ( .not. UA_EGRP ( field, lenf ) ) THEN inxlev = ilev + 1 IF ( inxlev .eq. 11 ) THEN inxlev = 2 END IF IF ( field (1:2) .eq. + siglev ( inxlev ) ) THEN lost = .false. level = ilev irptr = ipt1 END IF END IF C END IF ilev = ilev + 1 END DO END IF C IF ( lost ) THEN iskpct = iskpct + 1 C C* How many groups have we skipped over so far?? C IF ( iskpct .gt. MXSKIP ) THEN WRITE ( UNIT = logmsg, FMT = '( A, I3, A )' ) + 'skipped ', iskpct, ' groups during recovery' CALL DC_WLOG ( 2, 'UA', -1, logmsg, ierwlg ) CALL UA_RDCS ( 116, ierrdc ) iret = -1 RETURN END IF END IF C END DO END IF END DO C* RETURN END