!
!##################################################################
!##################################################################
!###### ######
!###### NMCDECODE ######
!###### ######
!##################################################################
!##################################################################
!
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Decode the NMC GRIB files.
!
!-----------------------------------------------------------------------
!
! AUTHOR: NWS/NMC
!
! MODIFICATION HISTORY:
! 01/16/1996 (Yuhe Liu)
! Changed subroutine name of SBYTE(S) and GBYTE(S) to GRBSBYTE(S)
! and GRBGBYTE(S) to avoid the conflict with the subroutines of
! same names in NCAR graphics package.
!
!-----------------------------------------------------------------------
!
! Original comments:
!
! FILE UPDATED ON 11-22-94 BY M. FARLEY.
! CONTAINS SUBROUTINES NEEDED TO DECODE GRIB MESSAGES:
! W3FI63 AND W3FI83.
!
SUBROUTINE w3fi63(msga,kpds,kgds,kbms,DATA,kptr,kret) 1,24
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: W3FI63 UNPK GRIB FIELD TO GRIB GRID
! PRGMMR: FARLEY ORG: NMC421 DATE:94-11-22
!
! ABSTRACT: UNPACK A GRIB (EDITION 1) FIELD TO THE EXACT GRID
! SPECIFIED IN THE GRIB MESSAGE, ISOLATE THE BIT MAP, AND MAKE
! THE VALUES OF THE PRODUCT DESCRIPTON SECTION (PDS) AND THE
! GRID DESCRIPTION SECTION (GDS) AVAILABLE IN RETURN ARRAYS.
!
! WHEN DECODING IS COMPLETED, DATA AT EACH GRID POINT HAS BEEN
! RETURNED IN THE UNITS SPECIFIED IN THE GRIB MANUAL.
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
! 91-11-12 CAVANAUGH MODIFIED SIZE OF ECMWF GRIDS 5-8
! 91-12-22 CAVANAUGH CORRECTED PROCESSING OF MERCATOR PROJECTIONS
! IN GRID DEFINITION SECTION (GDS) IN
! ROUTINE FI633
! 92-08-05 CAVANAUGH CORRECTED MAXIMUM GRID SIZE TO ALLOW FOR
! ONE DEGREE BY ONE DEGREE GLOBAL GRIDS
! 92-08-27 CAVANAUGH CORRECTED TYPO ERROR, ADDED CODE TO COMPARE
! TOTAL BYTE SIZE FROM SECTION 0 WITH SUM OF
! SECTION SIZES.
! 92-10-21 CAVANAUGH CORRECTIONS WERE MADE (IN FI634) TO REDUCE
! PROCESSING TIME FOR INTERNATIONAL GRIDS.
! REMOVED A TYPOGRAPHICAL ERROR IN FI635.
! 93-01-07 CAVANAUGH CORRECTIONS WERE MADE (IN FI635) TO
! FACILITATE USE OF THESE ROUTINES ON A PC.
! A TYPOGRAPHICAL ERROR WAS ALSO CORRECTED
! 93-01-13 CAVANAUGH CORRECTIONS WERE MADE (IN FI632) TO
! PROPERLY HANDLE CONDITION WHEN
! TIME RANGE INDICATOR = 10.
! ADDED U.S.GRID 87.
! 93-02-04 CAVANAUGH ADDED U.S.GRIDS 85 AND 86
! 93-02-26 CAVANAUGH ADDED GRIDS 2, 3, 37 THRU 44,AND
! GRIDS 55, 56, 90, 91, 92, AND 93 TO
! LIST OF U.S. GRIDS.
! 93-04-07 CAVANAUGH ADDED GRIDS 67 THRU 77 TO
! LIST OF U.S. GRIDS.
! 93-04-20 CAVANAUGH INCREASED MAX SIZE TO ACCOMODATE
! GAUSSIAN GRIDS.
! 93-05-26 CAVANAUGH CORRECTED GRID RANGE SELECTION IN FI634
! FOR RANGES 67-71 & 75-77
! 93-06-08 CAVANAUGH CORRECTED FI635 TO ACCEPT GRIB MESSAGES
! WITH SECOND ORDER PACKING. ADDED ROUTINE FI636
! TO PROCESS MESSAGES WITH SECOND ORDER PACKING.
! 93-09-22 CAVANAUGH MODIFIED TO EXTRACT SUB-CENTER NUMBER FROM
! PDS BYTE 26
! 93-10-13 CAVANAUGH MODIFIED FI634 TO CORRECT GRID SIZES FOR
! GRIDS 204 AND 208
! 93-10-14 CAVANAUGH INCREASED SIZE OF KGDS TO INCLUDE ENTRIES FOR
! NUMBER OF POINTS IN GRID AND NUMBER OF WORDS
! IN EACH ROW
! 93-12-08 CAVANAUGH CORRECTED TEST FOR EDITION NUMBER INSTEAD
! OF VERSION NUMBER
! 93-12-15 CAVANAUGH MODIFIED SECOND ORDER POINTERS TO FIRST ORDER
! VALUES AND SECOND ORDER VALUES CORRECTLY
! IN ROUTINE FI636
! 94-03-02 CAVANAUGH ADDED CALL TO W3FI83 WITHIN DECODER. USER
! NO LONGER NEEDS TO MAKE CALL TO THIS ROUTINE
! 94-04-22 CAVANAUGH MODIFIED FI635, FI636 TO PROCESS ROW BY ROW
! SECOND ORDER PACKING, ADDED SCALING CORRECTION
! TO FI635, AND CORRECTED TYPOGRAPHICAL ERRORS
! IN COMMENT FIELDS IN FI634
! 94-05-17 CAVANAUGH CORRECTED ERROR IN FI633 TO EXTRACT RESOLUTION
! FOR LAMBERT-CONFORMAL GRIDS. ADDED CLARIFYING
! INFORMATION TO DOCBLOCK ENTRIES
! 94-05-25 CAVANAUGH ADDED CODE TO PROCESS COLUMN BY COLUMN AS WELL
! AS ROW BY ROW ORDERING OF SECOND ORDER DATA
! 94-06-27 CAVANAUGH ADDED PROCESSING FOR GRIDS 45, 94 AND 95.
! INCLUDES CONSTRUCTION OF SECOND ORDER BIT MAPS
! FOR THINNED GRIDS IN FI636.
! 94-07-08 CAVANAUGH COMMENTED OUT PRINT OUTS USED FOR DEBUGGING
! 94-09-08 CAVANAUGH ADDED GRIDS 220, 221, 223 FOR FNOC
! 94-11-10 FARLEY INCREASED MXSIZE FROM 72960 TO 260000
! FOR .5 DEGREE SST ANALYSIS FIELDS
!
!
! USAGE: CALL W3FI63(MSGA,KPDS,KGDS,KBMS,DATA,KPTR,KRET)
! INPUT ARGUMENT LIST:
! MSGA - GRIB FIELD - "GRIB" THRU "7777" CHAR*1
! (MESSAGE CAN BE PRECEDED BY JUNK CHARS)
!
! OUTPUT ARGUMENT LIST:
! DATA - ARRAY CONTAINING DATA ELEMENTS
! KPDS - ARRAY CONTAINING PDS ELEMENTS. (EDITION 1)
! (1) - ID OF CENTER
! (2) - GENERATING PROCESS ID NUMBER
! (3) - GRID DEFINITION
! (4) - GDS/BMS FLAG (RIGHT ADJ COPY OF OCTET 8)
! (5) - INDICATOR OF PARAMETER
! (6) - TYPE OF LEVEL
! (7) - HEIGHT/PRESSURE , ETC OF LEVEL
! (8) - YEAR INCLUDING (CENTURY-1)
! (9) - MONTH OF YEAR
! (10) - DAY OF MONTH
! (11) - HOUR OF DAY
! (12) - MINUTE OF HOUR
! (13) - INDICATOR OF FORECAST TIME UNIT
! (14) - TIME RANGE 1
! (15) - TIME RANGE 2
! (16) - TIME RANGE FLAG
! (17) - NUMBER INCLUDED IN AVERAGE
! (18) - VERSION NR OF GRIB SPECIFICATION
! (19) - VERSION NR OF PARAMETER TABLE
! (20) - NR MISSING FROM AVERAGE/ACCUMULATION
! (21) - CENTURY OF REFERENCE TIME OF DATA
! (22) - UNITS DECIMAL SCALE FACTOR
! (23) - SUBCENTER NUMBER
! (26-35) - RESERVED
! (24-25) - RESERVED FOR FUTURE USE
! (36-N) - CONSECUTIVE BYTES EXTRACTED FROM PROGRAM
! DEFINITION SECTION (PDS) OF GRIB MESSAGE
! KGDS - ARRAY CONTAINING GDS ELEMENTS.
! (1) - DATA REPRESENTATION TYPE
! (19) - NUMBER OF VERTICAL COORDINATE PARAMETERS
! (20) - OCTET NUMBER OF THE LIST OF VERTICAL COORDINATE
! PARAMETERS
! OR
! OCTET NUMBER OF THE LIST OF NUMBERS OF POINTS
! IN EACH ROW
! OR
! 255 IF NEITHER ARE PRESENT
! (21) - FOR GRIDS WITH PL, NUMBER OF POINTS IN GRID
! (22) - NUMBER OF WORDS IN EACH ROW
! LATITUDE/LONGITUDE GRIDS
! (2) - N(I) NR POINTS ON LATITUDE CIRCLE
! (3) - N(J) NR POINTS ON LONGITUDE MERIDIAN
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESOLUTION FLAG (RIGHT ADJ COPY OF OCTET 17)
! (7) - LA(2) LATITUDE OF EXTREME POINT
! (8) - LO(2) LONGITUDE OF EXTREME POINT
! (9) - DI LATITUDINAL DIRECTION OF INCREMENT
! (10) - DJ LONGITUDINAL DIRECTION INCREMENT
! (11) - SCANNING MODE FLAG (RIGHT ADJ COPY OF OCTET 28)
! GAUSSIAN GRIDS
! (2) - N(I) NR POINTS ON LATITUDE CIRCLE
! (3) - N(J) NR POINTS ON LONGITUDE MERIDIAN
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESOLUTION FLAG (RIGHT ADJ COPY OF OCTET 17)
! (7) - LA(2) LATITUDE OF EXTREME POINT
! (8) - LO(2) LONGITUDE OF EXTREME POINT
! (9) - DI LATITUDINAL DIRECTION OF INCREMENT
! (10) - N - NR OF CIRCLES POLE TO EQUATOR
! (11) - SCANNING MODE FLAG (RIGHT ADJ COPY OF OCTET 28)
! (12) - NV - NR OF VERT COORD PARAMETERS
! (13) - PV - OCTET NR OF LIST OF VERT COORD PARAMETERS
! OR
! PL - LOCATION OF THE LIST OF NUMBERS OF POINTS IN
! EACH ROW (IF NO VERT COORD PARAMETERS
! ARE PRESENT
! OR
! 255 IF NEITHER ARE PRESENT
! POLAR STEREOGRAPHIC GRIDS
! (2) - N(I) NR POINTS ALONG LAT CIRCLE
! (3) - N(J) NR POINTS ALONG LON CIRCLE
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESOLUTION FLAG (RIGHT ADJ COPY OF OCTET 17)
! (7) - LOV GRID ORIENTATION
! (8) - DX - X DIRECTION INCREMENT
! (9) - DY - Y DIRECTION INCREMENT
! (10) - PROJECTION CENTER FLAG
! (11) - SCANNING MODE (RIGHT ADJ COPY OF OCTET 28)
! SPHERICAL HARMONIC COEFFICIENTS
! (2) - J PENTAGONAL RESOLUTION PARAMETER
! (3) - K " " "
! (4) - M " " "
! (5) - REPRESENTATION TYPE
! (6) - COEFFICIENT STORAGE MODE
! MERCATOR GRIDS
! (2) - N(I) NR POINTS ON LATITUDE CIRCLE
! (3) - N(J) NR POINTS ON LONGITUDE MERIDIAN
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESOLUTION FLAG (RIGHT ADJ COPY OF OCTET 17)
! (7) - LA(2) LATITUDE OF LAST GRID POINT
! (8) - LO(2) LONGITUDE OF LAST GRID POINT
! (9) - LATIT - LATITUDE OF PROJECTION INTERSECTION
! (10) - RESERVED
! (11) - SCANNING MODE FLAG (RIGHT ADJ COPY OF OCTET 28)
! (12) - LONGITUDINAL DIR GRID LENGTH
! (13) - LATITUDINAL DIR GRID LENGTH
! LAMBERT CONFORMAL GRIDS
! (2) - NX NR POINTS ALONG X-AXIS
! (3) - NY NR POINTS ALONG Y-AXIS
! (4) - LA1 LAT OF ORIGIN (LOWER LEFT)
! (5) - LO1 LON OF ORIGIN (LOWER LEFT)
! (6) - RESOLUTION (RIGHT ADJ COPY OF OCTET 17)
! (7) - LOV - ORIENTATION OF GRID
! (8) - DX - X-DIR INCREMENT
! (9) - DY - Y-DIR INCREMENT
! (10) - PROJECTION CENTER FLAG
! (11) - SCANNING MODE FLAG (RIGHT ADJ COPY OF OCTET 28)
! (12) - LATIN 1 - FIRST LAT FROM POLE OF SECANT CONE INTER
! (13) - LATIN 2 - SECOND LAT FROM POLE OF SECANT CONE INTER
! KBMS - BITMAP DESCRIBING LOCATION OF OUTPUT ELEMENTS.
! (ALWAYS CONSTRUCTED)
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! (1) - TOTAL LENGTH OF GRIB MESSAGE
! (2) - LENGTH OF INDICATOR (SECTION 0)
! (3) - LENGTH OF PDS (SECTION 1)
! (4) - LENGTH OF GDS (SECTION 2)
! (5) - LENGTH OF BMS (SECTION 3)
! (6) - LENGTH OF BDS (SECTION 4)
! (7) - VALUE OF CURRENT BYTE
! (8) - BIT POINTER
! (9) - GRIB START BIT NR
! (10) - GRIB/GRID ELEMENT COUNT
! (11) - NR UNUSED BITS AT END OF SECTION 3
! (12) - BIT MAP FLAG (COPY OF BMS OCTETS 5,6)
! (13) - NR UNUSED BITS AT END OF SECTION 2
! (14) - BDS FLAGS (RIGHT ADJ COPY OF OCTET 4)
! (15) - NR UNUSED BITS AT END OF SECTION 4
! KRET - FLAG INDICATING QUALITY OF COMPLETION
!
! REMARKS: WHEN DECODING IS COMPLETED, DATA AT EACH GRID POINT HAS BEEN
! RETURNED IN THE UNITS SPECIFIED IN THE GRIB MANUAL.
!
! VALUES FOR RETURN FLAG (KRET)
! KRET = 0 - NORMAL RETURN, NO ERRORS
! = 1 - 'GRIB' NOT FOUND IN FIRST 100 CHARS
! = 2 - '7777' NOT IN CORRECT LOCATION
! = 3 - UNPACKED FIELD IS LARGER THAN 65160
! = 4 - GDS/ GRID NOT ONE OF CURRENTLY ACCEPTED VALUES
! = 5 - GRID NOT CURRENTLY AVAIL FOR CENTER INDICATED
! = 8 - TEMP GDS INDICATED, BUT GDS FLAG IS OFF
! = 9 - GDS INDICATES SIZE MISMATCH WITH STD GRID
! =10 - INCORRECT CENTER INDICATOR
! =11 - BINARY DATA SECTION (BDS) NOT COMPLETELY PROCESSED.
! PROGRAM IS NOT SET TO PROCESS FLAG COMBINATIONS
! SHOWN IN OCTETS 4 AND 14.
! =12 - BINARY DATA SECTION (BDS) NOT COMPLETELY PROCESSED.
! PROGRAM IS NOT SET TO PROCESS FLAG COMBINATIONS
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS9000
!
!$$$
! 4 AUG 1988
! W3FI63
!
!
! GRIB UNPACKING ROUTINE
!
!
! THIS ROUTINE WILL UNPACK A 'GRIB' FIELD TO THE EXACT GRID
! TYPE SPECIFIED IN THE MESSAGE, RETURN A BIT MAP AND MAKE THE
! VALUES OF THE PRODUCT DEFINITION SEC (PDS) AND THE GRID
! DESCRIPTION SEC (GDS) AVAILABLE IN RETURN ARRAYS.
! SEE "GRIB - THE WMO FORMAT FOR THE STORAGE OF WEATHER PRODUCT
! INFORMATION AND THE EXCHANGE OF WEATHER PRODUCT MESSAGES IN
! GRIDDED BINARY FORM" DATED JULY 1, 1988 BY JOHN D. STACKPOLE
! DOC, NOAA, NWS, NATIONAL METEOROLOGICAL CENTER.
!
! THE CALL TO THE GRIB UNPACKING ROUTINE IS AS FOLLOWS:
!
! CALL W3FI63(MSGA,KPDS,KGDS,LBMS,DATA,KPTR,KRET)
!
! INPUT:
!
! MSGA = CONTAINS THE GRIB MESSAGE TO BE UNPACKED. CHARACTERS
! "GRIB" MAY BEGIN ANYWHERE WITHIN FIRST 100 BYTES.
!
! OUTPUT:
!
! KPDS(100) INTEGER*4
! ARRAY TO CONTAIN THE ELEMENTS OF THE PRODUCT
! DEFINITION SEC .
! (VERSION 1)
! KPDS(1) - ID OF CENTER
! KPDS(2) - MODEL IDENTIFICATION (SEE "GRIB" TABLE 1)
! KPDS(3) - GRID IDENTIFICATION (SEE "GRIB" TABLE 2)
! KPDS(4) - GDS/BMS FLAG
! BIT DEFINITION
! 25 0 - GDS OMITTED
! 1 - GDS INCLUDED
! 26 0 - BMS OMITTED
! 1 - BMS INCLUDED
! NOTE:- LEFTMOST BIT = 1,
! RIGHTMOST BIT = 32
! KPDS(5) - INDICATOR OF PARAMETER (SEE "GRIB" TABLE 5)
! KPDS(6) - TYPE OF LEVEL (SEE "GRIB" TABLES 6 & 7)
! KPDS(7) - HEIGHT,PRESSURE,ETC OF LEVEL
! KPDS(8) - YEAR INCLUDING CENTURY
! KPDS(9) - MONTH OF YEAR
! KPDS(10) - DAY OF MONTH
! KPDS(11) - HOUR OF DAY
! KPDS(12) - MINUTE OF HOUR
! KPDS(13) - INDICATOR OF FORECAST TIME UNIT (SEE "GRIB"
! TABLE 8)
! KPDS(14) - TIME 1 (SEE "GRIB" TABLE 8A)
! KPDS(15) - TIME 2 (SEE "GRIB" TABLE 8A)
! KPDS(16) - TIME RANGE INDICATOR (SEE "GRIB" TABLE 8A)
! KPDS(17) - NUMBER INCLUDED IN AVERAGE
! KPDS(18) - EDITION NR OF GRIB SPECIFICATION
! KPDS(19) - VERSION NR OF PARAMETER TABLE
!
! KGDS(13) INTEGER*4
! ARRAY CONTAINING GDS ELEMENTS.
!
! KGDS(1) - DATA REPRESENTATION TYPE
!
! LATITUDE/LONGITUDE GRIDS (SEE "GRIB" TABLE 10)
! KGDS(2) - N(I) NUMBER OF POINTS ON LATITUDE
! CIRCLE
! KGDS(3) - N(J) NUMBER OF POINTS ON LONGITUDE
! CIRCLE
! KGDS(4) - LA(1) LATITUDE OF ORIGIN
! KGDS(5) - LO(1) LONGITUDE OF ORIGIN
! KGDS(6) - RESOLUTION FLAG
! BIT MEANING
! 25 0 - DIRECTION INCREMENTS NOT
! GIVEN
! 1 - DIRECTION INCREMENTS GIVEN
! KGDS(7) - LA(2) LATITUDE OF EXTREME POINT
! KGDS(8) - LO(2) LONGITUDE OF EXTREME POINT
! KGDS(9) - DI LATITUDINAL DIRECTION INCREMENT
! KGDS(10) - REGULAR LAT/LON GRID
! DJ - LONGITUDINAL DIRECTION
! INCREMENT
! GAUSSIAN GRID
! N - NUMBER OF LATITUDE CIRCLES
! BETWEEN A POLE AND THE EQUATOR
! KGDS(11) - SCANNING MODE FLAG
! BIT MEANING
! 25 0 - POINTS ALONG A LATITUDE
! SCAN FROM WEST TO EAST
! 1 - POINTS ALONG A LATITUDE
! SCAN FROM EAST TO WEST
! 26 0 - POINTS ALONG A MERIDIAN
! SCAN FROM NORTH TO SOUTH
! 1 - POINTS ALONG A MERIDIAN
! SCAN FROM SOUTH TO NORTH
! 27 0 - POINTS SCAN FIRST ALONG
! CIRCLES OF LATITUDE, THEN
! ALONG MERIDIANS
! (FORTRAN: (I,J))
! 1 - POINTS SCAN FIRST ALONG
! MERIDIANS THEN ALONG
! CIRCLES OF LATITUDE
! (FORTRAN: (J,I))
!
! POLAR STEREOGRAPHIC GRIDS (SEE GRIB TABLE 12)
! KGDS(2) - N(I) NR POINTS ALONG LAT CIRCLE
! KGDS(3) - N(J) NR POINTS ALONG LON CIRCLE
! KGDS(4) - LA(1) LATITUDE OF ORIGIN
! KGDS(5) - LO(1) LONGITUDE OF ORIGIN
! KGDS(6) - RESERVED
! KGDS(7) - LOV GRID ORIENTATION
! KGDS(8) - DX - X DIRECTION INCREMENT
! KGDS(9) - DY - Y DIRECTION INCREMENT
! KGDS(10) - PROJECTION CENTER FLAG
! KGDS(11) - SCANNING MODE
!
! SPHERICAL HARMONIC COEFFICIENTS (SEE "GRIB" TABLE 14)
! KGDS(2) - J PENTAGONAL RESOLUTION PARAMETER
! KGDS(3) - K PENTAGONAL RESOLUTION PARAMETER
! KGDS(4) - M PENTAGONAL RESOLUTION PARAMETER
! KGDS(5) - REPRESENTATION TYPE
! KGDS(6) - COEFFICIENT STORAGE MODE
!
! MERCATOR GRIDS
! KGDS(2) - N(I) NR POINTS ON LATITUDE CIRCLE
! KGDS(3) - N(J) NR POINTS ON LONGITUDE MERIDIAN
! KGDS(4) - LA(1) LATITUDE OF ORIGIN
! KGDS(5) - LO(1) LONGITUDE OF ORIGIN
! KGDS(6) - RESOLUTION FLAG
! KGDS(7) - LA(2) LATITUDE OF LAST GRID POINT
! KGDS(8) - LO(2) LONGITUDE OF LAST GRID POINT
! KGDS(9) - LATIN - LATITUDE OF PROJECTION INTERSECTION
! KGDS(10) - RESERVED
! KGDS(11) - SCANNING MODE FLAG
! KGDS(12) - LONGITUDINAL DIR GRID LENGTH
! KGDS(13) - LATITUDINAL DIR GRID LENGTH
! LAMBERT CONFORMAL GRIDS
! KGDS(2) - NX NR POINTS ALONG X-AXIS
! KGDS(3) - NY NR POINTS ALONG Y-AXIS
! KGDS(4) - LA1 LAT OF ORIGIN (LOWER LEFT)
! KGDS(5) - LO1 LON OF ORIGIN (LOWER LEFT)
! KGDS(6) - RESOLUTION (RIGHT ADJ COPY OF OCTET 17)
! KGDS(7) - LOV - ORIENTATION OF GRID
! KGDS(8) - DX - X-DIR INCREMENT
! KGDS(9) - DY - Y-DIR INCREMENT
! KGDS(10) - PROJECTION CENTER FLAG
! KGDS(11) - SCANNING MODE FLAG
! KGDS(12) - LATIN 1 - FIRST LAT FROM POLE OF
! SECANT CONE INTERSECTION
! KGDS(13) - LATIN 2 - SECOND LAT FROM POLE OF
! SECANT CONE INTERSECTION
!
! LBMS(65160) LOGICAL
! ARRAY TO CONTAIN THE BIT MAP DESCRIBING THE
! PLACEMENT OF DATA IN THE OUTPUT ARRAY. IF A
! BIT MAP IS NOT INCLUDED IN THE SOURCE MESSAGE,
! ONE WILL BE GENERATED AUTOMATICALLY BY THE
! UNPACKING ROUTINE.
!
!
! DATA(65160) REAL*4
! THIS ARRAY WILL CONTAIN THE UNPACKED DATA POINTS.
!
! NOTE:- 65160 IS MAXIMUN FIELD SIZE ALLOWABLE
!
! KPTR(10) INTEGER*4
! ARRAY CONTAINING STORAGE FOR THE FOLLOWING
! PARAMETERS.
!
! (1) - UNUSED
! (2) - UNUSED
! (3) - LENGTH OF PDS (IN BYTES)
! (4) - LENGTH OF GDS (IN BYTES)
! (5) - LENGTH OF BMS (IN BYTES)
! (6) - LENGTH OF BDS (IN BYTES)
! (7) - USED BY UNPACKING ROUTINE
! (8) - NUMBER OF DATA POINTS FOR GRID
! (9) - "GRIB" CHARACTERS START IN BYTE NUMBER
! (10) - USED BY UNPACKING ROUTINE
!
!
! KRET INTEGER*4
! THIS VARIABLE WILL CONTAIN THE RETURN INDICATOR.
!
! 0 - NO ERRORS DETECTED.
!
! 1 - 'GRIB' NOT FOUND IN FIRST 100
! CHARACTERS.
!
! 2 - '7777' NOT FOUND, EITHER MISSING OR
! TOTAL OF SEC COUNTS OF INDIVIDUAL
! SECTIONS IS INCORRECT.
!
! 3 - UNPACKED FIELD IS LARGER THAN 65160.
!
! 4 - IN GDS, DATA REPRESENTATION TYPE
! NOT ONE OF THE CURRENTLY ACCEPTABLE
! VALUES. SEE "GRIB" TABLE 9. VALUE
! OF INCORRECT TYPE RETURNED IN KGDS(1).
!
! 5 - GRID INDICATED IN KPDS(3) IS NOT
! AVAILABLE FOR THE CENTER INDICATED IN
! KPDS(1) AND NO GDS SENT.
!
! 7 - EDITION INDICATED IN KPDS(18) HAS NOT
! YET BEEN INCLUDED IN THE DECODER.
!
! 8 - GRID IDENTIFICATION = 255 (NOT STANDARD
! GRID) BUT FLAG INDICATING PRESENCE OF
! GDS IS TURNED OFF. NO METHOD OF
! GENERATING PROPER GRID.
!
! 9 - PRODUCT OF KGDS(2) AND KGDS(3) DOES NOT
! MATCH STANDARD NUMBER OF POINTS FOR THIS
! GRID (FOR OTHER THAN SPECTRALS). THIS
! WILL OCCUR ONLY IF THE GRID.
! IDENTIFICATION, KPDS(3), AND A
! TRANSMITTED GDS ARE INCONSISTENT.
!
! 10 - CENTER INDICATOR WAS NOT ONE INDICATED
! IN "GRIB" TABLE 1. PLEASE CONTACT AD
! PRODUCTION MANAGEMENT BRANCH (W/NMC42)
! IF THIS ERROR IS ENCOUNTERED.
!
! 11 - BINARY DATA SECTION (BDS) NOT COMPLETELY
! PROCESSED. PROGRAM IS NOT SET TO PROCESS
! FLAG COMBINATIONS AS SHOWN IN
! OCTETS 4 AND 14.
!
!
! LIST OF TEXT MESSAGES FROM CODE
!
!
! W3FI63/FI632
!
! 'HAVE ENCOUNTERED A NEW GRID FOR NMC, PLEASE NOTIFY
! AUTOMATION DIVISION, PRODUCTION MANAGEMENT BRANCH
! (W/NMC42)'
!
! 'HAVE ENCOUNTERED A NEW GRID FOR ECMWF, PLEASE NOTIFY
! AUTOMATION DIVISION, PRODUCTION MANAGEMENT BRANCH
! (W/NMC42)'
!
! 'HAVE ENCOUNTERED A NEW GRID FOR U.K. METEOROLOGICAL
! OFFICE, BRACKNELL. PLEASE NOTIFY AUTOMATION DIVISION,
! PRODUCTION MANAGEMENT BRANCH (W/NMC42)'
!
! 'HAVE ENCOUNTERED A NEW GRID FOR FNOC, PLEASE NOTIFY
! AUTOMATION DIVISION, PRODUCTION MANAGEMENT BRANCH
! (W/NMC42)'
!
!
! W3FI63/FI633
!
! 'POLAR STEREO PROCESSING NOT AVAILABLE' *
!
! W3FI63/FI634
!
! 'WARNING - BIT MAP MAY NOT BE ASSOCIATED WITH SPHERICAL
! COEFFICIENTS'
!
!
! W3FI63/FI637
!
! 'NO CURRENT LISTING OF FNOC GRIDS' *
!
!
! * WILL BE AVAILABLE IN NEXT UPDATE
! ***************************************************************
!
! INCOMING MESSAGE HOLDER
CHARACTER :: msga(*)
! BIT MAP
LOGICAL*1 :: kbms(*)
!
! ELEMENTS OF PRODUCT DESCRIPTION SEC (PDS)
INTEGER :: kpds(*)
! ELEMENTS OF GRID DESCRIPTION SEC (PDS)
INTEGER :: kgds(*)
!
! CONTAINER FOR GRIB GRID
REAL :: DATA(*)
!
! ARRAY OF POINTERS AND COUNTERS
INTEGER :: kptr(*)
!
! *****************************************************************
INTEGER :: kkk,jsgn,jexp,ifr,npts
CHARACTER (LEN=1) :: kk(8)
REAL :: realkk,fval1,fdiff1
EQUIVALENCE (kk(1),kkk)
! *****************************************************************
! 1.0 LOCATE BEGINNING OF 'GRIB' MESSAGE
! FIND 'GRIB' CHARACTERS
! 2.0 USE COUNTS IN EACH DESCRIPTION SEC TO DETERMINE
! IF '7777' IS IN PROPER PLACE.
! 3.0 PARSE PRODUCT DEFINITION SECTION.
! 4.0 PARSE GRID DESCRIPTION SEC (IF INCLUDED)
! 5.0 PARSE BIT MAP SEC (IF INCLUDED)
! 6.0 USING INFORMATION FROM PRODUCT DEFINITION, GRID
! DESCRIPTION, AND BIT MAP SECTIONS.. EXTRACT
! DATA AND PLACE INTO PROPER ARRAY.
! *******************************************************************
!
! MAIN DRIVER
!
! *******************************************************************
SAVE
kptr(10) = 0
! SEE IF PROPER 'GRIB' KEY EXISTS, THEN
! USING SEC COUNTS, DETERMINE IF '7777'
! IS IN THE PROPER LOCATION
!
CALL fi631
(msga,kptr,kpds,kret)
IF(kret /= 0) THEN
GO TO 900
END IF
! PRINT *,'FI631 KPTR',(KPTR(I),I=1,16)
!
! PARSE PARAMETERS FROM PRODUCT DESCRIPTION SECTION
!
CALL fi632
(msga,kptr,kpds,kret)
IF(kret /= 0) THEN
GO TO 900
END IF
! PRINT *,'FI632 KPTR',(KPTR(I),I=1,16)
!
! IF AVAILABLE, EXTRACT NEW GRID DESCRIPTION
!
IF (IAND(kpds(4),128) /= 0) THEN
CALL fi633
(msga,kptr,kgds,kret)
IF(kret /= 0) THEN
GO TO 900
END IF
! PRINT *,'FI633 KPTR',(KPTR(I),I=1,16)
END IF
!
! EXTRACT OR GENERATE BIT MAP
!
CALL fi634
(msga,kptr,kpds,kgds,kbms,kret)
IF(kret /= 0) THEN
GO TO 900
END IF
! PRINT *,'FI634 KPTR',(KPTR(I),I=1,16)
!
! USING INFORMATION FROM PDS, BMS AND BIT DATA SEC ,
! EXTRACT AND SAVE IN GRIB GRID, ALL DATA ENTRIES.
!
IF (kpds(18) == 1) THEN
CALL fi635
(msga,kptr,kpds,kgds,kbms,DATA,kret)
IF (kptr(3) >= 50) THEN
!
! PDS GREATER THAN 28 BYTES
! THEREFORE SOMETHING SPECIAL IS GOING ON
!
! IN THIS CASE 2ND DIFFERENCE PACKING
! NEEDS TO BE UNDONE.
!
! EXTRACT FIRST VALUE FROM BYTE 41-44 PDS
! KPTR(9) CONTAINS OFFSET TO START OF
! GRIB MESSAGE.
! EXTRACT FIRST FIRST-DIFFERENCE FROM BYTES 45-48 PDS
!
! AND EXTRACT SCALE FACTOR (E) TO UNDO 2**E
! THAT WAS APPLIED PRIOR TO 2ND ORDER PACKING
! AND PLACED IN PDS BYTES 49-51
! FACTOR IS A SIGNED TWO BYTE INTEGER
!
! ALSO NEED THE DECIMAL SCALING FROM PDS(27-28)
! (AVAILABLE IN KPDS(22) FROM UNPACKER)
! TO UNDO THE DECIMAL SCALING APPLIED TO THE
! SECOND DIFFERENCES DURING UNPACKING.
! SECOND DIFFS ALWAYS PACKED WITH 0 DECIMAL SCALE
! BUT UNPACKER DOESNT KNOW THAT.
!
! CALL GRBGBYTE (MSGA,FVAL1,KPTR(9)+384,32)
!
! NOTE INTEGERS, CHARACTERS AND EQUIVALENCES
! DEFINED ABOVE TO MAKE THIS KKK EXTRACTION
! WORK AND LINE UP ON WORD BOUNDARIES
!
CALL grbgbyte
(msga,kkk,kptr(9)+384,32)
!
! THE NEXT CODE WILL CONVERT THE IBM370 FOATING POINT
! TO THE FLOATING POINT USED ON YOUR MACHINE.
!
! 1ST TEST TO SEE IN ON 32 OR 64 BIT WORD MACHINE
! LW = 4 OR 8; IF 8 MAY BE A CRAY
!
CALL w3fi01
(lw)
IF (lw == 4) THEN
CALL grbgbyte
(kk,jsgn,0,1)
CALL grbgbyte
(kk,jexp,1,7)
CALL grbgbyte
(kk,ifr,8,24)
ELSE
CALL grbgbyte
(kk,jsgn,32,1)
CALL grbgbyte
(kk,jexp,33,7)
CALL grbgbyte
(kk,ifr,40,24)
END IF
!
IF (ifr == 0) THEN
realkk = 0.0
ELSE IF (jexp == 0.AND.ifr == 0) THEN
realkk = 0.0
ELSE
realkk = FLOAT(ifr) * 16.0 ** (jexp - 64 - 6)
IF (jsgn /= 0) realkk = -realkk
END IF
fval1 = realkk
!
! CALL GRBGBYTE (MSGA,FDIFF1,KPTR(9)+416,32)
! (REPLACED BY FOLLOWING EXTRACTION)
!
CALL grbgbyte
(msga,kkk,kptr(9)+416,32)
!
! THE NEXT CODE WILL CONVERT THE IBM370 FOATING POINT
! TO THE FLOATING POINT USED ON YOUR MACHINE.
!
! 1ST TEST TO SEE IN ON 32 OR 64 BIT WORD MACHINE
! LW = 4 OR 8; IF 8 MAY BE A CRAY
!
CALL w3fi01
(lw)
IF (lw == 4) THEN
CALL grbgbyte
(kk,jsgn,0,1)
CALL grbgbyte
(kk,jexp,1,7)
CALL grbgbyte
(kk,ifr,8,24)
ELSE
CALL grbgbyte
(kk,jsgn,32,1)
CALL grbgbyte
(kk,jexp,33,7)
CALL grbgbyte
(kk,ifr,40,24)
END IF
!
IF (ifr == 0) THEN
realkk = 0.0
ELSE IF (jexp == 0.AND.ifr == 0) THEN
realkk = 0.0
ELSE
realkk = FLOAT(ifr) * 16.0 ** (jexp - 64 - 6)
IF (jsgn /= 0) realkk = -realkk
END IF
fdiff1 = realkk
!
CALL grbgbyte
(msga,ISIGN,kptr(9)+448,1)
CALL grbgbyte
(msga,iscal2,kptr(9)+449,15)
IF(ISIGN > 0) THEN
iscal2 = - iscal2
END IF
! PRINT *,'DELTA POINT 1-',FVAL1
! PRINT *,'DELTA POINT 2-',FDIFF1
! PRINT *,'DELTA POINT 3-',ISCAL2
npts = kptr(10)
! WRITE (6,FMT='('' 2ND DIFF POINTS IN FIELD = '',/,
! & 10(3X,10F12.2,/))') (DATA(I),I=1,NPTS)
! PRINT *,'DELTA POINT 4-',KPDS(22)
CALL w3fi83
(DATA,npts,fval1,fdiff1, &
iscal2,kpds(22),kpds,kgds)
! WRITE (6,FMT='('' 2ND DIFF EXPANDED POINTS IN FIELD = '',
! & /,10(3X,10F12.2,/))') (DATA(I),I=1,NPTS)
! WRITE (6,FMT='('' END OF ARRAY IN FIELD = '',/,
! & 10(3X,10F12.2,/))') (DATA(I),I=NPTS-5,NPTS)
END IF
ELSE
PRINT *,'FI635 NOT PROGRAMMED FOR EDITION NR',kpds(18)
kret = 7
END IF
!
900 RETURN
END SUBROUTINE w3fi63
SUBROUTINE fi631(msga,kptr,kpds,kret) 1,10
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI631 FIND 'GRIB' CHARS & RESET POINTERS
! PRGMMR: BILL CAVANAUGH ORG: W/NMC42 DATE: 91-09-13
!
! ABSTRACT: FIND 'GRIB; CHARACTERS AND SET POINTERS TO THE NEXT
! BYTE FOLLOWING 'GRIB'. IF THEY EXIST EXTRACT COUNTS FROM GDS AND
! BMS. EXTRACT COUNT FROM BDS. DETERMINE IF SUM OF COUNTS ACTUALLY
! PLACES TERMINATOR '7777' AT THE CORRECT LOCATION.
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
!
! USAGE: CALL FI631(MSGA,KPTR,KPDS,KRET)
! INPUT ARGUMENT LIST:
! MSGA - GRIB FIELD - "GRIB" THRU "7777"
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! (1) - TOTAL LENGTH OF GRIB MESSAGE
! (2) - LENGTH OF INDICATOR (SECTION 0)
! (3) - LENGTH OF PDS (SECTION 1)
! (4) - LENGTH OF GDS (SECTION 2)
! (5) - LENGTH OF BMS (SECTION 3)
! (6) - LENGTH OF BDS (SECTION 4)
! (7) - VALUE OF CURRENT BYTE
! (8) - BIT POINTER
! (9) - GRIB START BIT NR
! (10) - GRIB/GRID ELEMENT COUNT
! (11) - NR UNUSED BITS AT END OF SECTION 3
! (12) - BIT MAP FLAG
! (13) - NR UNUSED BITS AT END OF SECTION 2
! (14) - BDS FLAGS
! (15) - NR UNUSED BITS AT END OF SECTION 4
!
! OUTPUT ARGUMENT LIST: (INCLUDING WORK ARRAYS)
! KPDS - ARRAY CONTAINING PDS ELEMENTS.
! (1) - ID OF CENTER
! (2) - MODEL IDENTIFICATION
! (3) - GRID IDENTIFICATION
! (4) - GDS/BMS FLAG
! (5) - INDICATOR OF PARAMETER
! (6) - TYPE OF LEVEL
! (7) - HEIGHT/PRESSURE , ETC OF LEVEL
! (8) - YEAR OF CENTURY
! (9) - MONTH OF YEAR
! (10) - DAY OF MONTH
! (11) - HOUR OF DAY
! (12) - MINUTE OF HOUR
! (13) - INDICATOR OF FORECAST TIME UNIT
! (14) - TIME RANGE 1
! (15) - TIME RANGE 2
! (16) - TIME RANGE FLAG
! (17) - NUMBER INCLUDED IN AVERAGE
! KPTR - SEE INPUT LIST
! KRET - ERROR RETURN
!
! REMARKS:
! ERROR RETURNS
! KRET = 1 - NO 'GRIB'
! 2 - NO '7777' OR MISLOCATED (BY COUNTS)
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS9000
!
!$$$
!
! INCOMING MESSAGE HOLDER
CHARACTER :: msga(*)
! ARRAY OF POINTERS AND COUNTERS
INTEGER :: kptr(*)
! PRODUCT DESCRIPTION SECTION DATA.
INTEGER :: kpds(*)
!
INTEGER :: kret
!
! ******************************************************************
SAVE
kret = 0
! ------------------- FIND 'GRIB' KEY
DO i = 0, 839, 8
CALL grbgbyte
(msga,mgrib,i,32)
IF (mgrib == 1196575042) THEN
kptr(9) = i
GO TO 60
END IF
END DO
kret = 1
RETURN
60 CONTINUE
! -------------FOUND 'GRIB'
! SKIP GRIB CHARACTERS
! PRINT *,'FI631 GRIB AT',I
kptr(8) = kptr(9) + 32
CALL grbgbyte
(msga,itotal,kptr(8),24)
! HAVE LIFTED WHAT MAY BE A MSG TOTAL BYTE COUNT
ipoint = kptr(9) + itotal * 8 - 32
CALL grbgbyte
(msga,i7777,ipoint,32)
IF (i7777 == 926365495) THEN
! HAVE FOUND END OF MESSAGE '7777' IN PROPER LOCATION
! MARK AND PROCESS AS GRIB VERSION 1 OR HIGHER
! PRINT *,'FI631 7777 AT',IPOINT
kptr(8) = kptr(8) + 24
kptr(1) = itotal
kptr(2) = 8
CALL grbgbyte
(msga,kpds(18),kptr(8),8)
kptr(8) = kptr(8) + 8
ELSE
! CANNOT FIND END OF GRIB EDITION 1 MESSAGE
kret = 2
RETURN
END IF
! ------------------- PROCESS SECTION 1
! EXTRACT COUNT FROM PDS
! PRINT *,'START OF PDS',KPTR(8)
CALL grbgbyte
(msga,kptr(3),kptr(8),24)
look = kptr(8) + 56
! EXTRACT GDS/BMS FLAG
CALL grbgbyte
(msga,kpds(4),look,8)
kptr(8) = kptr(8) + kptr(3) * 8
! PRINT *,'START OF GDS',KPTR(8)
IF (IAND(kpds(4),128) /= 0) THEN
! EXTRACT COUNT FROM GDS
CALL grbgbyte
(msga,kptr(4),kptr(8),24)
kptr(8) = kptr(8) + kptr(4) * 8
ELSE
kptr(4) = 0
END IF
! PRINT *,'START OF BMS',KPTR(8)
IF (IAND(kpds(4),64) /= 0) THEN
! EXTRACT COUNT FROM BMS
CALL grbgbyte
(msga,kptr(5),kptr(8),24)
ELSE
kptr(5) = 0
END IF
kptr(8) = kptr(8) + kptr(5) * 8
! PRINT *,'START OF BDS',KPTR(8)
! EXTRACT COUNT FROM BDS
CALL grbgbyte
(msga,kptr(6),kptr(8),24)
! --------------- TEST FOR '7777'
! PRINT *,(KPTR(KJ),KJ=1,10)
kptr(8) = kptr(8) + kptr(6) * 8
! EXTRACT FOUR BYTES FROM THIS LOCATION
! PRINT *,'FI631 LOOKING FOR 7777 AT',KPTR(8)
CALL grbgbyte
(msga,k7777,kptr(8),32)
match = kptr(2) + kptr(3) + kptr(4) + kptr(5) + kptr(6) + 4
IF (k7777 /= 926365495.OR.match /= kptr(1)) THEN
kret = 2
ELSE
! PRINT *,'FI631 7777 AT',KPTR(8)
IF (kpds(18) == 0) THEN
kptr(1) = kptr(2) + kptr(3) + kptr(4) + kptr(5) + &
kptr(6) + 4
END IF
END IF
! PRINT *,'KPTR',(KPTR(I),I=1,16)
RETURN
END SUBROUTINE fi631
SUBROUTINE fi632(msga,kptr,kpds,kret) 1,24
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI632 GATHER INFO FROM PRODUCT DEFINITION SEC
! PRGMMR: BILL CAVANAUGH ORG: W/NMC42 DATE: 91-09-13
!
! ABSTRACT: EXTRACT INFORMATION FROM THE PRODUCT DESCRIPTION
! SEC , AND GENERATE LABEL INFORMATION TO PERMIT STORAGE
! IN OFFICE NOTE 84 FORMAT.
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
! 93-12-08 CAVANAUGH CORRECTED TEST FOR EDITION NUMBER INSTEAD
! OF VERSION NUMBER
!
! USAGE: CALL FI632(MSGA,KPTR,KPDS,KRET)
! INPUT ARGUMENT LIST:
! MSGA - ARRAY CONTAINING GRIB MESSAGE
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! (1) - TOTAL LENGTH OF GRIB MESSAGE
! (2) - LENGTH OF INDICATOR (SECTION 0)
! (3) - LENGTH OF PDS (SECTION 1)
! (4) - LENGTH OF GDS (SECTION 2)
! (5) - LENGTH OF BMS (SECTION 3)
! (6) - LENGTH OF BDS (SECTION 4)
! (7) - VALUE OF CURRENT BYTE
! (8) - BIT POINTER
! (9) - GRIB START BIT NR
! (10) - GRIB/GRID ELEMENT COUNT
! (11) - NR UNUSED BITS AT END OF SECTION 3
! (12) - BIT MAP FLAG
! (13) - NR UNUSED BITS AT END OF SECTION 2
! (14) - BDS FLAGS
! (15) - NR UNUSED BITS AT END OF SECTION 4
!
! OUTPUT ARGUMENT LIST: (INCLUDING WORK ARRAYS)
! KPDS - ARRAY CONTAINING PDS ELEMENTS.
! (1) - ID OF CENTER
! (2) - MODEL IDENTIFICATION
! (3) - GRID IDENTIFICATION
! (4) - GDS/BMS FLAG
! (5) - INDICATOR OF PARAMETER
! (6) - TYPE OF LEVEL
! (7) - HEIGHT/PRESSURE , ETC OF LEVEL
! (8) - YEAR OF CENTURY
! (9) - MONTH OF YEAR
! (10) - DAY OF MONTH
! (11) - HOUR OF DAY
! (12) - MINUTE OF HOUR
! (13) - INDICATOR OF FORECAST TIME UNIT
! (14) - TIME RANGE 1
! (15) - TIME RANGE 2
! (16) - TIME RANGE FLAG
! (17) - NUMBER INCLUDED IN AVERAGE
! (18) -
! (19) -
! (20) - NUMBER MISSING FROM AVGS/ACCUMULATIONS
! (21) - CENTURY
! (22) - UNITS DECIMAL SCALE FACTOR
! (23) - SUBCENTER
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! SEE INPUT LIST
! KRET - ERROR RETURN
!
! REMARKS:
! ERROR RETURN = 0 - NO ERRORS
! = 8 - TEMP GDS INDICATED, BUT NO GDS
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS9000
!
!$$$
!
! INCOMING MESSAGE HOLDER
CHARACTER :: msga(*)
!
! ARRAY OF POINTERS AND COUNTERS
INTEGER :: kptr(*)
! PRODUCT DESCRIPTION SECTION ENTRIES
INTEGER :: kpds(*)
!
INTEGER :: kret
! ------------------- PROCESS SECTION 1
SAVE
kptr(8) = kptr(9) + kptr(2) * 8 + 24
! BYTE 4
! PARAMETER TABLE VERSION NR
CALL grbgbyte
(msga,kpds(19),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 5 IDENTIFICATION OF CENTER
CALL grbgbyte
(msga,kpds(1),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 6
! GET GENERATING PROCESS ID NR
CALL grbgbyte
(msga,kpds(2),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 7
! GRID DEFINITION
CALL grbgbyte
(msga,kpds(3),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 8
! GDS/BMS FLAGS
! CALL GRBGBYTE (MSGA,KPDS(4),KPTR(8),8)
kptr(8) = kptr(8) + 8
! BYTE 9
! INDICATOR OF PARAMETER
CALL grbgbyte
(msga,kpds(5),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 10
! TYPE OF LEVEL
CALL grbgbyte
(msga,kpds(6),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 11,12
! HEIGHT/PRESSURE
CALL grbgbyte
(msga,kpds(7),kptr(8),16)
kptr(8) = kptr(8) + 16
! BYTE 13
! YEAR OF CENTURY
CALL grbgbyte
(msga,kpds(8),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 14
! MONTH OF YEAR
CALL grbgbyte
(msga,kpds(9),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 15
! DAY OF MONTH
CALL grbgbyte
(msga,kpds(10),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 16
! HOUR OF DAY
CALL grbgbyte
(msga,kpds(11),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 17
! MINUTE
CALL grbgbyte
(msga,kpds(12),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 18
! INDICATOR TIME UNIT RANGE
CALL grbgbyte
(msga,kpds(13),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 19
! P1 - PERIOD OF TIME
CALL grbgbyte
(msga,kpds(14),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 20
! P2 - PERIOD OF TIME
CALL grbgbyte
(msga,kpds(15),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 21
! TIME RANGE INDICATOR
CALL grbgbyte
(msga,kpds(16),kptr(8),8)
kptr(8) = kptr(8) + 8
!
! IF TIME RANGE INDICATOR IS 10, P1 IS PACKED IN
! PDS BYTES 19-20
!
IF (kpds(16) == 10) THEN
kpds(14) = kpds(14) * 256 + kpds(15)
kpds(15) = 0
END IF
! BYTE 22,23
! NUMBER INCLUDED IN AVERAGE
CALL grbgbyte
(msga,kpds(17),kptr(8),16)
kptr(8) = kptr(8) + 16
! BYTE 24
! NUMBER MISSING FROM AVERAGES/ACCUMULATIONS
CALL grbgbyte
(msga,kpds(20),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 25
! IDENTIFICATION OF CENTURY
CALL grbgbyte
(msga,kpds(21),kptr(8),8)
kptr(8) = kptr(8) + 8
IF (kptr(3) > 25) THEN
! BYTE 26 SUB CENTER NUMBER
CALL grbgbyte
(msga,kpds(23),kptr(8),8)
kptr(8) = kptr(8) + 8
IF (kptr(3) >= 28) THEN
! BYTE 27-28
! UNITS DECIMAL SCALE FACTOR
CALL grbgbyte
(msga,ISIGN,kptr(8),1)
kptr(8) = kptr(8) + 1
CALL grbgbyte
(msga,idec,kptr(8),15)
kptr(8) = kptr(8) + 15
IF (ISIGN > 0) THEN
kpds(22) = - idec
ELSE
kpds(22) = idec
END IF
isiz = kptr(3) - 28
IF (isiz <= 12) THEN
! BYTES 29-40 CURRENTLY RESERVED FOR FUTURE USE
kptr(8) = kptr(8) + isiz * 8
ELSE
! BYTES 29-40 CURRENTLY RESERVED FOR FUTURE USE
kptr(8) = kptr(8) + 12 * 8
! BYTES 40 - N LOCAL USE DATA
CALL w3fi01
(lw)
mwdbit = lw * 8
isiz = kptr(3) - 40
iter = isiz / lw
CALL grbgbytes
(msga,kpds(36),kptr(8),mwdbit,0,iter)
kptr(8) = kptr(8) + isiz * 8
END IF
END IF
END IF
! ----------- TEST FOR NEW GRID
IF (IAND(kpds(4),128) /= 0) THEN
IF (IAND(kpds(4),64) /= 0) THEN
IF (kpds(3) /= 255) THEN
IF (kpds(3) >= 21.AND.kpds(3) <= 26)THEN
RETURN
ELSE IF (kpds(3) >= 37.AND.kpds(3) <= 44)THEN
RETURN
ELSE IF (kpds(3) >= 61.AND.kpds(3) <= 64) THEN
RETURN
END IF
IF (kpds(1) == 7) THEN
IF (kpds(3) >= 2.AND.kpds(3) <= 3)THEN
ELSE IF (kpds(3) >= 5.AND.kpds(3) <= 6)THEN
ELSE IF (kpds(3) >= 27.AND.kpds(3) <= 34)THEN
ELSE IF (kpds(3) == 50) THEN
ELSE IF (kpds(3) >= 70.AND.kpds(3) <= 77) THEN
ELSE IF (kpds(3) >= 100.AND.kpds(3) <= 105) THEN
ELSE IF (kpds(3) >= 201.AND.kpds(3) <= 214) THEN
ELSE
PRINT *,' HAVE ENCOUNTERED A NEW GRID FOR', &
' NMC WITHOUT A GRID DESCRIPTION SECTION'
PRINT *,' PLEASE NOTIFY AUTOMATION DIVISION'
PRINT *,' PRODUCTION MANAGEMENT BRANCH'
PRINT *,' W/NMC42)'
END IF
ELSE IF (kpds(1) == 98) THEN
IF (kpds(3) >= 1.AND.kpds(3) <= 16) THEN
ELSE
PRINT *,' HAVE ENCOUNTERED A NEW GRID FOR', &
' ECMWF WITHOUT A GRID DESCRIPTION SECTION'
PRINT *,' PLEASE NOTIFY AUTOMATION DIVISION'
PRINT *,' PRODUCTION MANAGEMENT BRANCH'
PRINT *,' W/NMC42)'
END IF
ELSE IF (kpds(1) == 74) THEN
IF (kpds(3) >= 1.AND.kpds(3) <= 12) THEN
ELSE IF (kpds(3) >= 21.AND.kpds(3) <= 26)THEN
ELSE IF (kpds(3) >= 61.AND.kpds(3) <= 64) THEN
ELSE IF (kpds(3) >= 70.AND.kpds(3) <= 77) THEN
ELSE
PRINT *,' HAVE ENCOUNTERED A NEW GRID FOR', &
' U.K. MET OFFICE, BRACKNELL', &
' WITHOUT A GRID DESCRIPTION SECTION'
PRINT *,' PLEASE NOTIFY AUTOMATION DIVISION'
PRINT *,' PRODUCTION MANAGEMENT BRANCH'
PRINT *,' W/NMC42)'
END IF
ELSE IF (kpds(1) == 58) THEN
IF (kpds(3) >= 1.AND.kpds(3) <= 12) THEN
ELSE
PRINT *,' HAVE ENCOUNTERED A NEW GRID FOR', &
' FNOC WITHOUT A GRID DESCRIPTION SECTION'
PRINT *,' PLEASE NOTIFY AUTOMATION DIVISION'
PRINT *,' PRODUCTION MANAGEMENT BRANCH'
PRINT *,' W/NMC42)'
END IF
END IF
END IF
END IF
END IF
RETURN
END SUBROUTINE fi632
SUBROUTINE fi633(msga,kptr,kgds,kret) 1,58
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI633 EXTRACT INFO FROM GRIB-GDS
! PRGMMR: BILL CAVANAUGH ORG: W/NMC42 DATE: 91-09-13
!
! ABSTRACT: EXTRACT INFORMATION ON UNLISTED GRID TO ALLOW
! CONVERSION TO OFFICE NOTE 84 FORMAT.
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
!
! USAGE: CALL FI633(MSGA,KPTR,KGDS,KRET)
! INPUT ARGUMENT LIST:
! MSGA - ARRAY CONTAINING GRIB MESSAGE
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! (1) - TOTAL LENGTH OF GRIB MESSAGE
! (2) - LENGTH OF INDICATOR (SECTION 0)
! (3) - LENGTH OF PDS (SECTION 1)
! (4) - LENGTH OF GDS (SECTION 2)
! (5) - LENGTH OF BMS (SECTION 3)
! (6) - LENGTH OF BDS (SECTION 4)
! (7) - VALUE OF CURRENT BYTE
! (8) - BIT POINTER
! (9) - GRIB START BIT NR
! (10) - GRIB/GRID ELEMENT COUNT
! (11) - NR UNUSED BITS AT END OF SECTION 3
! (12) - BIT MAP FLAG
! (13) - NR UNUSED BITS AT END OF SECTION 2
! (14) - BDS FLAGS
! (15) - NR UNUSED BITS AT END OF SECTION 4
!
! OUTPUT ARGUMENT LIST: (INCLUDING WORK ARRAYS)
! KGDS - ARRAY CONTAINING GDS ELEMENTS.
! (1) - DATA REPRESENTATION TYPE
! (19) - NUMBER OF VERTICAL COORDINATE PARAMETERS
! (20) - OCTET NUMBER OF THE LIST OF VERTICAL COORDINATE
! PARAMETERS
! OR
! OCTET NUMBER OF THE LIST OF NUMBERS OF POINTS
! IN EACH ROW
! OR
! 255 IF NEITHER ARE PRESENT
! (21) - FOR GRIDS WITH PL, NUMBER OF POINTS IN GRID
! (22) - NUMBER OF WORDS IN EACH ROW
! LATITUDE/LONGITUDE GRIDS
! (2) - N(I) NR POINTS ON LATITUDE CIRCLE
! (3) - N(J) NR POINTS ON LONGITUDE MERIDIAN
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESOLUTION FLAG
! (7) - LA(2) LATITUDE OF EXTREME POINT
! (8) - LO(2) LONGITUDE OF EXTREME POINT
! (9) - DI LATITUDINAL DIRECTION OF INCREMENT
! (10) - DJ LONGITUDINAL DIRECTION INCREMENT
! (11) - SCANNING MODE FLAG
! POLAR STEREOGRAPHIC GRIDS
! (2) - N(I) NR POINTS ALONG LAT CIRCLE
! (3) - N(J) NR POINTS ALONG LON CIRCLE
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESERVED
! (7) - LOV GRID ORIENTATION
! (8) - DX - X DIRECTION INCREMENT
! (9) - DY - Y DIRECTION INCREMENT
! (10) - PROJECTION CENTER FLAG
! (11) - SCANNING MODE
! SPHERICAL HARMONIC COEFFICIENTS
! (2) - J PENTAGONAL RESOLUTION PARAMETER
! (3) - K " " "
! (4) - M " " "
! (5) - REPRESENTATION TYPE
! (6) - COEFFICIENT STORAGE MODE
! MERCATOR GRIDS
! (2) - N(I) NR POINTS ON LATITUDE CIRCLE
! (3) - N(J) NR POINTS ON LONGITUDE MERIDIAN
! (4) - LA(1) LATITUDE OF ORIGIN
! (5) - LO(1) LONGITUDE OF ORIGIN
! (6) - RESOLUTION FLAG
! (7) - LA(2) LATITUDE OF LAST GRID POINT
! (8) - LO(2) LONGITUDE OF LAST GRID POINT
! (9) - LATIN - LATITUDE OF PROJECTION INTERSECTION
! (10) - RESERVED
! (11) - SCANNING MODE FLAG
! (12) - LONGITUDINAL DIR GRID LENGTH
! (13) - LATITUDINAL DIR GRID LENGTH
! LAMBERT CONFORMAL GRIDS
! (2) - NX NR POINTS ALONG X-AXIS
! (3) - NY NR POINTS ALONG Y-AXIS
! (4) - LA1 LAT OF ORIGIN (LOWER LEFT)
! (5) - LO1 LON OF ORIGIN (LOWER LEFT)
! (6) - RESOLUTION (RIGHT ADJ COPY OF OCTET 17)
! (7) - LOV - ORIENTATION OF GRID
! (8) - DX - X-DIR INCREMENT
! (9) - DY - Y-DIR INCREMENT
! (10) - PROJECTION CENTER FLAG
! (11) - SCANNING MODE FLAG
! (12) - LATIN 1 - FIRST LAT FROM POLE OF SECANT CONE INTER
! (13) - LATIN 2 - SECOND LAT FROM POLE OF SECANT CONE INTER
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! SEE INPUT LIST
! KRET - ERROR RETURN
!
! REMARKS:
! KRET = 0
! = 4 - DATA REPRESENTATION TYPE NOT CURRENTLY ACCEPTABLE
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS9000
!
!$$$
! ************************************************************
! INCOMING MESSAGE HOLDER
CHARACTER :: msga(*)
!
! ARRAY GDS ELEMENTS
INTEGER :: kgds(*)
! ARRAY OF POINTERS AND COUNTERS
INTEGER :: kptr(*)
!
INTEGER :: kret
! ---------------------------------------------------------------
SAVE
kret = 0
! PROCESS GRID DEFINITION SECTION (IF PRESENT)
! MAKE SURE BIT POINTER IS PROPERLY SET
kptr(8) = kptr(9) + (kptr(2)*8) + (kptr(3)*8) + 24
nsave = kptr(8) - 24
! BYTE 4
! NV - NR OF VERT COORD PARAMETERS
CALL grbgbyte
(msga,kgds(19),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 5
! PV - LOCATION - SEE FM92 MANUAL
CALL grbgbyte
(msga,kgds(20),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTE 6
! DATA REPRESENTATION TYPE
CALL grbgbyte
(msga,kgds(1),kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTES 7-32 ARE GRID DEFINITION DEPENDING ON
! DATA REPRESENTATION TYPE
IF (kgds(1) == 0) THEN
GO TO 1000
ELSE IF (kgds(1) == 1) THEN
GO TO 4000
ELSE IF (kgds(1) == 2.OR.kgds(1) == 5) THEN
GO TO 2000
ELSE IF (kgds(1) == 3) THEN
GO TO 5000
ELSE IF (kgds(1) == 4) THEN
GO TO 1000
! ELSE IF (KGDS(1).EQ.10) THEN
! ELSE IF (KGDS(1).EQ.14) THEN
! ELSE IF (KGDS(1).EQ.20) THEN
! ELSE IF (KGDS(1).EQ.24) THEN
! ELSE IF (KGDS(1).EQ.30) THEN
! ELSE IF (KGDS(1).EQ.34) THEN
ELSE IF (kgds(1) == 50) THEN
GO TO 3000
! ELSE IF (KGDS(1).EQ.60) THEN
! ELSE IF (KGDS(1).EQ.70) THEN
! ELSE IF (KGDS(1).EQ.80) THEN
ELSE
! MARK AS GDS/ UNKNOWN DATA REPRESENTATION TYPE
kret = 4
RETURN
END IF
! BYTE 33-N VERTICAL COORDINATE PARAMETERS
! -----------
! BYTES 33-42 EXTENSIONS OF GRID DEFINITION FOR ROTATION
! OR STRETCHING OF THE COORDINATE SYSTEM OR
! LAMBERT CONFORMAL PROJECTION.
! BYTE 43-N VERTICAL COORDINATE PARAMETERS
! -----------
! BYTES 33-52 EXTENSIONS OF GRID DEFINITION FOR STRETCHED
! AND ROTATED COORDINATE SYSTEM
! BYTE 53-N VERTICAL COORDINATE PARAMETERS
! -----------
! ************************************************************
! ------------------- LATITUDE/LONGITUDE GRIDS
!
! ------------------- BYTE 7-8 NR OF POINTS ALONG LATITUDE CIRCLE
1000 CONTINUE
CALL grbgbyte
(msga,kgds(2),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 9-10 NR OF POINTS ALONG LONG MERIDIAN
CALL grbgbyte
(msga,kgds(3),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 11-13 LATITUDE OF ORIGIN
CALL grbgbyte
(msga,kgds(4),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(4),8388608) /= 0) THEN
kgds(4) = IAND(kgds(4),8388607) * (-1)
END IF
! ------------------- BYTE 14-16 LONGITUDE OF ORIGIN
CALL grbgbyte
(msga,kgds(5),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(5),8388608) /= 0) THEN
kgds(5) = - IAND(kgds(5),8388607)
END IF
! ------------------- BYTE 17 RESOLUTION FLAG
CALL grbgbyte
(msga,kgds(6),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 18-20 LATITUDE OF LAST GRID POINT
CALL grbgbyte
(msga,kgds(7),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(7),8388608) /= 0) THEN
kgds(7) = - IAND(kgds(7),8388607)
END IF
! ------------------- BYTE 21-23 LONGITUDE OF LAST GRID POINT
CALL grbgbyte
(msga,kgds(8),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(8),8388608) /= 0) THEN
kgds(8) = - IAND(kgds(8),8388607)
END IF
! ------------------- BYTE 24-25 LATITUDINAL DIR INCREMENT
CALL grbgbyte
(msga,kgds(9),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 26-27 IF REGULAR LAT/LON GRID
! HAVE LONGIT DIR INCREMENT
! ELSE IF GAUSSIAN GRID
! HAVE NR OF LAT CIRCLES
! BETWEEN POLE AND EQUATOR
CALL grbgbyte
(msga,kgds(10),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 28 SCANNING MODE FLAGS
CALL grbgbyte
(msga,kgds(11),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 29-32 RESERVED
! SKIP TO START OF BYTE 33
CALL grbgbyte
(msga,kgds(12),kptr(8),32)
kptr(8) = kptr(8) + 32
! -------------------
GO TO 900
! ******************************************************************
! ' POLAR STEREO PROCESSING '
!
! ------------------- BYTE 7-8 NR OF POINTS ALONG X=AXIS
2000 CONTINUE
CALL grbgbyte
(msga,kgds(2),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 9-10 NR OF POINTS ALONG Y-AXIS
CALL grbgbyte
(msga,kgds(3),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 11-13 LATITUDE OF ORIGIN
CALL grbgbyte
(msga,kgds(4),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(4),8388608) /= 0) THEN
kgds(4) = - IAND(kgds(4),8388607)
END IF
! ------------------- BYTE 14-16 LONGITUDE OF ORIGIN
CALL grbgbyte
(msga,kgds(5),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(5),8388608) /= 0) THEN
kgds(5) = - IAND(kgds(5),8388607)
END IF
! ------------------- BYTE 17 RESERVED
CALL grbgbyte
(msga,kgds(6),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 18-20 LOV ORIENTATION OF THE GRID
CALL grbgbyte
(msga,kgds(7),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(7),8388608) /= 0) THEN
kgds(7) = - IAND(kgds(7),8388607)
END IF
! ------------------- BYTE 21-23 DX - THE X DIRECTION INCREMENT
CALL grbgbyte
(msga,kgds(8),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(8),8388608) /= 0) THEN
kgds(8) = - IAND(kgds(8),8388607)
END IF
! ------------------- BYTE 24-26 DY - THE Y DIRECTION INCREMENT
CALL grbgbyte
(msga,kgds(9),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(9),8388608) /= 0) THEN
kgds(9) = - IAND(kgds(9),8388607)
END IF
! ------------------- BYTE 27 PROJECTION CENTER FLAG
CALL grbgbyte
(msga,kgds(10),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 28 SCANNING MODE
CALL grbgbyte
(msga,kgds(11),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 29-32 RESERVED
! SKIP TO START OF BYTE 33
CALL grbgbyte
(msga,kgds(12),kptr(8),32)
kptr(8) = kptr(8) + 32
!
! -------------------
GO TO 900
!
! ******************************************************************
! ------------------- GRID DESCRIPTION FOR SPHERICAL HARMONIC COEFF.
!
! ------------------- BYTE 7-8 J PENTAGONAL RESOLUTION PARAMETER
3000 CONTINUE
CALL grbgbyte
(msga,kgds(2),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 9-10 K PENTAGONAL RESOLUTION PARAMETER
CALL grbgbyte
(msga,kgds(3),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 11-12 M PENTAGONAL RESOLUTION PARAMETER
CALL grbgbyte
(msga,kgds(4),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 13 REPRESENTATION TYPE
CALL grbgbyte
(msga,kgds(5),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 14 COEFFICIENT STORAGE MODE
CALL grbgbyte
(msga,kgds(6),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- EMPTY FIELDS - BYTES 15 - 32
! SET TO START OF BYTE 33
kptr(8) = kptr(8) + 18 * 8
GO TO 900
! ******************************************************************
! PROCESS MERCATOR GRIDS
!
! ------------------- BYTE 7-8 NR OF POINTS ALONG LATITUDE CIRCLE
4000 CONTINUE
CALL grbgbyte
(msga,kgds(2),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 9-10 NR OF POINTS ALONG LONG MERIDIAN
CALL grbgbyte
(msga,kgds(3),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 11-13 LATITUE OF ORIGIN
CALL grbgbyte
(msga,kgds(4),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(4),8388608) /= 0) THEN
kgds(4) = - IAND(kgds(4),8388607)
END IF
! ------------------- BYTE 14-16 LONGITUDE OF ORIGIN
CALL grbgbyte
(msga,kgds(5),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(5),8388608) /= 0) THEN
kgds(5) = - IAND(kgds(5),8388607)
END IF
! ------------------- BYTE 17 RESOLUTION FLAG
CALL grbgbyte
(msga,kgds(6),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 18-20 LATITUDE OF EXTREME POINT
CALL grbgbyte
(msga,kgds(7),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(7),8388608) /= 0) THEN
kgds(7) = - IAND(kgds(7),8388607)
END IF
! ------------------- BYTE 21-23 LONGITUDE OF EXTREME POINT
CALL grbgbyte
(msga,kgds(8),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(8),8388608) /= 0) THEN
kgds(8) = - IAND(kgds(8),8388607)
END IF
! ------------------- BYTE 24-26 LATITUDE OF PROJECTION INTERSECTION
CALL grbgbyte
(msga,kgds(9),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(9),8388608) /= 0) THEN
kgds(9) = - IAND(kgds(9),8388607)
END IF
! ------------------- BYTE 27 RESERVED
CALL grbgbyte
(msga,kgds(10),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 28 SCANNING MODE
CALL grbgbyte
(msga,kgds(11),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 29-31 LONGITUDINAL DIR INCREMENT
CALL grbgbyte
(msga,kgds(12),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(12),8388608) /= 0) THEN
kgds(12) = - IAND(kgds(12),8388607)
END IF
! ------------------- BYTE 32-34 LATITUDINAL DIR INCREMENT
CALL grbgbyte
(msga,kgds(13),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(13),8388608) /= 0) THEN
kgds(13) = - IAND(kgds(13),8388607)
END IF
! ------------------- BYTE 35-42 RESERVED
! SKIP TO START OF BYTE 43
kptr(8) = kptr(8) + 8 * 8
! -------------------
GO TO 900
! ******************************************************************
! PROCESS LAMBERT CONFORMAL
!
! ------------------- BYTE 7-8 NR OF POINTS ALONG X-AXIS
5000 CONTINUE
CALL grbgbyte
(msga,kgds(2),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 9-10 NR OF POINTS ALONG Y-AXIS
CALL grbgbyte
(msga,kgds(3),kptr(8),16)
kptr(8) = kptr(8) + 16
! ------------------- BYTE 11-13 LATITUDE OF ORIGIN
CALL grbgbyte
(msga,kgds(4),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(4),8388608) /= 0) THEN
kgds(4) = - IAND(kgds(4),8388607)
END IF
! ------------------- BYTE 14-16 LONGITUDE OF ORIGIN (LOWER LEFT)
CALL grbgbyte
(msga,kgds(5),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(5),8388608) /= 0) THEN
kgds(5) = - IAND(kgds(5),8388607)
END IF
! ------------------- BYTE 17 RESOLUTION
CALL grbgbyte
(msga,kgds(6),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 18-20 LOV -ORIENTATION OF GRID
CALL grbgbyte
(msga,kgds(7),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(7),8388608) /= 0) THEN
kgds(7) = - IAND(kgds(7),8388607)
END IF
! ------------------- BYTE 21-23 DX - X-DIR INCREMENT
CALL grbgbyte
(msga,kgds(8),kptr(8),24)
kptr(8) = kptr(8) + 24
! ------------------- BYTE 24-26 DY - Y-DIR INCREMENT
CALL grbgbyte
(msga,kgds(9),kptr(8),24)
kptr(8) = kptr(8) + 24
! ------------------- BYTE 27 PROJECTION CENTER FLAG
CALL grbgbyte
(msga,kgds(10),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 28 SCANNING MODE
CALL grbgbyte
(msga,kgds(11),kptr(8),8)
kptr(8) = kptr(8) + 8
! ------------------- BYTE 29-31 LATIN1 - 1ST LAT FROM POLE
CALL grbgbyte
(msga,kgds(12),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(12),8388608) /= 0) THEN
kgds(12) = - IAND(kgds(12),8388607)
END IF
! ------------------- BYTE 32-34 LATIN2 - 2ND LAT FROM POLE
CALL grbgbyte
(msga,kgds(13),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(13),8388608) /= 0) THEN
kgds(13) = - IAND(kgds(13),8388607)
END IF
! ------------------- BYTE 35-37 LATITUDE OF SOUTHERN POLE
CALL grbgbyte
(msga,kgds(14),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(14),8388608) /= 0) THEN
kgds(14) = - IAND(kgds(14),8388607)
END IF
! ------------------- BYTE 38-40 LONGITUDE OF SOUTHERN POLE
CALL grbgbyte
(msga,kgds(15),kptr(8),24)
kptr(8) = kptr(8) + 24
IF (IAND(kgds(15),8388608) /= 0) THEN
kgds(15) = - IAND(kgds(15),8388607)
END IF
! ------------------- BYTE 41-42 RESERVED
CALL grbgbyte
(msga,kgds(16),kptr(8),16)
kptr(8) = kptr(8) + 16
! -------------------
900 CONTINUE
!
! MORE CODE FOR GRIDS WITH PL
!
IF (kgds(19) == 0.AND.kgds(20) /= 255) THEN
isum = 0
kptr(8) = nsave + (kgds(20) - 1) * 8
CALL grbgbytes
(msga,kgds(22),kptr(8),16,0,kgds(3))
DO j = 1, kgds(3)
isum = isum + kgds(21+j)
END DO
kgds(21) = isum
END IF
RETURN
END SUBROUTINE fi633
SUBROUTINE fi634(msga,kptr,kpds,kgds,kbms,kret) 1,17
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI634 EXTRACT OR GENERATE BIT MAP FOR OUTPUT
! PRGMMR: BILL CAVANAUGH ORG: W/NMC42 DATE: 91-09-13
!
! ABSTRACT: IF BIT MAP SEC IS AVAILABLE IN GRIB MESSAGE, EXTRACT
! FOR PROGRAM USE, OTHERWISE GENERATE AN APPROPRIATE BIT MAP.
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
! 91-11-12 CAVANAUGH MODIFIED SIZE OF ECMWF GRIDS 5 - 8.
!
! USAGE: CALL FI634(MSGA,KPTR,KPDS,KGDS,KBMS,KRET)
! INPUT ARGUMENT LIST:
! MSGA - BUFR MESSAGE
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! (1) - TOTAL LENGTH OF GRIB MESSAGE
! (2) - LENGTH OF INDICATOR (SECTION 0)
! (3) - LENGTH OF PDS (SECTION 1)
! (4) - LENGTH OF GDS (SECTION 2)
! (5) - LENGTH OF BMS (SECTION 3)
! (6) - LENGTH OF BDS (SECTION 4)
! (7) - VALUE OF CURRENT BYTE
! (8) - BIT POINTER
! (9) - GRIB START BIT NR
! (10) - GRIB/GRID ELEMENT COUNT
! (11) - NR UNUSED BITS AT END OF SECTION 3
! (12) - BIT MAP FLAG
! (13) - NR UNUSED BITS AT END OF SECTION 2
! (14) - BDS FLAGS
! (15) - NR UNUSED BITS AT END OF SECTION 4
! KPDS - ARRAY CONTAINING PDS ELEMENTS.
! (1) - ID OF CENTER
! (2) - MODEL IDENTIFICATION
! (3) - GRID IDENTIFICATION
! (4) - GDS/BMS FLAG
! (5) - INDICATOR OF PARAMETER
! (6) - TYPE OF LEVEL
! (7) - HEIGHT/PRESSURE , ETC OF LEVEL
! (8) - YEAR OF CENTURY
! (9) - MONTH OF YEAR
! (10) - DAY OF MONTH
! (11) - HOUR OF DAY
! (12) - MINUTE OF HOUR
! (13) - INDICATOR OF FORECAST TIME UNIT
! (14) - TIME RANGE 1
! (15) - TIME RANGE 2
! (16) - TIME RANGE FLAG
! (17) - NUMBER INCLUDED IN AVERAGE
!
! OUTPUT ARGUMENT LIST:
! KBMS - BITMAP DESCRIBING LOCATION OF OUTPUT ELEMENTS.
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! SEE INPUT LIST
! KRET - ERROR RETURN
!
! REMARKS:
! KRET = 0 - NO ERROR
! = 5 - GRID NOT AVAIL FOR CENTER INDICATED
! =10 - INCORRECT CENTER INDICATOR
! =12 - BYTES 5-6 ARE NOT ZERO IN BMS, PREDEFINED BIT MAP
! NOT PROVIDED BY THIS CENTER
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS9000
!
!$$$
!
! INCOMING MESSAGE HOLDER
CHARACTER :: msga(*)
!
! BIT MAP
LOGICAL*1 :: kbms(*)
!
! ARRAY OF POINTERS AND COUNTERS
INTEGER :: kptr(*)
! ARRAY OF POINTERS AND COUNTERS
INTEGER :: kpds(*)
INTEGER :: kgds(*)
!
INTEGER :: kret
INTEGER :: mask(8)
! ----------------------GRID 21 AND GRID 22 ARE THE SAME
LOGICAL*1 grd21( 1369)
! ----------------------GRID 23 AND GRID 24 ARE THE SAME
LOGICAL*1 grd23( 1369)
LOGICAL*1 grd25( 1368)
LOGICAL*1 grd26( 1368)
! ----------------------GRID 27 AND GRID 28 ARE THE SAME
! ----------------------GRID 29 AND GRID 30 ARE THE SAME
! ----------------------GRID 33 AND GRID 34 ARE THE SAME
LOGICAL*1 grd50( 1188)
! -----------------------GRID 61 AND GRID 62 ARE THE SAME
LOGICAL*1 grd61( 4186)
! -----------------------GRID 63 AND GRID 64 ARE THE SAME
LOGICAL*1 grd63( 4186)
! LOGICAL*1 GRD70(16380)/16380*.TRUE./
! -------------------------------------------------------------
SAVE
DATA grd21 /1333*.true.,36*.false./
DATA grd23 /.true.,36*.false.,1332*.true./
DATA grd25 /1297*.true.,71*.false./
DATA grd26 /.true.,71*.false.,1296*.true./
DATA grd50/ &
! LINE 1-4
7*.false.,22*.true.,14*.false.,22*.true., &
14*.false.,22*.true.,14*.false.,22*.true.,7*.false., &
! LINE 5-8
6*.false.,24*.true.,12*.false.,24*.true., &
12*.false.,24*.true.,12*.false.,24*.true.,6*.false., &
! LINE 9-12
5*.false.,26*.true.,10*.false.,26*.true., &
10*.false.,26*.true.,10*.false.,26*.true.,5*.false., &
! LINE 13-16
4*.false.,28*.true., 8*.false.,28*.true., &
8*.false.,28*.true., 8*.false.,28*.true.,4*.false., &
! LINE 17-20
3*.false.,30*.true., 6*.false.,30*.true., &
6*.false.,30*.true., 6*.false.,30*.true.,3*.false., &
! LINE 21-24
2*.false.,32*.true., 4*.false.,32*.true., &
4*.false.,32*.true., 4*.false.,32*.true.,2*.false., &
! LINE 25-28
.false.,34*.true., 2*.false.,34*.true., &
2*.false.,34*.true., 2*.false.,34*.true., .false., &
! LINE 29-33
180*.true./
DATA grd61 /4096*.true.,90*.false./
DATA grd63 /.true.,90*.false.,4095*.true./
DATA mask /128,64,32,16,8,4,2,1/
!
! PRINT *,'FI634'
IF (IAND(kpds(4),64) == 64) THEN
!
! SET UP BIT POINTER
! SECTION 0 SECTION 1 SECTION 2
kptr(8) = kptr(9) + (kptr(2)*8) + (kptr(3)*8) + (kptr(4)*8) + 24
!
! BYTE 4 NUMBER OF UNUSED BITS AT END OF SECTION 3
!
CALL grbgbyte
(msga,kptr(11),kptr(8),8)
kptr(8) = kptr(8) + 8
!
! BYTE 5,6 TABLE REFERENCE IF 0, BIT MAP FOLLOWS
!
CALL grbgbyte
(msga,kptr(12),kptr(8),16)
kptr(8) = kptr(8) + 16
! IF TABLE REFERENCE = 0, EXTRACT BIT MAP
IF (kptr(12) == 0) THEN
! CALCULATE NR OF BITS IN BIT MAP
ibits = (kptr(5) - 6) * 8 - kptr(11)
kptr(10) = ibits
IF (kpds(3) == 21.OR.kpds(3) == 22.OR.kpds(3) == 25 &
.OR.kpds(3) == 61.OR.kpds(3) == 62) THEN
! NORTHERN HEMISPHERE 21, 22, 25, 61, 62
DO i = 1, ibits
CALL grbgbyte
(msga,ichk,kptr(8),1)
kptr(8) = kptr(8) + 1
IF (ichk /= 0) THEN
kbms(i) = .true.
ELSE
kbms(i) = .false.
END IF
END DO
IF (kpds(3) == 25) THEN
kadd = 71
ELSE IF (kpds(3) == 61.OR.kpds(3) == 62) THEN
kadd = 90
ELSE
kadd = 36
END IF
DO i = 1, kadd
kbms(i+ibits) = .false.
END DO
kptr(10) = kptr(10) + kadd
RETURN
ELSE IF (kpds(3) == 23.OR.kpds(3) == 24.OR.kpds(3) == 26 &
.OR.kpds(3) == 63.OR.kpds(3) == 64) THEN
! SOUTHERN HEMISPHERE 23, 24, 26, 63, 64
IF (kpds(3) == 26) THEN
kadd = 72
ELSE IF (kpds(3) == 63.OR.kpds(3) == 64) THEN
kadd = 91
ELSE
kadd = 37
END IF
DO i = 1, kadd
kbms(i+ibits) = .false.
END DO
DO i = 1, ibits
CALL grbgbyte
(msga,ichk,kptr(8),1)
kptr(8) = kptr(8) + 1
IF (ichk /= 0) THEN
kbms(i) = .true.
ELSE
kbms(i) = .false.
END IF
END DO
kptr(10) = kptr(10) + kadd - 1
RETURN
ELSE IF (kpds(3) == 50) THEN
kpad = 7
kin = 22
kbits = 0
DO i = 1, 7
DO j = 1, 4
DO k = 1, kpad
kbits = kbits + 1
kbms(kbits) = .false.
END DO
DO k = 1, kin
CALL grbgbyte
(msga,ichk,kptr(8),1)
kptr(8) = kptr(8) + 1
kbits = kbits + 1
IF (ichk /= 0) THEN
kbms(kbits) = .true.
ELSE
kbms(kbits) = .false.
END IF
END DO
DO k = 1, kpad
kbits = kbits + 1
kbms(kbits) = .false.
END DO
END DO
kin = kin + 2
kpad = kpad - 1
END DO
DO ii = 1, 5
DO j = 1, kin
CALL grbgbyte
(msga,ichk,kptr(8),1)
kptr(8) = kptr(8) + 1
kbits = kbits + 1
IF (ichk /= 0) THEN
kbms(kbits) = .true.
ELSE
kbms(kbits) = .false.
END IF
END DO
END DO
ELSE
! EXTRACT BIT MAP FROM BMS FOR OTHER GRIDS
DO i = 1, ibits
CALL grbgbyte
(msga,ichk,kptr(8),1)
kptr(8) = kptr(8) + 1
IF (ichk /= 0) THEN
kbms(i) = .true.
ELSE
kbms(i) = .false.
END IF
END DO
END IF
RETURN
ELSE
PRINT *,'FI634-NO PREDEFINED BIT MAP PROVIDED BY THIS CENTER'
kret = 12
RETURN
END IF
!
END IF
kret = 0
! -------------------------------------------------------
! PROCESS NON-STANDARD GRID
! -------------------------------------------------------
IF (kpds(3) == 255) THEN
PRINT *,'NON STANDARD GRID, CENTER = ',kpds(1)
j = kgds(2) * kgds(3)
kptr(10) = j
DO i = 1, j
kbms(i) = .true.
END DO
RETURN
END IF
! -------------------------------------------------------
! CHECK INTERNATIONAL SET
! -------------------------------------------------------
IF (kpds(3) == 21.OR.kpds(3) == 22) THEN
! ----- INT'L GRIDS 21, 22 - MAP SIZE 1369
j = 1369
kptr(10) = j
CALL fi637
(*820,j,kpds,kgds,kret)
DO i = 1, 1369
kbms(i) = grd21(i)
END DO
RETURN
ELSE IF (kpds(3) == 23.OR.kpds(3) == 24) THEN
! ----- INT'L GRIDS 23, 24 - MAP SIZE 1369
j = 1369
kptr(10) = j
CALL fi637
(*820,j,kpds,kgds,kret)
DO i = 1, 1369
kbms(i) = grd23(i)
END DO
RETURN
ELSE IF (kpds(3) == 25) THEN
! ----- INT'L GRID 25 - MAP SIZE 1368
j = 1368
kptr(10) = j
CALL fi637
(*820,j,kpds,kgds,kret)
DO i = 1, 1368
kbms(i) = grd25(i)
END DO
RETURN
ELSE IF (kpds(3) == 26) THEN
! ----- INT'L GRID 26 - MAP SIZE 1368
j = 1368
kptr(10) = j
CALL fi637
(*820,j,kpds,kgds,kret)
DO i = 1, 1368
kbms(i) = grd26(i)
END DO
RETURN
ELSE IF (kpds(3) >= 37.AND.kpds(3) <= 44) THEN
! ----- INT'L GRID 37-44 - MAP SIZE 3447
j = 3447
GO TO 800
ELSE IF (kpds(1) == 7.AND.kpds(3) == 50) THEN
! ----- INT'L GRIDS 50 - MAP SIZE 964
j = 1188
kptr(10) = j
CALL fi637
(*890,j,kpds,kgds,kret)
DO i = 1, j
kbms(i) = grd50(i)
END DO
RETURN
ELSE IF (kpds(3) == 61.OR.kpds(3) == 62) THEN
! ----- INT'L GRIDS 61, 62 - MAP SIZE 4186
j = 4186
kptr(10) = j
CALL fi637
(*820,j,kpds,kgds,kret)
DO i = 1, 4186
kbms(i) = grd61(i)
END DO
RETURN
ELSE IF (kpds(3) == 63.OR.kpds(3) == 64) THEN
! ----- INT'L GRIDS 63, 64 - MAP SIZE 4186
j = 4186
kptr(10) = j
CALL fi637
(*820,j,kpds,kgds,kret)
DO i = 1, 4186
kbms(i) = grd63(i)
END DO
RETURN
END IF
! -------------------------------------------------------
! CHECK UNITED STATES SET
! -------------------------------------------------------
IF (kpds(1) == 7) THEN
IF (kpds(3) < 100) THEN
IF (kpds(3) == 1) THEN
! ----- U.S. GRID 1 - MAP SIZE 1679
j = 1679
GO TO 800
END IF
IF (kpds(3) == 2) THEN
! ----- U.S. GRID 2 - MAP SIZE 10512
j = 10512
GO TO 800
ELSE IF (kpds(3) == 3) THEN
! ----- U.S. GRID 3 - MAP SIZE 65160
j = 65160
GO TO 800
ELSE IF (kpds(3) == 5) THEN
! ----- U.S. GRID 5 - MAP SIZE 3021
j = 3021
GO TO 800
ELSE IF (kpds(3) == 6) THEN
! ----- U.S. GRID 6 - MAP SIZE 2385
j = 2385
GO TO 800
ELSE IF (kpds(3) == 27.OR.kpds(3) == 28) THEN
! ----- U.S. GRIDS 27, 28 - MAP SIZE 4225
j = 4225
GO TO 800
ELSE IF (kpds(3) == 29.OR.kpds(3) == 30) THEN
! ----- U.S. GRIDS 29,30 - MAP SIZE 5365
j = 5365
GO TO 800
ELSE IF (kpds(3) == 33.OR.kpds(3) == 34) THEN
! ----- U.S GRID 33, 34 - MAP SIZE 8326
j = 8326
GO TO 800
ELSE IF (kpds(3) >= 37.AND.kpds(3) <= 44) THEN
! ----- U.S. GRID 37-44 - MAP SIZE 3447
j = 3447
GO TO 800
ELSE IF (kpds(3) == 45) THEN
! ----- U.S. GRID 45 - MAP SIZE 41760
j = 41760
GO TO 800
ELSE IF (kpds(3) == 55.OR.kpds(3) == 56) THEN
! ----- U.S GRID 55, 56 - MAP SIZE 6177
j = 6177
GO TO 800
ELSE IF (kpds(3) >= 67.AND.kpds(3) <= 71) THEN
! ----- U.S GRID 67-71 - MAP SIZE 13689
j = 13689
GO TO 800
ELSE IF (kpds(3) == 72) THEN
! ----- U.S GRID 72 - MAP SIZE 406
j = 406
GO TO 800
ELSE IF (kpds(3) == 73) THEN
! ----- U.S GRID 73 - MAP SIZE 13056
j = 13056
GO TO 800
ELSE IF (kpds(3) == 74) THEN
! ----- U.S GRID 74 - MAP SIZE 10800
j = 10800
GO TO 800
ELSE IF (kpds(3) >= 75.AND.kpds(3) <= 77) THEN
! ----- U.S GRID 75-77 - MAP SIZE 12321
j = 12321
GO TO 800
ELSE IF (kpds(3) == 85.OR.kpds(3) == 86) THEN
! ----- U.S GRID 85,86 - MAP SIZE 32400
j = 32400
GO TO 800
ELSE IF (kpds(3) == 87) THEN
! ----- U.S GRID 87 - MAP SIZE 5022
j = 5022
GO TO 800
ELSE IF (kpds(3) == 90) THEN
! ----- U.S GRID 90 - MAP SIZE 12902
j = 12902
GO TO 800
ELSE IF (kpds(3) == 91) THEN
! ----- U.S GRID 91 - MAP SIZE 25803
j = 25803
GO TO 800
ELSE IF (kpds(3) == 92) THEN
! ----- U.S GRID 92 - MAP SIZE 24162
j = 24162
GO TO 800
ELSE IF (kpds(3) == 93) THEN
! ----- U.S GRID 93 - MAP SIZE 48323
j = 48323
GO TO 800
ELSE IF (kpds(3) == 94) THEN
! ----- U.S GRID 94 - MAP SIZE XXXXX
j = 48916
GO TO 800
ELSE IF (kpds(3) == 95) THEN
! ----- U.S GRID 95 - MAP SIZE XXXXX
j = 97831
GO TO 800
END IF
ELSE IF (kpds(3) >= 100.AND.kpds(3) < 200) THEN
IF (kpds(3) == 100) THEN
! ----- U.S. GRID 100 - MAP SIZE 6889
j = 6889
GO TO 800
ELSE IF (kpds(3) == 101) THEN
! ----- U.S. GRID 101 - MAP SIZE 10283
j = 10283
GO TO 800
ELSE IF (kpds(3) == 103) THEN
! ----- U.S. GRID 103 - MAP SIZE 3640
j = 3640
GO TO 800
ELSE IF (kpds(3) == 104) THEN
! ----- U.S. GRID 104 - MAP SIZE 16170
j = 16170
GO TO 800
ELSE IF (kpds(3) == 105) THEN
! ----- U.S. GRID 105 - MAP SIZE 6889
j = 6889
GO TO 800
ELSE IF (kpds(3) == 106) THEN
! ----- U.S. GRID 106 - MAP SIZE 19305
j = 19305
GO TO 800
ELSE IF (kpds(3) == 107) THEN
! ----- U.S. GRID 107 - MAP SIZE 11040
j = 11040
GO TO 800
ELSE IF (IAND(kpds(4),128) == 128) THEN
! ----- U.S. NON-STANDARD GRID
GO TO 895
END IF
ELSE IF (kpds(3) >= 200) THEN
IF (kpds(3) == 201) THEN
j = 4225
GO TO 800
ELSE IF (kpds(3) == 202) THEN
j = 2795
GO TO 800
ELSE IF (kpds(3) == 203.OR.kpds(3) == 205) THEN
j = 1755
GO TO 800
ELSE IF (kpds(3) == 204) THEN
j = 6324
GO TO 800
ELSE IF (kpds(3) == 206) THEN
j = 2091
GO TO 800
ELSE IF (kpds(3) == 207) THEN
j = 1715
GO TO 800
ELSE IF (kpds(3) == 208) THEN
j = 783
GO TO 800
ELSE IF (kpds(3) == 209) THEN
j = 8181
GO TO 800
ELSE IF (kpds(3) == 210) THEN
j = 625
GO TO 800
ELSE IF (kpds(3) == 211) THEN
j = 6045
GO TO 800
ELSE IF (kpds(3) == 212) THEN
j = 23865
GO TO 800
ELSE IF (kpds(3) == 213) THEN
j = 10965
GO TO 800
ELSE IF (kpds(3) == 214) THEN
j = 6693
GO TO 800
ELSE IF (IAND(kpds(4),128) == 128) THEN
GO TO 895
END IF
kret = 5
RETURN
END IF
END IF
! -------------------------------------------------------
! CHECK JAPAN METEOROLOGICAL AGENCY SET
! -------------------------------------------------------
IF (kpds(1) == 34) THEN
IF (IAND(kpds(4),128) == 128) THEN
PRINT *,'JMA MAP IS NOT PREDEFINED, THE GDS WILL'
PRINT *,'BE USED TO UNPACK THE DATA, MAP = ',kpds(3)
GO TO 900
END IF
END IF
! -------------------------------------------------------
! CHECK CANADIAN SET
! -------------------------------------------------------
IF (kpds(1) == 54) THEN
IF (IAND(kpds(4),128) == 128) THEN
PRINT *,'CANADIAN MAP IS NOT PREDEFINED, THE GDS WILL'
PRINT *,'BE USED TO UNPACK THE DATA, MAP = ',kpds(3)
GO TO 900
END IF
END IF
! -------------------------------------------------------
! CHECK FNOC SET
! -------------------------------------------------------
IF (kpds(1) == 58) THEN
IF (kpds(3) == 220.OR.kpds(3) == 221) THEN
! FNOC GRID 220, 221 - MAPSIZE 3969 (63 * 63)
j = 3969
kptr(10) = j
DO i = 1, j
kbms(i) = .true.
END DO
RETURN
END IF
IF (kpds(3) == 223) THEN
! FNOC GRID 223 - MAPSIZE 10512 (73 * 144)
j = 10512
kptr(10) = j
DO i = 1, j
kbms(i) = .true.
END DO
RETURN
END IF
IF (IAND(kpds(4),128) == 128) THEN
PRINT *,'FNOC MAP IS NOT PREDEFINED, THE GDS WILL'
PRINT *,'BE USED TO UNPACK THE DATA, MAP = ',kpds(3)
GO TO 900
END IF
END IF
! -------------------------------------------------------
! CHECK UKMET SET
! -------------------------------------------------------
IF (kpds(1) == 74) THEN
IF (IAND(kpds(4),128) == 128) THEN
GO TO 820
END IF
END IF
! -------------------------------------------------------
! CHECK ECMWF SET
! -------------------------------------------------------
IF (kpds(1) == 98) THEN
IF (kpds(3) >= 1.AND.kpds(3) <= 12) THEN
IF (kpds(3) >= 5.AND.kpds(3) <= 8) THEN
j = 1073
ELSE
j = 1369
END IF
kptr(10) = j
CALL fi637
(*810,j,kpds,kgds,kret)
DO i = 1, j
kbms(i) = .true.
END DO
RETURN
ELSE IF (kpds(3) >= 13.AND.kpds(3) <= 16) THEN
j = 361
kptr(10) = j
CALL fi637
(*810,j,kpds,kgds,kret)
DO i = 1, j
kbms(i) = .true.
END DO
RETURN
ELSE IF (IAND(kpds(4),128) == 128) THEN
GO TO 810
ELSE
kret = 5
RETURN
END IF
ELSE
PRINT *,'CENTER',kpds(1),' IS NOT DEFINED'
IF (IAND(kpds(4),128) == 128) THEN
PRINT *,'GDS WILL BE USED TO UNPACK THE DATA', &
' MAP = ',kpds(3)
GO TO 900
ELSE
kret = 10
RETURN
END IF
END IF
! =======================================
!
800 CONTINUE
kptr(10) = j
CALL fi637
(*801,j,kpds,kgds,kret)
DO i = 1, j
kbms(i) = .true.
END DO
RETURN
801 CONTINUE
!
! ----- THE MAP HAS A GDS, BYTE 7 OF THE (PDS) THE GRID IDENTIFICATION
! ----- IS NOT 255, THE SIZE OF THE GRID IS NOT THE SAME AS THE
! ----- PREDEFINED SIZES OF THE U.S. GRIDS, OR KNOWN GRIDS OF THE
! ----- OF THE OTHER CENTERS. THE GRID CAN BE UNKNOWN, OR FROM AN
! ----- UNKNOWN CENTER, WE WILL USE THE INFORMATION IN THE GDS TO MAKE
! ----- A BIT MAP.
!
810 CONTINUE
PRINT *,'ECMWF PREDEFINED MAP SIZE DOES NOT MATCH, I WILL USE'
GO TO 895
!
820 CONTINUE
PRINT *,'U.K. MET PREDEFINED MAP SIZE DOES NOT MATCH, I WILL USE'
GO TO 895
!
890 CONTINUE
PRINT *,'PREDEFINED MAP SIZE DOES NOT MATCH, I WILL USE'
895 CONTINUE
PRINT *,'THE GDS TO UNPACK THE DATA, MAP TYPE = ',kpds(3)
!
900 CONTINUE
j = kgds(2) * kgds(3)
! AFOS AFOS AFOS SPECIAL CASE
! INVOLVES NEXT SINGLE STATEMENT ONLY
IF (kpds(3) == 211) kret = 0
kptr(10) = j
DO i = 1, j
kbms(i) = .true.
END DO
! PRINT *,'EXIT FI634'
RETURN
END SUBROUTINE fi634
SUBROUTINE fi635(msga,kptr,kpds,kgds,kbms,DATA,kret) 1,37
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI635 EXTRACT GRIB DATA ELEMENTS FROM BDS
! PRGMMR: BILL CAVANAUGH ORG: W/NMC42 DATE: 91-09-13
!
! ABSTRACT: EXTRACT GRIB DATA FROM BINARY DATA SECTION AND PLACE
! INTO OUTPUT ARRAY IN PROPER POSITION.
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
! 94-04-01 CAVANAUGH MODIFIED CODE TO INCLUDE DECIMAL SCALING WHEN
! CALCULATING THE VALUE OF DATA POINTS SPECIFIED
! AS BEING EQUAL TO THE REFERENCE VALUE
! 94-11-10 FARLEY INCREASED MXSIZE FROM 72960 TO 260000
! FOR .5 DEGREE SST ANALYSIS FIELDS
!
! USAGE: CALL FI635(MSGA,KPTR,KPDS,KGDS,KBMS,DATA,KRET)
! INPUT ARGUMENT LIST:
! MSGA - ARRAY CONTAINING GRIB MESSAGE
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! (1) - TOTAL LENGTH OF GRIB MESSAGE
! (2) - LENGTH OF INDICATOR (SECTION 0)
! (3) - LENGTH OF PDS (SECTION 1)
! (4) - LENGTH OF GDS (SECTION 2)
! (5) - LENGTH OF BMS (SECTION 3)
! (6) - LENGTH OF BDS (SECTION 4)
! (7) - VALUE OF CURRENT BYTE
! (8) - BIT POINTER
! (9) - GRIB START BIT NR
! (10) - GRIB/GRID ELEMENT COUNT
! (11) - NR UNUSED BITS AT END OF SECTION 3
! (12) - BIT MAP FLAG
! (13) - NR UNUSED BITS AT END OF SECTION 2
! (14) - BDS FLAGS
! (15) - NR UNUSED BITS AT END OF SECTION 4
! KPDS - ARRAY CONTAINING PDS ELEMENTS.
! SEE INITIAL ROUTINE
! KBMS - BITMAP DESCRIBING LOCATION OF OUTPUT ELEMENTS.
!
! OUTPUT ARGUMENT LIST:
! KBDS - INFORMATION EXTRACTED FROM BINARY DATA SECTION
! KBDS(1) - N1
! KBDS(2) - N2
! KBDS(3) - P1
! KBDS(4) - P2
! KBDS(5) - BIT POINTER TO 2ND ORDER WIDTHS
! KBDS(6) - " " " " " BIT MAPS
! KBDS(7) - " " " FIRST ORDER VALUES
! KBDS(8) - " " " SECOND ORDER VALUES
! KBDS(9) - " " START OF BDS
! KBDS(10) - " " MAIN BIT MAP
! KBDS(11) - BINARY SCALING
! KBDS(12) - DECIMAL SCALING
! KBDS(13) - BIT WIDTH OF FIRST ORDER VALUES
! KBDS(14) - BIT MAP FLAG
! 0 = NO SECOND ORDER BIT MAP
! 1 = SECOND ORDER BIT MAP PRESENT
! KBDS(15) - SECOND ORDER BIT WIDTH
! KBDS(16) - CONSTANT / DIFFERENT WIDTHS
! 0 = CONSTANT WIDTHS
! 1 = DIFFERENT WIDTHS
! KBDS(17) - SINGLE DATUM / MATRIX
! 0 = SINGLE DATUM AT EACH GRID POINT
! 1 = MATRIX OF VALUES AT EACH GRID POINT
! (18-20)- UNUSED
!
! DATA - REAL*4 ARRAY OF GRIDDED ELEMENTS IN GRIB MESSAGE.
! KPTR - ARRAY CONTAINING STORAGE FOR FOLLOWING PARAMETERS
! SEE INPUT LIST
! KRET - ERROR RETURN
!
! REMARKS:
! ERROR RETURN
! 3 = UNPACKED FIELD IS LARGER THAN 65160
! 6 = DOES NOT MATCH NR OF ENTRIES FOR THIS GRIB/GRID
! 7 = NUMBER OF BITS IN FILL TOO LARGE
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS9000
!
!$$$
! *************************************************************
! ON A PC THIS CAN BE CHANGED TO A SMALLER SIZE TO BETTER FIT
! THE DOS MEMORY LIMIT OF 640K BYTES. YOU COULD DO THIS
! FOR MICROSOFT 5.0. A PC 32 BIT FORTRAN COMPILER
! WOULD NOT NEED THIS CHANGE. IF NONE OF YOUR GRIB RECORDS
! IS LARGER THAN 20000, SET MXSIZE TO 20000.
! *************************************************************
PARAMETER (mxsize=260000)
CHARACTER :: msga(*)
CHARACTER (LEN=1) :: kk(8)
CHARACTER (LEN=1) :: ckref(8)
!
LOGICAL*1 kbms(*)
!
INTEGER :: kpds(*)
INTEGER :: kgds(*)
INTEGER :: kbds(20)
INTEGER :: kptr(*)
INTEGER :: nrbits
INTEGER :: kref
INTEGER :: kkk
INTEGER :: ksave(mxsize)
INTEGER :: kscale
!
REAL :: DATA(*)
REAL :: refnce
REAL :: scale
REAL :: realkk
!
EQUIVALENCE (ckref(1),kref,refnce)
EQUIVALENCE (kk(1),kkk,realkk)
!
!
! CHANGED HEX VALUES TO DECIMAL TO MAKE CODE MORE PORTABLE
!
! *************************************************************
SAVE
! PRINT *,'ENTER FI635'
! SET UP BIT POINTER
kptr(8) = kptr(9) + (kptr(2)*8) + (kptr(3)*8) + (kptr(4)*8) &
+ (kptr(5)*8) + 24
! ------------- EXTRACT FLAGS
! BYTE 4
CALL grbgbyte
(msga,kptr(14),kptr(8),4)
kptr(8) = kptr(8) + 4
! --------- NR OF UNUSED BITS IN SECTION 4
CALL grbgbyte
(msga,kptr(15),kptr(8),4)
kptr(8) = kptr(8) + 4
kend = kptr(9) + (kptr(2)*8) + (kptr(3)*8) + (kptr(4)*8) &
+ (kptr(5)*8) + kptr(6) * 8 - kptr(15)
! ------------- GET SCALE FACTOR
! BYTES 5,6
! CHECK SIGN
CALL grbgbyte
(msga,ksign,kptr(8),1)
kptr(8) = kptr(8) + 1
! GET ABSOLUTE SCALE VALUE
CALL grbgbyte
(msga,kscale,kptr(8),15)
kptr(8) = kptr(8) + 15
IF (ksign > 0) THEN
kscale = - kscale
END IF
scale = 2.0**kscale
! ------------ GET REFERENCE VALUE
! BYTES 7,10
CALL grbgbyte
(msga,kref,kptr(8),32)
kptr(8) = kptr(8) + 32
!
! THE NEXT CODE WILL CONVERT THE IBM370 FLOATING POINT
! TO THE FLOATING POINT USED ON YOUR COMPUTER.
!
! 1ST TEST TO SEE IN ON 32 OR 64 BIT WORD MACHINE
! LW = 4 OR 8; IF 8 MAY BE A CRAY
!
CALL w3fi01
(lw)
IF (lw == 4) THEN
CALL grbgbyte
(ckref,jsgn,0,1)
CALL grbgbyte
(ckref,jexp,1,7)
CALL grbgbyte
(ckref,ifr,8,24)
ELSE
CALL grbgbyte
(ckref,jsgn,32,1)
CALL grbgbyte
(ckref,jexp,33,7)
CALL grbgbyte
(ckref,ifr,40,24)
END IF
! PRINT *,109,JSGN,JEXP,IFR
! 109 FORMAT (' JSGN,JEXP,IFR = ',3(1X,Z8))
IF (ifr == 0) THEN
refnce = 0.0
ELSE IF (jexp == 0.AND.ifr == 0) THEN
refnce = 0.0
ELSE
refnce = FLOAT(ifr) * 16.0 ** (jexp - 64 - 6)
IF (jsgn /= 0) refnce = - refnce
END IF
! PRINT *,'SCALE ',SCALE,' REF VAL ',KREF,REFNCE
! ------------- NUMBER OF BITS SPECIFIED FOR EACH ENTRY
! BYTE 11
CALL grbgbyte
(msga,kbits,kptr(8),8)
kptr(8) = kptr(8) + 8
kbds(4) = kbits
! KBDS(13) = KBITS
ibyt12 = kptr(8)
! ------------------ IF THERE ARE NO EXTENDED FLAGS PRESENT
! THIS IS WHERE DATA BEGINS AND AND THE PROCESSING
! INCLUDED IN THE FOLLOWING IF...END IF
! WILL BE SKIPPED
! PRINT *,'BASIC FLAGS =',KPTR(14) ,IAND(KPTR(14),1)
IF (IAND(kptr(14),1) == 0) THEN
! PRINT *,'NO EXTENDED FLAGS'
ELSE
! BYTES 12,13
CALL grbgbyte
(msga,koctet,kptr(8),16)
kptr(8) = kptr(8) + 16
! --------------------------- EXTENDED FLAGS
! BYTE 14
CALL grbgbyte
(msga,kxflag,kptr(8),8)
! PRINT *,'HAVE EXTENDED FLAGS',KXFLAG
kptr(8) = kptr(8) + 8
IF (IAND(kxflag,16) == 0) THEN
! SECOND ORDER VALUES CONSTANT WIDTHS
kbds(16) = 0
ELSE
! SECOND ORDER VALUES DIFFERENT WIDTHS
kbds(16) = 1
END IF
IF (IAND (kxflag,32) == 0) THEN
! NO SECONDARY BIT MAP
kbds(14) = 0
ELSE
! HAVE SECONDARY BIT MAP
kbds(14) = 1
END IF
IF (IAND (kxflag,64) == 0) THEN
! SINGLE DATUM AT GRID POINT
kbds(17) = 0
ELSE
! MATRIX OF VALUES AT GRID POINT
kbds(17) = 1
END IF
! ---------------------- NR - FIRST DIMENSION (ROWS) OF EACH MATRIX
! BYTES 15,16
CALL grbgbyte
(msga,nr,kptr(8),16)
kptr(8) = kptr(8) + 16
! ---------------------- NC - SECOND DIMENSION (COLS) OF EACH MATRIX
! BYTES 17,18
CALL grbgbyte
(msga,nc,kptr(8),16)
kptr(8) = kptr(8) + 16
! ---------------------- NRV - FIRST DIM COORD VALS
! BYTE 19
CALL grbgbyte
(msga,nrv,kptr(8),8)
kptr(8) = kptr(8) + 8
! ---------------------- NC1 - NR COEFF'S OR VALUES
! BYTE 20
CALL grbgbyte
(msga,nc1,kptr(8),8)
kptr(8) = kptr(8) + 8
! ---------------------- NCV - SECOND DIM COORD OR VALUE
! BYTE 21
CALL grbgbyte
(msga,ncv,kptr(8),8)
kptr(8) = kptr(8) + 8
! ---------------------- NC2 - NR COEFF'S OR VALS
! BYTE 22
CALL grbgbyte
(msga,nc2,kptr(8),8)
kptr(8) = kptr(8) + 8
! ---------------------- KPHYS1 - FIRST DIM PHYSICAL SIGNIF
! BYTE 23
CALL grbgbyte
(msga,kphys1,kptr(8),8)
kptr(8) = kptr(8) + 8
! ---------------------- KPHYS2 - SECOND DIM PHYSICAL SIGNIF
! BYTE 24
CALL grbgbyte
(msga,kphys2,kptr(8),8)
kptr(8) = kptr(8) + 8
! BYTES 25-N
END IF
IF (kbits == 0) THEN
! HAVE NO BDS ENTRIES, ALL ENTRIES = REFNCE
scal10 = 10.0 ** kpds(22)
scal10 = 1.0 / scal10
refn10 = refnce * scal10
kentry = kptr(10)
DO i = 1, kentry
DATA(i) = 0.0
IF (kbms(i)) THEN
DATA(i) = refn10
END IF
END DO
GO TO 900
END IF
! PRINT *,'KEND ',KEND,' KPTR(8) ',KPTR(8),'KBITS ',KBITS
knr = (kend - kptr(8)) / kbits
! PRINT *,'NUMBER OF ENTRIES IN DATA ARRAY',KNR
! --------------------
! CYCLE THRU BDS UNTIL HAVE USED ALL (SPECIFIED NUMBER)
! ENTRIES.
! ------------- UNUSED BITS IN DATA AREA
! NUMBER OF BYTES IN DATA AREA
nrbyte = kptr(6) - 11
! ------------- TOTAL NR OF USABLE BITS
nrbits = nrbyte * 8 - kptr(15)
! ------------- TOTAL NR OF ENTRIES
kentry = nrbits / kbits
! MAX SIZE CHECK
IF (kentry > mxsize) THEN
kret = 3
RETURN
END IF
!
! IF (IAND(KPTR(14),2).EQ.0) THEN
! PRINT *,'SOURCE VALUES IN FLOATING POINT'
! ELSE
! PRINT *,'SOURCE VALUES IN INTEGER'
! END IF
!
IF (IAND(kptr(14),8) == 0) THEN
! PRINT *,'PROCESSING GRID POINT DATA'
IF (IAND(kptr(14),4) == 0) THEN
! PRINT *,' WITH SIMPLE PACKING'
IF (IAND(kptr(14),1) == 0) THEN
! PRINT *,' WITH NO ADDITIONAL FLAGS'
GO TO 4000
ELSE IF (IAND(kptr(14),1) /= 0) THEN
PRINT *,' WITH ADDITIONAL FLAGS',kxflag
IF (kbds(17) == 0) THEN
PRINT *,' SINGLE DATUM EACH GRID PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
ELSE IF (kbds(17) /= 0) THEN
PRINT *,' MATRIX OF VALS EACH PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
END IF
END IF
ELSE IF (IAND(kptr(14),4) /= 0) THEN
PRINT *,' WITH COMPLEX/SECOND ORDER PACKING'
IF (IAND(kptr(14),1) == 0) THEN
PRINT *,' WITH NO ADDITIONAL FLAGS'
ELSE IF (IAND(kptr(14),1) /= 0) THEN
PRINT *,' WITH ADDITIONAL FLAGS'
IF (kbds(17) == 0) THEN
PRINT *,' SINGLE DATUM AT EACH PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
! ROW BY ROW - COL BY COL
CALL fi636
(DATA,msga,kbms, &
refnce,kptr,kpds,kgds)
GO TO 900
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
CALL fi636
(DATA,msga,kbms, &
refnce,kptr,kpds,kgds)
GO TO 900
END IF
ELSE IF (kbds(17) /= 0) THEN
PRINT *,' MATRIX OF VALS EACH PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
END IF
END IF
END IF
ELSE IF (IAND(kptr(14),8) /= 0) THEN
PRINT *,'PROCESSING SPHERICAL HARMONIC COEFFICIENTS'
IF (IAND(kptr(14),4) == 0) THEN
PRINT *,' WITH SIMPLE PACKING'
IF (IAND(kptr(14),1) == 0) THEN
PRINT *,' WITH NO ADDITIONAL FLAGS'
GO TO 5000
ELSE IF (IAND(kptr(14),1) /= 0) THEN
PRINT *,' WITH ADDITIONAL FLAGS'
IF (kbds(17) == 0) THEN
PRINT *,' SINGLE DATUM EACH GRID PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
ELSE IF (kbds(17) /= 0) THEN
PRINT *,' MATRIX OF VALS EACH PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
END IF
END IF
ELSE IF (IAND(kptr(14),4) /= 0) THEN
! COMPLEX/SECOND ORDER PACKING
PRINT *,' WITH COMPLEX/SECOND ORDER PACKING'
IF (IAND(kptr(14),1) == 0) THEN
PRINT *,' WITH NO ADDITIONAL FLAGS'
ELSE IF (IAND(kptr(14),1) /= 0) THEN
PRINT *,' WITH ADDITIONAL FLAGS'
IF (kbds(17) == 0) THEN
PRINT *,' SINGLE DATUM EACH GRID PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
ELSE IF (kbds(17) /= 0) THEN
PRINT *,' MATRIX OF VALS EACH PT'
IF (kbds(14) == 0) THEN
PRINT *,' NO SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
ELSE IF (kbds(14) /= 0) THEN
PRINT *,' SEC BIT MAP'
IF (kbds(16) == 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES CONSTANT WIDTH'
ELSE IF (kbds(16) /= 0) THEN
PRINT *,' SECOND ORDER', &
' VALUES DIFFERENT WIDTHS'
END IF
END IF
END IF
END IF
END IF
END IF
PRINT *,' NOT PROCESSED - NOT PROCESSED - NOT PROCESSED'
kret = 11
RETURN
4000 CONTINUE
! ****************************************************************
!
! GRID POINT DATA, SIMPLE PACKING, FLOATING POINT, NO ADDN'L FLAGS
!
scal10 = 10.0 ** kpds(22)
scal10 = 1.0 / scal10
IF (kpds(3) == 23.OR.kpds(3) == 24.OR.kpds(3) == 26 &
.OR.kpds(3) == 63.OR.kpds(3) == 64) THEN
IF (kpds(3) == 26) THEN
kadd = 72
ELSE IF (kpds(3) == 63.OR.kpds(3) == 64) THEN
kadd = 91
ELSE
kadd = 37
END IF
CALL grbgbytes
(msga,ksave,kptr(8),kbits,0,knr)
kptr(8) = kptr(8) + kbits * knr
ii = 1
kentry = kptr(10)
DO i = 1, kentry
IF (kbms(i)) THEN
DATA(i) = (refnce+FLOAT(ksave(ii))*scale)*scal10
ii = ii + 1
ELSE
DATA(i) = 0.0
END IF
END DO
DO i = 2, kadd
DATA(i) = DATA(1)
END DO
ELSE IF (kpds(3) == 21.OR.kpds(3) == 22.OR.kpds(3) == 25 &
.OR.kpds(3) == 61.OR.kpds(3) == 62) THEN
CALL grbgbytes
(msga,ksave,kptr(8),kbits,0,knr)
ii = 1
kentry = kptr(10)
DO i = 1, kentry
IF (kbms(i)) THEN
DATA(i) = (refnce + FLOAT(ksave(ii)) * scale) * scal10
ii = ii + 1
ELSE
DATA(i) = 0.0
END IF
END DO
IF (kpds(3) == 25) THEN
kadd = 71
ELSE IF (kpds(3) == 61.OR.kpds(3) == 62) THEN
kadd = 90
ELSE
kadd = 36
END IF
lastp = kentry - kadd
DO i = lastp+1, kentry
DATA(i) = DATA(lastp)
END DO
ELSE
CALL grbgbytes
(msga,ksave,kptr(8),kbits,0,knr)
ii = 1
kentry = kptr(10)
DO i = 1, kentry
IF (kbms(i)) THEN
DATA(i) = (refnce + FLOAT(ksave(ii)) * scale) * scal10
ii = ii + 1
ELSE
DATA(i) = 0.0
END IF
END DO
END IF
GO TO 900
! ------------- PROCESS SPHERICAL HARMONIC COEFFICIENTS,
! SIMPLE PACKING, FLOATING POINT, NO ADDN'L FLAGS
5000 CONTINUE
! PRINT *,'CHECK POINT SPECTRAL COEFF'
kptr(8) = ibyt12
CALL grbgbyte
(msga,kkk,kptr(8),32)
kptr(8) = kptr(8) + 32
!
! THE NEXT CODE WILL CONVERT THE IBM370 FOATING POINT
! TO THE FLOATING POINT USED ON YOUR MACHINE.
!
! 1ST TEST TO SEE IN ON 32 OR 64 BIT WORD MACHINE
! LW = 4 OR 8; IF 8 MAY BE A CRAY
!
CALL w3fi01
(lw)
IF (lw == 4) THEN
CALL grbgbyte
(kk,jsgn,0,1)
CALL grbgbyte
(kk,jexp,1,7)
CALL grbgbyte
(kk,ifr,8,24)
ELSE
CALL grbgbyte
(kk,jsgn,32,1)
CALL grbgbyte
(kk,jexp,33,7)
CALL grbgbyte
(kk,ifr,40,24)
END IF
!
IF (ifr == 0) THEN
realkk = 0.0
ELSE IF (jexp == 0.AND.ifr == 0) THEN
realkk = 0.0
ELSE
realkk = FLOAT(ifr) * 16.0 ** (jexp - 64 - 6)
IF (jsgn /= 0) realkk = -realkk
END IF
DATA(1) = realkk
CALL grbgbytes
(msga,ksave,kptr(8),kbits,0,knr)
! --------------
DO i = 1, kentry
DATA(i+1) = refnce + FLOAT(ksave(i)) * scale
END DO
900 CONTINUE
! PRINT *,'EXIT FI635'
RETURN
END SUBROUTINE fi635
SUBROUTINE fi636 (DATA,msga,kbms,refnce,kptr,kpds,kgds) 2,17
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI636 PROCESS SECOND ORDER PACKING
! PRGMMR: CAVANAUGH ORG: W/NMC42 DATE: 92-09-22
!
! ABSTRACT: PROCESS SECOND ORDER PACKING FROM THE BINARY DATA SECTION
! (BDS) FOR SINGLE DATA ITEMS GRID POINT DATA
!
! PROGRAM HISTORY LOG:
! 93-06-08 CAVANAUGH
! 93-12-15 CAVANAUGH MODIFIED SECOND ORDER POINTERS TO FIRST ORDER
! VALUES AND SECOND ORDER VALUES CORRECTLY.
!
! USAGE: CALL FI636 (DATA,MSGA,KBMS,REFNCE,KPTR,KPDS,KGDS)
! INPUT ARGUMENT LIST:
!
! MSGA - ARRAY CONTAINING GRIB MESSAGE
! REFNCE - REFERENCE VALUE
! KPTR - WORK ARRAY
!
! OUTPUT ARGUMENT LIST: (INCLUDING WORK ARRAYS)
! DATA - LOCATION OF OUTPUT ARRAY
! WORKING ARRAY
! KBDS(1) - N1
! KBDS(2) - N2
! KBDS(3) - P1
! KBDS(4) - P2
! KBDS(5) - BIT POINTER TO 2ND ORDER WIDTHS
! KBDS(6) - " " " " " BIT MAPS
! KBDS(7) - " " " FIRST ORDER VALUES
! KBDS(8) - " " " SECOND ORDER VALUES
! KBDS(9) - " " START OF BDS
! KBDS(10) - " " MAIN BIT MAP
! KBDS(11) - BINARY SCALING
! KBDS(12) - DECIMAL SCALING
! KBDS(13) - BIT WIDTH OF FIRST ORDER VALUES
! KBDS(14) - BIT MAP FLAG
! 0 = NO SECOND ORDER BIT MAP
! 1 = SECOND ORDER BIT MAP PRESENT
! KBDS(15) - SECOND ORDER BIT WIDTH
! KBDS(16) - CONSTANT / DIFFERENT WIDTHS
! 0 = CONSTANT WIDTHS
! 1 = DIFFERENT WIDTHS
! KBDS(17) - SINGLE DATUM / MATRIX
! 0 = SINGLE DATUM AT EACH GRID POINT
! 1 = MATRIX OF VALUES AT EACH GRID POINT
! (18-20)- UNUSED
!
! REMARKS:
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS, CYBER
!
!$$$
REAL :: DATA(*)
REAL :: refn
REAL :: refnce
!
INTEGER :: kbds(20)
INTEGER :: kptr(*)
INTEGER :: jref,bmap2(12500)
INTEGER :: i,ibds
INTEGER :: kbit,ifoval,isoval
INTEGER :: kpds(*),kgds(*)
!
LOGICAL*1 kbms(*)
!
CHARACTER :: msga(*)
!
EQUIVALENCE (jref,refn)
! ******************* SETUP ******************************
SAVE
! PRINT *,'ENTER FI636'
ij = 0
! ========================================================
IF (kbds(14) == 0) THEN
! NO BIT MAP, MUST CONSTRUCT ONE
IF (kgds(2) == 65535) THEN
IF (kgds(20) == 255) THEN
PRINT *,'CANNOT BE USED HERE'
ELSE
! POINT TO PL
lp = kptr(9) + kptr(2)*8 + kptr(3)*8 + kgds(20)*8 - 8
jt = 0
DO jz = 1, kgds(3)
! GET NUMBER IN CURRENT ROW
CALL grbgbyte
(msga,NUMBER,lp,16)
! INCREMENT TO NEXT ROW NUMBER
lp = lp + 16
! PRINT *,'NUMBER IN ROW',JZ,' = ',NUMBER
DO jq = 1, NUMBER
jt = jt + 1
IF (jq == 1) THEN
bmap2(jt) = 1
ELSE
bmap2(jt) = 0
END IF
END DO
END DO
END IF
ELSE
IF (IAND(kgds(11),32) == 0) THEN
! ROW BY ROW
! PRINT *,' ROW BY ROW'
kout = kgds(3)
kin = kgds(2)
ELSE
! COL BY COL
! PRINT *,' COL BY COL'
kin = kgds(3)
kout = kgds(2)
END IF
! PRINT *,'KIN=',KIN,' KOUT= ',KOUT
DO i = 1, kout
DO j = 1, kin
IF (j == 1) THEN
CALL grbsbyte
(bmap2,1,ij,1)
ELSE
CALL grbsbyte
(bmap2,0,ij,1)
END IF
ij = ij + 1
END DO
END DO
END IF
END IF
! ========================================================
! CALL BINARY (BMAP2,2)
! START OF BMS (BIT POINTER)
! KBDS(10) = 0
! BYTE START OF BDS
ibds = kptr(2) + kptr(3) + kptr(4) + kptr(5)
! PRINT *,'KPTR(2-5) ',KPTR(2),KPTR(3),KPTR(4),KPTR(5)
! BIT START OF BDS
jptr = ibds * 8
! PRINT *,'JPTR ',JPTR
kbds(9) = jptr
! PRINT *,'START OF BDS ',KBDS(9)
! BINARY SCALE VALUE BDS BYTES 5-6
CALL grbgbyte
(msga,ISIGN,jptr+32,1)
CALL grbgbyte
(msga,kbds(11),jptr+33,15)
IF (ISIGN > 0) THEN
kbds(11) = - kbds(11)
END IF
! PRINT *,'BINARY SCALE VALUE =',KBDS(11)
! EXTRACT REFERENCE VALUE
CALL grbgbyte
(msga,jref,jptr+48,32)
! PRINT *,'DECODED REFERENCE VALUE =',REFN,REFNCE
! F O BIT WIDTH
CALL grbgbyte
(msga,kbds(13),jptr+80,8)
jptr = jptr + 88
! AT START OF BDS BYTE 12
! EXTRACT N1
CALL grbgbyte
(msga,kbds(1),jptr,16)
! PRINT *,'N1 = ',KBDS(1)
jptr = jptr + 16
! EXTENDED FLAGS
CALL grbgbyte
(msga,kflag,jptr,8)
! ISOLATE BIT MAP FLAG
kbds(14) = IAND(kflag,32)
jptr = jptr + 8
! EXTRACT N2
CALL grbgbyte
(msga,kbds(2),jptr,16)
! PRINT *,'N2 = ',KBDS(2)
jptr = jptr + 16
! EXTRACT P1
CALL grbgbyte
(msga,kbds(3),jptr,16)
! PRINT *,'P1 = ',KBDS(3)
jptr = jptr + 16
! EXTRACT P2
CALL grbgbyte
(msga,kbds(4),jptr,16)
! PRINT *,'P2 = ',KBDS(4)
jptr = jptr + 16
! SKIP RESERVED BYTE
jptr = jptr + 8
! START OF SECOND ORDER BIT WIDTHS
kbds(5) = jptr
! COMPUTE START OF SECONDARY BIT MAP
IF (kbds(14) /= 0) THEN
! FOR INCLUDED SECONDARY BIT MAP
jptr = jptr + (kbds(3) * 8)
kbds(6) = jptr
ELSE
! FOR CONSTRUCTED SECONDARY BIT MAP
kbds(6) = 0
END IF
! CREATE POINTER TO START OF FIRST ORDER VALUES
kbds(7) = kbds(9) + kbds(1) * 8 - 8
PRINT *,'BIT POINTER TO START OF FOVALS',kbds(7)
! CREATE POINTER TO START OF SECOND ORDER VALUES
! KBDS(8) = KBDS(9) + KBDS(2) * 8 - 8
! PRINT *,'BIT POINTER TO START OF SOVALS',KBDS(8)
! PRINT *,'KBDS( 1) - N1 ',KBDS( 1)
! PRINT *,'KBDS( 2) - N2 ',KBDS( 2)
! PRINT *,'KBDS( 3) - P1 ',KBDS( 3)
! PRINT *,'KBDS( 4) - P2 ',KBDS( 4)
! PRINT *,'KBDS( 5) - BIT PTR - 2ND ORDER WIDTHS ',KBDS( 5)
! PRINT *,'KBDS( 6) - " " " " BIT MAPS ',KBDS( 6)
! PRINT *,'KBDS( 7) - " " F O VALS ',KBDS( 7)
! PRINT *,'KBDS( 8) - " " S O VALS ',KBDS( 8)
! PRINT *,'KBDS( 9) - " " START OF BDS ',KBDS( 9)
! PRINT *,'KBDS(10) - " " MAIN BIT MAP ',KBDS(10)
! PRINT *,'KBDS(11) - BINARY SCALING ',KBDS(11)
! PRINT *,'KPDS(22) - DECIMAL SCALING ',KPDS(22)
! PRINT *,'KBDS(13) - FO BIT WIDTH ',KBDS(13)
! PRINT *,'KBDS(14) - 2ND ORDER BIT MAP FLAG ',KBDS(14)
! PRINT *,'KBDS(15) - 2ND ORDER BIT WIDTH ',KBDS(15)
! PRINT *,'KBDS(16) - CONSTANT/DIFFERENT WIDTHS ',KBDS(16)
! PRINT *,'KBDS(17) - SINGLE DATUM/MATRIX ',KBDS(17)
! PRINT *,'REFNCE VAL ',REFNCE
! ************************* PROCESS DATA **********************
! FOR EACH GRID POINT ENTRY
!
scale2 = 2.0**kbds(11)
scal10 = 10.0**kpds(22)
! PRINT *,'SCALE VALUES - ',SCALE2,SCAL10
DO i = 1, kptr(10)
! GET NEXT MASTER BIT MAP BIT POSITION
! IF NEXT MASTER BIT MAP BIT POSITION IS 'ON' (1)
IF (kbms(i)) THEN
! WRITE(6,900)I,KBMS(I)
! 900 FORMAT (1X,I4,3X,14HMAIN BIT IS ON,3X,L4)
IF (kbds(14) /= 0) THEN
CALL grbgbyte
(msga,kbit,kbds(6),1)
ELSE
CALL grbgbyte
(bmap2,kbit,kbds(6),1)
END IF
! PRINT *,'KBDS(6) =',KBDS(6),' KBIT =',KBIT
kbds(6) = kbds(6) + 1
IF (kbit /= 0) THEN
! PRINT *,' SOB ON'
! GET NEXT FIRST ORDER PACKED VALUE
CALL grbgbyte
(msga,ifoval,kbds(7),kbds(13))
kbds(7) = kbds(7) + kbds(13)
! PRINT *,'FOVAL =',IFOVAL
! GET SECOND ORDER BIT WIDTH
CALL grbgbyte
(msga,kbds(15),kbds(5),8)
kbds(5) = kbds(5) + 8
! PRINT *,KBDS(7)-KBDS(13),' FOVAL =',IFOVAL,' KBDS(5)=',
! * ,KBDS(5), 'ISOWID =',KBDS(15)
ELSE
! PRINT *,' SOB NOT ON'
END IF
isoval = 0
IF (kbds(15) == 0) THEN
! IF SECOND ORDER BIT WIDTH = 0
! THEN SECOND ORDER VALUE IS 0
! SO CALCULATE DATA VALUE FOR THIS POINT
! DATA(I) = (REFNCE + (FLOAT(IFOVAL) * SCALE2)) / SCAL10
ELSE
CALL grbgbyte
(msga,isoval,kbds(8),kbds(15))
kbds(8) = kbds(8) + kbds(15)
END IF
DATA(i) = (refnce + (FLOAT(ifoval + isoval) * &
scale2)) / scal10
! PRINT *,I,DATA(I),REFNCE,IFOVAL,ISOVAL,SCALE2,SCAL10
ELSE
! WRITE(6,901) I,KBMS(I)
! 901 FORMAT (1X,I4,3X,15HMAIN BIT NOT ON,3X,L4)
DATA(i) = 0.0
END IF
! PRINT *,I,DATA(I),IFOVAL,ISOVAL,KBDS(5),KBDS(15)
END DO
! **************************************************************
! PRINT *,'EXIT FI636'
RETURN
END SUBROUTINE fi636
SUBROUTINE fi637(*,j,kpds,kgds,kret) 10
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: FI637 GRIB GRID/SIZE TEST
! PRGMMR: CAVANAUGH ORG: W/NMC42 DATE: 91-09-13
!
! ABSTRACT: TO TEST WHEN GDS IS AVAILABLE TO SEE IF SIZE MISMATCH
! ON EXISTING GRIDS (BY CENTER) IS INDICATED
!
! PROGRAM HISTORY LOG:
! 91-09-13 CAVANAUGH
!
! USAGE: CALL FI637(*,J,KPDS,KGDS,KRET)
! INPUT ARGUMENT LIST:
! J - SIZE FOR INDICATED GRID
! KPDS -
! KGDS -
!
! OUTPUT ARGUMENT LIST: (INCLUDING WORK ARRAYS)
! KRET - ERROR RETURN
!
! REMARKS:
! KRET -
! = 9 - GDS INDICATES SIZE MISMATCH WITH STD GRID
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS
!
!$$$
INTEGER :: kpds(*)
INTEGER :: kgds(*)
INTEGER :: j
INTEGER :: i
! ---------------------------------------
SAVE
! ---------------------------------------
! IF GDS NOT INDICATED, RETURN
! ----------------------------------------
IF (IAND(kpds(4),128) == 0) RETURN
! ---------------------------------------
! GDS IS INDICATED, PROCEED WITH TESTING
! ---------------------------------------
IF (kgds(2) == 65535) THEN
RETURN
END IF
i = kgds(2) * kgds(3)
! ---------------------------------------
! INTERNATIONAL SET
! ---------------------------------------
IF (kpds(3) >= 21.AND.kpds(3) <= 26) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 37.AND.kpds(3) <= 44) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) == 50) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 61.AND.kpds(3) <= 64) THEN
IF (i /= j) THEN
RETURN 1
END IF
! ---------------------------------------
! TEST ECMWF CONTENT
! ---------------------------------------
ELSE IF (kpds(1) == 98) THEN
kret = 9
IF (kpds(3) >= 1.AND.kpds(3) <= 16) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE
kret = 5
RETURN 1
END IF
! ---------------------------------------
! U.K. MET OFFICE, BRACKNELL
! ---------------------------------------
ELSE IF (kpds(1) == 74) THEN
kret = 9
IF (kpds(3) >= 25.AND.kpds(3) <= 26) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE
kret = 5
RETURN 1
END IF
! ---------------------------------------
! CANADA
! ---------------------------------------
ELSE IF (kpds(1) == 54) THEN
PRINT *,' NO CURRENT LISTING OF CANADIAN GRIDS'
RETURN 1
! ---------------------------------------
! JAPAN METEOROLOGICAL AGENCY
! ---------------------------------------
ELSE IF (kpds(1) == 34) THEN
PRINT *,' NO CURRENT LISTING OF JMA GRIDS'
RETURN 1
! ---------------------------------------
! NAVY - FNOC
! ---------------------------------------
ELSE IF (kpds(1) == 58) THEN
IF (kpds(3) >= 220.AND.kpds(3) <= 221) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) == 223) THEN
IF (i /= j) THEN
RETURN 1
END IF
END IF
! ---------------------------------------
! U.S. GRIDS
! ---------------------------------------
ELSE IF (kpds(1) == 7) THEN
kret = 9
IF (kpds(3) >= 1.AND.kpds(3) <= 3) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) == 5.OR.kpds(3) == 6) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 27.AND.kpds(3) <= 30) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 33.AND.kpds(3) <= 34) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 37.AND.kpds(3) <= 45) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 55.AND.kpds(3) <= 56) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 67.AND.kpds(3) <= 77) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 85.AND.kpds(3) <= 86) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) == 87) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 90.AND.kpds(3) <= 95) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) == 100.OR.kpds(3) == 101) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 103.AND.kpds(3) <= 107) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE IF (kpds(3) >= 201.AND.kpds(3) <= 214) THEN
IF (i /= j) THEN
RETURN 1
END IF
ELSE
kret = 5
RETURN 1
END IF
ELSE
kret = 10
RETURN 1
END IF
! ------------------------------------
! NORMAL EXIT
! ------------------------------------
kret = 0
RETURN
END SUBROUTINE fi637
SUBROUTINE w3fi83 (DATA,npts,fval1,fdiff1,iscal2, & 1
isc10,kpds,kgds)
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: W3FI83 RESTORE DELTA PACKED DATA TO ORIGINAL
! PRGMMR: CAVANAUGH ORG: NMC421 DATE:94-03-09
!
! ABSTRACT: RESTORE DELTA PACKED DATA TO ORIGINAL VALUES
! RESTORE FROM BOUSTREPHEDONIC ALIGNMENT
!
! PROGRAM HISTORY LOG:
! 93-07-14 CAVANAUGH
! 93-07-22 STACKPOLE ADDITIONS TO FIX SCALING
! 94-01-27 CAVANAUGH ADDED REVERSAL OF EVEN NUMBERED ROWS
! (BOUSTROPHEDONIC PROCESSING) TO RESTORE
! DATA TO ORIGINAL SEQUENCE.
! 94-03-02 CAVANAUGH CORRECTED REVERSAL OF EVEN NUMBERED ROWS
!
! USAGE: CALL W3FI83(DATA,NPTS,FVAL1,FDIFF1,ISCAL2,
! * ISC10,KPDS,KGDS)
! INPUT ARGUMENT LIST:
! DATA - SECOND ORDER DIFFERENCES
! NPTS - NUMBER OF POINTS IN ARRAY
! FVAL1 - ORIGINAL FIRST ENTRY IN ARRAY
! FDIFF1 - ORIGINAL FIRST FIRST-DIFFERENCE
! ISCAL2 - POWER-OF-TWO EXPONENT FOR UNSCALING
! ISC10 - POWER-OF-TEN EXPONENT FOR UNSCALING
! KPDS - ARRAY OF INFORMATION FOR PDS
! KGDS - ARRAY OF INFORMATION FOR GDS
!
! OUTPUT ARGUMENT LIST:
! DATA - EXPANDED ORIGINAL DATA VALUES
!
! REMARKS:
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 77
! MACHINE: NAS
!
!$$$
REAL :: fval1,fdiff1
REAL :: DATA(*),boust(200)
INTEGER :: npts,nrow,ncol,kpds(*),kgds(*),isc10
! ---------------------------------------
SAVE
!
! REMOVE DECIMAL UN-SCALING INTRODUCED DURING UNPACKING
!
dscal = 10.0 ** isc10
IF (dscal == 0.0) THEN
DO i=1,npts
DATA(i) = 1.0
END DO
ELSE IF (dscal == 1.0) THEN
ELSE
DO i=1,npts
DATA(i) = DATA(i) * dscal
END DO
END IF
!
DATA(1) = fval1
DATA(2) = fdiff1
DO j = 3,2,-1
DO k = j, npts
DATA(k) = DATA(k) + DATA(k-1)
END DO
END DO
!
! NOW REMOVE THE BINARY SCALING FROM THE RECONSTRUCTED FIELD
! AND THE DECIMAL SCALING TOO
!
IF (dscal == 0) THEN
scale = 0.0
ELSE
scale =(2.0**iscal2)/dscal
END IF
DO i=1,npts
DATA(i) = DATA(i) * scale
END DO
! ==========================================================
IF (IAND(kpds(4),128) /= 0) THEN
nrow = kgds(3)
ncol = kgds(2)
!
! DATA LAID OUT BOUSTROPHEDONIC STYLE
!
!
! PRINT*, ' REVERSE BOUSTROPHEDON'
DO i = 2, nrow, 2
!
! REVERSE THE EVEN NUMBERED ROWS
!
DO j = 1, ncol
npos = i * ncol - j + 1
boust(j) = DATA(npos)
END DO
DO j = 1, ncol
npos = ncol * (i-1) + j
DATA(npos) = boust(j)
END DO
END DO
!
!
END IF
! =================================================================
RETURN
END SUBROUTINE w3fi83
SUBROUTINE w3fi01(lw) 5
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . . .
! SUBPROGRAM: W3FI01 DETERMINES MACHINE WORD LENGTH IN BYTES
! PRGMMR: KEYSER ORG: NMC22 DATE:92-07-30
!
! ABSTRACT: DETERMINES THE NUMBER OF BYTES IN A FULL WORD FOR THE
! PARTICULAR MACHINE (IBM, CRAY, WORKSTATION, PC).
!
! PROGRAM HISTORY LOG:
! 92-01-10 R. KISTLER (W/NMC23)
! 92-05-22 D. A. KEYSER -- DOCBLOCKED/COMMENTED
! 93-03-29 R.E.JONES -- ADD SAVE STATEMENT
!
! USAGE: CALL W3FI01(LW)
! OUTPUT ARGUMENT LIST: (INCLUDING WORK ARRAYS)
! LW - MACHINE WORD LENGTH IN BYTES
!
! OUTPUT FILES:
! FT06F001 - PRINTOUT
!
! REMARKS: NONE.
!
! ATTRIBUTES:
! LANGUAGE: IBM AIX XL FORTRAN Compiler/6000
! MACHINE: IBM RS6000 model 530
!
!$$$
!
CHARACTER (LEN=8) :: ctest1,ctest2
!
INTEGER :: itest1,itest2
!
EQUIVALENCE (ctest1,itest1),(ctest2,itest2)
!
SAVE
!
DATA ctest1/'12345678'/
!
itest2 = itest1
!CCCC PRINT *,' CTEST1 = ',CTEST1,' CTEST2 = ',CTEST2
IF (ctest1 == ctest2) THEN
!CCCC PRINT*,' MACHINE WORD LENGTH IS 8 BYTES'
lw = 8
ELSE
!CCCC PRINT*,' MACHINE WORD LENGTH IS 4 BYTES'
lw = 4
END IF
RETURN
END SUBROUTINE w3fi01
SUBROUTINE w3fi04(iendn,itypec,lw)
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
!
! SUBPROGRAM: W3FI04 FIND WORD SIZE, ENDIAN, CHARACTER SET
! PRGMNR: JONES,R.E. ORG: W/NMC42 DATE: 94-10-07
!
! ABSTRACT: SUBROUTINE COMPUTES WORD SIZE, THE TYPE OF CHARACTER
! SET, ASCII OR EBCDIC, AND IF THE COMPUTER IS BIG-ENDIAN, OR
! LITTLE-ENDIAN.
!
! PROGRAM HISTORY LOG:
! 94-10-07 R.E.JONES
!
! USAGE: CALL W3FI04 (IENDN, ITYPEC, LW)
!
! OUTPUT ARGUMENT LIST:
! IENDN - INTEGER FOR BIG-ENDIAN OR LITTLE-ENDIAN
! = 0 BIG-ENDIAN
! = 1 LITTLE-ENDIAN
! = 2 CANNOT COMPUTE
! ITYPEC - INTEGER FOR TYPE OF CHARACTER SET
! = 0 ASCII CHARACTER SET
! = 1 EBCDIC CHARACTER SET
! = 2 NOT ASCII OR EBCDIC
! LW - INTEGER FOR WORDS SIZE OF COMPUTER IN BYTES
! = 4 FOR 32 BIT COMPUTERS
! = 8 FOR 64 BIT COMPUTERS
!
! ATTRIBUTES:
! LANGUAGE: SiliconGraphics 3.5 FORTRAN 77
! MACHINE: SiliconGraphics IRIS-4D/25, 35, INDIGO, INDY
!
!$$$
!
INTEGER :: itest1
INTEGER :: itest2
INTEGER :: itest3
INTEGER :: iendn
INTEGER :: itypec
INTEGER :: lw
!
CHARACTER (LEN=8) :: ctest1
CHARACTER (LEN=8) :: ctest2
CHARACTER (LEN=1) :: ctest3(8)
CHARACTER (LEN=1) :: BLANK
!
EQUIVALENCE (ctest1,itest1),(ctest2,itest2)
!
EQUIVALENCE (itest3,ctest3(1))
!
DATA ctest1/'12345678'/
DATA itest3/z'01020304'/
DATA BLANK /' '/
!
SAVE
!
! TEST FOR TYPE OF CHARACTER SET
! BLANK IS 32 (20 HEX) IN ASCII, 64 (40 HEX) IN EBCDEC
!
IF (ICHAR(BLANK) == 32) THEN
itypec = 0
ELSE IF (ICHAR(BLANK) == 64) THEN
!
! COMPUTER IS PROBABLY AN IBM360, 370, OR 390 WITH
! A 32 BIT WORD SIZE, AND BIG-ENDIAN.
!
itypec = 1
ELSE
itypec = 2
END IF
!
! TEST FOR WORD SIZE, SET LW TO 4 FOR 32 BIT COMPUTER,
! 8 FOR FOR 64 BIT COMPUTERS
!
itest2 = itest1
IF (ctest1 == ctest2) THEN
!
! COMPUTER MAY BE A CRAY, OR COULD BE DEC VAX ALPHA
! OR SGI WITH R4000, R4400, R8800 AFTER THEY CHANGE
! FORTRAN COMPILERS FOR 64 BIT INTEGER.
!
lw = 8
ELSE
lw = 4
END IF
!
! IF CHARACTER SET IS NOT ASCII OR EBCDIC SET IENDN = 2
! CAN NOT TEST FOR ENDIAN TYPE
!
IF (itypec == 2) THEN
iendn = 2
RETURN
END IF
!
! USING ITEST3 WITH Z'01020304' EQUIVALNCED TO CTEST3
! ON A 32 BIT BIG-ENDIAN COMPUTER 03 IS IN THE 3RD
! BYTE OF A 4 BYTE WORD. ON A 32 BIT LITTLE-ENDIAN
! COMPUTER IT IS IN 2ND BYTE.
! ON A 64 BIT COMPUTER Z'01020304' IS RIGHT ADJUSTED IN
! A 64 BIT WORD, 03 IS IN THE 7TH BYTE. ON A LITTLE-
! ENDIAN 64 BIT COMPUTER IT IS IN THE 2ND BYTE.
!
IF (lw == 4) THEN
IF (ICHAR(ctest3(3)) == 3) THEN
iendn = 0
ELSE IF (ICHAR(ctest3(3)) == 2) THEN
iendn = 1
ELSE
iendn = 2
END IF
ELSE IF (lw == 8) THEN
IF (ICHAR(ctest3(7)) == 3) THEN
iendn = 0
ELSE IF (ICHAR(ctest3(2)) == 3) THEN
iendn = 1
ELSE
iendn = 2
END IF
ELSE
iendn = 2
END IF
!
RETURN
END SUBROUTINE w3fi04