42 subroutine cmplxpack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
44 integer,
intent(in) :: ndpts,idrsnum
45 real,
intent(in) :: fld(ndpts)
46 character(len=1),
intent(out) :: cpack(*)
47 integer,
intent(inout) :: idrstmpl(*)
48 integer,
intent(out) :: lcpack
50 if ( idrstmpl(7) .eq. 0 )
then
51 call compack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
52 elseif ( idrstmpl(7).eq.1 .OR. idrstmpl(7).eq.2)
then
53 call misspack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
55 print *,
'cmplxpack: Do not recognize Missing value option.'
88 subroutine compack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
92 integer,
intent(in) :: ndpts,idrsnum
93 real,
intent(in) :: fld(ndpts)
94 character(len=1),
intent(out) :: cpack(*)
95 integer,
intent(inout) :: idrstmpl(*)
96 integer,
intent(out) :: lcpack
99 integer :: j,iofst,imin,ival1,ival2,minsd,nbitsd,n
100 integer :: igmax,nbitsgref,left,iwmax,i,ilmax,kk,ij
101 integer :: ngwidthref,nbitsgwidth,nglenref,nglenlast
102 integer :: maxorig,nbitorig,isd,ngroups,itemp,minpk
103 integer :: inc,maxgrps,missopt,miss1,miss2,lg
104 integer :: ibit,jbit,kbit,novref,lbitref,ier,ng,imax
110 integer,
allocatable :: ifld(:)
111 integer,
allocatable :: jmin(:),jmax(:),lbit(:)
112 integer,
parameter :: zero=0
113 integer,
allocatable :: gref(:),gwidth(:),glen(:)
114 integer :: glength,grpwidth
115 logical :: simple_alg
119 bscale=2.0**real(-idrstmpl(2))
120 dscale=10.0**real(idrstmpl(3))
132 if (fld(j).gt.rmax) rmax=fld(j)
133 if (fld(j).lt.rmin) rmin=fld(j)
141 multival:
if (rmin.ne.rmax)
then
143 allocate(ifld(ndpts))
144 allocate(gref(ndpts))
145 allocate(gwidth(ndpts))
146 allocate(glen(ndpts))
150 if (idrstmpl(2).eq.0)
then
151 imin=nint(rmin*dscale)
155 ifld(j)=max(0,nint(fld(j)*dscale)-imin)
161 ifld(j)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
167 alg3:
if (idrsnum.eq.3)
then
168 if (idrstmpl(17).ne.1.and.idrstmpl(17).ne.2) idrstmpl(17)=2
169 if (idrstmpl(17).eq.1)
then
172 print *,
'G2: negative ival1',ival1
176 ifld(j)=ifld(j)-ifld(j-1)
179 elseif (idrstmpl(17).eq.2)
then
183 print *,
'G2: negative ival1',ival1
187 print *,
'G2: negative ival2',ival2
191 ifld(j)=ifld(j)-(2*ifld(j-1))+ifld(j-2)
200 minsd=minval(ifld(isd:ndpts))
202 ifld(j)=ifld(j)-minsd
208 nbitsd=
i1log2(abs(minsd))+1
214 if (idrstmpl(17).eq.2.and.ival2.gt.ival1) maxorig=ival2
215 nbitorig=
i1log2(maxorig)+1
216 if (nbitorig.gt.nbitsd) nbitsd=nbitorig
218 if (mod(nbitsd,8).ne.0) nbitsd=nbitsd+(8-mod(nbitsd,8))
223 if (nbitsd.ne.0)
then
231 call g2_sbytec(cpack,iabs(ival1),iofst,nbitsd-1)
234 if (idrstmpl(17).eq.2)
then
242 call g2_sbytec(cpack,iabs(ival2),iofst,nbitsd-1)
253 call g2_sbytec(cpack,iabs(minsd),iofst,nbitsd-1)
262 simplealg:
if ( simple_alg )
then
265 print *,
'G2: use simple algorithm'
278 maxgrps=((ndpts+minpk-1)/minpk)
279 allocate(jmin(maxgrps))
280 allocate(jmax(maxgrps))
281 allocate(lbit(maxgrps))
283 call pack_gp(ifld,ndpts,missopt,minpk,inc,miss1,miss2, &
284 jmin,jmax,lbit,glen,maxgrps,ngroups,ibit,jbit, &
285 kbit,novref,lbitref,ier)
288 1099
format(
'G2: fall back to simple algorithm (glahn ier=',i0,
')')
297 elseif(ngroups<1)
then
299 print *,
'Glahn algorithm failed; use simple packing'
310 glen(ng)=glen(ng)+novref
328 if (ifld(j).lt.gref(ng)) gref(ng)=ifld(j)
329 if (ifld(j).gt.imax) imax=ifld(j)
333 if ( gref(ng).ne.imax )
then
334 gwidth(ng)=
i1log2(imax-gref(ng))
341 ifld(j)=ifld(j)-gref(ng)
353 igmax=maxval(gref(1:ngroups))
356 call g2_sbytesc(cpack,gref,iofst,nbitsgref,0,ngroups)
357 itemp=nbitsgref*ngroups
359 if (mod(itemp,8).ne.0)
then
373 iwmax=maxval(gwidth(1:ngroups))
374 ngwidthref=minval(gwidth(1:ngroups))
375 if (iwmax.ne.ngwidthref)
then
376 nbitsgwidth=
i1log2(iwmax-ngwidthref)
378 gwidth(i)=gwidth(i)-ngwidthref
380 write(0,*)
'i,gw,ngw=',i,gwidth(i),ngwidthref
384 call g2_sbytesc(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)
385 itemp=nbitsgwidth*ngroups
388 if (mod(itemp,8).ne.0)
then
403 ilmax=maxval(glen(1:ngroups-1))
404 nglenref=minval(glen(1:ngroups-1))
405 nglenlast=glen(ngroups)
406 if (ilmax.ne.nglenref)
then
407 nbitsglen=
i1log2(ilmax-nglenref)
409 glen(i)=glen(i)-nglenref
411 write(0,*)
'i,glen(i) = ',i,glen(i)
415 call g2_sbytesc(cpack,glen,iofst,nbitsglen,0,ngroups)
416 itemp=nbitsglen*ngroups
419 if (mod(itemp,8).ne.0)
then
435 glength=glen(ng)+nglenref
436 if (ng.eq.ngroups ) glength=nglenlast
437 grpwidth=gwidth(ng)+ngwidthref
439 if ( grpwidth.ne.0 )
then
440 call g2_sbytesc(cpack,ifld(n),iofst,grpwidth,0,glength)
441 iofst=iofst+(grpwidth*glength)
450 if (mod(iofst,8).ne.0)
then
457 if (
allocated(ifld) )
deallocate(ifld)
458 if (
allocated(gref) )
deallocate(gref)
459 if (
allocated(gwidth) )
deallocate(gwidth)
460 if (
allocated(glen) )
deallocate(glen)
476 rmin4 = real(rmin, 4)
479 iref=transfer(ref,iref)
481 idrstmpl(4)=nbitsgref
488 idrstmpl(11)=ngwidthref
489 idrstmpl(12)=nbitsgwidth
490 idrstmpl(13)=nglenref
492 idrstmpl(15)=nglenlast
493 idrstmpl(16)=nbitsglen
494 if (idrsnum.eq.3)
then
495 idrstmpl(18)=nbitsd/8
526 subroutine comunpack(cpack,len,lensec,idrsnum,idrstmpl,ndpts, &
529 character(len=1),
intent(in) :: cpack(len)
530 integer,
intent(in) :: ndpts,len
531 integer,
intent(in) :: idrstmpl(*)
532 real,
intent(out) :: fld(ndpts)
534 integer,
allocatable :: ifld(:),ifldmiss(:)
536 integer,
allocatable :: gref(:),gwidth(:),glen(:)
537 real :: ref,bscale,dscale,rmiss1,rmiss2
539 integer :: totBit, totLen
545 bscale = 2.0**real(idrstmpl(2))
546 dscale = 10.0**real(-idrstmpl(3))
547 nbitsgref = idrstmpl(4)
549 ngroups = idrstmpl(10)
550 nbitsgwidth = idrstmpl(12)
551 nbitsglen = idrstmpl(16)
552 if (idrsnum.eq.3)
then
553 nbitsd=idrstmpl(18)*8
558 if (ngroups.eq.0)
then
566 allocate(ifld(ndpts),stat=is)
568 allocate(gref(ngroups),stat=is)
570 allocate(gwidth(ngroups),stat=is)
575 if ( idrstmpl(7).eq.1 )
then
577 call rdieee(idrstmpl(8),rmiss1,1)
579 rmiss1=real(idrstmpl(8))
581 elseif ( idrstmpl(7).eq.2 )
then
583 call rdieee(idrstmpl(8),rmiss1,1)
584 call rdieee(idrstmpl(9),rmiss2,1)
586 rmiss1=real(idrstmpl(8))
587 rmiss2=real(idrstmpl(9))
594 if (idrsnum.eq.3)
then
595 if (nbitsd.ne.0)
then
598 if (idrstmpl(17).eq.2)
then
604 call g2_gbytec(cpack,minsd,iofst,nbitsd-1)
606 if (isign.eq.1) minsd=-minsd
618 if (nbitsgref.ne.0)
then
619 call g2_gbytesc(cpack,gref,iofst,nbitsgref,0,ngroups)
620 itemp=nbitsgref*ngroups
622 if (mod(itemp,8).ne.0) iofst=iofst+(8-mod(itemp,8))
631 if (nbitsgwidth.ne.0)
then
632 call g2_gbytesc(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)
633 itemp=nbitsgwidth*ngroups
635 if (mod(itemp,8).ne.0) iofst=iofst+(8-mod(itemp,8))
640 gwidth(j)=gwidth(j)+idrstmpl(11)
646 allocate(glen(ngroups),stat=is)
649 if (nbitsglen.ne.0)
then
650 call g2_gbytesc(cpack,glen,iofst,nbitsglen,0,ngroups)
651 itemp=nbitsglen*ngroups
653 if (mod(itemp,8).ne.0) iofst=iofst+(8-mod(itemp,8))
658 glen(j)=(glen(j)*idrstmpl(14))+idrstmpl(13)
660 glen(ngroups)=idrstmpl(15)
670 totbit = totbit + (gwidth(j)*glen(j));
671 totlen = totlen + glen(j);
673 if (totlen .NE. ndpts)
then
677 if ( (totbit/8) .GT. lensec)
then
684 if ( idrstmpl(7).eq.0 )
then
688 if (gwidth(j).ne.0)
then
689 call g2_gbytesc(cpack,ifld(n),iofst,gwidth(j),0,glen(j))
691 ifld(n)=ifld(n)+gref(j)
695 ifld(n:n+glen(j)-1)=gref(j)
698 iofst=iofst+(gwidth(j)*glen(j))
700 elseif ( idrstmpl(7).eq.1.OR.idrstmpl(7).eq.2 )
then
702 allocate(ifldmiss(ndpts))
708 if (gwidth(j).ne.0)
then
709 msng1=(2**gwidth(j))-1
711 call g2_gbytesc(cpack,ifld(n),iofst,gwidth(j),0,glen(j))
712 iofst=iofst+(gwidth(j)*glen(j))
714 if (ifld(n).eq.msng1)
then
716 elseif (idrstmpl(7).eq.2.AND.ifld(n).eq.msng2)
then
720 ifld(non)=ifld(n)+gref(j)
726 msng1=(2**nbitsgref)-1
728 if (gref(j).eq.msng1)
then
729 ifldmiss(n:n+glen(j)-1)=1
731 elseif (idrstmpl(7).eq.2.AND.gref(j).eq.msng2)
then
732 ifldmiss(n:n+glen(j)-1)=2
735 ifldmiss(n:n+glen(j)-1)=0
736 ifld(non:non+glen(j)-1)=gref(j)
745 if (
allocated(gref) )
deallocate(gref)
746 if (
allocated(gwidth) )
deallocate(gwidth)
747 if (
allocated(glen) )
deallocate(glen)
752 if (idrsnum.eq.3)
then
753 if (idrstmpl(17).eq.1)
then
755 if ( idrstmpl(7).eq.0 )
then
761 ifld(n)=ifld(n)+minsd
762 ifld(n)=ifld(n)+ifld(n-1)
764 elseif (idrstmpl(17).eq.2)
then
767 if ( idrstmpl(7).eq.0 )
then
773 ifld(n)=ifld(n)+minsd
774 ifld(n)=ifld(n)+(2*ifld(n-1))-ifld(n-2)
783 if ( idrstmpl(7).eq.0 )
then
785 fld(n)=((real(ifld(n))*bscale)+ref)*dscale
788 elseif ( idrstmpl(7).eq.1.OR.idrstmpl(7).eq.2 )
then
792 if ( ifldmiss(n).eq.0 )
then
793 fld(n)=((real(ifld(non))*bscale)+ref)*dscale
796 elseif ( ifldmiss(n).eq.1 )
then
798 elseif ( ifldmiss(n).eq.2 )
then
802 if (
allocated(ifldmiss) )
deallocate(ifldmiss)
805 if (
allocated(ifld) )
deallocate(ifld)
854 subroutine misspack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
857 integer,
intent(in) :: ndpts,idrsnum
858 real,
intent(in) :: fld(ndpts)
859 character(len=1),
intent(out) :: cpack(*)
860 integer,
intent(inout) :: idrstmpl(*)
861 integer,
intent(out) :: lcpack
863 real(4) :: ref, rmin4
865 integer,
allocatable :: ifld(:),ifldmiss(:),jfld(:)
866 integer,
allocatable :: jmin(:),jmax(:),lbit(:)
867 integer,
parameter :: zero=0
868 integer,
allocatable :: gref(:),gwidth(:),glen(:)
869 integer :: glength,grpwidth
870 logical :: simple_alg
875 bscale=2.0**real(-idrstmpl(2))
876 dscale=10.0**real(idrstmpl(3))
878 if ( missopt.ne.1 .AND. missopt.ne.2 )
then
879 print *,
'misspack: Unrecognized option.'
883 call rdieee(idrstmpl(8),rmissp,1)
884 if (missopt.eq.2)
call rdieee(idrstmpl(9),rmisss,1)
889 allocate(ifldmiss(ndpts))
891 if ( missopt .eq. 1 )
then
893 if (fld(j).eq.rmissp)
then
898 if (fld(j).lt.rmin) rmin=fld(j)
905 if(.not.have_rmin) rmin=rmissp
907 if ( missopt .eq. 2 )
then
909 if (fld(j).eq.rmissp)
then
911 elseif (fld(j).eq.rmisss)
then
916 if (fld(j).lt.rmin) rmin=fld(j)
922 if(.not.have_rmin) rmin=rmissp
933 allocate(ifld(ndpts))
934 allocate(jfld(ndpts))
935 allocate(gref(ndpts))
936 allocate(gwidth(ndpts))
937 allocate(glen(ndpts))
942 if (idrstmpl(2).eq.0)
then
943 imin=nint(rmin*dscale)
947 if (ifldmiss(j).eq.0)
then
949 jfld(nonmiss)=max(0,nint(fld(j)*dscale)-imin)
955 if (ifldmiss(j).eq.0)
then
957 jfld(nonmiss)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
964 if (idrsnum.eq.3)
then
965 if (idrstmpl(17).ne.1.and.idrstmpl(17).ne.2) idrstmpl(17)=2
966 if (idrstmpl(17).eq.1)
then
973 jfld(j)=jfld(j)-jfld(j-1)
975 if(nonmiss>0) jfld(1)=0
976 elseif (idrstmpl(17).eq.2)
then
980 elseif(nonmiss<1)
then
988 jfld(j)=jfld(j)-(2*jfld(j-1))+jfld(j-2)
990 if(nonmiss>=1) jfld(1)=0
991 if(nonmiss>=2) jfld(2)=0
996 minsd=minval(jfld(isd:nonmiss))
998 jfld(j)=jfld(j)-minsd
1004 nbitsd=ceiling(temp)+1
1009 if (idrstmpl(17).eq.2.and.ival2.gt.ival1) maxorig=ival2
1011 nbitorig=ceiling(temp)+1
1012 if (nbitorig.gt.nbitsd) nbitsd=nbitorig
1014 if (mod(nbitsd,8).ne.0) nbitsd=nbitsd+(8-mod(nbitsd,8))
1018 if (nbitsd.ne.0)
then
1020 if (ival1.ge.0)
then
1021 call g2_sbytec(cpack,ival1,iofst,nbitsd)
1026 call g2_sbytec(cpack,iabs(ival1),iofst,nbitsd-1)
1027 iofst=iofst+nbitsd-1
1029 if (idrstmpl(17).eq.2)
then
1031 if (ival2.ge.0)
then
1032 call g2_sbytec(cpack,ival2,iofst,nbitsd)
1037 call g2_sbytec(cpack,iabs(ival2),iofst,nbitsd-1)
1038 iofst=iofst+nbitsd-1
1042 if (minsd.ge.0)
then
1043 call g2_sbytec(cpack,minsd,iofst,nbitsd)
1048 call g2_sbytec(cpack,iabs(minsd),iofst,nbitsd-1)
1049 iofst=iofst+nbitsd-1
1056 miss1=minval(jfld(1:nonmiss))-1
1060 if ( ifldmiss(j).eq.0 )
then
1063 elseif ( ifldmiss(j).eq.1 )
then
1065 elseif ( ifldmiss(j).eq.2 )
then
1069 if(ndpts<2) simple_alg=.true.
1072 if ( simple_alg )
then
1078 if (itemp.ne.0)
then
1087 maxgrps=(ndpts/minpk)+1
1088 allocate(jmin(maxgrps))
1089 allocate(jmax(maxgrps))
1090 allocate(lbit(maxgrps))
1091 call pack_gp(ifld,ndpts,missopt,minpk,inc,miss1,miss2, &
1092 jmin,jmax,lbit,glen,maxgrps,ngroups,ibit,jbit, &
1093 kbit,novref,lbitref,ier)
1096 glen(ng)=glen(ng)+novref
1108 num0=count(ifldmiss(n:n+glen(ng)-1) .EQ. 0)
1109 num1=count(ifldmiss(n:n+glen(ng)-1) .EQ. 1)
1110 num2=count(ifldmiss(n:n+glen(ng)-1) .EQ. 2)
1111 if ( num0.eq.0 )
then
1112 if ( num1.eq.0 )
then
1115 elseif ( num2.eq.0 )
then
1128 if ( ifldmiss(j).eq.0 )
then
1129 if (ifld(j).lt.gref(ng)) gref(ng)=ifld(j)
1130 if (ifld(j).gt.imax) imax=ifld(j)
1134 if (missopt.eq.1) imax=imax+1
1135 if (missopt.eq.2) imax=imax+2
1137 if ( gref(ng).ne.imax )
then
1138 temp=
i1log2(imax-gref(ng))
1139 gwidth(ng)=ceiling(temp)
1148 if (ifldmiss(j).eq.0)
then
1149 ifld(j)=ifld(j)-gref(ng)
1150 elseif (ifldmiss(j).eq.1)
then
1152 elseif (ifldmiss(j).eq.2)
then
1165 igmax=maxval(gref(1:ngroups))
1166 if (missopt.eq.1) igmax=igmax+1
1167 if (missopt.eq.2) igmax=igmax+2
1168 if (igmax.ne.0)
then
1170 nbitsgref=ceiling(temp)
1174 if (gref(j).eq.-1) gref(j)=mtemp-1
1175 if (gref(j).eq.-2) gref(j)=mtemp-2
1177 call g2_sbytesc(cpack,gref,iofst,nbitsgref,0,ngroups)
1178 itemp=nbitsgref*ngroups
1181 if (mod(itemp,8).ne.0)
then
1194 iwmax=maxval(gwidth(1:ngroups))
1195 ngwidthref=minval(gwidth(1:ngroups))
1196 if (iwmax.ne.ngwidthref)
then
1197 temp=
i1log2(iwmax-ngwidthref)
1198 nbitsgwidth=ceiling(temp)
1200 gwidth(i)=gwidth(i)-ngwidthref
1202 call g2_sbytesc(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)
1203 itemp=nbitsgwidth*ngroups
1206 if (mod(itemp,8).ne.0)
then
1220 ilmax=maxval(glen(1:ngroups-1))
1221 nglenref=minval(glen(1:ngroups-1))
1223 nglenlast=glen(ngroups)
1227 if (ilmax.ne.nglenref)
then
1228 temp=
i1log2(ilmax-nglenref)
1229 nbitsglen=ceiling(temp)
1231 glen(i)=glen(i)-nglenref
1233 call g2_sbytesc(cpack,glen,iofst,nbitsglen,0,ngroups)
1234 itemp=nbitsglen*ngroups
1237 if (mod(itemp,8).ne.0)
then
1252 glength=glen(ng)+nglenref
1253 if (ng.eq.ngroups ) glength=nglenlast
1254 grpwidth=gwidth(ng)+ngwidthref
1256 if ( grpwidth.ne.0 )
then
1257 call g2_sbytesc(cpack,ifld(n),iofst,grpwidth,0,glength)
1258 iofst=iofst+(grpwidth*glength)
1267 if (mod(iofst,8).ne.0)
then
1274 if (
allocated(ifld) )
deallocate(ifld)
1275 if (
allocated(jfld) )
deallocate(jfld)
1276 if (
allocated(ifldmiss) )
deallocate(ifldmiss)
1277 if (
allocated(gref) )
deallocate(gref)
1278 if (
allocated(gwidth) )
deallocate(gwidth)
1279 if (
allocated(glen) )
deallocate(glen)
1282 rmin4 = real(rmin, 4)
1284 iref=transfer(ref,iref)
1286 idrstmpl(4)=nbitsgref
1289 idrstmpl(10)=ngroups
1290 idrstmpl(11)=ngwidthref
1291 idrstmpl(12)=nbitsgwidth
1292 idrstmpl(13)=nglenref
1294 idrstmpl(15)=nglenlast
1295 idrstmpl(16)=nbitsglen
1296 if (idrsnum.eq.3)
then
1297 idrstmpl(18)=nbitsd/8
subroutine misspack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack up a data field using a GRIB2 algorithm with missing value management.
subroutine comunpack(cpack, len, lensec, idrsnum, idrstmpl, ndpts, fld, ier)
Unpack a data field that was packed using a complex packing algorithm as defined in the GRIB2 documen...
subroutine cmplxpack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack up a data field using a complex packing algorithm.
subroutine compack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack a data field with complex packing with or without spatial differences, defined in Data Represent...
subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n)
Extract arbitrary size big-endian integer values (up to 32 bits each) from a packed bit string.
subroutine rdieee(rieee, a, num)
Copy array of 32-bit IEEE floating point values to local floating point representation.
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_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.
Define math functions used by compack(), simpack(), and misspack().
subroutine pack_gp(IC, NXY, IS523, MINPK, INC, MISSP, MISSS, JMIN, JMAX, LBIT, NOV, NDG, LX, IBIT, JBIT, KBIT, NOVREF, LBITREF, IER)
This subroutine determines groups of variable size, but at least of size minpk, the associated max(JM...