NCEPLIBS-bufr 11.7.1
ufdump.f
Go to the documentation of this file.
1C> @file
2C> @brief Print the contents of a data subset.
3
4C> This subroutine prints a verbose listing of the contents of a data
5C> subset, including all data values and replicated sequences, as well
6C> as the meanings of data values which are code or flag table entries.
7C>
8C> <p>This subroutine is similar to subroutine ufbdmp(), but it prints
9C> different characteristics of each data subset, and in a slightly
10C> different format. However, both subroutines can be useful for
11C> different diagnostic purposes, and both can also be run
12C> interactively to scroll through the contents of a data subset.
13C>
14C> @authors J. Woollen
15C> @authors J. Ator
16C> @date 2002-05-14
17C>
18C> @param[in] LUNIT -- integer: Fortran logical unit number for
19C> BUFR file
20C> @param[in] LUPRT -- integer: Fortran logical unit number for
21C> print output
22C> - 0 = Run interactively, printing to
23C> standard output
24C>
25C> <p>Logical unit LUNIT should have already been opened for
26C> input operations via a previous call to subroutine openbf(), and a
27C> BUFR data subset should have already been read into internal arrays
28C> via a previous call to one of the
29C> [subset-reading subroutines](@ref hierarchy).
30C>
31C> <p>Except when LUPRT = 0, logical unit LUPRT must already be
32C> associated with a filename on the local system, typically via a
33C> Fortran "OPEN" statement. When LUPRT = 0, the subroutine will run
34C> interactively and print to standard output, scrolling 20 lines at
35C> a time and prompting each time whether to quit and return to the
36C> application program (by typing 'q' then '<Enter>') or continue
37C> scrolling (by typing anything else).
38C>
39C> @remarks
40C> - In order for the meanings of code and flag table values to be
41C> included in the output, a previous call to subroutine codflg()
42C> must have been made with argument CF = 'Y'. Otherwise, only the
43C> code and flag table values themselves will be printed.
44C>
45C> <b>Program history log:</b>
46C> | Date | Programmer | Comments |
47C> | -----|------------|----------|
48C> | 2002-05-14 | J. Woollen | Original author |
49C> | 2003-11-04 | J. Woollen | Modified to handle print of character values greater than 8 bytes |
50C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
51C> | 2003-11-04 | D. Keyser | Increased MAXJL from 15000 to 16000; unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally |
52C> | 2004-08-18 | J. Ator | Added fuzziness test and threshold for missing value; added interactive and scrolling capability similar to ufbdmp() |
53C> | 2006-04-14 | J. Ator | Add call to upftbv() for flag tables to get actual bits that were set to generate value |
54C> | 2007-01-19 | J. Ator | Use function ibfms() |
55C> | 2009-03-23 | J. Ator | Add level markers to output for sequences where the replication count is > 1; output all occurrences of long character strings |
56C> | 2012-02-24 | J. Ator | Fix missing check for long character strings |
57C> | 2012-03-02 | J. Ator | Label redefined reference values |
58C> | 2014-12-10 | J. Ator | Use modules instead of COMMON blocks |
59C> | 2015-09-24 | J. Woollen | Print level identifiers for event stacks |
60C> | 2020-08-18 | J. Ator | Improve logic for sequence tracking |
61C> | 2021-09-30 | J. Ator | Replace rjust with Fortran intrinsic adjustr |
62C>
63 SUBROUTINE ufdump(LUNIT,LUPRT)
64
65 USE moda_usrint
66 USE moda_msgcwd
67 USE moda_tababd
68 USE moda_tables
69 USE moda_nrv203
70
71 COMMON /tablef/ cdmf
72
73 CHARACTER*120 CFMEANG
74 CHARACTER*80 FMT
75 CHARACTER*64 DESC
76 CHARACTER*24 UNIT
77 CHARACTER*120 LCHR2
78 CHARACTER*20 LCHR,PMISS
79 CHARACTER*15 NEMO3
80 CHARACTER*10 NEMO,NEMO2,TAGRFE
81 CHARACTER*8 NEMOD
82 CHARACTER*6 NUMB
83 CHARACTER*7 FMTF
84 CHARACTER*8 CVAL
85 CHARACTER*3 TYPE
86 CHARACTER*1 CDMF,TAB,YOU
87 equivalence(rval,cval)
88 real*8 rval
89 LOGICAL TRACK,FOUND,RDRV
90
91 parameter(mxcfdp=5)
92 INTEGER ICFDP(MXCFDP)
93
94 parameter(mxfv=31)
95 integer ifv(mxfv)
96
97 parameter(mxseq=10)
98 INTEGER IDXREP(MXSEQ)
99 INTEGER NUMREP(MXSEQ)
100 CHARACTER*10 SEQNAM(MXSEQ)
101 INTEGER LSQNAM(MXSEQ)
102
103 parameter(mxls=10)
104 CHARACTER*10 LSNEMO(MXLS)
105 INTEGER LSCT(MXLS)
106
107 DATA pmiss /' MISSING'/
108 DATA you /'Y'/
109
110C----------------------------------------------------------------------
111C----------------------------------------------------------------------
112
113 nseq = 0
114 nls = 0
115 lcfmeang = len(cfmeang)
116
117 IF(luprt.EQ.0) THEN
118 luout = 6
119 ELSE
120 luout = luprt
121 ENDIF
122
123C CHECK THE FILE STATUS AND I-NODE
124C --------------------------------
125
126 CALL status(lunit,lun,il,im)
127 IF(il.EQ.0) GOTO 900
128 IF(il.GT.0) GOTO 901
129 IF(im.EQ.0) GOTO 902
130 IF(inode(lun).NE.inv(1,lun)) GOTO 903
131
132 WRITE(luout,fmt='(/,2A,/)') 'MESSAGE TYPE ',tag(inode(lun))
133
134C DUMP THE CONTENTS OF MODULE USRINT FOR UNIT LUNIT
135C -------------------------------------------------
136
137C If code/flag table details are being printed, and if this is the
138C first subset of a new message, then make sure the appropriate
139C master tables have been read in to memory for this message.
140
141 IF(cdmf.EQ.'Y' .AND. nsub(lun).EQ.1) itmp = ireadmt(lun)
142
143 DO nv=1,nval(lun)
144 IF(luprt.EQ.0 .AND. mod(nv,20).EQ.0) THEN
145
146C When LUPRT=0, the output will be scrolled, 20 elements at a time
147C ----------------------------------------------------------------
148
149 print*,'(<enter> for MORE, q <enter> to QUIT)'
150 READ(5,'(A1)') you
151
152C If the terminal enters "q" followed by "<enter>" after the prompt
153C "(<enter> for MORE, q <enter> to QUIT)", scrolling will end and the
154C subroutine will return to the calling program
155C -------------------------------------------------------------------
156
157 IF(you.EQ.'q') THEN
158 print*
159 print*,'==> You have chosen to stop the dumping of this subset'
160 print*
161 GOTO 100
162 ENDIF
163 ENDIF
164
165 node = inv(nv,lun)
166 nemo = tag(node)
167 ityp = itp(node)
168 TYPE = typ(node)
169
170 IF(ityp.GE.1.AND.ityp.LE.3) THEN
171 CALL nemtab(lun,nemo,idn,tab,n)
172 numb = tabb(n,lun)(1:6)
173 desc = tabb(n,lun)(16:70)
174 unit = tabb(n,lun)(71:94)
175 rval = val(nv,lun)
176 ENDIF
177
178 IF((ityp.EQ.0).OR.(ityp.EQ.1)) THEN
179
180C Sequence descriptor or delayed descriptor replication factor
181
182 IF((type.EQ.'REP').OR.(type.EQ.'DRP').OR.
183 . (type.EQ.'DRB').OR.(type.EQ.'DRS')) THEN
184
185C Print the number of replications
186
187 nseq = nseq+1
188 IF(nseq.GT.mxseq) GOTO 904
189 IF(type.EQ.'REP') THEN
190 numrep(nseq) = irf(node)
191 ELSE
192 numrep(nseq) = nint(rval)
193 ENDIF
194 CALL strsuc(nemo,nemo2,lnm2)
195 fmt = '(11X,A,I6,1X,A)'
196 WRITE(luout,fmt) nemo2(1:lnm2), numrep(nseq), 'REPLICATIONS'
197
198C How many times is this sequence replicated?
199
200 IF(numrep(nseq).GT.1) THEN
201
202C Track the sequence
203
204 seqnam(nseq) = nemo2
205 lsqnam(nseq) = lnm2
206 idxrep(nseq) = 1
207 ELSE
208
209C Don't bother
210
211 nseq = nseq-1
212 ENDIF
213 ELSEIF( ((type.EQ.'SEQ').OR.(type.EQ.'RPC').OR.(type.EQ.'RPS'))
214 . .AND. (nseq.GT.0) ) THEN
215
216C Is this one of the sequences being tracked?
217
218 ii = nseq
219 track = .false.
220 CALL strsuc(nemo,nemo2,lnm2)
221 DO WHILE ((ii.GE.1).AND.(.NOT.track))
222 IF(nemo2(1:lnm2).EQ.seqnam(ii)(2:lsqnam(ii)-1)) THEN
223 track = .true.
224
225C Mark this level in the output
226
227 fmt = '(4X,A,2X,A,2X,A,I6,2X,A)'
228 WRITE(luout,fmt) '++++++', nemo2(1:lnm2),
229 . 'REPLICATION #', idxrep(ii), '++++++'
230 IF(idxrep(ii).LT.numrep(ii)) THEN
231
232C There are more levels to come
233
234 idxrep(ii) = idxrep(ii)+1
235 ELSE
236
237C This was the last level for this sequence, so stop
238C tracking it
239
240 nseq = nseq-1
241 ENDIF
242 ELSE
243 ii = ii-1
244 ENDIF
245 ENDDO
246 ENDIF
247 ELSEIF(ityp.EQ.2) THEN
248
249C Other numeric value
250
251C First check if this node contains a redefined reference
252C value. If so, modify the DESC field to label it as such.
253
254 jj = 1
255 rdrv = .false.
256 DO WHILE ((jj.LE.nnrv).AND.(.NOT.rdrv))
257 IF (node.EQ.inodnrv(jj)) THEN
258 rdrv = .true.
259 desc = 'New reference value for ' // nemo
260 unit = ' '
261 ELSE
262 jj = jj + 1
263 ENDIF
264 ENDDO
265
266C Check if this element refers to another element via a bitmap.
267C If so, modify the DESC field to identify the referred element.
268
269 nrfe = nrfelm(nv,lun)
270 IF(nrfe.GT.0) THEN
271 tagrfe = tag(inv(nrfe,lun))
272 jj = 48
273 DO WHILE((jj.GE.1).AND.(desc(jj:jj).EQ.' '))
274 jj = jj - 1
275 ENDDO
276 IF(jj.LE.33) desc(jj+1:jj+15) = ' for ' // tagrfe
277 ENDIF
278
279C Now print the value
280
281 IF(ibfms(rval).NE.0) THEN
282
283C The value is "missing".
284
285 fmt = '(A6,2X,A10,2X,A20,2X,A24,6X,A48)'
286 WRITE(luout,fmt) numb,nemo,pmiss,unit,desc
287 ELSE
288 fmt = '(A6,2X,A10,2X,F20.00,2X,A24,6X,A48)'
289
290C Based upon the corresponding scale factor, select an
291C appropriate format for the printing of this value.
292
293 WRITE(fmt(19:20),'(I2)') max(1,isc(node))
294 IF(unit(1:4).EQ.'FLAG') THEN
295
296C Print a listing of the bits corresponding to
297C this value.
298
299 CALL upftbv(lunit,nemo,rval,mxfv,ifv,nifv)
300 IF(nifv.GT.0) THEN
301 unit(11:11) = '('
302 ipt = 12
303 DO ii=1,nifv
304 isz = isize(ifv(ii))
305 WRITE(fmtf,'(A2,I1,A4)') '(I', isz, ',A1)'
306 IF((ipt+isz).LE.24) THEN
307 WRITE(unit(ipt:ipt+isz),fmtf) ifv(ii), ','
308 ipt = ipt + isz + 1
309 ELSE
310 unit(12:23) = 'MANY BITS ON'
311 ipt = 25
312 ENDIF
313 ENDDO
314 unit(ipt-1:ipt-1) = ')'
315 ENDIF
316 ENDIF
317
318 WRITE(luout,fmt) numb,nemo,rval,unit,desc
319
320 IF( (unit(1:4).EQ.'FLAG' .OR. unit(1:4).EQ.'CODE') .AND.
321 . (cdmf.EQ.'Y') ) THEN
322
323C Print the meanings of the code and flag values.
324
325 fmt = '(31X,I8,A,A)'
326 IF(unit(1:4).EQ.'CODE') THEN
327 nifv = 1
328 ifv(nifv) = nint(rval)
329 ENDIF
330 DO ii=1,nifv
331 icfdp(1) = (-1)
332 ifvd = (-1)
333 CALL srchtbf(idn,ifv(ii),icfdp,mxcfdp,ifvd,
334 . cfmeang,lcfmeang,lcfmg,iersf)
335 IF(iersf.EQ.0) THEN
336 WRITE(luout,fmt) ifv(ii),' = ',cfmeang(1:lcfmg)
337 ELSEIF(iersf.LT.0) THEN
338 WRITE(luout,fmt) ifv(ii),' = ',
339 . '***THIS IS AN ILLEGAL/UNDEFINED VALUE***'
340 ELSE
341
342C The meaning of this value is dependent on the
343C value of another mnemonic in the report. Look for
344C that other mnemonic within the report and then use
345C it and its associated value to retrieve and print
346C the proper meaning from the code/flag tables.
347
348 ierft = (-1)
349 jj = 0
350 DO WHILE((jj.LT.iersf).AND.(ierft.LT.0))
351 jj = jj + 1
352 CALL numtbd(lun,icfdp(jj),nemod,tab,ierbd)
353 IF((ierbd.GT.0).AND.(tab.EQ.'B')) THEN
354 CALL fstag(lun,nemod,-1,nv,nout,ierft)
355 ENDIF
356 ENDDO
357 IF(ierft.EQ.0) THEN
358 ifvd = nint(val(nout,lun))
359 IF(jj.GT.1) icfdp(1) = icfdp(jj)
360 CALL srchtbf(idn,ifv(ii),icfdp,mxcfdp,ifvd,
361 . cfmeang,lcfmeang,lcfmg,iersf)
362 IF(iersf.EQ.0) THEN
363 WRITE(luout,fmt) ifv(ii),' = ',
364 . cfmeang(1:lcfmg)
365 ENDIF
366 ENDIF
367 ENDIF
368 ENDDO
369 ENDIF
370 ENDIF
371 ELSEIF(ityp.EQ.3) THEN
372
373C Character (CCITT IA5) value
374
375 nchr = ibt(node)/8
376
377 IF(ibfms(rval).NE.0) THEN
378 lchr = pmiss
379 ELSE IF(nchr.LE.8) THEN
380 lchr = cval
381 ELSE
382
383C Track the number of occurrences of this long character string, so
384C that we can properly output each one.
385
386 ii = 1
387 found = .false.
388 DO WHILE((ii.LE.nls).AND.(.NOT.found))
389 IF(nemo.EQ.lsnemo(ii)) THEN
390 found = .true.
391 ELSE
392 ii = ii + 1
393 ENDIF
394 ENDDO
395
396 IF(.NOT.found) THEN
397 nls = nls+1
398 IF(nls.GT.mxls) GOTO 905
399 lsnemo(nls) = nemo
400 lsct(nls) = 1
401 nemo3 = nemo
402 ELSE
403 CALL strsuc(nemo,nemo3,lnm3)
404 lsct(ii) = lsct(ii) + 1
405 WRITE(fmtf,'(A,I1,A)') '(2A,I', isize(lsct(ii)), ')'
406 WRITE(nemo3,fmtf) nemo(1:lnm3), '#', lsct(ii)
407 ENDIF
408
409 CALL readlc(lunit,lchr2,nemo3)
410 IF (icbfms(lchr2,nchr).NE.0) THEN
411 lchr = pmiss
412 ELSE
413 lchr = lchr2(1:20)
414 ENDIF
415 ENDIF
416
417 IF ( nchr.LE.20 .OR. lchr.EQ.pmiss ) THEN
418 lchr = adjustr(lchr)
419 fmt = '(A6,2X,A10,2X,A20,2X,"(",I2,")",A24,2X,A48)'
420 WRITE(luout,fmt) numb,nemo,lchr,nchr,unit,desc
421 ELSE
422 fmt = '(A6,2X,A10,2X,A,2X,"(",I3,")",A23,2X,A48)'
423 WRITE(luout,fmt) numb,nemo,lchr2(1:nchr),nchr,unit,desc
424 ENDIF
425 ENDIF
426
427 ENDDO
428
429 WRITE(luout,3)
4303 FORMAT(/' >>> END OF SUBSET <<< '/)
431
432C EXITS
433C -----
434
435100 RETURN
436900 CALL bort('BUFRLIB: UFDUMP - INPUT BUFR FILE IS CLOSED, IT '//
437 . 'MUST BE OPEN FOR INPUT')
438901 CALL bort('BUFRLIB: UFDUMP - INPUT BUFR FILE IS OPEN FOR '//
439 . 'OUTPUT, IT MUST BE OPEN FOR INPUT')
440902 CALL bort('BUFRLIB: UFDUMP - A MESSAGE MUST BE OPEN IN INPUT '//
441 . 'BUFR FILE, NONE ARE')
442903 CALL bort('BUFRLIB: UFDUMP - LOCATION OF INTERNAL TABLE FOR '//
443 . 'INPUT BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN '//
444 . 'INTERNAL SUBSET ARRAY')
445904 CALL bort('BUFRLIB: UFDUMP - MXSEQ OVERFLOW')
446905 CALL bort('BUFRLIB: UFDUMP - MXLS OVERFLOW')
447 END
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
void srchtbf(f77int *, f77int *, f77int *, f77int *, f77int *, char *, f77int *, f77int *, f77int *)
This subroutine searches for a specified FXY number and associated value (code figure or bit number) ...
Definition: srchtbf.c:74
subroutine fstag(LUN, UTAG, NUTAG, NIN, NOUT, IRET)
THIS SUBROUTINE FINDS THE (NUTAG)th OCCURRENCE OF MNEMONIC UTAG WITHIN THE CURRENT OVERALL SUBSET DEF...
Definition: fstag.f:41
integer function ibfms(R8VAL)
This function provides a handy way to check whether a real*8 data value returned from a previous call...
Definition: ibfms.f:39
integer function icbfms(STR, LSTR)
This function provides a handy way to check whether a character string returned from a previous call ...
Definition: icbfms.f:32
integer function ireadmt(LUN)
This function checks the most recent BUFR message that was read via a call to one of the message-read...
Definition: ireadmt.f:43
integer function isize(NUM)
THIS FUNCTION COMPUTES AND RETURNS THE NUMBER OF CHARACTERS NEEDED TO ENCODE THE INPUT INTEGER NUM AS...
Definition: isize.f:28
This module contains array and variable declarations for use with any 2-03-YYY (change reference valu...
Definition: moda_nrv203.F:15
integer nnrv
Number of entries in the jump/link table which contain new reference values (up to a maximum of MXNRV...
Definition: moda_nrv203.F:56
integer, dimension(:), allocatable inodnrv
Entries within jump/link table which contain new reference values.
Definition: moda_nrv203.F:60
This module contains array and variable declarations used to store DX BUFR tables internally for mult...
Definition: moda_tababd.F:10
character *128, dimension(:,:), allocatable tabb
Table B entries for each internal I/O stream.
Definition: moda_tababd.F:59
This module contains array and variable declarations used to store the internal jump/link table.
Definition: moda_tables.F:13
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
Definition: moda_tables.F:141
integer, dimension(:), allocatable isc
Scale factors corresponding to tag and typ:
Definition: moda_tables.F:140
character *3, dimension(:), allocatable typ
Type indicators corresponding to tag:
Definition: moda_tables.F:133
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
Definition: moda_tables.F:138
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
Definition: moda_tables.F:132
integer, dimension(:), allocatable irf
Reference values corresponding to tag and typ:
Definition: moda_tables.F:139
subroutine nemtab(LUN, NEMO, IDN, TAB, IRET)
This subroutine returns information about a descriptor from the internal DX BUFR tables,...
Definition: nemtab.f:45
subroutine numtbd(LUN, IDN, NEMO, TAB, IRET)
This subroutine searches for a descriptor within Table B and Table D of the internal DX BUFR tables.
Definition: numtbd.f:36
subroutine readlc(LUNIT, CHR, STR)
This subroutine reads a long character string (greater than 8 bytes) from a data subset.
Definition: readlc.f:59
subroutine status(LUNIT, LUN, IL, IM)
This subroutine checks whether a specified Fortran logical unit number is currently connected to the ...
Definition: status.f:56
subroutine strsuc(STR1, STR2, LENS)
This subroutine removes leading and trailing blanks from a character string.
Definition: strsuc.f:24
subroutine ufdump(LUNIT, LUPRT)
This subroutine prints a verbose listing of the contents of a data subset, including all data values ...
Definition: ufdump.f:64
subroutine upftbv(LUNIT, NEMO, VAL, MXIB, IBIT, NIB)
Given a Table B mnemonic with flag table units and a corresponding numerical data value,...
Definition: upftbv.f:38