NCEPLIBS-bufr  12.2.0
All Data Structures Namespaces Files Functions Variables Macros Pages
compress.F90
Go to the documentation of this file.
1 
5 
32 subroutine cmpmsg(cf)
33 
34  use moda_msgcmp
35 
36  implicit none
37 
38  character, intent(in) :: cf
39  character*128 bort_str
40 
41  call capit(cf)
42  if(cf/='Y'.and. cf/='N') then
43  write(bort_str,'("BUFRLIB: CMPMSG - INPUT ARGUMENT IS ",A1,", IT MUST BE EITHER Y OR N")') cf
44  call bort(bort_str)
45  endif
46  ccmf = cf
47 
48  return
49 end subroutine cmpmsg
50 
71 recursive subroutine writcp(lunit)
72 
73  use modv_vars, only: im8b
74 
75  implicit none
76 
77  integer, intent(in) :: lunit
78  integer my_lunit
79 
80  ! Check for I8 integers.
81 
82  if(im8b) then
83  im8b=.false.
84 
85  call x84(lunit,my_lunit,1)
86  call writcp(my_lunit)
87 
88  im8b=.true.
89  return
90  endif
91 
92  call cmpmsg('Y')
93  call writsb(lunit)
94  call cmpmsg('N')
95 
96  return
97 end subroutine writcp
98 
109 subroutine rdcmps(lun)
110 
111  use modv_vars, only: bmiss, mxrst
112 
113  use moda_usrint
114  use moda_msgcwd
115  use moda_bitbuf
116  use moda_tables
117  use moda_rlccmn
118  use moda_stcode
119 
120  implicit none
121 
122  integer, intent(in) :: lun
123  integer*8 :: ival, lref, ninc, lps
124  integer nsbs, jbit, lbit, nbit, n, node, ityp, linc, lre4, nin4, nbmp, nchr, lelm, ibsv, igetrfel, ibfms, icbfms
125 
126  real*8 rval, ups
127 
128  character*128 bort_str
129  character*8 cref, cval
130 
131  equivalence(cval,rval)
132 
133  ! Statement function to compute BUFR "missing value" for field of length lbit bits (all bits "on")
134  lps(lbit) = max(2_8**(lbit)-1,1)
135 
136  ! Setup the subset template
137 
138  call usrtpl(lun,1,1)
139 
140  ! Uncompress a subset into the val array according to Table B
141 
142  nsbs = nsub(lun)
143 
144  ! Note that we are going to unpack the (nsbs)th subset from within the current BUFR message.
145 
146  ibit = mbyt(lun)
147  nrst = 0
148 
149  ! Loop through each element of the subset, including immediately resolving any replication sequences by emulating recursion
150  ! via an explicit goto statement.
151 
152  n = 0
153  11 do n=n+1,nval(lun)
154  node = inv(n,lun)
155  nrfelm(n,lun) = igetrfel(n,lun)
156  nbit = ibt(node)
157  ityp = itp(node)
158 
159  ! In each of the following code blocks, the "local reference value" for the element is determined first, followed by the
160  ! 6-bit value which indicates how many bits are used to store the increment (i.e. offset) from this "local reference value".
161  ! Then, we jump ahead to where this increment is stored for this particular subset, unpack it, and add it to the
162  ! "local reference value" to determine the final uncompressed value for this element from this subset. Note that, if an
163  ! element has the same final uncompressed value for each subset in the message, then the encoding rules for BUFR compression
164  ! dictate that the "local reference value" will be equal to this value, the 6-bit increment length indicator will have a
165  ! value of zero, and the actual increments themselves will be omitted from the message.
166 
167  if(ityp==1.or.ityp==2) then
168  ! This is a numeric element.
169  if(nbit<=32) then
170  call upb(lre4,nbit,mbay(1,lun),ibit)
171  call upb(linc,6,mbay(1,lun),ibit)
172  jbit = ibit + linc*(nsbs-1)
173  call upb(nin4,linc,mbay(1,lun),jbit)
174  lref = lre4
175  ninc = nin4
176  elseif(nbit<=64) then
177  call up8(lref,nbit,mbay(1,lun),ibit)
178  call upb(linc,6,mbay(1,lun),ibit)
179  jbit = ibit + linc*(nsbs-1)
180  call up8(ninc,linc,mbay(1,lun),jbit)
181  endif
182  if(ninc==lps(linc)) then
183  ival = lps(nbit)
184  else
185  ival = lref + ninc
186  endif
187  if(ityp==1) then
188  nbmp = int(ival)
189  call usrtpl(lun,n,nbmp)
190  if (iscodes(lun) /= 0) return
191  goto 11
192  endif
193  if(ival<lps(nbit)) val(n,lun) = ups(ival,node)
194  call strbtm(n,lun,ibfms(val(n,lun)))
195  ibit = ibit + linc*msub(lun)
196  elseif(ityp==3) then
197  ! This is a character element. If there are more than 8 characters, then only the first 8 will be unpacked by this
198  ! routine, and a separate subsequent call to subroutine readlc() will be required to unpack the remainder of the string.
199  ! In this case, pointers will be saved within module @ref moda_rlccmn for later use within readlc().
200  lelm = nbit/8
201  nchr = min(8,lelm)
202  ibsv = ibit
203  cref = ' '
204  call upc(cref,nchr,mbay(1,lun),ibit,.true.)
205  if(lelm>8) then
206  ibit = ibit + (lelm-8)*8
207  nrst = nrst + 1
208  if(nrst>mxrst) then
209  write(bort_str,'("BUFRLIB: RDCMPS - NUMBER OF LONG CHARACTER STRINGS EXCEEDS THE LIMIT (",I4,")")') mxrst
210  call bort(bort_str)
211  endif
212  crtag(nrst) = tag(node)
213  endif
214  ! Unpack the increment length indicator. For character elements, this length is in bytes rather than bits.
215  call upb(linc,6,mbay(1,lun),ibit)
216  if(linc==0) then
217  if(lelm>8) then
218  irnch(nrst) = lelm
219  irbit(nrst) = ibsv
220  endif
221  cval = cref
222  else
223  jbit = ibit + linc*(nsbs-1)*8
224  if(lelm>8) then
225  irnch(nrst) = linc
226  irbit(nrst) = jbit
227  endif
228  nchr = min(8,linc)
229  cval = ' '
230  call upc(cval,nchr,mbay(1,lun),jbit,.true.)
231  endif
232  if (lelm<=8 .and. icbfms(cval,nchr)/=0) then
233  val(n,lun) = bmiss
234  else
235  val(n,lun) = rval
236  endif
237  ibit = ibit + 8*linc*msub(lun)
238  endif
239  enddo
240 
241  return
242 end subroutine rdcmps
243 
258 subroutine cmsgini(lun,mesg,subset,idate,nsub,nbyt)
259 
260  use modv_vars, only: mtv, nby1, nby5, bmostr
261 
262  implicit none
263 
264  integer, intent(in) :: lun, idate, nsub
265  integer, intent(inout) :: nbyt
266  integer, intent(out) :: mesg(*)
267  integer mtyp, msbt, inod, isub, iret, jdate, mcen, mear, mmon, mday, mour, mmin, mbit, mbyt, len3, i4dy
268 
269  character*128 bort_str
270  character*8, intent(in) :: subset
271  character tab
272 
273  ! Get the message tag and type, and break up the date which can be either YYMMDDHH or YYYYMMDDHH
274 
275  call nemtba(lun,subset,mtyp,msbt,inod)
276  call nemtab(lun,subset,isub,tab,iret)
277  if(iret==0) then
278  write(bort_str,'("BUFRLIB: CMSGINI - TABLE A MESSAGE TYPE MNEMONIC ",A," NOT FOUND IN INTERNAL TABLE D ARRAYS")') subset
279  call bort(bort_str)
280  endif
281 
282  jdate = i4dy(idate)
283  mcen = mod(jdate/10**8,100)+1
284  mear = mod(jdate/10**6,100)
285  mmon = mod(jdate/10**4,100)
286  mday = mod(jdate/10**2,100)
287  mour = mod(jdate ,100)
288  mmin = 0
289 
290  if(mear==0) then
291  mcen = mcen-1
292  mear = 100
293  endif
294 
295  ! Initialize the message
296 
297  mbit = 0
298 
299  ! Section 0
300 
301  call pkc(bmostr, 4 , mesg,mbit)
302  ! Note that the actual Section 0 length will be computed and stored below; for now, we're really only interested in
303  ! advancing mbit by the correct amount, so we'll just store a default value of 0.
304  call pkb( 0 , 24 , mesg,mbit)
305  call pkb( 3 , 8 , mesg,mbit)
306 
307  ! Section 1
308 
309  call pkb(nby1 , 24 , mesg,mbit)
310  call pkb( 0 , 8 , mesg,mbit)
311  call pkb( 3 , 8 , mesg,mbit)
312  call pkb( 7 , 8 , mesg,mbit)
313  call pkb( 0 , 8 , mesg,mbit)
314  call pkb( 0 , 8 , mesg,mbit)
315  call pkb(mtyp , 8 , mesg,mbit)
316  call pkb(msbt , 8 , mesg,mbit)
317  call pkb( mtv , 8 , mesg,mbit)
318  call pkb( 0 , 8 , mesg,mbit)
319  call pkb(mear , 8 , mesg,mbit)
320  call pkb(mmon , 8 , mesg,mbit)
321  call pkb(mday , 8 , mesg,mbit)
322  call pkb(mour , 8 , mesg,mbit)
323  call pkb(mmin , 8 , mesg,mbit)
324  call pkb(mcen , 8 , mesg,mbit)
325 
326  ! Section 3
327 
328  len3 = 10
329 
330  call pkb(len3 , 24 , mesg,mbit)
331  call pkb( 0 , 8 , mesg,mbit)
332  call pkb(nsub , 16 , mesg,mbit)
333  call pkb( 192 , 8 , mesg,mbit)
334  call pkb(isub , 16 , mesg,mbit)
335  call pkb( 0 , 8 , mesg,mbit)
336 
337  ! Section 4
338 
339  ! Store the total length of Section 4. Remember that the input value of nbyt only contains the length of the compressed
340  ! data portion of Section 4, so we need to add four bytes to this number in order to account for the total length of
341  ! Section 4. The actual compressed data portion will be filled in later by subroutine wrcmps().
342  call pkb((nbyt+4) , 24 , mesg,mbit)
343  call pkb( 0 , 8 , mesg,mbit)
344 
345  ! Section 5
346 
347  ! This section will be filled in later by subroutine wrcmps(). However, for now, and noting that mbit currently points
348  ! to the last bit of the fourth byte of Section 4, then we have:
349  ! (total length of BUFR message (in Section 0)) =
350  ! (length of message up through fourth byte of Section 4)
351  ! + (length of compressed data portion of Section 4)
352  ! + (length of Section 5)
353  mbyt = mbit/8 + nbyt + nby5
354 
355  ! For output, make nbyt point to the current location of mbit, which is the byte after which to actually begin writing the
356  ! compressed data into Section 4.
357  nbyt = mbit/8
358 
359  ! Now, store the total length of the BUFR message in Section 0.
360  mbit = 32
361  call pkb(mbyt,24,mesg,mbit)
362 
363  return
364 end subroutine cmsgini
365 
383 subroutine wrcmps(lunix)
384 
385  use modv_vars, only: mxcdv, mxcsb, nby5, bmcstr
386 
387  use moda_usrint
388  use moda_msgcwd
389  use moda_bitbuf
390  use moda_mgwa
391  use moda_tables
392  use moda_comprx
393  use moda_comprs
394  use moda_s01cm
395 
396  implicit none
397 
398  integer, intent(in) :: lunix
399  integer ibyt, jbit, lunit, lun, il, im, icol, i, j, node, lbyt, nbyt, nchr, ldata, iupbs01, imrkopr
400 
401  character*128 bort_str
402  character*8 subset
403  character czero
404 
405  logical first, kmiss, edge4, msgfull, cmpres
406 
407  real, parameter :: rln2 = 1./log(2.)
408  real range
409 
410  data first /.true./
411 
412  save first, ibyt, jbit, subset, edge4
413 
414  ! Get the unit and subset tag
415 
416  lunit = abs(lunix)
417  call status(lunit,lun,il,im)
418 
419  do while (.true.)
420 
421  if(first) then
422  ! Initialize some values in order to prepare for the creation of a new compressed BUFR message for output.
423  kbyt = 0
424  ncol = 0
425  lunc = lun
426  nrow = nval(lun)
427  subset = tag(inode(lun))(1:8)
428  first = .false.
429  flush = .false.
430  writ1 = .false.
431  ! The following call to cmsgini() is just being done to determine how many bytes (kbyt) will be taken up in a message
432  ! by the information in Sections 0, 1, 2 and 3. This in turn will allow us to determine how many compressed data subsets
433  ! will fit into Section 4 without overflowing maxbyt. Then, later on, another separate call to cmsgini() will be done to
434  ! actually initialize Sections 0, 1, 2 and 3 of the final compressed BUFR message that will be written out.
435  call cmsgini(lun,mbay(1,lun),subset,idate(lun),ncol,kbyt)
436  ! Check the edition number of the BUFR message to be created
437  edge4 = .false.
438  if(ns01v>0) then
439  i = 1
440  do while ( (.not.edge4) .and. (i<=ns01v) )
441  if( (cmnem(i)=='BEN') .and. (ivmnem(i)>=4) ) then
442  edge4 = .true.
443  else
444  i = i+1
445  endif
446  enddo
447  endif
448  endif
449 
450  if(lun/=lunc) then
451  write(bort_str,.NE.'("BUFRLIB: WRCMPS - FILE ID FOR THIS CALL (",I3,") FILE ID FOR INITIAL CALL (",I3,")'// &
452  ' - UNIT NUMBER NOW IS",I4)') lun,lunc,lunix
453  call bort(bort_str)
454  endif
455 
456  cmpres = .true.
457  if(lunix<0) then
458  ! This is a "flush" call, so clear out the buffer (note that there is no current subset to be stored!) and prepare
459  ! to write the final compressed BUFR message.
460  if(ncol<=0) return
461  flush = .true.
462  writ1 = .true.
463  icol = 1
464  elseif(ncol+1>mxcsb) then
465  ! There's no more room in the internal compression arrays for another subset, so we'll need to write out a message
466  ! containing all of the data in those arrays, then initialize a new message to hold the current subset.
467  cmpres = .false.
468  else
469  ! Check on some other possibly problematic situations
470  if(nval(lun)/=nrow) then
471  writ1 = .true.
472  icol = 1
473  elseif(nval(lun)>mxcdv) then
474  write(bort_str,'("BUFRLIB: WRCMPS - NO. OF ELEMENTS IN THE '// &
475  .GT.'SUBSET (",I6,") THE NO. OF ROWS ALLOCATED FOR THE COMPRESSION MATRIX (",I6,")")') nval(lun),mxcdv
476  call bort(bort_str)
477  elseif(ncol>0) then
478  ! Confirm that all of the nodes are the same as in the previous subset for this same BUFR message. If not, then
479  ! there may be different nested replication sequences activated in the current subset vs. in the previous subset,
480  ! even though the total number of nodes is the same.
481  do i = 1, nval(lun)
482  if ( inv(i,lun) /= jlnode(i) ) then
483  writ1 = .true.
484  icol = 1
485  exit
486  endif
487  enddo
488  endif
489  if(.not.writ1) then
490  ! Store the next subset for compression
491  ncol = ncol+1
492  icol = ncol
493  ibit = 16
494  do i=1,nval(lun)
495  node = inv(i,lun)
496  jlnode(i) = node
497  ityp(i) = itp(node)
498  if(imrkopr(tag(node))==1) then
499  iwid(i) = ibt(inv(nrfelm(i,lun),lun))
500  else
501  iwid(i) = ibt(node)
502  endif
503  if(ityp(i)==1.or.ityp(i)==2) then
504  call up8(matx(i,ncol),iwid(i),ibay,ibit)
505  elseif(ityp(i)==3) then
506  catx(i,ncol) = ' '
507  call upc(catx(i,ncol),iwid(i)/8,ibay,ibit,.true.)
508  endif
509  enddo
510  endif
511  endif
512 
513  ! Will the next subset fit into the current message? The only way to find out is to actually re-do the compression
514  ! by re-computing all of the local reference values, increments, etc. to determine the new Section 4 length.
515 
516  do while (cmpres)
517  if(ncol<=0) then
518  write(bort_str,'("BUFRLIB: WRCMPS - NO. OF COLUMNS CALCULATED '// &
519  .LE.'FOR COMPRESSION MAXRIX IS 0 (=",I6,")")') ncol
520  call bort(bort_str)
521  endif
522  ! ldata will hold the length (in bits) of the compressed data, i.e. the sum total for all data values for all data
523  ! subsets in the message
524  ldata = 0
525  do i=1,nrow
526  if(ityp(i)==1 .or. ityp(i)==2) then
527  ! Row i of the compression matrix contains numeric values, so kmis(i) will store .true. if any such values are
528  ! "missing", or .false. otherwise
529  imiss = 2_8**iwid(i)-1
530  if(icol==1) then
531  kmin(i) = imiss
532  kmax(i) = 0
533  kmis(i) = .false.
534  endif
535  do j=icol,ncol
536  if(matx(i,j)<imiss) then
537  kmin(i) = min(kmin(i),matx(i,j))
538  kmax(i) = max(kmax(i),matx(i,j))
539  else
540  kmis(i) = .true.
541  endif
542  enddo
543  kmiss = kmis(i) .and. kmin(i)<imiss
544  range = real(max(1,kmax(i)-kmin(i)+1))
545  if(ityp(i)==2 .and. (range>1. .or. kmiss)) then
546  ! The data values in row i of the compression matrix are numeric values that aren't all identical. Compute the
547  ! number of bits needed to hold the largest of the increments.
548  kbit(i) = nint(log(range)*rln2)
549  if(2**kbit(i)-1<=range) kbit(i) = kbit(i)+1
550  ! However, under no circumstances should this number ever exceed the width of the original underlying descriptor!
551  if(kbit(i)>iwid(i)) kbit(i) = iwid(i)
552  else
553  ! The data values in row i of the compression matrix are numeric values that are all identical, so the increments
554  ! will be omitted from the message.
555  kbit(i) = 0
556  endif
557  ldata = ldata + iwid(i) + 6 + ncol*kbit(i)
558  elseif(ityp(i)==3) then
559  ! Row i of the compression matrix contains character values, so kmis(i) will store .false. if all such values are
560  ! identical, OR .true. otherwise
561  if(icol==1) then
562  cstr(i) = catx(i,1)
563  kmis(i) = .false.
564  endif
565  do j=icol,ncol
566  if ( (.not.kmis(i)) .and. (cstr(i)/=catx(i,j)) ) then
567  kmis(i) = .true.
568  endif
569  enddo
570  if (kmis(i)) then
571  ! The data values in row i of the compression matrix are character values that are not all identical
572  kbit(i) = iwid(i)
573  else
574  ! The data values in row i of the compression matrix are character values that are all identical, so the
575  ! increments will be omitted from the message
576  kbit(i) = 0
577  endif
578  ldata = ldata + iwid(i) + 6 + ncol*kbit(i)
579  endif
580  enddo
581  ! Round data length up to a whole byte count
582  ibyt = (ldata+8-mod(ldata,8))/8
583  ! Depending on the edition number of the message, we need to ensure that we round to an even byte count
584  if( (.not.edge4) .and. (mod(ibyt,2)/=0) ) ibyt = ibyt+1
585  jbit = ibyt*8-ldata
586  if(msgfull(ibyt,kbyt,maxbyt)) then
587  ! The current subset will not fit into the current message. Set the flag to indicate that a message write is needed,
588  ! then go back and re-compress the Section 4 data for this message while excluding the data for the current subset,
589  ! which will be held and stored as the first subset of a new message after writing the current message.
590  writ1 = .true.
591  ncol = ncol-1
592  icol = 1
593  elseif(.not.writ1) then
594  ! Add the current subset to the current message and return
595  call usrtpl(lun,1,1)
596  nsub(lun) = -ncol
597  return
598  else
599  ! Exit the loop and proceed to write out the current message
600  cmpres = .false.
601  endif
602  enddo
603 
604  ! Write the complete compressed message. First, we need to do another call to cmsgini() to initialize Sections 0, 1, 2,
605  ! and 3 of the final compressed BUFR message that will be written out.
606 
607  call cmsgini(lun,mgwa,subset,idate(lun),ncol,ibyt)
608 
609  ! Now add the Section 4 data
610 
611  ibit = ibyt*8
612  do i=1,nrow
613  if(ityp(i)==1.or.ityp(i)==2) then
614  call pkb8(kmin(i),iwid(i),mgwa,ibit)
615  call pkb(kbit(i),6,mgwa,ibit)
616  if(kbit(i)>0) then
617  do j=1,ncol
618  if(matx(i,j)<2_8**iwid(i)-1) then
619  incr = matx(i,j)-kmin(i)
620  else
621  incr = 2_8**kbit(i)-1
622  endif
623  call pkb8(incr,kbit(i),mgwa,ibit)
624  enddo
625  endif
626  elseif(ityp(i)==3) then
627  nchr = iwid(i)/8
628  if(kbit(i)>0) then
629  call ipkm(czero,1,0)
630  do j=1,nchr
631  call pkc(czero,1,mgwa,ibit)
632  enddo
633  call pkb(nchr,6,mgwa,ibit)
634  do j=1,ncol
635  call pkc(catx(i,j),nchr,mgwa,ibit)
636  enddo
637  else
638  call pkc(cstr(i),nchr,mgwa,ibit)
639  call pkb(0,6,mgwa,ibit)
640  endif
641  endif
642  enddo
643 
644  ! Pad the end of Section 4 with zeroes up to the necessary byte count
645 
646  call pkb(0,jbit,mgwa,ibit)
647 
648  ! Add Section 5
649 
650  call pkc(bmcstr,nby5,mgwa,ibit)
651 
652  ! Check that the message byte counters agree, then write the message
653 
654  if(mod(ibit,8)/=0) call bort('BUFRLIB: WRCMPS - THE NUMBER OF BITS IN THE '// &
655  'COMPRESSED BUFR MSG IS NOT A MULTIPLE OF 8 - MSG MUST END ON A BYTE BOUNDARY')
656  lbyt = iupbs01(mgwa,'LENM')
657  nbyt = ibit/8
658  if(nbyt/=lbyt) then
659  write(bort_str,'("BUFRLIB: WRCMPS - OUTPUT MESSAGE LENGTH FROM '// &
660  'SECTION 0",I6," DOES NOT EQUAL FINAL PACKED MESSAGE LENGTH (",I6,")")') lbyt,nbyt
661  call bort(bort_str)
662  endif
663 
664  call msgwrt(lunit,mgwa,nbyt)
665 
666  ! Now, unless this was a "flush" call to this subroutine, go back and initialize a new message to hold the current subset
667  ! that we weren't able to fit into the message that was just written out.
668 
669  first = .true.
670  if(flush) return
671  end do
672 
673 end subroutine wrcmps
subroutine strbtm(n, lun, ival)
Store internal information in module moda_bitmaps if the input element is part of a bitmap.
Definition: bitmaps.F90:20
subroutine bort(str)
Log an error message, then abort the application program.
Definition: borts.F90:15
subroutine upb(nval, nbits, ibay, ibit)
Decode an integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:202
real *8 function ups(ival, node)
Unpack a real*8 value from an integer by applying the proper scale and reference values.
Definition: cidecode.F90:319
subroutine up8(nval, nbits, ibay, ibit)
Decode an 8-byte integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:128
subroutine upc(chr, nchr, ibay, ibit, cnvnull)
Decode a character string from within a specified number of bytes of an integer array,...
Definition: cidecode.F90:26
subroutine pkc(chr, nchr, ibay, ibit)
Encode a character string within a specified number of bytes of an integer array, starting at the bit...
Definition: ciencode.F90:25
recursive subroutine ipkm(cbay, nbyt, n)
Encode an integer value within a specified number of bytes of a character string, up to a maximum of ...
Definition: ciencode.F90:194
subroutine pkb(nval, nbits, ibay, ibit)
Encode an integer value within a specified number of bits of an integer array, starting at the bit im...
Definition: ciencode.F90:140
subroutine pkb8(nval, nbits, ibay, ibit)
Encode an 8-byte integer value within a specified number of bits of an integer array,...
Definition: ciencode.F90:97
subroutine rdcmps(lun)
Read the next compressed BUFR data subset into internal arrays.
Definition: compress.F90:110
subroutine cmsgini(lun, mesg, subset, idate, nsub, nbyt)
Initialize a new BUFR message for output in compressed format.
Definition: compress.F90:259
recursive subroutine writcp(lunit)
Write a data subset into a BUFR message using compression.
Definition: compress.F90:72
subroutine wrcmps(lunix)
Write a compressed BUFR data subset.
Definition: compress.F90:384
subroutine cmpmsg(cf)
Specify whether BUFR messages output by future calls to message-writing subroutines and subset-writin...
Definition: compress.F90:33
subroutine nemtba(lun, nemo, mtyp, msbt, inod)
Get information about a Table A descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1238
subroutine nemtab(lun, nemo, idn, tab, iret)
Get information about a descriptor, based on a mnemonic.
Definition: fxy.F90:434
subroutine capit(str)
Capitalize all of the alphabetic characters in a string.
Definition: misc.F90:334
Declare arrays and variables used to store BUFR messages internally for multiple file IDs.
integer, dimension(:), allocatable ibay
Current data subset.
integer ibit
Bit pointer within ibay.
integer, dimension(:,:), allocatable mbay
Current BUFR message for each file ID.
integer, dimension(:), allocatable mbyt
Length (in bytes) of current BUFR message for each file ID.
integer maxbyt
Maximum length of an output BUFR message.
Declare arrays and variables needed for the storage of data values needed when writing compressed dat...
integer ncol
Number of data subsets in message.
integer *8 incr
Increment used when compressing non-character data values.
character *(:), dimension(:,:), allocatable catx
Character data values for all data subsets in message.
integer *8, dimension(:,:), allocatable matx
Non-character data values for all data subsets in message.
Declare arrays and variable needed for the storage of data values needed when writing compressed data...
character *(:), dimension(:), allocatable cstr
Character data value, if corresponding ityp value is set to 3.
integer kbyt
Number of bytes required to store Sections 0, 1, 2, and 3 of message.
logical flush
Flush flag.
integer nrow
Number of data values for each data subset in message.
integer *8 imiss
"Missing" value used when compressing non-character data values.
integer *8, dimension(:), allocatable kmax
Maximum of each data value across all data subsets in message.
integer, dimension(:), allocatable jlnode
Jump/link table node corresponding to each data value.
logical writ1
Write-out flag.
integer, dimension(:), allocatable ityp
Type of each data value:
integer, dimension(:), allocatable iwid
Bit width of underlying data descriptor as defined within Table B for each data value.
integer lunc
File ID for output file.
integer, dimension(:), allocatable kbit
Number of bits needed to hold the increments for this data value within each data subset of the messa...
logical, dimension(:), allocatable kmis
"Missing" values flag.
integer *8, dimension(:), allocatable kmin
Minimum of each data value across all data subsets in message.
Declare an array used by various subroutines and functions to hold a temporary working copy of a BUFR...
integer, dimension(:), allocatable mgwa
Temporary working copy of BUFR message.
Declare a variable used to indicate whether output BUFR messages should be compressed.
character ccmf
Flag indicating whether BUFR output messages are to be compressed; this variable is initialized to a ...
Declare arrays used to store information about the current BUFR message that is in the process of bei...
integer, dimension(:), allocatable inode
Table A mnemonic for type of BUFR message.
integer, dimension(:), allocatable idate
Section 1 date-time of message.
integer, dimension(:), allocatable msub
Total number of data subsets in message.
integer, dimension(:), allocatable nsub
Current subset pointer within message.
Declare arrays and variables needed to store information about long character strings (greater than 8...
integer nrst
Number of long character strings in data subset.
integer, dimension(:), allocatable irnch
Lengths (in bytes) of long character strings.
integer, dimension(:), allocatable irbit
Pointers in data subset to first bits of long character strings.
character *10, dimension(:), allocatable crtag
Table B mnemonics associated with long character strings.
Declare arrays and variables used to store custom values for certain mnemonics within Sections 0 and ...
integer, dimension(:), allocatable ivmnem
Custom values for use within Sections 0 and 1 of all future output BUFR messages written to all Fortr...
integer ns01v
Number of custom values stored.
character *8, dimension(:), allocatable cmnem
Section 0 and 1 mnemonics corresponding to ivmnem.
Declare an array used to store a status code for each file ID if an error or other abnormal result oc...
integer, dimension(:), allocatable iscodes
Abnormal status codes.
Declare arrays and variables used to store the internal jump/link table.
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
Declare arrays used to store data values and associated metadata for the current BUFR data subset in ...
integer, dimension(:), allocatable nval
Number of data values in BUFR data subset.
real *8, dimension(:,:), allocatable, target val
Data values.
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
integer, dimension(:,:), allocatable nrfelm
Referenced data value, for data values which refer to a previous data value in the BUFR data subset v...
recursive subroutine status(lunit, lun, il, im)
Check whether a specified Fortran logical unit number is currently connected to the NCEPLIBS-bufr sof...
subroutine msgwrt(lunit, mesg, mgbyt)
Perform final checks and updates on a BUFR message before writing it to a specified Fortran logical u...
subroutine usrtpl(lun, invn, nbmp)
Expand a subset template within internal arrays.
recursive subroutine writsb(lunit)
Write a complete data subset into a BUFR message, for eventual output to logical unit lunit.
subroutine x84(iin8, iout4, nval)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x4884.F90:65