diff --git a/src/g2index.F90 b/src/g2index.F90 index f7e08368..00fc9060 100644 --- a/src/g2index.F90 +++ b/src/g2index.F90 @@ -57,7 +57,7 @@ end subroutine getg2i2r mnum = mnum + nmess ! Write headers. - call g2_write_index_headers(lugi, nlen, numtot, filename) + call g2_write_index_headers(lugi, nlen, numtot, idxver, filename) iw = 162 ! Write the index data we have so far. @@ -81,7 +81,7 @@ end subroutine getg2i2r endif enddo ! Go back and overwrite headers with new info. - call g2_write_index_headers(lugi, iw, numtot, filename) + call g2_write_index_headers(lugi, iw, numtot, idxver, filename) endif deallocate(cbuf) @@ -92,13 +92,15 @@ end subroutine g2_create_index !> @param[in] lugi integer logical unit of output index file !> @param[in] nlen integer total length of index records !> @param[in] nnum integer number of index records +!> @param[in] idxver Index version, 1 for legacy, 2 for files that may +!> be > 2 GB. !> @param[in] filename character name of GRIB file !> -!> @author Iredell @date 93-11-22 -subroutine g2_write_index_headers(lugi, nlen, nnum, filename) +!> @author Iredell, Ed Hartnett @date 93-11-22 +subroutine g2_write_index_headers(lugi, nlen, nnum, idxver, filename) implicit none - integer, intent(in) :: lugi, nlen, nnum + integer, intent(in) :: lugi, nlen, nnum, idxver character, intent(in) :: filename*(*) character cd8*8, ct10*10, hostname*15 @@ -135,7 +137,11 @@ subroutine g2_write_index_headers(lugi, nlen, nnum, filename) chead(1)(81:81) = char(10) ! fill second 81-byte header - chead(2) = 'IX1FORM:' + if (idxver .eq. 1) then + chead(2) = 'IX1FORM:' + else + chead(2) = 'IX2FORM:' + endif write(chead(2)(9:38),'(3i10)') 162, nlen, nnum chead(2)(41:80) = filename chead(2)(81:81) = char(10) diff --git a/tests/test_create_index.F90 b/tests/test_create_index.F90 index 01da21c0..b45025f4 100644 --- a/tests/test_create_index.F90 +++ b/tests/test_create_index.F90 @@ -13,7 +13,7 @@ program test_create_index character(*) :: TEST_FILE_GDAS_INDEX parameter (TEST_FILE_GDAS_INDEX = 'test_create_index_gdaswave.grb2index') character(len=1), pointer, dimension(:) :: cbuf(:) - integer :: idxver = 1, nlen, nnum, lugi = 31, lugb = 11 + integer :: idxver, myidxver, nlen, nnum, lugi = 31, lugb = 11 integer :: j, jdisc, jpdtn, jgdtn integer :: jids(13), jpdt(100), jgdt(250) integer :: i @@ -22,8 +22,55 @@ program test_create_index integer :: expected_idsect(13) = (/ 7, 0, 2, 1, 1, 2021, 11, 30, 0, 0, 0, 0, 1 /) integer :: expected_igdtmpl(19) = (/ 6, 0, 0, 0, 0, 0, 0, 241, 151, 0, 0, 50000000, & 210000000, 48, 25000000, 250000000, 166667, 166667, 0 /) - integer :: expected_ipdtmpl(15) = (/ 2, 1, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0 /) - integer :: expected_idrtmpl(7) = (/ 1092616192, 0, 2, 11, 0, 0, 255 /) + + ! These are the PDT templates of the 19 messages in the test file, + ! verified with degrib2. + integer :: expected_ipdtmpl(15, 19) = reshape((/ & + 2, 1, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 2, 0, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 2, 2, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 2, 3, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 3, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 11, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 10, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 5, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 8, 2, 0, 11, 0, 0, 1, 0, 241, 0, 1, 255, 0, 0, & + 0, 8, 2, 0, 11, 0, 0, 1, 0, 241, 0, 2, 255, 0, 0, & + 0, 8, 2, 0, 11, 0, 0, 1, 0, 241, 0, 3, 255, 0, 0, & + 0, 6, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 9, 2, 0, 11, 0, 0, 1, 0, 241, 0, 1, 255, 0, 0, & + 0, 9, 2, 0, 11, 0, 0, 1, 0, 241, 0, 2, 255, 0, 0, & + 0, 9, 2, 0, 11, 0, 0, 1, 0, 241, 0, 3, 255, 0, 0, & + 0, 4, 2, 0, 11, 0, 0, 1, 0, 1, 0, 1, 255, 0, 0, & + 0, 7, 2, 0, 11, 0, 0, 1, 0, 241, 0, 1, 255, 0, 0, & + 0, 7, 2, 0, 11, 0, 0, 1, 0, 241, 0, 2, 255, 0, 0, & + 0, 7, 2, 0, 11, 0, 0, 1, 0, 241, 0, 3, 255, 0, 0 /), & + shape(expected_ipdtmpl)) + + ! These are the DRT templates of the 19 messages in the test file, + ! verified with degrib2. + integer :: expected_idrtmpl(7, 19) = reshape((/ & + 1092616192, 0, 2, 11, 0, 0, 255, & + 1065353216, 0, 2, 16, 0, 0, 255, & + -1006403584, 0, 2, 11, 0, 0, 255, & + -996777984, 0, 2, 12, 0, 0, 255, & + 1102053376, 0, 2, 9, 0, 0, 255, & + 1144815616, 0, 2, 10, 0, 0, 255, & + 1185159680, 0, 2, 14, 0, 0, 255, & + 1086324736, 0, 2, 9, 0, 0, 255, & + 1095761920, 0, 2, 9, 0, 0, 255, & + 1086324736, 0, 2, 8, 0, 0, 255, & + 1084227584, 0, 2, 7, 0, 0, 255, & + 1125908480, 0, 2, 11, 0, 0, 255, & + 1136328704, 0, 2, 11, 0, 0, 255, & + 1135411200, 0, 2, 11, 0, 0, 255, & + 1133510656, 0, 2, 11, 0, 0, 255, & + 0, 0, 2, 16, 0, 0, 255, & + 1183603200, 0, 2, 14, 0, 0, 255, & + 1140424704, 0, 2, 16, 0, 0, 255, & + 1092616192, 0, 2, 16, 0, 0, 255 /), & + shape(expected_idrtmpl)) + integer :: ios interface @@ -40,94 +87,118 @@ end subroutine g2_create_index end interface print *, 'Testing index creation and reading.' - print *, 'testing g2_create_index on ', TEST_FILE_GDAS - - ! Open GRIB2 file for reading. - call baopenr(lugb, TEST_FILE_GDAS, ios) - if (ios .ne. 0) stop 2 - - ! Open output file where index will be written. - call baopen(lugi, TEST_FILE_GDAS_INDEX, ios) - if (ios .ne. 0) stop 3 - - call g2_create_index(lugb, lugi, idxver, TEST_FILE_GDAS, iret) - if (iret .ne. 0) stop 10 - - call baclose(lugb, ios) - if (ios .ne. 0) stop 11 - call baclose(lugi, ios) - if (ios .ne. 0) stop 12 - - print *, 'OK!' - print *, 'testing that index file can be read with getg2i2()...' - - ! Open the index file. - call baopen(lugi, TEST_FILE_GDAS_INDEX, iret) - if (iret .ne. 0) stop 20 - - ! Read the index file. - call getg2i2(lugi, cbuf, idxver, nlen, nnum, iret) - if (nlen .ne. 3800 .or. nnum .ne. 19 .or. iret .ne. 0) stop 80 - - ! Close the index file. - call baclose(lugi, iret) - if (iret .ne. 0) stop 100 - - print *, 'OK!' - print *, 'testing that index buffer can be understood by getgb2s2()...' - - ! Parse the index info in cbuf, and fill gfld with the info about - ! the first message. - j = 0 - jdisc = -1 - do i = 1, 13 - jids(i) = -9999 - end do - jpdtn = -1 - do i = 1, 100 - jpdt(i) = -9999 - end do - jgdtn = -1 - do i = 1, 250 - jgdt(i) = -9999 - end do - call getgb2s2(cbuf, idxver, nlen, nnum, j, jdisc, jids, jpdtn, jpdt, jgdtn, & - jgdt, k, gfld, lpos, iret) - if (iret .ne. 0) stop 101 - - ! Check that the information is correct for the first record. - if (gfld%version .ne. 2 .or. gfld%discipline .ne. 0) stop 102 - if (gfld%idsectlen .ne. 13) stop 103 - if (gfld%ifldnum .ne. 1) stop 105 - if (gfld%griddef .ne. 0) stop 106 - if (gfld%ngrdpts .ne. 36391) stop 107 - if (gfld%numoct_opt .ne. 0 .or. gfld%interp_opt .ne. 0 .or. gfld%num_opt .ne. 0) stop 108 - if (gfld%igdtnum .ne. 0 .or. gfld%igdtlen .ne. 19) stop 109 - if (gfld%ipdtnum .ne. 0 .or. gfld%ipdtlen .ne. 15 .or. gfld%num_coord .ne. 0) stop 110 - if (gfld%unpacked .neqv. .FALSE.) stop 112 - if (gfld%ibmap .ne. 0) stop 113 - do i = 1, gfld%idsectlen - if (gfld%idsect(i) .ne. expected_idsect(i)) stop 200 - end do - do i = 1, gfld%igdtlen - if (gfld%igdtmpl(i) .ne. expected_igdtmpl(i)) stop 201 - end do - do i = 1, gfld%ipdtlen - if (gfld%ipdtmpl(i) .ne. expected_ipdtmpl(i)) stop 202 + do idxver = 1, 2 + print *, 'testing g2_create_index version ', idxver + + ! Open GRIB2 file for reading. + call baopenr(lugb, TEST_FILE_GDAS, ios) + if (ios .ne. 0) stop 2 + + ! Open output file where index will be written. + call baopen(lugi, TEST_FILE_GDAS_INDEX, ios) + if (ios .ne. 0) stop 3 + + call g2_create_index(lugb, lugi, idxver, TEST_FILE_GDAS, iret) + if (iret .ne. 0) stop 10 + + call baclose(lugb, ios) + if (ios .ne. 0) stop 11 + call baclose(lugi, ios) + if (ios .ne. 0) stop 12 + + print *, ' OK!' + print *, ' testing that index file can be read with getg2i2()...' + + ! Open the index file. + call baopen(lugi, TEST_FILE_GDAS_INDEX, iret) + if (iret .ne. 0) stop 20 + + ! Read the index file. + call getg2i2(lugi, cbuf, myidxver, nlen, nnum, iret) + !print *, myidxver, nlen, nnum, iret + if (myidxver .ne. idxver) stop 79 + if (idxver .eq. 1) then + if (nlen .ne. 3800) stop 80 + else + if (nlen .ne. 3876) stop 80 + endif + if (nnum .ne. 19 .or. iret .ne. 0) stop 81 + + ! Close the index file. + call baclose(lugi, iret) + if (iret .ne. 0) stop 100 + + print *, ' OK!' + + ! Parse the index info in cbuf, and fill gfld with the info about + ! the first message. + jdisc = -1 + do i = 1, 13 + jids(i) = -9999 + end do + jpdtn = -1 + do i = 1, 100 + jpdt(i) = -9999 + end do + jgdtn = -1 + do i = 1, 250 + jgdt(i) = -9999 + end do + do j = 1, 19 + print *, ' testing unpacking index buffer with getgb2s2() for message', j + call getgb2s2(cbuf, idxver, nlen, nnum, j - 1, jdisc, jids, jpdtn, jpdt, jgdtn, & + jgdt, k, gfld, lpos, iret) + if (iret .ne. 0) stop 101 + + ! Check that the information is correct for the first record. + if (gfld%version .ne. 2) stop 102 + if (j .lt. 5) then + if (gfld%discipline .ne. 0) stop 103 + else + if (gfld%discipline .ne. 10) stop 104 + end if + if (gfld%idsectlen .ne. 13) stop 110 + if (gfld%ifldnum .ne. 1) stop 111 + if (gfld%griddef .ne. 0) stop 112 + if (gfld%ngrdpts .ne. 36391) stop 120 + if (gfld%numoct_opt .ne. 0 .or. gfld%interp_opt .ne. 0 .or. gfld%num_opt .ne. 0) stop 122 + if (gfld%igdtnum .ne. 0 .or. gfld%igdtlen .ne. 19) stop 123 + if (gfld%ipdtnum .ne. 0 .or. gfld%ipdtlen .ne. 15 .or. gfld%num_coord .ne. 0) stop 130 + if (gfld%unpacked .neqv. .FALSE.) stop 131 + if (gfld%ibmap .ne. 0) stop 132 + do i = 1, gfld%idsectlen + if (gfld%idsect(i) .ne. expected_idsect(i)) stop 200 + end do + do i = 1, gfld%igdtlen + if (gfld%igdtmpl(i) .ne. expected_igdtmpl(i)) stop 210 + end do + do i = 1, gfld%ipdtlen + if (gfld%ipdtmpl(i) .ne. expected_ipdtmpl(i, j)) then + print *, i, gfld%ipdtmpl(i), expected_ipdtmpl(i, j) + print *, 'gfld%ipdtmpl', gfld%ipdtmpl + print *, 'expected_ipdtmpl', expected_ipdtmpl + stop 220 + endif + end do + do i = 1, gfld%idrtlen + if (gfld%idrtmpl(i) .ne. expected_idrtmpl(i, j)) then + print *, i, gfld%idrtmpl(i), expected_idrtmpl(i, j) + print *, 'gfld%idrtmpl', gfld%idrtmpl + print *, 'expected_idrtmpl', expected_idrtmpl + stop 230 + endif + end do + + ! Free memory. + call gf_free(gfld) + print *, ' OK!' + end do + + ! Clean up. + deallocate(cbuf) + call gf_finalize(iret) + if (iret .ne. 0) stop 200 + print *, 'OK!' end do - do i = 1, gfld%idrtlen - if (gfld%idrtmpl(i) .ne. expected_idrtmpl(i)) stop 203 - end do - - ! Free memory. - call gf_free(gfld) - - print *, 'OK!' - - ! Clean up. - deallocate(cbuf) - call gf_finalize(iret) - if (iret .ne. 0) stop 200 - print *, 'SUCCESS!...' end program test_create_index