[2759] | 1 | C----------------------------------------------------------------------- |
---|
| 2 | SUBROUTINE IXGB2(LUGB,LSKIP,LGRIB,CBUF,NUMFLD,MLEN,IRET) |
---|
| 3 | C$$$ SUBPROGRAM DOCUMENTATION BLOCK |
---|
| 4 | C |
---|
| 5 | C SUBPROGRAM: IXGB2 MAKE INDEX RECORDS FOR FIELDS IN A GRIB2 MESSAGE |
---|
| 6 | C PRGMMR: GILBERT ORG: W/NP11 DATE: 2001-12-10 |
---|
| 7 | C |
---|
| 8 | C ABSTRACT: THIS SUBPROGRAM GENERATES AN INDEX RECORD FOR EACH FIELD IN A |
---|
| 9 | C GRIB2 MESSAGE. THE INDEX RECORDS ARE WRITTEN TO INDEX BUFFER |
---|
| 10 | C POINTED TO BY CBUF. |
---|
| 11 | C |
---|
| 12 | C EACH INDEX RECORD HAS THE FOLLOWING FORM: |
---|
| 13 | C BYTE 001 - 004: LENGTH OF INDEX RECORD |
---|
| 14 | C BYTE 005 - 008: BYTES TO SKIP IN DATA FILE BEFORE GRIB MESSAGE |
---|
| 15 | C BYTE 009 - 012: BYTES TO SKIP IN MESSAGE BEFORE LUS (LOCAL USE) |
---|
| 16 | C SET = 0, IF NO LOCAL USE SECTION IN GRIB2 MESSAGE. |
---|
| 17 | C BYTE 013 - 016: BYTES TO SKIP IN MESSAGE BEFORE GDS |
---|
| 18 | C BYTE 017 - 020: BYTES TO SKIP IN MESSAGE BEFORE PDS |
---|
| 19 | C BYTE 021 - 024: BYTES TO SKIP IN MESSAGE BEFORE DRS |
---|
| 20 | C BYTE 025 - 028: BYTES TO SKIP IN MESSAGE BEFORE BMS |
---|
| 21 | C BYTE 029 - 032: BYTES TO SKIP IN MESSAGE BEFORE DATA SECTION |
---|
| 22 | C BYTE 033 - 040: BYTES TOTAL IN THE MESSAGE |
---|
| 23 | C BYTE 041 - 041: GRIB VERSION NUMBER ( CURRENTLY 2 ) |
---|
| 24 | C BYTE 042 - 042: MESSAGE DISCIPLINE |
---|
| 25 | C BYTE 043 - 044: FIELD NUMBER WITHIN GRIB2 MESSAGE |
---|
| 26 | C BYTE 045 - II: IDENTIFICATION SECTION (IDS) |
---|
| 27 | C BYTE II+1- JJ: GRID DEFINITION SECTION (GDS) |
---|
| 28 | C BYTE JJ+1- KK: PRODUCT DEFINITION SECTION (PDS) |
---|
| 29 | C BYTE KK+1- LL: THE DATA REPRESENTATION SECTION (DRS) |
---|
| 30 | C BYTE LL+1-LL+6: FIRST 6 BYTES OF THE BIT MAP SECTION (BMS) |
---|
| 31 | C |
---|
| 32 | C PROGRAM HISTORY LOG: |
---|
| 33 | C 95-10-31 IREDELL |
---|
| 34 | C 96-10-31 IREDELL AUGMENTED OPTIONAL DEFINITIONS TO BYTE 320 |
---|
| 35 | C 2001-12-10 GILBERT MODIFIED FROM IXGB TO CREATE GRIB2 INDEXES |
---|
| 36 | C 2002-01-31 GILBERT ADDED IDENTIFICATION SECTION TO INDEX RECORD |
---|
| 37 | C |
---|
| 38 | C USAGE: CALL IXGB2(LUGB,LSKIP,LGRIB,CBUF,NUMFLD,MLEN,IRET) |
---|
| 39 | C INPUT ARGUMENTS: |
---|
| 40 | C LUGB INTEGER LOGICAL UNIT OF INPUT GRIB FILE |
---|
| 41 | C LSKIP INTEGER NUMBER OF BYTES TO SKIP BEFORE GRIB MESSAGE |
---|
| 42 | C LGRIB INTEGER NUMBER OF BYTES IN GRIB MESSAGE |
---|
| 43 | C OUTPUT ARGUMENTS: |
---|
| 44 | C CBUF CHARACTER*1 POINTER TO A BUFFER THAT CONTAINS INDEX RECORDS. |
---|
| 45 | C USERS SHOULD FREE MEMORY THAT CBUF POINTS TO |
---|
| 46 | C USING DEALLOCATE(CBUF) WHEN CBUF IS NO LONGER NEEDED. |
---|
| 47 | C NUMFLD INTEGER NUMBER OF INDEX RECORDS CREATED. |
---|
| 48 | C = 0, IF PROBLEMS |
---|
| 49 | C MLEN INTEGER TOTAL LENGTH OF ALL INDEX RECORDS |
---|
| 50 | C IRET INTEGER RETURN CODE |
---|
| 51 | C =0, ALL OK |
---|
| 52 | C =1, NOT ENOUGH MEMORY TO ALLOCATE INITIAL INDEX BUFFER |
---|
| 53 | C =2, I/O ERROR IN READ |
---|
| 54 | C =3, GRIB MESSAGE IS NOT EDITION 2 |
---|
| 55 | C =4, NOT ENOUGH MEMORY TO ALLOCATE EXTENT TO INDEX BUFFER |
---|
| 56 | C =5, UNIDENTIFIED GRIB SECTION ENCOUNTERED...PROBLEM |
---|
| 57 | C SOMEWHERE. |
---|
| 58 | C |
---|
| 59 | C SUBPROGRAMS CALLED: |
---|
| 60 | C G2LIB_GBYTE GET INTEGER DATA FROM BYTES |
---|
| 61 | C G2LIB_SBYTE STORE INTEGER DATA IN BYTES |
---|
| 62 | C BAREAD BYTE-ADDRESSABLE READ |
---|
| 63 | C REALLOC RE-ALLOCATES MORE MEMORY |
---|
| 64 | C |
---|
| 65 | C ATTRIBUTES: |
---|
| 66 | C LANGUAGE: FORTRAN 90 |
---|
| 67 | C |
---|
| 68 | C$$$ |
---|
| 69 | USE RE_ALLOC ! NEEDED FOR SUBROUTINE REALLOC |
---|
| 70 | CHARACTER(LEN=1),POINTER,DIMENSION(:) :: CBUF |
---|
| 71 | PARAMETER(LINMAX=5000,INIT=50000,NEXT=10000) |
---|
| 72 | PARAMETER(IXSKP=4,IXLUS=8,IXSGD=12,IXSPD=16,IXSDR=20,IXSBM=24, |
---|
| 73 | & IXDS=28,IXLEN=36,IXFLD=42,IXIDS=44) |
---|
| 74 | PARAMETER(MXSKP=4,MXLUS=4,MXSGD=4,MXSPD=4,MXSDR=4,MXSBM=4, |
---|
| 75 | & MXDS=4,MXLEN=4,MXFLD=2,MXBMS=6) |
---|
| 76 | CHARACTER CBREAD(LINMAX),CINDEX(LINMAX) |
---|
| 77 | CHARACTER CVER,CDISC |
---|
| 78 | CHARACTER CIDS(LINMAX),CGDS(LINMAX),CBMS(6) |
---|
| 79 | CHARACTER(LEN=4) :: CTEMP |
---|
| 80 | INTEGER LOCLUS,LOCGDS,LENGDS,LOCBMS |
---|
| 81 | C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
---|
| 82 | LOCLUS=0 |
---|
| 83 | IRET=0 |
---|
| 84 | MLEN=0 |
---|
| 85 | NUMFLD=0 |
---|
| 86 | IF (ASSOCIATED(CBUF)) NULLIFY(CBUF) |
---|
| 87 | MBUF=INIT |
---|
| 88 | ALLOCATE(CBUF(MBUF),STAT=ISTAT) ! ALLOCATE INITIAL SPACE FOR CBUF |
---|
| 89 | IF (ISTAT.NE.0) THEN |
---|
| 90 | IRET=1 |
---|
| 91 | RETURN |
---|
| 92 | ENDIF |
---|
| 93 | C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
---|
| 94 | C READ SECTIONS 0 AND 1 FOR VERSIN NUMBER AND DISCIPLINE |
---|
| 95 | IBREAD=MIN(LGRIB,LINMAX) |
---|
| 96 | CALL BAREAD(LUGB,LSKIP,IBREAD,LBREAD,CBREAD) |
---|
| 97 | IF(LBREAD.NE.IBREAD) THEN |
---|
| 98 | IRET=2 |
---|
| 99 | RETURN |
---|
| 100 | ENDIF |
---|
| 101 | IF(CBREAD(8).NE.CHAR(2)) THEN ! NOT GRIB EDITION 2 |
---|
| 102 | IRET=3 |
---|
| 103 | RETURN |
---|
| 104 | ENDIF |
---|
| 105 | CVER=CBREAD(8) |
---|
| 106 | CDISC=CBREAD(7) |
---|
| 107 | CALL G2LIB_GBYTE(CBREAD,LENSEC1,16*8,4*8) |
---|
| 108 | LENSEC1=MIN(LENSEC1,IBREAD) |
---|
| 109 | CIDS(1:LENSEC1)=CBREAD(17:16+LENSEC1) |
---|
| 110 | IBSKIP=LSKIP+16+LENSEC1 |
---|
| 111 | C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
---|
| 112 | C LOOP THROUGH REMAINING SECTIONS CREATING AN INDEX FOR EACH FIELD |
---|
| 113 | IBREAD=MAX(5,MXBMS) |
---|
| 114 | DO |
---|
| 115 | CALL BAREAD(LUGB,IBSKIP,IBREAD,LBREAD,CBREAD) |
---|
| 116 | CTEMP=CBREAD(1)//CBREAD(2)//CBREAD(3)//CBREAD(4) |
---|
| 117 | IF (CTEMP.EQ.'7777') RETURN ! END OF MESSAGE FOUND |
---|
| 118 | IF(LBREAD.NE.IBREAD) THEN |
---|
| 119 | IRET=2 |
---|
| 120 | RETURN |
---|
| 121 | ENDIF |
---|
| 122 | CALL G2LIB_GBYTE(CBREAD,LENSEC,0*8,4*8) |
---|
| 123 | CALL G2LIB_GBYTE(CBREAD,NUMSEC,4*8,1*8) |
---|
| 124 | |
---|
| 125 | IF (NUMSEC.EQ.2) THEN ! SAVE LOCAL USE LOCATION |
---|
| 126 | LOCLUS=IBSKIP-LSKIP |
---|
| 127 | ELSEIF (NUMSEC.EQ.3) THEN ! SAVE GDS INFO |
---|
| 128 | LENGDS=LENSEC |
---|
| 129 | CGDS=CHAR(0) |
---|
| 130 | CALL BAREAD(LUGB,IBSKIP,LENGDS,LBREAD,CGDS) |
---|
| 131 | IF(LBREAD.NE.LENGDS) THEN |
---|
| 132 | IRET=2 |
---|
| 133 | RETURN |
---|
| 134 | ENDIF |
---|
| 135 | LOCGDS=IBSKIP-LSKIP |
---|
| 136 | ELSEIF (NUMSEC.EQ.4) THEN ! FOUND PDS |
---|
| 137 | CINDEX=CHAR(0) |
---|
| 138 | CALL G2LIB_SBYTE(CINDEX,LSKIP,8*IXSKP,8*MXSKP) ! BYTES TO SKIP |
---|
| 139 | CALL G2LIB_SBYTE(CINDEX,LOCLUS,8*IXLUS,8*MXLUS) ! LOCATION OF LOCAL USE |
---|
| 140 | CALL G2LIB_SBYTE(CINDEX,LOCGDS,8*IXSGD,8*MXSGD) ! LOCATION OF GDS |
---|
| 141 | CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXSPD,8*MXSPD) ! LOCATION OF PDS |
---|
| 142 | CALL G2LIB_SBYTE(CINDEX,LGRIB,8*IXLEN,8*MXLEN) ! LEN OF GRIB2 |
---|
| 143 | CINDEX(41)=CVER |
---|
| 144 | CINDEX(42)=CDISC |
---|
| 145 | CALL G2LIB_SBYTE(CINDEX,NUMFLD+1,8*IXFLD,8*MXFLD) ! FIELD NUM |
---|
| 146 | CINDEX(IXIDS+1:IXIDS+LENSEC1)=CIDS(1:LENSEC1) |
---|
| 147 | LINDEX=IXIDS+LENSEC1 |
---|
| 148 | CINDEX(LINDEX+1:LINDEX+LENGDS)=CGDS(1:LENGDS) |
---|
| 149 | LINDEX=LINDEX+LENGDS |
---|
| 150 | ILNPDS=LENSEC |
---|
| 151 | CALL BAREAD(LUGB,IBSKIP,ILNPDS,LBREAD,CINDEX(LINDEX+1)) |
---|
| 152 | IF(LBREAD.NE.ILNPDS) THEN |
---|
| 153 | IRET=2 |
---|
| 154 | RETURN |
---|
| 155 | ENDIF |
---|
| 156 | ! CINDEX(LINDEX+1:LINDEX+ILNPDS)=CBREAD(1:ILNPDS) |
---|
| 157 | LINDEX=LINDEX+ILNPDS |
---|
| 158 | ELSEIF (NUMSEC.EQ.5) THEN ! FOUND DRS |
---|
| 159 | CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXSDR,8*MXSDR) ! LOCATION OF DRS |
---|
| 160 | ILNDRS=LENSEC |
---|
| 161 | CALL BAREAD(LUGB,IBSKIP,ILNDRS,LBREAD,CINDEX(LINDEX+1)) |
---|
| 162 | IF(LBREAD.NE.ILNDRS) THEN |
---|
| 163 | IRET=2 |
---|
| 164 | RETURN |
---|
| 165 | ENDIF |
---|
| 166 | ! CINDEX(LINDEX+1:LINDEX+ILNDRS)=CBREAD(1:ILNDRS) |
---|
| 167 | LINDEX=LINDEX+ILNDRS |
---|
| 168 | ELSEIF (NUMSEC.EQ.6) THEN ! FOUND BMS |
---|
| 169 | INDBMP=MOVA2I(CBREAD(6)) |
---|
| 170 | IF ( INDBMP.LT.254 ) THEN |
---|
| 171 | LOCBMS=IBSKIP-LSKIP |
---|
| 172 | CALL G2LIB_SBYTE(CINDEX,LOCBMS,8*IXSBM,8*MXSBM) ! LOC. OF BMS |
---|
| 173 | ELSEIF ( INDBMP.EQ.254 ) THEN |
---|
| 174 | CALL G2LIB_SBYTE(CINDEX,LOCBMS,8*IXSBM,8*MXSBM) ! LOC. OF BMS |
---|
| 175 | ELSEIF ( INDBMP.EQ.255 ) THEN |
---|
| 176 | CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXSBM,8*MXSBM) ! LOC. OF BMS |
---|
| 177 | ENDIF |
---|
| 178 | CINDEX(LINDEX+1:LINDEX+MXBMS)=CBREAD(1:MXBMS) |
---|
| 179 | LINDEX=LINDEX+MXBMS |
---|
| 180 | CALL G2LIB_SBYTE(CINDEX,LINDEX,0,8*4) ! NUM BYTES IN INDEX RECORD |
---|
| 181 | ELSEIF (NUMSEC.EQ.7) THEN ! FOUND DATA SECTION |
---|
| 182 | CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXDS,8*MXDS) ! LOC. OF DATA SEC. |
---|
| 183 | NUMFLD=NUMFLD+1 |
---|
| 184 | IF ((LINDEX+MLEN).GT.MBUF) THEN ! ALLOCATE MORE SPACE IF |
---|
| 185 | ! NECESSARY |
---|
| 186 | NEWSIZE=MAX(MBUF+NEXT,MBUF+LINDEX) |
---|
| 187 | CALL REALLOC(CBUF,MLEN,NEWSIZE,ISTAT) |
---|
| 188 | IF ( ISTAT .NE. 0 ) THEN |
---|
| 189 | NUMFLD=NUMFLD-1 |
---|
| 190 | IRET=4 |
---|
| 191 | RETURN |
---|
| 192 | ENDIF |
---|
| 193 | MBUF=NEWSIZE |
---|
| 194 | ENDIF |
---|
| 195 | CBUF(MLEN+1:MLEN+LINDEX)=CINDEX(1:LINDEX) |
---|
| 196 | MLEN=MLEN+LINDEX |
---|
| 197 | ELSE ! UNRECOGNIZED SECTION |
---|
| 198 | IRET=5 |
---|
| 199 | RETURN |
---|
| 200 | ENDIF |
---|
| 201 | IBSKIP=IBSKIP+LENSEC |
---|
| 202 | ENDDO |
---|
| 203 | |
---|
| 204 | C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
---|
| 205 | RETURN |
---|
| 206 | END |
---|