NCEPLIBS-bufr  12.0.0
openbf.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Connect a new file to the library, or initialize the
3 C> library, or change verbosity associated with already-connected file.
4 C>
5 C> @authors J. Woollen, J. Ator, D. Keyser @date 1994-01-06
6 
7 C> Connects a new file to the NCEPLIBS-bufr software for
8 C> input or output operations, or initializes the library without
9 C> connecting to a file, or changes the verbosity of the library for an
10 C> already-connected BUFR file.
11 C>
12 C> The logical unit numbers LUNIT and LUNDX must already be associated
13 C> with actual filenames on the local system, typically via a Fortran "OPEN"
14 C> statement. Multiple logical units can be connected to the NCEPLIBS-bufr software
15 C> at any one time.
16 C>
17 C> The argument IO is a character string describing how the file connected to
18 C> LUNIT will be used, e.g. 'IN' is used to access an existing file of BUFR
19 C> messages for input (i.e. reading/decoding BUFR), and 'OUT' is used to access
20 C> a new file for output (i.e. writing/encoding BUFR). An option 'APX' is also
21 C> available which behaves like 'OUT', except that output is then appended to
22 C> an existing BUFR file rather than creating a new one from scratch, and there
23 C> are also some additional options 'NUL' and 'NODX' which can likewise be used
24 C> instead of 'OUT' for some very special cases as needed. There's also an
25 C> option 'SEC3' which can be used in place of 'IN' for certain cases when the
26 C> user is attempting to read BUFR messages whose content and descriptor layout
27 C> are unknown in advance. However, all of these additional options are
28 C> basically just variations of 'IN' or 'OUT', again depending on whether the
29 C> intent is to read or write BUFR messages from the file connected to LUNIT.
30 C> The only exceptions are when IO = 'FIRST' or 'QUIET'. When IO = 'FIRST',
31 C> the subroutine simply checks whether it has already been called from within
32 C> the application program and, if not, goes ahead and initializes the library
33 C> without actually connecting any files in LUNIT or LUNDX.
34 C>
35 C> Alternatively, when IO = 'QUIET', the subroutine simply sets or resets the
36 C> internal print verbosity switch to the value of input argument LUNDX,
37 C> overriding its previous value and/or its internal default value of 0.
38 C>
39 C> The third and final call argument LUNDX identifies the logical unit which
40 C> contains the definition of the DX BUFR tables to be associated with unit
41 C> LUNIT. Except when IO = 'SEC3', every BUFR file that is linked to the NCEPLIBS-bufr
42 C> software must have a DX BUFR tables file associated with it, and these tables
43 C> may be defined within a separate ASCII text file
44 C> (see [Description and Format of DX BUFR Tables](@ref dfbftab) for more info.)
45 C> or, in the case of an existing BUFR file, may be embedded within the first few
46 C> BUFR messages of the file itself, and in which case the user can denote this
47 C> to the subroutine by setting LUNDX to the same value as LUBFR.
48 C>
49 C> @remarks
50 C> - When an existing BUFR file is accessed for input (i.e. reading/decoding BUFR),
51 C> the associated DX BUFR tables defined by LUNDX are stored internally within
52 C> the NCEPLIBS-bufr software and are referenced during all subsequent processing of
53 C> the file. Likewise, when a file is accessed for output (i.e. writing/encoding
54 C> BUFR), the associated DX BUFR tables are still stored internally for subsequent
55 C> reference; however, the output file itself is also initialized by writing the
56 C> BUFR table information (as one or more BUFR messages) to the beginning of the
57 C> file, except when IO = 'NODX', and in which case the writing of these
58 C> additional messages is suppressed.
59 C> - As noted above, 'SEC3' is the only value of IO (other than 'QUIET') where it's
60 C> not necessary to provide pre-defined DX BUFR tables via LUNDX. Instead, this
61 C> option instructs the NCEPLIBS-bufr software to unpack the data description section
62 C> (Section 3) from each BUFR message it reads and then decode the contents
63 C> accordingly. In this case, it's necessary to provide a set of BUFR master
64 C> tables containing listings of all possible BUFR descriptors
65 C> (see [Description and Format of master BUFR Tables](@ref dfbfmstab) for more
66 C> info.), but otherwise no prior knowledge is required of the contents of the
67 C> messages to be decoded.
68 C>
69 C>
70 C> @param[in] LUNIT -- integer: Fortran logical unit number for BUFR
71 C> file (unless IO is set to 'FIRST' or 'QUIET', in
72 C> which case this is a dummy argument)
73 C> @param[in] IO -- character*(*): flag indicating how LUNIT is to be
74 C> used by the software:
75 C> - 'IN' = input operations with table processing
76 C> - 'INX' = input operations w/o table processing
77 C> - 'OUX' = output operations w/o table processing
78 C> - 'OUT' = output operations with table processing
79 C> - 'SEC3' = same as 'IN', except use Section 3 of input
80 C> messages for decoding rather than DX BUFR
81 C> table information from LUNDX; in this case
82 C> LUNDX is ignored, and user must provide
83 C> appropriate [master BUFR tables](@ref dfbfmstab)
84 C> within the directory specified by a subsequent
85 C> call to subroutine mtinfo()
86 C> - 'NODX' = same as 'OUT', except don't write DX BUFR
87 C> table messages to LUNIT
88 C> - 'APN' = same as 'NODX', except begin writing at end
89 C> of file ("append")
90 C> - 'APX' = same as 'APN', except backspace before
91 C> appending
92 C> - 'NUL' = same as 'OUT', except don't write any
93 C> messages whatsoever to LUNIT (e.g. when
94 C> subroutine writsa() is to be used)
95 C> - 'INUL' = same as 'IN', except don't read any
96 C> messages whatsoever from LUNIT (e.g. when
97 C> subroutine readerme() is to be used)
98 C> - 'QUIET' = LUNIT is ignored; this is an indicator
99 C> that the value for IPRT in COMMON block
100 C> /QUIET/ is being reset to the value in
101 C> LUNDX
102 C> - 'FIRST' = LUNIT and LUNDX are ignored; this is an
103 C> indicator to initialize the NCEPLIBS-bufr
104 C> software, in case this subroutine was
105 C> never previously called
106 C> @param[in] LUNDX -- integer:
107 C> - If IO is not set to 'FIRST' or 'QUIET' =
108 C> Fortran logical unit number
109 C> containing DX BUFR table information to be used in
110 C> reading/writing from/to LUNIT (depending on the case).
111 C> This value may be set equal to LUNIT if DX BUFR table
112 C> information is already embedded in LUNIT.
113 C> - If IO is set to 'QUIET' = indicator for degree of
114 C> printout:
115 C> - -1 = no printout except for ABORT messages
116 C> - 0 = limited printout (default)
117 C> - 1 = all warning messages are printed out
118 C> - 2 = all warning and informational messages are
119 C> printed out
120 C>
121 C> @authors J. Woollen, J. Ator, D. Keyser @date 1994-01-06
122 
123  RECURSIVE SUBROUTINE openbf(LUNIT,IO,LUNDX)
124 
125  use bufrlib
126 
127  USE modv_ifopbf
128  USE modv_nfiles
129  USE modv_im8b
130 
131  USE moda_msgcwd
132  USE moda_stbfr
133  USE moda_sc3bfr
134  USE moda_lushr
135  USE moda_nulbfr
136  USE moda_stcode
137 
138  COMMON /quiet / iprt
139 
140  CHARACTER*(*) io
141  CHARACTER*255 filename,fileacc
142  CHARACTER*128 bort_str,errstr
143  CHARACTER*28 cprint(0:3)
144 
145  DATA cprint/
146  . ' (only ABORTs) ',
147  . ' (limited - default) ',
148  . ' (all warnings) ',
149  . ' (all warning+informational)'/
150 
151 C-----------------------------------------------------------------------
152 C-----------------------------------------------------------------------
153 
154 C CHECK FOR I8 INTEGERS
155 C ---------------------
156 
157  IF(im8b) THEN
158  im8b=.false.
159 
160  CALL x84(lunit,my_lunit,1)
161  CALL x84(lundx,my_lundx,1)
162  CALL openbf(my_lunit,io,my_lundx)
163 
164  im8b=.true.
165  RETURN
166  ENDIF
167 
168 C If this is the first call to this subroutine, initialize
169 C IPRT in /QUIET/ as 0 (limited printout - except for abort
170 C messages)
171 
172  IF(ifopbf.EQ.0) iprt = 0
173 
174  IF(io.EQ.'QUIET') THEN
175 c .... override previous IPRT value (printout indicator)
176  iprtprv = iprt
177  iprt = lundx
178  IF(iprt.LT.-1) iprt = -1
179  IF(iprt.GT. 2) iprt = 2
180  IF(iprt.GE.0) THEN
181  CALL errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
182  WRITE ( unit=errstr, fmt='(A,I3,A,A,I3,A)' )
183  . 'BUFRLIB: OPENBF - DEGREE OF MESSAGE PRINT INDICATOR '//
184  . 'CHNGED FROM',iprtprv,cprint(iprtprv+1),' TO',iprt,cprint(iprt+1)
185  CALL errwrt(errstr)
186  CALL errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
187  CALL errwrt(' ')
188  ENDIF
189  ENDIF
190 
191  IF(ifopbf.EQ.0) THEN
192 
193 C This is the first call to this subroutine, so take care of some
194 C initial housekeeping tasks. Note that ARALLOCF, ARALLOCC_C, and
195 C WRDLEN must all be called prior to calling BFRINI.
196 
197 C Allocate any arrays which are being dynamically sized.
198  CALL arallocf
199  CALL arallocc_c
200 
201 C Figure out some important information about the local machine.
202  CALL wrdlen
203 
204 C Initialize some global variables.
205  CALL bfrini
206 
207  ifopbf = 1
208  ENDIF
209 
210  IF(io.EQ.'FIRST') GOTO 100
211  IF(io.EQ.'QUIET') GOTO 100
212 
213 C SEE IF A FILE CAN BE OPENED
214 C ---------------------------
215 
216  CALL status(lunit,lun,il,im)
217  IF(lun.EQ.0) GOTO 900
218  IF(il .NE.0) GOTO 901
219  null(lun) = 0
220  isc3(lun) = 0
221  iscodes(lun) = 0
222  lus(lun) = 0
223 
224 C USE INQUIRE TO OBTAIN THE FILENAME ASSOCIATED WITH UNIT LUNIT
225 C -------------------------------------------------------------
226 
227  IF (io.NE.'NUL' .AND. io.NE.'INUL') THEN
228  INQUIRE(lunit,access=fileacc)
229  IF(fileacc=='UNDEFINED') OPEN(lunit)
230  INQUIRE(lunit,name=filename)
231  filename=trim(filename)//char(0)
232  ENDIF
233 
234 C SET INITIAL OPEN DEFAULTS (CLEAR OUT A MSG CONTROL WORD PARTITION)
235 C ------------------------------------------------------------------
236 
237  nmsg(lun) = 0
238  nsub(lun) = 0
239  msub(lun) = 0
240  inode(lun) = 0
241  idate(lun) = 0
242 
243 C DECIDE HOW TO OPEN THE FILE AND SETUP THE DICTIONARY
244 C ----------------------------------------------------
245 
246  IF(io.EQ.'IN') THEN
247  CALL openrb_c(lun,filename)
248  CALL wtstat(lunit,lun,-1,0)
249  CALL readdx(lunit,lun,lundx)
250  ELSE IF(io.EQ.'INUL') THEN
251  CALL wtstat(lunit,lun,-1,0)
252  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
253  null(lun) = 1
254  ELSE IF(io.EQ.'NUL') THEN
255  CALL wtstat(lunit,lun, 1,0)
256  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
257  null(lun) = 1
258  ELSE IF(io.EQ.'INX') THEN
259  CALL openrb_c(lun,filename)
260  CALL wtstat(lunit,lun,-1,0)
261  null(lun) = 1
262  ELSE IF(io.EQ.'OUX') THEN
263  CALL openwb_c(lun,filename)
264  CALL wtstat(lunit,lun, 1,0)
265  ELSE IF(io.EQ.'SEC3') THEN
266  CALL openrb_c(lun,filename)
267  CALL wtstat(lunit,lun,-1,0)
268  isc3(lun) = 1
269  ELSE IF(io.EQ.'OUT') THEN
270  CALL openwb_c(lun,filename)
271  CALL wtstat(lunit,lun, 1,0)
272  CALL writdx(lunit,lun,lundx)
273  ELSE IF(io.EQ.'NODX') THEN
274  CALL openwb_c(lun,filename)
275  CALL wtstat(lunit,lun, 1,0)
276  CALL readdx(lunit,lun,lundx)
277  ELSE IF(io.EQ.'APN' .OR. io.EQ.'APX') THEN
278  CALL openab_c(lun,filename)
279  CALL wtstat(lunit,lun, 1,0)
280  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
281  CALL posapx(lunit)
282  ELSE
283  GOTO 904
284  ENDIF
285 
286  GOTO 100
287 
288 C FILE OPENED FOR INPUT IS EMPTY - LET READMG OR READERME GIVE
289 C THE BAD NEWS LATER
290 
291  rewind lunit
292  IF(iprt.GE.0) THEN
293  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
294  WRITE ( unit=errstr, fmt='(A,I3,A)' )
295  . 'BUFRLIB: OPENBF - INPUT BUFR FILE IN UNIT ', lunit,
296  . ' IS EMPTY'
297  CALL errwrt(errstr)
298  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
299  CALL errwrt(' ')
300  ENDIF
301  CALL wtstat(lunit,lun,-1,0)
302 
303 C INITIALIZE THE DICTIONARY TABLE PARTITION
304 C -----------------------------------------
305 
306  CALL dxinit(lun,0)
307 
308 C EXITS
309 C -----
310 
311 100 RETURN
312 900 WRITE(bort_str,'("BUFRLIB: OPENBF - THERE ARE ALREADY",I3,'//
313  . '" BUFR FILES OPENED, CANNOT OPEN FILE CONNECTED TO UNIT",I4)')
314  . nfiles,lunit
315  CALL bort(bort_str)
316 901 WRITE(bort_str,'("BUFRLIB: OPENBF - THE FILE CONNECTED TO UNIT"'//
317  . ',I5," IS ALREADY OPEN")') lunit
318  CALL bort(bort_str)
319 904 CALL bort('BUFRLIB: OPENBF - SECOND (INPUT) ARGUMENT MUST BE'//
320  . ' "IN", "OUT", "NODX", "NUL", "APN", "APX", "SEC3"'//
321  . ' OR "QUIET"')
322  END
subroutine arallocf
This subroutine is called internally during the first call to subroutine openbf() from an application...
Definition: arallocf.f:17
subroutine bfrini
This subroutine initializes numerous global variables and arrays within internal modules and COMMON b...
Definition: bfrini.f90:16
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
subroutine dxinit(LUN, IOI)
This subroutine initializes the internal arrays (in module moda_tababd) holding the DX BUFR table.
Definition: dxinit.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
Wrap C NCEPLIBS-bufr functions so they can be called from within the Fortran part of the library.
Definition: bufrlib.F90:11
This module contains a declaration for an array used by subroutine makestab() to keep track of which ...
integer, dimension(:), allocatable lus
Tracking index for each I/O internal stream index.
This module contains declarations for arrays used to store information about the current BUFR message...
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 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 an array declaration used to store a switch for each internal I/O stream index,...
integer, dimension(:), allocatable null
Output switch for each internal I/O stream index:
This module contains an array declaration used to store a switch for each internal I/O stream index,...
integer, dimension(:), allocatable isc3
Section 3 switch for each internal I/O stream index:
This module contains array declarations used to store file and message status indicators for all logi...
This module contains an array declaration used to store a status code for each internal I/O stream in...
integer, dimension(:), allocatable iscodes
Abnormal status codes.
This module declares and initializes the IFOPBF variable.
integer, public ifopbf
Status indicator to keep track of whether subroutine openbf() has already been called:
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 ...
This module declares and initializes the NFILES variable.
integer, public nfiles
Maximum number of BUFR files that can be connected to the BUFRLIB software (for reading or writing) a...
recursive subroutine openbf(LUNIT, IO, LUNDX)
Connects a new file to the NCEPLIBS-bufr software for input or output operations, or initializes the ...
Definition: openbf.f:124
subroutine posapx(LUNXX)
Reads to the end of the file pointed to by abs(LUNXX) and positions it for appending.
Definition: posapx.f:18
subroutine readdx(LUNIT, LUN, LUNDX)
This subroutine initializes modules moda_tababd and moda_msgcwd with DX BUFR (dictionary) tables.
Definition: readdx.f:35
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 wrdlen
Determine important information about the local machine.
Definition: wrdlen.F:25
subroutine writdx(LUNIT, LUN, LUNDX)
Write DX BUFR tables messages to the beginning of a BUFR file.
Definition: writdx.f:26
subroutine wtstat(LUNIT, LUN, IL, IM)
Update file status in library internals.
Definition: wtstat.f:37
subroutine x84(IIN8, IOUT4, NVAL)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x84.F:19