updated top-level README and version_decl for V4.4.2 (#1795)
[WRF.git] / external / io_grib2 / g2lib / simpack.F
blob4195fd1cac0ed5839b3ff8c1b2917973ea6f6045
1       subroutine simpack(fld,ndpts,idrstmpl,cpack,lcpack)
2 !$$$  SUBPROGRAM DOCUMENTATION BLOCK
3 !                .      .    .                                       .
4 ! SUBPROGRAM:    simpack
5 !   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2000-06-21
7 ! ABSTRACT: This subroutine packs up a data field using a simple
8 !   packing algorithm as defined in the GRIB2 documention.  It
9 !   also fills in GRIB2 Data Representation Template 5.0 with the
10 !   appropriate values.
12 ! PROGRAM HISTORY LOG:
13 ! 2000-06-21  Gilbert
15 ! USAGE:    CALL simpack(fld,ndpts,idrstmpl,cpack,lcpack)
16 !   INPUT ARGUMENT LIST:
17 !     fld()    - Contains the data values to pack
18 !     ndpts    - The number of data values in array fld()
19 !     idrstmpl - Contains the array of values for Data Representation
20 !                Template 5.0
21 !                (1) = Reference value - ignored on input
22 !                (2) = Binary Scale Factor
23 !                (3) = Decimal Scale Factor
24 !                (4) = Number of bits used to pack data, if value is
25 !                      > 0 and  <= 31.
26 !                      If this input value is 0 or outside above range
27 !                      then the num of bits is calculated based on given 
28 !                      data and scale factors.
29 !                (5) = Original field type - currently ignored on input
30 !                      Data values assumed to be reals.
32 !   OUTPUT ARGUMENT LIST: 
33 !     idrstmpl - Contains the array of values for Data Representation
34 !                Template 5.0
35 !                (1) = Reference value - set by simpack routine.
36 !                (2) = Binary Scale Factor - unchanged from input
37 !                (3) = Decimal Scale Factor - unchanged from input
38 !                (4) = Number of bits used to pack data, unchanged from 
39 !                      input if value is between 0 and 31.
40 !                      If this input value is 0 or outside above range
41 !                      then the num of bits is calculated based on given 
42 !                      data and scale factors.
43 !                (5) = Original field type - currently set = 0 on output.
44 !                      Data values assumed to be reals.
45 !     cpack    - The packed data field (character*1 array)
46 !     lcpack   - length of packed field cpack().
48 ! REMARKS: None
50 ! ATTRIBUTES:
51 !   LANGUAGE: XL Fortran 90
52 !   MACHINE:  IBM SP
54 !$$$
56       integer,intent(in) :: ndpts
57       real,intent(in) :: fld(ndpts)
58       character(len=1),intent(out) :: cpack(*)
59       integer,intent(inout) :: idrstmpl(*)
60       integer,intent(out) :: lcpack
62       real(4) :: ref
63       integer(4) :: iref
64       integer :: ifld(ndpts)
65       integer,parameter :: zero=0
66       
67       bscale=2.0**real(-idrstmpl(2))
68       dscale=10.0**real(idrstmpl(3))
69       if (idrstmpl(4).le.0.OR.idrstmpl(4).gt.31) then
70          nbits=0
71       else
72          nbits=idrstmpl(4)
73       endif
75 !  Find max and min values in the data
77       rmax=fld(1)
78       rmin=fld(1)
79       do j=2,ndpts
80         if (fld(j).gt.rmax) rmax=fld(j)
81         if (fld(j).lt.rmin) rmin=fld(j)
82       enddo
84 !  If max and min values are not equal, pack up field.
85 !  If they are equal, we have a constant field, and the reference
86 !  value (rmin) is the value for each point in the field and
87 !  set nbits to 0.
89       if (rmin.ne.rmax) then
90         !
91         !  Determine which algorithm to use based on user-supplied 
92         !  binary scale factor and number of bits.
93         !
94         if (nbits.eq.0.AND.idrstmpl(2).eq.0) then
95            !
96            !  No binary scaling and calculate minumum number of 
97            !  bits in which the data will fit.
98            !
99            imin=nint(rmin*dscale)
100            imax=nint(rmax*dscale)
101            maxdif=imax-imin
102            temp=alog(real(maxdif+1))/alog(2.0)
103            nbits=ceiling(temp)
104            rmin=real(imin)
105            !   scale data
106            do j=1,ndpts
107              ifld(j)=nint(fld(j)*dscale)-imin
108            enddo
109         elseif (nbits.ne.0.AND.idrstmpl(2).eq.0) then
110            !
111            !  Use minimum number of bits specified by user and
112            !  adjust binary scaling factor to accomodate data.
113            !
114            rmin=rmin*dscale
115            rmax=rmax*dscale
116            maxnum=(2**nbits)-1
117            temp=alog(real(maxnum)/(rmax-rmin))/alog(2.0)
118            idrstmpl(2)=ceiling(-1.0*temp)
119            bscale=2.0**real(-idrstmpl(2))
120            !   scale data
121            do j=1,ndpts
122              ifld(j)=nint(((fld(j)*dscale)-rmin)*bscale)
123            enddo
124         elseif (nbits.eq.0.AND.idrstmpl(2).ne.0) then
125            !
126            !  Use binary scaling factor and calculate minumum number of 
127            !  bits in which the data will fit.
128            !
129            rmin=rmin*dscale
130            rmax=rmax*dscale
131            maxdif=nint((rmax-rmin)*bscale)
132            temp=alog(real(maxdif+1))/alog(2.0)
133            nbits=ceiling(temp)
134            !   scale data
135            do j=1,ndpts
136              ifld(j)=nint(((fld(j)*dscale)-rmin)*bscale)
137            enddo
138         elseif (nbits.ne.0.AND.idrstmpl(2).ne.0) then
139            !
140            !  Use binary scaling factor and use minumum number of 
141            !  bits specified by user.   Dangerous - may loose
142            !  information if binary scale factor and nbits not set
143            !  properly by user.
144            !
145            rmin=rmin*dscale
146            !   scale data
147            do j=1,ndpts
148              ifld(j)=nint(((fld(j)*dscale)-rmin)*bscale)
149            enddo
150         endif
151         !
152         !  Pack data, Pad last octet with Zeros, if necessary,
153         !  and calculate the length of the packed data in bytes
154         !
155         call g2lib_sbytes(cpack,ifld,0,nbits,0,ndpts)
156         nbittot=nbits*ndpts
157         left=8-mod(nbittot,8)
158         if (left.ne.8) then
159           call g2lib_sbyte(cpack,zero,nbittot,left)    ! Pad with zeros to fill Octet
160           nbittot=nbittot+left
161         endif
162         lcpack=nbittot/8
164       else
165         nbits=0
166         lcpack=0
167       endif
170 !  Fill in ref value and number of bits in Template 5.0
172       call mkieee(rmin,ref,1)   ! ensure reference value is IEEE format
173 !      call g2lib_gbyte(ref,idrstmpl(1),0,32)
174       iref=transfer(ref,iref)
175       idrstmpl(1)=iref
176       idrstmpl(4)=nbits
177       idrstmpl(5)=0         ! original data were reals
179       return
180       end