NCEPLIBS-bufr  12.0.0
ufbtam.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Read one or more data values from every data subset in
3 C> internal arrays
4 C>
5 C> @author J. Woollen @date 1994-01-06
6 
7 C> This subroutine reads through every data subset in internal arrays
8 C> and returns one or more specified data values from each subset.
9 C>
10 C> This provides a useful way to scan the ranges of one or more
11 C> specified data values across all of the data subsets in the
12 C> internal arrays. It is similar to subroutine ufbtab(), except
13 C> that ufbtab() works on data subsets in a BUFR file.
14 C>
15 C> It is the user's responsibility to ensure that TAB is dimensioned
16 C> sufficiently large enough to accommodate the number of data values
17 C> that are to be read from the internal arrays. Specifically, each row of
18 C> TAB will contain the data values read from a different data subset,
19 C> so the value I2 must be at least as large as the total number of data
20 C> subsets in the internal arrays.
21 C>
22 C> The internal arrays must have already been populated via a previous
23 C> call to subroutine ufbmem().
24 C>
25 C> There are a few additional special mnemonics that can be
26 C> included within STR when calling this subroutine, and which in turn
27 C> will result in special information being returned within the
28 C> corresponding location in TAB:
29 C> - IREC - returns the number of the BUFR message within the
30 C> internal arrays (counting from the beginning of the
31 C> internal arrays) in which the current data subset resides.
32 C> - ISUB - returns the number of the current data subset within
33 C> the BUFR message pointed to by IREC, counting from
34 C> the beginning of the message.
35 C> - ITBL - returns the number of the DX BUFR table that is
36 C> in scope for the current data subset.
37 C>
38 C> This subroutine will not work on compressed data subsets.
39 C>
40 C> @param[out] TAB -- real*8(*,*): Data values.
41 C> @param[in] I1 -- integer: First dimension of TAB as allocated
42 C> within the calling program.
43 C> @param[in] I2 -- integer: Second dimension of TAB as allocated
44 C> within the calling program.
45 C> @param[out] IRET -- integer: Number of data subsets in internal arrays.
46 C> @param[in] STR -- character*(*): String of blank-separated
47 C> Table B mnemonics, in one-to-one correspondence
48 C> with the number of data values that will be read
49 C> from each data subset within the first dimension of
50 C> TAB (see [DX BUFR Tables](@ref dfbftab) for further
51 C> information about Table B mnemonics).
52 C>
53 C> @author J. Woollen @date 1994-01-06
54  RECURSIVE SUBROUTINE ufbtam(TAB,I1,I2,IRET,STR)
55 
56  USE modv_bmiss
57  USE modv_im8b
58 
59  USE moda_usrint
60  USE moda_msgcwd
61  USE moda_bitbuf
62  USE moda_msgmem
63  USE moda_tables
64 
65  COMMON /usrstr/ nnod,ncon,nods(20),nodc(10),vals(10),kons(10)
66  COMMON /quiet / iprt
67 
68  CHARACTER*(*) str
69  CHARACTER*128 bort_str,errstr
70  CHARACTER*10 tgs(100)
71  CHARACTER*8 subset,cval
72  equivalence(cval,rval)
73  integer*8 mps,ival
74  real*8 tab(i1,i2),rval,ups
75 
76  DATA maxtg /100/
77 
78 C-----------------------------------------------------------------------
79  mps(node) = 2_8**(ibt(node))-1
80 C-----------------------------------------------------------------------
81 
82 C CHECK FOR I8 INTEGERS
83 C ---------------------
84 
85  IF(im8b) THEN
86  im8b=.false.
87 
88  CALL x84(i1,my_i1,1)
89  CALL x84(i2,my_i2,1)
90  CALL ufbtam(tab,my_i1,my_i2,iret,str)
91  CALL x48(iret,iret,1)
92 
93  im8b=.true.
94  RETURN
95  ENDIF
96 
97  iret = 0
98 
99  IF(msgp(0).EQ.0) GOTO 100
100 
101  DO j=1,i2
102  DO i=1,i1
103  tab(i,j) = bmiss
104  ENDDO
105  ENDDO
106 
107 C CHECK FOR SPECIAL TAGS IN STRING
108 C --------------------------------
109 
110  CALL parstr(str,tgs,maxtg,ntg,' ',.true.)
111  irec = 0
112  isub = 0
113  itbl = 0
114  DO i=1,ntg
115  IF(tgs(i).EQ.'IREC') irec = i
116  IF(tgs(i).EQ.'ISUB') isub = i
117  IF(tgs(i).EQ.'ITBL') itbl = i
118  ENDDO
119 
120 C READ A MESSAGE AND PARSE A STRING
121 C ---------------------------------
122 
123  CALL status(munit,lun,il,im)
124 
125  DO imsg=1,msgp(0)
126  CALL rdmemm(imsg,subset,jdate,mret)
127  IF(mret.LT.0) GOTO 900
128 
129  CALL string(str,lun,i1,0)
130  IF(irec.GT.0) nods(irec) = 0
131  IF(isub.GT.0) nods(isub) = 0
132  IF(itbl.GT.0) nods(itbl) = 0
133 
134 C PROCESS ALL THE SUBSETS IN THE MEMORY MESSAGE
135 C ---------------------------------------------
136 
137  DO WHILE (nsub(lun).LT.msub(lun))
138  IF(iret+1.GT.i2) GOTO 99
139  iret = iret+1
140 
141  DO i=1,nnod
142  nods(i) = abs(nods(i))
143  ENDDO
144 
145  CALL usrtpl(lun,1,1)
146  mbit = mbyt(lun)*8+16
147  nbit = 0
148  n = 1
149 
150 20 IF(n+1.LE.nval(lun)) THEN
151  n = n+1
152  node = inv(n,lun)
153  mbit = mbit+nbit
154  nbit = ibt(node)
155  IF(itp(node).EQ.1) THEN
156  CALL upb8(ival,nbit,mbit,mbay(1,lun))
157  nbmp=int(ival)
158  CALL usrtpl(lun,n,nbmp)
159  ENDIF
160  DO i=1,nnod
161  IF(nods(i).EQ.node) THEN
162  IF(itp(node).EQ.1) THEN
163  CALL upb8(ival,nbit,mbit,mbay(1,lun))
164  tab(i,iret) = ival
165  ELSEIF(itp(node).EQ.2) THEN
166  CALL upb8(ival,nbit,mbit,mbay(1,lun))
167  IF(ival.LT.mps(node)) tab(i,iret) = ups(ival,node)
168  ELSEIF(itp(node).EQ.3) THEN
169  cval = ' '
170  kbit = mbit
171  CALL upc(cval,nbit/8,mbay(1,lun),kbit,.true.)
172  tab(i,iret) = rval
173  ENDIF
174  nods(i) = -nods(i)
175  GOTO 20
176  ENDIF
177  ENDDO
178  DO i=1,nnod
179  IF(nods(i).GT.0) GOTO 20
180  ENDDO
181  ENDIF
182 
183 C UPDATE THE SUBSET POINTERS BEFORE NEXT READ
184 C -------------------------------------------
185 
186  ibit = mbyt(lun)*8
187  CALL upb(nbyt,16,mbay(1,lun),ibit)
188  mbyt(lun) = mbyt(lun) + nbyt
189  nsub(lun) = nsub(lun) + 1
190  IF(irec.GT.0) tab(irec,iret) = nmsg(lun)
191  IF(isub.GT.0) tab(isub,iret) = nsub(lun)
192  IF(itbl.GT.0) tab(itbl,iret) = ldxts
193  ENDDO
194 
195  ENDDO
196 
197  GOTO 200
198 
199 C EMERGENCY ROOM TREATMENT FOR ARRAY OVERFLOW
200 C -------------------------------------------
201 
202 99 CALL rdmemm(0,subset,jdate,mret)
203  nrep = 0
204  DO imsg=1,msgp(0)
205  CALL rdmemm(imsg,subset,jdate,mret)
206  IF(mret.LT.0) GOTO 900
207  nrep = nrep+nmsub(munit)
208  ENDDO
209  IF(iprt.GE.0) THEN
210  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
211  WRITE ( unit=errstr, fmt='(A,A,I8,A,A)' )
212  . 'BUFRLIB: UFBTAM - THE NO. OF DATA SUBSETS IN MEMORY ',
213  . .GT.'IS LIMIT OF ', i2, ' IN THE 3RD ARG. (INPUT) - ',
214  . 'INCOMPLETE READ'
215  CALL errwrt(errstr)
216  WRITE ( unit=errstr, fmt='(A,I8,A,I8,A)' )
217  . '>>>UFBTAM STORED ', iret, ' REPORTS OUT OF ', nrep, '<<<'
218  CALL errwrt(errstr)
219  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
220  CALL errwrt(' ')
221  ENDIF
222 
223 C RESET THE MEMORY FILE
224 C ---------------------
225 
226 200 CALL rdmemm(0,subset,jdate,mret)
227 
228 C EXITS
229 C -----
230 
231 100 RETURN
232 900 WRITE(bort_str,'("BUFRLIB: UFBTAM - HIT END-OF-FILE READING '//
233  . 'MESSAGE NUMBER",I5," IN INTERNAL MEMORY")') imsg
234  CALL bort(bort_str)
235  END
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:36
This module contains array and variable declarations used to store BUFR messages internally for multi...
integer ibit
Bit pointer within IBAY.
integer, dimension(:,:), allocatable mbay
Current BUFR message for each internal I/O stream.
integer, dimension(:), allocatable mbyt
Length (in bytes) of current BUFR message for each internal I/O stream.
This module contains declarations for arrays used to store information about the current BUFR message...
integer, dimension(:), allocatable nmsg
Current message pointer within logical unit.
integer, dimension(:), allocatable msub
Total number of data subsets in message.
integer, dimension(:), allocatable nsub
Current subset pointer within message.
This module contains array and variable declarations used to store the contents of one or more BUFR f...
integer, dimension(:), allocatable msgp
Pointers to the beginning of each message within msgs (up to a maximum of MAXMSG, and where array ele...
integer munit
Fortran logical unit number for use in accessing contents of BUFR files within internal memory.
integer ldxts
Number of DX BUFR table that is currently in scope, depending on which BUFR message within msgs is cu...
This module contains array and variable declarations used to store the internal jump/link table.
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
This module contains declarations for arrays used to store data values and associated metadata for th...
integer, dimension(:), allocatable nval
Number of data values in BUFR data subset.
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
This module declares and initializes the BMISS variable.
Definition: modules_vars.F90:9
real *8, public bmiss
Current placeholder value to represent "missing" data when reading from or writing to BUFR files; thi...
This module declares and initializes the IM8B variable.
logical, public im8b
Status indicator to keep track of whether all future calls to BUFRLIB subroutines and functions from ...
recursive function nmsub(LUNIT)
This function returns the total number of data subsets available within the BUFR message that was mos...
Definition: nmsub.f:22
subroutine parstr(STR, TAGS, MTAG, NTAG, SEP, LIMIT80)
Parse a string containing one or more substrings into an array of substrings.
Definition: parstr.f:24
recursive subroutine rdmemm(IMSG, SUBSET, JDATE, IRET)
This subroutine reads a specified BUFR message from internal arrays in memory, so that it is now in s...
Definition: rdmemm.f:40
recursive subroutine status(LUNIT, LUN, IL, IM)
Check whether a specified Fortran logical unit number is currently connected to the NCEPLIBS-bufr sof...
Definition: status.f:36
subroutine string(STR, LUN, I1, IO)
This subroutine checks to see if a user-specified character string is in the string cache (arrays in ...
Definition: string.f:28
recursive subroutine ufbtam(TAB, I1, I2, IRET, STR)
This subroutine reads through every data subset in internal arrays and returns one or more specified ...
Definition: ufbtam.f:55
subroutine upb8(nval, nbits, ibit, ibay)
This subroutine decodes an 8-byte integer value from within a specified number of bits of an integer ...
Definition: upb8.f:26
subroutine upb(NVAL, NBITS, IBAY, IBIT)
This subroutine decodes an integer value from within a specified number of bits of an integer array,...
Definition: upb.f:28
subroutine upc(CHR, NCHR, IBAY, IBIT, CNVNULL)
Decode a character string from an integer array.
Definition: upc.f:32
real *8 function ups(IVAL, NODE)
This function unpacks a real*8 user value from a packed BUFR integer by applying the proper scale and...
Definition: ups.f:22
subroutine usrtpl(LUN, INVN, NBMP)
Store the subset template into internal arrays.
Definition: usrtpl.f:22
subroutine x48(IIN4, IOUT8, NVAL)
Encode one or more 4-byte integer values as 8-byte integer values.
Definition: x48.F:19
subroutine x84(IIN8, IOUT4, NVAL)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x84.F:19