NCEPLIBS-g2 4.0.0
Loading...
Searching...
No Matches
compack.F90
Go to the documentation of this file.
1
9
42subroutine cmplxpack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
43
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
49
50 if ( idrstmpl(7) .eq. 0 ) then ! No internal missing values
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)
54 else
55 print *,'cmplxpack: Do not recognize Missing value option.'
56 lcpack=-1
57 endif
58
59 return
60end subroutine cmplxpack
61
88subroutine compack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
89
90 use intmath
91 implicit none
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
97
98 real :: bscale,dscale
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
105 integer :: nbitsglen
106 real(4) :: ref,rmin4
107 real(8) :: rmin,rmax
108
109 integer(4) :: iref
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
116
117 simple_alg = .false.
118
119 bscale=2.0**real(-idrstmpl(2))
120 dscale=10.0**real(idrstmpl(3))
121 !
122 ! Find max and min values in the data
123 !
124 if(ndpts>0) then
125 rmax=fld(1)
126 rmin=fld(1)
127 else
128 rmax=1.0
129 rmin=1.0
130 endif
131 do j=2,ndpts
132 if (fld(j).gt.rmax) rmax=fld(j)
133 if (fld(j).lt.rmin) rmin=fld(j)
134 enddo
135 !
136 ! If max and min values are not equal, pack up field.
137 ! If they are equal, we have a constant field, and the reference
138 ! value (rmin) is the value for each point in the field and
139 ! set nbits to 0.
140 !
141 multival: if (rmin.ne.rmax) then
142 iofst=0
143 allocate(ifld(ndpts))
144 allocate(gref(ndpts))
145 allocate(gwidth(ndpts))
146 allocate(glen(ndpts))
147 !
148 ! Scale original data
149 !
150 if (idrstmpl(2).eq.0) then ! No binary scaling
151 imin=nint(rmin*dscale)
152 !imax=nint(rmax*dscale)
153 rmin=real(imin)
154 do j=1,ndpts
155 ifld(j)=max(0,nint(fld(j)*dscale)-imin)
156 enddo
157 else ! Use binary scaling factor
158 rmin=rmin*dscale
159 !rmax=rmax*dscale
160 do j=1,ndpts
161 ifld(j)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
162 enddo
163 endif
164 !
165 ! Calculate Spatial differences, if using DRS Template 5.3
166 !
167 alg3: if (idrsnum.eq.3) then ! spatial differences
168 if (idrstmpl(17).ne.1.and.idrstmpl(17).ne.2) idrstmpl(17)=2
169 if (idrstmpl(17).eq.1) then ! first order
170 ival1=ifld(1)
171 if(ival1<0) then
172 print *,'G2: negative ival1',ival1
173 stop 101
174 endif
175 do j=ndpts,2,-1
176 ifld(j)=ifld(j)-ifld(j-1)
177 enddo
178 ifld(1)=0
179 elseif (idrstmpl(17).eq.2) then ! second order
180 ival1=ifld(1)
181 ival2=ifld(2)
182 if(ival1<0) then
183 print *,'G2: negative ival1',ival1
184 stop 11
185 endif
186 if(ival2<0) then
187 print *,'G2: negative ival2',ival2
188 stop 12
189 endif
190 do j=ndpts,3,-1
191 ifld(j)=ifld(j)-(2*ifld(j-1))+ifld(j-2)
192 enddo
193 ifld(1)=0
194 ifld(2)=0
195 endif
196 !
197 ! subtract min value from spatial diff field
198 !
199 isd=idrstmpl(17)+1
200 minsd=minval(ifld(isd:ndpts))
201 do j=isd,ndpts
202 ifld(j)=ifld(j)-minsd
203 enddo
204 !
205 ! find num of bits need to store minsd and add 1 extra bit
206 ! to indicate sign
207 !
208 nbitsd=i1log2(abs(minsd))+1
209 !
210 ! find num of bits need to store ifld(1) ( and ifld(2)
211 ! if using 2nd order differencing )
212 !
213 maxorig=ival1
214 if (idrstmpl(17).eq.2.and.ival2.gt.ival1) maxorig=ival2
215 nbitorig=i1log2(maxorig)+1
216 if (nbitorig.gt.nbitsd) nbitsd=nbitorig
217 ! increase number of bits to even multiple of 8 ( octet )
218 if (mod(nbitsd,8).ne.0) nbitsd=nbitsd+(8-mod(nbitsd,8))
219 !
220 ! Store extra spatial differencing info into the packed
221 ! data section.
222 !
223 if (nbitsd.ne.0) then
224 ! pack first original value
225 if (ival1.ge.0) then
226 call g2_sbytec(cpack,ival1,iofst,nbitsd)
227 iofst=iofst+nbitsd
228 else
229 call g2_sbytec(cpack,1,iofst,1)
230 iofst=iofst+1
231 call g2_sbytec(cpack,iabs(ival1),iofst,nbitsd-1)
232 iofst=iofst+nbitsd-1
233 endif
234 if (idrstmpl(17).eq.2) then
235 ! pack second original value
236 if (ival2.ge.0) then
237 call g2_sbytec(cpack,ival2,iofst,nbitsd)
238 iofst=iofst+nbitsd
239 else
240 call g2_sbytec(cpack,1,iofst,1)
241 iofst=iofst+1
242 call g2_sbytec(cpack,iabs(ival2),iofst,nbitsd-1)
243 iofst=iofst+nbitsd-1
244 endif
245 endif
246 ! pack overall min of spatial differences
247 if (minsd.ge.0) then
248 call g2_sbytec(cpack,minsd,iofst,nbitsd)
249 iofst=iofst+nbitsd
250 else
251 call g2_sbytec(cpack,1,iofst,1)
252 iofst=iofst+1
253 call g2_sbytec(cpack,iabs(minsd),iofst,nbitsd-1)
254 iofst=iofst+nbitsd-1
255 endif
256 endif
257 !print *,'SDp ',ival1,ival2,minsd,nbitsd
258 endif alg3 ! end of spatial diff section
259 !
260 ! Determine Groups to be used.
261 !
262 simplealg: if ( simple_alg ) then
263 ! set group length to 10 : calculate number of groups
264 ! and length of last group
265 print *,'G2: use simple algorithm'
266 ngroups=ndpts/10
267 glen(1:ngroups)=10
268 itemp=mod(ndpts,10)
269 if (itemp.ne.0) then
270 ngroups=ngroups+1
271 glen(ngroups)=itemp
272 endif
273 else
274 ! Use Dr. Glahn's algorithm for determining grouping.
275 !
276 minpk=10
277 inc=1
278 maxgrps=((ndpts+minpk-1)/minpk)
279 allocate(jmin(maxgrps))
280 allocate(jmax(maxgrps))
281 allocate(lbit(maxgrps))
282 missopt=0
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)
286 if(ier/=0) then
287 ! Dr. Glahn's algorithm failed; use simple packing method instead.
2881099 format('G2: fall back to simple algorithm (glahn ier=',i0,')')
289 print 1099,ier
290 ngroups=ndpts/10
291 glen(1:ngroups)=10
292 itemp=mod(ndpts,10)
293 if (itemp.ne.0) then
294 ngroups=ngroups+1
295 glen(ngroups)=itemp
296 endif
297 elseif(ngroups<1) then
298 ! Dr. Glahn's algorithm failed; use simple packing method instead.
299 print *,'Glahn algorithm failed; use simple packing'
300 ngroups=ndpts/10
301 glen(1:ngroups)=10
302 itemp=mod(ndpts,10)
303 if (itemp.ne.0) then
304 ngroups=ngroups+1
305 glen(ngroups)=itemp
306 endif
307 else
308 !print *,'SAGier = ',ier,ibit,jbit,kbit,novref,lbitref
309 do ng=1,ngroups
310 glen(ng)=glen(ng)+novref
311 enddo
312 deallocate(jmin)
313 deallocate(jmax)
314 deallocate(lbit)
315 endif
316 endif simplealg
317 !
318 ! For each group, find the group's reference value
319 ! and the number of bits needed to hold the remaining values
320 !
321 n=1
322 do ng=1,ngroups
323 ! find max and min values of group
324 gref(ng)=ifld(n)
325 imax=ifld(n)
326 j=n+1
327 do lg=2,glen(ng)
328 if (ifld(j).lt.gref(ng)) gref(ng)=ifld(j)
329 if (ifld(j).gt.imax) imax=ifld(j)
330 j=j+1
331 enddo
332 ! calc num of bits needed to hold data
333 if ( gref(ng).ne.imax ) then
334 gwidth(ng)=i1log2(imax-gref(ng))
335 else
336 gwidth(ng)=0
337 endif
338 ! Subtract min from data
339 j=n
340 do lg=1,glen(ng)
341 ifld(j)=ifld(j)-gref(ng)
342 j=j+1
343 enddo
344 ! increment fld array counter
345 n=n+glen(ng)
346 enddo
347 !
348 ! Find max of the group references and calc num of bits needed
349 ! to pack each groups reference value, then
350 ! pack up group reference values
351 !
352 !write(77,*)'GREFS: ',(gref(j),j=1,ngroups)
353 igmax=maxval(gref(1:ngroups))
354 if (igmax.ne.0) then
355 nbitsgref=i1log2(igmax)
356 call g2_sbytesc(cpack,gref,iofst,nbitsgref,0,ngroups)
357 itemp=nbitsgref*ngroups
358 iofst=iofst+itemp
359 if (mod(itemp,8).ne.0) then
360 left=8-mod(itemp,8)
361 call g2_sbytec(cpack,zero,iofst,left)
362 iofst=iofst+left
363 endif
364 else
365 nbitsgref=0
366 endif
367 !
368 ! Find max/min of the group widths and calc num of bits needed
369 ! to pack each groups width value, then
370 ! pack up group width values
371 !
372 !write(77,*)'GWIDTHS: ',(gwidth(j),j=1,ngroups)
373 iwmax=maxval(gwidth(1:ngroups))
374 ngwidthref=minval(gwidth(1:ngroups))
375 if (iwmax.ne.ngwidthref) then
376 nbitsgwidth=i1log2(iwmax-ngwidthref)
377 do i=1,ngroups
378 gwidth(i)=gwidth(i)-ngwidthref
379 if(gwidth(i)<0) then
380 write(0,*) 'i,gw,ngw=',i,gwidth(i),ngwidthref
381 stop 9
382 endif
383 enddo
384 call g2_sbytesc(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)
385 itemp=nbitsgwidth*ngroups
386 iofst=iofst+itemp
387 ! Pad last octet with Zeros, if necessary,
388 if (mod(itemp,8).ne.0) then
389 left=8-mod(itemp,8)
390 call g2_sbytec(cpack,zero,iofst,left)
391 iofst=iofst+left
392 endif
393 else
394 nbitsgwidth=0
395 gwidth(1:ngroups)=0
396 endif
397 !
398 ! Find max/min of the group lengths and calc num of bits needed
399 ! to pack each groups length value, then
400 ! pack up group length values
401 !
402 !write(77,*)'GLENS: ',(glen(j),j=1,ngroups)
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)
408 do i=1,ngroups-1
409 glen(i)=glen(i)-nglenref
410 if(glen(i)<0) then
411 write(0,*) 'i,glen(i) = ',i,glen(i)
412 stop 23
413 endif
414 enddo
415 call g2_sbytesc(cpack,glen,iofst,nbitsglen,0,ngroups)
416 itemp=nbitsglen*ngroups
417 iofst=iofst+itemp
418 ! Pad last octet with Zeros, if necessary,
419 if (mod(itemp,8).ne.0) then
420 left=8-mod(itemp,8)
421 call g2_sbytec(cpack,zero,iofst,left)
422 iofst=iofst+left
423 endif
424 else
425 nbitsglen=0
426 glen(1:ngroups)=0
427 endif
428 !
429 ! For each group, pack data values
430 !
431 !write(77,*)'IFLDS: ',(ifld(j),j=1,ndpts)
432 n=1
433 ij=0
434 do ng=1,ngroups
435 glength=glen(ng)+nglenref
436 if (ng.eq.ngroups ) glength=nglenlast
437 grpwidth=gwidth(ng)+ngwidthref
438 !write(77,*)'NGP ',ng,grpwidth,glength,gref(ng)
439 if ( grpwidth.ne.0 ) then
440 call g2_sbytesc(cpack,ifld(n),iofst,grpwidth,0,glength)
441 iofst=iofst+(grpwidth*glength)
442 endif
443 do kk=1,glength
444 ij=ij+1
445 !write(77,*)'SAG ',ij,fld(ij),ifld(ij),gref(ng),bscale,rmin,dscale
446 enddo
447 n=n+glength
448 enddo
449 ! Pad last octet with Zeros, if necessary,
450 if (mod(iofst,8).ne.0) then
451 left=8-mod(iofst,8)
452 call g2_sbytec(cpack,zero,iofst,left)
453 iofst=iofst+left
454 endif
455 lcpack=iofst/8
456 !
457 if ( allocated(ifld) ) deallocate(ifld)
458 if ( allocated(gref) ) deallocate(gref)
459 if ( allocated(gwidth) ) deallocate(gwidth)
460 if ( allocated(glen) ) deallocate(glen)
461 else ! Constant field ( max = min )
462 lcpack=0
463 nbitsgref=0
464 ngroups=0
465 ngwidthref=0
466 nbitsgwidth=0
467 nglenref=0
468 nglenlast=0
469 nbitsglen=0
470 nbitsd=0
471 endif multival
472
473 !
474 ! Fill in ref value and number of bits in Template 5.2
475 !
476 rmin4 = real(rmin, 4)
477 call mkieee(rmin4,ref,1) ! ensure reference value is IEEE format
478 ! call g2_gbytec(ref,idrstmpl(1),0,32)
479 iref=transfer(ref,iref)
480 idrstmpl(1)=iref
481 idrstmpl(4)=nbitsgref
482 idrstmpl(5)=0 ! original data were reals
483 idrstmpl(6)=1 ! general group splitting
484 idrstmpl(7)=0 ! No internal missing values
485 idrstmpl(8)=0 ! Primary missing value
486 idrstmpl(9)=0 ! secondary missing value
487 idrstmpl(10)=ngroups ! Number of groups
488 idrstmpl(11)=ngwidthref ! reference for group widths
489 idrstmpl(12)=nbitsgwidth ! num bits used for group widths
490 idrstmpl(13)=nglenref ! Reference for group lengths
491 idrstmpl(14)=1 ! length increment for group lengths
492 idrstmpl(15)=nglenlast ! True length of last group
493 idrstmpl(16)=nbitsglen ! num bits used for group lengths
494 if (idrsnum.eq.3) then
495 idrstmpl(18)=nbitsd/8 ! num bits used for extra spatial
496 ! differencing values
497 endif
498
499end subroutine compack
500
526subroutine comunpack(cpack,len,lensec,idrsnum,idrstmpl,ndpts, &
527 fld,ier)
528
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)
533
534 integer,allocatable :: ifld(:),ifldmiss(:)
535 integer(4) :: ieee
536 integer,allocatable :: gref(:),gwidth(:),glen(:)
537 real :: ref,bscale,dscale,rmiss1,rmiss2
538 ! real :: fldo(6045)
539 integer :: totBit, totLen
540
541 ier=0
542 !print *,'IDRSTMPL: ',(idrstmpl(j),j=1,16)
543 ieee = idrstmpl(1)
544 call rdieee(ieee,ref,1)
545 bscale = 2.0**real(idrstmpl(2))
546 dscale = 10.0**real(-idrstmpl(3))
547 nbitsgref = idrstmpl(4)
548 itype = idrstmpl(5)
549 ngroups = idrstmpl(10)
550 nbitsgwidth = idrstmpl(12)
551 nbitsglen = idrstmpl(16)
552 if (idrsnum.eq.3) then
553 nbitsd=idrstmpl(18)*8
554 endif
555
556 ! Constant field
557
558 if (ngroups.eq.0) then
559 do j=1,ndpts
560 fld(j)=ref
561 enddo
562 return
563 endif
564
565 iofst=0
566 allocate(ifld(ndpts),stat=is)
567 !print *,'ALLOC ifld: ',is,ndpts
568 allocate(gref(ngroups),stat=is)
569 !print *,'ALLOC gref: ',is
570 allocate(gwidth(ngroups),stat=is)
571 !print *,'ALLOC gwidth: ',is
572 !
573 ! Get missing values, if supplied
574 !
575 if ( idrstmpl(7).eq.1 ) then
576 if (itype.eq.0) then
577 call rdieee(idrstmpl(8),rmiss1,1)
578 else
579 rmiss1=real(idrstmpl(8))
580 endif
581 elseif ( idrstmpl(7).eq.2 ) then
582 if (itype.eq.0) then
583 call rdieee(idrstmpl(8),rmiss1,1)
584 call rdieee(idrstmpl(9),rmiss2,1)
585 else
586 rmiss1=real(idrstmpl(8))
587 rmiss2=real(idrstmpl(9))
588 endif
589 endif
590 !print *,'RMISSs: ',rmiss1,rmiss2,ref
591 !
592 ! Extract Spatial differencing values, if using DRS Template 5.3
593 !
594 if (idrsnum.eq.3) then
595 if (nbitsd.ne.0) then
596 call g2_gbytec(cpack,ival1,iofst,nbitsd)
597 iofst=iofst+nbitsd
598 if (idrstmpl(17).eq.2) then
599 call g2_gbytec(cpack,ival2,iofst,nbitsd)
600 iofst=iofst+nbitsd
601 endif
602 call g2_gbytec(cpack,isign,iofst,1)
603 iofst=iofst+1
604 call g2_gbytec(cpack,minsd,iofst,nbitsd-1)
605 iofst=iofst+nbitsd-1
606 if (isign.eq.1) minsd=-minsd
607 else
608 ival1=0
609 ival2=0
610 minsd=0
611 endif
612 !print *,'SDu ',ival1,ival2,minsd,nbitsd
613 endif
614 !
615 ! Extract Each Group's reference value
616 !
617 !print *,'SAG1: ',nbitsgref,ngroups,iofst
618 if (nbitsgref.ne.0) then
619 call g2_gbytesc(cpack,gref,iofst,nbitsgref,0,ngroups)
620 itemp=nbitsgref*ngroups
621 iofst=iofst+(itemp)
622 if (mod(itemp,8).ne.0) iofst=iofst+(8-mod(itemp,8))
623 else
624 gref(1:ngroups)=0
625 endif
626 !write(78,*)'GREFs: ',(gref(j),j=1,ngroups)
627 !
628 ! Extract Each Group's bit width
629 !
630 !print *,'SAG2: ',nbitsgwidth,ngroups,iofst,idrstmpl(11)
631 if (nbitsgwidth.ne.0) then
632 call g2_gbytesc(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)
633 itemp=nbitsgwidth*ngroups
634 iofst=iofst+(itemp)
635 if (mod(itemp,8).ne.0) iofst=iofst+(8-mod(itemp,8))
636 else
637 gwidth(1:ngroups)=0
638 endif
639 do j=1,ngroups
640 gwidth(j)=gwidth(j)+idrstmpl(11)
641 enddo
642 !write(78,*)'GWIDTHs: ',(gwidth(j),j=1,ngroups)
643 !
644 ! Extract Each Group's length (number of values in each group)
645 !
646 allocate(glen(ngroups),stat=is)
647 !print *,'ALLOC glen: ',is
648 !print *,'SAG3: ',nbitsglen,ngroups,iofst,idrstmpl(14),idrstmpl(13)
649 if (nbitsglen.ne.0) then
650 call g2_gbytesc(cpack,glen,iofst,nbitsglen,0,ngroups)
651 itemp=nbitsglen*ngroups
652 iofst=iofst+(itemp)
653 if (mod(itemp,8).ne.0) iofst=iofst+(8-mod(itemp,8))
654 else
655 glen(1:ngroups)=0
656 endif
657 do j=1,ngroups
658 glen(j)=(glen(j)*idrstmpl(14))+idrstmpl(13)
659 enddo
660 glen(ngroups)=idrstmpl(15)
661 !write(78,*)'GLENs: ',(glen(j),j=1,ngroups)
662 !print *,'GLENsum: ',sum(glen)
663 !
664 ! Test to see if the group widths and lengths are consistent with number of
665 ! values, and length of section 7.
666 !
667 totbit = 0
668 totlen = 0
669 do j=1,ngroups
670 totbit = totbit + (gwidth(j)*glen(j));
671 totlen = totlen + glen(j);
672 enddo
673 if (totlen .NE. ndpts) then
674 ier=1
675 return
676 endif
677 if ( (totbit/8) .GT. lensec) then
678 ier=1
679 return
680 endif
681 !
682 ! For each group, unpack data values
683 !
684 if ( idrstmpl(7).eq.0 ) then ! no missing values
685 n=1
686 do j=1,ngroups
687 !write(78,*)'NGP ',j,gwidth(j),glen(j),gref(j)
688 if (gwidth(j).ne.0) then
689 call g2_gbytesc(cpack,ifld(n),iofst,gwidth(j),0,glen(j))
690 do k=1,glen(j)
691 ifld(n)=ifld(n)+gref(j)
692 n=n+1
693 enddo
694 else
695 ifld(n:n+glen(j)-1)=gref(j)
696 n=n+glen(j)
697 endif
698 iofst=iofst+(gwidth(j)*glen(j))
699 enddo
700 elseif ( idrstmpl(7).eq.1.OR.idrstmpl(7).eq.2 ) then
701 ! missing values included
702 allocate(ifldmiss(ndpts))
703 !ifldmiss=0
704 n=1
705 non=1
706 do j=1,ngroups
707 !print *,'SAGNGP ',j,gwidth(j),glen(j),gref(j)
708 if (gwidth(j).ne.0) then
709 msng1=(2**gwidth(j))-1
710 msng2=msng1-1
711 call g2_gbytesc(cpack,ifld(n),iofst,gwidth(j),0,glen(j))
712 iofst=iofst+(gwidth(j)*glen(j))
713 do k=1,glen(j)
714 if (ifld(n).eq.msng1) then
715 ifldmiss(n)=1
716 elseif (idrstmpl(7).eq.2.AND.ifld(n).eq.msng2) then
717 ifldmiss(n)=2
718 else
719 ifldmiss(n)=0
720 ifld(non)=ifld(n)+gref(j)
721 non=non+1
722 endif
723 n=n+1
724 enddo
725 else
726 msng1=(2**nbitsgref)-1
727 msng2=msng1-1
728 if (gref(j).eq.msng1) then
729 ifldmiss(n:n+glen(j)-1)=1
730 !ifld(n:n+glen(j)-1)=0
731 elseif (idrstmpl(7).eq.2.AND.gref(j).eq.msng2) then
732 ifldmiss(n:n+glen(j)-1)=2
733 !ifld(n:n+glen(j)-1)=0
734 else
735 ifldmiss(n:n+glen(j)-1)=0
736 ifld(non:non+glen(j)-1)=gref(j)
737 non=non+glen(j)
738 endif
739 n=n+glen(j)
740 endif
741 enddo
742 endif
743 !write(78,*)'IFLDs: ',(ifld(j),j=1,ndpts)
744
745 if ( allocated(gref) ) deallocate(gref)
746 if ( allocated(gwidth) ) deallocate(gwidth)
747 if ( allocated(glen) ) deallocate(glen)
748 !
749 ! If using spatial differences, add overall min value, and
750 ! sum up recursively
751 !
752 if (idrsnum.eq.3) then ! spatial differencing
753 if (idrstmpl(17).eq.1) then ! first order
754 ifld(1)=ival1
755 if ( idrstmpl(7).eq.0 ) then ! no missing values
756 itemp=ndpts
757 else
758 itemp=non-1
759 endif
760 do n=2,itemp
761 ifld(n)=ifld(n)+minsd
762 ifld(n)=ifld(n)+ifld(n-1)
763 enddo
764 elseif (idrstmpl(17).eq.2) then ! second order
765 ifld(1)=ival1
766 ifld(2)=ival2
767 if ( idrstmpl(7).eq.0 ) then ! no missing values
768 itemp=ndpts
769 else
770 itemp=non-1
771 endif
772 do n=3,itemp
773 ifld(n)=ifld(n)+minsd
774 ifld(n)=ifld(n)+(2*ifld(n-1))-ifld(n-2)
775 enddo
776 endif
777 !write(78,*)'IFLDs: ',(ifld(j),j=1,ndpts)
778 endif
779 !
780 ! Scale data back to original form
781 !
782 !print *,'SAGT: ',ref,bscale,dscale
783 if ( idrstmpl(7).eq.0 ) then ! no missing values
784 do n=1,ndpts
785 fld(n)=((real(ifld(n))*bscale)+ref)*dscale
786 !write(78,*)'SAG ',n,fld(n),ifld(n),bscale,ref,1./dscale
787 enddo
788 elseif ( idrstmpl(7).eq.1.OR.idrstmpl(7).eq.2 ) then
789 ! missing values included
790 non=1
791 do n=1,ndpts
792 if ( ifldmiss(n).eq.0 ) then
793 fld(n)=((real(ifld(non))*bscale)+ref)*dscale
794 !print *,'SAG ',n,fld(n),ifld(non),bscale,ref,dscale
795 non=non+1
796 elseif ( ifldmiss(n).eq.1 ) then
797 fld(n)=rmiss1
798 elseif ( ifldmiss(n).eq.2 ) then
799 fld(n)=rmiss2
800 endif
801 enddo
802 if ( allocated(ifldmiss) ) deallocate(ifldmiss)
803 endif
804
805 if ( allocated(ifld) ) deallocate(ifld)
806
807 !open(10,form='unformatted',recl=24180,access='direct')
808 !read(10,rec=1) (fldo(k),k=1,6045)
809 !do i =1,6045
810 ! print *,i,fldo(i),fld(i),fldo(i)-fld(i)
811 !enddo
812
813 return
814end subroutine comunpack
815
854subroutine misspack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)
855
856 use intmath
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
862
863 real(4) :: ref, rmin4
864 integer(4) :: iref
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
871 logical :: have_rmin
872
873 simple_alg = .false.
874 have_rmin = .false.
875 bscale=2.0**real(-idrstmpl(2))
876 dscale=10.0**real(idrstmpl(3))
877 missopt=idrstmpl(7)
878 if ( missopt.ne.1 .AND. missopt.ne.2 ) then
879 print *,'misspack: Unrecognized option.'
880 lcpack=-1
881 return
882 else ! Get missing values
883 call rdieee(idrstmpl(8),rmissp,1)
884 if (missopt.eq.2) call rdieee(idrstmpl(9),rmisss,1)
885 endif
886
887 ! Find min value of non-missing values in the data,
888 ! AND set up missing value mapping of the field.
889 allocate(ifldmiss(ndpts))
890
891 if ( missopt .eq. 1 ) then ! Primary missing value only
892 do j=1,ndpts
893 if (fld(j).eq.rmissp) then
894 ifldmiss(j)=1
895 else
896 ifldmiss(j)=0
897 if(have_rmin) then
898 if (fld(j).lt.rmin) rmin=fld(j)
899 else
900 rmin=fld(j)
901 have_rmin=.true.
902 endif
903 endif
904 enddo
905 if(.not.have_rmin) rmin=rmissp
906 endif
907 if ( missopt .eq. 2 ) then ! Primary and secondary missing values
908 do j=1,ndpts
909 if (fld(j).eq.rmissp) then
910 ifldmiss(j)=1
911 elseif (fld(j).eq.rmisss) then
912 ifldmiss(j)=2
913 else
914 ifldmiss(j)=0
915 if(have_rmin) then
916 if (fld(j).lt.rmin) rmin=fld(j)
917 else
918 rmin=fld(j)
919 have_rmin=.true.
920 endif
921 endif
922 if(.not.have_rmin) rmin=rmissp
923 enddo
924 endif
925
926 ! Allocate work arrays:
927 ! Note: -ifldmiss(j),j=1,ndpts is a map of original field indicating
928 ! which of the original data values
929 ! are primary missing (1), sencondary missing (2) or non-missing (0).
930 ! -jfld(j),j=1,nonmiss is a subarray of just the non-missing values from
931 ! the original field.
932 iofst=0
933 allocate(ifld(ndpts))
934 allocate(jfld(ndpts))
935 allocate(gref(ndpts))
936 allocate(gwidth(ndpts))
937 allocate(glen(ndpts))
938 !
939 ! Scale original data
940 !
941 nonmiss=0
942 if (idrstmpl(2).eq.0) then ! No binary scaling
943 imin=nint(rmin*dscale)
944 !imax=nint(rmax*dscale)
945 rmin=real(imin)
946 do j=1,ndpts
947 if (ifldmiss(j).eq.0) then
948 nonmiss=nonmiss+1
949 jfld(nonmiss)=max(0,nint(fld(j)*dscale)-imin)
950 endif
951 enddo
952 else ! Use binary scaling factor
953 rmin=rmin*dscale
954 do j=1,ndpts
955 if (ifldmiss(j).eq.0) then
956 nonmiss=nonmiss+1
957 jfld(nonmiss)=max(0,nint(((fld(j)*dscale)-rmin)*bscale))
958 endif
959 enddo
960 endif
961 !
962 ! Calculate Spatial differences, if using DRS Template 5.3
963 !
964 if (idrsnum.eq.3) then ! spatial differences
965 if (idrstmpl(17).ne.1.and.idrstmpl(17).ne.2) idrstmpl(17)=2
966 if (idrstmpl(17).eq.1) then ! first order
967 if(nonmiss<1) then
968 ival1=1.0
969 else
970 ival1=jfld(1)
971 endif
972 do j=nonmiss,2,-1
973 jfld(j)=jfld(j)-jfld(j-1)
974 enddo
975 if(nonmiss>0) jfld(1)=0
976 elseif (idrstmpl(17).eq.2) then ! second order
977 if(nonmiss==1) then
978 ival1=jfld(1)
979 ival2=jfld(1)
980 elseif(nonmiss<1) then
981 ival1=1.0
982 ival2=1.0
983 else
984 ival1=jfld(1)
985 ival2=jfld(2)
986 endif
987 do j=nonmiss,3,-1
988 jfld(j)=jfld(j)-(2*jfld(j-1))+jfld(j-2)
989 enddo
990 if(nonmiss>=1) jfld(1)=0
991 if(nonmiss>=2) jfld(2)=0
992 endif
993
994 ! subtract min value from spatial diff field
995 isd=idrstmpl(17)+1
996 minsd=minval(jfld(isd:nonmiss))
997 do j=isd,nonmiss
998 jfld(j)=jfld(j)-minsd
999 enddo
1000
1001 ! find num of bits need to store minsd and add 1 extra bit
1002 ! to indicate sign
1003 temp=i1log2(abs(minsd))
1004 nbitsd=ceiling(temp)+1
1005
1006 ! find num of bits need to store ifld(1) ( and ifld(2)
1007 ! if using 2nd order differencing )
1008 maxorig=ival1
1009 if (idrstmpl(17).eq.2.and.ival2.gt.ival1) maxorig=ival2
1010 temp=i1log2(maxorig)
1011 nbitorig=ceiling(temp)+1
1012 if (nbitorig.gt.nbitsd) nbitsd=nbitorig
1013 ! increase number of bits to even multiple of 8 ( octet )
1014 if (mod(nbitsd,8).ne.0) nbitsd=nbitsd+(8-mod(nbitsd,8))
1015
1016 ! Store extra spatial differencing info into the packed
1017 ! data section.
1018 if (nbitsd.ne.0) then
1019 ! pack first original value
1020 if (ival1.ge.0) then
1021 call g2_sbytec(cpack,ival1,iofst,nbitsd)
1022 iofst=iofst+nbitsd
1023 else
1024 call g2_sbytec(cpack,1,iofst,1)
1025 iofst=iofst+1
1026 call g2_sbytec(cpack,iabs(ival1),iofst,nbitsd-1)
1027 iofst=iofst+nbitsd-1
1028 endif
1029 if (idrstmpl(17).eq.2) then
1030 ! pack second original value
1031 if (ival2.ge.0) then
1032 call g2_sbytec(cpack,ival2,iofst,nbitsd)
1033 iofst=iofst+nbitsd
1034 else
1035 call g2_sbytec(cpack,1,iofst,1)
1036 iofst=iofst+1
1037 call g2_sbytec(cpack,iabs(ival2),iofst,nbitsd-1)
1038 iofst=iofst+nbitsd-1
1039 endif
1040 endif
1041 ! pack overall min of spatial differences
1042 if (minsd.ge.0) then
1043 call g2_sbytec(cpack,minsd,iofst,nbitsd)
1044 iofst=iofst+nbitsd
1045 else
1046 call g2_sbytec(cpack,1,iofst,1)
1047 iofst=iofst+1
1048 call g2_sbytec(cpack,iabs(minsd),iofst,nbitsd-1)
1049 iofst=iofst+nbitsd-1
1050 endif
1051 endif
1052 !print *,'SDp ',ival1,ival2,minsd,nbitsd
1053 endif ! end of spatial diff section
1054
1055 ! Expand non-missing data values to original grid.
1056 miss1=minval(jfld(1:nonmiss))-1
1057 miss2=miss1-1
1058 n=0
1059 do j=1,ndpts
1060 if ( ifldmiss(j).eq.0 ) then
1061 n=n+1
1062 ifld(j)=jfld(n)
1063 elseif ( ifldmiss(j).eq.1 ) then
1064 ifld(j)=miss1
1065 elseif ( ifldmiss(j).eq.2 ) then
1066 ifld(j)=miss2
1067 endif
1068 enddo
1069 if(ndpts<2) simple_alg=.true.
1070
1071 ! Determine Groups to be used.
1072 if ( simple_alg ) then
1073 ! set group length to 10 : calculate number of groups
1074 ! and length of last group
1075 ngroups=ndpts/10
1076 glen(1:ngroups)=10
1077 itemp=mod(ndpts,10)
1078 if (itemp.ne.0) then
1079 ngroups=ngroups+1
1080 glen(ngroups)=itemp
1081 endif
1082 else
1083 ! Use Dr. Glahn's algorithm for determining grouping.
1084 !
1085 minpk=10
1086 inc=1
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)
1094 !print *,'SAGier = ',ier,ibit,jbit,kbit,novref,lbitref
1095 do ng=1,ngroups
1096 glen(ng)=glen(ng)+novref
1097 enddo
1098 deallocate(jmin)
1099 deallocate(jmax)
1100 deallocate(lbit)
1101 endif
1102
1103 ! For each group, find the group's reference value (min)
1104 ! and the number of bits needed to hold the remaining values
1105 n=1
1106 do ng=1,ngroups
1107 ! how many of each type?
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 ! all missing values
1112 if ( num1.eq.0 ) then ! all secondary missing
1113 gref(ng)=-2
1114 gwidth(ng)=0
1115 elseif ( num2.eq.0 ) then ! all primary missing
1116 gref(ng)=-1
1117 gwidth(ng)=0
1118 else ! both primary and secondary
1119 gref(ng)=0
1120 gwidth(ng)=1
1121 endif
1122 else ! contains some non-missing data
1123 ! find max and min values of group
1124 gref(ng)=huge(n)
1125 imax=-1*huge(n)
1126 j=n
1127 do lg=1,glen(ng)
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)
1131 endif
1132 j=j+1
1133 enddo
1134 if (missopt.eq.1) imax=imax+1
1135 if (missopt.eq.2) imax=imax+2
1136 ! calc num of bits needed to hold data
1137 if ( gref(ng).ne.imax ) then
1138 temp=i1log2(imax-gref(ng))
1139 gwidth(ng)=ceiling(temp)
1140 else
1141 gwidth(ng)=0
1142 endif
1143 endif
1144 ! Subtract min from data
1145 j=n
1146 mtemp=2**gwidth(ng)
1147 do lg=1,glen(ng)
1148 if (ifldmiss(j).eq.0) then ! non-missing
1149 ifld(j)=ifld(j)-gref(ng)
1150 elseif (ifldmiss(j).eq.1) then ! primary missing
1151 ifld(j)=mtemp-1
1152 elseif (ifldmiss(j).eq.2) then ! secondary missing
1153 ifld(j)=mtemp-2
1154 endif
1155 j=j+1
1156 enddo
1157 ! increment fld array counter
1158 n=n+glen(ng)
1159 enddo
1160
1161 ! Find max of the group references and calc num of bits needed
1162 ! to pack each groups reference value, then
1163 ! pack up group reference values
1164 !write(77,*)'GREFS: ',(gref(j),j=1,ngroups)
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
1169 temp=i1log2(igmax)
1170 nbitsgref=ceiling(temp)
1171 ! restet the ref values of any "missing only" groups.
1172 mtemp=2**nbitsgref
1173 do j=1,ngroups
1174 if (gref(j).eq.-1) gref(j)=mtemp-1
1175 if (gref(j).eq.-2) gref(j)=mtemp-2
1176 enddo
1177 call g2_sbytesc(cpack,gref,iofst,nbitsgref,0,ngroups)
1178 itemp=nbitsgref*ngroups
1179 iofst=iofst+itemp
1180 ! Pad last octet with Zeros, if necessary,
1181 if (mod(itemp,8).ne.0) then
1182 left=8-mod(itemp,8)
1183 call g2_sbytec(cpack,zero,iofst,left)
1184 iofst=iofst+left
1185 endif
1186 else
1187 nbitsgref=0
1188 endif
1189
1190 ! Find max/min of the group widths and calc num of bits needed
1191 ! to pack each groups width value, then
1192 ! pack up group width values
1193 !write(77,*)'GWIDTHS: ',(gwidth(j),j=1,ngroups)
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)
1199 do i=1,ngroups
1200 gwidth(i)=gwidth(i)-ngwidthref
1201 enddo
1202 call g2_sbytesc(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)
1203 itemp=nbitsgwidth*ngroups
1204 iofst=iofst+itemp
1205 ! Pad last octet with Zeros, if necessary,
1206 if (mod(itemp,8).ne.0) then
1207 left=8-mod(itemp,8)
1208 call g2_sbytec(cpack,zero,iofst,left)
1209 iofst=iofst+left
1210 endif
1211 else
1212 nbitsgwidth=0
1213 gwidth(1:ngroups)=0
1214 endif
1215
1216 ! Find max/min of the group lengths and calc num of bits needed
1217 ! to pack each groups length value, then
1218 ! pack up group length values
1219 !write(77,*)'GLENS: ',(glen(j),j=1,ngroups)
1220 ilmax=maxval(glen(1:ngroups-1))
1221 nglenref=minval(glen(1:ngroups-1))
1222 if(ngroups>0) then
1223 nglenlast=glen(ngroups)
1224 else
1225 nglenlast=0
1226 endif
1227 if (ilmax.ne.nglenref) then
1228 temp=i1log2(ilmax-nglenref)
1229 nbitsglen=ceiling(temp)
1230 do i=1,ngroups-1
1231 glen(i)=glen(i)-nglenref
1232 enddo
1233 call g2_sbytesc(cpack,glen,iofst,nbitsglen,0,ngroups)
1234 itemp=nbitsglen*ngroups
1235 iofst=iofst+itemp
1236 ! Pad last octet with Zeros, if necessary,
1237 if (mod(itemp,8).ne.0) then
1238 left=8-mod(itemp,8)
1239 call g2_sbytec(cpack,zero,iofst,left)
1240 iofst=iofst+left
1241 endif
1242 else
1243 nbitsglen=0
1244 glen(1:ngroups)=0
1245 endif
1246
1247 ! For each group, pack data values
1248 !write(77,*)'IFLDS: ',(ifld(j),j=1,ndpts)
1249 n=1
1250 ij=0
1251 do ng=1,ngroups
1252 glength=glen(ng)+nglenref
1253 if (ng.eq.ngroups ) glength=nglenlast
1254 grpwidth=gwidth(ng)+ngwidthref
1255 !write(77,*)'NGP ',ng,grpwidth,glength,gref(ng)
1256 if ( grpwidth.ne.0 ) then
1257 call g2_sbytesc(cpack,ifld(n),iofst,grpwidth,0,glength)
1258 iofst=iofst+(grpwidth*glength)
1259 endif
1260 do kk=1,glength
1261 ij=ij+1
1262 !write(77,*)'SAG ',ij,fld(ij),ifld(ij),gref(ng),bscale,rmin,dscale
1263 enddo
1264 n=n+glength
1265 enddo
1266 ! Pad last octet with Zeros, if necessary,
1267 if (mod(iofst,8).ne.0) then
1268 left=8-mod(iofst,8)
1269 call g2_sbytec(cpack,zero,iofst,left)
1270 iofst=iofst+left
1271 endif
1272 lcpack=iofst/8
1273 !
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)
1280
1281 ! Fill in ref value and number of bits in Template 5.2
1282 rmin4 = real(rmin, 4)
1283 call mkieee(rmin4,ref,1) ! ensure reference value is IEEE format
1284 iref=transfer(ref,iref)
1285 idrstmpl(1)=iref
1286 idrstmpl(4)=nbitsgref
1287 idrstmpl(5)=0 ! original data were reals
1288 idrstmpl(6)=1 ! general group splitting
1289 idrstmpl(10)=ngroups ! Number of groups
1290 idrstmpl(11)=ngwidthref ! reference for group widths
1291 idrstmpl(12)=nbitsgwidth ! num bits used for group widths
1292 idrstmpl(13)=nglenref ! Reference for group lengths
1293 idrstmpl(14)=1 ! length increment for group lengths
1294 idrstmpl(15)=nglenlast ! True length of last group
1295 idrstmpl(16)=nbitsglen ! num bits used for group lengths
1296 if (idrsnum.eq.3) then
1297 idrstmpl(18)=nbitsd/8 ! num bits used for extra spatial
1298 ! differencing values
1299 endif
1300
1301end subroutine misspack
subroutine misspack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack up a data field using a GRIB2 algorithm with missing value management.
Definition compack.F90:855
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...
Definition compack.F90:528
subroutine cmplxpack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack up a data field using a complex packing algorithm.
Definition compack.F90:43
subroutine compack(fld, ndpts, idrsnum, idrstmpl, cpack, lcpack)
Pack a data field with complex packing with or without spatial differences, defined in Data Represent...
Definition compack.F90:89
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 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...
Definition g2bytes.F90:21
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
Define math functions used by compack(), simpack(), and misspack().
Definition intmath.F90:22
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...
Definition pack_gp.f:116