NCEPLIBS-bufr  11.5.0
 All Data Structures Files Functions Variables Pages
openbf.F
Go to the documentation of this file.
1 C> @file
2 C> @brief Connect a new system file to the BUFRLIB software for
3 C> reading or writing BUFR messages.
4 
5 C> This subroutine connects a new file to the BUFRLIB software for
6 C> input or output operations.
7 C>
8 C> @authors J. Woollen
9 C> @authors J. Ator
10 C> @authors D. Keyser
11 C> @date 1994-01-06
12 C>
13 C> @param[in] LUNIT - integer: Fortran logical unit number for BUFR
14 C> file (unless IO is set to 'FIRST' or 'QUIET', in
15 C> which case this is a dummy argument)
16 C> @param[in] IO - character*(*): flag indicating how LUNIT is to be
17 C> used by the software:
18 C> - 'IN' = input operations with table processing
19 C> - 'INX' = input operations w/o table processing
20 C> - 'OUX' = output operations w/o table processing
21 C> - 'OUT' = output operations with table processing
22 C> - 'SEC3' = same as 'IN', except use Section 3 of input
23 C> messages for decoding rather than DX BUFR
24 C> table information from LUNDX; in this case
25 C> LUNDX is ignored, and user must provide
26 C> appropriate [master BUFR tables](@ref dfbfmstab)
27 C> within the directory specified by a subsequent
28 C> call to subroutine mtinfo()
29 C> - 'NODX' = same as 'OUT', except don't write DX BUFR
30 C> table messages to LUNIT
31 C> - 'APN' = same as 'NODX', except begin writing at end
32 C> of file ("append")
33 C> - 'APX' = same as 'APN', except backspace before
34 C> appending
35 C> - 'NUL' = same as 'OUT', except don't write any
36 C> messages whatsoever to LUNIT (e.g. when
37 C> subroutine writsa() is to be used)
38 C> - 'INUL' = same as 'IN', except don't read any
39 C> messages whatsoever from LUNIT (e.g. when
40 C> subroutine readerme() is to be used)
41 C> - 'QUIET' = LUNIT is ignored; this is an indicator
42 C> that the value for IPRT in COMMON block
43 C> /QUIET/ is being reset to the value in
44 C> LUNDX
45 C> - 'FIRST' = LUNIT and LUNDX are ignored; this is an
46 C> indicator to initialize the BUFRLIB
47 C> software, in case this subroutine was
48 C> never previously called
49 C> @param[in] LUNDX - integer:
50 C> - If IO is not set to 'FIRST' or 'QUIET' =
51 C> Fortran logical unit number
52 C> containing DX BUFR table information to be used in
53 C> reading/writing from/to LUNIT (depending on the case).
54 C> This value may be set equal to LUNIT if DX BUFR table
55 C> information is already embedded in LUNIT.
56 C> - If IO is set to 'QUIET' = indicator for degree of
57 C> printout:
58 C> - -1 = no printout except for ABORT messages
59 C> - 0 = limited printout (default)
60 C> - 1 = all warning messages are printed out
61 C> - 2 = all warning and informational messages are
62 C> printed out
63 C>
64 C> <p>The logical unit numbers LUNIT and LUNDX must already be associated
65 C> with actual filenames on the local system, typically via a Fortran "OPEN"
66 C> statement. Multiple logical units can be connected to the BUFRLIB software
67 C> at any one time.
68 C>
69 C> <p>The argument IO is a character string describing how the file connected to
70 C> LUNIT will be used, e.g. 'IN' is used to access an existing file of BUFR
71 C> messages for input (i.e. reading/decoding BUFR), and 'OUT' is used to access
72 C> a new file for output (i.e. writing/encoding BUFR). An option 'APX' is also
73 C> available which behaves like 'OUT', except that output is then appended to
74 C> an existing BUFR file rather than creating a new one from scratch, and there
75 C> are also some additional options 'NUL' and 'NODX' which can likewise be used
76 C> instead of 'OUT' for some very special cases as needed. There's also an
77 C> option 'SEC3' which can be used in place of 'IN' for certain cases when the
78 C> user is attempting to read BUFR messages whose content and descriptor layout
79 C> are unknown in advance. However, all of these additional options are
80 C> basically just variations of 'IN' or 'OUT', again depending on whether the
81 C> intent is to read or write BUFR messages from the file connected to LUNIT.
82 C> The only exceptions are when IO = 'FIRST' or 'QUIET'. When IO = 'FIRST',
83 C> the subroutine simply checks whether it has already been called from within
84 C> the application program and, if not, goes ahead and initializes the library
85 C> without actually connecting any files in LUNIT or LUNDX.
86 C> Alternatively, when IO = 'QUIET', the subroutine simply sets or resets the
87 C> internal print verbosity switch to the value of input argument LUNDX,
88 C> overriding its previous value and/or its internal default value of 0.
89 C>
90 C> <p>The third and final call argument LUNDX identifies the logical unit which
91 C> contains the definition of the DX BUFR tables to be associated with unit
92 C> LUNIT. Except when IO = 'SEC3', every BUFR file that is linked to the BUFRLIB
93 C> software must have a DX BUFR tables file associated with it, and these tables
94 C> may be defined within a separate ASCII text file
95 C> (see [Description and Format of DX BUFR Tables](@ref dfbftab) for more info.)
96 C> or, in the case of an existing BUFR file, may be embedded within the first few
97 C> BUFR messages of the file itself, and in which case the user can denote this
98 C> to the subroutine by setting LUNDX to the same value as LUBFR.
99 C>
100 C> @remarks
101 C> - When an existing BUFR file is accessed for input (i.e. reading/decoding BUFR),
102 C> the associated DX BUFR tables defined by LUNDX are stored internally within
103 C> the BUFRLIB software and are referenced during all subsequent processing of
104 C> the file. Likewise, when a file is accessed for output (i.e. writing/encoding
105 C> BUFR), the associated DX BUFR tables are still stored internally for subsequent
106 C> reference; however, the output file itself is also initialized by writing the
107 C> BUFR table information (as one or more BUFR messages) to the beginning of the
108 C> file, except when IO = 'NODX', and in which case the writing of these
109 C> additional messages is suppressed.
110 C> - As noted above, 'SEC3' is the only value of IO (other than 'QUIET') where it's
111 C> not necessary to provide pre-defined DX BUFR tables via LUNDX. Instead, this
112 C> option instructs the BUFRLIB software to unpack the data description section
113 C> (Section 3) from each BUFR message it reads and then decode the contents
114 C> accordingly. In this case, it's necessary to provide a set of BUFR master
115 C> tables containing listings of all possible BUFR descriptors
116 C> (see [Description and Format of master BUFR Tables](@ref dfbfmstab) for more
117 C> info.), but otherwise no prior knowledge is required of the contents of the
118 C> messages to be decoded.
119 C>
120 C> <b>Program history log:</b>
121 C> - 1994-01-06 J. Woollen -- Original author
122 C> - 1998-07-08 J. Woollen -- Replaced call to Cray library routine ABORT
123 C> with call to new internal routine bort()
124 C> - 1999-11-18 J. Woollen -- The number of BUFR files which can be
125 C> opened at one time increased from 10 to 32
126 C> (necessary in order to process multiple
127 C> BUFR files under the MPI)
128 C> - 2003-11-04 J. Ator -- Added IO='NUL' option in order to prevent
129 C> later writing to BUFR file in LUNIT (was in
130 C> decoder version); added documentation
131 C> - 2003-11-04 S. Bender -- Added remarks and routine interdependencies
132 C> - 2003-11-04 D. Keyser -- Unified/portable for WRF; added history
133 C> documentation; outputs more complete
134 C> diagnostic info when routine terminates
135 C> abnormally, unusual things happen or for
136 C> informational purposes
137 C> - 2004-08-18 J. Ator -- Added SAVE for IFIRST flag and IO="NODX"
138 C> option
139 C> - 2005-11-29 J. Ator -- Added COMMON /MSGFMT/ and ichkstr() call
140 C> - 2009-03-23 J. Ator -- Added IO='SEC3' option; removed call to
141 C> posapn; clarified comments; use errwrt()
142 C> - 2010-05-11 J. Ator -- Added COMMON /STCODE/
143 C> - 2012-06-18 J. Ator -- Added IO='INUL' option
144 C> - 2012-09-15 J. Woollen -- Modified for C/I/O/BUFR interface;
145 C> use INQUIRE to obtain the filename;
146 C> call C routines openrb(), openwb() and
147 C> openab() to connect BUFR files to C;
148 C> added IO type 'INX' to enable open and
149 C> close for C file without closing FORTRAN
150 C> file; add IO type 'FIRST' to support calls
151 C> to bfrini() and wrdlen() prior to user reset
152 C> of BUFRLIB parameters found in new routines
153 C> setbmiss() and setblock()
154 C> - 2014-11-07 J. Ator -- Allow dynamic allocation of certain arrays
155 C> - 2015-03-03 J. Ator -- Use MODA_IFOPBF instead of IFIRST
156 C>
157  SUBROUTINE openbf(LUNIT,IO,LUNDX)
158 
159  USE modv_ifopbf
160  USE moda_msgcwd
161  USE moda_stbfr
162  USE moda_sc3bfr
163  USE moda_lushr
164  USE moda_nulbfr
165  USE moda_stcode
166 
167  COMMON /quiet / iprt
168 
169  CHARACTER*(*) io
170  CHARACTER*255 filename,fileacc
171  CHARACTER*128 bort_str,errstr
172  CHARACTER*28 cprint(0:3)
173  CHARACTER*1 bstr(4)
174 
175  DATA cprint/
176  . ' (only ABORTs) ',
177  . ' (limited - default) ',
178  . ' (all warnings) ',
179  . ' (all warning+informational)'/
180 
181 C-----------------------------------------------------------------------
182 C-----------------------------------------------------------------------
183 
184 C If this is the first call to this subroutine, initialize
185 C IPRT in /QUIET/ as 0 (limited printout - except for abort
186 C messages)
187 
188  IF(ifopbf.EQ.0) iprt = 0
189 
190  IF(io.EQ.'QUIET') THEN
191 c .... override previous IPRT value (printout indicator)
192  IF(lundx.LT.-1) lundx = -1
193  IF(lundx.GT. 2) lundx = 2
194  IF(lundx.GE.0) THEN
195  CALL errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
196  WRITE ( unit=errstr, fmt='(A,I3,A,A,I3,A)' )
197  . 'BUFRLIB: OPENBF - DEGREE OF MESSAGE PRINT INDICATOR '//
198  . 'CHNGED FROM',iprt,cprint(iprt+1),' TO',lundx,cprint(lundx+1)
199  CALL errwrt(errstr)
200  CALL errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
201  CALL errwrt(' ')
202  ENDIF
203  iprt = lundx
204  ENDIF
205 
206  IF(ifopbf.EQ.0) THEN
207 
208 C This is the first call to this subroutine, so take care of some
209 C initial housekeeping tasks. Note that ARALLOCF, ARALLOCC, and
210 C WRDLEN must all be called prior to calling BFRINI.
211 
212 #ifdef DYNAMIC_ALLOCATION
213 C Allocate any arrays which are being dynamically sized.
214  CALL arallocf
215  CALL arallocc
216 #endif
217 
218 C Figure out some important information about the local machine.
219  CALL wrdlen
220 
221 C Initialize some global variables.
222  CALL bfrini
223 
224  ifopbf = 1
225  ENDIF
226 
227  IF(io.EQ.'FIRST') goto 100
228  IF(io.EQ.'QUIET') goto 100
229 
230 C SEE IF A FILE CAN BE OPENED
231 C ---------------------------
232 
233  CALL status(lunit,lun,il,im)
234  IF(lun.EQ.0) goto 900
235  IF(il .NE.0) goto 901
236  null(lun) = 0
237  isc3(lun) = 0
238  iscodes(lun) = 0
239  lus(lun) = 0
240 
241 C USE INQUIRE TO OBTAIN THE FILENAME ASSOCIATED WITH UNIT LUNIT
242 C -------------------------------------------------------------
243 
244  IF (io.NE.'NUL' .AND. io.NE.'INUL') THEN
245  INQUIRE(lunit,access=fileacc)
246  IF(fileacc=='UNDEFINED') OPEN(lunit)
247  INQUIRE(lunit,name=filename)
248  filename=trim(filename)//char(0)
249  ENDIF
250 
251 C SET INITIAL OPEN DEFAULTS (CLEAR OUT A MSG CONTROL WORD PARTITION)
252 C ------------------------------------------------------------------
253 
254  nmsg(lun) = 0
255  nsub(lun) = 0
256  msub(lun) = 0
257  inode(lun) = 0
258  idate(lun) = 0
259 
260 C DECIDE HOW TO OPEN THE FILE AND SETUP THE DICTIONARY
261 C ----------------------------------------------------
262 
263  IF(io.EQ.'IN') THEN
264  CALL openrb(lun,filename)
265  CALL wtstat(lunit,lun,-1,0)
266  CALL readdx(lunit,lun,lundx)
267  ELSE IF(io.EQ.'INUL') THEN
268  CALL wtstat(lunit,lun,-1,0)
269  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
270  null(lun) = 1
271  ELSE IF(io.EQ.'NUL') THEN
272  CALL wtstat(lunit,lun, 1,0)
273  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
274  null(lun) = 1
275  ELSE IF(io.EQ.'INX') THEN
276  CALL openrb(lun,filename)
277  CALL wtstat(lunit,lun,-1,0)
278  null(lun) = 1
279  ELSE IF(io.EQ.'OUX') THEN
280  CALL openwb(lun,filename)
281  CALL wtstat(lunit,lun, 1,0)
282  ELSE IF(io.EQ.'SEC3') THEN
283  CALL openrb(lun,filename)
284  CALL wtstat(lunit,lun,-1,0)
285  isc3(lun) = 1
286  ELSE IF(io.EQ.'OUT') THEN
287  CALL openwb(lun,filename)
288  CALL wtstat(lunit,lun, 1,0)
289  CALL writdx(lunit,lun,lundx)
290  ELSE IF(io.EQ.'NODX') THEN
291  CALL openwb(lun,filename)
292  CALL wtstat(lunit,lun, 1,0)
293  CALL readdx(lunit,lun,lundx)
294  ELSE IF(io.EQ.'APN' .OR. io.EQ.'APX') THEN
295  CALL openab(lun,filename)
296  CALL wtstat(lunit,lun, 1,0)
297  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
298  CALL posapx(lunit)
299  ELSE
300  goto 904
301  ENDIF
302 
303  goto 100
304 
305 C FILE OPENED FOR INPUT IS EMPTY - LET READMG OR READERME GIVE
306 C THE BAD NEWS LATER
307 
308 200 rewind lunit
309  IF(iprt.GE.0) THEN
310  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
311  WRITE ( unit=errstr, fmt='(A,I3,A)' )
312  . 'BUFRLIB: OPENBF - INPUT BUFR FILE IN UNIT ', lunit,
313  . ' IS EMPTY'
314  CALL errwrt(errstr)
315  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
316  CALL errwrt(' ')
317  ENDIF
318  CALL wtstat(lunit,lun,-1,0)
319 
320 C INITIALIZE THE DICTIONARY TABLE PARTITION
321 C -----------------------------------------
322 
323  CALL dxinit(lun,0)
324 
325 C EXITS
326 C -----
327 
328 100 RETURN
329 900 WRITE(bort_str,'("BUFRLIB: OPENBF - THERE ARE ALREADY",I3,'//
330  . '" BUFR FILES OPENED, CANNOT OPEN FILE CONNECTED TO UNIT",I4)')
331  . nfiles,lunit
332  CALL bort(bort_str)
333 901 WRITE(bort_str,'("BUFRLIB: OPENBF - THE FILE CONNECTED TO UNIT"'//
334  . ',I5," IS ALREADY OPEN")') lunit
335  CALL bort(bort_str)
336 904 CALL bort('BUFRLIB: OPENBF - SECOND (INPUT) ARGUMENT MUST BE'//
337  . ' "IN", "OUT", "NODX", "NUL", "APN", "APX", "SEC3"'//
338  . ' OR "QUIET"')
339  END
subroutine arallocf
For dynamic allocation builds of the library, this subroutine is called internally during the first c...
Definition: arallocf.F:33
void arallocc(void)
For dynamic allocation builds of the library, this subroutine is called internally during the first c...
Definition: arallocc.c:34
subroutine openbf(LUNIT, IO, LUNDX)
This subroutine connects a new file to the BUFRLIB software for input or output operations.
Definition: openbf.F:157
subroutine dxinit(LUN, IOI)
THIS SUBROUTINE INITIALIZES THE INTERNAL ARRAYS (IN MODULE TABABD) HOLDING THE DICTIONARY TABLE...
Definition: dxinit.f:40
subroutine writdx(LUNIT, LUN, LUNDX)
THIS SUBROUTINE WRITES BUFR TABLE (DICTIONARY) MESSAGES TO THE BEGINNING OF AN OUTPUT BUFR FILE IN LU...
Definition: writdx.f:50
void openab(f77int *nfile, char *ufile)
This subroutine opens a new system file for appending BUFR messages.
Definition: cread.c:62
subroutine wtstat(LUNIT, LUN, IL, IM)
This subroutine can be used to connect or disconnect a specified Fortran logical unit number to/from ...
Definition: wtstat.f:58
subroutine status(LUNIT, LUN, IL, IM)
This subroutine checks whether a specified Fortran logical unit number is currently connected to the ...
Definition: status.f:61
This module declares and initializes the IFOPBF variable.
Definition: modv_IFOPBF.f90:9
subroutine readdx(LUNIT, LUN, LUNDX)
THIS SUBROUTINE GENERATES INTERNAL ARRAYS CONTAINING BUFR DICTIONARY TABLES WHICH ARE NEEDED TO READ...
Definition: readdx.f:54
subroutine wrdlen
This subroutine figures out some important information about the local machine on which the BUFRLIB s...
Definition: wrdlen.F:43
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:39
void openwb(f77int *nfile, char *ufile)
This subroutine opens a new system file for writing BUFR messages.
Definition: cread.c:47
subroutine bfrini
This subroutine initializes numerous global variables and arrays within internal modules and COMMON b...
Definition: bfrini.f90:57
subroutine posapx(LUNXX)
THIS SUBROUTINE READS TO THE END OF THE FILE POINTED TO BY ABS(LUNXX) AND POSITIONS IT FOR APPENDING...
Definition: posapx.f:49
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
void openrb(f77int *nfile, char *ufile)
This subroutine opens a new system file for reading BUFR messages.
Definition: cread.c:32