From 7f5d2d7577b55cfd2763d22f340483d8c90c5ce5 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 11:08:06 -0700 Subject: [PATCH 01/69] more index progress --- src/g2index.F90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 46a0e025..e6d19ef5 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -832,7 +832,11 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) locgds = ibskip-lskip elseif (numsec .eq. 4) then ! found pds cindex = char(0) - call g2_sbytec(cindex, lskip, 8 * ixskp, 8 * mxskp) ! bytes to skip + if (idxver .eq. 1) then + call g2_sbytec(cindex, lskip, 8 * ixskp, 8 * mxskp) ! bytes to skip + else + call g2_sbytec8(cindex, lskip8, 8 * ixskp, 8 * mxskp) ! bytes to skip + endif call g2_sbytec(cindex, loclus, 8 * ixlus, 8 * mxlus) ! location of local use call g2_sbytec(cindex, locgds, 8 * ixsgd, 8 * mxsgd) ! location of gds call g2_sbytec(cindex, ibskip-lskip, 8 * ixspd, 8 * mxspd) ! location of pds From 2204d3890c2dffa52fb0210cc6c30337caf0ccaf Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 11:24:02 -0700 Subject: [PATCH 02/69] more index progress --- src/g2index.F90 | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index e6d19ef5..928639f4 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -803,6 +803,7 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) lensec1 = min(lensec1, int(ibread8, kind(lensec1))) cids(1:lensec1) = cbread(17:16 + lensec1) ibskip = lskip + 16 + lensec1 + ibskip8 = lskip8 + 16_8 + int(lensec1, kind(8)) ! Loop through remaining sections creating an index for each field. ibread8 = max(5, mxbms) @@ -819,17 +820,16 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) call g2_gbytec(cbread, numsec, 4 * 8, 1 * 8) if (numsec .eq. 2) then ! save local use location - loclus = ibskip-lskip + loclus = int(ibskip8 - lskip8, kind(4)) elseif (numsec .eq. 3) then ! save gds info lengds8 = lensec cgds = char(0) - ibskip8 = ibskip call bareadl(lugb, ibskip8, lengds8, lbread8, cgds) if (lbread8 .ne. lengds8) then iret = 2 return endif - locgds = ibskip-lskip + locgds = int(ibskip8 - lskip8, kind(4)) elseif (numsec .eq. 4) then ! found pds cindex = char(0) if (idxver .eq. 1) then @@ -839,7 +839,7 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) endif call g2_sbytec(cindex, loclus, 8 * ixlus, 8 * mxlus) ! location of local use call g2_sbytec(cindex, locgds, 8 * ixsgd, 8 * mxsgd) ! location of gds - call g2_sbytec(cindex, ibskip-lskip, 8 * ixspd, 8 * mxspd) ! location of pds + call g2_sbytec(cindex, int(ibskip - lskip, kind(4)), 8 * ixspd, 8 * mxspd) ! location of pds call g2_sbytec(cindex, lgrib, 8 * ixlen, 8 * mxlen) ! len of grib2 cindex(41) = cver cindex(42) = cdisc @@ -849,7 +849,6 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) cindex(lindex + 1:lindex + lengds8) = cgds(1:lengds8) lindex = lindex + int(lengds8, kind(lindex)) ilnpds = lensec - ibskip8 = ibskip ilnpds8 = ilnpds call bareadl(lugb, ibskip8, ilnpds8, lbread8, cindex(lindex + 1)) if (lbread8 .ne. ilnpds8) then @@ -858,9 +857,8 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) endif lindex = lindex + ilnpds elseif (numsec .eq. 5) then ! found drs - call g2_sbytec(cindex, ibskip-lskip, 8 * ixsdr, 8 * mxsdr) ! location of drs + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsdr, 8 * mxsdr) ! location of drs ilndrs = lensec - ibskip8 = ibskip ilndrs8 = ilndrs call bareadl(lugb, ibskip8, ilndrs8, lbread8, cindex(lindex + 1)) if (lbread8 .ne. ilndrs8) then @@ -871,18 +869,18 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) elseif (numsec .eq. 6) then ! found bms indbmp = mova2i(cbread(6)) if (indbmp.lt.254) then - locbms = ibskip-lskip + locbms = int(ibskip8 - lskip8, kind(4)) call g2_sbytec(cindex, locbms, 8 * ixsbm, 8 * mxsbm) ! loc. of bms elseif (indbmp.eq.254) then call g2_sbytec(cindex, locbms, 8 * ixsbm, 8 * mxsbm) ! loc. of bms elseif (indbmp.eq.255) then - call g2_sbytec(cindex, ibskip-lskip, 8 * ixsbm, 8 * mxsbm) ! loc. of bms + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsbm, 8 * mxsbm) ! loc. of bms endif cindex(lindex + 1:lindex + mxbms) = cbread(1:mxbms) lindex = lindex + mxbms call g2_sbytec(cindex, lindex, 0, 8 * 4) ! num bytes in index record elseif (numsec .eq. 7) then ! found data section - call g2_sbytec(cindex, ibskip-lskip, 8 * ixds, 8 * mxds) ! loc. of data sec. + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixds, 8 * mxds) ! loc. of data sec. numfld = numfld + 1 if ((lindex + mlen) .gt. mbuf) then ! allocate more space if necessary newsize = max(mbuf + next, mbuf + lindex) @@ -900,6 +898,7 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) iret = 5 return endif + ibskip8 = ibskip8 + lensec ibskip = ibskip + lensec enddo end subroutine ix2gb2 From d71e4aeec972412bad16a831a697d3c34542ad7b Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 11:32:13 -0700 Subject: [PATCH 03/69] more index progress --- src/g2index.F90 | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 928639f4..4d3dae61 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -676,11 +676,12 @@ subroutine ixgb2(lugb, lskip, lgrib, cbuf, numfld, mlen, iret) integer :: lugb, lskip, lgrib character(len = 1), pointer, dimension(:) :: cbuf integer :: numfld, mlen, iret + integer (kind = 8) :: lskip8 interface - subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) + subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) integer :: lugb - integer :: lskip + integer (kind = 8) :: lskip8 integer :: idxver, lgrib character(len = 1), pointer, dimension(:) :: cbuf integer :: numfld, mlen, iret @@ -688,7 +689,8 @@ end subroutine ix2gb2 end interface ! Always use index version 1 from this subroutine. - call ix2gb2(lugb, lskip, 1, lgrib, cbuf, numfld, mlen, iret) + lskip8 = lskip + call ix2gb2(lugb, lskip8, 1, lgrib, cbuf, numfld, mlen, iret) end subroutine ixgb2 !> Generate an index record for each field in a GRIB2 message. The index @@ -721,7 +723,7 @@ end subroutine ixgb2 !> @param lugb Unit of the unblocked GRIB file. Must !> be opened by [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/). -!> @param lskip Number of bytes to skip before GRIB message. +!> @param lskip8 Number of bytes to skip before GRIB message. !> @param idxver Index version, use 1 for legacy, 2 for GRIB2 files > 2 GB. !> @param lgrib Number of bytes in GRIB message. When subroutine is !> called, this must be set to the size of the cbuf buffer. @@ -742,12 +744,12 @@ end subroutine ixgb2 !> - 5 Unidentified GRIB section encountered. !> !> @author Ed Hartnett, Mark Iredell @date Feb 5, 2024 -subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) +subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) use re_alloc ! needed for subroutine realloc implicit none integer :: lugb - integer :: lskip + integer (kind = 8) :: lskip8 integer :: idxver, lgrib character(len = 1), pointer, dimension(:) :: cbuf integer :: numfld, mlen, iret @@ -759,9 +761,9 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) integer :: linmax, ixskp integer :: mxspd, mxskp, mxsgd, mxsdr, mxsbm, mxlus integer :: mxlen, mxds, mxfld, mxbms - integer :: init, ixlus - integer :: ixsgd, ibskip, ilndrs, ilnpds, istat, ixds - integer (kind = 8) :: lskip8, ibread8, lbread8, ibskip8, lengds8 + integer :: init, ixlus, lskip + integer :: ixsgd, ilndrs, ilnpds, istat, ixds + integer (kind = 8) :: ibread8, lbread8, ibskip8, lengds8 integer (kind = 8) :: ilnpds8, ilndrs8 integer :: ixspd, ixfld, ixids, ixlen, ixsbm, ixsdr integer :: lensec, lensec1 @@ -787,7 +789,6 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) ! Read sections 0 and 1 for GRIB version number and discipline. ibread8 = min(lgrib, linmax) - lskip8 = lskip call bareadl(lugb, lskip8, ibread8, lbread8, cbread) if (lbread8 .ne. ibread8) then iret = 2 @@ -802,13 +803,11 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) call g2_gbytec(cbread, lensec1, 16 * 8, 4 * 8) lensec1 = min(lensec1, int(ibread8, kind(lensec1))) cids(1:lensec1) = cbread(17:16 + lensec1) - ibskip = lskip + 16 + lensec1 ibskip8 = lskip8 + 16_8 + int(lensec1, kind(8)) ! Loop through remaining sections creating an index for each field. ibread8 = max(5, mxbms) do - ibskip8 = ibskip call bareadl(lugb, ibskip8, ibread8, lbread8, cbread) ctemp = cbread(1)//cbread(2)//cbread(3)//cbread(4) if (ctemp .eq. '7777') return ! end of message found @@ -833,13 +832,14 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) elseif (numsec .eq. 4) then ! found pds cindex = char(0) if (idxver .eq. 1) then + lskip = int(lskip8, kind(4)) call g2_sbytec(cindex, lskip, 8 * ixskp, 8 * mxskp) ! bytes to skip else call g2_sbytec8(cindex, lskip8, 8 * ixskp, 8 * mxskp) ! bytes to skip endif call g2_sbytec(cindex, loclus, 8 * ixlus, 8 * mxlus) ! location of local use call g2_sbytec(cindex, locgds, 8 * ixsgd, 8 * mxsgd) ! location of gds - call g2_sbytec(cindex, int(ibskip - lskip, kind(4)), 8 * ixspd, 8 * mxspd) ! location of pds + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixspd, 8 * mxspd) ! location of pds call g2_sbytec(cindex, lgrib, 8 * ixlen, 8 * mxlen) ! len of grib2 cindex(41) = cver cindex(42) = cdisc @@ -899,7 +899,6 @@ subroutine ix2gb2(lugb, lskip, idxver, lgrib, cbuf, numfld, mlen, iret) return endif ibskip8 = ibskip8 + lensec - ibskip = ibskip + lensec enddo end subroutine ix2gb2 From 86508f412d6d6e7417cda8cfae66e1a4560fa86c Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 13:27:22 -0700 Subject: [PATCH 04/69] more index work --- src/g2index.F90 | 99 +++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 4d3dae61..465f5e1a 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -269,9 +269,12 @@ subroutine getg2ir(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) use re_alloc ! needed for subroutine realloc implicit none + integer, intent(in) :: lugb + integer, intent(in) :: msk1, msk2 + integer, intent(in) :: mnum character(len = 1), pointer, dimension(:) :: cbuf - integer, intent(in) :: lugb, msk1, msk2, mnum integer, intent(out) :: nlen, nnum, nmess, iret + character(len = 1), pointer, dimension(:) :: cbuftmp integer :: nbytes, newsize, next, numfld, m, mbuf, lskip, lgrib integer :: istat, iseek, init, iret1 @@ -286,61 +289,61 @@ end subroutine ixgb2 end interface ! Initialize. - IRET = 0 - NULLIFY(CBUF) - MBUF = INIT - ALLOCATE(CBUF(MBUF), STAT = ISTAT) ! Allocate initial space for cbuf. - IF (ISTAT .NE. 0) THEN - IRET = 2 - RETURN - ENDIF + iret = 0 + nullify(cbuf) + mbuf = init + allocate(cbuf(mbuf), stat = istat) ! allocate initial space for cbuf. + if (istat .ne. 0) then + iret = 2 + return + endif - ! Search for first grib message. - ISEEK = 0 - CALL SKGB(LUGB, ISEEK, MSK1, LSKIP, LGRIB) - DO M = 1, MNUM - IF(LGRIB.GT.0) THEN - ISEEK = LSKIP + LGRIB - CALL SKGB(LUGB, ISEEK, MSK2, LSKIP, LGRIB) - ENDIF - ENDDO + ! search for first grib message. + iseek = 0 + call skgb(lugb, iseek, msk1, lskip, lgrib) + do m = 1, mnum + if(lgrib.gt.0) then + iseek = lskip + lgrib + call skgb(lugb, iseek, msk2, lskip, lgrib) + endif + enddo ! Get index records for every grib message found. - NLEN = 0 - NNUM = 0 - NMESS = MNUM - DO WHILE(IRET .EQ. 0 .AND. LGRIB .GT. 0) - CALL IXGB2(LUGB, LSKIP, LGRIB, CBUFTMP, NUMFLD, NBYTES, IRET1) - IF (IRET1 .NE. 0) PRINT *, ' SAGT ', NUMFLD, NBYTES, IRET1 - IF((NBYTES + NLEN) .GT. MBUF) THEN ! Allocate more space, if necessary. - NEWSIZE = MAX(MBUF + NEXT, MBUF + NBYTES) - CALL REALLOC(CBUF, NLEN, NEWSIZE, ISTAT) - IF (ISTAT .NE. 0) THEN - IRET = 1 - RETURN - ENDIF - MBUF = NEWSIZE - ENDIF + nlen = 0 + nnum = 0 + nmess = mnum + do while(iret .eq. 0 .and. lgrib .gt. 0) + call ixgb2(lugb, lskip, lgrib, cbuftmp, numfld, nbytes, iret1) + if (iret1 .ne. 0) print *, ' SAGT ', numfld, nbytes, iret1 + if((nbytes + nlen) .gt. mbuf) then ! Allocate more space, if necessary. + newsize = max(mbuf + next, mbuf + nbytes) + call realloc(cbuf, nlen, newsize, istat) + if (istat .ne. 0) then + iret = 1 + return + endif + mbuf = newsize + endif ! If index records were returned in cbuftmp from ixgb2, ! copy cbuftmp into cbuf, then deallocate cbuftmp when done. - IF (ASSOCIATED(CBUFTMP)) THEN - CBUF(NLEN + 1 : NLEN + NBYTES) = CBUFTMP(1 : NBYTES) - DEALLOCATE(CBUFTMP, STAT = ISTAT) - IF (ISTAT.NE.0) THEN - PRINT *, ' deallocating cbuftmp ... ', istat - IRET = 3 - RETURN - ENDIF - NULLIFY(CBUFTMP) - NNUM = NNUM + NUMFLD - NLEN = NLEN + NBYTES - NMESS = NMESS + 1 - ENDIF + if (associated(cbuftmp)) then + cbuf(nlen + 1 : nlen + nbytes) = cbuftmp(1 : nbytes) + deallocate(cbuftmp, stat = istat) + if (istat.ne.0) then + print *, ' deallocating cbuftmp ... ', istat + iret = 3 + return + endif + nullify(cbuftmp) + nnum = nnum + numfld + nlen = nlen + nbytes + nmess = nmess + 1 + endif ! Look for next grib message. - ISEEK = LSKIP + LGRIB - CALL SKGB(LUGB, ISEEK, MSK2, LSKIP, LGRIB) + iseek = lskip + lgrib + call skgb(lugb, iseek, msk2, lskip, lgrib) ENDDO END SUBROUTINE GETG2IR From 0866db4fc74ea9cefba70543dafd71485d7691c1 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 13:32:38 -0700 Subject: [PATCH 05/69] more index work --- src/g2index.F90 | 59 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 465f5e1a..f045f032 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -269,6 +269,61 @@ subroutine getg2ir(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) use re_alloc ! needed for subroutine realloc implicit none + integer, intent(in) :: lugb + integer, intent(in) :: msk1, msk2 + integer, intent(in) :: mnum + character(len = 1), pointer, dimension(:) :: cbuf + integer, intent(out) :: nlen, nnum, nmess, iret + + interface + subroutine getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) + integer, intent(in) :: lugb + integer, intent(in) :: msk1, msk2 + integer, intent(in) :: mnum + character(len = 1), pointer, dimension(:) :: cbuf + integer, intent(out) :: nlen, nnum, nmess, iret + end subroutine getg2i2r + end interface + + call getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) +end subroutine getg2ir + +!> Generate an index record for a message in a GRIB2 file. +!> +!> The index record contains byte offsets to the message, it's length, +!> and byte offsets within the message to each section. The index file +!> record format is documented in subroutine ixgb2(). +!> +!> @note Subprogram can be called from a multiprocessing environment. +!> Do not engage the same logical unit from more than one processor. +!> +!> @param[in] lugb Unit of the unblocked GRIB file. Must +!> be opened by [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/). +!> @param[in] msk1 Number of bytes to search for first message. +!> @param[in] msk2 Number of bytes to search for other messages. +!> @param[in] mnum Number of GRIB messages to skip (usually 0). +!> @param[out] cbuf Pointer to a buffer that will get the index +!> records. If any memory is associated with cbuf when this subroutine +!> is called, cbuf will be nullified in the subroutine. Initially cbuf +!> will get an allocation of 5000 bytes. realloc() will be used to +!> increase the size if necessary. Users must free memory that cbuf +!> points to when cbuf is no longer needed. +!> @param[out] nlen Total length of index record buffer in bytes. +!> @param[out] nnum Number of index records, zero if no GRIB +!> messages are found. +!> @param[out] nmess Last GRIB message in file successfully processed +!> @param[out] iret Return code. +!> - 0 No error. +!> - 1 Not enough memory available to hold full index buffer. +!> - 2 Not enough memory to allocate initial index buffer. +!> - 3 Error deallocating memory. +!> +!> @author Mark Iredell @date 1995-10-31 +subroutine getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) + use re_alloc ! needed for subroutine realloc + implicit none + integer, intent(in) :: lugb integer, intent(in) :: msk1, msk2 integer, intent(in) :: mnum @@ -344,8 +399,8 @@ end subroutine ixgb2 ! Look for next grib message. iseek = lskip + lgrib call skgb(lugb, iseek, msk2, lskip, lgrib) - ENDDO -END SUBROUTINE GETG2IR + enddo +end subroutine getg2i2r !> Find information about a GRIB field from the index and fill a @ref !> grib_mod::gribfield. From 9598dfad61ce31ce126eeaa358e28b0b050b541a Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 13:51:36 -0700 Subject: [PATCH 06/69] more index work --- src/g2index.F90 | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index f045f032..d43f250b 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -275,17 +275,21 @@ subroutine getg2ir(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) character(len = 1), pointer, dimension(:) :: cbuf integer, intent(out) :: nlen, nnum, nmess, iret + integer (kind = 8) :: msk1_8, msk2_8 + interface subroutine getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) integer, intent(in) :: lugb - integer, intent(in) :: msk1, msk2 + integer (kind = 8), intent(in) :: msk1, msk2 integer, intent(in) :: mnum character(len = 1), pointer, dimension(:) :: cbuf integer, intent(out) :: nlen, nnum, nmess, iret end subroutine getg2i2r end interface - call getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) + msk1_8 = msk1 + msk2_8 = msk2 + call getg2i2r(lugb, msk1_8, msk2_8, mnum, cbuf, nlen, nnum, nmess, iret) end subroutine getg2ir !> Generate an index record for a message in a GRIB2 file. @@ -297,9 +301,8 @@ end subroutine getg2ir !> @note Subprogram can be called from a multiprocessing environment. !> Do not engage the same logical unit from more than one processor. !> -!> @param[in] lugb Unit of the unblocked GRIB file. Must -!> be opened by [baopen() or baopenr()] -!> (https://noaa-emc.github.io/NCEPLIBS-bacio/). +!> @param[in] lugb Unit of the GRIB file. Must be opened by [baopen() +!> or baopenr()] (https://noaa-emc.github.io/NCEPLIBS-bacio/). !> @param[in] msk1 Number of bytes to search for first message. !> @param[in] msk2 Number of bytes to search for other messages. !> @param[in] mnum Number of GRIB messages to skip (usually 0). @@ -325,22 +328,25 @@ subroutine getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) implicit none integer, intent(in) :: lugb - integer, intent(in) :: msk1, msk2 + integer (kind = 8), intent(in) :: msk1, msk2 integer, intent(in) :: mnum character(len = 1), pointer, dimension(:) :: cbuf integer, intent(out) :: nlen, nnum, nmess, iret character(len = 1), pointer, dimension(:) :: cbuftmp - integer :: nbytes, newsize, next, numfld, m, mbuf, lskip, lgrib - integer :: istat, iseek, init, iret1 + integer :: nbytes, newsize, next, numfld, m, mbuf + integer (kind = 8) :: iseek, lskip, lgrib + integer :: istat, init, iret1, lgrib4 parameter(init = 50000, next = 10000) interface ! required for cbuf pointer - subroutine ixgb2(lugb, lskip, lgrib, cbuf, numfld, mlen, iret) - integer :: lugb, lskip, lgrib + subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) + integer :: lugb + integer (kind = 8) :: lskip8 + integer :: idxver, lgrib character(len = 1), pointer, dimension(:) :: cbuf integer :: numfld, mlen, iret - end subroutine ixgb2 + end subroutine ix2gb2 end interface ! Initialize. @@ -354,12 +360,12 @@ end subroutine ixgb2 endif ! search for first grib message. - iseek = 0 - call skgb(lugb, iseek, msk1, lskip, lgrib) + iseek = 0_8 + call skgb8(lugb, iseek, msk1, lskip, lgrib) do m = 1, mnum if(lgrib.gt.0) then iseek = lskip + lgrib - call skgb(lugb, iseek, msk2, lskip, lgrib) + call skgb8(lugb, iseek, msk2, lskip, lgrib) endif enddo @@ -368,7 +374,8 @@ end subroutine ixgb2 nnum = 0 nmess = mnum do while(iret .eq. 0 .and. lgrib .gt. 0) - call ixgb2(lugb, lskip, lgrib, cbuftmp, numfld, nbytes, iret1) + lgrib4 = int(lgrib, kind(4)) + call ix2gb2(lugb, lskip, 1, lgrib4, cbuftmp, numfld, nbytes, iret1) if (iret1 .ne. 0) print *, ' SAGT ', numfld, nbytes, iret1 if((nbytes + nlen) .gt. mbuf) then ! Allocate more space, if necessary. newsize = max(mbuf + next, mbuf + nbytes) @@ -398,7 +405,7 @@ end subroutine ixgb2 ! Look for next grib message. iseek = lskip + lgrib - call skgb(lugb, iseek, msk2, lskip, lgrib) + call skgb8(lugb, iseek, msk2, lskip, lgrib) enddo end subroutine getg2i2r From 05a6c3cfe75abe5b0f291fb837a31b4b82b1ef02 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 13:54:52 -0700 Subject: [PATCH 07/69] more index work --- src/g2index.F90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index d43f250b..427d3a5c 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -278,10 +278,11 @@ subroutine getg2ir(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) integer (kind = 8) :: msk1_8, msk2_8 interface - subroutine getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) + subroutine getg2i2r(lugb, msk1, msk2, mnum, idxver, cbuf, & + nlen, nnum, nmess, iret) integer, intent(in) :: lugb integer (kind = 8), intent(in) :: msk1, msk2 - integer, intent(in) :: mnum + integer, intent(in) :: mnum, idxver character(len = 1), pointer, dimension(:) :: cbuf integer, intent(out) :: nlen, nnum, nmess, iret end subroutine getg2i2r @@ -289,7 +290,7 @@ end subroutine getg2i2r msk1_8 = msk1 msk2_8 = msk2 - call getg2i2r(lugb, msk1_8, msk2_8, mnum, cbuf, nlen, nnum, nmess, iret) + call getg2i2r(lugb, msk1_8, msk2_8, mnum, 1, cbuf, nlen, nnum, nmess, iret) end subroutine getg2ir !> Generate an index record for a message in a GRIB2 file. @@ -306,6 +307,7 @@ end subroutine getg2ir !> @param[in] msk1 Number of bytes to search for first message. !> @param[in] msk2 Number of bytes to search for other messages. !> @param[in] mnum Number of GRIB messages to skip (usually 0). +!> @param[in] idxver Index version number. Use 1 for legacy, 2 for files > 2 GB. !> @param[out] cbuf Pointer to a buffer that will get the index !> records. If any memory is associated with cbuf when this subroutine !> is called, cbuf will be nullified in the subroutine. Initially cbuf @@ -323,13 +325,13 @@ end subroutine getg2ir !> - 3 Error deallocating memory. !> !> @author Mark Iredell @date 1995-10-31 -subroutine getg2i2r(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) +subroutine getg2i2r(lugb, msk1, msk2, mnum, idxver, cbuf, nlen, nnum, nmess, iret) use re_alloc ! needed for subroutine realloc implicit none integer, intent(in) :: lugb integer (kind = 8), intent(in) :: msk1, msk2 - integer, intent(in) :: mnum + integer, intent(in) :: mnum, idxver character(len = 1), pointer, dimension(:) :: cbuf integer, intent(out) :: nlen, nnum, nmess, iret @@ -375,7 +377,7 @@ end subroutine ix2gb2 nmess = mnum do while(iret .eq. 0 .and. lgrib .gt. 0) lgrib4 = int(lgrib, kind(4)) - call ix2gb2(lugb, lskip, 1, lgrib4, cbuftmp, numfld, nbytes, iret1) + call ix2gb2(lugb, lskip, idxver, lgrib4, cbuftmp, numfld, nbytes, iret1) if (iret1 .ne. 0) print *, ' SAGT ', numfld, nbytes, iret1 if((nbytes + nlen) .gt. mbuf) then ! Allocate more space, if necessary. newsize = max(mbuf + next, mbuf + nbytes) From 07900a9d08a195e489a137ada12effc8705f8ba3 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 14:24:34 -0700 Subject: [PATCH 08/69] more --- src/g2index.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 427d3a5c..e0414c8f 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -39,7 +39,7 @@ !> - 90 Unit number out of range. !> - 96 Error reading/creating index file. !> -!> @author Stephen Gilbert @date 2005-03-15 +!> @author Stephen Gilbert, Ed Hartnett @date 2005-03-15 subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) implicit none From 56cdb8e2fa5bea5393643549161d81e6d6efd1bd Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Thu, 8 Feb 2024 07:28:12 -0700 Subject: [PATCH 09/69] more index changes --- src/g2index.F90 | 62 +++++++++++++------------- src/getgb2.F90 | 113 +++++++++++++++++++++++------------------------- 2 files changed, 86 insertions(+), 89 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index e0414c8f..03af907f 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -47,7 +47,7 @@ subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) integer, intent(out) :: nlen, nnum, iret character(len = 1), pointer, dimension(:) :: cindex integer, parameter :: maxidx = 10000 - integer, parameter :: msk1 = 32000, msk2 = 4000 + integer (kind = 8), parameter :: msk1 = 32000_8, msk2 = 4000_8 integer :: lux integer :: irgi, mskp, nmess, i @@ -69,12 +69,14 @@ subroutine getg2i(lugi, cbuf, nlen, nnum, iret) integer, intent(in) :: lugi integer, intent(out) :: nlen, nnum, iret end subroutine getg2i - subroutine getg2ir(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, & - nmess, iret) + subroutine getg2i2r(lugb, msk1, msk2, mnum, idxver, cbuf, & + nlen, nnum, nmess, iret) + integer, intent(in) :: lugb + integer (kind = 8), intent(in) :: msk1, msk2 + integer, intent(in) :: mnum, idxver character(len = 1), pointer, dimension(:) :: cbuf - integer, intent(in) :: lugb, msk1, msk2, mnum integer, intent(out) :: nlen, nnum, nmess, iret - end subroutine getg2ir + end subroutine getg2i2r end interface ! Free all associated memory and exit. @@ -135,7 +137,7 @@ end subroutine getg2ir call getg2i(lux, idxlist(lugb)%cbuf, nlen, nnum, irgi) elseif (lux .le. 0) then mskp = 0 - call getg2ir(lugb, msk1, msk2, mskp, idxlist(lugb)%cbuf, & + call getg2i2r(lugb, msk1, msk2, mskp, 1, idxlist(lugb)%cbuf, & nlen, nnum, nmess, irgi) endif if (irgi .eq. 0) then @@ -204,34 +206,34 @@ end subroutine getidx !> - 4 error reading index file header !> !> @author Mark Iredell @date 2000-05-26 -SUBROUTINE GETG2I(LUGI, CBUF, NLEN, NNUM, IRET) +subroutine getg2i(lugi, cbuf, nlen, nnum, iret) implicit none - CHARACTER(LEN=1), POINTER, DIMENSION(:) :: CBUF - INTEGER, INTENT(IN) :: LUGI - INTEGER, INTENT(OUT) :: NLEN, NNUM, IRET - CHARACTER CHEAD*162 + character(len=1), pointer, dimension(:) :: cbuf + integer, intent(in) :: lugi + integer, intent(out) :: nlen, nnum, iret + character chead*162 integer :: ios, istat, lbuf, lhead, nskp - NULLIFY(CBUF) - NLEN = 0 - NNUM = 0 - IRET = 4 - CALL BAREAD(LUGI, 0, 162, LHEAD, CHEAD) - IF (LHEAD .EQ. 162 .AND. CHEAD(42:47) .EQ. 'GB2IX1') THEN - READ(CHEAD(82:162), '(8X, 3I10, 2X, A40)', IOSTAT = IOS) NSKP, NLEN, NNUM - IF (IOS .EQ. 0) THEN - ALLOCATE(CBUF(NLEN), STAT = ISTAT) ! ALLOCATE SPACE FOR CBUF - IF (ISTAT .NE. 0) THEN - IRET = 2 - RETURN - ENDIF - IRET = 0 - CALL BAREAD(LUGI, NSKP, NLEN, LBUF, CBUF) - IF (LBUF .NE. NLEN) IRET = 3 - ENDIF - ENDIF -END SUBROUTINE GETG2I + nullify(cbuf) + nlen = 0 + nnum = 0 + iret = 4 + call baread(lugi, 0, 162, lhead, chead) + if (lhead .eq. 162 .and. chead(42:47) .eq. 'GB2IX1') then + read(chead(82:162), '(8x, 3i10, 2x, a40)', iostat = ios) nskp, nlen, nnum + if (ios .eq. 0) then + allocate(cbuf(nlen), stat = istat) ! Allocate space for cbuf. + if (istat .ne. 0) then + iret = 2 + return + endif + iret = 0 + call baread(lugi, nskp, nlen, lbuf, cbuf) + if (lbuf .ne. nlen) iret = 3 + endif + endif +end subroutine getg2i !> Generate an index record for a message in a GRIB2 file. !> diff --git a/src/getgb2.F90 b/src/getgb2.F90 index dc50f53c..04003858 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -34,30 +34,25 @@ !> call gf_finalize() after all library operations are complete. !> !> @note Specify an index file if feasible to increase speed. Do not -!> engage the same logical unit from more than one processor. Note -!> that derived type gribfield contains pointers to many arrays of -!> data. The memory for these arrays is allocated when the values in -!> the arrays are set, to help minimize problems with array -!> overloading. Because of this users should free this memory, when it -!> is no longer needed, by a call to subroutine gf_free(). +!> engage the same logical unit from more than one processor. !> -!> @param[in] LUGB integer unit of the unblocked grib data file. +!> @param[in] lugb integer unit of the unblocked grib data file. !> File must be opened with [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling !> this routine. -!> @param[in] LUGI integer unit of the unblocked grib index file. +!> @param[in] lugi integer unit of the unblocked grib index file. !> If nonzero, file must be opened with [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before -!> calling this routine. -!> - >0 read index from index file lugi, if index doesn"t already exist. -!> - =0 to get index buffer from the grib file, if index +!> calling this routine. lugi may be: +!> - > 0 read index from index file lugi, if index doesn"t already exist. +!> - = 0 to get index buffer from the grib file, if index !> doesn"t already exist. -!> - <0 force reread of index from index file abs(lugi). -!> - =lugb force regeneration of index from grib2 file lugb. -!> @param[in] J integer number of fields to skip -!> (=0 to search from beginning) -!> @param[in] JDISC grib2 discipline number of requested field -!> (if = -1, accept any discipline see code table 0.0) +!> - < 0 force reread of index from index file abs(lugi). +!> - = lugb force regeneration of index from GRIB2 file lugb. +!> @param[in] j integer number of fields to skip (0 to search from +!> beginning). +!> @param[in] jdisc GRIB2 discipline number of requested field: +!> --1 accept any discipline !> - 0 meteorological products !> - 1 hydrological products !> - 2 land surface products @@ -88,20 +83,20 @@ !> products; 3 control forecast products; 4 perturbed forecast products; !> 5 control and perturbed forecast products; 6 processed satellite !> observations; 7 processed radar observations. -!> @param[in] JPDTN integer product definition template number (n) +!> @param[in] jpdtn integer product definition template number (n) !> (if = -1, don't bother matching pdt - accept any) !> @param[in] JPDT integer array of values defining the product definition !> template 4.n of the field for which to search (=-9999 for wildcard) -!> @param[in] JGDTN integer grid definition template number (m) +!> @param[in] jgdtn integer grid definition template number (m) !> (if = -1, don't bother matching gdt - accept any ) !> @param[in] JGDT integer array of values defining the grid definition !> template 3.m of the field for which to search (=-9999 for wildcard) -!> @param[in] UNPACK logical value indicating whether to unpack bitmap/data +!> @param[in] unpack logical value indicating whether to unpack bitmap/data !> - .TRUE. unpack bitmap and data values !> - .FALSE. do not unpack bitmap and data values -!> @param[out] K integer field number unpacked -!> @param[out] GFLD derived type @ref grib_mod::gribfield. -!> @param[out] IRET integer return code +!> @param[out] k integer field number unpacked +!> @param[out] gfld derived type @ref grib_mod::gribfield. +!> @param[out] iret integer return code !> - 0 all ok !> - 96 error reading index !> - 97 error reading grib file @@ -109,51 +104,51 @@ !> - other gf_getfld grib2 unpacker return code !> !> @author Mark Iredell @date 1994-04-01 -SUBROUTINE GETGB2(LUGB, LUGI, J, JDISC, JIDS, JPDTN, JPDT, JGDTN, JGDT, & - UNPACK, K, GFLD, IRET) - USE GRIB_MOD +subroutine getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + use grib_mod implicit none - INTEGER, INTENT(IN) :: LUGB, LUGI, J, JDISC, JPDTN, JGDTN - INTEGER, DIMENSION(:) :: JIDS(*), JPDT(*), JGDT(*) - LOGICAL, INTENT(IN) :: UNPACK - INTEGER, INTENT(OUT) :: K, IRET - TYPE(GRIBFIELD), INTENT(OUT) :: GFLD - CHARACTER(LEN = 1), POINTER, DIMENSION(:) :: CBUF + integer, intent(in) :: lugb, lugi, j, jdisc, jpdtn, jgdtn + integer, dimension(:) :: jids(*), jpdt(*), jgdt(*) + logical, intent(in) :: unpack + integer, intent(out) :: k, iret + type(gribfield), intent(out) :: gfld + character(len = 1), pointer, dimension(:) :: cbuf integer :: nnum, nlen, lpos, jk, irgi, irgs ! Declare interfaces (required for cbuf pointer). - INTERFACE - SUBROUTINE GETIDX(LUGB, LUGI, CBUF, NLEN, NNUM, IRGI) - CHARACTER(LEN = 1), POINTER, DIMENSION(:) :: CBUF - INTEGER, INTENT(IN) :: LUGB, LUGI - INTEGER, INTENT(OUT) :: NLEN, NNUM, IRGI - END SUBROUTINE GETIDX - END INTERFACE + interface + subroutine getidx(lugb, lugi, cbuf, nlen, nnum, irgi) + character(len = 1), pointer, dimension(:) :: cbuf + integer, intent(in) :: lugb, lugi + integer, intent(out) :: nlen, nnum, irgi + end subroutine getidx + end interface ! Determine whether index buffer needs to be initialized. - IRGI = 0 - CALL GETIDX(LUGB, LUGI, CBUF, NLEN, NNUM, IRGI) - IF (IRGI .GT. 1) THEN - IRET = 96 - RETURN - ENDIF + irgi = 0 + call getidx(lugb, lugi, cbuf, nlen, nnum, irgi) + if (irgi .gt. 1) then + iret = 96 + return + endif - ! Search index buffer. - CALL GETGB2S(CBUF, NLEN, NNUM, J, JDISC, JIDS, JPDTN, JPDT, JGDTN, JGDT, JK, & - GFLD, LPOS, IRGS) - IF (IRGS .NE. 0) THEN - IRET = 99 - CALL GF_FREE(GFLD) - RETURN - ENDIF + ! search index buffer. + call getgb2s(cbuf, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, jk, & + gfld, lpos, irgs) + if (irgs .ne. 0) then + iret = 99 + call gf_free(gfld) + return + endif ! Read local use section, if available. - CALL GETGB2L(LUGB, CBUF(LPOS), GFLD, IRET) + call getgb2l(lugb, cbuf(lpos), gfld, iret) ! Read and unpack grib record. - IF (UNPACK) THEN - CALL GETGB2R(LUGB, CBUF(LPOS), GFLD, IRET) - ENDIF - K = JK -END SUBROUTINE GETGB2 + if (unpack) then + call getgb2r(lugb, cbuf(lpos), gfld, iret) + endif + k = jk +end subroutine getgb2 From fd288eec53fd8d0fbf58523838b5b84bb10fb806 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Thu, 8 Feb 2024 07:47:08 -0700 Subject: [PATCH 10/69] more index changes --- src/g2index.F90 | 108 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 18 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 03af907f..9a7ed6b4 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -2,10 +2,11 @@ !> @brief Subroutines for dealing with indexes. !> @author Edward Hartnett @date Jan 31, 2024 -!> Find, read or generate a GRIB2 index for a GRIB2 file. +!> Find, read or generate a version 1 GRIB2 index for a GRIB2 file +!> (which must be < 2 GB). !> !> If the index already exists in library memory, it is returned, -!> otherwise, the index is read from an existing indexfile associated +!> otherwise, the index is read from an existing index file associated !> with unit lugi or generated from the GRIB2 file lugb. !> !> Users can force a regeneration of an index: if lugi equals lugb, @@ -44,11 +45,73 @@ subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) implicit none integer, intent(in) :: lugb, lugi + character(len = 1), pointer, dimension(:) :: cindex integer, intent(out) :: nlen, nnum, iret + + interface + subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + integer, intent(in) :: lugb, lugi, idxver + character(len = 1), pointer, dimension(:) :: cindex + integer, intent(out) :: nlen, nnum, iret + end subroutine getidx2 + end interface + + ! When getidx() is called, always use index version 1. Call + ! getidx2() for a chance to set the index version. + call getidx2(lugb, lugi, 1, cindex, nlen, nnum, iret) + +end subroutine getidx + +!> Find, read or generate a version 1 or 2 GRIB2 index for a GRIB2 +!> file (which may be > 2 GB). +!> +!> If the index already exists in library memory, it is returned, +!> otherwise, the index is read from an existing index file associated +!> with unit lugi or generated from the GRIB2 file lugb. +!> +!> Users can force a regeneration of an index: if lugi equals lugb, +!> the index will be regenerated from the data in file lugb. If lugi +!> is less than zero, then the index is re-read from index file +!> abs(lugi). +!> +!> This subroutine allocates memory and stores the resulting pointers +!> in an array that is a Fortran "save" variable. The result is that +!> the memory will not be freed by the library and cannot be reached +!> by the caller. To free this memory call gf_finalize() after all +!> library operations are complete. +!> +!> @note The file unit numbers must be in range 1 - 9999. +!> +!> @param[in] lugb integer unit of the GRIB2 data file. File must +!> have been opened with [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this +!> routine. If 0, then all saved memory will be released (necessary +!> for g2_finalize()). +!> @param[in] lugi integer unit of the GRIB2 index file. +!> If nonzero, file must have been opened with [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before +!> calling this routine. Set to 0 to get index information from the GRIB2 file. +!> @param[in] idxver Index version, 1 for legacy, 2 if files may be > 2 GB. +!> index records. +!> @param[inout] cindex character*1 Pointer to a buffer that will get +!> index records. +!> @param[out] nlen integer Total length of all index records. +!> @param[out] nnum integer Number of index records. +!> @param[out] iret integer Return code: +!> - 0 No error. +!> - 90 Unit number out of range. +!> - 96 Error reading/creating index file. +!> +!> @author Stephen Gilbert, Ed Hartnett @date 2005-03-15 +subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + implicit none + + integer, intent(in) :: lugb, lugi, idxver character(len = 1), pointer, dimension(:) :: cindex + integer, intent(out) :: nlen, nnum, iret + integer, parameter :: maxidx = 10000 integer (kind = 8), parameter :: msk1 = 32000_8, msk2 = 4000_8 - integer :: lux integer :: irgi, mskp, nmess, i @@ -93,7 +156,7 @@ end subroutine getg2i2r return endif - ! determine whether index buffer needs to be initialized + ! Determine whether index buffer needs to be initialized. lux = 0 iret = 0 if (lugb .le. 0 .or. lugb .gt. 9999) then @@ -102,7 +165,9 @@ end subroutine getg2i2r iret = 90 return endif - if (lugi .eq. lugb) then ! force regeneration of index from grib2 file + + ! Force regeneration of index from GRIB2 file. + if (lugi .eq. lugb) then if (associated(idxlist(lugb)%cbuf)) & deallocate(idxlist(lugb)%cbuf) !print *, 'Force regeneration' @@ -112,7 +177,8 @@ end subroutine getg2i2r lux = 0 endif - if (lugi .lt. 0) then ! force re-read of index from indexfile + ! Force re-read of index from indexfile. + if (lugi .lt. 0) then ! associated with unit abs(lugi) if (associated(idxlist(lugb)%cbuf)) & deallocate(idxlist(lugb)%cbuf) @@ -123,7 +189,7 @@ end subroutine getg2i2r lux = abs(lugi) endif - ! check if index already exists in memory + ! Check if index already exists in memory. if (associated(idxlist(lugb)%cbuf)) then !print *, 'Index exists in memory!' cindex => idxlist(lugb)%cbuf @@ -132,26 +198,32 @@ end subroutine getg2i2r return endif + ! Either read index record from index file, or generate it from the + ! GRIB2 file. irgi = 0 if (lux .gt. 0) then call getg2i(lux, idxlist(lugb)%cbuf, nlen, nnum, irgi) elseif (lux .le. 0) then mskp = 0 - call getg2i2r(lugb, msk1, msk2, mskp, 1, idxlist(lugb)%cbuf, & + call getg2i2r(lugb, msk1, msk2, mskp, idxver, idxlist(lugb)%cbuf, & nlen, nnum, nmess, irgi) endif - if (irgi .eq. 0) then - cindex => idxlist(lugb)%cbuf - idxlist(lugb)%nlen = nlen - idxlist(lugb)%nnum = nnum - else + + ! Handle errors. + if (irgi .ne. 0) then nlen = 0 nnum = 0 print *, ' error reading index file ' iret = 96 return endif -end subroutine getidx + + ! Fill these values. + cindex => idxlist(lugb)%cbuf + idxlist(lugb)%nlen = nlen + idxlist(lugb)%nnum = nnum + +end subroutine getidx2 !> Read a GRIB2 index file and return its contents. !> @@ -986,10 +1058,10 @@ subroutine gf_finalize(iret) ! Declare interfaces (required for cbuf pointer). interface - subroutine getidx(lugb,lugi,cbuf,nlen,nnum,irgi) - character(len=1),pointer,dimension(:) :: cbuf - integer,intent(in) :: lugb,lugi - integer,intent(out) :: nlen,nnum,irgi + subroutine getidx(lugb, lugi, cbuf, nlen, nnum, irgi) + character(len = 1), pointer, dimension(:) :: cbuf + integer, intent(in) :: lugb, lugi + integer, intent(out) :: nlen, nnum, irgi end subroutine getidx end interface From 014b00eb86645c876279dfe24cb0babb941f56b6 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Thu, 8 Feb 2024 08:07:49 -0700 Subject: [PATCH 11/69] more index changes --- src/g2index.F90 | 304 ++++++++++++++++++++++++------------------------ 1 file changed, 154 insertions(+), 150 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 9a7ed6b4..3967a1b6 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -557,19 +557,19 @@ end subroutine getg2i2r !> - other gf_getfld GRIB2 unpacker return code. !> !> @author Stephen Gilbert @date 2002-01-15 -SUBROUTINE GETGB2S(CBUF, NLEN, NNUM, J, JDISC, JIDS, JPDTN, JPDT, JGDTN, & - JGDT, K, GFLD, LPOS, IRET) - USE GRIB_MOD +subroutine getgb2s(cbuf, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & + jgdt, k, gfld, lpos, iret) + use grib_mod implicit none - CHARACTER(LEN = 1), INTENT(IN) :: CBUF(NLEN) - INTEGER, INTENT(IN) :: NLEN, NNUM, J, JDISC, JPDTN, JGDTN - INTEGER, DIMENSION(:) :: JIDS(*), JPDT(*), JGDT(*) - INTEGER, INTENT(OUT) :: K, LPOS, IRET - TYPE(GRIBFIELD), INTENT(OUT) :: GFLD + character(len = 1), intent(in) :: cbuf(nlen) + integer, intent(in) :: nlen, nnum, j, jdisc, jpdtn, jgdtn + integer, dimension(:) :: jids(*), jpdt(*), jgdt(*) + integer, intent(out) :: k, lpos, iret + type(gribfield), intent(out) :: gfld - INTEGER :: KGDS(5) - LOGICAL :: MATCH1, MATCH3, MATCH4 + integer :: kgds(5) + logical :: match1, match3, match4 integer :: i, icnd, inlen, iof, ipos, jpos, lsec1, lsec3, lsec4, lsec5, numgdt, numpdt interface @@ -610,155 +610,159 @@ subroutine gf_unpack5(cgrib, lcgrib, iofst, ndpts, idrsnum, & end subroutine gf_unpack5 end interface - ! INITIALIZE - K = 0 - LPOS = 0 - IRET = 1 - IPOS = 0 + ! Initialize. + k = 0 + lpos = 0 + iret = 1 + ipos = 0 nullify(gfld%idsect, gfld%local) nullify(gfld%list_opt, gfld%igdtmpl, gfld%ipdtmpl) nullify(gfld%coord_list, gfld%idrtmpl, gfld%bmap, gfld%fld) - ! SEARCH FOR REQUEST - DO WHILE(IRET.NE.0 .and. K.LT.NNUM) - K = K + 1 - CALL G2_GBYTEC(CBUF, INLEN, IPOS * 8, 4 * 8) ! GET LENGTH OF CURRENT - ! INDEX RECORD - IF (K.LE.J) THEN ! SKIP THIS INDEX - IPOS = IPOS + INLEN - CYCLE - ENDIF + ! Search for request. + do while(iret.ne.0 .and. k.lt.nnum) + k = k + 1 + ! Get length of current index record. + call g2_gbytec(cbuf, inlen, ipos * 8, 4 * 8) + if (k.le.j) then ! skip this index + ipos = ipos + inlen + cycle + endif - ! CHECK IF GRIB2 DISCIPLINE IS A MATCH - CALL G2_GBYTEC(CBUF, GFLD%DISCIPLINE, (IPOS + 41)*8, 1*8) - IF ((JDISC.NE.-1) .and. (JDISC.NE.GFLD%DISCIPLINE)) THEN - IPOS = IPOS + INLEN - CYCLE - ENDIF + ! Check if grib2 discipline is a match. + call g2_gbytec(cbuf, gfld%discipline, (ipos + 41) * 8, 1 * 8) + if (jdisc .ne. -1 .and. jdisc .ne. gfld%discipline) then + ipos = ipos + inlen + cycle + endif + + ! Check if identification section is a match. + match1 = .false. + ! Get length of ids. + call g2_gbytec(cbuf, lsec1, (ipos + 44) * 8, 4 * 8) + iof = 0 + call gf_unpack1(cbuf(ipos + 45), lsec1, iof, gfld%idsect, gfld%idsectlen, icnd) + if (icnd .eq. 0) then + match1 = .true. + do i = 1, gfld%idsectlen + if (jids(i) .ne. -9999 .and. jids(i) .ne. gfld%idsect(i)) then + match1 = .false. + exit + endif + enddo + endif + if (.not. match1) then + deallocate(gfld%idsect) + ipos = ipos + inlen + cycle + endif - ! CHECK IF IDENTIFICATION SECTION IS A MATCH - MATCH1 = .FALSE. - CALL G2_GBYTEC(CBUF, LSEC1, (IPOS + 44) * 8, 4 * 8) ! GET LENGTH OF IDS - IOF = 0 - CALL GF_UNPACK1(CBUF(IPOS + 45), LSEC1, IOF, GFLD%IDSECT, GFLD%IDSECTLEN, ICND) - IF (ICND .eq. 0) THEN - MATCH1 = .TRUE. - DO I = 1, GFLD%IDSECTLEN - IF ((JIDS(I).NE.-9999) .and. (JIDS(I).NE.GFLD%IDSECT(I))) THEN - MATCH1 = .FALSE. - EXIT - ENDIF - ENDDO - ENDIF - IF (.NOT. MATCH1) THEN - DEALLOCATE(GFLD%IDSECT) - IPOS = IPOS + INLEN - CYCLE - ENDIF + ! Check if grid definition template is a match. + jpos = ipos + 44 + lsec1 + match3 = .false. + call g2_gbytec(cbuf, lsec3, jpos * 8, 4 * 8) ! get length of gds + if (jgdtn .eq. -1) then + match3 = .true. + else + call g2_gbytec(cbuf, numgdt, (jpos + 12) * 8, 2 * 8) ! get gdt template no. + if (jgdtn .eq. numgdt) then + iof = 0 + call gf_unpack3(cbuf(jpos + 1), lsec3, iof, kgds, gfld%igdtmpl, & + gfld%igdtlen, gfld%list_opt, gfld%num_opt, icnd) + if (icnd .eq. 0) then + match3 = .true. + do i = 1, gfld%igdtlen + if (jgdt(i) .ne. -9999 .and. jgdt(i).ne.gfld%igdtmpl(i)) then + match3 = .false. + exit + endif + enddo + endif + endif + endif + if (.not. match3) then + if (associated(gfld%idsect)) deallocate(gfld%idsect) + if (associated(gfld%igdtmpl)) deallocate(gfld%igdtmpl) + if (associated(gfld%list_opt)) deallocate(gfld%list_opt) + ipos = ipos + inlen + cycle + else + gfld%griddef = kgds(1) + gfld%ngrdpts = kgds(2) + gfld%numoct_opt = kgds(3) + gfld%interp_opt = kgds(4) + gfld%igdtnum = kgds(5) + endif - ! CHECK IF GRID DEFINITION TEMPLATE IS A MATCH - JPOS = IPOS + 44 + LSEC1 - MATCH3 = .FALSE. - CALL G2_GBYTEC(CBUF, LSEC3, JPOS * 8, 4 * 8) ! GET LENGTH OF GDS - IF (JGDTN .eq. -1) THEN - MATCH3 = .TRUE. - ELSE - CALL G2_GBYTEC(CBUF, NUMGDT, (JPOS + 12) * 8, 2 * 8) ! GET GDT TEMPLATE NO. - IF (JGDTN .eq. NUMGDT) THEN - IOF = 0 - CALL GF_UNPACK3(CBUF(JPOS + 1), LSEC3, IOF, KGDS, GFLD%IGDTMPL, & - GFLD%IGDTLEN, GFLD%LIST_OPT, GFLD%NUM_OPT, ICND) - IF (ICND .eq. 0) THEN - MATCH3 = .TRUE. - DO I = 1, GFLD%IGDTLEN - IF ((JGDT(I).NE.-9999) .and. (JGDT(I).NE.GFLD%IGDTMPL(I))) THEN - MATCH3 = .FALSE. - EXIT - ENDIF - ENDDO - ENDIF - ENDIF - ENDIF - IF (.NOT. MATCH3) THEN - IF (ASSOCIATED(GFLD%IDSECT)) DEALLOCATE(GFLD%IDSECT) - IF (ASSOCIATED(GFLD%IGDTMPL)) DEALLOCATE(GFLD%IGDTMPL) - IF (ASSOCIATED(GFLD%LIST_OPT)) DEALLOCATE(GFLD%LIST_OPT) - IPOS = IPOS + INLEN - CYCLE - ELSE - GFLD%GRIDDEF = KGDS(1) - GFLD%NGRDPTS = KGDS(2) - GFLD%NUMOCT_OPT = KGDS(3) - GFLD%INTERP_OPT = KGDS(4) - GFLD%IGDTNUM = KGDS(5) - ENDIF + ! Check if product definition template is a match. + jpos = jpos + lsec3 + match4 = .false. - ! CHECK IF PRODUCT DEFINITION TEMPLATE IS A MATCH - JPOS = JPOS + LSEC3 - MATCH4 = .FALSE. - CALL G2_GBYTEC(CBUF, LSEC4, JPOS * 8, 4 * 8) ! GET LENGTH OF PDS - IF (JPDTN .eq. -1) THEN - MATCH4 = .TRUE. - ELSE - CALL G2_GBYTEC(CBUF, NUMPDT, (JPOS + 7) * 8, 2 * 8) ! GET PDT TEMPLATE NO. - IF (JPDTN .eq. NUMPDT) THEN - IOF = 0 - CALL GF_UNPACK4(CBUF(JPOS + 1), LSEC4, IOF, GFLD%IPDTNUM, & - GFLD%IPDTMPL, GFLD%IPDTLEN, GFLD%COORD_LIST, GFLD%NUM_COORD, ICND) - IF (ICND .eq. 0) THEN - MATCH4 = .TRUE. - DO I = 1, GFLD%IPDTLEN - IF ((JPDT(I).NE.-9999) .and. (JPDT(I).NE.GFLD%IPDTMPL(I))) THEN - MATCH4 = .FALSE. - EXIT - ENDIF - ENDDO - ENDIF - ENDIF - ENDIF - IF (.NOT. MATCH4) THEN - IF (ASSOCIATED(GFLD%IDSECT)) DEALLOCATE(GFLD%IDSECT) - IF (ASSOCIATED(GFLD%IPDTMPL)) DEALLOCATE(GFLD%IPDTMPL) - IF (ASSOCIATED(GFLD%COORD_LIST)) DEALLOCATE(GFLD%COORD_LIST) - ENDIF + ! Get length of pds. + call g2_gbytec(cbuf, lsec4, jpos * 8, 4 * 8) + if (jpdtn .eq. -1) then + match4 = .true. + else + ! Get pdt template no. + call g2_gbytec(cbuf, numpdt, (jpos + 7) * 8, 2 * 8) + if (jpdtn .eq. numpdt) then + iof = 0 + call gf_unpack4(cbuf(jpos + 1), lsec4, iof, gfld%ipdtnum, & + gfld%ipdtmpl, gfld%ipdtlen, gfld%coord_list, gfld%num_coord, icnd) + if (icnd .eq. 0) then + match4 = .true. + do i = 1, gfld%ipdtlen + if (jpdt(i) .ne. -9999 .and. jpdt(i) .ne. gfld%ipdtmpl(i)) then + match4 = .false. + exit + endif + enddo + endif + endif + endif + if (.not. match4) then + if (associated(gfld%idsect)) deallocate(gfld%idsect) + if (associated(gfld%ipdtmpl)) deallocate(gfld%ipdtmpl) + if (associated(gfld%coord_list)) deallocate(gfld%coord_list) + endif - ! IF REQUEST IS FOUND - ! SET VALUES FOR DERIVED TYPE GFLD AND RETURN - IF(MATCH1 .and. MATCH3 .and. MATCH4) THEN - LPOS = IPOS + 1 - CALL G2_GBYTEC(CBUF, GFLD%VERSION, (IPOS + 40) * 8, 1 * 8) - CALL G2_GBYTEC(CBUF, GFLD%IFLDNUM, (IPOS + 42) * 8, 2 * 8) - GFLD%UNPACKED = .FALSE. - JPOS = IPOS + 44 + LSEC1 - IF (JGDTN.EQ.-1) THEN ! UNPACK GDS, IF NOT DONE BEFORE - IOF = 0 - CALL GF_UNPACK3(CBUF(JPOS + 1), LSEC3, IOF, KGDS, GFLD%IGDTMPL, & - GFLD%IGDTLEN, GFLD%LIST_OPT, GFLD%NUM_OPT, ICND) - GFLD%GRIDDEF = KGDS(1) - GFLD%NGRDPTS = KGDS(2) - GFLD%NUMOCT_OPT = KGDS(3) - GFLD%INTERP_OPT = KGDS(4) - GFLD%IGDTNUM = KGDS(5) - ENDIF - JPOS = JPOS + LSEC3 - IF (JPDTN.EQ.-1 ) THEN ! UNPACK PDS, IF NOT DONE BEFORE - IOF = 0 - CALL GF_UNPACK4(CBUF(JPOS + 1), LSEC4, IOF, GFLD%IPDTNUM, & - GFLD%IPDTMPL, GFLD%IPDTLEN, GFLD%COORD_LIST, GFLD%NUM_COORD, ICND) - ENDIF - JPOS = JPOS + LSEC4 - CALL G2_GBYTEC(CBUF, LSEC5, JPOS * 8, 4 * 8) ! GET LENGTH OF DRS - IOF = 0 - CALL GF_UNPACK5(CBUF(JPOS + 1), LSEC5, IOF, GFLD%NDPTS, & - GFLD%IDRTNUM, GFLD%IDRTMPL, GFLD%IDRTLEN, ICND) - JPOS = JPOS + LSEC5 - CALL G2_GBYTEC(CBUF, GFLD%IBMAP, (JPOS + 5)*8, 1 * 8) ! GET IBMAP - IRET = 0 - ELSE ! PDT DID NOT MATCH - IPOS = IPOS+INLEN - ENDIF - ENDDO -END SUBROUTINE GETGB2S + ! if request is found + ! set values for derived type gfld and return + if (match1 .and. match3 .and. match4) then + lpos = ipos + 1 + call g2_gbytec(cbuf, gfld%version, (ipos + 40) * 8, 1 * 8) + call g2_gbytec(cbuf, gfld%ifldnum, (ipos + 42) * 8, 2 * 8) + gfld%unpacked = .false. + jpos = ipos + 44 + lsec1 + if (jgdtn .eq. -1) then ! unpack gds, if not done before + iof = 0 + call gf_unpack3(cbuf(jpos + 1), lsec3, iof, kgds, gfld%igdtmpl, & + gfld%igdtlen, gfld%list_opt, gfld%num_opt, icnd) + gfld%griddef = kgds(1) + gfld%ngrdpts = kgds(2) + gfld%numoct_opt = kgds(3) + gfld%interp_opt = kgds(4) + gfld%igdtnum = kgds(5) + endif + jpos = jpos + lsec3 + if (jpdtn .eq. -1) then ! unpack pds, if not done before + iof = 0 + call gf_unpack4(cbuf(jpos + 1), lsec4, iof, gfld%ipdtnum, & + gfld%ipdtmpl, gfld%ipdtlen, gfld%coord_list, gfld%num_coord, icnd) + endif + jpos = jpos + lsec4 + call g2_gbytec(cbuf, lsec5, jpos * 8, 4 * 8) ! get length of drs + iof = 0 + call gf_unpack5(cbuf(jpos + 1), lsec5, iof, gfld%ndpts, & + gfld%idrtnum, gfld%idrtmpl, gfld%idrtlen, icnd) + jpos = jpos + lsec5 + call g2_gbytec(cbuf, gfld%ibmap, (jpos + 5)*8, 1 * 8) ! get ibmap + iret = 0 + else ! pdt did not match + ipos = ipos+inlen + endif + enddo +end subroutine getgb2s !> Generate an index record for each field in a GRIB2 message. The index !> records are written to index buffer pointed to by cbuf. All integers From ee4841d2ea5c691fb96b6ebb361f640074215069 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Thu, 8 Feb 2024 08:27:58 -0700 Subject: [PATCH 12/69] more index work --- src/g2index.F90 | 154 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 139 insertions(+), 15 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 3967a1b6..29a9ffa4 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -563,14 +563,132 @@ subroutine getgb2s(cbuf, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & implicit none character(len = 1), intent(in) :: cbuf(nlen) - integer, intent(in) :: nlen, nnum, j, jdisc, jpdtn, jgdtn - integer, dimension(:) :: jids(*), jpdt(*), jgdt(*) - integer, intent(out) :: k, lpos, iret + integer, intent(in) :: nlen, nnum, j, jdisc + integer, dimension(:) :: jids(*) + integer, intent(in) :: jpdtn + integer, dimension(:) :: jpdt(*) + integer, intent(in) :: jgdtn + integer, dimension(:) :: jgdt(*) + integer, intent(out) :: k type(gribfield), intent(out) :: gfld + integer, intent(out) :: lpos, iret + + interface + subroutine getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & + jgdt, k, gfld, lpos, iret) + import gribfield + character(len = 1), intent(in) :: cbuf(nlen) + integer, intent(in) :: idxver, nlen, nnum, j, jdisc + integer, dimension(:) :: jids(*) + integer, intent(in) :: jpdtn + integer, dimension(:) :: jpdt(*) + integer, intent(in) :: jgdtn + integer, dimension(:) :: jgdt(*) + integer, intent(out) :: k + type(gribfield), intent(out) :: gfld + integer, intent(out) :: lpos, iret + end subroutine getgb2s2 + end interface + + ! When getgb2s() is called, always use index version 1. Call + ! getgb2s2() to handle version 1 or 2. + call getgb2s2(cbuf, 1, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & + jgdt, k, gfld, lpos, iret) + +end subroutine getgb2s + +!> Find information about a GRIB field from the index and fill a @ref +!> grib_mod::gribfield. +!> +!> For a description of the index record see getg2i(). +!> +!> Users of this routine will need to include the line "use grib_mod" +!> in their calling routine. +!> +!> The unpacked bitmap and bitmap data field are the only components +!> of the @ref grib_mod::gribfield type not set by this routine. +!> +!> @note This subprogram is intended for private use by getgb2() +!> routines only. Note that derived type @ref grib_mod::gribfield contains +!> pointers to many arrays of data. The memory for these arrays is +!> allocated when the values in the arrays are set. Users must free this +!> memory, when it is no longer needed, by a call to subroutine +!> gf_free(). +!> +!> @param[in] cbuf Buffer (of size nlen bytes) containing index data. +!> @param[in] idxver Index version, 1 for legacy, 2 if files may be > 2 GB. +!> @param[in] nlen Total length of all index records. +!> @param[in] nnum Number of index records. +!> @param[in] j Number of fields to skip (0 to search from beginning). +!> @param[in] jdisc GRIB2 discipline number of requested field. See +!> [GRIB2 - TABLE 0.0 - +!> DISCIPLINE](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml). +!> Use -1 to accept any discipline. +!> @param[in] jids Array of values in the identification +!> section. (Set to -9999 for wildcard.) +!> - jids(1) Identification of originating centre. See [TABLE 0 - +!> NATIONAL/INTERNATIONAL ORIGINATING +!> CENTERS](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html). +!> - jids(2) Identification of originating sub-centre. See [TABLE C - +!> NATIONAL +!> SUB-CENTERS](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html). +!> - jids(3) GRIB master tables version number. See [GRIB2 - TABLE 1.0 +!> - GRIB Master Tables Version +!> Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml). +!> - jids(4) GRIB local tables version number. See [GRIB2 - TABLE 1.1 +!> - GRIB Local Tables Version +!> Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml). +!> - jids(5) Significance of reference time. See [GRIB2 - TABLE 1.2 - +!> Significance of Reference +!> Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml). +!> - jids(6) year (4 digits) +!> - jids(7) month +!> - jids(8) day +!> - jids(9) hour +!> - jids(10) minute +!> - jids(11) second +!> - jids(12) Production status of processed data. See [GRIB2 - TABLE +!> 1.3 - Production Status of +!> Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml). +!> - jids(13) Type of processed data. See [GRIB2 - TABLE 1.4 - TYPE OF +!> DATA](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml). +!> @param[in] jpdtn Product Definition Template (PDT) number (n) +!> (if = -1, don't bother matching PDT - accept any). +!> @param[in] jpdt Array of values defining the Product Definition +!> Template of the field for which to search (=-9999 for wildcard). +!> @param[in] jgdtn Grid Definition Template (GDT) number (if = -1, +!> don't bother matching GDT - accept any). +!> @param[in] jgdt array of values defining the Grid Definition +!> Template of the field for which to search (=-9999 for wildcard). +!> @param[out] k Field number unpacked. +!> @param[out] gfld Derived type @ref grib_mod::gribfield. +!> @param[out] lpos Starting position of the found index record +!> within the complete index buffer, CBUF. = 0, if request not found. +!> @param[out] iret integer return code: +!> - 0 No error. +!> - 97 Error reading GRIB file. +!> - other gf_getfld GRIB2 unpacker return code. +!> +!> @author Stephen Gilbert @date 2002-01-15 +subroutine getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & + jgdt, k, gfld, lpos, iret) + use grib_mod + implicit none + + character(len = 1), intent(in) :: cbuf(nlen) + integer, intent(in) :: idxver, nlen, nnum, j, jdisc + integer, dimension(:) :: jids(*) + integer, intent(in) :: jpdtn + integer, dimension(:) :: jpdt(*) + integer, intent(in) :: jgdtn + integer, dimension(:) :: jgdt(*) + integer, intent(out) :: k + type(gribfield), intent(out) :: gfld + integer, intent(out) :: lpos, iret integer :: kgds(5) logical :: match1, match3, match4 - integer :: i, icnd, inlen, iof, ipos, jpos, lsec1, lsec3, lsec4, lsec5, numgdt, numpdt + integer :: i, icnd, inlen, iof, ipos, jpos, lsec1, lsec3, lsec4, lsec5, numgdt, numpdt, inc interface subroutine gf_unpack1(cgrib, lcgrib, iofst, ids, idslen, ierr) @@ -618,6 +736,13 @@ end subroutine gf_unpack5 nullify(gfld%idsect, gfld%local) nullify(gfld%list_opt, gfld%igdtmpl, gfld%ipdtmpl) nullify(gfld%coord_list, gfld%idrtmpl, gfld%bmap, gfld%fld) + if (idxver .eq. 1) then + inc = 0 + else + ! Add the extra 4 bytes in the version 2 index record, starting + ! at byte 9. + inc = 4 + endif ! Search for request. do while(iret.ne.0 .and. k.lt.nnum) @@ -630,7 +755,7 @@ end subroutine gf_unpack5 endif ! Check if grib2 discipline is a match. - call g2_gbytec(cbuf, gfld%discipline, (ipos + 41) * 8, 1 * 8) + call g2_gbytec(cbuf, gfld%discipline, (ipos + inc + 41) * 8, 1 * 8) if (jdisc .ne. -1 .and. jdisc .ne. gfld%discipline) then ipos = ipos + inlen cycle @@ -639,7 +764,7 @@ end subroutine gf_unpack5 ! Check if identification section is a match. match1 = .false. ! Get length of ids. - call g2_gbytec(cbuf, lsec1, (ipos + 44) * 8, 4 * 8) + call g2_gbytec(cbuf, lsec1, (ipos + inc + 44) * 8, 4 * 8) iof = 0 call gf_unpack1(cbuf(ipos + 45), lsec1, iof, gfld%idsect, gfld%idsectlen, icnd) if (icnd .eq. 0) then @@ -658,7 +783,7 @@ end subroutine gf_unpack5 endif ! Check if grid definition template is a match. - jpos = ipos + 44 + lsec1 + jpos = ipos + 44 + inc + lsec1 match3 = .false. call g2_gbytec(cbuf, lsec3, jpos * 8, 4 * 8) ! get length of gds if (jgdtn .eq. -1) then @@ -726,14 +851,13 @@ end subroutine gf_unpack5 if (associated(gfld%coord_list)) deallocate(gfld%coord_list) endif - ! if request is found - ! set values for derived type gfld and return + ! If request is found set values for derived type gfld and return. if (match1 .and. match3 .and. match4) then lpos = ipos + 1 - call g2_gbytec(cbuf, gfld%version, (ipos + 40) * 8, 1 * 8) - call g2_gbytec(cbuf, gfld%ifldnum, (ipos + 42) * 8, 2 * 8) + call g2_gbytec(cbuf, gfld%version, (ipos + inc + 40) * 8, 1 * 8) + call g2_gbytec(cbuf, gfld%ifldnum, (ipos + inc + 42) * 8, 2 * 8) gfld%unpacked = .false. - jpos = ipos + 44 + lsec1 + jpos = ipos + 44 + inc + lsec1 if (jgdtn .eq. -1) then ! unpack gds, if not done before iof = 0 call gf_unpack3(cbuf(jpos + 1), lsec3, iof, kgds, gfld%igdtmpl, & @@ -756,13 +880,13 @@ end subroutine gf_unpack5 call gf_unpack5(cbuf(jpos + 1), lsec5, iof, gfld%ndpts, & gfld%idrtnum, gfld%idrtmpl, gfld%idrtlen, icnd) jpos = jpos + lsec5 - call g2_gbytec(cbuf, gfld%ibmap, (jpos + 5)*8, 1 * 8) ! get ibmap + call g2_gbytec(cbuf, gfld%ibmap, (jpos + 5) * 8, 1 * 8) ! get ibmap iret = 0 else ! pdt did not match - ipos = ipos+inlen + ipos = ipos + inlen endif enddo -end subroutine getgb2s +end subroutine getgb2s2 !> Generate an index record for each field in a GRIB2 message. The index !> records are written to index buffer pointed to by cbuf. All integers From 68a0f33fb57b181a5c1124c56e23a614226710bb Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Thu, 8 Feb 2024 08:32:17 -0700 Subject: [PATCH 13/69] more index work --- src/getgb2.F90 | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/getgb2.F90 b/src/getgb2.F90 index 04003858..9a1c9f08 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -119,23 +119,37 @@ subroutine getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & ! Declare interfaces (required for cbuf pointer). interface - subroutine getidx(lugb, lugi, cbuf, nlen, nnum, irgi) - character(len = 1), pointer, dimension(:) :: cbuf - integer, intent(in) :: lugb, lugi - integer, intent(out) :: nlen, nnum, irgi - end subroutine getidx + subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + integer, intent(in) :: lugb, lugi, idxver + character(len = 1), pointer, dimension(:) :: cindex + integer, intent(out) :: nlen, nnum, iret + end subroutine getidx2 + subroutine getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & + jgdt, k, gfld, lpos, iret) + import gribfield + character(len = 1), intent(in) :: cbuf(nlen) + integer, intent(in) :: idxver, nlen, nnum, j, jdisc + integer, dimension(:) :: jids(*) + integer, intent(in) :: jpdtn + integer, dimension(:) :: jpdt(*) + integer, intent(in) :: jgdtn + integer, dimension(:) :: jgdt(*) + integer, intent(out) :: k + type(gribfield), intent(out) :: gfld + integer, intent(out) :: lpos, iret + end subroutine getgb2s2 end interface ! Determine whether index buffer needs to be initialized. irgi = 0 - call getidx(lugb, lugi, cbuf, nlen, nnum, irgi) + call getidx2(lugb, lugi, 1, cbuf, nlen, nnum, irgi) if (irgi .gt. 1) then iret = 96 return endif ! search index buffer. - call getgb2s(cbuf, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, jk, & + call getgb2s2(cbuf, 1, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, jk, & gfld, lpos, irgs) if (irgs .ne. 0) then iret = 99 From aa92f1c5de1a6aeb33bf53088e2b1f54fd706dc6 Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 8 Feb 2024 14:16:28 -0700 Subject: [PATCH 14/69] documentation update --- src/g2index.F90 | 105 ++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 67 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 29a9ffa4..e7a85204 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -225,7 +225,7 @@ end subroutine getg2i2r end subroutine getidx2 -!> Read a GRIB2 index file and return its contents. +!> Read a version 1 or 2 index file and return its contents. !> !> The index file may be generated by the grb2index utility of the !> [NCEPLIBS-grib_util](https://github.com/NOAA-EMC/NCEPLIBS-grib_util) @@ -233,31 +233,35 @@ end subroutine getidx2 !> !> The index file has two header records: !> 1. an 81-byte header with 'GB2IX1' in columns 42-47 -!> 2. an 81-byte header with number of bytes to skip before index -!> records, total length in bytes of the index records, number of -!> index records, and GRIB file basename written in format -!> ('IX1FORM:',3i10,2x,a40). +!> 2. an 81-byte header with the index version number, the number of +!> bytes to skip before index records, total length in bytes of the +!> index records, number of index records, and the GRIB file basename. !> !> Each record in the index table contains the following fields. All -!> integers are in big-endian format in the file. +!> integers are in big-endian format in the file. The only difference +!> between index version 1 and index version 2 is the size of the +!> field containing the number of bytes to skip in file before +!> message. To accomodate files > 2 GB, this must be a 64-bit int. !> -!> - byte 001 - 004 length of index record -!> - byte 005 - 008 bytes to skip in data file before grib message -!> - byte 009 - 012 bytes to skip in message before lus (local use) set = 0, if no local section. -!> - byte 013 - 016 bytes to skip in message before gds -!> - byte 017 - 020 bytes to skip in message before pds -!> - byte 021 - 024 bytes to skip in message before drs -!> - byte 025 - 028 bytes to skip in message before bms -!> - byte 029 - 032 bytes to skip in message before data section -!> - byte 033 - 040 bytes total in the message -!> - byte 041 - 041 grib version number (currently 2) -!> - byte 042 - 042 message discipline -!> - byte 043 - 044 field number within grib2 message -!> - byte 045 - ii identification section (ids) -!> - byte ii+1- jj grid definition section (gds) -!> - byte jj+1- kk product definition section (pds) -!> - byte kk+1- ll the data representation section (drs) -!> - byte ll+1-ll+6 first 6 bytes of the bit map section (bms) +!> Index Version 1 | Index Version 2 | Contents +!> ----------------|-----------------|--------- +!> 001 - 004 | 001 - 004 | length of index record +!> 005 - 008 | 005 - 012 | bytes to skip in data file before grib message +!> 009 - 012 | 013 - 016 | bytes to skip in message before lus (local use) set = 0, if no local section. +!> 013 - 016 | 017 - 020 | bytes to skip in message before gds +!> 017 - 020 | 021 - 024 | bytes to skip in message before pds +!> 021 - 024 | 025 - 028 | bytes to skip in message before drs +!> 025 - 028 | 029 - 032 | bytes to skip in message before bms +!> 029 - 032 | 033 - 036 | bytes to skip in message before data section +!> 033 - 040 | 037 - 044 | bytes total in the message +!> 041 - 041 | 045 - 045 | grib version number (always 2) +!> 042 - 042 | 046 - 046 | message discipline +!> 043 - 044 | 047 - 048 | field number within grib2 message +!> 045 - ii | 045 - ii | identification section (ids) +!> ii+1- jj | ii+1- jj | grid definition section (gds) +!> jj+1- kk | jj+1- kk | product definition section (pds) +!> kk+1- ll | kk+1- ll | the data representation section (drs) +!> ll+1-ll+6 | ll+1-ll+6 | first 6 bytes of the bit map section (bms) !> !> @note Subprogram can be called from a multiprocessing environment. !> Do not engage the same logical unit from more than one processor. @@ -888,32 +892,15 @@ end subroutine gf_unpack5 enddo end subroutine getgb2s2 -!> Generate an index record for each field in a GRIB2 message. The index -!> records are written to index buffer pointed to by cbuf. All integers -!> in the index are in big-endian format. +!> Generate a version 1 index record for each field in a GRIB2 message. +!> +!> The index records are written to index buffer pointed to by +!> cbuf. All integers in the index are in big-endian format. !> !> This subroutine is called by getg2ir(), which packages the index !> records into an index file. !> -!> The index buffer returned contains index records with the -!> format: -!> - byte 001 - 004 length of index record -!> - byte 005 - 008 bytes to skip in data file before GRIB message -!> - byte 009 - 012 bytes to skip in message before lus (local use) set = 0, if no local section. -!> - byte 013 - 016 bytes to skip in message before gds -!> - byte 017 - 020 bytes to skip in message before pds -!> - byte 021 - 024 bytes to skip in message before drs -!> - byte 025 - 028 bytes to skip in message before bms -!> - byte 029 - 032 bytes to skip in message before data section -!> - byte 033 - 040 bytes total in the message -!> - byte 041 - 041 GRIB version number (2) -!> - byte 042 - 042 message discipline -!> - byte 043 - 044 field number within GRIB2 message -!> - byte 045 - ii identification section (ids) -!> - byte ii + 1- jj grid definition section (gds) -!> - byte jj + 1- kk product definition section (pds) -!> - byte kk + 1- ll the data representation section (drs) -!> - byte ll + 1-ll + 6 first 6 bytes of the bit map section (bms) +!> See getg2i() for thr format of the index buffer records. !> !> @param lugb Unit of the unblocked GRIB file. Must !> be opened by [baopen() or baopenr()] @@ -962,32 +949,16 @@ end subroutine ix2gb2 call ix2gb2(lugb, lskip8, 1, lgrib, cbuf, numfld, mlen, iret) end subroutine ixgb2 -!> Generate an index record for each field in a GRIB2 message. The index -!> records are written to index buffer pointed to by cbuf. All integers -!> in the index are in big-endian format. +!> Generate a version 1 or 2 index record for each field in a GRIB2 +!> message. +!> +!> The index records are written to index buffer pointed to by +!> cbuf. All integers in the index are in big-endian format. !> !> This subroutine is called by getg2ir(), which packages the index !> records into an index file. !> -!> The index buffer returned contains index records with the -!> format: -!> - byte 001 - 004 length of index record -!> - byte 005 - 008 bytes to skip in data file before GRIB message -!> - byte 009 - 012 bytes to skip in message before lus (local use) set = 0, if no local section. -!> - byte 013 - 016 bytes to skip in message before gds -!> - byte 017 - 020 bytes to skip in message before pds -!> - byte 021 - 024 bytes to skip in message before drs -!> - byte 025 - 028 bytes to skip in message before bms -!> - byte 029 - 032 bytes to skip in message before data section -!> - byte 033 - 040 bytes total in the message -!> - byte 041 - 041 GRIB version number (2) -!> - byte 042 - 042 message discipline -!> - byte 043 - 044 field number within GRIB2 message -!> - byte 045 - ii identification section (ids) -!> - byte ii + 1- jj grid definition section (gds) -!> - byte jj + 1- kk product definition section (pds) -!> - byte kk + 1- ll the data representation section (drs) -!> - byte ll + 1-ll + 6 first 6 bytes of the bit map section (bms) +!> See getg2i() for thr format of the index buffer records. !> !> @param lugb Unit of the unblocked GRIB file. Must !> be opened by [baopen() or baopenr()] From e1bca4eaccf6530f5f2dc6397a931d974a3c5e3e Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 8 Feb 2024 14:29:23 -0700 Subject: [PATCH 15/69] more index work --- src/g2index.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index e7a85204..f3271a7c 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1014,6 +1014,8 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) mxds = 4, mxlen = 4, mxfld = 2, mxbms = 6) character cbread(linmax), cindex(linmax) character cids(linmax), cgds(linmax) + integer :: INT1_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT4_BITS = 32, INT8_BITS = 64) loclus = 0 iret = 0 @@ -1055,8 +1057,8 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) iret = 2 return endif - call g2_gbytec(cbread, lensec, 0 * 8, 4 * 8) - call g2_gbytec(cbread, numsec, 4 * 8, 1 * 8) + call g2_gbytec(cbread, lensec, 0, INT4_BITS) + call g2_gbytec(cbread, numsec, INT4_BITS, INT1_BITS) if (numsec .eq. 2) then ! save local use location loclus = int(ibskip8 - lskip8, kind(4)) From 035484970101ac38c25882577780aac9c9fc47d8 Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 8 Feb 2024 14:31:06 -0700 Subject: [PATCH 16/69] more index work --- src/g2index.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index f3271a7c..4fb737ff 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1075,9 +1075,9 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) cindex = char(0) if (idxver .eq. 1) then lskip = int(lskip8, kind(4)) - call g2_sbytec(cindex, lskip, 8 * ixskp, 8 * mxskp) ! bytes to skip + call g2_sbytec(cindex, lskip, INT4_BITS, INT4_BITS) ! bytes to skip else - call g2_sbytec8(cindex, lskip8, 8 * ixskp, 8 * mxskp) ! bytes to skip + call g2_sbytec8(cindex, lskip8, INT4_BITS, INT8_BITS) ! bytes to skip endif call g2_sbytec(cindex, loclus, 8 * ixlus, 8 * mxlus) ! location of local use call g2_sbytec(cindex, locgds, 8 * ixsgd, 8 * mxsgd) ! location of gds From 3d6dc5c19bf5822f8299e77569ed71ff11d23703 Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 8 Feb 2024 14:32:39 -0700 Subject: [PATCH 17/69] more index work --- src/g2index.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 4fb737ff..bcbcfddf 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1079,10 +1079,10 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) else call g2_sbytec8(cindex, lskip8, INT4_BITS, INT8_BITS) ! bytes to skip endif - call g2_sbytec(cindex, loclus, 8 * ixlus, 8 * mxlus) ! location of local use - call g2_sbytec(cindex, locgds, 8 * ixsgd, 8 * mxsgd) ! location of gds - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixspd, 8 * mxspd) ! location of pds - call g2_sbytec(cindex, lgrib, 8 * ixlen, 8 * mxlen) ! len of grib2 + call g2_sbytec(cindex, loclus, 8 * ixlus, INT4_BITS) ! location of local use + call g2_sbytec(cindex, locgds, 8 * ixsgd, INT4_BITS) ! location of gds + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixspd, INT4_BITS) ! location of pds + call g2_sbytec(cindex, lgrib, 8 * ixlen, INT4_BITS) ! len of grib2 cindex(41) = cver cindex(42) = cdisc call g2_sbytec(cindex, numfld + 1, 8 * ixfld, 8 * mxfld) ! field num From 7431200d7e9ff3f5fd8df9be874063a4fef4c226 Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 8 Feb 2024 14:35:36 -0700 Subject: [PATCH 18/69] more index work --- src/g2index.F90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index bcbcfddf..f5970c7a 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1014,8 +1014,8 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) mxds = 4, mxlen = 4, mxfld = 2, mxbms = 6) character cbread(linmax), cindex(linmax) character cids(linmax), cgds(linmax) - integer :: INT1_BITS, INT4_BITS, INT8_BITS - parameter(INT1_BITS = 8, INT4_BITS = 32, INT8_BITS = 64) + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) loclus = 0 iret = 0 @@ -1085,7 +1085,7 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) call g2_sbytec(cindex, lgrib, 8 * ixlen, INT4_BITS) ! len of grib2 cindex(41) = cver cindex(42) = cdisc - call g2_sbytec(cindex, numfld + 1, 8 * ixfld, 8 * mxfld) ! field num + call g2_sbytec(cindex, numfld + 1, 8 * ixfld, INT2_BITS) ! field num cindex(ixids + 1:ixids + lensec1) = cids(1:lensec1) lindex = ixids + lensec1 cindex(lindex + 1:lindex + lengds8) = cgds(1:lengds8) @@ -1099,7 +1099,7 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) endif lindex = lindex + ilnpds elseif (numsec .eq. 5) then ! found drs - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsdr, 8 * mxsdr) ! location of drs + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsdr, INT4_BITS) ! location of drs ilndrs = lensec ilndrs8 = ilndrs call bareadl(lugb, ibskip8, ilndrs8, lbread8, cindex(lindex + 1)) @@ -1112,17 +1112,17 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) indbmp = mova2i(cbread(6)) if (indbmp.lt.254) then locbms = int(ibskip8 - lskip8, kind(4)) - call g2_sbytec(cindex, locbms, 8 * ixsbm, 8 * mxsbm) ! loc. of bms + call g2_sbytec(cindex, locbms, 8 * ixsbm, INT4_BITS) ! loc. of bms elseif (indbmp.eq.254) then - call g2_sbytec(cindex, locbms, 8 * ixsbm, 8 * mxsbm) ! loc. of bms + call g2_sbytec(cindex, locbms, 8 * ixsbm, INT4_BITS) ! loc. of bms elseif (indbmp.eq.255) then - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsbm, 8 * mxsbm) ! loc. of bms + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsbm, INT4_BITS) ! loc. of bms endif cindex(lindex + 1:lindex + mxbms) = cbread(1:mxbms) lindex = lindex + mxbms call g2_sbytec(cindex, lindex, 0, 8 * 4) ! num bytes in index record elseif (numsec .eq. 7) then ! found data section - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixds, 8 * mxds) ! loc. of data sec. + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixds, INT4_BITS) ! loc. of data sec. numfld = numfld + 1 if ((lindex + mlen) .gt. mbuf) then ! allocate more space if necessary newsize = max(mbuf + next, mbuf + lindex) From 6f0a3b96ea37d6cce12e39180fab424d89dca596 Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 8 Feb 2024 14:38:37 -0700 Subject: [PATCH 19/69] more index work --- src/g2index.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index f5970c7a..2e65ffac 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1016,6 +1016,7 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) character cids(linmax), cgds(linmax) integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) + integer :: mypos loclus = 0 iret = 0 @@ -1042,7 +1043,7 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) endif cver = cbread(8) cdisc = cbread(7) - call g2_gbytec(cbread, lensec1, 16 * 8, 4 * 8) + call g2_gbytec(cbread, lensec1, 16 * 8, INT4_BITS) lensec1 = min(lensec1, int(ibread8, kind(lensec1))) cids(1:lensec1) = cbread(17:16 + lensec1) ibskip8 = lskip8 + 16_8 + int(lensec1, kind(8)) From 994170347d635a42af913f47d40ac8410ba4a269 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Fri, 9 Feb 2024 05:35:07 -0700 Subject: [PATCH 20/69] more index work --- src/g2index.F90 | 71 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 2e65ffac..0a459417 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -225,6 +225,60 @@ end subroutine getg2i2r end subroutine getidx2 +!> Read a version 1 index file and return its contents. +!> +!> The index file may be generated by the grb2index utility of the +!> [NCEPLIBS-grib_util](https://github.com/NOAA-EMC/NCEPLIBS-grib_util) +!> project. +!> +!> For the contents of the index file, see getgi2(). +!> +!> This subroutine is maintained for backward compatibility, and may +!> only be used with version 1 of the index files. To handle both +!> version 1 and 2 index files, use getg2i2(). +!> +!> @param[in] lugi Integer unit of the GRIB index file. Must be opened +!> by [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/). +!> @param[out] cbuf Pointer to a buffer that will get the index +!> records. Memory will be allocated within this function, so callers +!> must free the memory that cbuf points to, using deallocate(cbuf) +!> when cbuf is no longer needed. +!> @param[out] nlen Total length of all index records. +!> @param[out] nnum Number of index records. +!> @param[out] iret Return code. +!> - 0 No error. +!> - 2 not enough memory to hold index buffer +!> - 3 error reading index file buffer +!> - 4 error reading index file header +!> - 5 index format 2 detected +!> +!> @author Mark Iredell @date 2000-05-26 +subroutine getg2i(lugi, cbuf, nlen, nnum, iret) + implicit none + + integer, intent(in) :: lugi + character(len=1), pointer, dimension(:) :: cbuf + integer, intent(out) :: nlen, nnum, iret + integer :: idxver + + interface + subroutine getg2i2(lugi, cbuf, idxver, nlen, nnum, iret) + integer, intent(in) :: lugi + character(len=1), pointer, dimension(:) :: cbuf + integer, intent(out) :: idxver, nlen, nnum, iret + end subroutine getg2i2 + end interface + + ! Call the version of this subroutine that handles version 1 and + ! version 2. If getg2i() is called on a version 2 index, return + ! error. + call getg2i2(lugi, cbuf, idxver, nlen, nnum, iret) + if (idxver .eq. 2) iret = 5 + +end subroutine getg2i + + !> Read a version 1 or 2 index file and return its contents. !> !> The index file may be generated by the grb2index utility of the @@ -273,6 +327,7 @@ end subroutine getidx2 !> records. Memory will be allocated within this function, so callers !> must free the memory that cbuf points to, using deallocate(cbuf) !> when cbuf is no longer needed. +!> @param[out] idxver Index version of this index, will be 1 or 2. !> @param[out] nlen Total length of all index records. !> @param[out] nnum Number of index records. !> @param[out] iret Return code. @@ -281,13 +336,14 @@ end subroutine getidx2 !> - 3 error reading index file buffer !> - 4 error reading index file header !> -!> @author Mark Iredell @date 2000-05-26 -subroutine getg2i(lugi, cbuf, nlen, nnum, iret) +!> @author Ed Hartnett, Mark Iredell @date Feb 9, 2024 +subroutine getg2i2(lugi, cbuf, idxver, nlen, nnum, iret) implicit none - character(len=1), pointer, dimension(:) :: cbuf integer, intent(in) :: lugi - integer, intent(out) :: nlen, nnum, iret + character(len=1), pointer, dimension(:) :: cbuf + integer, intent(out) :: idxver, nlen, nnum, iret + character chead*162 integer :: ios, istat, lbuf, lhead, nskp @@ -297,7 +353,8 @@ subroutine getg2i(lugi, cbuf, nlen, nnum, iret) iret = 4 call baread(lugi, 0, 162, lhead, chead) if (lhead .eq. 162 .and. chead(42:47) .eq. 'GB2IX1') then - read(chead(82:162), '(8x, 3i10, 2x, a40)', iostat = ios) nskp, nlen, nnum +! read(chead(82:162), '(8x, 3i10, 2x, a40)', iostat = ios) nskp, nlen, nnum + read(chead(82:162), '(2x, i1, 5x, 3i10, 2x, a40)', iostat = ios) idxver, nskp, nlen, nnum if (ios .eq. 0) then allocate(cbuf(nlen), stat = istat) ! Allocate space for cbuf. if (istat .ne. 0) then @@ -309,7 +366,7 @@ subroutine getg2i(lugi, cbuf, nlen, nnum, iret) if (lbuf .ne. nlen) iret = 3 endif endif -end subroutine getg2i +end subroutine getg2i2 !> Generate an index record for a message in a GRIB2 file. !> @@ -439,7 +496,7 @@ end subroutine ix2gb2 return endif - ! search for first grib message. + ! Search for first grib message. iseek = 0_8 call skgb8(lugb, iseek, msk1, lskip, lgrib) do m = 1, mnum From 6919c6121fb18f6d6ab1ec3126a16fc3f0469726 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Fri, 9 Feb 2024 05:42:45 -0700 Subject: [PATCH 21/69] more index progress --- src/g2index.F90 | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 0a459417..0cff4101 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -39,6 +39,7 @@ !> - 0 No error. !> - 90 Unit number out of range. !> - 96 Error reading/creating index file. +!> - 97 Index version 2 detected. !> !> @author Stephen Gilbert, Ed Hartnett @date 2005-03-15 subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) @@ -47,10 +48,12 @@ subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) integer, intent(in) :: lugb, lugi character(len = 1), pointer, dimension(:) :: cindex integer, intent(out) :: nlen, nnum, iret + integer :: idxver interface subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) - integer, intent(in) :: lugb, lugi, idxver + integer, intent(in) :: lugb, lugi + integer, intent(inout) :: idxver character(len = 1), pointer, dimension(:) :: cindex integer, intent(out) :: nlen, nnum, iret end subroutine getidx2 @@ -58,7 +61,11 @@ end subroutine getidx2 ! When getidx() is called, always use index version 1. Call ! getidx2() for a chance to set the index version. - call getidx2(lugb, lugi, 1, cindex, nlen, nnum, iret) + idxver = 1 + call getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + + ! If index version 2 is being used, return error. + if (iret .eq. 0 .and. idxver .eq. 2) iret = 97 end subroutine getidx @@ -106,7 +113,8 @@ end subroutine getidx subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) implicit none - integer, intent(in) :: lugb, lugi, idxver + integer, intent(in) :: lugb, lugi + integer, intent(inout) :: idxver character(len = 1), pointer, dimension(:) :: cindex integer, intent(out) :: nlen, nnum, iret @@ -127,11 +135,11 @@ subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) ! declare interfaces (required for cbuf pointer) interface - subroutine getg2i(lugi, cbuf, nlen, nnum, iret) - character(len = 1), pointer, dimension(:) :: cbuf + subroutine getg2i2(lugi, cbuf, idxver, nlen, nnum, iret) integer, intent(in) :: lugi - integer, intent(out) :: nlen, nnum, iret - end subroutine getg2i + character(len=1), pointer, dimension(:) :: cbuf + integer, intent(out) :: idxver, nlen, nnum, iret + end subroutine getg2i2 subroutine getg2i2r(lugb, msk1, msk2, mnum, idxver, cbuf, & nlen, nnum, nmess, iret) integer, intent(in) :: lugb @@ -202,7 +210,7 @@ end subroutine getg2i2r ! GRIB2 file. irgi = 0 if (lux .gt. 0) then - call getg2i(lux, idxlist(lugb)%cbuf, nlen, nnum, irgi) + call getg2i2(lux, idxlist(lugb)%cbuf, idxver, nlen, nnum, irgi) elseif (lux .le. 0) then mskp = 0 call getg2i2r(lugb, msk1, msk2, mskp, idxver, idxlist(lugb)%cbuf, & From cb2df9782c06dbe592d9d039428ef42469b40a5e Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Fri, 9 Feb 2024 06:25:09 -0700 Subject: [PATCH 22/69] more progress --- src/g2index.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 0cff4101..c1a40125 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -557,7 +557,7 @@ end subroutine getg2i2r !> Find information about a GRIB field from the index and fill a @ref !> grib_mod::gribfield. !> -!> For a description of the index record see getg2i(). +!> For a description of the index record see getg2i2(). !> !> Users of this routine will need to include the line "use grib_mod" !> in their calling routine. @@ -669,7 +669,7 @@ end subroutine getgb2s !> Find information about a GRIB field from the index and fill a @ref !> grib_mod::gribfield. !> -!> For a description of the index record see getg2i(). +!> For a description of the index record see getg2i2(). !> !> Users of this routine will need to include the line "use grib_mod" !> in their calling routine. @@ -965,7 +965,7 @@ end subroutine getgb2s2 !> This subroutine is called by getg2ir(), which packages the index !> records into an index file. !> -!> See getg2i() for thr format of the index buffer records. +!> See getg2i2() for thr format of the index buffer records. !> !> @param lugb Unit of the unblocked GRIB file. Must !> be opened by [baopen() or baopenr()] @@ -1023,7 +1023,7 @@ end subroutine ixgb2 !> This subroutine is called by getg2ir(), which packages the index !> records into an index file. !> -!> See getg2i() for thr format of the index buffer records. +!> See getg2i2() for thr format of the index buffer records. !> !> @param lugb Unit of the unblocked GRIB file. Must !> be opened by [baopen() or baopenr()] From 16f2561c825a72cd9251cf6f92810a1e7e82a978 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Fri, 9 Feb 2024 06:39:28 -0700 Subject: [PATCH 23/69] more index work --- src/g2index.F90 | 5 ++++- src/getgb2.F90 | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index c1a40125..89765feb 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -121,11 +121,12 @@ subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) integer, parameter :: maxidx = 10000 integer (kind = 8), parameter :: msk1 = 32000_8, msk2 = 4000_8 integer :: lux - integer :: irgi, mskp, nmess, i + integer :: irgi, mskp, nmess, i, myidxver type gindex integer :: nlen integer :: nnum + integer :: idxver character(len = 1), pointer, dimension(:) :: cbuf end type gindex @@ -203,6 +204,7 @@ end subroutine getg2i2r cindex => idxlist(lugb)%cbuf nlen = idxlist(lugb)%nlen nnum = idxlist(lugb)%nnum + idxver = idxlist(lugb)%idxver return endif @@ -230,6 +232,7 @@ end subroutine getg2i2r cindex => idxlist(lugb)%cbuf idxlist(lugb)%nlen = nlen idxlist(lugb)%nnum = nnum + idxlist(lugb)%idxver = idxver end subroutine getidx2 diff --git a/src/getgb2.F90 b/src/getgb2.F90 index 9a1c9f08..67f2690f 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -115,7 +115,7 @@ subroutine getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & integer, intent(out) :: k, iret type(gribfield), intent(out) :: gfld character(len = 1), pointer, dimension(:) :: cbuf - integer :: nnum, nlen, lpos, jk, irgi, irgs + integer :: nnum, nlen, lpos, jk, irgi, irgs, idxver ! Declare interfaces (required for cbuf pointer). interface @@ -142,14 +142,15 @@ end subroutine getgb2s2 ! Determine whether index buffer needs to be initialized. irgi = 0 - call getidx2(lugb, lugi, 1, cbuf, nlen, nnum, irgi) + idxver = 1 + call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, irgi) if (irgi .gt. 1) then iret = 96 return endif ! search index buffer. - call getgb2s2(cbuf, 1, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, jk, & + call getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, jk, & gfld, lpos, irgs) if (irgs .ne. 0) then iret = 99 From 6e968e822adb279518befb153fa5b4896b3d40eb Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Fri, 9 Feb 2024 07:03:07 -0700 Subject: [PATCH 24/69] more index work --- src/g2index.F90 | 53 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 89765feb..d528095b 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1084,7 +1084,15 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) character cids(linmax), cgds(linmax) integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) - integer :: mypos + integer :: mypos, inc + + if (idxver .eq. 1) then + inc = 0 + else + ! Add the extra 4 bytes in the version 2 index record, starting + ! at byte 9. + inc = 4 + endif loclus = 0 iret = 0 @@ -1142,19 +1150,29 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) locgds = int(ibskip8 - lskip8, kind(4)) elseif (numsec .eq. 4) then ! found pds cindex = char(0) + mypos = INT4_BITS if (idxver .eq. 1) then lskip = int(lskip8, kind(4)) - call g2_sbytec(cindex, lskip, INT4_BITS, INT4_BITS) ! bytes to skip + call g2_sbytec(cindex, lskip, mypos, INT4_BITS) ! bytes to skip + mypos = mypos + INT4_BITS else - call g2_sbytec8(cindex, lskip8, INT4_BITS, INT8_BITS) ! bytes to skip + call g2_sbytec8(cindex, lskip8, mypos, INT8_BITS) ! bytes to skip + mypos = mypos + INT8_BITS endif - call g2_sbytec(cindex, loclus, 8 * ixlus, INT4_BITS) ! location of local use - call g2_sbytec(cindex, locgds, 8 * ixsgd, INT4_BITS) ! location of gds - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixspd, INT4_BITS) ! location of pds - call g2_sbytec(cindex, lgrib, 8 * ixlen, INT4_BITS) ! len of grib2 - cindex(41) = cver - cindex(42) = cdisc - call g2_sbytec(cindex, numfld + 1, 8 * ixfld, INT2_BITS) ! field num + call g2_sbytec(cindex, loclus, mypos, INT4_BITS) ! location of local use + mypos = mypos + INT4_BITS + call g2_sbytec(cindex, locgds, mypos, INT4_BITS) ! location of gds + mypos = mypos + INT4_BITS + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), mypos, INT4_BITS) ! location of pds + mypos = mypos + INT4_BITS * 5 ! skip ahead in cbuf + call g2_sbytec(cindex, lgrib, mypos, INT4_BITS) ! len of grib2 + mypos = mypos + INT4_BITS + cindex(int(mypos / 8) + 1) = cver + mypos = mypos + INT1_BITS + cindex(int(mypos / 8) + 1) = cdisc + mypos = mypos + INT1_BITS + call g2_sbytec(cindex, numfld + 1, mypos, INT2_BITS) ! field num + mypos = mypos + INT2_BITS cindex(ixids + 1:ixids + lensec1) = cids(1:lensec1) lindex = ixids + lensec1 cindex(lindex + 1:lindex + lengds8) = cgds(1:lengds8) @@ -1168,7 +1186,8 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) endif lindex = lindex + ilnpds elseif (numsec .eq. 5) then ! found drs - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsdr, INT4_BITS) ! location of drs + mypos = (ixsdr + inc) * INT1_BITS + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), mypos, INT4_BITS) ! location of drs ilndrs = lensec ilndrs8 = ilndrs call bareadl(lugb, ibskip8, ilndrs8, lbread8, cindex(lindex + 1)) @@ -1179,19 +1198,21 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) lindex = lindex + ilndrs elseif (numsec .eq. 6) then ! found bms indbmp = mova2i(cbread(6)) + mypos = (ixsbm + inc) * INT1_BITS if (indbmp.lt.254) then locbms = int(ibskip8 - lskip8, kind(4)) - call g2_sbytec(cindex, locbms, 8 * ixsbm, INT4_BITS) ! loc. of bms + call g2_sbytec(cindex, locbms, mypos, INT4_BITS) ! loc. of bms elseif (indbmp.eq.254) then - call g2_sbytec(cindex, locbms, 8 * ixsbm, INT4_BITS) ! loc. of bms + call g2_sbytec(cindex, locbms, mypos, INT4_BITS) ! loc. of bms elseif (indbmp.eq.255) then - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixsbm, INT4_BITS) ! loc. of bms + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), mypos, INT4_BITS) ! loc. of bms endif cindex(lindex + 1:lindex + mxbms) = cbread(1:mxbms) lindex = lindex + mxbms - call g2_sbytec(cindex, lindex, 0, 8 * 4) ! num bytes in index record + call g2_sbytec(cindex, lindex, 0, INT4_BITS) ! num bytes in index record elseif (numsec .eq. 7) then ! found data section - call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), 8 * ixds, INT4_BITS) ! loc. of data sec. + mypos = (ixds + inc) * INT1_BITS + call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), mypos, INT4_BITS) ! loc. of data sec. numfld = numfld + 1 if ((lindex + mlen) .gt. mbuf) then ! allocate more space if necessary newsize = max(mbuf + next, mbuf + lindex) From 36e282887f58c95ac7067ffc8d24fdbcef61fb0a Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Fri, 9 Feb 2024 08:27:09 -0700 Subject: [PATCH 25/69] documentation fix --- src/g2index.F90 | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index d528095b..06e57b9d 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -109,7 +109,7 @@ end subroutine getidx !> - 90 Unit number out of range. !> - 96 Error reading/creating index file. !> -!> @author Stephen Gilbert, Ed Hartnett @date 2005-03-15 +!> @author Stephen Gilbert, Ed Hartnett @date Feb 9, 2024 subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) implicit none @@ -264,7 +264,7 @@ end subroutine getidx2 !> - 4 error reading index file header !> - 5 index format 2 detected !> -!> @author Mark Iredell @date 2000-05-26 +!> @author Mark Iredell, Ed Hartnett @date 2000-05-26 subroutine getg2i(lugi, cbuf, nlen, nnum, iret) implicit none @@ -288,7 +288,6 @@ end subroutine getg2i2 if (idxver .eq. 2) iret = 5 end subroutine getg2i - !> Read a version 1 or 2 index file and return its contents. !> @@ -410,7 +409,7 @@ end subroutine getg2i2 !> - 2 Not enough memory to allocate initial index buffer. !> - 3 Error deallocating memory. !> -!> @author Mark Iredell @date 1995-10-31 +!> @author Mark Iredell, Ed Hartnett @date 1995-10-31 subroutine getg2ir(lugb, msk1, msk2, mnum, cbuf, nlen, nnum, nmess, iret) use re_alloc ! needed for subroutine realloc implicit none @@ -470,7 +469,7 @@ end subroutine getg2ir !> - 2 Not enough memory to allocate initial index buffer. !> - 3 Error deallocating memory. !> -!> @author Mark Iredell @date 1995-10-31 +!> @author Mark Iredell, Ed Hartnett @date 1995-10-31 subroutine getg2i2r(lugb, msk1, msk2, mnum, idxver, cbuf, nlen, nnum, nmess, iret) use re_alloc ! needed for subroutine realloc implicit none @@ -628,7 +627,7 @@ end subroutine getg2i2r !> - 97 Error reading GRIB file. !> - other gf_getfld GRIB2 unpacker return code. !> -!> @author Stephen Gilbert @date 2002-01-15 +!> @author Stephen Gilbert, Ed Hartnett @date 2002-01-15 subroutine getgb2s(cbuf, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & jgdt, k, gfld, lpos, iret) use grib_mod @@ -741,7 +740,7 @@ end subroutine getgb2s !> - 97 Error reading GRIB file. !> - other gf_getfld GRIB2 unpacker return code. !> -!> @author Stephen Gilbert @date 2002-01-15 +!> @author Stephen Gilbert, Ed Hartnett @date Feb 9 2024 subroutine getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & jgdt, k, gfld, lpos, iret) use grib_mod @@ -992,7 +991,7 @@ end subroutine getgb2s2 !> - 4 Not enough memory to allocate extent to index buffer. !> - 5 Unidentified GRIB section encountered. !> -!> @author Mark Iredell @date 1995-10-31 +!> @author Mark Iredell, Ed Hartnett @date 1995-10-31 subroutine ixgb2(lugb, lskip, lgrib, cbuf, numfld, mlen, iret) use re_alloc ! needed for subroutine realloc implicit none From 7df56722ba9ca4050be1614e72493bd2884bbdd6 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sun, 11 Feb 2024 05:25:39 -0700 Subject: [PATCH 26/69] more index work --- src/g2index.F90 | 6 +++--- src/getgb2.F90 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 06e57b9d..b20e8cf6 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -510,7 +510,7 @@ end subroutine ix2gb2 iseek = 0_8 call skgb8(lugb, iseek, msk1, lskip, lgrib) do m = 1, mnum - if(lgrib.gt.0) then + if (lgrib .gt. 0) then iseek = lskip + lgrib call skgb8(lugb, iseek, msk2, lskip, lgrib) endif @@ -520,7 +520,7 @@ end subroutine ix2gb2 nlen = 0 nnum = 0 nmess = mnum - do while(iret .eq. 0 .and. lgrib .gt. 0) + do while (iret .eq. 0 .and. lgrib .gt. 0) lgrib4 = int(lgrib, kind(4)) call ix2gb2(lugb, lskip, idxver, lgrib4, cbuftmp, numfld, nbytes, iret1) if (iret1 .ne. 0) print *, ' SAGT ', numfld, nbytes, iret1 @@ -539,7 +539,7 @@ end subroutine ix2gb2 if (associated(cbuftmp)) then cbuf(nlen + 1 : nlen + nbytes) = cbuftmp(1 : nbytes) deallocate(cbuftmp, stat = istat) - if (istat.ne.0) then + if (istat .ne. 0) then print *, ' deallocating cbuftmp ... ', istat iret = 3 return diff --git a/src/getgb2.F90 b/src/getgb2.F90 index 67f2690f..74c4c1b7 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -142,7 +142,7 @@ end subroutine getgb2s2 ! Determine whether index buffer needs to be initialized. irgi = 0 - idxver = 1 + idxver = 2 call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, irgi) if (irgi .gt. 1) then iret = 96 From 1a707bfd6c0f14f2e3e3608cea3246b3288954d1 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sun, 11 Feb 2024 05:52:45 -0700 Subject: [PATCH 27/69] working on index testing --- src/g2index.F90 | 2 +- tests/test_getidx.F90 | 117 +++++++++++++++++++++++------------------- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index b20e8cf6..9f606abd 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -820,7 +820,7 @@ end subroutine gf_unpack5 k = k + 1 ! Get length of current index record. call g2_gbytec(cbuf, inlen, ipos * 8, 4 * 8) - if (k.le.j) then ! skip this index + if (k .le. j) then ! skip this index ipos = ipos + inlen cycle endif diff --git a/tests/test_getidx.F90 b/tests/test_getidx.F90 index 3ac16e28..3a660832 100644 --- a/tests/test_getidx.F90 +++ b/tests/test_getidx.F90 @@ -21,7 +21,7 @@ program test_getidx integer :: lugb = 3 integer :: nlen, nnum, iret integer :: index_rec_len, b2s_message, b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data - integer :: total_bytes, grib_version, discipline, field_number + integer :: total_bytes, grib_version, discipline, field_number, i integer :: lu_gdas = 4, lu_gdas_index = 5 @@ -31,62 +31,73 @@ subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) integer, intent(out) :: nlen, nnum, iret character(len = 1), pointer, dimension(:) :: cindex end subroutine getidx + subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + integer, intent(in) :: lugb, lugi + integer, intent(inout) :: idxver + character(len = 1), pointer, dimension(:) :: cindex + integer, intent(out) :: nlen, nnum, iret + end subroutine getidx2 end interface print *, 'Testing the getidx() subroutine - expect and ignore error messages during test...' - ! Open a real GRIB2 file. - print *, 'Indexing a real GRIB2 file: ', TEST_FILE_WW3_WEST - call baopenr(lugb, TEST_FILE_WW3_WEST, iret) - if (iret .ne. 0) stop 100 - - ! This will not work because the first argument must be between 0 and 9999. -! call getidx(0, lugi, cbuf, nlen, nnum, iret) -! if (iret .ne. 90) stop 99 - call getidx(10000, lugi, cbuf, nlen, nnum, iret) - if (iret .ne. 90) stop 99 - - ! Get the index info, telling getidx() to generate it directly from - ! the GRIB2 file. - lugi = 0 - call getidx(lugb, lugi, cbuf, nlen, nnum, iret) - if (iret .ne. 0) stop 101 - if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 - print *, 'nlen, nnum: ', nlen, nnum - - ! Break out the index record into component values and check them for correctness. - call g2_gbytec(cbuf, index_rec_len, 0, 8*4) - if (index_rec_len .ne. 200) stop 105 - call g2_gbytec(cbuf, b2s_message, 8*4, 8*4) - if (b2s_message .ne. 202) stop 106 - call g2_gbytec(cbuf, b2s_lus, 8*8, 8*4) - if (b2s_lus .ne. 0) stop 107 - call g2_gbytec(cbuf, b2s_gds, 8*12, 8*4) - if (b2s_gds .ne. 37) stop 108 - call g2_gbytec(cbuf, b2s_pds, 8*16, 8*4) - if (b2s_pds .ne. 109) stop 109 - call g2_gbytec(cbuf, b2s_drs, 8*20, 8*4) - if (b2s_drs .ne. 143) stop 110 - call g2_gbytec(cbuf, b2s_bms, 8*24, 8*4) - if (b2s_bms .ne. 166) stop 111 - call g2_gbytec(cbuf, b2s_data, 8*28, 8*4) - if (b2s_data .ne. 4721) stop 112 - call g2_gbytec(cbuf, total_bytes, 8*32, 8*8) - if (total_bytes .ne. 11183) stop 113 - call g2_gbytec(cbuf, grib_version, 8*40, 8*1) - if (grib_version .ne. 2) stop 113 - call g2_gbytec(cbuf, discipline, 8*41, 8*1) - if (discipline .ne. 10) stop 113 - call g2_gbytec(cbuf, field_number, 8*42, 8*2) - if (field_number .ne. 1) stop 113 - print *, 'index_rec_len = ', index_rec_len, ' b2s_message = ', b2s_message - print *, 'b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data: ', b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data - print *, 'total_bytes, grib_version, discipline, field_number: ', total_bytes, grib_version, discipline, field_number - - ! Clean up. - deallocate(cbuf) - call baclose(lugb, iret) - if (iret .ne. 0) stop 199 + do i = 1, 2 + ! Open a real GRIB2 file. + print *, 'Indexing a real GRIB2 file: ', TEST_FILE_WW3_WEST + call baopenr(lugb, TEST_FILE_WW3_WEST, iret) + if (iret .ne. 0) stop 100 + + ! This will not work because the first argument must be between 0 and 9999. + ! call getidx(0, lugi, cbuf, nlen, nnum, iret) + ! if (iret .ne. 90) stop 99 + ! call getidx(10000, lugi, cbuf, nlen, nnum, iret) + ! if (iret .ne. 90) stop 99 + + ! Get the index info, telling getidx() to generate it directly from + ! the GRIB2 file. + lugi = 0 + call getidx(lugb, lugi, cbuf, nlen, nnum, iret) + if (iret .ne. 0) stop 101 + if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 + print *, 'nlen, nnum: ', nlen, nnum + + ! Break out the index record into component values and check them for correctness. + call g2_gbytec(cbuf, index_rec_len, 0, 8*4) + if (index_rec_len .ne. 200) stop 105 + call g2_gbytec(cbuf, b2s_message, 8*4, 8*4) + if (b2s_message .ne. 202) stop 106 + call g2_gbytec(cbuf, b2s_lus, 8*8, 8*4) + if (b2s_lus .ne. 0) stop 107 + call g2_gbytec(cbuf, b2s_gds, 8*12, 8*4) + if (b2s_gds .ne. 37) stop 108 + call g2_gbytec(cbuf, b2s_pds, 8*16, 8*4) + if (b2s_pds .ne. 109) stop 109 + call g2_gbytec(cbuf, b2s_drs, 8*20, 8*4) + if (b2s_drs .ne. 143) stop 110 + call g2_gbytec(cbuf, b2s_bms, 8*24, 8*4) + if (b2s_bms .ne. 166) stop 111 + call g2_gbytec(cbuf, b2s_data, 8*28, 8*4) + if (b2s_data .ne. 4721) stop 112 + call g2_gbytec(cbuf, total_bytes, 8*32, 8*8) + if (total_bytes .ne. 11183) stop 113 + call g2_gbytec(cbuf, grib_version, 8*40, 8*1) + if (grib_version .ne. 2) stop 113 + call g2_gbytec(cbuf, discipline, 8*41, 8*1) + if (discipline .ne. 10) stop 113 + call g2_gbytec(cbuf, field_number, 8*42, 8*2) + if (field_number .ne. 1) stop 113 + print *, 'index_rec_len = ', index_rec_len, ' b2s_message = ', b2s_message + print *, 'b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data: ', b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data + print *, 'total_bytes, grib_version, discipline, field_number: ', total_bytes, grib_version, discipline, field_number + + ! Clean up. Call gf_finalize or else index will be found in + !library buffer. Don't deallocate cbuf becuase gf_finalize() does + !that. + call gf_finalize(iret) + if (iret .ne. 0) stop 198 + call baclose(lugb, iret) + if (iret .ne. 0) stop 199 + end do ! Open a real GRIB2 file. print *, 'Open a real GRIB2 file: ', TEST_FILE_GDAS From a0318edd47cf3d7fea1478cd41ae025b53a077b0 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sun, 11 Feb 2024 05:54:05 -0700 Subject: [PATCH 28/69] working on index testing --- tests/test_getidx.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_getidx.F90 b/tests/test_getidx.F90 index 3a660832..bf8d73fb 100644 --- a/tests/test_getidx.F90 +++ b/tests/test_getidx.F90 @@ -21,7 +21,7 @@ program test_getidx integer :: lugb = 3 integer :: nlen, nnum, iret integer :: index_rec_len, b2s_message, b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data - integer :: total_bytes, grib_version, discipline, field_number, i + integer :: total_bytes, grib_version, discipline, field_number, i, idxver integer :: lu_gdas = 4, lu_gdas_index = 5 @@ -56,7 +56,8 @@ end subroutine getidx2 ! Get the index info, telling getidx() to generate it directly from ! the GRIB2 file. lugi = 0 - call getidx(lugb, lugi, cbuf, nlen, nnum, iret) + idxver = 1 + call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, iret) if (iret .ne. 0) stop 101 if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 print *, 'nlen, nnum: ', nlen, nnum From 78c4cd59d81ef5220b6661d634d5d495a65eae14 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 05:24:16 -0700 Subject: [PATCH 29/69] more work on index --- src/g2_gbytesc.F90 | 4 +- src/g2index.F90 | 18 +++-- tests/test_getidx.F90 | 177 ++++++++++++++++++++++++++---------------- 3 files changed, 122 insertions(+), 77 deletions(-) diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index de9f69bc..9f62c041 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -313,14 +313,14 @@ subroutine g2_sbytesc8(out, in, iskip, nbits, nskip, n) ! number bits from zero to ... ! nbit is the last bit of the field to be filled nbit = iskip + nbits - 1 - print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n + !print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n do i = 1, n itmp8 = in(i) bitcnt = nbits index = nbit / 8 + 1 ibit = mod(nbit, 8) nbit = nbit + nbits + nskip - print *, 'i', i, 'itmp8', itmp8, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit + !print *, 'i', i, 'itmp8', itmp8, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit ! make byte aligned if (ibit .ne. 7) then diff --git a/src/g2index.F90 b/src/g2index.F90 index 9f606abd..e20dbb06 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1163,17 +1163,23 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) call g2_sbytec(cindex, locgds, mypos, INT4_BITS) ! location of gds mypos = mypos + INT4_BITS call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), mypos, INT4_BITS) ! location of pds - mypos = mypos + INT4_BITS * 5 ! skip ahead in cbuf - call g2_sbytec(cindex, lgrib, mypos, INT4_BITS) ! len of grib2 - mypos = mypos + INT4_BITS - cindex(int(mypos / 8) + 1) = cver + mypos = mypos + INT4_BITS * 4 ! skip ahead in cbuf + print *, 'total_bytes mypos ', mypos + call g2_sbytec(cindex, lgrib, mypos, INT8_BITS) ! len of grib2 + mypos = mypos + INT8_BITS + print *, 'storing cver at byte, bit', mypos/8 + 1, ((mypos / 8) + 1) * 8 + cindex((mypos / 8) + 1) = cver mypos = mypos + INT1_BITS - cindex(int(mypos / 8) + 1) = cdisc + cindex((mypos / 8) + 1) = cdisc + print '(z2.2)', cindex((mypos / 8) - 1) + print '(z2.2)', cindex((mypos / 8) + 0) + print '(z2.2)', cindex((mypos / 8) + 1) + print '(z2.2)', cindex((mypos / 8) + 2) mypos = mypos + INT1_BITS call g2_sbytec(cindex, numfld + 1, mypos, INT2_BITS) ! field num mypos = mypos + INT2_BITS cindex(ixids + 1:ixids + lensec1) = cids(1:lensec1) - lindex = ixids + lensec1 + lindex = ixids + lensec1 + inc cindex(lindex + 1:lindex + lengds8) = cgds(1:lengds8) lindex = lindex + int(lengds8, kind(lindex)) ilnpds = lensec diff --git a/tests/test_getidx.F90 b/tests/test_getidx.F90 index bf8d73fb..fd09c6b2 100644 --- a/tests/test_getidx.F90 +++ b/tests/test_getidx.F90 @@ -22,8 +22,11 @@ program test_getidx integer :: nlen, nnum, iret integer :: index_rec_len, b2s_message, b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data integer :: total_bytes, grib_version, discipline, field_number, i, idxver + integer (kind = 8) :: b2s_message8 - integer :: lu_gdas = 4, lu_gdas_index = 5 + integer :: lu_gdas = 4, lu_gdas_index = 5, mypos + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) interface subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) @@ -41,53 +44,89 @@ end subroutine getidx2 print *, 'Testing the getidx() subroutine - expect and ignore error messages during test...' - do i = 1, 2 + !do i = 1, 2 + do i = 1, 1 ! Open a real GRIB2 file. print *, 'Indexing a real GRIB2 file: ', TEST_FILE_WW3_WEST call baopenr(lugb, TEST_FILE_WW3_WEST, iret) - if (iret .ne. 0) stop 100 + if (iret .ne. 0) stop 10 ! This will not work because the first argument must be between 0 and 9999. ! call getidx(0, lugi, cbuf, nlen, nnum, iret) - ! if (iret .ne. 90) stop 99 + ! if (iret .ne. 90) stop 11 ! call getidx(10000, lugi, cbuf, nlen, nnum, iret) - ! if (iret .ne. 90) stop 99 + ! if (iret .ne. 90) stop 12 ! Get the index info, telling getidx() to generate it directly from ! the GRIB2 file. lugi = 0 - idxver = 1 + idxver = i call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, iret) - if (iret .ne. 0) stop 101 - if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 + if (iret .ne. 0) stop 20 print *, 'nlen, nnum: ', nlen, nnum + if (nnum .ne. 688) stop 21 + if (i .eq. 1) then + if (nlen .ne. 137600) stop 22 + else + if (nlen .ne. 140352) stop 23 + endif ! Break out the index record into component values and check them for correctness. - call g2_gbytec(cbuf, index_rec_len, 0, 8*4) - if (index_rec_len .ne. 200) stop 105 - call g2_gbytec(cbuf, b2s_message, 8*4, 8*4) - if (b2s_message .ne. 202) stop 106 - call g2_gbytec(cbuf, b2s_lus, 8*8, 8*4) - if (b2s_lus .ne. 0) stop 107 - call g2_gbytec(cbuf, b2s_gds, 8*12, 8*4) - if (b2s_gds .ne. 37) stop 108 - call g2_gbytec(cbuf, b2s_pds, 8*16, 8*4) - if (b2s_pds .ne. 109) stop 109 - call g2_gbytec(cbuf, b2s_drs, 8*20, 8*4) - if (b2s_drs .ne. 143) stop 110 - call g2_gbytec(cbuf, b2s_bms, 8*24, 8*4) - if (b2s_bms .ne. 166) stop 111 - call g2_gbytec(cbuf, b2s_data, 8*28, 8*4) - if (b2s_data .ne. 4721) stop 112 - call g2_gbytec(cbuf, total_bytes, 8*32, 8*8) - if (total_bytes .ne. 11183) stop 113 - call g2_gbytec(cbuf, grib_version, 8*40, 8*1) - if (grib_version .ne. 2) stop 113 - call g2_gbytec(cbuf, discipline, 8*41, 8*1) - if (discipline .ne. 10) stop 113 - call g2_gbytec(cbuf, field_number, 8*42, 8*2) - if (field_number .ne. 1) stop 113 - print *, 'index_rec_len = ', index_rec_len, ' b2s_message = ', b2s_message + mypos = 0 + call g2_gbytec(cbuf, index_rec_len, mypos, INT4_BITS) + mypos = mypos + INT4_BITS + if (i .eq. 1) then + if (index_rec_len .ne. 200) stop 30 + else + if (index_rec_len .ne. 204) stop 30 + endif + if (i .eq. 1) then + call g2_gbytec(cbuf, b2s_message, mypos, INT4_BITS) + if (b2s_message .ne. 202) stop 31 + mypos = mypos + INT4_BITS + b2s_message8 = b2s_message + else + call g2_gbytec8(cbuf, b2s_message8, mypos, INT8_BITS) + if (b2s_message8 .ne. 202) stop 32 + mypos = mypos + INT8_BITS + endif + call g2_gbytec(cbuf, b2s_lus, mypos, INT4_BITS) + if (b2s_lus .ne. 0) stop 33 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_gds, mypos, INT4_BITS) + if (b2s_gds .ne. 37) stop 34 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_pds, mypos, INT4_BITS) + if (b2s_pds .ne. 109) stop 35 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_drs, mypos, INT4_BITS) + if (b2s_drs .ne. 143) stop 36 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_bms, mypos, INT4_BITS) + if (b2s_bms .ne. 166) stop 37 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_data, mypos, INT4_BITS) + if (b2s_data .ne. 4721) stop 38 + mypos = mypos + INT4_BITS + print *, 'total_bytes mypos ', mypos + call g2_gbytec(cbuf, total_bytes, mypos, INT8_BITS) + if (total_bytes .ne. 11183) stop 39 + mypos = mypos + INT8_BITS + print *, 'test_getidx expecting grib_version after byte, bit ', mypos, mypos/8 + print '(z2.2)', cbuf(mypos/8 + 0) + print '(z2.2)', cbuf(mypos/8 + 1) + print '(z2.2)', cbuf(mypos/8 + 2) + print '(z2.2)', cbuf(mypos/8 + 3) + call g2_gbytec(cbuf, grib_version, mypos, INT1_BITS) + print *, grib_version, mypos + if (grib_version .ne. 2) stop 40 + mypos = mypos + INT1_BITS + call g2_gbytec(cbuf, discipline, mypos, INT1_BITS) + if (discipline .ne. 10) stop 41 + mypos = mypos + INT1_BITS + call g2_gbytec(cbuf, field_number, mypos, INT2_BITS) + if (field_number .ne. 1) stop 42 + print *, 'index_rec_len = ', index_rec_len, ' b2s_message8 = ', b2s_message8 print *, 'b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data: ', b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data print *, 'total_bytes, grib_version, discipline, field_number: ', total_bytes, grib_version, discipline, field_number @@ -95,32 +134,32 @@ end subroutine getidx2 !library buffer. Don't deallocate cbuf becuase gf_finalize() does !that. call gf_finalize(iret) - if (iret .ne. 0) stop 198 + if (iret .ne. 0) stop 50 call baclose(lugb, iret) - if (iret .ne. 0) stop 199 + if (iret .ne. 0) stop 51 end do ! Open a real GRIB2 file. print *, 'Open a real GRIB2 file: ', TEST_FILE_GDAS call baopenr(lu_gdas, TEST_FILE_GDAS, iret) - if (iret .ne. 0) stop 100 + if (iret .ne. 0) stop 60 ! Open a real GRIB2 index file. print *, 'Open a real GRIB2 index file: ', TEST_FILE_GDAS_INDEX call baopenr(lu_gdas_index, TEST_FILE_GDAS_INDEX, iret) - if (iret .ne. 0) stop 100 + if (iret .ne. 0) stop 70 ! Get the index info, telling getidx() to use the index file. call getidx(lu_gdas, -1 * lu_gdas_index, cbuf, nlen, nnum, iret) - if (iret .ne. 0) stop 101 + if (iret .ne. 0) stop 80 print *, 'nlen, nnum: ', nlen, nnum - if (nlen .ne. 3800 .or. nnum .ne. 19) stop 102 + if (nlen .ne. 3800 .or. nnum .ne. 19) stop 81 ! Get the index info, telling getidx() to use the index file. call getidx(lu_gdas, -1 * lu_gdas_index, cbuf, nlen, nnum, iret) - if (iret .ne. 0) stop 101 + if (iret .ne. 0) stop 90 print *, 'nlen, nnum: ', nlen, nnum - if (nlen .ne. 3800 .or. nnum .ne. 19) stop 102 + if (nlen .ne. 3800 .or. nnum .ne. 19) stop 91 ! Break out the index record into component values and check them for correctness. call g2_gbytec(cbuf, index_rec_len, 0, 8*4) @@ -153,35 +192,35 @@ end subroutine getidx2 ! Do the same read again. call getidx(lu_gdas, lu_gdas_index, cbuf, nlen, nnum, iret) - if (iret .ne. 0) stop 101 + if (iret .ne. 0) stop 300 print *, 'nlen, nnum: ', nlen, nnum - if (nlen .ne. 3800 .or. nnum .ne. 19) stop 102 + if (nlen .ne. 3800 .or. nnum .ne. 19) stop 301 ! Break out the index record into component values and check them for correctness. call g2_gbytec(cbuf, index_rec_len, 0, 8*4) - if (index_rec_len .ne. 200) stop 205 + if (index_rec_len .ne. 200) stop 305 call g2_gbytec(cbuf, b2s_message, 8*4, 8*4) - if (b2s_message .ne. 0) stop 206 + if (b2s_message .ne. 0) stop 306 call g2_gbytec(cbuf, b2s_lus, 8*8, 8*4) - if (b2s_lus .ne. 0) stop 207 + if (b2s_lus .ne. 0) stop 307 call g2_gbytec(cbuf, b2s_gds, 8*12, 8*4) - if (b2s_gds .ne. 37) stop 208 + if (b2s_gds .ne. 37) stop 308 call g2_gbytec(cbuf, b2s_pds, 8*16, 8*4) - if (b2s_pds .ne. 109) stop 209 + if (b2s_pds .ne. 109) stop 309 call g2_gbytec(cbuf, b2s_drs, 8*20, 8*4) - if (b2s_drs .ne. 143) stop 210 + if (b2s_drs .ne. 143) stop 310 call g2_gbytec(cbuf, b2s_bms, 8*24, 8*4) - if (b2s_bms .ne. 166) stop 211 + if (b2s_bms .ne. 166) stop 311 call g2_gbytec(cbuf, b2s_data, 8*28, 8*4) - if (b2s_data .ne. 4721) stop 212 + if (b2s_data .ne. 4721) stop 312 call g2_gbytec(cbuf, total_bytes, 8*32, 8*8) - if (total_bytes .ne. 15254) stop 213 + if (total_bytes .ne. 15254) stop 313 call g2_gbytec(cbuf, grib_version, 8*40, 8*1) - if (grib_version .ne. 2) stop 215 + if (grib_version .ne. 2) stop 315 call g2_gbytec(cbuf, discipline, 8*41, 8*1) - if (discipline .ne. 0) stop 217 + if (discipline .ne. 0) stop 317 call g2_gbytec(cbuf, field_number, 8*42, 8*2) - if (field_number .ne. 1) stop 220 + if (field_number .ne. 1) stop 320 print *, 'index_rec_len = ', index_rec_len, ' b2s_message = ', b2s_message print *, 'b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data: ', b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data print *, 'total_bytes, grib_version, discipline, field_number: ', total_bytes, grib_version, discipline, field_number @@ -194,29 +233,29 @@ end subroutine getidx2 ! Break out the index record into component values and check them for correctness. call g2_gbytec(cbuf, index_rec_len, 0, 8*4) - if (index_rec_len .ne. 200) stop 205 + if (index_rec_len .ne. 200)stop 405 call g2_gbytec(cbuf, b2s_message, 8*4, 8*4) - if (b2s_message .ne. 0) stop 206 + if (b2s_message .ne. 0)stop 406 call g2_gbytec(cbuf, b2s_lus, 8*8, 8*4) - if (b2s_lus .ne. 0) stop 207 + if (b2s_lus .ne. 0)stop 407 call g2_gbytec(cbuf, b2s_gds, 8*12, 8*4) - if (b2s_gds .ne. 37) stop 208 + if (b2s_gds .ne. 37)stop 408 call g2_gbytec(cbuf, b2s_pds, 8*16, 8*4) - if (b2s_pds .ne. 109) stop 209 + if (b2s_pds .ne. 109)stop 409 call g2_gbytec(cbuf, b2s_drs, 8*20, 8*4) - if (b2s_drs .ne. 143) stop 210 + if (b2s_drs .ne. 143)stop 410 call g2_gbytec(cbuf, b2s_bms, 8*24, 8*4) - if (b2s_bms .ne. 166) stop 211 + if (b2s_bms .ne. 166)stop 411 call g2_gbytec(cbuf, b2s_data, 8*28, 8*4) - if (b2s_data .ne. 4721) stop 212 + if (b2s_data .ne. 4721)stop 412 call g2_gbytec(cbuf, total_bytes, 8*32, 8*8) - if (total_bytes .ne. 15254) stop 213 + if (total_bytes .ne. 15254)stop 413 call g2_gbytec(cbuf, grib_version, 8*40, 8*1) - if (grib_version .ne. 2) stop 215 + if (grib_version .ne. 2)stop 415 call g2_gbytec(cbuf, discipline, 8*41, 8*1) - if (discipline .ne. 0) stop 217 + if (discipline .ne. 0)stop 417 call g2_gbytec(cbuf, field_number, 8*42, 8*2) - if (field_number .ne. 1) stop 220 + if (field_number .ne. 1)stop 420 print *, 'index_rec_len = ', index_rec_len, ' b2s_message = ', b2s_message print *, 'b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data: ', b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data print *, 'total_bytes, grib_version, discipline, field_number: ', total_bytes, grib_version, discipline, field_number @@ -224,9 +263,9 @@ end subroutine getidx2 ! Clean up. deallocate(cbuf) call baclose(lu_gdas, iret) - if (iret .ne. 0) stop 199 + if (iret .ne. 0) stop 500 call baclose(lu_gdas_index, iret) - if (iret .ne. 0) stop 199 + if (iret .ne. 0) stop 501 print *, 'SUCCESS!...' From 7088a651cb4b0499fdde6dc8d540cd21905d5e8d Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 05:55:25 -0700 Subject: [PATCH 30/69] more index work --- src/g2index.F90 | 2 +- tests/CMakeLists.txt | 3 + tests/test_g1.F90 | 136 ++++++++++++++++++++++++++++++++++++++++++ tests/test_getidx.F90 | 3 +- 4 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 tests/test_g1.F90 diff --git a/src/g2index.F90 b/src/g2index.F90 index e20dbb06..d88c815b 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1178,7 +1178,7 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) mypos = mypos + INT1_BITS call g2_sbytec(cindex, numfld + 1, mypos, INT2_BITS) ! field num mypos = mypos + INT2_BITS - cindex(ixids + 1:ixids + lensec1) = cids(1:lensec1) + cindex(ixids + 1 + inc:ixids + lensec1 + inc) = cids(1:lensec1) lindex = ixids + lensec1 + inc cindex(lindex + 1:lindex + lengds8) = cgds(1:lengds8) lindex = lindex + int(lengds8, kind(lindex)) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dc14d912..ae4f14cc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -39,6 +39,7 @@ endfunction() # Some very small test files may be committed to the repo. This # function copies such a data file to the build directory. function(copy_test_data name) + message(STATUS "Copying test file ${name}") file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${name}" DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) @@ -133,6 +134,7 @@ endif() # Copy test data files that are in the repo to the build directory. copy_test_data(testdata_g2grids) copy_test_data(ref_gdaswave.t00z.wcoast.0p16.f000.grb2index) +copy_test_data(g1.grib2) copy_test_data(gdaswave.t00z.wcoast.0p16.f000.grib2) copy_test_data(ref_test_jpcpack_4_output.txt) @@ -142,6 +144,7 @@ foreach(kind ${kinds}) # create_test(test_g2cf ${kind}) create_test(test_misc ${kind}) create_test(test_g2 ${kind}) + create_test(test_g1 ${kind}) create_test(test_g2_encode ${kind}) create_test(test_g2_decode ${kind}) create_test(test_gridtemplates ${kind}) diff --git a/tests/test_g1.F90 b/tests/test_g1.F90 new file mode 100644 index 00000000..f488faff --- /dev/null +++ b/tests/test_g1.F90 @@ -0,0 +1,136 @@ +! This is a test program for NCEPLIBS-g2. +! +! This program tests getidx(). +! +! Ed Hartnett 7/26/22 +program test_getidx + use bacio_module + implicit none + + character(*) :: TEST_FILE_G1 + parameter (TEST_FILE_G1 = 'g1.grib2') + integer :: lugi + character(len=1), pointer, dimension(:) :: cbuf(:) + integer :: lugb = 3 + integer :: nlen, nnum, iret + integer :: index_rec_len, b2s_message, b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data + integer :: total_bytes, grib_version, discipline, field_number, i, idxver, j + integer (kind = 8) :: b2s_message8 + + integer :: lu_gdas = 4, lu_gdas_index = 5, mypos + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) + + interface + subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) + integer, intent(in) :: lugb, lugi + integer, intent(out) :: nlen, nnum, iret + character(len = 1), pointer, dimension(:) :: cindex + end subroutine getidx + subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + integer, intent(in) :: lugb, lugi + integer, intent(inout) :: idxver + character(len = 1), pointer, dimension(:) :: cindex + integer, intent(out) :: nlen, nnum, iret + end subroutine getidx2 + end interface + + print *, 'Testing the getidx() subroutine with simple file...' + + do i = 1, 2 + ! Open a real GRIB2 file. + print *, 'Indexing a real GRIB2 file: ', TEST_FILE_G1 + call baopenr(lugb, TEST_FILE_G1, iret) + if (iret .ne. 0) stop 10 + + ! Get the index info, telling getidx() to generate it directly from + ! the GRIB2 file. + lugi = 0 + idxver = i + call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, iret) + if (iret .ne. 0) stop 20 + print *, 'nlen, nnum: ', nlen, nnum + if (nnum .ne. 1) stop 21 + if (i .eq. 1) then + if (nlen .ne. 200) stop 22 + else + if (nlen .ne. 204) stop 23 + endif + do j = 1, nlen + print '(i3, x, z2.2)', j, cbuf(j) + end do + + ! Break out the index record into component values and check them for correctness. + mypos = 0 + call g2_gbytec(cbuf, index_rec_len, mypos, INT4_BITS) + mypos = mypos + INT4_BITS + if (i .eq. 1) then + if (index_rec_len .ne. 200) stop 30 + else + if (index_rec_len .ne. 204) stop 30 + endif + if (i .eq. 1) then + call g2_gbytec(cbuf, b2s_message, mypos, INT4_BITS) + if (b2s_message .ne. 0) stop 31 + mypos = mypos + INT4_BITS + b2s_message8 = b2s_message + else + call g2_gbytec8(cbuf, b2s_message8, mypos, INT8_BITS) + if (b2s_message8 .ne. 0) stop 32 + mypos = mypos + INT8_BITS + endif + call g2_gbytec(cbuf, b2s_lus, mypos, INT4_BITS) + if (b2s_lus .ne. 0) stop 33 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_gds, mypos, INT4_BITS) + if (b2s_gds .ne. 37) stop 34 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_pds, mypos, INT4_BITS) + if (b2s_pds .ne. 109) stop 35 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_drs, mypos, INT4_BITS) + if (b2s_drs .ne. 143) stop 36 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_bms, mypos, INT4_BITS) + if (b2s_bms .ne. 166) stop 37 + mypos = mypos + INT4_BITS + call g2_gbytec(cbuf, b2s_data, mypos, INT4_BITS) + if (b2s_data .ne. 4721) stop 38 + mypos = mypos + INT4_BITS + print *, 'total_bytes mypos ', mypos + call g2_gbytec(cbuf, total_bytes, mypos, INT8_BITS) + print *, 'total_bytes ', total_bytes + + if (total_bytes .ne. 15254) stop 39 + mypos = mypos + INT8_BITS + print *, 'test_getidx expecting grib_version after byte, bit ', mypos, mypos/8 + print '(z2.2)', cbuf(mypos/8 + 0) + print '(z2.2)', cbuf(mypos/8 + 1) + print '(z2.2)', cbuf(mypos/8 + 2) + print '(z2.2)', cbuf(mypos/8 + 3) + call g2_gbytec(cbuf, grib_version, mypos, INT1_BITS) + print *, grib_version, mypos + if (grib_version .ne. 2) stop 40 + mypos = mypos + INT1_BITS + call g2_gbytec(cbuf, discipline, mypos, INT1_BITS) + print *, 'discipline', discipline + if (discipline .ne. 0) stop 41 + mypos = mypos + INT1_BITS + call g2_gbytec(cbuf, field_number, mypos, INT2_BITS) + if (field_number .ne. 1) stop 42 + print *, 'index_rec_len = ', index_rec_len, ' b2s_message8 = ', b2s_message8 + print *, 'b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data: ', b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data + print *, 'total_bytes, grib_version, discipline, field_number: ', total_bytes, grib_version, discipline, field_number + + ! Clean up. Call gf_finalize or else index will be found in + !library buffer. Don't deallocate cbuf becuase gf_finalize() does + !that. + call gf_finalize(iret) + if (iret .ne. 0) stop 50 + call baclose(lugb, iret) + if (iret .ne. 0) stop 51 + end do + + print *, 'SUCCESS!...' + +end program test_getidx diff --git a/tests/test_getidx.F90 b/tests/test_getidx.F90 index fd09c6b2..5d0db320 100644 --- a/tests/test_getidx.F90 +++ b/tests/test_getidx.F90 @@ -44,8 +44,7 @@ end subroutine getidx2 print *, 'Testing the getidx() subroutine - expect and ignore error messages during test...' - !do i = 1, 2 - do i = 1, 1 + do i = 1, 2 ! Open a real GRIB2 file. print *, 'Indexing a real GRIB2 file: ', TEST_FILE_WW3_WEST call baopenr(lugb, TEST_FILE_WW3_WEST, iret) From e931cf9d4e73705bab108d7d561f31b4e9df44ff Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 05:59:18 -0700 Subject: [PATCH 31/69] added small data file --- src/g2index.F90 | 6 ------ tests/g1.grib2 | Bin 0 -> 15254 bytes tests/test_g1.F90 | 12 +++--------- 3 files changed, 3 insertions(+), 15 deletions(-) create mode 100644 tests/g1.grib2 diff --git a/src/g2index.F90 b/src/g2index.F90 index d88c815b..15501a1b 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -1164,17 +1164,11 @@ subroutine ix2gb2(lugb, lskip8, idxver, lgrib, cbuf, numfld, mlen, iret) mypos = mypos + INT4_BITS call g2_sbytec(cindex, int(ibskip8 - lskip8, kind(4)), mypos, INT4_BITS) ! location of pds mypos = mypos + INT4_BITS * 4 ! skip ahead in cbuf - print *, 'total_bytes mypos ', mypos call g2_sbytec(cindex, lgrib, mypos, INT8_BITS) ! len of grib2 mypos = mypos + INT8_BITS - print *, 'storing cver at byte, bit', mypos/8 + 1, ((mypos / 8) + 1) * 8 cindex((mypos / 8) + 1) = cver mypos = mypos + INT1_BITS cindex((mypos / 8) + 1) = cdisc - print '(z2.2)', cindex((mypos / 8) - 1) - print '(z2.2)', cindex((mypos / 8) + 0) - print '(z2.2)', cindex((mypos / 8) + 1) - print '(z2.2)', cindex((mypos / 8) + 2) mypos = mypos + INT1_BITS call g2_sbytec(cindex, numfld + 1, mypos, INT2_BITS) ! field num mypos = mypos + INT2_BITS diff --git a/tests/g1.grib2 b/tests/g1.grib2 new file mode 100644 index 0000000000000000000000000000000000000000..c61316c2665e2088dfff6e157a577ee34b9dfc44 GIT binary patch literal 15254 zcmeIYbyyT_AHThHcS|hYof5J%NJw{gH`1`Agc6bxg0#|&N=hl+-AD-1-TUhEsQ0bz z^Lu~)zwaEo12gB$b$!n7bFzZ4plSwjzK5Abr~d1B0}VM)7?w z%(u53+_zOM!}m?Z@2lUJ!*83ZKX<`i9R#6==>&1Y1bB;KZd3;WV4tG>=l$&nYWVMm z!NR}-(7yfs-tvzXKXO>A$oM`pIzrr8m$i%zr5)2s-{j|3@zHfAJmkb3s2&UWST+ zKWH0N`a>83{oEhIkOQda{t$*hH~uO7KZ^My)&Hmm_y>j_3-p6Rj|Kcep~w0u484{= zg`tQ3DGWXIFX1+*)%ua@f7BBE14EwxpdS>v67UCwuJltFy3#MM5c~^6>lpNlLhBg#4~1gMFt;ctBe{V{+3Ee!d4kpG?P?^=WZjsG$R z{hR(33;1vP*9XXN!hhA{H{riR|1SJztlx$IngYM2`YRUrH{A9|EkVE0A|gZ@50{t!O@eSZ8Q{72|NmHwDo|NrLyCo8~2 zg#=NCr~;V2+kbn~^WzE7e{1o_HVi5Z48#IJ3xJVyvo!T^b`zqMH+5IBbfeU=baS_L zcB15B7v$t*=N5#h0nq=`6aqXv00v?Jz!TFkF|qmg3la}N{oV^>{0*bnh;&}Yi5Wa6NHOWLtSRfu~`?ZciD;f4m%2$<}^BtgeTFT%zel=YlQa! z+niGD@Y~_nTxq)T4QjI?%-+#nmsYqCo^%1OAj=&ztoyOPWGDwphRCkMo)JT}h{o_V zO9;{W#kjcFt7Y`4MX!cK?=YbG?gg^ zQ*r|@!iS>B&&~-aA#D6`20YAEta_!DV}WepJ=$IrFe zDXyMdto+J;_J$-+7T~n3&ty+8nT|jj0uUQ}tCAUe9H)G&5073qjg6uk;GkKGw$-aDIN$11%{9&X>9YxGG-o{xbdfq1ak)*BY@eNWDNll~7<{}x*)wvHi ztF5D(5VEwc**68#&ESy`^=Pc}cwan zLZsWB7)|oJ3cLgB>xy;ND>VUl!{RLOPz9D8rmkN`G!Z$CRI}Ao!gG4lEMbW9kqqx?o6CS;biuoIwtL= zQ`qOG>iWlS_QzT9A+idVP>vKe$a3k#mnRT&xkmL%Lj?$B0v&&Cd&+uT_G+e7t2DIT=?asF4&JHxda@W(ak-T?<)0(b)GYFu5EFm?5 zj%B()weh$r%g%?h(kH$rU*@fpw`lS{hGgq#XM!)Ock+X+Q{}2hXVNH&OUjgaeh@#( zQ%)bSuJ^46glH8p(N-GmquISuEh+s~#K}f5Ceeu1N!LZLae@CM!-rIZO)<4hLl}$i z-Yq9^`8yV@B4_&D@h!>mW@#lqsJ#@|8H;s(azFvVk}?{GJAk2x>ts~IdMFaPy?T&I zl(b>e>^OyXev;1tAK%qrka)UVoj>YZ-+}jDZjeyKEBl$K&vnQ~-R^v^S3UQ0H_aJZ z^5M?rs)kR;9t6Wip!u_^9()52!a7HP$IK+`VAVMm}eFdYI zY2SSgtxAnCV&K41jC~SZ)7?V5-KkH9yALX~P0X8r@Vd`4BD0jnG@fbq<1(<^w1gQy zS#ui=LY6fYacZrW=_sAxiaZC?Sf9K$b>vfu^BKpTkTdtT^)udY$CvnFKS9 z9c5GI{*5zSMu~FHXz=Xp7pnP3EVcwT6~tQg^9z`#CIU!W9b#gGdH3~DhX_8d={=c3 z0A_EdzJ1TgJ7S1Jhg5n5cGp^IznPPo+Dzt-VWV0=L3(1$G<&7}o;zTWD(b8%nPQXB zlvDp@Wl}-DxlI<3PqDWcfHXr^bVM zZ}M?{=7C7eXb72JXnM2+d32G>b9$#Cd##}R0{9uha78u;gH@*!Sp$wzcta9tzyKOz zg{5`v8U&}qrw<8_*OMN%D09RzS#3{6i5Tj@su1$0GvJhX^_j)p8Go=n+IJRftg<|D zI`o8z^n>}VG%Jj`WBn4wJgC22qfXXq?(M|m0ZNsgG$)?->-nPbLd?;!28b%13y!jP zplf=tMfNq_x7GIxD|P4t!!;cQ#2dGhR`G%5GT-YmAI!^kgAEaf+q*;7p7n#=!#b9P zxQn&Is>p9Sj--5ijdb>8Iiz}h-F4VA+Zy|$$x7V^^aevdAXx3SeSf;o7+y-|VsW7@ zR+@=0vDT}c_{$da2cu|7ZIFYTzc8@fGIoK7iTTG?Vfo~)g$NIR8Vf*YEoCO!~Y`vaqh}v=E zJ&zkVKV!5RKy;Jtpwyf+)B&%vsV<~mQ?(lbk!HbdP{Us`B;1gKv~mK#OKT(x9y zN7HYs=bB?%2l@H;>|u?ITDVaa&{P?7geN_?N`hdVez~Fg&0LIL_mRdY&5zMp?VUmZl4U2({5m+xVte@%(3E4^ zDDDjE)i|%RF|W#-x`ij&K!W-viy4`eODQFE#6*}K;7a3BG?Jgua31ozQgB4GT$ug# zyZe5R7#$Rk+>GPc8I>M?&7b12o6b|NvqK#sPghYF?m94SKx4#R(;&j>lCcaD zHl`hYL%J?1o{=mJ77Xmbok+XK;ID-$``IhStClG>`JGo*p`6U4S$0QxTRW^~gdkeQ zsbyGNgmil=msWA1*|`vl4Pm0ykw}Gk{0!E9%d@!J@t7mNue34rLAo(wj00@!0O#HeqgiVi?5sX*-LhTN8h6GiZIpRe znF-NFMUKA9T<{4ZN>L4d@%Ft1gknjdy>t9$HK}a6W!4MGUv-}p7JS*x8-ytvdFpmD zYsnY6cPr2kdsxg@Cx#GuJ={V2&TVSCY{_|-?*k*nLnPi8TD3EIf~3@8HjQ0yU~@aW zx{kQBIFAJ@dP97;urMC|S=AE*Q*w-Jy?6_DaHUV|V={#_25Fhp`56wY zeB9e(aRd$Dv1Xw-Efo$FV+tcu7nsx!=M=gyHA{VM1??ZHQJ3pUl(3tu=?p4-c|P*s z9~6ju5b4hrdcJ};5E$PPV$mkH<9wzqT~^%3$orYG+9lzIMFlfCdP!KF&k3G$VfxGH ziTzNKx`M{_AScwL`Tfm@R#fHDxx-Wy9NmL7lil5Ku-M$DxIx?niH0pbD;%msnwbM| z*r+utuV1#TvG=*1^nmRL6%iWGlmS@~+H;vcX_94os@zh44Kr%I0#x9*kJYYFluC$$ zUPZqNyUcpH+Y7X}S5GChj|B=4*#<1VJ$igHO6b|Mm;rg+Xjt{=eXa_*l*+dm^WFKn z-@Y(aGi(Is4oCyUUQUNW{SZyE%<9oA74x^BCHPVSKa3;#btFoZOBbP zkpBeUYI&32SeuQM%%?<{7XTnm)RQn_iQcYiw^!S59%$qcc@5*a-o+7o zEwJl|CuV@fq^+k{!9^b_>pdLi?y67G^2O52cVZOBx!n=KXq=v7vtJUcg(~SxXFYu#f@nfvi-p&<^3~>r~W9- z(tJg)^a%YAC<#|NP}Nu-erBGxIalP&k{4d`Hlwyt4tVMBf{aXz>ke%7i3`U(?lA3X z;R2N1VLuYJAGf2XZ#q#bThLNh;|rlU$sARaKMEX8tS?_Q&*PHCPZhE?`Anoj-sAP! zk+RURQW|fAv>}HPcP1u3O(rUSnbiM5D+FsP9e4(U=s*JEK-Uz;X^VH(5Ub$Z%Nz(d z#hs1Ua`@(f_#HC&Wj2Hx>Gt~?cpJ~K?6(w2qzjYn0q zOc1cRlHIM|jc~|=revSAPGpeDMUe5cVdo0F0Z*jK4_h4O*Fnv(zHOowJnABrUTqR- z^E#9(4YGba0BH@AH$vq6%rkxPN8Din1RYI{=r8H+`poHDk>AY|0qy8D$r7AtIx1PX z-)5gwe++>|FOg&9$|~XW47W%u)o^S+ZzZ!G*hs1uaUwDI-bBXfe^$gt5jH@knS%m* z&roH`<}Imjh8kz4T9mCB-foS4yv*)3sUCZQ>#Ev%^SM=Z;00+kuuuPDI2UP4LW0?E zJRFfLQN`bcFoV%NO?`5OUM4TqPS8@MvQ8<&b$eorz)W3*Iq}}9wXodgg)6xy1;(f# z&?JFEjv3<{($P*V4WyY9nT@p1VCW4w&F-HbG z7lsuZl=zUvfgiNsC2pyfiCZDk*7OKTWwt%GW8KGR1kT!6Vsw{Kl%!Fvo{zUh`2w|< zZh4v)UYI#msu6Duq~S7pJ;E+|m}EmLY)I!pj$g15Mpocm>Vfq%d51#cPSoy>=suXb zHtH_yi(wex_}&Xp2%}fSv+_rDG`@`jYN>{zA&3cP}bs zK9MMEu*&TYOpZ#9P{}y2J<73n`$T`CKPX@+_B1FNPK>gxkD^z;+DcS8NaMX3n|X?4|+Ur*sDj3Y#EpfuE>wyut-IGyho); ziv_;_q0J%Vk%FDhJ#be~N94&c?K#=BBUPStanbcorzu%RD9<6$>vS~}BI>S@SL=0g zC)W%>xhIwzk9*QR3&8xHo4NK4?L3(k{S8mddNRo`9nK;#XC9&tzUZdX|Mq<6@XU`n zN2?4g_BHa8+CE`>8@EJ__yT?8g5rAptCHj|d`cpNiq&M_R_Xnl?!dm^9o}E7w~n6fJob1k!% zDPa5=Z{w1R<4|(9q!e665=FMi=A5C6lR@T4vpNqof7VDUO;3^aHoGriIuGuELo}AV z=DLW(3V_}~57`$~Sq64Bjr0@seiva}zM0!Q$+3AZ9a$nm6yb3g4Wy^8$NUmpmK!hQ zQv7;T<0xW#q-O|K{R`N?guupRp)nXsXXqX@(QH^yf30XqvJMCKt@GrQI(ijNbx?L! zkV}vl`M-P}$ zREXVB1aH%s)C~UqI}<_1%VmKD z=dWoanCz_=OsVyzik+|%bTRDHi>In|9|A(s(AK9!y}l?A+Ldn?_GGe+L*z@g1DTlY zdq>}zJm62l<&Eo&k(rYb=OgiQRFs{~z3m?^3z@MIs9!@!D0&qML2a|0L(itMJ&R#i zyQ>|NERNuCt`O^%9TMN+l|p=##~{sJ>rsG{6e&GXez^98C!7EAtS5tdD=)Q}e;pYf z7C{of?>%qq$6wq0D37^ULli*|?z8gS1)K8A+u96>97bPpsOEfb@Qvy7Mw4|4S*wbh zspc_XVbVu~QF`+zJNVVb0f0?Nt{7aqwa4f4&{iXU5|8b18S=&`d~sam>x^as;@8J7 z<(RXlgOYCNYZ7T=<0_o+q-ya?(4rdLJGiBlrX3HJ?$Sz=arSq11}i($((}z#s2Co3 z_tD9-y4BGi&`f0eiK>TZm{QdTnZQeH;{-sY0NlGDl-uIW_T>iDaPOqkc)3$y?by z>_aq36j)9+5vO6hev~)F!gc=OU^rZD4>Q+8++m*s92MCgH8DdXrmsG+zX_6|6NkbMr`$aemGj#U76$l6fGXl?IOv#-OlDrj9WN!BuQbYw`--O=FO-kY)Lmyux zxp=b_zvN*g2s3w&Lx$2-_mNuF{i^2Iiv~`&WD=Uh)y1Fn=9$)N;qNKf`1@L~Wf&?BdKX7BC0tY$|x6&&j>Zh;rSz9JBrq&4Zf8973M_d&P!`VFov9jW4|qIm&I z(GI~Lu|`NfJ)b6l>a4t3Mj68hnCGovAOt_sK(Hd>D1KYBIV*PmcuvV}0J{pQb%OQ| zoIWb;^h*304ep`P?FIhz^LYE09N7eQ&8%_&bGOC9mxON<=7MfbwoqaU@X$EQGGT%R z8SGpd5a3iO*L#>!W%=WjmdTz$NKC71niMcQz@T>|>t9aO=j)&1yEb+V5}Ejc=abuR z1{VeKkqJs8FhmN7XzD;XlEy9FRud;JmT&Rc(3>TY2L>oC%QwY_=wZ`BU%t=oDtfz{ zsU=mB7=OH7r;%>3Zk|xF$7vb5O3*Pm1+ydC;@+#6sSZmTBHC95HnC%nES}kxOb%ux z7m*hiIOfQ=t{`iR=+dc_$ikRjbIBMN!Ko$^pyq(jgQ1d*je|K`yoZ|9N*35KSIK!| zacd;F5*PKgr=myYlZv80(ms*=2%tUDSYx#p7iHQx{VDn~C4yMwE42hl81<#pY+}(g zVx~+*!F`DA{)XjEf9sCZimzf1%37~WujgHxw=d2b5?&eFkf%B^r%8~PBE)MMUTh?Qv|BIuaw&T8=v zv9+x)+ZKE*a2-%++%^?B2A(yCSlI_68eZH3^MH=e(u`G&Z~BX7wg1x=_<+4-v=ua~ zA0Ykyaw0Gn+>#qNt9myYH>-U+>%R@*t++#QJucq491k4LK1;eA%^urkxfI7T}+-snLcH z(X#8`y))+cl3cp-#3Dqo7y;ia8^|4`9x1voK1cfLJnoY0<#X{TDiFQB>^shtpvzHl zv*_8$Pfj%ys_?a(j5TC2OPt2K_QQ`oIk1us$#b%C9=K*W=ONIkm0g%y1uDr=orgIp zVZ27be9!4oW9*TG;Dp%-%Sn;f6?h3_7{XCr;U<7eXMGYps35A>v;&lNgZ1$cwYY>? zndHjGJ6rE?6cC_&pMee$;fZ$7CEV^d!x@T~D#mnp+n%J3g&0d@h{_w9QUl^!>J0ka z8r0v6DBiw%IP9CbxY`<_Wm#2Vi3@z96j(K6l$HiDH7t`M44Q#}MI;)fE5F1#!;O*| z;`p0}hq@^WJ`SJoFAB0Sn`r5GYX)Psmu$NctfUGq?3&%HdbU z8N*{rtahqYx`SAJ>X4}r*jK~=wwO>5?5A|~hw@k|y^2pTAk-q24{FP3d~yIYA2+fT zRlCrAwzQbpE~+Bl0aNq6`c&!Bz(`dxB`fhQyjT-sa(Dtp7jvhyF2%6ssjr?}1`j#y zQ(eQZ4=!{wU3#id*~H-{Q3+(&KGc5fiL+-7GxO@@q>P!-7~b1gJZ#n@K~?UMS|&PUj1}atvhbxKVM(iJ zGMY>z6;!XX1rN~?w#1a~Uo&n54bjL^Wq~cYSWX@@Z)U&T@OX7dik3`|60RT9`9X*` z%)#?$g)87DWiW&GfHq=_ilc0M5A z@`O-mdNOO{ zSklIaG@icVsXd9j>Z$wItvw>|xZ}M4;KM{S@dTGnE0>WB!i}w?KF<&tfd}+vM~VA3 zK~w~T@ewoGiuQ24sXgIOng9VYcRKJIQS|=16Xog>yOp1Jk6pYt7p>1guAIgyuN>^E zkYFhT*dEIqbX;=)@c zN=^IjgEG!mPa>l-NoIj@@fP_GDGqoM4&AE}Dj(i^jkT06)(dEa&vVR)!^= z{iJUS-#%nBV0weCfsHJr0A|kV{oS}}ZX}PJ7Q49SHsJ1rVk_W@-)F#Uq_W!u@oB+W z8Ku1T15SO8hfVN>Y-YiHEaHz73Lbr?yp|wi&KBnT(3sBPGfqJb11ek0Hdt-qxQ`h<`Fkj_~e+qke$xAPgkW6l;P!?a*lSG!6hC0fZ;XV^=5F!g*uidub^ z$fH9>{`Y#79Z!m~B`o@j9=)`kB7432OkWEHFBxTl!dCR7GJ8kw`#oZumPBq_Rws80 z-<<>l-PH+weIznul!*3t_YbKf5{CJ777dp0bW>Y!E3bhh%-T}DnR@nLadG3S(@Xjv z%9%oBDCr`-BFT1Urnk(6qeacE8^cCyPz`YB2kENdpHSw?#kA+=#6&UdIB&gZQs7Dh zAUy>4>GW@udE!;a-Xp4z&=kPKt%akBt%JZasgA@Q0NK@+xuTQ5WCnyx-|<1jJ7#F; zzNV?1LVQ@6O1oo#N|w~Z0NxTr&Fs^NH9CgHvHNcpu3x@>EscF_f2PUo$35K}1F zv5e{YhYHgZB&b3{wrsX5Oq;M_F}os{(3F%3UTXPXH|BYk-d^du)HT>D-j@&Qd!xa? zHn=y1N54Ce&T~2wf&k2ru^Tb_D1@`>xZG;b9>UCrc!Hy96f`8%1O;I0a_obP0*y3V$yaAz__Q}f^U zJV*4{3*kCNyORk?4Cn}60d4pmq1k=c4EByL zBr?3NtLm!?B!6LGq*AlIf0+g8G)qfHE1PBGwk_~6Px3PZci%n<Q7fD!*b*vt2 ztNW^ka1V>a0&X(fMG)d?uhi_#MS@o4IS}h~yJNm&MhDfW78RrWl{Z#WQch2%a#l>R zN?^v)yh+`ddG#tqNAgIfu>sHGX`??Qh$Mn!WR5&W!pPbthjT<~FJP69f$G+IF;wd7 zZMlmbfh($=66Iu3edOo+*2yV&4Y8Z%qOOG?keki~JT@kYh-{CiMuRGIcCy%G(Sv}B z4)UJ&RwpV*b6Mo;UN{}JH<|H;D}khXiRecC<^x4{UJbqmu&^;;(@4Q07B5D9odiuzMzBoI)ye8~|zjkcl08BGS)@9jpvdJmQ9* zz`tXoEdGR97o`88Z)k(@jXZAd_?!3MqOOu!17`Vj*7baSJb@odsZ^P!v#E*7vn5+etoW^%z0gPxXIN4$J4~Z1p zDr4X3$x+kjUM@}qm97X?XN&b0YQ!PT)lz9kkypXLxY4cX`lts_r>0$!b;Q=0&?;Fj zZW6x4ewjIVP|j@!QqOBHR}H-ZLD@o^lSI+4R;u z>#A%;58GL|l%_SL;Tw7u4t>rL)Lf!ZR-!qb@;sj7X?-N@Ym9p|rT(>NlNVW+K!C%r zKVJ83Tac!M>n;x?Kebkmjs^7!-*X&go$^tG0Q=8`9F+3_W;G;P{BqrcyyJ>dg?RoW z@YGvSJb#0lcl75m@wcwvZj55`1hh5BZ_k~hC0w2TtWKIpKe00mC^)J*E;|ZE z-=$7GE1dw(0~6uFXcv~&m;0C6@lN4I;A;wa#Z7h$ zlUr)ni>s=IA-zW{DDO2^e5LK21ZW4UeIG{CaSe;_Ss<0I_9aOTm-7NxT(cglQytxo$XG6bcxdYjUqWykKN!(v+Fvgs?&sd#M!~qNQPIi zL}G^8nul@@CH$m^`^>W2vUGEjvz(-#pCsnH_4L4n5mn ziIg3Ob#VXI-}sT2lGdyuDw*@g@!{Zn-sf31pWDbg3PXKlulf$c2lbVY>thG_uUDU< zKe6RedN(FLe|gVU*$o|O&~B3h`Hfw=)^;f#SQJTrwU9T3H6#@FEfIkR43%1aEidnZ z_|wvB_l?gK2oWQD&a7XT8$R`cJm5W_9p&xtQ<~*PdSdbtUhlzzNBeb$r*nx)s2_%1 z@Gr|`b+NHXms0M&~3&TY9LA{%Q$IS?6@$7NHa{j-`n6?>7O^<`FBKI#t5I6}$FC97 zxI9~fU0_qt7f<(y#FOdSO`ywU&%kAEOJYIorPq1;43||rwXyLTMFY<F6PTDtPJmnHF{k>Y7x-Roi|^<2%S@DFtYhH5bCDDC$BM# Z5#7qDK(9JxaUplXR*Jq4nGyK5{6F;|q8b1I literal 0 HcmV?d00001 diff --git a/tests/test_g1.F90 b/tests/test_g1.F90 index f488faff..f9d44648 100644 --- a/tests/test_g1.F90 +++ b/tests/test_g1.F90 @@ -56,9 +56,9 @@ end subroutine getidx2 else if (nlen .ne. 204) stop 23 endif - do j = 1, nlen - print '(i3, x, z2.2)', j, cbuf(j) - end do + ! do j = 1, nlen + ! print '(i3, x, z2.2)', j, cbuf(j) + ! end do ! Break out the index record into component values and check them for correctness. mypos = 0 @@ -103,17 +103,11 @@ end subroutine getidx2 if (total_bytes .ne. 15254) stop 39 mypos = mypos + INT8_BITS - print *, 'test_getidx expecting grib_version after byte, bit ', mypos, mypos/8 - print '(z2.2)', cbuf(mypos/8 + 0) - print '(z2.2)', cbuf(mypos/8 + 1) - print '(z2.2)', cbuf(mypos/8 + 2) - print '(z2.2)', cbuf(mypos/8 + 3) call g2_gbytec(cbuf, grib_version, mypos, INT1_BITS) print *, grib_version, mypos if (grib_version .ne. 2) stop 40 mypos = mypos + INT1_BITS call g2_gbytec(cbuf, discipline, mypos, INT1_BITS) - print *, 'discipline', discipline if (discipline .ne. 0) stop 41 mypos = mypos + INT1_BITS call g2_gbytec(cbuf, field_number, mypos, INT2_BITS) From dcaad64a104d8f53a9244fdc1ce213f99209f62d Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 06:07:33 -0700 Subject: [PATCH 32/69] clean up --- tests/test_g1.F90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_g1.F90 b/tests/test_g1.F90 index f9d44648..493db6dd 100644 --- a/tests/test_g1.F90 +++ b/tests/test_g1.F90 @@ -1,9 +1,11 @@ ! This is a test program for NCEPLIBS-g2. ! -! This program tests getidx(). +! This program tests getidx() with a file containing only one GRIB2 +! message, the first message from file +! gdaswave.t00z.wcoast.0p16.f000.grib2. ! -! Ed Hartnett 7/26/22 -program test_getidx +! Ed Hartnett 2/12/24 +program test_g1 use bacio_module implicit none @@ -14,10 +16,10 @@ program test_getidx integer :: lugb = 3 integer :: nlen, nnum, iret integer :: index_rec_len, b2s_message, b2s_lus, b2s_gds, b2s_pds, b2s_drs, b2s_bms, b2s_data - integer :: total_bytes, grib_version, discipline, field_number, i, idxver, j + integer :: total_bytes, grib_version, discipline, field_number, i, idxver integer (kind = 8) :: b2s_message8 - integer :: lu_gdas = 4, lu_gdas_index = 5, mypos + integer :: mypos integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) @@ -127,4 +129,4 @@ end subroutine getidx2 print *, 'SUCCESS!...' -end program test_getidx +end program test_g1 From 8fa40b408d2d4a5c0c0db6411db59fd53fb5b2e0 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 07:42:43 -0700 Subject: [PATCH 33/69] more index development --- src/g2index.F90 | 4 +-- src/getgb2l.F90 | 91 +++++++++++++++++++++++-------------------------- 2 files changed, 44 insertions(+), 51 deletions(-) diff --git a/src/g2index.F90 b/src/g2index.F90 index 15501a1b..84686a2a 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -837,7 +837,7 @@ end subroutine gf_unpack5 ! Get length of ids. call g2_gbytec(cbuf, lsec1, (ipos + inc + 44) * 8, 4 * 8) iof = 0 - call gf_unpack1(cbuf(ipos + 45), lsec1, iof, gfld%idsect, gfld%idsectlen, icnd) + call gf_unpack1(cbuf(ipos + inc + 45), lsec1, iof, gfld%idsect, gfld%idsectlen, icnd) if (icnd .eq. 0) then match1 = .true. do i = 1, gfld%idsectlen @@ -924,7 +924,7 @@ end subroutine gf_unpack5 ! If request is found set values for derived type gfld and return. if (match1 .and. match3 .and. match4) then - lpos = ipos + 1 + lpos = ipos + inc + 1 call g2_gbytec(cbuf, gfld%version, (ipos + inc + 40) * 8, 1 * 8) call g2_gbytec(cbuf, gfld%ifldnum, (ipos + inc + 42) * 8, 2 * 8) gfld%unpacked = .false. diff --git a/src/getgb2l.F90 b/src/getgb2l.F90 index 9e72cf4c..9c43028f 100644 --- a/src/getgb2l.F90 +++ b/src/getgb2l.F90 @@ -1,50 +1,43 @@ !> @file -!> @brief This subroutine reads and unpacks a local use section from a -!> GRIB2 message. +!> @brief Read and unpack a local use section from a GRIB2 index +!> record. !> @author Stephen Gilbert @date 2002-05-07 -!> This subroutine reads and unpacks a local use section from a GRIB2 -!> message. +!> Read and unpack a local use section from a GRIB2 index record. !> !> This subroutine decodes information for the selected grib field and !> returns it in a derived type variable, gfld. gfld is of type @ref !> grib_mod::gribfield. Users of this routine will need to include the !> line "use grib_mod" in their calling routine. !> -!> This subprogram is intended for private use by getgb2 routines +!> This subprogram is intended for private use by getgb2() routine !> only. !> !> Note that derived type gribfield contains pointers to many arrays -!> of data. The memory for these arrays is allocated when the values -!> in the arrays are set, to help minimize problems with array -!> overloading. Because of this users should free this memory, when it -!> is no longer needed, by an explicit call to subroutine gf_free(). +!> of data. Users must free this memory with gf_free(). !> !> @param[in] LUGB integer unit of the unblocked grib data file. -!> @param[in] CINDEX index record of the grib field (see docblock of -!> subroutine ixgb2 for description of an index record.) +!> @param[in] CINDEX index record of the grib field (see ix2gb2() for +!> description of an index record.) !> @param[out] GFLD derived type gribfield @ref grib_mod::gribfield. !> @param[out] IRET integer return code !> - 0 all ok !> - 97 error reading grib file !> - other gf_getfld grib2 unpacker return code !> -!> @note Do not engage the same logical unit from more than one -!> processor. -!> !> @author Stephen Gilbert @date 2002-05-07 -SUBROUTINE GETGB2L(LUGB, CINDEX, GFLD, IRET) - USE GRIB_MOD +subroutine getgb2l(lugb, cindex, gfld, iret) + use grib_mod implicit none - INTEGER, INTENT(IN) :: LUGB - CHARACTER(LEN = 1), INTENT(IN) :: CINDEX(*) - TYPE(GRIBFIELD) :: GFLD - INTEGER, INTENT(OUT) :: IRET + integer, intent(in) :: lugb + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret - INTEGER :: LSKIP, SKIP2 - CHARACTER(LEN = 1):: CSIZE(4) - CHARACTER(LEN = 1), ALLOCATABLE :: CTEMP(:) + integer :: lskip, skip2 + character(len = 1):: csize(4) + character(len = 1), allocatable :: ctemp(:) integer :: ilen, iofst, iskip, lread, ierr interface @@ -59,36 +52,36 @@ end subroutine gf_unpack2 end interface ! Get info. - NULLIFY(gfld%local) - IRET = 0 - CALL G2_GBYTEC(CINDEX, LSKIP, 4 * 8, 4 * 8) - CALL G2_GBYTEC(CINDEX, SKIP2, 8 * 8, 4 * 8) + nullify(gfld%local) + iret = 0 + call g2_gbytec(cindex, lskip, 4 * 8, 4 * 8) + call g2_gbytec(cindex, skip2, 8 * 8, 4 * 8) ! Read and unpack local use section, if present. - IF (SKIP2 .NE. 0) THEN - ISKIP = LSKIP + SKIP2 + if (skip2 .ne. 0) then + iskip = lskip + skip2 ! Get length of section. - CALL BAREAD(LUGB, ISKIP, 4, LREAD, CSIZE) - CALL G2_GBYTEC(CSIZE, ILEN, 0, 32) - ALLOCATE(CTEMP(ILEN)) + call baread(lugb, iskip, 4, lread, csize) + call g2_gbytec(csize, ilen, 0, 32) + allocate(ctemp(ilen)) ! Read in section. - CALL BAREAD(LUGB, ISKIP, ILEN, LREAD, CTEMP) - IF (ILEN .NE. LREAD) THEN - IRET = 97 - DEALLOCATE(CTEMP) - RETURN - ENDIF - IOFST = 0 - CALL GF_UNPACK2(CTEMP, ILEN, IOFST, gfld%locallen, gfld%local, ierr) - IF (IERR .NE. 0) THEN - IRET = 98 - DEALLOCATE(CTEMP) - RETURN - ENDIF - DEALLOCATE(CTEMP) - ELSE + call baread(lugb, iskip, ilen, lread, ctemp) + if (ilen .ne. lread) then + iret = 97 + deallocate(ctemp) + return + endif + iofst = 0 + call gf_unpack2(ctemp, ilen, iofst, gfld%locallen, gfld%local, ierr) + if (ierr .ne. 0) then + iret = 98 + deallocate(ctemp) + return + endif + deallocate(ctemp) + else gfld%locallen = 0 - ENDIF -END SUBROUTINE GETGB2L + endif +end subroutine getgb2l From 3b4e0c80a692656bbfee4e15131fc213c8fa0811 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 07:50:34 -0700 Subject: [PATCH 34/69] more index work --- src/getgb2l.F90 | 57 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/getgb2l.F90 b/src/getgb2l.F90 index 9c43028f..c3d4cdc5 100644 --- a/src/getgb2l.F90 +++ b/src/getgb2l.F90 @@ -1,11 +1,12 @@ !> @file !> @brief Read and unpack a local use section from a GRIB2 index -!> record. +!> record and file. !> @author Stephen Gilbert @date 2002-05-07 -!> Read and unpack a local use section from a GRIB2 index record. +!> Read and unpack a local use section from a GRIB2 index record and +!> file. !> -!> This subroutine decodes information for the selected grib field and +!> This subroutine decodes information for the selected GRIB2 field and !> returns it in a derived type variable, gfld. gfld is of type @ref !> grib_mod::gribfield. Users of this routine will need to include the !> line "use grib_mod" in their calling routine. @@ -35,6 +36,54 @@ subroutine getgb2l(lugb, cindex, gfld, iret) type(gribfield) :: gfld integer, intent(out) :: iret + interface + subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) + use grib_mod + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + end subroutine getgb2l2 + end interface + + call getgb2l2(lugb, 1, cindex, gfld, iret) + +end subroutine getgb2l + +!> Read and unpack a local use section from a GRIB2 index record and +!> file. +!> +!> This subroutine decodes information for the selected GRIB2 field and +!> returns it in a derived type variable, gfld. gfld is of type @ref +!> grib_mod::gribfield. Users of this routine will need to include the +!> line "use grib_mod" in their calling routine. +!> +!> This subprogram is intended for private use by getgb2() routine +!> only. +!> +!> Note that derived type gribfield contains pointers to many arrays +!> of data. Users must free this memory with gf_free(). +!> +!> @param[in] lugb integer unit of the unblocked grib data file. +!> @param[in] idxver Index version of the cindex buffer. +!> @param[in] cindex index record of the grib field (see ix2gb2() for +!> description of an index record.) +!> @param[out] gfld derived type gribfield @ref grib_mod::gribfield. +!> @param[out] iret integer return code +!> - 0 all ok +!> - 97 error reading grib file +!> - other gf_getfld grib2 unpacker return code +!> +!> @author Stephen Gilbert @date 2002-05-07 +subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) + use grib_mod + implicit none + + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + integer :: lskip, skip2 character(len = 1):: csize(4) character(len = 1), allocatable :: ctemp(:) @@ -84,4 +133,4 @@ end subroutine gf_unpack2 else gfld%locallen = 0 endif -end subroutine getgb2l +end subroutine getgb2l2 From 6dbd19f721ba2c4041763863aadbbec74285887a Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 07:58:05 -0700 Subject: [PATCH 35/69] combined source files --- src/CMakeLists.txt | 2 +- src/g2index.F90 | 4 +- src/getgb2.F90 | 130 +++++++++++++++++++++++++++++++++++++++++++ src/getgb2l.F90 | 136 --------------------------------------------- 4 files changed, 133 insertions(+), 139 deletions(-) delete mode 100644 src/getgb2l.F90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0bfc3fc5..f509990e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ # These are the fortran source files. set(fortran_src addfield.F90 addgrid.F90 addlocal.F90 cmplxpack.F90 compack.F90 comunpack.F90 drstemplates.F90 g2_gbytesc.F90 g2grids.F90 -gb_info.F90 getdim.F90 getfield.F90 getgb2.F90 getgb2l.F90 getgb2p.F90 +gb_info.F90 getdim.F90 getfield.F90 getgb2.F90 getgb2p.F90 getgb2r.F90 getgb2rp.F90 g2index.F90 getlocal.F90 getpoly.F90 gettemplates.F90 gf_free.F90 gf_getfld.F90 g2unpack.F90 gribcreate.F90 gribend.F90 gribinfo.F90 ${CMAKE_CURRENT_BINARY_DIR}/gribmod.F90 diff --git a/src/g2index.F90 b/src/g2index.F90 index 84686a2a..25a81e26 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -121,7 +121,7 @@ subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) integer, parameter :: maxidx = 10000 integer (kind = 8), parameter :: msk1 = 32000_8, msk2 = 4000_8 integer :: lux - integer :: irgi, mskp, nmess, i, myidxver + integer :: irgi, mskp, nmess, i type gindex integer :: nlen @@ -924,7 +924,7 @@ end subroutine gf_unpack5 ! If request is found set values for derived type gfld and return. if (match1 .and. match3 .and. match4) then - lpos = ipos + inc + 1 + lpos = ipos + 1 call g2_gbytec(cbuf, gfld%version, (ipos + inc + 40) * 8, 1 * 8) call g2_gbytec(cbuf, gfld%ifldnum, (ipos + inc + 42) * 8, 2 * 8) gfld%unpacked = .false. diff --git a/src/getgb2.F90 b/src/getgb2.F90 index 67f2690f..fe255228 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -167,3 +167,133 @@ end subroutine getgb2s2 endif k = jk end subroutine getgb2 + +!> Read and unpack a local use section from a GRIB2 index record +!> (index format 1) and GRIB2 file. +!> +!> This subprogram is intended for private use by getgb2() routine +!> only. +!> +!> Note that derived type gribfield contains pointers to many arrays +!> of data. Users must free this memory with gf_free(). +!> +!> This subroutine supports only index format 1, which will not work +!> for files > 2 GB. New code should use getgb2l2(). +!> +!> @param[in] lugb integer unit of the unblocked grib data file. +!> @param[in] cindex index record of the grib field (see ix2gb2() for +!> description of an index record.) +!> @param[out] gfld derived type gribfield @ref grib_mod::gribfield. +!> @param[out] iret integer return code +!> - 0 all ok +!> - 97 error reading grib file +!> - other gf_getfld grib2 unpacker return code +!> +!> @author Stephen Gilbert @date 2002-05-07 +subroutine getgb2l(lugb, cindex, gfld, iret) + use grib_mod + implicit none + + integer, intent(in) :: lugb + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + + interface + subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) + use grib_mod + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + end subroutine getgb2l2 + end interface + + call getgb2l2(lugb, 1, cindex, gfld, iret) + +end subroutine getgb2l + +!> Read and unpack a local use section from a GRIB2 index record +!> (index format 1 or 2) and GRIB2 file. +!> +!> This subroutine decodes information for the selected GRIB2 field and +!> returns it in a derived type variable, gfld. gfld is of type @ref +!> grib_mod::gribfield. Users of this routine will need to include the +!> line "use grib_mod" in their calling routine. +!> +!> This subprogram is intended for private use by getgb2() routine +!> only. +!> +!> Note that derived type gribfield contains pointers to many arrays +!> of data. Users must free this memory with gf_free(). +!> +!> @param[in] lugb integer unit of the unblocked grib data file. +!> @param[in] idxver Index version of the cindex buffer. +!> @param[in] cindex index record of the grib field (see ix2gb2() for +!> description of an index record.) +!> @param[out] gfld derived type gribfield @ref grib_mod::gribfield. +!> @param[out] iret integer return code +!> - 0 all ok +!> - 97 error reading grib file +!> - other gf_getfld grib2 unpacker return code +!> +!> @author Stephen Gilbert @date 2002-05-07 +subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) + use grib_mod + implicit none + + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + + integer :: lskip, skip2 + character(len = 1):: csize(4) + character(len = 1), allocatable :: ctemp(:) + integer :: ilen, iofst, iskip, lread, ierr + + interface + subroutine gf_unpack2(cgrib, lcgrib, iofst, lencsec2, csec2, ierr) + character(len = 1), intent(in) :: cgrib(lcgrib) + integer, intent(in) :: lcgrib + integer, intent(inout) :: iofst + integer, intent(out) :: lencsec2 + integer, intent(out) :: ierr + character(len = 1), pointer, dimension(:) :: csec2 + end subroutine gf_unpack2 + end interface + + ! Get info. + nullify(gfld%local) + iret = 0 + call g2_gbytec(cindex, lskip, 4 * 8, 4 * 8) + call g2_gbytec(cindex, skip2, 8 * 8, 4 * 8) + + ! Read and unpack local use section, if present. + if (skip2 .ne. 0) then + iskip = lskip + skip2 + + ! Get length of section. + call baread(lugb, iskip, 4, lread, csize) + call g2_gbytec(csize, ilen, 0, 32) + allocate(ctemp(ilen)) + + ! Read in section. + call baread(lugb, iskip, ilen, lread, ctemp) + if (ilen .ne. lread) then + iret = 97 + deallocate(ctemp) + return + endif + iofst = 0 + call gf_unpack2(ctemp, ilen, iofst, gfld%locallen, gfld%local, ierr) + if (ierr .ne. 0) then + iret = 98 + deallocate(ctemp) + return + endif + deallocate(ctemp) + else + gfld%locallen = 0 + endif +end subroutine getgb2l2 diff --git a/src/getgb2l.F90 b/src/getgb2l.F90 deleted file mode 100644 index c3d4cdc5..00000000 --- a/src/getgb2l.F90 +++ /dev/null @@ -1,136 +0,0 @@ -!> @file -!> @brief Read and unpack a local use section from a GRIB2 index -!> record and file. -!> @author Stephen Gilbert @date 2002-05-07 - -!> Read and unpack a local use section from a GRIB2 index record and -!> file. -!> -!> This subroutine decodes information for the selected GRIB2 field and -!> returns it in a derived type variable, gfld. gfld is of type @ref -!> grib_mod::gribfield. Users of this routine will need to include the -!> line "use grib_mod" in their calling routine. -!> -!> This subprogram is intended for private use by getgb2() routine -!> only. -!> -!> Note that derived type gribfield contains pointers to many arrays -!> of data. Users must free this memory with gf_free(). -!> -!> @param[in] LUGB integer unit of the unblocked grib data file. -!> @param[in] CINDEX index record of the grib field (see ix2gb2() for -!> description of an index record.) -!> @param[out] GFLD derived type gribfield @ref grib_mod::gribfield. -!> @param[out] IRET integer return code -!> - 0 all ok -!> - 97 error reading grib file -!> - other gf_getfld grib2 unpacker return code -!> -!> @author Stephen Gilbert @date 2002-05-07 -subroutine getgb2l(lugb, cindex, gfld, iret) - use grib_mod - implicit none - - integer, intent(in) :: lugb - character(len = 1), intent(in) :: cindex(*) - type(gribfield) :: gfld - integer, intent(out) :: iret - - interface - subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) - use grib_mod - integer, intent(in) :: lugb, idxver - character(len = 1), intent(in) :: cindex(*) - type(gribfield) :: gfld - integer, intent(out) :: iret - end subroutine getgb2l2 - end interface - - call getgb2l2(lugb, 1, cindex, gfld, iret) - -end subroutine getgb2l - -!> Read and unpack a local use section from a GRIB2 index record and -!> file. -!> -!> This subroutine decodes information for the selected GRIB2 field and -!> returns it in a derived type variable, gfld. gfld is of type @ref -!> grib_mod::gribfield. Users of this routine will need to include the -!> line "use grib_mod" in their calling routine. -!> -!> This subprogram is intended for private use by getgb2() routine -!> only. -!> -!> Note that derived type gribfield contains pointers to many arrays -!> of data. Users must free this memory with gf_free(). -!> -!> @param[in] lugb integer unit of the unblocked grib data file. -!> @param[in] idxver Index version of the cindex buffer. -!> @param[in] cindex index record of the grib field (see ix2gb2() for -!> description of an index record.) -!> @param[out] gfld derived type gribfield @ref grib_mod::gribfield. -!> @param[out] iret integer return code -!> - 0 all ok -!> - 97 error reading grib file -!> - other gf_getfld grib2 unpacker return code -!> -!> @author Stephen Gilbert @date 2002-05-07 -subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) - use grib_mod - implicit none - - integer, intent(in) :: lugb, idxver - character(len = 1), intent(in) :: cindex(*) - type(gribfield) :: gfld - integer, intent(out) :: iret - - integer :: lskip, skip2 - character(len = 1):: csize(4) - character(len = 1), allocatable :: ctemp(:) - integer :: ilen, iofst, iskip, lread, ierr - - interface - subroutine gf_unpack2(cgrib, lcgrib, iofst, lencsec2, csec2, ierr) - character(len = 1), intent(in) :: cgrib(lcgrib) - integer, intent(in) :: lcgrib - integer, intent(inout) :: iofst - integer, intent(out) :: lencsec2 - integer, intent(out) :: ierr - character(len = 1), pointer, dimension(:) :: csec2 - end subroutine gf_unpack2 - end interface - - ! Get info. - nullify(gfld%local) - iret = 0 - call g2_gbytec(cindex, lskip, 4 * 8, 4 * 8) - call g2_gbytec(cindex, skip2, 8 * 8, 4 * 8) - - ! Read and unpack local use section, if present. - if (skip2 .ne. 0) then - iskip = lskip + skip2 - - ! Get length of section. - call baread(lugb, iskip, 4, lread, csize) - call g2_gbytec(csize, ilen, 0, 32) - allocate(ctemp(ilen)) - - ! Read in section. - call baread(lugb, iskip, ilen, lread, ctemp) - if (ilen .ne. lread) then - iret = 97 - deallocate(ctemp) - return - endif - iofst = 0 - call gf_unpack2(ctemp, ilen, iofst, gfld%locallen, gfld%local, ierr) - if (ierr .ne. 0) then - iret = 98 - deallocate(ctemp) - return - endif - deallocate(ctemp) - else - gfld%locallen = 0 - endif -end subroutine getgb2l2 From 2de5feeb6cdc5935a6cd8de3556f1cc9644fece1 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 09:26:00 -0700 Subject: [PATCH 36/69] more index development --- src/getgb2.F90 | 34 ++++++++++++++++++++++++++++------ tests/g1.grib2 | Bin 15254 -> 15254 bytes 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/getgb2.F90 b/src/getgb2.F90 index fe255228..655f4d01 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -138,6 +138,13 @@ subroutine getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn type(gribfield), intent(out) :: gfld integer, intent(out) :: lpos, iret end subroutine getgb2s2 + subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) + use grib_mod + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + end subroutine getgb2l2 end interface ! Determine whether index buffer needs to be initialized. @@ -159,7 +166,7 @@ end subroutine getgb2s2 endif ! Read local use section, if available. - call getgb2l(lugb, cbuf(lpos), gfld, iret) + call getgb2l2(lugb, idxver, cbuf(lpos), gfld, iret) ! Read and unpack grib record. if (unpack) then @@ -248,9 +255,13 @@ subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) integer, intent(out) :: iret integer :: lskip, skip2 + integer (kind = 8) :: lskip8, iskip8, lread8, ilen8 character(len = 1):: csize(4) character(len = 1), allocatable :: ctemp(:) integer :: ilen, iofst, iskip, lread, ierr + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) + integer :: mypos interface subroutine gf_unpack2(cgrib, lcgrib, iofst, lencsec2, csec2, ierr) @@ -266,21 +277,32 @@ end subroutine gf_unpack2 ! Get info. nullify(gfld%local) iret = 0 - call g2_gbytec(cindex, lskip, 4 * 8, 4 * 8) - call g2_gbytec(cindex, skip2, 8 * 8, 4 * 8) + mypos = INT4_BITS + if (idxver .eq. 1) then + call g2_gbytec(cindex, lskip, mypos, INT4_BITS) + mypos = mypos + INT4_BITS + else + call g2_gbytec8(cindex, lskip8, mypos, INT8_BITS) + lskip = int(lskip8, kind(4)) + mypos = mypos + INT8_BITS + endif + call g2_gbytec(cindex, skip2, mypos, INT4_BITS) ! Read and unpack local use section, if present. if (skip2 .ne. 0) then iskip = lskip + skip2 + iskip8 = lskip8 + skip2 ! Get length of section. - call baread(lugb, iskip, 4, lread, csize) + call bareadl(lugb, iskip8, 4_8, lread8, csize) +! call baread(lugb, iskip, 4, lread, csize) call g2_gbytec(csize, ilen, 0, 32) allocate(ctemp(ilen)) + ilen8 = ilen ! Read in section. - call baread(lugb, iskip, ilen, lread, ctemp) - if (ilen .ne. lread) then + call bareadl(lugb, iskip8, ilen8, lread8, ctemp) + if (ilen8 .ne. lread8) then iret = 97 deallocate(ctemp) return diff --git a/tests/g1.grib2 b/tests/g1.grib2 index c61316c2665e2088dfff6e157a577ee34b9dfc44..541b275217ff4741e1e01d60db6976a193743b74 100644 GIT binary patch delta 13 UcmbPMKCOI#1Y`7OMv1A)044YYvj6}9 delta 13 UcmbPMKCOI#1moGwj1p6o0Vt#eB>(^b From 2face2c23ec747c5fde272965c41919bd47fd74f Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Mon, 12 Feb 2024 09:28:06 -0700 Subject: [PATCH 37/69] more index development --- src/getgb2.F90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/getgb2.F90 b/src/getgb2.F90 index 655f4d01..49626ef7 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -258,7 +258,7 @@ subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) integer (kind = 8) :: lskip8, iskip8, lread8, ilen8 character(len = 1):: csize(4) character(len = 1), allocatable :: ctemp(:) - integer :: ilen, iofst, iskip, lread, ierr + integer :: ilen, iofst, ierr integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) integer :: mypos @@ -281,21 +281,19 @@ end subroutine gf_unpack2 if (idxver .eq. 1) then call g2_gbytec(cindex, lskip, mypos, INT4_BITS) mypos = mypos + INT4_BITS + lskip8 = lskip else call g2_gbytec8(cindex, lskip8, mypos, INT8_BITS) - lskip = int(lskip8, kind(4)) mypos = mypos + INT8_BITS endif call g2_gbytec(cindex, skip2, mypos, INT4_BITS) ! Read and unpack local use section, if present. if (skip2 .ne. 0) then - iskip = lskip + skip2 iskip8 = lskip8 + skip2 ! Get length of section. call bareadl(lugb, iskip8, 4_8, lread8, csize) -! call baread(lugb, iskip, 4, lread, csize) call g2_gbytec(csize, ilen, 0, 32) allocate(ctemp(ilen)) ilen8 = ilen From afb91c3af674506bf76e73fa07acaf7884721e6d Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 13 Feb 2024 06:50:27 -0700 Subject: [PATCH 38/69] more index work --- src/getgb2rp.F90 | 233 +++++++++++++++++++++++++++++------------------ 1 file changed, 144 insertions(+), 89 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 10dfaf86..65ed9042 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -41,8 +41,63 @@ subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) integer, intent(in) :: lugb character(len = 1), intent(in) :: cindex(*) logical, intent(in) :: extract + character(len = 1), pointer, dimension(:) :: gribm integer, intent(out) :: leng, iret + + interface + subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + logical, intent(in) :: extract + character(len = 1), pointer, dimension(:) :: gribm + integer, intent(out) :: leng, iret + end subroutine getgb2rp2 + end interface + + call getgb2rp2(lugb, 1, cindex, extract, gribm, leng, iret) + +end subroutine getgb2rp + +!> Extract a grib message from a file given the index of the requested +!> field. +!> +!> The GRIB message returned can contain only the requested field +!> (extract=.true.), or the complete GRIB message originally +!> containing the desired field can be returned (extract=.false.) even +!> if other fields were included in the GRIB message. +!> +!> If the GRIB field is not found, then the return code will be +!> nonzero. +!> +!> @note For files greater than 2 GB, this subroutine will only work +!> if the message is within the first 2 GB of the file. +!> +!> @param[in] lugb integer unit of the unblocked grib data file. file +!> must be opened with [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this +!> routine. +!> @param[in] cindex Index record of the grib field (see docunentation of +!> subroutine ixgb2() for description of an index record.) +!> @param[in] extract Logical value indicating whether to return a +!> GRIB2 message with just the requested field, or the entire +!> GRIB2 message containing the requested field. +!> - .true. = return grib2 message containing only the requested field. +!> - .false. = return entire grib2 message containing the requested field. +!> @param[out] gribm Returned grib message. +!> @param[out] leng Length of returned grib message in bytes. +!> @param[out] iret Return code: +!> - 0 No error. +!> - 97 Error reading grib file. +!> +!> @author Stephen Gilbert @date 2003-12-31 +subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) + implicit none + + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + logical, intent(in) :: extract character(len = 1), pointer, dimension(:) :: gribm + integer, intent(out) :: leng, iret integer, parameter :: zero = 0 character(len = 1), allocatable, dimension(:) :: csec2, csec6, csec7 @@ -54,115 +109,115 @@ subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) iret = 0 ! Extract grib message from file. - IF (EXTRACT) THEN - LEN0 = 16 - LEN8 = 4 - CALL G2_GBYTEC(CINDEX, ISKIP, 4*8, 4*8) ! BYTES TO SKIP IN FILE - CALL G2_GBYTEC(CINDEX, ISKP2, 8*8, 4*8) ! BYTES TO SKIP FOR section 2 + if (extract) then + len0 = 16 + len8 = 4 + call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file + call g2_gbytec(cindex, iskp2, 8*8, 4*8) ! bytes to skip for section 2 if (iskp2 .gt. 0) then - CALL BAREAD(LUGB, ISKIP + ISKP2, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN2, 0, 4*8) ! LENGTH OF SECTION 2 - ALLOCATE(csec2(len2)) - CALL BAREAD(LUGB, ISKIP + ISKP2, LEN2, LREAD, csec2) + call baread(lugb, iskip + iskp2, 4, lread, ctemp) + call g2_gbytec(ctemp, len2, 0, 4*8) ! length of section 2 + allocate(csec2(len2)) + call baread(lugb, iskip + iskp2, len2, lread, csec2) else - LEN2 = 0 + len2 = 0 endif - CALL G2_GBYTEC(CINDEX, LEN1, 44*8, 4*8) ! LENGTH OF SECTION 1 - IPOS = 44 + LEN1 - CALL G2_GBYTEC(CINDEX, LEN3, IPOS*8, 4*8) ! LENGTH OF SECTION 3 - IPOS = IPOS + LEN3 - CALL G2_GBYTEC(CINDEX, LEN4, IPOS*8, 4*8) ! LENGTH OF SECTION 4 - IPOS = IPOS + LEN4 - CALL G2_GBYTEC(CINDEX, LEN5, IPOS*8, 4*8) ! LENGTH OF SECTION 5 - IPOS = IPOS + LEN5 - CALL G2_GBYTEC(CINDEX, LEN6, IPOS*8, 4*8) ! LENGTH OF SECTION 6 - IPOS = IPOS + 5 - CALL G2_GBYTEC(CINDEX, IBMAP, IPOS*8, 1*8) ! Bitmap indicator - IF (IBMAP .eq. 254) THEN - CALL G2_GBYTEC(CINDEX, ISKP6, 24*8, 4*8) ! BYTES TO SKIP FOR section 6 - CALL BAREAD(LUGB, ISKIP + ISKP6, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN6, 0, 4*8) ! LENGTH OF SECTION 6 - ENDIF - - ! READ IN SECTION 7 from file - CALL G2_GBYTEC(CINDEX, ISKP7, 28*8, 4*8) ! BYTES TO SKIP FOR section 7 - CALL BAREAD(LUGB, ISKIP + ISKP7, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN7, 0, 4*8) ! LENGTH OF SECTION 7 - ALLOCATE(csec7(len7)) - CALL BAREAD(LUGB, ISKIP + ISKP7, LEN7, LREAD, csec7) - - LENG = LEN0 + LEN1 + LEN2 + LEN3 + LEN4 + LEN5 + LEN6 + LEN7 + LEN8 - IF (.NOT. ASSOCIATED(GRIBM)) ALLOCATE(GRIBM(LENG)) + call g2_gbytec(cindex, len1, 44*8, 4*8) ! length of section 1 + ipos = 44 + len1 + call g2_gbytec(cindex, len3, ipos*8, 4*8) ! length of section 3 + ipos = ipos + len3 + call g2_gbytec(cindex, len4, ipos*8, 4*8) ! length of section 4 + ipos = ipos + len4 + call g2_gbytec(cindex, len5, ipos*8, 4*8) ! length of section 5 + ipos = ipos + len5 + call g2_gbytec(cindex, len6, ipos*8, 4*8) ! length of section 6 + ipos = ipos + 5 + call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator + if (ibmap .eq. 254) then + call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + endif + + ! Read in section 7 from file. + call g2_gbytec(cindex, iskp7, 28*8, 4*8) ! bytes to skip for section 7 + call baread(lugb, iskip + iskp7, 4, lread, ctemp) + call g2_gbytec(ctemp, len7, 0, 4*8) ! length of section 7 + allocate(csec7(len7)) + call baread(lugb, iskip + iskp7, len7, lread, csec7) + + leng = len0 + len1 + len2 + len3 + len4 + len5 + len6 + len7 + len8 + if (.not. associated(gribm)) allocate(gribm(leng)) ! Create Section 0 - GRIBM(1) = 'G' - GRIBM(2) = 'R' - GRIBM(3) = 'I' - GRIBM(4) = 'B' - GRIBM(5) = CHAR(0) - GRIBM(6) = CHAR(0) - GRIBM(7) = CINDEX(42) - GRIBM(8) = CINDEX(41) - GRIBM(9) = CHAR(0) - GRIBM(10) = CHAR(0) - GRIBM(11) = CHAR(0) - GRIBM(12) = CHAR(0) - CALL G2_SBYTEC(GRIBM, LENG, 12*8, 4*8) + gribm(1) = 'G' + gribm(2) = 'R' + gribm(3) = 'I' + gribm(4) = 'B' + gribm(5) = char(0) + gribm(6) = char(0) + gribm(7) = cindex(42) + gribm(8) = cindex(41) + gribm(9) = char(0) + gribm(10) = char(0) + gribm(11) = char(0) + gribm(12) = char(0) + call g2_sbytec(gribm, leng, 12*8, 4*8) ! Copy Section 1 - GRIBM(17:16 + LEN1) = CINDEX(45:44 + LEN1) - lencur = 16 + LEN1 + gribm(17:16 + len1) = cindex(45:44 + len1) + lencur = 16 + len1 ipos = 44 + len1 - ! Copy Section 2, if necessary + ! copy section 2, if necessary if (iskp2 .gt. 0) then - GRIBM(lencur + 1:lencur + LEN2) = csec2(1:LEN2) - lencur = lencur + LEN2 + gribm(lencur + 1:lencur + len2) = csec2(1:len2) + lencur = lencur + len2 endif ! Copy Sections 3 through 5 - GRIBM(lencur + 1:lencur + LEN3 + LEN4 + LEN5) = CINDEX(ipos + 1:ipos + LEN3 + LEN4 + LEN5) - lencur = lencur + LEN3 + LEN4 + LEN5 - ipos = ipos + LEN3 + LEN4 + LEN5 + gribm(lencur + 1:lencur + len3 + len4 + len5) = cindex(ipos + 1:ipos + len3 + len4 + len5) + lencur = lencur + len3 + len4 + len5 + ipos = ipos + len3 + len4 + len5 ! Copy Section 6 - if (LEN6 .eq. 6 .AND. IBMAP .ne. 254) then - GRIBM(lencur + 1:lencur + LEN6) = CINDEX(ipos + 1:ipos + LEN6) - lencur = lencur + LEN6 + if (len6 .eq. 6 .and. ibmap .ne. 254) then + gribm(lencur + 1:lencur + len6) = cindex(ipos + 1:ipos + len6) + lencur = lencur + len6 else - CALL G2_GBYTEC(CINDEX, ISKP6, 24*8, 4*8) ! BYTES TO SKIP FOR section 6 - CALL BAREAD(LUGB, ISKIP + ISKP6, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN6, 0, 4*8) ! LENGTH OF SECTION 6 - ALLOCATE(csec6(len6)) - CALL BAREAD(LUGB, ISKIP + ISKP6, LEN6, LREAD, csec6) - GRIBM(lencur + 1:lencur + LEN6) = csec6(1:LEN6) - lencur = lencur + LEN6 - IF (allocated(csec6)) DEALLOCATE(csec6) + call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + allocate(csec6(len6)) + call baread(lugb, iskip + iskp6, len6, lread, csec6) + gribm(lencur + 1:lencur + len6) = csec6(1:len6) + lencur = lencur + len6 + if (allocated(csec6)) deallocate(csec6) endif ! Copy Section 7 - GRIBM(lencur + 1:lencur + LEN7) = csec7(1:LEN7) - lencur = lencur + LEN7 + gribm(lencur + 1:lencur + len7) = csec7(1:len7) + lencur = lencur + len7 ! Section 8 - GRIBM(lencur + 1) = '7' - GRIBM(lencur + 2) = '7' - GRIBM(lencur + 3) = '7' - GRIBM(lencur + 4) = '7' + gribm(lencur + 1) = '7' + gribm(lencur + 2) = '7' + gribm(lencur + 3) = '7' + gribm(lencur + 4) = '7' ! clean up - IF (allocated(csec2)) DEALLOCATE(csec2) - IF (allocated(csec7)) deallocate(csec7) - ELSE ! DO NOT extract field from message : Get entire message - CALL G2_GBYTEC(CINDEX, ISKIP, 4*8, 4*8) ! BYTES TO SKIP IN FILE - CALL G2_GBYTEC(CINDEX, LENG, 36*8, 4*8) ! LENGTH OF GRIB MESSAGE - IF (.NOT. ASSOCIATED(GRIBM)) ALLOCATE(GRIBM(LENG)) - CALL BAREAD(LUGB, ISKIP, LENG, LREAD, GRIBM) - IF (LENG .NE. LREAD ) THEN - DEALLOCATE(GRIBM) - NULLIFY(GRIBM) - IRET = 97 - RETURN - ENDIF - ENDIF -END SUBROUTINE GETGB2RP + if (allocated(csec2)) deallocate(csec2) + if (allocated(csec7)) deallocate(csec7) + else ! do not extract field from message : get entire message + call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file + call g2_gbytec(cindex, leng, 36*8, 4*8) ! length of grib message + if (.not. associated(gribm)) allocate(gribm(leng)) + call baread(lugb, iskip, leng, lread, gribm) + if (leng .ne. lread ) then + deallocate(gribm) + nullify(gribm) + iret = 97 + return + endif + endif +end subroutine getgb2rp2 From 8405853154c8b6ff9a1978c8c8b06e4eb7f1d140 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 13 Feb 2024 06:57:51 -0700 Subject: [PATCH 39/69] more index work --- src/getgb2rp.F90 | 58 ++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 65ed9042..d460cfaa 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -3,8 +3,11 @@ !> field. !> @author Stephen Gilbert @date 2003-12-31 -!> Extract a grib message from a file given the index of the requested -!> field. +!> Extract a grib message from a file given the index (index format 1) +!> of the requested field. +!> +!> This subroutine is maintained for backward compatibility. New code +!> should use getgb2rp2(). !> !> The GRIB message returned can contain only the requested field !> (extract=.true.), or the complete GRIB message originally @@ -22,7 +25,7 @@ !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this !> routine. !> @param[in] cindex Index record of the grib field (see docunentation of -!> subroutine ixgb2() for description of an index record.) +!> subroutine ix2gb2() for description of an index record.) !> @param[in] extract Logical value indicating whether to return a !> GRIB2 message with just the requested field, or the entire !> GRIB2 message containing the requested field. @@ -34,7 +37,7 @@ !> - 0 No error. !> - 97 Error reading grib file. !> -!> @author Stephen Gilbert @date 2003-12-31 +!> @author Stephen Gilbert, Ed Hartnett @date 2003-12-31 subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) implicit none @@ -58,8 +61,8 @@ end subroutine getgb2rp2 end subroutine getgb2rp -!> Extract a grib message from a file given the index of the requested -!> field. +!> Extract a grib message from a file given the version 1 or 2 index +!> of the requested field. !> !> The GRIB message returned can contain only the requested field !> (extract=.true.), or the complete GRIB message originally @@ -69,13 +72,12 @@ end subroutine getgb2rp !> If the GRIB field is not found, then the return code will be !> nonzero. !> -!> @note For files greater than 2 GB, this subroutine will only work -!> if the message is within the first 2 GB of the file. -!> !> @param[in] lugb integer unit of the unblocked grib data file. file !> must be opened with [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this !> routine. +!> @param[in] idxver Version of index, use 1 for legacy, 2 if files +!> may be > 2 GB. !> @param[in] cindex Index record of the grib field (see docunentation of !> subroutine ixgb2() for description of an index record.) !> @param[in] extract Logical value indicating whether to return a @@ -89,7 +91,7 @@ end subroutine getgb2rp !> - 0 No error. !> - 97 Error reading grib file. !> -!> @author Stephen Gilbert @date 2003-12-31 +!> @author Edward Hartnett, Stephen Gilbert @date Feb 13, 2024 subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) implicit none @@ -105,6 +107,8 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: lencur, lread, len0, ibmap, ipos, iskip integer :: len7, len8, len3, len4, len5, len6, len1, len2 integer :: iskp2, iskp6, iskp7 + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) iret = 0 @@ -112,37 +116,37 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (extract) then len0 = 16 len8 = 4 - call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file - call g2_gbytec(cindex, iskp2, 8*8, 4*8) ! bytes to skip for section 2 + call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + call g2_gbytec(cindex, iskp2, 8*8, INT4_BITS) ! bytes to skip for section 2 if (iskp2 .gt. 0) then call baread(lugb, iskip + iskp2, 4, lread, ctemp) - call g2_gbytec(ctemp, len2, 0, 4*8) ! length of section 2 + call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 allocate(csec2(len2)) call baread(lugb, iskip + iskp2, len2, lread, csec2) else len2 = 0 endif - call g2_gbytec(cindex, len1, 44*8, 4*8) ! length of section 1 + call g2_gbytec(cindex, len1, 44*8, INT4_BITS) ! length of section 1 ipos = 44 + len1 - call g2_gbytec(cindex, len3, ipos*8, 4*8) ! length of section 3 + call g2_gbytec(cindex, len3, ipos*8, INT4_BITS) ! length of section 3 ipos = ipos + len3 - call g2_gbytec(cindex, len4, ipos*8, 4*8) ! length of section 4 + call g2_gbytec(cindex, len4, ipos*8, INT4_BITS) ! length of section 4 ipos = ipos + len4 - call g2_gbytec(cindex, len5, ipos*8, 4*8) ! length of section 5 + call g2_gbytec(cindex, len5, ipos*8, INT4_BITS) ! length of section 5 ipos = ipos + len5 - call g2_gbytec(cindex, len6, ipos*8, 4*8) ! length of section 6 + call g2_gbytec(cindex, len6, ipos*8, INT4_BITS) ! length of section 6 ipos = ipos + 5 call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator if (ibmap .eq. 254) then - call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 call baread(lugb, iskip + iskp6, 4, lread, ctemp) - call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 endif ! Read in section 7 from file. - call g2_gbytec(cindex, iskp7, 28*8, 4*8) ! bytes to skip for section 7 + call g2_gbytec(cindex, iskp7, 28*8, INT4_BITS) ! bytes to skip for section 7 call baread(lugb, iskip + iskp7, 4, lread, ctemp) - call g2_gbytec(ctemp, len7, 0, 4*8) ! length of section 7 + call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 allocate(csec7(len7)) call baread(lugb, iskip + iskp7, len7, lread, csec7) @@ -162,7 +166,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) gribm(10) = char(0) gribm(11) = char(0) gribm(12) = char(0) - call g2_sbytec(gribm, leng, 12*8, 4*8) + call g2_sbytec(gribm, leng, 12*8, INT4_BITS) ! Copy Section 1 gribm(17:16 + len1) = cindex(45:44 + len1) @@ -185,9 +189,9 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) gribm(lencur + 1:lencur + len6) = cindex(ipos + 1:ipos + len6) lencur = lencur + len6 else - call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 call baread(lugb, iskip + iskp6, 4, lread, ctemp) - call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 allocate(csec6(len6)) call baread(lugb, iskip + iskp6, len6, lread, csec6) gribm(lencur + 1:lencur + len6) = csec6(1:len6) @@ -209,8 +213,8 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (allocated(csec2)) deallocate(csec2) if (allocated(csec7)) deallocate(csec7) else ! do not extract field from message : get entire message - call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file - call g2_gbytec(cindex, leng, 36*8, 4*8) ! length of grib message + call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + call g2_gbytec(cindex, leng, 36*8, INT4_BITS) ! length of grib message if (.not. associated(gribm)) allocate(gribm(leng)) call baread(lugb, iskip, leng, lread, gribm) if (leng .ne. lread ) then From aa3fd66c0332db05354e435ed3f960b1420bf5f7 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 13 Feb 2024 07:06:22 -0700 Subject: [PATCH 40/69] more index work --- src/getgb2rp.F90 | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index d460cfaa..dfae611a 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -107,6 +107,8 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: lencur, lread, len0, ibmap, ipos, iskip integer :: len7, len8, len3, len4, len5, len6, len1, len2 integer :: iskp2, iskp6, iskp7 + integer :: mypos + integer (kind = 8) :: iskip8, lread8, len2_8 integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) @@ -116,13 +118,21 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (extract) then len0 = 16 len8 = 4 - call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file - call g2_gbytec(cindex, iskp2, 8*8, INT4_BITS) ! bytes to skip for section 2 + if (idxver .eq. 1) then + call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + mypos = INT4_BITS + INT4_BITS + else + call g2_gbytec8(cindex, iskip8, INT4_BITS, INT8_BITS) ! bytes to skip in file + mypos = INT4_BITS + INT8_BITS + iskip = int(iskip8, kind(4)) + endif + call g2_gbytec(cindex, iskp2, mypos, INT4_BITS) ! bytes to skip for section 2 if (iskp2 .gt. 0) then - call baread(lugb, iskip + iskp2, 4, lread, ctemp) + call bareadl(lugb, int(iskip + iskp2, kind(8)), 4_8, lread8, ctemp) call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 allocate(csec2(len2)) - call baread(lugb, iskip + iskp2, len2, lread, csec2) + len2_8 = len2 + call bareadl(lugb, int(iskip + iskp2, kind(8)), len2_8, lread8, csec2) else len2 = 0 endif @@ -139,7 +149,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator if (ibmap .eq. 254) then call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 - call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call bareadl(lugb, int(iskip + iskp6, kind(8)), 4_8, lread8, ctemp) call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 endif From 01fcb5afc1eb1c3444116aae248d1416a259c4ad Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 13 Feb 2024 07:11:00 -0700 Subject: [PATCH 41/69] more index work --- src/getgb2rp.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index dfae611a..688b4f8d 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -155,7 +155,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) ! Read in section 7 from file. call g2_gbytec(cindex, iskp7, 28*8, INT4_BITS) ! bytes to skip for section 7 - call baread(lugb, iskip + iskp7, 4, lread, ctemp) + call bareadl(lugb, int(iskip + iskp7, kind(8)), 4_8, lread8, ctemp) call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 allocate(csec7(len7)) call baread(lugb, iskip + iskp7, len7, lread, csec7) From 834ac803a01381d373d3e6247932d43a8b935f89 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 13 Feb 2024 07:11:45 -0700 Subject: [PATCH 42/69] more index work --- src/getgb2rp.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 688b4f8d..8c70e8a5 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -158,7 +158,8 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) call bareadl(lugb, int(iskip + iskp7, kind(8)), 4_8, lread8, ctemp) call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 allocate(csec7(len7)) - call baread(lugb, iskip + iskp7, len7, lread, csec7) + !call baread(lugb, iskip + iskp7, len7, lread, csec7) + call bareadl(lugb, int(iskip + iskp7, kind(8)), int(len7, kind(8)), lread8, csec7) leng = len0 + len1 + len2 + len3 + len4 + len5 + len6 + len7 + len8 if (.not. associated(gribm)) allocate(gribm(leng)) From 2da05fecc680ee47129a4e5b2133b524a5c9117b Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:22:06 -0700 Subject: [PATCH 43/69] rolled back some changes --- src/getgb2rp.F90 | 256 +++++++++++++++++------------------------------ 1 file changed, 93 insertions(+), 163 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 8c70e8a5..10dfaf86 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -3,11 +3,8 @@ !> field. !> @author Stephen Gilbert @date 2003-12-31 -!> Extract a grib message from a file given the index (index format 1) -!> of the requested field. -!> -!> This subroutine is maintained for backward compatibility. New code -!> should use getgb2rp2(). +!> Extract a grib message from a file given the index of the requested +!> field. !> !> The GRIB message returned can contain only the requested field !> (extract=.true.), or the complete GRIB message originally @@ -25,7 +22,7 @@ !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this !> routine. !> @param[in] cindex Index record of the grib field (see docunentation of -!> subroutine ix2gb2() for description of an index record.) +!> subroutine ixgb2() for description of an index record.) !> @param[in] extract Logical value indicating whether to return a !> GRIB2 message with just the requested field, or the entire !> GRIB2 message containing the requested field. @@ -37,69 +34,15 @@ !> - 0 No error. !> - 97 Error reading grib file. !> -!> @author Stephen Gilbert, Ed Hartnett @date 2003-12-31 +!> @author Stephen Gilbert @date 2003-12-31 subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) implicit none integer, intent(in) :: lugb character(len = 1), intent(in) :: cindex(*) logical, intent(in) :: extract - character(len = 1), pointer, dimension(:) :: gribm integer, intent(out) :: leng, iret - - interface - subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) - integer, intent(in) :: lugb, idxver - character(len = 1), intent(in) :: cindex(*) - logical, intent(in) :: extract - character(len = 1), pointer, dimension(:) :: gribm - integer, intent(out) :: leng, iret - end subroutine getgb2rp2 - end interface - - call getgb2rp2(lugb, 1, cindex, extract, gribm, leng, iret) - -end subroutine getgb2rp - -!> Extract a grib message from a file given the version 1 or 2 index -!> of the requested field. -!> -!> The GRIB message returned can contain only the requested field -!> (extract=.true.), or the complete GRIB message originally -!> containing the desired field can be returned (extract=.false.) even -!> if other fields were included in the GRIB message. -!> -!> If the GRIB field is not found, then the return code will be -!> nonzero. -!> -!> @param[in] lugb integer unit of the unblocked grib data file. file -!> must be opened with [baopen() or baopenr()] -!> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this -!> routine. -!> @param[in] idxver Version of index, use 1 for legacy, 2 if files -!> may be > 2 GB. -!> @param[in] cindex Index record of the grib field (see docunentation of -!> subroutine ixgb2() for description of an index record.) -!> @param[in] extract Logical value indicating whether to return a -!> GRIB2 message with just the requested field, or the entire -!> GRIB2 message containing the requested field. -!> - .true. = return grib2 message containing only the requested field. -!> - .false. = return entire grib2 message containing the requested field. -!> @param[out] gribm Returned grib message. -!> @param[out] leng Length of returned grib message in bytes. -!> @param[out] iret Return code: -!> - 0 No error. -!> - 97 Error reading grib file. -!> -!> @author Edward Hartnett, Stephen Gilbert @date Feb 13, 2024 -subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) - implicit none - - integer, intent(in) :: lugb, idxver - character(len = 1), intent(in) :: cindex(*) - logical, intent(in) :: extract character(len = 1), pointer, dimension(:) :: gribm - integer, intent(out) :: leng, iret integer, parameter :: zero = 0 character(len = 1), allocatable, dimension(:) :: csec2, csec6, csec7 @@ -107,132 +50,119 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: lencur, lread, len0, ibmap, ipos, iskip integer :: len7, len8, len3, len4, len5, len6, len1, len2 integer :: iskp2, iskp6, iskp7 - integer :: mypos - integer (kind = 8) :: iskip8, lread8, len2_8 - integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS - parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) iret = 0 ! Extract grib message from file. - if (extract) then - len0 = 16 - len8 = 4 - if (idxver .eq. 1) then - call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file - mypos = INT4_BITS + INT4_BITS - else - call g2_gbytec8(cindex, iskip8, INT4_BITS, INT8_BITS) ! bytes to skip in file - mypos = INT4_BITS + INT8_BITS - iskip = int(iskip8, kind(4)) - endif - call g2_gbytec(cindex, iskp2, mypos, INT4_BITS) ! bytes to skip for section 2 + IF (EXTRACT) THEN + LEN0 = 16 + LEN8 = 4 + CALL G2_GBYTEC(CINDEX, ISKIP, 4*8, 4*8) ! BYTES TO SKIP IN FILE + CALL G2_GBYTEC(CINDEX, ISKP2, 8*8, 4*8) ! BYTES TO SKIP FOR section 2 if (iskp2 .gt. 0) then - call bareadl(lugb, int(iskip + iskp2, kind(8)), 4_8, lread8, ctemp) - call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 - allocate(csec2(len2)) - len2_8 = len2 - call bareadl(lugb, int(iskip + iskp2, kind(8)), len2_8, lread8, csec2) + CALL BAREAD(LUGB, ISKIP + ISKP2, 4, LREAD, ctemp) + CALL G2_GBYTEC(Ctemp, LEN2, 0, 4*8) ! LENGTH OF SECTION 2 + ALLOCATE(csec2(len2)) + CALL BAREAD(LUGB, ISKIP + ISKP2, LEN2, LREAD, csec2) else - len2 = 0 + LEN2 = 0 endif - call g2_gbytec(cindex, len1, 44*8, INT4_BITS) ! length of section 1 - ipos = 44 + len1 - call g2_gbytec(cindex, len3, ipos*8, INT4_BITS) ! length of section 3 - ipos = ipos + len3 - call g2_gbytec(cindex, len4, ipos*8, INT4_BITS) ! length of section 4 - ipos = ipos + len4 - call g2_gbytec(cindex, len5, ipos*8, INT4_BITS) ! length of section 5 - ipos = ipos + len5 - call g2_gbytec(cindex, len6, ipos*8, INT4_BITS) ! length of section 6 - ipos = ipos + 5 - call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator - if (ibmap .eq. 254) then - call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 - call bareadl(lugb, int(iskip + iskp6, kind(8)), 4_8, lread8, ctemp) - call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 - endif - - ! Read in section 7 from file. - call g2_gbytec(cindex, iskp7, 28*8, INT4_BITS) ! bytes to skip for section 7 - call bareadl(lugb, int(iskip + iskp7, kind(8)), 4_8, lread8, ctemp) - call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 - allocate(csec7(len7)) - !call baread(lugb, iskip + iskp7, len7, lread, csec7) - call bareadl(lugb, int(iskip + iskp7, kind(8)), int(len7, kind(8)), lread8, csec7) - - leng = len0 + len1 + len2 + len3 + len4 + len5 + len6 + len7 + len8 - if (.not. associated(gribm)) allocate(gribm(leng)) + CALL G2_GBYTEC(CINDEX, LEN1, 44*8, 4*8) ! LENGTH OF SECTION 1 + IPOS = 44 + LEN1 + CALL G2_GBYTEC(CINDEX, LEN3, IPOS*8, 4*8) ! LENGTH OF SECTION 3 + IPOS = IPOS + LEN3 + CALL G2_GBYTEC(CINDEX, LEN4, IPOS*8, 4*8) ! LENGTH OF SECTION 4 + IPOS = IPOS + LEN4 + CALL G2_GBYTEC(CINDEX, LEN5, IPOS*8, 4*8) ! LENGTH OF SECTION 5 + IPOS = IPOS + LEN5 + CALL G2_GBYTEC(CINDEX, LEN6, IPOS*8, 4*8) ! LENGTH OF SECTION 6 + IPOS = IPOS + 5 + CALL G2_GBYTEC(CINDEX, IBMAP, IPOS*8, 1*8) ! Bitmap indicator + IF (IBMAP .eq. 254) THEN + CALL G2_GBYTEC(CINDEX, ISKP6, 24*8, 4*8) ! BYTES TO SKIP FOR section 6 + CALL BAREAD(LUGB, ISKIP + ISKP6, 4, LREAD, ctemp) + CALL G2_GBYTEC(Ctemp, LEN6, 0, 4*8) ! LENGTH OF SECTION 6 + ENDIF + + ! READ IN SECTION 7 from file + CALL G2_GBYTEC(CINDEX, ISKP7, 28*8, 4*8) ! BYTES TO SKIP FOR section 7 + CALL BAREAD(LUGB, ISKIP + ISKP7, 4, LREAD, ctemp) + CALL G2_GBYTEC(Ctemp, LEN7, 0, 4*8) ! LENGTH OF SECTION 7 + ALLOCATE(csec7(len7)) + CALL BAREAD(LUGB, ISKIP + ISKP7, LEN7, LREAD, csec7) + + LENG = LEN0 + LEN1 + LEN2 + LEN3 + LEN4 + LEN5 + LEN6 + LEN7 + LEN8 + IF (.NOT. ASSOCIATED(GRIBM)) ALLOCATE(GRIBM(LENG)) ! Create Section 0 - gribm(1) = 'G' - gribm(2) = 'R' - gribm(3) = 'I' - gribm(4) = 'B' - gribm(5) = char(0) - gribm(6) = char(0) - gribm(7) = cindex(42) - gribm(8) = cindex(41) - gribm(9) = char(0) - gribm(10) = char(0) - gribm(11) = char(0) - gribm(12) = char(0) - call g2_sbytec(gribm, leng, 12*8, INT4_BITS) + GRIBM(1) = 'G' + GRIBM(2) = 'R' + GRIBM(3) = 'I' + GRIBM(4) = 'B' + GRIBM(5) = CHAR(0) + GRIBM(6) = CHAR(0) + GRIBM(7) = CINDEX(42) + GRIBM(8) = CINDEX(41) + GRIBM(9) = CHAR(0) + GRIBM(10) = CHAR(0) + GRIBM(11) = CHAR(0) + GRIBM(12) = CHAR(0) + CALL G2_SBYTEC(GRIBM, LENG, 12*8, 4*8) ! Copy Section 1 - gribm(17:16 + len1) = cindex(45:44 + len1) - lencur = 16 + len1 + GRIBM(17:16 + LEN1) = CINDEX(45:44 + LEN1) + lencur = 16 + LEN1 ipos = 44 + len1 - ! copy section 2, if necessary + ! Copy Section 2, if necessary if (iskp2 .gt. 0) then - gribm(lencur + 1:lencur + len2) = csec2(1:len2) - lencur = lencur + len2 + GRIBM(lencur + 1:lencur + LEN2) = csec2(1:LEN2) + lencur = lencur + LEN2 endif ! Copy Sections 3 through 5 - gribm(lencur + 1:lencur + len3 + len4 + len5) = cindex(ipos + 1:ipos + len3 + len4 + len5) - lencur = lencur + len3 + len4 + len5 - ipos = ipos + len3 + len4 + len5 + GRIBM(lencur + 1:lencur + LEN3 + LEN4 + LEN5) = CINDEX(ipos + 1:ipos + LEN3 + LEN4 + LEN5) + lencur = lencur + LEN3 + LEN4 + LEN5 + ipos = ipos + LEN3 + LEN4 + LEN5 ! Copy Section 6 - if (len6 .eq. 6 .and. ibmap .ne. 254) then - gribm(lencur + 1:lencur + len6) = cindex(ipos + 1:ipos + len6) - lencur = lencur + len6 + if (LEN6 .eq. 6 .AND. IBMAP .ne. 254) then + GRIBM(lencur + 1:lencur + LEN6) = CINDEX(ipos + 1:ipos + LEN6) + lencur = lencur + LEN6 else - call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 - call baread(lugb, iskip + iskp6, 4, lread, ctemp) - call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 - allocate(csec6(len6)) - call baread(lugb, iskip + iskp6, len6, lread, csec6) - gribm(lencur + 1:lencur + len6) = csec6(1:len6) - lencur = lencur + len6 - if (allocated(csec6)) deallocate(csec6) + CALL G2_GBYTEC(CINDEX, ISKP6, 24*8, 4*8) ! BYTES TO SKIP FOR section 6 + CALL BAREAD(LUGB, ISKIP + ISKP6, 4, LREAD, ctemp) + CALL G2_GBYTEC(Ctemp, LEN6, 0, 4*8) ! LENGTH OF SECTION 6 + ALLOCATE(csec6(len6)) + CALL BAREAD(LUGB, ISKIP + ISKP6, LEN6, LREAD, csec6) + GRIBM(lencur + 1:lencur + LEN6) = csec6(1:LEN6) + lencur = lencur + LEN6 + IF (allocated(csec6)) DEALLOCATE(csec6) endif ! Copy Section 7 - gribm(lencur + 1:lencur + len7) = csec7(1:len7) - lencur = lencur + len7 + GRIBM(lencur + 1:lencur + LEN7) = csec7(1:LEN7) + lencur = lencur + LEN7 ! Section 8 - gribm(lencur + 1) = '7' - gribm(lencur + 2) = '7' - gribm(lencur + 3) = '7' - gribm(lencur + 4) = '7' + GRIBM(lencur + 1) = '7' + GRIBM(lencur + 2) = '7' + GRIBM(lencur + 3) = '7' + GRIBM(lencur + 4) = '7' ! clean up - if (allocated(csec2)) deallocate(csec2) - if (allocated(csec7)) deallocate(csec7) - else ! do not extract field from message : get entire message - call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file - call g2_gbytec(cindex, leng, 36*8, INT4_BITS) ! length of grib message - if (.not. associated(gribm)) allocate(gribm(leng)) - call baread(lugb, iskip, leng, lread, gribm) - if (leng .ne. lread ) then - deallocate(gribm) - nullify(gribm) - iret = 97 - return - endif - endif -end subroutine getgb2rp2 + IF (allocated(csec2)) DEALLOCATE(csec2) + IF (allocated(csec7)) deallocate(csec7) + ELSE ! DO NOT extract field from message : Get entire message + CALL G2_GBYTEC(CINDEX, ISKIP, 4*8, 4*8) ! BYTES TO SKIP IN FILE + CALL G2_GBYTEC(CINDEX, LENG, 36*8, 4*8) ! LENGTH OF GRIB MESSAGE + IF (.NOT. ASSOCIATED(GRIBM)) ALLOCATE(GRIBM(LENG)) + CALL BAREAD(LUGB, ISKIP, LENG, LREAD, GRIBM) + IF (LENG .NE. LREAD ) THEN + DEALLOCATE(GRIBM) + NULLIFY(GRIBM) + IRET = 97 + RETURN + ENDIF + ENDIF +END SUBROUTINE GETGB2RP From ddc802f45f74e592ce03d790ba6960d6a05e0f41 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:27:24 -0700 Subject: [PATCH 44/69] more index work --- src/getgb2rp.F90 | 67 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 10dfaf86..b596e4bd 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -3,8 +3,11 @@ !> field. !> @author Stephen Gilbert @date 2003-12-31 -!> Extract a grib message from a file given the index of the requested -!> field. +!> Extract a grib message from a file given the index (index format 1) +!> of the requested field. +!> +!> This subroutine is maintained for backward compatibility. New code +!> should use getgb2rp2(). !> !> The GRIB message returned can contain only the requested field !> (extract=.true.), or the complete GRIB message originally @@ -22,7 +25,7 @@ !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this !> routine. !> @param[in] cindex Index record of the grib field (see docunentation of -!> subroutine ixgb2() for description of an index record.) +!> subroutine ix2gb2() for description of an index record.) !> @param[in] extract Logical value indicating whether to return a !> GRIB2 message with just the requested field, or the entire !> GRIB2 message containing the requested field. @@ -34,13 +37,67 @@ !> - 0 No error. !> - 97 Error reading grib file. !> -!> @author Stephen Gilbert @date 2003-12-31 +!> @author Stephen Gilbert, Ed Hartnett @date 2003-12-31 subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) implicit none integer, intent(in) :: lugb character(len = 1), intent(in) :: cindex(*) logical, intent(in) :: extract + character(len = 1), pointer, dimension(:) :: gribm + integer, intent(out) :: leng, iret + + interface + subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + logical, intent(in) :: extract + character(len = 1), pointer, dimension(:) :: gribm + integer, intent(out) :: leng, iret + end subroutine getgb2rp2 + end interface + + call getgb2rp2(lugb, 1, cindex, extract, gribm, leng, iret) + +end subroutine getgb2rp + +!> Extract a grib message from a file given the version 1 or 2 index +!> of the requested field. +!> +!> The GRIB message returned can contain only the requested field +!> (extract=.true.), or the complete GRIB message originally +!> containing the desired field can be returned (extract=.false.) even +!> if other fields were included in the GRIB message. +!> +!> If the GRIB field is not found, then the return code will be +!> nonzero. +!> +!> @param[in] lugb integer unit of the unblocked grib data file. file +!> must be opened with [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling this +!> routine. +!> @param[in] idxver Version of index, use 1 for legacy, 2 if files +!> may be > 2 GB. +!> @param[in] cindex Index record of the grib field (see docunentation of +!> subroutine ixgb2() for description of an index record.) +!> @param[in] extract Logical value indicating whether to return a +!> GRIB2 message with just the requested field, or the entire +!> GRIB2 message containing the requested field. +!> - .true. = return grib2 message containing only the requested field. +!> - .false. = return entire grib2 message containing the requested field. +!> @param[out] gribm Returned grib message. +!> @param[out] leng Length of returned grib message in bytes. +!> @param[out] iret Return code: +!> - 0 No error. +!> - 97 Error reading grib file. +!> +!> @author Edward Hartnett, Stephen Gilbert @date Feb 13, 2024 +subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) + implicit none + + integer, intent(in) :: lugb, idxver + character(len = 1), intent(in) :: cindex(*) + logical, intent(in) :: extract integer, intent(out) :: leng, iret character(len = 1), pointer, dimension(:) :: gribm @@ -165,4 +222,4 @@ subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) RETURN ENDIF ENDIF -END SUBROUTINE GETGB2RP +END SUBROUTINE GETGB2RP2 From 1d5f0009af390104fe8d0f869e807572812fc97c Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:29:46 -0700 Subject: [PATCH 45/69] more index work --- src/getgb2rp.F90 | 176 +++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index b596e4bd..f65841dc 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -111,115 +111,115 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) iret = 0 ! Extract grib message from file. - IF (EXTRACT) THEN - LEN0 = 16 - LEN8 = 4 - CALL G2_GBYTEC(CINDEX, ISKIP, 4*8, 4*8) ! BYTES TO SKIP IN FILE - CALL G2_GBYTEC(CINDEX, ISKP2, 8*8, 4*8) ! BYTES TO SKIP FOR section 2 + if (extract) then + len0 = 16 + len8 = 4 + call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file + call g2_gbytec(cindex, iskp2, 8*8, 4*8) ! bytes to skip for section 2 if (iskp2 .gt. 0) then - CALL BAREAD(LUGB, ISKIP + ISKP2, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN2, 0, 4*8) ! LENGTH OF SECTION 2 - ALLOCATE(csec2(len2)) - CALL BAREAD(LUGB, ISKIP + ISKP2, LEN2, LREAD, csec2) + call baread(lugb, iskip + iskp2, 4, lread, ctemp) + call g2_gbytec(ctemp, len2, 0, 4*8) ! length of section 2 + allocate(csec2(len2)) + call baread(lugb, iskip + iskp2, len2, lread, csec2) else - LEN2 = 0 + len2 = 0 endif - CALL G2_GBYTEC(CINDEX, LEN1, 44*8, 4*8) ! LENGTH OF SECTION 1 - IPOS = 44 + LEN1 - CALL G2_GBYTEC(CINDEX, LEN3, IPOS*8, 4*8) ! LENGTH OF SECTION 3 - IPOS = IPOS + LEN3 - CALL G2_GBYTEC(CINDEX, LEN4, IPOS*8, 4*8) ! LENGTH OF SECTION 4 - IPOS = IPOS + LEN4 - CALL G2_GBYTEC(CINDEX, LEN5, IPOS*8, 4*8) ! LENGTH OF SECTION 5 - IPOS = IPOS + LEN5 - CALL G2_GBYTEC(CINDEX, LEN6, IPOS*8, 4*8) ! LENGTH OF SECTION 6 - IPOS = IPOS + 5 - CALL G2_GBYTEC(CINDEX, IBMAP, IPOS*8, 1*8) ! Bitmap indicator - IF (IBMAP .eq. 254) THEN - CALL G2_GBYTEC(CINDEX, ISKP6, 24*8, 4*8) ! BYTES TO SKIP FOR section 6 - CALL BAREAD(LUGB, ISKIP + ISKP6, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN6, 0, 4*8) ! LENGTH OF SECTION 6 - ENDIF - - ! READ IN SECTION 7 from file - CALL G2_GBYTEC(CINDEX, ISKP7, 28*8, 4*8) ! BYTES TO SKIP FOR section 7 - CALL BAREAD(LUGB, ISKIP + ISKP7, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN7, 0, 4*8) ! LENGTH OF SECTION 7 - ALLOCATE(csec7(len7)) - CALL BAREAD(LUGB, ISKIP + ISKP7, LEN7, LREAD, csec7) - - LENG = LEN0 + LEN1 + LEN2 + LEN3 + LEN4 + LEN5 + LEN6 + LEN7 + LEN8 - IF (.NOT. ASSOCIATED(GRIBM)) ALLOCATE(GRIBM(LENG)) + call g2_gbytec(cindex, len1, 44*8, 4*8) ! length of section 1 + ipos = 44 + len1 + call g2_gbytec(cindex, len3, ipos*8, 4*8) ! length of section 3 + ipos = ipos + len3 + call g2_gbytec(cindex, len4, ipos*8, 4*8) ! length of section 4 + ipos = ipos + len4 + call g2_gbytec(cindex, len5, ipos*8, 4*8) ! length of section 5 + ipos = ipos + len5 + call g2_gbytec(cindex, len6, ipos*8, 4*8) ! length of section 6 + ipos = ipos + 5 + call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator + if (ibmap .eq. 254) then + call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + endif + + ! read in section 7 from file + call g2_gbytec(cindex, iskp7, 28*8, 4*8) ! bytes to skip for section 7 + call baread(lugb, iskip + iskp7, 4, lread, ctemp) + call g2_gbytec(ctemp, len7, 0, 4*8) ! length of section 7 + allocate(csec7(len7)) + call baread(lugb, iskip + iskp7, len7, lread, csec7) + + leng = len0 + len1 + len2 + len3 + len4 + len5 + len6 + len7 + len8 + if (.not. associated(gribm)) allocate(gribm(leng)) ! Create Section 0 - GRIBM(1) = 'G' - GRIBM(2) = 'R' - GRIBM(3) = 'I' - GRIBM(4) = 'B' - GRIBM(5) = CHAR(0) - GRIBM(6) = CHAR(0) - GRIBM(7) = CINDEX(42) - GRIBM(8) = CINDEX(41) - GRIBM(9) = CHAR(0) - GRIBM(10) = CHAR(0) - GRIBM(11) = CHAR(0) - GRIBM(12) = CHAR(0) - CALL G2_SBYTEC(GRIBM, LENG, 12*8, 4*8) + gribm(1) = 'G' + gribm(2) = 'R' + gribm(3) = 'I' + gribm(4) = 'B' + gribm(5) = char(0) + gribm(6) = char(0) + gribm(7) = cindex(42) + gribm(8) = cindex(41) + gribm(9) = char(0) + gribm(10) = char(0) + gribm(11) = char(0) + gribm(12) = char(0) + call g2_sbytec(gribm, leng, 12*8, 4*8) ! Copy Section 1 - GRIBM(17:16 + LEN1) = CINDEX(45:44 + LEN1) - lencur = 16 + LEN1 + gribm(17:16 + len1) = cindex(45:44 + len1) + lencur = 16 + len1 ipos = 44 + len1 ! Copy Section 2, if necessary if (iskp2 .gt. 0) then - GRIBM(lencur + 1:lencur + LEN2) = csec2(1:LEN2) - lencur = lencur + LEN2 + gribm(lencur + 1:lencur + len2) = csec2(1:len2) + lencur = lencur + len2 endif ! Copy Sections 3 through 5 - GRIBM(lencur + 1:lencur + LEN3 + LEN4 + LEN5) = CINDEX(ipos + 1:ipos + LEN3 + LEN4 + LEN5) - lencur = lencur + LEN3 + LEN4 + LEN5 - ipos = ipos + LEN3 + LEN4 + LEN5 + gribm(lencur + 1:lencur + len3 + len4 + len5) = cindex(ipos + 1:ipos + len3 + len4 + len5) + lencur = lencur + len3 + len4 + len5 + ipos = ipos + len3 + len4 + len5 ! Copy Section 6 - if (LEN6 .eq. 6 .AND. IBMAP .ne. 254) then - GRIBM(lencur + 1:lencur + LEN6) = CINDEX(ipos + 1:ipos + LEN6) - lencur = lencur + LEN6 + if (len6 .eq. 6 .and. ibmap .ne. 254) then + gribm(lencur + 1:lencur + len6) = cindex(ipos + 1:ipos + len6) + lencur = lencur + len6 else - CALL G2_GBYTEC(CINDEX, ISKP6, 24*8, 4*8) ! BYTES TO SKIP FOR section 6 - CALL BAREAD(LUGB, ISKIP + ISKP6, 4, LREAD, ctemp) - CALL G2_GBYTEC(Ctemp, LEN6, 0, 4*8) ! LENGTH OF SECTION 6 - ALLOCATE(csec6(len6)) - CALL BAREAD(LUGB, ISKIP + ISKP6, LEN6, LREAD, csec6) - GRIBM(lencur + 1:lencur + LEN6) = csec6(1:LEN6) - lencur = lencur + LEN6 - IF (allocated(csec6)) DEALLOCATE(csec6) + call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + allocate(csec6(len6)) + call baread(lugb, iskip + iskp6, len6, lread, csec6) + gribm(lencur + 1:lencur + len6) = csec6(1:len6) + lencur = lencur + len6 + if (allocated(csec6)) deallocate(csec6) endif ! Copy Section 7 - GRIBM(lencur + 1:lencur + LEN7) = csec7(1:LEN7) - lencur = lencur + LEN7 + gribm(lencur + 1:lencur + len7) = csec7(1:len7) + lencur = lencur + len7 ! Section 8 - GRIBM(lencur + 1) = '7' - GRIBM(lencur + 2) = '7' - GRIBM(lencur + 3) = '7' - GRIBM(lencur + 4) = '7' + gribm(lencur + 1) = '7' + gribm(lencur + 2) = '7' + gribm(lencur + 3) = '7' + gribm(lencur + 4) = '7' ! clean up - IF (allocated(csec2)) DEALLOCATE(csec2) - IF (allocated(csec7)) deallocate(csec7) - ELSE ! DO NOT extract field from message : Get entire message - CALL G2_GBYTEC(CINDEX, ISKIP, 4*8, 4*8) ! BYTES TO SKIP IN FILE - CALL G2_GBYTEC(CINDEX, LENG, 36*8, 4*8) ! LENGTH OF GRIB MESSAGE - IF (.NOT. ASSOCIATED(GRIBM)) ALLOCATE(GRIBM(LENG)) - CALL BAREAD(LUGB, ISKIP, LENG, LREAD, GRIBM) - IF (LENG .NE. LREAD ) THEN - DEALLOCATE(GRIBM) - NULLIFY(GRIBM) - IRET = 97 - RETURN - ENDIF - ENDIF -END SUBROUTINE GETGB2RP2 + if (allocated(csec2)) deallocate(csec2) + if (allocated(csec7)) deallocate(csec7) + else ! do not extract field from message : get entire message + call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file + call g2_gbytec(cindex, leng, 36*8, 4*8) ! length of grib message + if (.not. associated(gribm)) allocate(gribm(leng)) + call baread(lugb, iskip, leng, lread, gribm) + if (leng .ne. lread ) then + deallocate(gribm) + nullify(gribm) + iret = 97 + return + endif + endif +end subroutine getgb2rp2 From fbe506e77a53094e1e84a0b219366297f417f767 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:46:21 -0700 Subject: [PATCH 46/69] more index work --- src/getgb2rp.F90 | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index f65841dc..7f0b3c73 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -107,6 +107,8 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: lencur, lread, len0, ibmap, ipos, iskip integer :: len7, len8, len3, len4, len5, len6, len1, len2 integer :: iskp2, iskp6, iskp7 + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) iret = 0 @@ -114,37 +116,41 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (extract) then len0 = 16 len8 = 4 - call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file - call g2_gbytec(cindex, iskp2, 8*8, 4*8) ! bytes to skip for section 2 + if (idxver .eq. 1) then + call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + else + call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + endif + call g2_gbytec(cindex, iskp2, 8*8, INT4_BITS) ! bytes to skip for section 2 if (iskp2 .gt. 0) then call baread(lugb, iskip + iskp2, 4, lread, ctemp) - call g2_gbytec(ctemp, len2, 0, 4*8) ! length of section 2 + call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 allocate(csec2(len2)) call baread(lugb, iskip + iskp2, len2, lread, csec2) else len2 = 0 endif - call g2_gbytec(cindex, len1, 44*8, 4*8) ! length of section 1 + call g2_gbytec(cindex, len1, 44*8, INT4_BITS) ! length of section 1 ipos = 44 + len1 - call g2_gbytec(cindex, len3, ipos*8, 4*8) ! length of section 3 + call g2_gbytec(cindex, len3, ipos*8, INT4_BITS) ! length of section 3 ipos = ipos + len3 - call g2_gbytec(cindex, len4, ipos*8, 4*8) ! length of section 4 + call g2_gbytec(cindex, len4, ipos*8, INT4_BITS) ! length of section 4 ipos = ipos + len4 - call g2_gbytec(cindex, len5, ipos*8, 4*8) ! length of section 5 + call g2_gbytec(cindex, len5, ipos*8, INT4_BITS) ! length of section 5 ipos = ipos + len5 - call g2_gbytec(cindex, len6, ipos*8, 4*8) ! length of section 6 + call g2_gbytec(cindex, len6, ipos*8, INT4_BITS) ! length of section 6 ipos = ipos + 5 call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator if (ibmap .eq. 254) then - call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 call baread(lugb, iskip + iskp6, 4, lread, ctemp) - call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 endif ! read in section 7 from file - call g2_gbytec(cindex, iskp7, 28*8, 4*8) ! bytes to skip for section 7 + call g2_gbytec(cindex, iskp7, 28*8, INT4_BITS) ! bytes to skip for section 7 call baread(lugb, iskip + iskp7, 4, lread, ctemp) - call g2_gbytec(ctemp, len7, 0, 4*8) ! length of section 7 + call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 allocate(csec7(len7)) call baread(lugb, iskip + iskp7, len7, lread, csec7) @@ -164,7 +170,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) gribm(10) = char(0) gribm(11) = char(0) gribm(12) = char(0) - call g2_sbytec(gribm, leng, 12*8, 4*8) + call g2_sbytec(gribm, leng, 12*8, INT4_BITS) ! Copy Section 1 gribm(17:16 + len1) = cindex(45:44 + len1) @@ -187,9 +193,9 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) gribm(lencur + 1:lencur + len6) = cindex(ipos + 1:ipos + len6) lencur = lencur + len6 else - call g2_gbytec(cindex, iskp6, 24*8, 4*8) ! bytes to skip for section 6 + call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 call baread(lugb, iskip + iskp6, 4, lread, ctemp) - call g2_gbytec(ctemp, len6, 0, 4*8) ! length of section 6 + call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 allocate(csec6(len6)) call baread(lugb, iskip + iskp6, len6, lread, csec6) gribm(lencur + 1:lencur + len6) = csec6(1:len6) @@ -211,8 +217,12 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (allocated(csec2)) deallocate(csec2) if (allocated(csec7)) deallocate(csec7) else ! do not extract field from message : get entire message - call g2_gbytec(cindex, iskip, 4*8, 4*8) ! bytes to skip in file - call g2_gbytec(cindex, leng, 36*8, 4*8) ! length of grib message + call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + if (idxver .eq. 1) then + call g2_gbytec(cindex, leng, 36*8, INT4_BITS) ! length of grib message + else + call g2_gbytec(cindex, leng, 36*8, INT4_BITS) ! length of grib message + endif if (.not. associated(gribm)) allocate(gribm(leng)) call baread(lugb, iskip, leng, lread, gribm) if (leng .ne. lread ) then From bd0a39a6ad2dae4c581c758b4a07182faf0bf4ed Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:53:56 -0700 Subject: [PATCH 47/69] more index work --- tests/test_getgb2rp.F90 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_getgb2rp.F90 b/tests/test_getgb2rp.F90 index 6bccc005..0129a17e 100644 --- a/tests/test_getgb2rp.F90 +++ b/tests/test_getgb2rp.F90 @@ -14,14 +14,16 @@ program test_getgb2rp logical :: extract integer :: leng character(len=1), pointer, dimension(:) :: gribm + integer :: idxver = 1 ! Interfaces are needed due to pointers in the parameter lists. interface - subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) + subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) integer, intent(in) :: lugb, lugi - integer, intent(out) :: nlen, nnum, iret + integer, intent(inout) :: idxver character(len = 1), pointer, dimension(:) :: cindex - end subroutine getidx + integer, intent(out) :: nlen, nnum, iret + end subroutine getidx2 end interface interface @@ -42,7 +44,7 @@ end subroutine getgb2rp if (iret .ne. 0) stop 100 lugi = 0 - call getidx(lugb, lugi, cbuf, nlen, nnum, iret) + call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, iret) if (iret .ne. 0) stop 101 if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 print *, 'nlen, nnum: ', nlen, nnum From 624d770e5cddd9304824a07bbd2e4f5cb3fa9568 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:56:36 -0700 Subject: [PATCH 48/69] reverted test --- tests/test_getgb2rp.F90 | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/test_getgb2rp.F90 b/tests/test_getgb2rp.F90 index 0129a17e..6bccc005 100644 --- a/tests/test_getgb2rp.F90 +++ b/tests/test_getgb2rp.F90 @@ -14,16 +14,14 @@ program test_getgb2rp logical :: extract integer :: leng character(len=1), pointer, dimension(:) :: gribm - integer :: idxver = 1 ! Interfaces are needed due to pointers in the parameter lists. interface - subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + subroutine getidx(lugb, lugi, cindex, nlen, nnum, iret) integer, intent(in) :: lugb, lugi - integer, intent(inout) :: idxver - character(len = 1), pointer, dimension(:) :: cindex integer, intent(out) :: nlen, nnum, iret - end subroutine getidx2 + character(len = 1), pointer, dimension(:) :: cindex + end subroutine getidx end interface interface @@ -44,7 +42,7 @@ end subroutine getgb2rp if (iret .ne. 0) stop 100 lugi = 0 - call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, iret) + call getidx(lugb, lugi, cbuf, nlen, nnum, iret) if (iret .ne. 0) stop 101 if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 print *, 'nlen, nnum: ', nlen, nnum From fdc37ca10d4981c88e732ab13a1d13823f626304 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 09:58:33 -0700 Subject: [PATCH 49/69] added new test --- tests/CMakeLists.txt | 1 + tests/test_getgb2rp_2.F90 | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/test_getgb2rp_2.F90 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ae4f14cc..3c26f400 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -113,6 +113,7 @@ if(FTP_TEST_FILES) create_test(test_getg2ir ${kind}) create_test(test_getidx ${kind}) create_test(test_getgb2rp ${kind}) + create_test(test_getgb2rp_2 ${kind}) create_test(test_getgb2s ${kind}) create_test(test_getgb2p ${kind}) create_test(test_getgb2r ${kind}) diff --git a/tests/test_getgb2rp_2.F90 b/tests/test_getgb2rp_2.F90 new file mode 100644 index 00000000..0129a17e --- /dev/null +++ b/tests/test_getgb2rp_2.F90 @@ -0,0 +1,77 @@ +! This is a test program for NCEPLIBS-g2. +! +! This program tests getg2rp.F90 +! +! Ed Hartnett 7/26/22 +program test_getgb2rp + use bacio_module + implicit none + + integer :: lugi + character(len=1), pointer, dimension(:) :: cbuf(:) + integer :: lugb = 3 + integer :: nlen, nnum, iret + logical :: extract + integer :: leng + character(len=1), pointer, dimension(:) :: gribm + integer :: idxver = 1 + + ! Interfaces are needed due to pointers in the parameter lists. + interface + subroutine getidx2(lugb, lugi, idxver, cindex, nlen, nnum, iret) + integer, intent(in) :: lugb, lugi + integer, intent(inout) :: idxver + character(len = 1), pointer, dimension(:) :: cindex + integer, intent(out) :: nlen, nnum, iret + end subroutine getidx2 + end interface + + interface + subroutine getgb2rp(lugb, cindex, extract, gribm, leng, iret) + integer, intent(in) :: lugb + character(len=1), intent(in) :: cindex(*) + logical, intent(in) :: extract + character(len=1), pointer, dimension(:) :: gribm + integer, intent(out) :: leng, iret + end subroutine getgb2rp + end interface + + print *, 'Testing the getgb2rp() subroutine - expect and ignore error messages during test...' + + ! Open a real GRIB2 file. + print *, 'Indexing a real GRIB2 file WW3_Regional_US_West_Coast_20220718_0000.grib2...' + call baopenr(lugb, "data/WW3_Regional_US_West_Coast_20220718_0000.grib2", iret) + if (iret .ne. 0) stop 100 + + lugi = 0 + call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, iret) + if (iret .ne. 0) stop 101 + if (nlen .ne. 137600 .or. nnum .ne. 688) stop 102 + print *, 'nlen, nnum: ', nlen, nnum + + ! Extract the whole message. + extract = .false. + nullify(gribm) + call getgb2rp(lugb, cbuf, extract, gribm, leng, iret) + print *, 'leng ', leng + if (leng .ne. 11183) stop 110 + ! Deallocate buffer that got GRIB message. + deallocate(gribm) + + ! Extract just the field (same result). + extract = .true. + call getgb2rp(lugb, cbuf, extract, gribm, leng, iret) + print *, 'leng ', leng + if (leng .ne. 11183) stop 110 + ! Deallocate buffer that got GRIB message. + deallocate(gribm) + + ! Deallocate the buffer that holds index. + deallocate(cbuf) + + call baclose(lugb, iret) + if (iret .ne. 0) stop 199 + + print *, 'SUCCESS!...' + +end program test_getgb2rp From 494f37f4ee9638dcd2ba2b7c8dcb0e8e3601cf5d Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 10:27:59 -0700 Subject: [PATCH 50/69] more index work --- src/getgb2rp.F90 | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 7f0b3c73..ec5def31 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -109,19 +109,25 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: iskp2, iskp6, iskp7 integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) + integer :: mypos + integer (kind = 8) :: lread8, iskip8 iret = 0 ! Extract grib message from file. + mypos = INT4_BITS if (extract) then len0 = 16 len8 = 4 if (idxver .eq. 1) then - call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + call g2_gbytec(cindex, iskip, mypos, INT4_BITS) ! bytes to skip in file + mypos = mypos + INT4_BITS else - call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file + call g2_gbytec8(cindex, iskip8, mypos, INT8_BITS) ! bytes to skip in file + mypos = mypos + INT8_BITS + iskip = int(iskip8, kind(4)) endif - call g2_gbytec(cindex, iskp2, 8*8, INT4_BITS) ! bytes to skip for section 2 + call g2_gbytec(cindex, iskp2, mypos, INT4_BITS) ! bytes to skip for section 2 if (iskp2 .gt. 0) then call baread(lugb, iskip + iskp2, 4, lread, ctemp) call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 @@ -217,12 +223,16 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (allocated(csec2)) deallocate(csec2) if (allocated(csec7)) deallocate(csec7) else ! do not extract field from message : get entire message - call g2_gbytec(cindex, iskip, INT4_BITS, INT4_BITS) ! bytes to skip in file if (idxver .eq. 1) then - call g2_gbytec(cindex, leng, 36*8, INT4_BITS) ! length of grib message + call g2_gbytec(cindex, iskip, mypos, INT4_BITS) ! bytes to skip in file + mypos = mypos + INT4_BITS else - call g2_gbytec(cindex, leng, 36*8, INT4_BITS) ! length of grib message + call g2_gbytec8(cindex, iskip8, mypos, INT8_BITS) ! bytes to skip in file + mypos = mypos + INT8_BITS + iskip = int(iskip8, kind(4)) endif + mypos = mypos + 7 * INT4_BITS + call g2_gbytec(cindex, leng, mypos, INT4_BITS) ! length of grib message if (.not. associated(gribm)) allocate(gribm(leng)) call baread(lugb, iskip, leng, lread, gribm) if (leng .ne. lread ) then From a3dabe5229966e886317a3bcbdae8fe03fe0021e Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 10:32:07 -0700 Subject: [PATCH 51/69] more index work --- src/getgb2rp.F90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index ec5def31..56db85e9 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -110,7 +110,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) integer :: mypos - integer (kind = 8) :: lread8, iskip8 + integer (kind = 8) :: lread8, iskip8, leng8 iret = 0 @@ -226,16 +226,17 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (idxver .eq. 1) then call g2_gbytec(cindex, iskip, mypos, INT4_BITS) ! bytes to skip in file mypos = mypos + INT4_BITS + iskip8 = iskip else call g2_gbytec8(cindex, iskip8, mypos, INT8_BITS) ! bytes to skip in file mypos = mypos + INT8_BITS - iskip = int(iskip8, kind(4)) endif mypos = mypos + 7 * INT4_BITS call g2_gbytec(cindex, leng, mypos, INT4_BITS) ! length of grib message if (.not. associated(gribm)) allocate(gribm(leng)) - call baread(lugb, iskip, leng, lread, gribm) - if (leng .ne. lread ) then + leng8 = leng + call bareadl(lugb, iskip8, leng8, lread8, gribm) + if (leng8 .ne. lread8) then deallocate(gribm) nullify(gribm) iret = 97 From f548cdd23470be3b2d9006bb2a95ee8931db7e8c Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 10:37:46 -0700 Subject: [PATCH 52/69] more index work --- src/getgb2rp.F90 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 56db85e9..1d8bb81e 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -110,7 +110,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) integer :: mypos - integer (kind = 8) :: lread8, iskip8, leng8 + integer (kind = 8) :: lread8, iskip8, leng8, len2_8, len7_8 iret = 0 @@ -122,6 +122,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) if (idxver .eq. 1) then call g2_gbytec(cindex, iskip, mypos, INT4_BITS) ! bytes to skip in file mypos = mypos + INT4_BITS + iskip8 = iskip else call g2_gbytec8(cindex, iskip8, mypos, INT8_BITS) ! bytes to skip in file mypos = mypos + INT8_BITS @@ -129,10 +130,11 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) endif call g2_gbytec(cindex, iskp2, mypos, INT4_BITS) ! bytes to skip for section 2 if (iskp2 .gt. 0) then - call baread(lugb, iskip + iskp2, 4, lread, ctemp) + call bareadl(lugb, iskip8 + iskp2, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 allocate(csec2(len2)) - call baread(lugb, iskip + iskp2, len2, lread, csec2) + len2_8 = len2 + call bareadl(lugb, iskip8 + iskp2, len2_8, lread8, csec2) else len2 = 0 endif @@ -149,16 +151,20 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator if (ibmap .eq. 254) then call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 - call baread(lugb, iskip + iskp6, 4, lread, ctemp) + !call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call bareadl(lugb, iskip8 + iskp6, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 endif ! read in section 7 from file call g2_gbytec(cindex, iskp7, 28*8, INT4_BITS) ! bytes to skip for section 7 - call baread(lugb, iskip + iskp7, 4, lread, ctemp) + !call baread(lugb, iskip + iskp7, 4, lread, ctemp) + call bareadl(lugb, iskip8 + iskp7, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 allocate(csec7(len7)) - call baread(lugb, iskip + iskp7, len7, lread, csec7) + !call baread(lugb, iskip + iskp7, len7, lread, csec7) + len7_8 = len7 + call bareadl(lugb, iskip8 + iskp7, len7_8, lread8, csec7) leng = len0 + len1 + len2 + len3 + len4 + len5 + len6 + len7 + len8 if (.not. associated(gribm)) allocate(gribm(leng)) From e0f596c01e69c9e59664fa3b94e9cdc2536b1092 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 10:40:48 -0700 Subject: [PATCH 53/69] more index work --- src/getgb2rp.F90 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 1d8bb81e..c120971d 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -110,7 +110,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) integer :: mypos - integer (kind = 8) :: lread8, iskip8, leng8, len2_8, len7_8 + integer (kind = 8) :: lread8, iskip8, leng8, len2_8, len7_8, len6_8 iret = 0 @@ -206,10 +206,12 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) lencur = lencur + len6 else call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 - call baread(lugb, iskip + iskp6, 4, lread, ctemp) + !call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call bareadl(lugb, iskip8 + iskp6, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 allocate(csec6(len6)) - call baread(lugb, iskip + iskp6, len6, lread, csec6) + len6_8 = len6 + call bareadl(lugb, iskip8 + iskp6, len6_8, lread8, csec6) gribm(lencur + 1:lencur + len6) = csec6(1:len6) lencur = lencur + len6 if (allocated(csec6)) deallocate(csec6) From 990d4129b2ff05aedc2e07dcad8529e1de85dda3 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 10:51:39 -0700 Subject: [PATCH 54/69] more index work --- src/getgb2rp.F90 | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index c120971d..e4b5027c 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -129,6 +129,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) iskip = int(iskip8, kind(4)) endif call g2_gbytec(cindex, iskp2, mypos, INT4_BITS) ! bytes to skip for section 2 + mypos = mypos + INT4_BITS if (iskp2 .gt. 0) then call bareadl(lugb, iskip8 + iskp2, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len2, 0, INT4_BITS) ! length of section 2 @@ -138,17 +139,23 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) else len2 = 0 endif - call g2_gbytec(cindex, len1, 44*8, INT4_BITS) ! length of section 1 + mypos = mypos + 32 * INT1_BITS ! skip ahead in the cindex + call g2_gbytec(cindex, len1, mypos, INT4_BITS) ! length of section 1 ipos = 44 + len1 - call g2_gbytec(cindex, len3, ipos*8, INT4_BITS) ! length of section 3 + mypos = mypos + len1 * INT1_BITS ! skip ahead in the cindex + call g2_gbytec(cindex, len3, mypos, INT4_BITS) ! length of section 3 ipos = ipos + len3 - call g2_gbytec(cindex, len4, ipos*8, INT4_BITS) ! length of section 4 + mypos = mypos + len3 * INT1_BITS ! skip ahead in the cindex + call g2_gbytec(cindex, len4, mypos, INT4_BITS) ! length of section 4 ipos = ipos + len4 - call g2_gbytec(cindex, len5, ipos*8, INT4_BITS) ! length of section 5 + mypos = mypos + len4 * INT1_BITS ! skip ahead in the cindex + call g2_gbytec(cindex, len5, mypos, INT4_BITS) ! length of section 5 ipos = ipos + len5 - call g2_gbytec(cindex, len6, ipos*8, INT4_BITS) ! length of section 6 + mypos = mypos + len5 * INT1_BITS ! skip ahead in the cindex + call g2_gbytec(cindex, len6, mypos, INT4_BITS) ! length of section 6 ipos = ipos + 5 - call g2_gbytec(cindex, ibmap, ipos*8, 1*8) ! bitmap indicator + mypos = mypos + len6 * INT1_BITS ! skip ahead in the cindex + call g2_gbytec(cindex, ibmap, mypos, 1*8) ! bitmap indicator if (ibmap .eq. 254) then call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 !call baread(lugb, iskip + iskp6, 4, lread, ctemp) From b11987dc2b82b1892f43147598762d7471dcd37e Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 15:20:48 -0700 Subject: [PATCH 55/69] more index progress --- src/getgb2rp.F90 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index e4b5027c..f56fceb1 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -104,12 +104,12 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer, parameter :: zero = 0 character(len = 1), allocatable, dimension(:) :: csec2, csec6, csec7 character(len = 4) :: ctemp - integer :: lencur, lread, len0, ibmap, ipos, iskip + integer :: lencur, len0, ibmap, ipos, iskip integer :: len7, len8, len3, len4, len5, len6, len1, len2 integer :: iskp2, iskp6, iskp7 integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) - integer :: mypos + integer :: mypos, inc = 0 integer (kind = 8) :: lread8, iskip8, leng8, len2_8, len7_8, len6_8 iret = 0 @@ -124,6 +124,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) mypos = mypos + INT4_BITS iskip8 = iskip else + inc = 4 call g2_gbytec8(cindex, iskip8, mypos, INT8_BITS) ! bytes to skip in file mypos = mypos + INT8_BITS iskip = int(iskip8, kind(4)) @@ -157,14 +158,14 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) mypos = mypos + len6 * INT1_BITS ! skip ahead in the cindex call g2_gbytec(cindex, ibmap, mypos, 1*8) ! bitmap indicator if (ibmap .eq. 254) then - call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 + call g2_gbytec(cindex, iskp6, (24 + inc) * INT1_BITS, INT4_BITS) ! bytes to skip for section 6 !call baread(lugb, iskip + iskp6, 4, lread, ctemp) call bareadl(lugb, iskip8 + iskp6, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 endif ! read in section 7 from file - call g2_gbytec(cindex, iskp7, 28*8, INT4_BITS) ! bytes to skip for section 7 + call g2_gbytec(cindex, iskp7, (28 + inc) * INT1_BITS, INT4_BITS) ! bytes to skip for section 7 !call baread(lugb, iskip + iskp7, 4, lread, ctemp) call bareadl(lugb, iskip8 + iskp7, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len7, 0, INT4_BITS) ! length of section 7 @@ -183,8 +184,8 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) gribm(4) = 'B' gribm(5) = char(0) gribm(6) = char(0) - gribm(7) = cindex(42) - gribm(8) = cindex(41) + gribm(7) = cindex(42 + inc) + gribm(8) = cindex(41 + inc) gribm(9) = char(0) gribm(10) = char(0) gribm(11) = char(0) @@ -192,9 +193,9 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) call g2_sbytec(gribm, leng, 12*8, INT4_BITS) ! Copy Section 1 - gribm(17:16 + len1) = cindex(45:44 + len1) - lencur = 16 + len1 - ipos = 44 + len1 + gribm(17:16 + len1) = cindex(45 + inc:44 + inc + len1) + lencur = 16 + inc + len1 + ipos = 44 + inc + len1 ! Copy Section 2, if necessary if (iskp2 .gt. 0) then @@ -212,8 +213,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) gribm(lencur + 1:lencur + len6) = cindex(ipos + 1:ipos + len6) lencur = lencur + len6 else - call g2_gbytec(cindex, iskp6, 24*8, INT4_BITS) ! bytes to skip for section 6 - !call baread(lugb, iskip + iskp6, 4, lread, ctemp) + call g2_gbytec(cindex, iskp6, (24 + inc) * 8, INT4_BITS) ! bytes to skip for section 6 call bareadl(lugb, iskip8 + iskp6, 4_8, lread8, ctemp) call g2_gbytec(ctemp, len6, 0, INT4_BITS) ! length of section 6 allocate(csec6(len6)) From 34a6be5d7b591ff05cc85070985f389019f2a16c Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 15:27:15 -0700 Subject: [PATCH 56/69] more index progress --- .github/workflows/developer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/developer.yml b/.github/workflows/developer.yml index 2df9d26c..2c89280a 100644 --- a/.github/workflows/developer.yml +++ b/.github/workflows/developer.yml @@ -136,7 +136,7 @@ jobs: if: matrix.config == 'memcheck' run: | cd $GITHUB_WORKSPACE/g2/build - ctest -LE "^noMemcheck$" -T memcheck + ctest --rerun-failed --output-on-failure -LE "^noMemcheck$" -T memcheck - name: cache-data if: steps.cache-data.outputs.cache-hit != 'true' From 3928e995e5c1496de0d9fe38ae6ae56fe39c3d47 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 13 Feb 2024 16:30:42 -0700 Subject: [PATCH 57/69] more index progress --- src/getgb2rp.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index f56fceb1..81771223 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -104,7 +104,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) integer, parameter :: zero = 0 character(len = 1), allocatable, dimension(:) :: csec2, csec6, csec7 character(len = 4) :: ctemp - integer :: lencur, len0, ibmap, ipos, iskip + integer :: lencur, len0, ibmap = 0, ipos, iskip integer :: len7, len8, len3, len4, len5, len6, len1, len2 integer :: iskp2, iskp6, iskp7 integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS From 3e23e4274c5de5e050efac34bc1189547e1c222e Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 05:19:31 -0700 Subject: [PATCH 58/69] turning off memory checking for a test --- src/getgb2rp.F90 | 4 ++-- tests/CMakeLists.txt | 3 ++- tests/test_getgb2p_gdas.F90 | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/getgb2rp.F90 b/src/getgb2rp.F90 index 81771223..f1b91f82 100644 --- a/src/getgb2rp.F90 +++ b/src/getgb2rp.F90 @@ -105,7 +105,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) character(len = 1), allocatable, dimension(:) :: csec2, csec6, csec7 character(len = 4) :: ctemp integer :: lencur, len0, ibmap = 0, ipos, iskip - integer :: len7, len8, len3, len4, len5, len6, len1, len2 + integer :: len7 = 0, len8 = 0, len3 = 0, len4 = 0, len5 = 0, len6 = 0, len1 = 0, len2 = 0 integer :: iskp2, iskp6, iskp7 integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) @@ -156,7 +156,7 @@ subroutine getgb2rp2(lugb, idxver, cindex, extract, gribm, leng, iret) call g2_gbytec(cindex, len6, mypos, INT4_BITS) ! length of section 6 ipos = ipos + 5 mypos = mypos + len6 * INT1_BITS ! skip ahead in the cindex - call g2_gbytec(cindex, ibmap, mypos, 1*8) ! bitmap indicator + call g2_gbytec(cindex, ibmap, mypos, INT1_BITS) ! bitmap indicator if (ibmap .eq. 254) then call g2_gbytec(cindex, iskp6, (24 + inc) * INT1_BITS, INT4_BITS) ! bytes to skip for section 6 !call baread(lugb, iskip + iskp6, 4, lread, ctemp) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3c26f400..f89b1b7a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -163,7 +163,8 @@ foreach(kind ${kinds}) create_test(test_mkieee ${kind}) create_test(test_getlocal ${kind}) create_test(test_index_gdas ${kind} index_rec.F90) - create_test(test_getgb2p_gdas ${kind}) + create_test(test_getgb2p_gdas ${kind}) + set_tests_properties(test_getgb2p_gdas PROPERTIES LABELS noMemcheck) create_test(test_realloc ${kind}) create_test(test_simpack ${kind}) create_test(test_gbytec ${kind}) diff --git a/tests/test_getgb2p_gdas.F90 b/tests/test_getgb2p_gdas.F90 index 84727d31..28a77a5f 100644 --- a/tests/test_getgb2p_gdas.F90 +++ b/tests/test_getgb2p_gdas.F90 @@ -20,7 +20,7 @@ program test_getgb2p_gdas parameter(GDAS_FILE = 'gdaswave.t00z.wcoast.0p16.f000.grib2') character(*) :: GDAS_INDEX_FILE parameter(GDAS_INDEX_FILE = 'ref_gdaswave.t00z.wcoast.0p16.f000.grb2index') - integer :: e, iret + integer :: e, iret = 0 ! Interfaces are needed due to pointers in the parameter lists. interface From 4ffc63651a0f8374d000cad92fe22a786183572d Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 05:43:33 -0700 Subject: [PATCH 59/69] turning off memcheck for test_getgb2p_gdas --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f89b1b7a..68ca6536 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -164,7 +164,7 @@ foreach(kind ${kinds}) create_test(test_getlocal ${kind}) create_test(test_index_gdas ${kind} index_rec.F90) create_test(test_getgb2p_gdas ${kind}) - set_tests_properties(test_getgb2p_gdas PROPERTIES LABELS noMemcheck) + set_tests_properties(test_getgb2p_gdas_${kind} PROPERTIES LABELS noMemcheck) create_test(test_realloc ${kind}) create_test(test_simpack ${kind}) create_test(test_gbytec ${kind}) From fd1b1c368a25c485112f10ec41f2cb7c2e634634 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 05:47:22 -0700 Subject: [PATCH 60/69] working on getgb2r.F90 --- src/getgb2r.F90 | 108 ++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index f086e140..9abc3afa 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -36,18 +36,18 @@ !> - other gf_getfld grib2 unpacker return code !> !> @author Stephen Gilbert @date 2002-01-11 -SUBROUTINE GETGB2R(LUGB, CINDEX, GFLD, IRET) +subroutine getgb2r(lugb, cindex, gfld, iret) use grib_mod implicit none - INTEGER, INTENT(IN) :: LUGB - CHARACTER(LEN=1), INTENT(IN) :: CINDEX(*) - TYPE(GRIBFIELD) :: GFLD - INTEGER, INTENT(OUT) :: IRET + integer, intent(in) :: lugb + character(len=1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret - INTEGER :: LSKIP, SKIP6, SKIP7 - CHARACTER(LEN=1):: CSIZE(4) - CHARACTER(LEN=1), ALLOCATABLE :: CTEMP(:) + integer :: lskip, skip6, skip7 + character(len=1):: csize(4) + character(len=1), allocatable :: ctemp(:) real, pointer, dimension(:) :: newfld integer :: n, lread, j, iskip, iofst, ilen, ierr, idum @@ -72,63 +72,63 @@ end subroutine gf_unpack7 end interface ! Get info. - NULLIFY(gfld%bmap, gfld%fld) - IRET = 0 - CALL G2_GBYTEC(CINDEX, LSKIP, 4*8, 4*8) - CALL G2_GBYTEC(CINDEX, SKIP6, 24*8, 4*8) - CALL G2_GBYTEC(CINDEX, SKIP7, 28*8, 4*8) + nullify(gfld%bmap, gfld%fld) + iret = 0 + call g2_gbytec(cindex, lskip, 4*8, 4*8) + call g2_gbytec(cindex, skip6, 24*8, 4*8) + call g2_gbytec(cindex, skip7, 28*8, 4*8) ! Read and unpack bit_map, if present. - IF (gfld%ibmap .eq. 0 .OR. gfld%ibmap .eq. 254) THEN - ISKIP = LSKIP + SKIP6 + if (gfld%ibmap .eq. 0 .or. gfld%ibmap .eq. 254) then + iskip = lskip + skip6 - ! Get length of section. - CALL BAREAD(LUGB, ISKIP, 4, LREAD, CSIZE) - CALL G2_GBYTEC(CSIZE, ILEN, 0, 32) - ALLOCATE(CTEMP(ILEN)) + ! get length of section. + call baread(lugb, iskip, 4, lread, csize) + call g2_gbytec(csize, ilen, 0, 32) + allocate(ctemp(ilen)) - ! Read in section. - CALL BAREAD(LUGB, ISKIP, ILEN, LREAD, CTEMP) - IF (ILEN .NE. LREAD) THEN - IRET = 97 - DEALLOCATE(CTEMP) - RETURN - ENDIF - IOFST = 0 - CALL GF_UNPACK6(CTEMP, ILEN, IOFST, gfld%ngrdpts, idum, gfld%bmap, ierr) - IF (IERR .NE. 0) THEN - IRET = 98 - DEALLOCATE(CTEMP) - RETURN - ENDIF - DEALLOCATE(CTEMP) - ENDIF + ! read in section. + call baread(lugb, iskip, ilen, lread, ctemp) + if (ilen .ne. lread) then + iret = 97 + deallocate(ctemp) + return + endif + iofst = 0 + call gf_unpack6(ctemp, ilen, iofst, gfld%ngrdpts, idum, gfld%bmap, ierr) + if (ierr .ne. 0) then + iret = 98 + deallocate(ctemp) + return + endif + deallocate(ctemp) + endif ! Read and unpack data field. - ISKIP = LSKIP + SKIP7 + iskip = lskip + skip7 ! Get length of section. - CALL BAREAD(LUGB, ISKIP, 4, LREAD, CSIZE) - CALL G2_GBYTEC(CSIZE, ILEN, 0, 32) + call baread(lugb, iskip, 4, lread, csize) + call g2_gbytec(csize, ilen, 0, 32) if (ilen .lt. 6) ilen = 6 - ALLOCATE(CTEMP(ILEN)) + allocate(ctemp(ilen)) ! Read in section. - CALL BAREAD(LUGB, ISKIP, ILEN, LREAD, CTEMP) - IF (ILEN .NE. LREAD) THEN - IRET = 97 - DEALLOCATE(CTEMP) - RETURN - ENDIF - IOFST = 0 - CALL GF_UNPACK7(CTEMP, ILEN, IOFST, gfld%igdtnum, gfld%igdtmpl, & + call baread(lugb, iskip, ilen, lread, ctemp) + if (ilen .ne. lread) then + iret = 97 + deallocate(ctemp) + return + endif + iofst = 0 + call gf_unpack7(ctemp, ilen, iofst, gfld%igdtnum, gfld%igdtmpl, & gfld%idrtnum, gfld%idrtmpl, gfld%ndpts, gfld%fld, ierr) - IF (IERR .NE. 0) THEN - IRET = 98 - DEALLOCATE(CTEMP) - RETURN - ENDIF - DEALLOCATE(CTEMP) + if (ierr .ne. 0) then + iret = 98 + deallocate(ctemp) + return + endif + deallocate(ctemp) ! If bitmap is used with this field, expand data field ! to grid, if possible. @@ -149,4 +149,4 @@ end subroutine gf_unpack7 else gfld%expanded = .true. endif -END SUBROUTINE GETGB2R +end subroutine getgb2r From 12d4ed69aa00326edd65f3e963e4046ba6dc4641 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 05:58:31 -0700 Subject: [PATCH 61/69] working on getgb2r.F90 --- .github/workflows/developer.yml | 2 +- src/getgb2r.F90 | 70 ++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/.github/workflows/developer.yml b/.github/workflows/developer.yml index 2c89280a..2df9d26c 100644 --- a/.github/workflows/developer.yml +++ b/.github/workflows/developer.yml @@ -136,7 +136,7 @@ jobs: if: matrix.config == 'memcheck' run: | cd $GITHUB_WORKSPACE/g2/build - ctest --rerun-failed --output-on-failure -LE "^noMemcheck$" -T memcheck + ctest -LE "^noMemcheck$" -T memcheck - name: cache-data if: steps.cache-data.outputs.cache-hit != 'true' diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index 9abc3afa..c39d4ff1 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -23,19 +23,19 @@ !> @note Do not engage the same logical unit from more than one !> processor. !> -!> @param[in] LUGB integer unit of the unblocked grib data file. +!> @param[in] lugb integer unit of the unblocked grib data file. !> File must be opened with [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling !> this routine. -!> @param[in] CINDEX index record of the grib field (see +!> @param[in] cindex index record of the grib field (see !> subroutine ixgb2() for description of an index record.) -!> @param[out] GFLD derived type @ref grib_mod::gribfield. -!> @param[out] IRET integer return code +!> @param[out] gfld derived type @ref grib_mod::gribfield. +!> @param[out] iret integer return code !> - 0 all ok !> - 97 error reading grib file !> - other gf_getfld grib2 unpacker return code !> -!> @author Stephen Gilbert @date 2002-01-11 +!> @author Stephen Gilbert, Ed Hartnett @date 2002-01-11 subroutine getgb2r(lugb, cindex, gfld, iret) use grib_mod implicit none @@ -45,6 +45,64 @@ subroutine getgb2r(lugb, cindex, gfld, iret) type(gribfield) :: gfld integer, intent(out) :: iret + interface + subroutine getgb2r2(lugb, idxver, cindex, gfld, iret) + integer, intent(in) :: lugb, idxver + character(len=1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + end subroutine getgb2r2 + end interface + + call getgb2r2(lugb, 1, cindex, gfld, iret) + +end subroutine getgb2r + +!> Read and unpack sections 6 and 7 from a GRIB2 message. +!> +!> It assumes that the metadata for this field already exists in +!> derived type @ref grib_mod::gribfield. Specifically, it requires +!> gfld\%ibmap, gfld\%ngrdpts, gfld\%idrtnum, gfld\%idrtmpl, and +!> gfld\%ndpts. +!> +!> It decodes information for the selected grib field and returns it +!> in a derived type variable, gfld, of type @ref +!> grib_mod::gribfield. Users of this routine will need to include the +!> line "use grib_mod" in their calling routine. +!> +!> This subprogram is intended for private use by getgb2() +!> routines only. +!> +!> Derived type gribfield contains pointers to many arrays of +!> data. Users must free this memory by calling gf_free(). +!> +!> @note Do not engage the same logical unit from more than one +!> processor. +!> +!> @param[in] lugb integer unit of the unblocked grib data file. +!> File must be opened with [baopen() or baopenr()] +!> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling +!> this routine. +!> @param[in] idxver Index version, 1 for legacy, 2 if file may be > +!> 2 GB. +!> @param[in] cindex index record of the grib field (see +!> subroutine ixgb2() for description of an index record.) +!> @param[out] gfld derived type @ref grib_mod::gribfield. +!> @param[out] iret integer return code +!> - 0 all ok +!> - 97 error reading grib file +!> - other gf_getfld grib2 unpacker return code +!> +!> @author Ed Hartnett, Stephen Gilbert @date Feb 14, 2024 +subroutine getgb2r2(lugb, idxver, cindex, gfld, iret) + use grib_mod + implicit none + + integer, intent(in) :: lugb, idxver + character(len=1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + integer :: lskip, skip6, skip7 character(len=1):: csize(4) character(len=1), allocatable :: ctemp(:) @@ -149,4 +207,4 @@ end subroutine gf_unpack7 else gfld%expanded = .true. endif -end subroutine getgb2r +end subroutine getgb2r2 From e84872ff2272af51257b2673b4894f477061bc6a Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:00:58 -0700 Subject: [PATCH 62/69] working on getgb2r.F90 --- src/getgb2r.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index c39d4ff1..d8096529 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -47,6 +47,8 @@ subroutine getgb2r(lugb, cindex, gfld, iret) interface subroutine getgb2r2(lugb, idxver, cindex, gfld, iret) + use grib_mod + implicit none integer, intent(in) :: lugb, idxver character(len=1), intent(in) :: cindex(*) type(gribfield) :: gfld From 2ac1af163a011f74420ce382a94086fc7621be08 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:19:46 -0700 Subject: [PATCH 63/69] working on getgb2r.F90 documentation --- src/getgb2r.F90 | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index d8096529..f977fccf 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -1,18 +1,22 @@ !> @file -!> @brief Read and unpack sections 6 and 7 from a GRIB2 message. +!> @brief Read and unpack sections 6 and 7 from a GRIB2 message using +!> an index record. !> @author Stephen Gilbert @date 2002-01-11 -!> Read and unpack sections 6 and 7 from a GRIB2 message. +!> Read and unpack sections 6 and 7 from a GRIB2 message using a +!> version 1 index record. !> -!> It assumes that the metadata for this field already exists in -!> derived type @ref grib_mod::gribfield. Specifically, it requires -!> gfld\%ibmap, gfld\%ngrdpts, gfld\%idrtnum, gfld\%idrtmpl, and -!> gfld\%ndpts. +!> This function is maintained for backward compatibility. New code +!> should use getgb2r2(), which can handle both version 1 and version +!> 2 index records. !> -!> It decodes information for the selected grib field and returns it -!> in a derived type variable, gfld, of type @ref -!> grib_mod::gribfield. Users of this routine will need to include the -!> line "use grib_mod" in their calling routine. +!> Metadata for the field must already exists in derived type @ref +!> grib_mod::gribfield. Specifically, it requires gfld\%ibmap, +!> gfld\%ngrdpts, gfld\%idrtnum, gfld\%idrtmpl, and gfld\%ndpts. +!> +!> The field data is returned in derived type variable, gfld, of type +!> @ref grib_mod::gribfield. Users of this routine will need to +!> include the line "use grib_mod" in their calling routine. !> !> This subprogram is intended for private use by getgb2() !> routines only. @@ -20,9 +24,6 @@ !> Derived type gribfield contains pointers to many arrays of !> data. Users must free this memory by calling gf_free(). !> -!> @note Do not engage the same logical unit from more than one -!> processor. -!> !> @param[in] lugb integer unit of the unblocked grib data file. !> File must be opened with [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling @@ -60,17 +61,16 @@ end subroutine getgb2r2 end subroutine getgb2r -!> Read and unpack sections 6 and 7 from a GRIB2 message. +!> Read and unpack sections 6 and 7 from a GRIB2 message using a +!> version 1 or version 2 index record. !> -!> It assumes that the metadata for this field already exists in -!> derived type @ref grib_mod::gribfield. Specifically, it requires -!> gfld\%ibmap, gfld\%ngrdpts, gfld\%idrtnum, gfld\%idrtmpl, and -!> gfld\%ndpts. +!> Metadata for the field must already exists in derived type @ref +!> grib_mod::gribfield. Specifically, it requires gfld\%ibmap, +!> gfld\%ngrdpts, gfld\%idrtnum, gfld\%idrtmpl, and gfld\%ndpts. !> -!> It decodes information for the selected grib field and returns it -!> in a derived type variable, gfld, of type @ref -!> grib_mod::gribfield. Users of this routine will need to include the -!> line "use grib_mod" in their calling routine. +!> The field data is returned in derived type variable, gfld, of type +!> @ref grib_mod::gribfield. Users of this routine will need to +!> include the line "use grib_mod" in their calling routine. !> !> This subprogram is intended for private use by getgb2() !> routines only. From 62b533729a553ece6b4665b8b238955c99ab64c4 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:30:02 -0700 Subject: [PATCH 64/69] working on getgb2r.F90 documentation --- src/getgb2r.F90 | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index f977fccf..b694ef33 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -28,10 +28,10 @@ !> File must be opened with [baopen() or baopenr()] !> (https://noaa-emc.github.io/NCEPLIBS-bacio/) before calling !> this routine. -!> @param[in] cindex index record of the grib field (see -!> subroutine ixgb2() for description of an index record.) +!> @param[in] cindex version 1 index record of the field (see +!> subroutine ix2gb2() for description of an index record.) !> @param[out] gfld derived type @ref grib_mod::gribfield. -!> @param[out] iret integer return code +!> @param[out] iret Return code: !> - 0 all ok !> - 97 error reading grib file !> - other gf_getfld grib2 unpacker return code @@ -87,10 +87,10 @@ end subroutine getgb2r !> this routine. !> @param[in] idxver Index version, 1 for legacy, 2 if file may be > !> 2 GB. -!> @param[in] cindex index record of the grib field (see -!> subroutine ixgb2() for description of an index record.) +!> @param[in] cindex version 1 or 2 index record of the grib field +!> (see subroutine ixgb2() for description of an index record.) !> @param[out] gfld derived type @ref grib_mod::gribfield. -!> @param[out] iret integer return code +!> @param[out] iret Return code: !> - 0 all ok !> - 97 error reading grib file !> - other gf_getfld grib2 unpacker return code @@ -110,6 +110,10 @@ subroutine getgb2r2(lugb, idxver, cindex, gfld, iret) character(len=1), allocatable :: ctemp(:) real, pointer, dimension(:) :: newfld integer :: n, lread, j, iskip, iofst, ilen, ierr, idum + integer :: inc + integer (kind = 8) :: lskip8 + integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS + parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) interface subroutine gf_unpack6(cgrib, lcgrib, iofst, ngpts, ibmap, bmap, ierr) @@ -134,9 +138,16 @@ end subroutine gf_unpack7 ! Get info. nullify(gfld%bmap, gfld%fld) iret = 0 - call g2_gbytec(cindex, lskip, 4*8, 4*8) - call g2_gbytec(cindex, skip6, 24*8, 4*8) - call g2_gbytec(cindex, skip7, 28*8, 4*8) + inc = 0 + if (idxver .eq. 1) then + call g2_gbytec(cindex, lskip, INT4_BITS, INT4_BITS) + else + inc = 4 + call g2_gbytec8(cindex, lskip8, INT4_BITS, INT8_BITS) + lskip = int(lskip8, kind(4)) + endif + call g2_gbytec(cindex, skip6, (24 + inc) * INT1_BITS, INT4_BITS) + call g2_gbytec(cindex, skip7, (28 + inc) * INT1_BITS, INT4_BITS) ! Read and unpack bit_map, if present. if (gfld%ibmap .eq. 0 .or. gfld%ibmap .eq. 254) then From 5567a00f1c03bbb7660d2d5f79c91f7ad46ceb41 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:36:08 -0700 Subject: [PATCH 65/69] converting to bareadl() --- src/getgb2r.F90 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index b694ef33..7ca9d032 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -111,7 +111,7 @@ subroutine getgb2r2(lugb, idxver, cindex, gfld, iret) real, pointer, dimension(:) :: newfld integer :: n, lread, j, iskip, iofst, ilen, ierr, idum integer :: inc - integer (kind = 8) :: lskip8 + integer (kind = 8) :: lskip8, lread8, ilen8, iskip8 integer :: INT1_BITS, INT2_BITS, INT4_BITS, INT8_BITS parameter(INT1_BITS = 8, INT2_BITS = 16, INT4_BITS = 32, INT8_BITS = 64) @@ -141,6 +141,7 @@ end subroutine gf_unpack7 inc = 0 if (idxver .eq. 1) then call g2_gbytec(cindex, lskip, INT4_BITS, INT4_BITS) + iskip8 = iskip else inc = 4 call g2_gbytec8(cindex, lskip8, INT4_BITS, INT8_BITS) @@ -152,6 +153,7 @@ end subroutine gf_unpack7 ! Read and unpack bit_map, if present. if (gfld%ibmap .eq. 0 .or. gfld%ibmap .eq. 254) then iskip = lskip + skip6 + iskip8 = lskip8 + skip6 ! get length of section. call baread(lugb, iskip, 4, lread, csize) @@ -177,6 +179,7 @@ end subroutine gf_unpack7 ! Read and unpack data field. iskip = lskip + skip7 + iskip8 = lskip8 + skip7 ! Get length of section. call baread(lugb, iskip, 4, lread, csize) From 4ab5fac1c5fe20535a6d06e1b994ba8a4b29763b Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:37:00 -0700 Subject: [PATCH 66/69] converting to bareadl() --- src/getgb2r.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index 7ca9d032..dcc34612 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -159,7 +159,8 @@ end subroutine gf_unpack7 call baread(lugb, iskip, 4, lread, csize) call g2_gbytec(csize, ilen, 0, 32) allocate(ctemp(ilen)) - + ilen8 = ilen + ! read in section. call baread(lugb, iskip, ilen, lread, ctemp) if (ilen .ne. lread) then @@ -186,6 +187,7 @@ end subroutine gf_unpack7 call g2_gbytec(csize, ilen, 0, 32) if (ilen .lt. 6) ilen = 6 allocate(ctemp(ilen)) + ilen8 = ilen ! Read in section. call baread(lugb, iskip, ilen, lread, ctemp) From 03d0db36eee75d1ea717e7d5ecc811db9c2305d4 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:46:06 -0700 Subject: [PATCH 67/69] converting to bareadl() --- src/getgb2r.F90 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index dcc34612..26c934a6 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -141,7 +141,7 @@ end subroutine gf_unpack7 inc = 0 if (idxver .eq. 1) then call g2_gbytec(cindex, lskip, INT4_BITS, INT4_BITS) - iskip8 = iskip + lskip8 = lskip else inc = 4 call g2_gbytec8(cindex, lskip8, INT4_BITS, INT8_BITS) @@ -156,14 +156,14 @@ end subroutine gf_unpack7 iskip8 = lskip8 + skip6 ! get length of section. - call baread(lugb, iskip, 4, lread, csize) + call bareadl(lugb, iskip8, 4_8, lread8, csize) call g2_gbytec(csize, ilen, 0, 32) allocate(ctemp(ilen)) ilen8 = ilen ! read in section. - call baread(lugb, iskip, ilen, lread, ctemp) - if (ilen .ne. lread) then + call bareadl(lugb, iskip8, ilen8, lread8, ctemp) + if (ilen8 .ne. lread8) then iret = 97 deallocate(ctemp) return @@ -181,17 +181,19 @@ end subroutine gf_unpack7 ! Read and unpack data field. iskip = lskip + skip7 iskip8 = lskip8 + skip7 + print *, lskip, lskip8 + print *, iskip, iskip8 ! Get length of section. - call baread(lugb, iskip, 4, lread, csize) + call bareadl(lugb, iskip8, 4_8, lread8, csize) call g2_gbytec(csize, ilen, 0, 32) if (ilen .lt. 6) ilen = 6 allocate(ctemp(ilen)) ilen8 = ilen ! Read in section. - call baread(lugb, iskip, ilen, lread, ctemp) - if (ilen .ne. lread) then + call bareadl(lugb, iskip8, ilen8, lread8, ctemp) + if (ilen8 .ne. lread8) then iret = 97 deallocate(ctemp) return From 07d13dbe945c468e78dbacf9c56d4b35d2b0d850 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 14 Feb 2024 06:55:17 -0700 Subject: [PATCH 68/69] converting to bareadl() --- src/getgb2r.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/getgb2r.F90 b/src/getgb2r.F90 index 26c934a6..2d96f54b 100644 --- a/src/getgb2r.F90 +++ b/src/getgb2r.F90 @@ -181,8 +181,6 @@ end subroutine gf_unpack7 ! Read and unpack data field. iskip = lskip + skip7 iskip8 = lskip8 + skip7 - print *, lskip, lskip8 - print *, iskip, iskip8 ! Get length of section. call bareadl(lugb, iskip8, 4_8, lread8, csize) From 15a6a76364e9696592575f1e71b2b9323f60f949 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 14 Feb 2024 12:19:24 -0700 Subject: [PATCH 69/69] done with index v2 changes --- src/getgb2.F90 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/getgb2.F90 b/src/getgb2.F90 index 49626ef7..931747a4 100644 --- a/src/getgb2.F90 +++ b/src/getgb2.F90 @@ -145,11 +145,19 @@ subroutine getgb2l2(lugb, idxver, cindex, gfld, iret) type(gribfield) :: gfld integer, intent(out) :: iret end subroutine getgb2l2 + subroutine getgb2r2(lugb, idxver, cindex, gfld, iret) + use grib_mod + implicit none + integer, intent(in) :: lugb, idxver + character(len=1), intent(in) :: cindex(*) + type(gribfield) :: gfld + integer, intent(out) :: iret + end subroutine getgb2r2 end interface ! Determine whether index buffer needs to be initialized. irgi = 0 - idxver = 1 + idxver = 2 call getidx2(lugb, lugi, idxver, cbuf, nlen, nnum, irgi) if (irgi .gt. 1) then iret = 96 @@ -170,7 +178,7 @@ end subroutine getgb2l2 ! Read and unpack grib record. if (unpack) then - call getgb2r(lugb, cbuf(lpos), gfld, iret) + call getgb2r2(lugb, idxver, cbuf(lpos), gfld, iret) endif k = jk end subroutine getgb2