NCEPLIBS-g2  3.5.0
g2sim.F90
Go to the documentation of this file.
1 
4 
26 subroutine simpack(fld,ndpts,idrstmpl,cpack,lcpack)
27  use intmath
28  implicit none
29 
30  integer,intent(in) :: ndpts
31  real,intent(in) :: fld(ndpts)
32  character(len=1),intent(out) :: cpack(*)
33  integer,intent(inout) :: idrstmpl(*)
34  integer,intent(out) :: lcpack
35 
36  real(4) :: ref,rmin4
37 
38  integer(4) :: iref
39  integer :: ifld(ndpts)
40  integer,parameter :: zero=0
41  integer :: nbittot, nbits, maxnum, maxdif, left
42  integer :: imax, imin, j
43  real :: rmax, rmin, temp, dscale, bscale
44 
45  bscale=2.0**real(-idrstmpl(2))
46  dscale=10.0**real(idrstmpl(3))
47  if (idrstmpl(4).le.0.OR.idrstmpl(4).gt.31) then
48  nbits=0
49  else
50  nbits=idrstmpl(4)
51  endif
52 
53  ! Find max and min values in the data
54  if(ndpts<1) then
55  rmin=0
56  rmax=0
57  else
58  rmax=fld(1)
59  rmin=fld(1)
60  do j=2,ndpts
61  if (fld(j).gt.rmax) rmax=fld(j)
62  if (fld(j).lt.rmin) rmin=fld(j)
63  enddo
64  endif
65 
66  ! If max and min values are not equal, pack up field.
67  ! If they are equal, we have a constant field, and the reference
68  ! value (rmin) is the value for each point in the field and
69  ! set nbits to 0.
70  if (rmin.ne.rmax) then
71 
72  ! Determine which algorithm to use based on user-supplied
73  ! binary scale factor and number of bits.
74  if (nbits.eq.0.AND.idrstmpl(2).eq.0) then
75 
76  ! No binary scaling and calculate minumum number of
77  ! bits in which the data will fit.
78  imin=nint(rmin*dscale)
79  imax=nint(rmax*dscale)
80  maxdif=imax-imin
81  temp=i1log2(maxdif+1)
82  nbits=ceiling(temp)
83  rmin=real(imin)
84  ! scale data
85  do j=1,ndpts
86  ifld(j)=nint(fld(j)*dscale)-imin
87  enddo
88  elseif (nbits.ne.0.AND.idrstmpl(2).eq.0) then
89 
90  ! Use minimum number of bits specified by user and
91  ! adjust binary scaling factor to accomodate data.
92  rmin=rmin*dscale
93  rmax=rmax*dscale
94  maxnum=(2**nbits)-1
95  temp=ilog2(nint(real(maxnum)/(rmax-rmin)))
96  idrstmpl(2)=ceiling(-1.0*temp)
97  bscale=2.0**real(-idrstmpl(2))
98  ! scale data
99  do j=1,ndpts
100  ifld(j)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
101  enddo
102  elseif (nbits.eq.0.AND.idrstmpl(2).ne.0) then
103 
104  ! Use binary scaling factor and calculate minumum number of
105  ! bits in which the data will fit.
106  rmin=rmin*dscale
107  rmax=rmax*dscale
108  maxdif=nint((rmax-rmin)*bscale)
109  temp=i1log2(maxdif)
110  nbits=ceiling(temp)
111  ! scale data
112  do j=1,ndpts
113  ifld(j)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
114  enddo
115  elseif (nbits.ne.0.AND.idrstmpl(2).ne.0) then
116 
117  ! Use binary scaling factor and use minumum number of
118  ! bits specified by user. Dangerous - may loose
119  ! information if binary scale factor and nbits not set
120  ! properly by user.
121  rmin=rmin*dscale
122  ! scale data
123  do j=1,ndpts
124  ifld(j)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
125  enddo
126  endif
127 
128  ! Pack data, Pad last octet with Zeros, if necessary,
129  ! and calculate the length of the packed data in bytes
130  call g2_sbytesc(cpack,ifld,0,nbits,0,ndpts)
131  nbittot=nbits*ndpts
132  left=8-mod(nbittot,8)
133  if (left.ne.8) then
134  call g2_sbytec(cpack,zero,nbittot,left) ! Pad with zeros to fill Octet
135  nbittot=nbittot+left
136  endif
137  lcpack=nbittot/8
138 
139  else
140  !print *,'nbits 0'
141  nbits=0
142  lcpack=0
143  endif
144 
145 
146  ! Fill in ref value and number of bits in Template 5.0
147  rmin4 = real(rmin, 4)
148  call mkieee(rmin4,ref,1) ! ensure reference value is IEEE format
149  iref=transfer(ref,iref)
150  idrstmpl(1)=iref
151  idrstmpl(4)=nbits
152  idrstmpl(5)=0 ! original data were reals
153 
154 end subroutine simpack
155 
168 subroutine simunpack(cpack, len, idrstmpl, ndpts, fld)
169  implicit none
170 
171  character(len=1), intent(in) :: cpack(len)
172  integer, intent(in) :: ndpts, len
173  integer, intent(in) :: idrstmpl(*)
174  real, intent(out) :: fld(ndpts)
175 
176  integer :: ifld(ndpts)
177  integer(4) :: ieee
178  real :: ref, bscale, dscale
179  integer :: itype, j, nbits
180 
181  ieee = idrstmpl(1)
182  call rdieee(ieee, ref, 1)
183  bscale = 2.0**real(idrstmpl(2))
184  dscale = 10.0**real(-idrstmpl(3))
185  nbits = idrstmpl(4)
186  itype = idrstmpl(5)
187 
188  ! If nbits equals 0, we have a constant field where the reference value
189  ! is the data value at each gridpoint.
190  if (nbits .ne. 0) then
191  call g2_gbytesc(cpack, ifld, 0, nbits, 0, ndpts)
192  do j=1, ndpts
193  fld(j) = ((real(ifld(j)) * bscale) + ref) * dscale
194  enddo
195  else
196  !print *, 'unpack ref ', ref
197  !print *, 'unpack ndpts ', ndpts
198  do j=1, ndpts
199  fld(j) = ref
200  enddo
201  endif
202 end subroutine simunpack
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.
Definition: g2bytes.F90:120
subroutine rdieee(rieee, a, num)
Copy array of 32-bit IEEE floating point values to local floating point representation.
Definition: g2bytes.F90:637
subroutine mkieee(a, rieee, num)
Copy an array of real to an array of 32-bit IEEE floating points.
Definition: g2bytes.F90:685
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,...
Definition: g2bytes.F90:306
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.
Definition: g2bytes.F90:402
subroutine simunpack(cpack, len, idrstmpl, ndpts, fld)
Unpack a data field that was packed using a simple packing, [Data Representation Template 5....
Definition: g2sim.F90:169
subroutine simpack(fld, ndpts, idrstmpl, cpack, lcpack)
Pack a data field using a simple packing algorithm.
Definition: g2sim.F90:27
Define math functions used by compack(), simpack(), and misspack().
Definition: intmath.F90:22