NCEPLIBS-bufr  12.1.0
debufr.F90
Go to the documentation of this file.
1 
5 
12 
14  character(len=:), allocatable :: tbldir_f
15 
17  integer ltbd
18 
20  integer ludx
21 end module share_table_info
22 
54 subroutine fdebufr_c ( ofile, lenof, tbldir, lentd, tblfil, lentf, prmstg, lenps, basic, forcemt, cfms ) &
55  bind( c, name = 'fdebufr_f' )
56 
57  use iso_c_binding
58  use bufr_interface
60 
61  implicit none
62 
63  integer, parameter :: mxbf = 2500000
64  integer, parameter :: mxbfd4 = mxbf/4
65  integer, parameter :: mxds3 = 500
66  integer, parameter :: mxprms = 20
67 
68  character(kind=c_char,len=1), intent(in) :: ofile(*), tbldir(*), tblfil(*), prmstg(*), basic, forcemt, cfms
69 
70  character(len=:), allocatable :: ofile_f, tblfil_f, prmstg_f
71 
72  integer(c_int), value, intent(in) :: lenof, lentd, lentf, lenps
73 
74  integer*4 :: isetprm, idxmsg, iupbs01, iupbs3, ireadsb
75  integer*4 :: nbyt, ierr
76 
77  logical exists
78 
79  character*120 cmorgc, cmgses, cmmtyp, cmmsbt, cmmsbti
80  character*20 ptag ( mxprms ), pvtag(2), cprmnm
81  character*8 cmgtag
82  character*6 cds3 ( mxds3 )
83  character opened, usemt, bfmg ( mxbf ), basic_f, forcemt_f, cfms_f
84 
85  integer ibfmg ( mxbfd4 ), lunit, nmsg, nsub, nsubt, ii, jj, nds3, nptag, npvtag, ipval, lcprmnm, ier, imgdt, ierme, &
86  iogce, lcmorgc, ierorgc, igses, lcmgses, iergses, iryr, irmo, irdy, irhr, irmi, irtret, &
87  mtyp, lcmmtyp, iermtyp, msbt, lcmmsbt, iermsbt, msbti, lcmmsbti, iermsbti, iersn
88 
89  equivalence( bfmg(1), ibfmg(1) )
90 
91  ! Initialize the values in the Share_Table_Info module.
92 
93  ludx = 93
94  ltbd = lentd
95  allocate( character(len=lentd) :: tbldir_f )
96  tbldir_f = transfer( tbldir(1:lentd), tbldir_f )
97 
98  ! Copy the other input C strings into Fortran strings.
99 
100  allocate( character(len=lenof) :: ofile_f )
101  ofile_f = transfer( ofile(1:lenof), ofile_f )
102  allocate( character(len=lentf) :: tblfil_f )
103  tblfil_f = transfer( tblfil(1:lentf), tblfil_f )
104  allocate( character(len=lenps) :: prmstg_f )
105  prmstg_f = transfer( prmstg(1:lenps), prmstg_f )
106  basic_f = transfer( basic(1:1), basic_f )
107  forcemt_f = transfer( forcemt(1:1), forcemt_f )
108  cfms_f = transfer( cfms(1:1), cfms_f )
109 
110  ! Open the output file.
111 
112  open ( unit = 51, file = ofile_f )
113 
114  ! Note that in the below open statement we just need to specify a dummy placeholder file.
115 
116  lunit = 92
117  open ( unit = lunit, file = '/dev/null' )
118 
119  call datelen ( 10 )
120 
121  ! Initialize some other values.
122 
123  nmsg = 0
124  nsubt = 0
125 
126  opened = 'N'
127  usemt = 'N'
128 
129  do while ( .true. )
130 
131  ! Get the next message from the input BUFR file.
132 
133  call crbmg_c ( bfmg, mxbf, nbyt, ierr )
134 
135  if ( ierr /= 0 ) then
136 
137  if ( ierr == -1 ) then
138  write ( 51, fmt = '( /, A, I7, A, I9, A )') 'Reached end of BUFR file; it contained a total of', nmsg, &
139  ' messages and', nsubt, ' subsets'
140  else
141  write ( 51, fmt = '( /, A, I4 )' ) 'Error while reading BUFR file; the return code from CRBMG = ', ierr
142  end if
143 
144  if ( ( basic_f == 'N' ) .and. ( opened == 'Y' ) ) then
145  write (51, fmt = '( /, A, / )' ) 'Here is the DX table that was generated:'
146  call dxdump ( lunit, 51 )
147  end if
148 
149  ! Close the output file, deallocate memory, and return.
150 
151  close ( 51 )
152  deallocate ( ofile_f )
153  deallocate ( tbldir_f )
154  deallocate ( tblfil_f )
155  deallocate ( prmstg_f )
156  return
157  end if
158 
159  if ( opened == 'N' ) then
160 
161  if ( ( isetprm( 'MAXCD', mxds3 ) /= 0 ) .or. ( isetprm( 'MXMSGL', mxbf ) /= 0 ) .or. &
162  ( isetprm( 'MAXSS', 300000 ) /= 0 ) .or. ( isetprm( 'NFILES', 2 ) /= 0 ) ) then
163  print *, 'Error: Bad return from isetprm'
164  return
165  end if
166 
167  ! Process any dynamic allocation parameters that were passed in on the command line.
168 
169  if ( prmstg_f(1:8) /= 'NULLPSTG' ) then
170  call parstr ( prmstg_f, ptag, mxprms, nptag, ',', .false. )
171  if ( nptag > 0 ) then
172  do ii = 1, nptag
173  call parstr ( ptag(ii), pvtag, 2, npvtag, '=', .false. )
174  if ( npvtag == 2 ) then
175  call strsuc ( pvtag(1), cprmnm, lcprmnm )
176  call strnum ( pvtag(2), ipval, iersn )
177  if ( ( lcprmnm > 0 ) .and. ( iersn /= -1 ) ) then
178  if ( isetprm( cprmnm(1:lcprmnm), ipval ) /= 0 ) then
179  print *, 'Error: Bad return from isetprm for parameter: ', cprmnm(1:lcprmnm)
180  return
181  end if
182  end if
183  end if
184  end do
185  end if
186  end if
187 
188  ! Decide how to process the file.
189 
190  if ( ( idxmsg( ibfmg ) == 1 ) .and. ( forcemt_f == 'N' ) ) then
191 
192  ! The first message in the file is a DX dictionary message, so assume there's an embedded table at the
193  ! front of the file, and use this table to decode it.
194 
195  call openbf ( lunit, 'INUL', lunit )
196  else if ( ( tblfil_f(1:8) /= 'NULLFILE' ) .and. ( forcemt_f == 'N' ) ) then
197 
198  ! A DX dictionary tables file was specified on the command line, so use it to decode the BUFR file.
199 
200  inquire ( file = tblfil_f, exist = exists )
201  if ( .not. exists ) then
202  print *, 'Error: Could not find file ', tblfil_f
203  return
204  end if
205  open ( unit = 91, file = tblfil_f, iostat = ier )
206  if ( ier /= 0 ) then
207  print *, 'Error: Could not open file ', tblfil_f
208  return
209  endif
210  call openbf ( lunit, 'IN', 91 )
211  else
212 
213  ! Decode the file using the master tables in tbldir_f.
214 
215  usemt = 'Y'
216  call openbf ( lunit, 'SEC3', lunit )
217  end if
218 
219  opened = 'Y'
220 
221  call mtinfo ( tbldir_f, 90, 91 )
222  if ( cfms_f == 'Y' ) call codflg ( 'Y' )
223  end if
224 
225  if ( basic_f == 'N' ) then
226 
227  ! Pass the message to the decoder.
228 
229  call readerme ( ibfmg, lunit, cmgtag, imgdt, ierme )
230  end if
231 
232  ! If this is a DX dictionary message, then don't generate any output unless master tables are being used for decoding.
233 
234  if ( ( idxmsg( ibfmg ) /= 1 ) .or. ( usemt == 'Y' ) ) then
235 
236  nmsg = nmsg + 1
237 
238  write ( 51, fmt = '( /, A, I7 )' ) 'Found BUFR message #', nmsg
239 
240  ! Decode and output the data from Section 0.
241 
242  write ( 51, fmt= '( /, A, I9 )' ) ' Message length: ', iupbs01( ibfmg, 'LENM' )
243  write ( 51, fmt= '( A, I4 )' ) ' Section 0 length: ', iupbs01( ibfmg, 'LEN0' )
244  write ( 51, fmt= '( A, I4 )' ) ' BUFR edition: ', iupbs01( ibfmg, 'BEN' )
245 
246  ! Decode and output the data from Section 1.
247 
248  write ( 51, fmt= '( /, A, I4 )' ) ' Section 1 length: ', iupbs01( ibfmg, 'LEN1' )
249  write ( 51, fmt= '( A, I4 )' ) ' Master table: ', iupbs01( ibfmg, 'BMT' )
250 
251  iogce = iupbs01( ibfmg, 'OGCE' )
252  igses = iupbs01( ibfmg, 'GSES' )
253  if ( ( basic_f == 'Y' ) .or. ( cfms_f == 'N' ) ) then
254  write ( 51, fmt= '( A, I5 )' ) ' Originating center: ', iogce
255  write ( 51, fmt= '( A, I4 )' ) ' Originating subcenter: ', igses
256  else
257  call getcfmng ( lunit, 'ORIGC', iogce, ' ', -1, cmorgc, lcmorgc, ierorgc )
258  if ( ierorgc == 0 ) then
259  write ( 51, fmt= '( A, I5, 3A )' ) ' Originating center: ', iogce, ' (= ', cmorgc(1:lcmorgc), ')'
260  else
261  write ( 51, fmt= '( A, I5 )' ) ' Originating center: ', iogce
262  end if
263  call getcfmng ( lunit, 'GSES', igses, 'ORIGC', iogce, cmgses, lcmgses, iergses )
264  if ( iergses == 0 ) then
265  write ( 51, fmt= '( A, I4, 3A )' ) ' Originating subcenter: ', igses, ' (= ', cmgses(1:lcmgses), ')'
266  else
267  write ( 51, fmt= '( A, I4 )' ) ' Originating subcenter: ', igses
268  end if
269  end if
270 
271  write ( 51, fmt= '( A, I4 )' ) ' Update sequence numbr: ', iupbs01( ibfmg, 'USN' )
272 
273  if ( iupbs01( ibfmg, 'ISC2' ) == 1 ) then
274  write ( 51, fmt = '( A )') ' Section 2 present?: Yes'
275  else
276  write ( 51, fmt = '( A )') ' Section 2 present?: No'
277  end if
278 
279  mtyp = iupbs01( ibfmg, 'MTYP' )
280  msbt = iupbs01( ibfmg, 'MSBT' )
281  msbti = iupbs01( ibfmg, 'MSBTI' )
282  if ( ( basic_f == 'Y' ) .or. ( cfms_f == 'N' ) ) then
283  write ( 51, fmt= '( A, I4 )' ) ' Data category: ', mtyp
284  write ( 51, fmt= '( A, I4 )' ) ' Local subcategory: ', msbt
285  write ( 51, fmt= '( A, I4 )' ) ' Internatl subcategory: ', msbti
286  else
287  call getcfmng ( lunit, 'TABLAT', mtyp, ' ', -1, cmmtyp, lcmmtyp, iermtyp )
288  if ( iermtyp == 0 ) then
289  write ( 51, fmt= '( A, I4, 3A )' ) ' Data category: ', mtyp, ' (= ', cmmtyp(1:lcmmtyp), ')'
290  else
291  write ( 51, fmt= '( A, I4 )' ) ' Data category: ', mtyp
292  end if
293  call getcfmng ( lunit, 'TABLASL', msbt, 'TABLAT', mtyp, cmmsbt, lcmmsbt, iermsbt )
294  if ( ( iermsbt == 0 ) .and. ( iogce == 7 ) ) then
295  write ( 51, fmt= '( A, I4, 3A )' ) ' Local subcategory: ', msbt, ' (= ', cmmsbt(1:lcmmsbt), ')'
296  else
297  write ( 51, fmt= '( A, I4 )' ) ' Local subcategory: ', msbt
298  end if
299  call getcfmng ( lunit, 'TABLASS', msbti, 'TABLAT', mtyp, cmmsbti, lcmmsbti, iermsbti )
300  if ( iermsbti == 0 ) then
301  write ( 51, fmt= '( A, I4, 3A )' ) ' Internatl subcategory: ', msbti, ' (= ', cmmsbti(1:lcmmsbti), ')'
302  else
303  write ( 51, fmt= '( A, I4 )' ) ' Internatl subcategory: ', msbti
304  end if
305  end if
306 
307  write ( 51, fmt= '( A, I4 )' ) ' Master table version: ', iupbs01( ibfmg, 'MTV' )
308  write ( 51, fmt= '( A, I4 )' ) ' Local table version: ', iupbs01( ibfmg, 'MTVL' )
309  write ( 51, fmt= '( A, I4 )' ) ' Year: ', iupbs01( ibfmg, 'YEAR' )
310  write ( 51, fmt= '( A, I4 )' ) ' Month: ', iupbs01( ibfmg, 'MNTH' )
311  write ( 51, fmt= '( A, I4 )' ) ' Day: ', iupbs01( ibfmg, 'DAYS' )
312  write ( 51, fmt= '( A, I4 )' ) ' Hour: ', iupbs01( ibfmg, 'HOUR' )
313  write ( 51, fmt= '( A, I4 )' ) ' Minute: ', iupbs01( ibfmg, 'MINU' )
314  write ( 51, fmt= '( A, I4 )' ) ' Second: ', iupbs01( ibfmg, 'SECO' )
315  if ( ( iogce == 7 ) .and. ( igses == 3 ) ) then
316  call rtrcptb ( ibfmg, iryr, irmo, irdy, irhr, irmi, irtret )
317  if ( irtret == 0 ) then
318  write ( 51, fmt= '( A, I4 )' ) ' NCEP tank rcpt year: ', iryr
319  write ( 51, fmt= '( A, I4 )' ) ' NCEP tank rcpt month: ', irmo
320  write ( 51, fmt= '( A, I4 )' ) ' NCEP tank rcpt day: ', irdy
321  write ( 51, fmt= '( A, I4 )' ) ' NCEP tank rcpt hour: ', irhr
322  write ( 51, fmt= '( A, I4 )' ) ' NCEP tank rcpt minute: ', irmi
323  end if
324  end if
325 
326  ! Decode and output the data from Section 3.
327 
328  nsub = iupbs3( ibfmg, 'NSUB' )
329  write ( 51, fmt= '( /, A, I4 )' ) ' Number of data subsets: ', nsub
330  nsubt = nsubt + nsub
331 
332  if ( iupbs3( ibfmg, 'IOBS' ) == 1 ) then
333  write ( 51, fmt = '( A )') ' Data are observed?: Yes'
334  else
335  write ( 51, fmt = '( A )') ' Data are observed?: No'
336  end if
337 
338  if ( iupbs3( ibfmg, 'ICMP' ) == 1 ) then
339  write ( 51, fmt = '( A )') ' Data are compressed?: Yes'
340  else
341  write ( 51, fmt = '( A )') ' Data are compressed?: No'
342  end if
343 
344  call upds3 ( ibfmg, mxds3, cds3, nds3 )
345  write ( 51, fmt= '( A, I5 )' ) ' Number of descriptors: ', nds3
346  do jj = 1, nds3
347  write ( 51, fmt = '( 5X, I4, A, A6)' ) jj, ": ", cds3( jj )
348  end do
349 
350  if ( ( basic_f == 'N' ) .and. ( ierme >= 0 ) ) then
351 
352  ! Decode and output the data from Section 4.
353 
354  write ( 51, fmt = '( /, A, I7, 3A, I10, A, I6, A )' ) &
355  'BUFR message #', nmsg, ' of type ', cmgtag, ' and date ', imgdt, ' contains ', nsub, ' subsets:'
356  do while ( ireadsb( lunit ) == 0 )
357  call ufdump ( lunit, 51 )
358  end do
359  end if
360 
361  write ( 51, fmt = '( /, A, I7 )' ) 'End of BUFR message #', nmsg
362  write ( 51, fmt = '( /, 120("-"))' )
363  end if
364 
365  end do
366 
367  return
368 end subroutine fdebufr_c
369 
383 subroutine openbt ( lundx, mtyp )
384 
385  use share_table_info
386 
387  implicit none
388 
389  character*11 bftab
390  character*275 bftabfil
391 
392  integer, intent(in) :: mtyp
393  integer, intent(out) :: lundx
394 
395  logical exists
396 
397  write ( bftab, '("bufrtab.",i3.3)' ) mtyp
398  bftabfil = tbldir_f(1:ltbd) // '/' // bftab
399 
400  inquire ( file = bftabfil, exist = exists )
401  if ( exists ) then
402  lundx = ludx
403  close ( lundx )
404  open ( unit = lundx, file = bftabfil )
405  else
406  lundx = 0
407  end if
408 
409  return
410 end subroutine openbt
recursive subroutine getcfmng(lunit, nemoi, ivali, nemod, ivald, cmeang, lnmng, iret)
Decode the meaning of a numerical value from a code or flag table.
Definition: cftbvs.F90:220
subroutine fdebufr_c(ofile, lenof, tbldir, lentd, tblfil, lentf, prmstg, lenps, basic, forcemt, cfms)
This subroutine reads, decodes, and generates a verbose output listing of the contents of every BUFR ...
Definition: debufr.F90:56
recursive subroutine ufdump(lunit, luprt)
Print a verbose listing of the contents of a data subset, including all data values and replicated se...
Definition: dumpdata.F90:228
recursive subroutine dxdump(lunit, ldxot)
Print a copy of the DX BUFR table associated with a specified Fortran logical unit.
Definition: dumpdata.F90:580
subroutine codflg(cf)
Specify whether or not code and flag table information should be included during all future reads of ...
recursive subroutine mtinfo(cmtdir, lunmt1, lunmt2)
Specify the directory location and Fortran logical unit numbers to be used when reading master BUFR t...
Definition: mastertable.F90:35
recursive subroutine strnum(str, num, iret)
Decode an integer from a character string.
Definition: misc.F90:177
subroutine strsuc(str1, str2, lens)
Remove leading and trailing blanks from a character string.
Definition: misc.F90:220
Wrap C NCEPLIBS-bufr functions so they can be called from within Fortran application programs.
This module is used within the debufr utility to share information between subroutine fdebufr_c() and...
Definition: debufr.F90:11
integer ludx
Fortran logical unit number to use for referencing a DX table.
Definition: debufr.F90:20
integer ltbd
Length (in characters) of tbldir_f.
Definition: debufr.F90:17
character(len=:), allocatable tbldir_f
Directory containing DX BUFR tables to be used for decoding.
Definition: debufr.F90:14
recursive subroutine openbt(lundx, mtyp)
Specify a DX BUFR table of last resort, in case subroutine cktaba() is unable to locate a DX BUFR tab...
Definition: openbt.F90:31
recursive subroutine openbf(lunit, io, lundx)
Connect a new file to the NCEPLIBS-bufr software for input or output operations, or initialize the li...
recursive subroutine readerme(mesg, lunit, subset, jdate, iret)
Read a BUFR message from a memory array.
recursive subroutine upds3(mbay, lcds3, cds3, nds3)
Read the sequence of data descriptors contained within Section 3 of a BUFR message.
Definition: s013vals.F90:829
recursive subroutine datelen(len)
Specify the format of Section 1 date-time values that will be output by future calls to any of the NC...
Definition: s013vals.F90:889
subroutine parstr(str, tags, mtag, ntag, sep, limit80)
Parse a string containing one or more substrings into an array of substrings.
Definition: strings.F90:473
recursive subroutine rtrcptb(mbay, iyr, imo, idy, ihr, imi, iret)
Read the tank receipt time (if one exists) from Section 1 of a BUFR message.
Definition: tankrcpt.F90:114