SUBROUTINE UA_TMLV ( report, lenr, irptr, iret ) C************************************************************************ C* UA_TMLV * C* * C* This subroutine decodes data for all mandatory levels from temp AA * C* and temp CC reports. It also decodes temp BB mandatory levels from * C* WMO Region 4. * C* * C* UA_TMLV ( 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 manlev via DATA statement * C* J. Ator/NCEP 10/99 Add error check for miscoded Id flag, * C* clean up function declarations * C* J. Ator/NCEP 03/00 Allow UA_SDID, UA_TPID, UA_MPID exits * C* iff AA or CC * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'uacmn.cmn' C* CHARACTER*(*) report C* CHARACTER manlev ( 11, 2 )*2, field*(MXLENF) C* LOGICAL UA_EGRP, UA_TPID, UA_MPID, + UA_SDID, UA_RPID, UA_NPID, + ENDMLV, lost, badid C* DATA manlev + / '00', '92', '85', '70', '50', '40', + '30', '25', '20', '15', '10', + '70', '50', '30', '20', '10', + '07', '05', '03', '02', '01', 'xx'/ C* INCLUDE 'ERMISS.FNC' C* C* Function to check for end of temp mandatory level data. C* ENDMLV ( field ) = + ( ( ( prttyp .ne. BB ) .and. + ( ( UA_TPID ( field ) ) .or. + ( UA_MPID ( field ) ) .or. + ( UA_SDID ( field ) ) ) ) + .or. + ( UA_RPID ( field ) ) + .or. + ( UA_NPID ( field ) ) ) C------------------------------------------------------------------------ C C* Initialize variables. C iret = 0 iskpct = 0 IF ( prttyp .eq. AA ) THEN ilev = 1 imxlev = 11 iaacc = 1 ELSE IF ( prttyp .eq. BB ) THEN ilev = 2 imxlev = 5 iaacc = 1 ELSE IF ( prttyp .eq. CC ) THEN ilev = 1 imxlev = 10 iaacc = 2 END IF C C* Determine the highest mandatory level for which winds are C* reported. C IF ( prttyp .eq. BB ) THEN topwnd = 500. ELSE CALL UA_TOPW ( topwnd, iertpw ) END IF C C* Loop through the data one mandatory level at a time. C DO WHILE ( ilev .le. imxlev ) C C* Get the first group for this mandatory level; C* it contains the pressure and the height. C ipt2 = irptr CALL UA_GFLD ( report, lenr, irptr, field, lenf, ier ) IF ( ier .ne. 0 ) THEN iret = -1 RETURN ELSE IF ( ENDMLV ( field ) ) THEN irptr = ipt2 RETURN END IF C C* Check if this is the expected level. C IF ( field (1:2) .eq. manlev ( ilev, iaacc ) ) THEN C C* Initialize all output values for this level. C vsig = 32.0 pres = RMISSD hgtm = RMISSD tmpc = RMISSD dwpc = RMISSD drct = RMISSD sped = RMISSD C IF ( .not. UA_EGRP ( field, lenf ) ) THEN C C* Compute the pressure and the height. C CALL UA_PRHT ( field, pres, hgtm, ier ) END IF C C* Get the temperature/dewpoint 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 CALL UA_TEMP ( field, tmpc, dwpc, ier ) END IF C C* Is there a wind group at this level ?? C IF ( pres .ge. topwnd ) THEN C C* Get the wind 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 CALL UA_WIND ( field, drct, sped, ier ) END IF END IF END IF C C* If the pressure and the height are both available for C* this level, then store all output values for this level C* into the interface arrays. C IF ( ( .not. ERMISS ( pres ) ) .and. + ( .not. ERMISS ( hgtm ) ) ) THEN CALL UA_STLV ( vsig, pres, hgtm, tmpc, dwpc, + drct, sped, RMISSD, RMISSD, ierstv ) IF ( ierstv .lt. 0 ) THEN iret = -1 RETURN END IF END IF C ilev = ilev + 1 C C* Stop if the end of the report was encountered during C* processing of this mandatory level. C IF ( iret .lt. 0 ) THEN RETURN END IF ELSE IF ( ( manlev ( ilev, iaacc ) .eq. '92' ) .and. + ( field (1:2) .eq. '85' ) ) THEN C C* The 925mb mandatory level is missing from the report. C* This is a legal omission. C ilev = ilev + 1 irptr = ipt2 ELSE logmsg = 'temp manlev marker ' // field (1:2) // + ' (expected ' // manlev ( ilev, iaacc ) // ')' CALL DC_WLOG ( 2, 'UA', 2, logmsg, ierwlg ) CALL UA_RDCS ( 111, ierrdc ) C C* Try to find valid mandatory level data further along C* in the report. C irptr = ipt2 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 ( ENDMLV ( field ) ) THEN irptr = ipt1 RETURN 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 mandatory level C* indicators that has not yet been found. C itlv = ilev DO WHILE ( ( lost ) .and. + ( itlv .lt. imxlev ) ) IF ( field (1:2) .eq. + manlev ( itlv, iaacc ) ) THEN C C* The first two digits of this group match C* one of the mandatory level indicators that C* has not yet been found. C C* Before accepting this as a valid mandatory C* level, peek further ahead in the report to C* determine if the mandatory level after C* this one is in the expected location. C* The expected location, based upon the C* Id wind level flag, is... C CALL UA_PRS2 ( field (1:2), tprs, ier ) IF ( tprs .ge. topwnd ) THEN C C* 3 groups ahead. C nahd = 3 ELSE C C* 2 groups ahead. C nahd = 2 END IF C ipt3 = irptr CALL UA_PAHD ( report, lenr, nahd, ipt3, + field, lenf, ierphd ) IF ( ierphd .eq. 0 ) THEN IF ( ( .not. UA_EGRP ( field, lenf ) ) + .and. + ( manlev ( itlv + 1, iaacc ) .eq. + field (1:2) ) ) THEN C C* The mandatory level after this one was C* found in the expected location, so C* accept the current level as a valid C* mandatory level. C lost = .false. ilev = itlv irptr = ipt1 END IF END IF C IF ( lost ) THEN C C* Perhaps the Id wind level flag itself C* was miscoded? C C* To check this, momentarily assume that C* the flag was miscoded, and then peek C* further ahead in the report to determine C* if the next few mandatory levels then C* appear in the expected locations. C C* NMLVCK is the number of mandatory levels C* ahead that will be checked. C nmlvck = 2 C IF ( ( itlv + nmlvck ) .le. imxlev ) THEN C C* Assuming that the Id wind level flag C* was miscoded... C badid = .true. C C* then this and all subsequent mandatory C* levels would contain... C IF ( nahd .eq. 3 ) THEN C C* 2 groups. C nahd = 2 topwnn = RMXPRS ELSE C C* 3 groups. C nahd = 3 topwnn = 1. END IF C C* Now, determine whether this change C* causes the next NMLVCK mandatory levels C* to appear in the expected locations. C ii = 1 ipt3 = irptr DO WHILE ( ( badid ) .and. + ( ii .le. nmlvck ) ) CALL UA_PAHD ( report, lenr,nahd,ipt3, + field, lenf, ierphd ) IF ( ierphd .ne. 0 ) THEN badid = .false. ELSE IF ( UA_EGRP (field, lenf) ) THEN badid = .false. ELSE IF ( field (1:2) .ne. + manlev ( itlv + ii, iaacc ) ) THEN badid = .false. END IF ii = ii + 1 END DO C IF ( badid ) THEN C C* The Id wind level flag indeed appears C* to have been miscoded, so correct it C* and then accept the current level as C* a valid mandatory level. C topwnd = topwnn lost = .false. ilev = itlv irptr = ipt1 WRITE ( UNIT = logmsg, + FMT = '( A, A, A, I3, A )' ) + 'Id wind flag ', idflag, + ' (fixed at ', INT ( tprs ), 'mb)' CALL DC_WLOG + ( 2, 'UA', 2, logmsg, ierwlg ) CALL UA_RDCS ( 120, ierrdc ) END IF END IF END IF END IF itlv = itlv + 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