53 subroutine gribcreate(cgrib, lcgrib, listsec0, listsec1, ierr)
56 character(len = 1),
intent(inout) :: cgrib(lcgrib)
57 integer,
intent(in) :: listsec0(*), listsec1(*)
58 integer,
intent(in) :: lcgrib
59 integer,
intent(out) :: ierr
61 integer :: i, lensec1, nbits
62 character(len = 4),
parameter :: grib =
'GRIB'
63 integer,
parameter :: ZERO = 0, one = 1
64 integer,
parameter :: mapsec1len = 13
65 integer,
parameter :: mapsec1(mapsec1len) = (/ 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1 /)
66 integer lensec0, iofst, ibeg
71 print *,
'gribcreate lcgrib ', lcgrib
75 if (listsec0(2) .ne. 2)
then
76 print *,
'gribcreate: can only code GRIB edition 2.'
102 nbits = mapsec1(i) * 8
103 call g2_sbytec(cgrib, listsec1(i), iofst, nbits)
104 iofst = iofst + nbits
109 lensec1 = (iofst - ibeg) / 8
114 call g2_sbytec(cgrib, lensec0 + lensec1, 96, 32)
183 subroutine addfield(cgrib,lcgrib,ipdsnum,ipdstmpl,ipdstmplen, &
184 coordlist,numcoord,idrsnum,idrstmpl, &
185 idrstmplen,fld,ngrdpts,ibmap,bmap,ierr)
191 character(len=1),
intent(inout) :: cgrib(lcgrib)
192 integer,
intent(in) :: ipdsnum,ipdstmpl(*)
193 integer,
intent(in) :: idrsnum,numcoord,ipdstmplen,idrstmplen
194 integer,
intent(in) :: lcgrib,ngrdpts,ibmap
195 real,
intent(in) :: coordlist(numcoord)
196 real(kind = 4) :: coordlist_4(numcoord)
197 real,
target,
intent(in) :: fld(ngrdpts)
198 integer,
intent(out) :: ierr
199 integer,
intent(inout) :: idrstmpl(*)
200 logical*1,
intent(in) :: bmap(ngrdpts)
202 character(len=4),
parameter :: grib=
'GRIB',c7777=
'7777'
203 character(len=4):: ctemp
204 character(len=1),
allocatable :: cpack(:)
205 real,
pointer,
dimension(:) :: pfld
206 real(4) :: coordieee(numcoord), re00, tmpre00(1)
207 integer(4) :: ire00,allones
208 integer :: mappds(ipdstmplen),intbmap(ngrdpts),mapdrs(idrstmplen)
209 integer,
parameter :: zero=0,one=1,four=4,five=5,six=6,seven=7
210 integer,
parameter :: minsize=50000
211 integer iofst,ibeg,lencurr,len,mappdslen,mapdrslen,lpos3
212 integer width,height,ndpts
213 integer lensec3,lensec4,lensec5,lensec6,lensec7
214 logical issec3,needext,isprevbmap
215 integer :: nbits, newlen, nsize, lcpack, left
216 integer :: ibmprev, ilen, ioctet, iscan, isecnum, itemp
217 integer :: i, jj, kk, mm
218 integer :: iret, istat
219 real (kind = 4) :: tmpfld(1)
221 allones = int(z
'FFFFFFFF')
227 if(cgrib(i) /= grib(i:i))
then
231 if (.not. match)
then
232 print *,
'addfield: GRIB not found in given message.'
233 print *,
'addfield: Call to routine gribcreate required to initialize GRIB messge.'
242 ctemp=cgrib(lencurr-3)//cgrib(lencurr-2)//cgrib(lencurr-1) //cgrib(lencurr)
243 if (ctemp.eq.c7777)
then
244 print *,
'addfield: GRIB message already complete. Cannot add new section.'
263 if (isecnum.eq.3)
then
269 if (isecnum.eq.6)
then
272 if ((ibmprev.ge.0).and.(ibmprev.le.253)) isprevbmap=.true.
276 if (len.eq.lencurr)
exit
279 if (len.gt.lencurr)
then
280 print *,
'addfield: Section byte counts don''t add to total.'
281 print *,
'addfield: Sum of section byte counts = ',len
282 print *,
'addfield: Total byte count in Section 0 = ',lencurr
289 if ((isecnum.ne.3) .and. (isecnum.ne.7))
then
290 print *,
'addfield: Sections 4-7 can only be added after', &
292 print *,
'addfield: Section ',isecnum,
' was the last found in', &
293 ' given GRIB message.'
298 elseif (.not.issec3)
then
299 print *,
'addfield: Sections 4-7 can only be added if Section', &
300 ' 3 was previously included.'
301 print *,
'addfield: Section 3 was not found in given GRIB message.'
302 print *,
'addfield: Call to routine addgrid required', &
303 ' to specify Grid definition.'
337 nbits=iabs(mappds(i))*8
338 if ((mappds(i).ge.0).or.(ipdstmpl(i).ge.0))
then
339 call g2_sbytec(cgrib,ipdstmpl(i),iofst,nbits)
342 call g2_sbytec(cgrib,iabs(ipdstmpl(i)),iofst+1,nbits-1)
349 if (numcoord .ne. 0)
then
351 coordlist_4(i) = real(coordlist(i), 4)
353 call mkieee(coordlist_4, coordieee, numcoord)
354 call g2_sbytescr(cgrib, coordieee, iofst, 32, 0, numcoord)
355 iofst = iofst + (32 * numcoord)
360 lensec4=(iofst-ibeg)/8
374 if (ibmap.eq.0 .OR. ibmap.eq.254)
then
375 allocate(pfld(max(2,ngrdpts)))
385 if(ndpts==0 .and. ngrdpts>0)
then
394 if (nsize .lt. minsize) nsize=minsize
395 allocate(cpack(nsize),stat=istat)
396 if (idrsnum.eq.0)
then
397 call simpack(pfld,ndpts,idrstmpl,cpack,lcpack)
398 elseif (idrsnum.eq.2.or.idrsnum.eq.3)
then
399 call cmplxpack(pfld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
400 elseif (idrsnum.eq.50)
then
401 call simpack(pfld(2),ndpts-1,idrstmpl,cpack,lcpack)
402 tmpfld(1) = real(pfld(1), 4)
403 call mkieee(tmpfld, tmpre00, 1)
405 ire00 = transfer(re00, ire00)
407 elseif (idrsnum.eq.51)
then
408 call getpoly(cgrib(lpos3),lensec3,jj,kk,mm)
409 if (jj.ne.0 .AND. kk.ne.0 .AND. mm.ne.0)
then
410 call specpack(pfld,ndpts,jj,kk,mm,idrstmpl,cpack,lcpack)
412 print *,
'addfield: Cannot pack DRT 5.51.'
417 elseif (idrsnum.eq.40 .OR. idrsnum.eq.40000)
then
418 if (ibmap.eq.255)
then
419 call getdim(cgrib(lpos3),lensec3,width,height,iscan)
420 if (width.eq.0 .OR. height.eq.0)
then
423 elseif (width.eq.allones .OR. height.eq.allones)
then
426 elseif (ibits(iscan,5,1) .eq. 1)
then
435 if(width<1 .or. height<1)
then
437 write(0,*)
'Warning: bitmask off everywhere.'
438 write(0,*)
' Pretend one point in jpcpack to avoid crash.'
444 call jpcpack(pfld,width,height,idrstmpl,cpack,lcpack)
446 elseif (idrsnum.eq.41 .OR. idrsnum.eq.40010)
then
447 if (ibmap.eq.255)
then
448 call getdim(cgrib(lpos3),lensec3,width,height,iscan)
449 if (width.eq.0 .OR. height.eq.0)
then
452 elseif (width.eq.allones .OR. height.eq.allones)
then
455 elseif (ibits(iscan,5,1) .eq. 1)
then
465 call pngpack(pfld,width,height,idrstmpl,cpack,lcpack)
468 print *,
'addfield: Data Representation Template 5.',idrsnum, &
469 ' not yet implemented.'
473 if (ibmap.eq.0 .OR. ibmap.eq.254)
then
476 if (lcpack .lt. 0)
then
477 if(
allocated(cpack))
deallocate(cpack)
496 nbits=iabs(mapdrs(i))*8
497 if ((mapdrs(i).ge.0).or.(idrstmpl(i).ge.0))
then
498 call g2_sbytec(cgrib,idrstmpl(i),iofst,nbits)
501 call g2_sbytec(cgrib,iabs(idrstmpl(i)),iofst+1,nbits-1)
508 lensec5=(iofst-ibeg)/8
521 call g2_sbytesc(cgrib,intbmap,iofst,1,0,ngrdpts)
527 if ((ibmap.eq.254).and.(.not.isprevbmap))
then
528 print *,
'addfield: Requested previously defined bitmap, ', &
529 ' but one does not exist in the current GRIB message.'
541 lensec6=(iofst-ibeg)/8
550 if (lcpack.ne.0)
then
552 cgrib(ioctet+1:ioctet+lcpack)=cpack(1:lcpack)
553 iofst=iofst+(8*lcpack)
558 lensec7=(iofst-ibeg)/8
561 if(
allocated(cpack) )
deallocate(cpack)
564 newlen=lencurr+lensec4+lensec5+lensec6+lensec7
613 subroutine addgrid(cgrib, lcgrib, igds, igdstmpl, igdstmplen, &
614 ideflist, idefnum, ierr)
618 character(len = 1),
intent(inout) :: cgrib(lcgrib)
619 integer,
intent(in) :: igds(*), igdstmpl(*), ideflist(idefnum)
620 integer,
intent(in) :: lcgrib, idefnum, igdstmplen
621 integer,
intent(out) :: ierr
623 character(len = 4),
parameter :: grib =
'GRIB', c7777 =
'7777'
624 character(len = 4):: ctemp
625 integer:: mapgrid(igdstmplen)
626 integer,
parameter :: ONE = 1, three = 3
627 integer lensec3, iofst, ibeg, lencurr, len, mapgridlen
629 integer :: i, ilen, iret, isecnum, nbits
634 print *,
'addgrid lcgrib ', lcgrib,
' igdstmplen ', igdstmplen,
' idefnum ', idefnum
639 if (cgrib(i) /= grib(i:i))
then
640 print *,
'addgrid: GRIB not found in given message.'
641 print *,
'addgrid: Call to routine gribcreate required', &
642 ' to initialize GRIB messge.'
643 10
format(
'"', 4a1,
'" /= "GRIB"')
654 ctemp = cgrib(lencurr - 3) // cgrib(lencurr - 2) // cgrib(lencurr &
655 - 1) // cgrib(lencurr)
656 if (ctemp .eq. c7777)
then
657 print *,
'addgrid: GRIB message already complete. Cannot', &
675 if (len .eq. lencurr)
exit
679 if (len .gt. lencurr)
then
680 print *,
'addgrid: Section byte counts don''t add to total.'
681 print *,
'addgrid: Sum of section byte counts = ', len
682 print *,
'addgrid: Total byte count in Section 0 = ', lencurr
689 if ((isecnum .ne. 1) .and. (isecnum .ne. 2) .and. &
690 (isecnum .ne. 7))
then
691 print *,
'addgrid: Section 3 can only be added after Section', &
693 print *,
'addgrid: Section ', isecnum, &
694 ' was the last found in given GRIB message.'
706 call g2_sbytec(cgrib, igds(2), iofst, 32)
715 if (igds(1) .eq. 0)
then
716 call g2_sbytec(cgrib, igds(5), iofst, 16)
723 if (igds(1) .eq. 0)
then
726 if (iret .ne. 0)
then
746 nbits = iabs(mapgrid(i)) * 8
747 if ((mapgrid(i) .ge. 0) .or. (igdstmpl(i) .ge. 0))
then
748 call g2_sbytec(cgrib, igdstmpl(i), iofst, nbits)
751 call g2_sbytec(cgrib, iabs(igdstmpl(i)), iofst + 1, nbits &
754 iofst = iofst + nbits
759 if (igds(3) .ne. 0)
then
761 call g2_sbytesc(cgrib, ideflist, iofst, nbits, 0, idefnum)
762 iofst = iofst + (nbits * idefnum)
767 lensec3 = (iofst - ibeg) / 8
772 call g2_sbytec(cgrib, lencurr + lensec3, 96, 32)
799 subroutine addlocal(cgrib, lcgrib, csec2, lcsec2, ierr)
802 character(len = 1),
intent(inout) :: cgrib(lcgrib)
803 character(len = 1),
intent(in) :: csec2(lcsec2)
804 integer,
intent(in) :: lcgrib, lcsec2
805 integer,
intent(out) :: ierr
807 character(len = 4),
parameter :: grib =
'GRIB', c7777 =
'7777'
808 character(len = 4):: ctemp
809 integer,
parameter :: two = 2
810 integer :: lensec2, iofst, ibeg, lencurr, len
811 integer :: ilen, isecnum, istart
816 ctemp = cgrib(1) // cgrib(2) // cgrib(3) // cgrib(4)
817 if (ctemp .ne. grib)
then
818 print *,
'addlocal: GRIB not found in given message.'
819 print *,
'addlocal: Call to routine gribcreate required', &
820 ' to initialize GRIB messge.'
829 ctemp = cgrib(lencurr - 3) // cgrib(lencurr - 2) // cgrib(lencurr - 1) // cgrib(lencurr)
830 if (ctemp .eq. c7777)
then
831 print *,
'addlocal: GRIB message already complete. Cannot add new section.'
847 if (len .eq. lencurr)
exit
851 if (len .gt. lencurr)
then
852 print *,
'addlocal: Section byte counts don''t add to total.'
853 print *,
'addlocal: Sum of section byte counts = ', len
854 print *,
'addlocal: Total byte count in Section 0 = ', lencurr
861 if ((isecnum .ne. 1) .and. (isecnum .ne. 7))
then
862 print *,
'addlocal: Section 2 can only be added after Section 1 or Section 7.'
863 print *,
'addlocal: Section ', isecnum,
' was the last found in given GRIB message.'
873 cgrib(istart + 1:istart + lcsec2) = csec2(1:lcsec2)
881 call g2_sbytec(cgrib, lencurr+lensec2, 96, 32)
905 subroutine gribend(cgrib, lcgrib, lengrib, ierr)
908 character(len = 1),
intent(inout) :: cgrib(lcgrib)
909 integer,
intent(in) :: lcgrib
910 integer,
intent(out) :: lengrib, ierr
912 integer ilen, isecnum
913 character(len = 4),
parameter :: grib =
'GRIB'
914 character(len = 1),
parameter :: c7777(4) = (/
'7',
'7',
'7',
'7' /)
915 character(len = 4):: ctemp
916 integer iofst, lencurr, len
921 ctemp = cgrib(1) // cgrib(2) // cgrib(3) // cgrib(4)
922 if (ctemp .ne. grib)
then
923 print *,
'gribend: GRIB not found in given message.'
943 if (len .eq. lencurr)
exit
947 if (len .gt. lencurr)
then
948 print *,
'gribend: Section byte counts don''t add ' &
950 print *,
'gribend: Sum of section byte counts = ', len
951 print *,
'gribend: Total byte count in Section 0 = ', &
959 if (isecnum .ne. 7)
then
960 print *,
'gribend: Section 8 can only be added after Section 7.'
961 print *,
'gribend: Section ', isecnum, &
962 ' was the last found in',
' given GRIB message.'
968 cgrib(lencurr + 1:lencurr + 4) = c7777
971 lengrib = lencurr + 4
subroutine cmplxpack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack up a data field using a complex packing algorithm.
subroutine g2_gbytec(in, iout, iskip, nbits)
Extract one arbitrary size big-endian value (up to 32 bits) from a packed bit string into one element...
subroutine mkieee(a, rieee, num)
Copy an array of real to an array of 32-bit IEEE floating points.
subroutine g2_sbytescr(out, rin, iskip, nbits, nskip, n)
Put real values into a packed bit string in big-endian order.
subroutine g2_sbytec(out, in, iskip, nbits)
Put one arbitrary sized (up to 32 bits) value from an integer array, into a packed bit string,...
subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n)
Put arbitrary size (up to 32 bits each) integer values into a packed bit string in big-endian order.
subroutine addgrid(cgrib, lcgrib, igds, igdstmpl, igdstmplen, ideflist, idefnum, ierr)
Add a Grid Definition Section (Section 3) to a GRIB2 message.
subroutine addlocal(cgrib, lcgrib, csec2, lcsec2, ierr)
Add a Local Use Section (Section 2) to a GRIB2 message.
subroutine gribcreate(cgrib, lcgrib, listsec0, listsec1, ierr)
Initialize a new GRIB2 message and pack GRIB2 sections 0 (Indicator) and 1 (Identification).
subroutine addfield(cgrib, lcgrib, ipdsnum, ipdstmpl, ipdstmplen, coordlist, numcoord, idrsnum, idrstmpl, idrstmplen, fld, ngrdpts, ibmap, bmap, ierr)
Pack up Sections 4 through 7 for a field and add them to a GRIB2 message.
subroutine gribend(cgrib, lcgrib, lengrib, ierr)
Finalize a GRIB2 message after all grids and fields have been added.
subroutine getdim(csec3, lcsec3, width, height, iscan)
Return the dimensions and scanning mode of a grid definition packed in the Grid Definition Section.
subroutine getpoly(csec3, lcsec3, jj, kk, mm)
Return the J, K, and M pentagonal resolution parameters specified in a GRIB2 Grid Definition Section ...
subroutine jpcpack(fld, width, height, idrstmpl, cpack, lcpack)
Pack a data field into a JPEG2000 code stream as defined in Data Representation Template 5....
subroutine pngpack(fld, width, height, idrstmpl, cpack, lcpack)
Pack a data field into PNG image format, defined in [Data Representation Template 5....
subroutine simpack(fld, ndpts, idrstmpl, cpack, lcpack)
Pack a data field using a simple packing algorithm.
subroutine specpack(fld, ndpts, JJ, KK, MM, idrstmpl, cpack, lcpack)
Pack a spectral data field using the complex packing algorithm for spherical harmonic data as defined...
Handles Data Representation Templates used in Section 5.
subroutine getdrstemplate(number, nummap, map, needext, iret)
Return DRS template information for a specified Data Representation Template.
This Fortran module contains info on all the available GRIB2 Grid Definition Templates used in [Secti...
subroutine getgridtemplate(number, nummap, map, needext, iret)
Get the grid template information for a specified Grid Definition Template.
subroutine extgridtemplate(number, list, nummap, map)
Generate the remaining octet map for a given Grid Definition Template, if required.
Information on all GRIB2 Product Definition Templates used in Section 4 - the Product Definition Sect...
subroutine extpdstemplate(number, list, nummap, map)
This subroutine generates the remaining octet map for a given Product Definition Template,...
subroutine getpdstemplate(number, nummap, map, needext, iret)
This subroutine returns PDS template information for a specified Product Definition Template.