NCEPLIBS-bufr 11.7.1
ufbint.f
Go to the documentation of this file.
1C> @file
2C> @brief Read/write one or more data values from/to a data subset.
3
4C> This subroutine reads or writes one or more data values from or to
5C> the BUFR data subset that is currently open within the BUFRLIB
6C> internal arrays. The direction of the data transfer is determined
7C> by the context of ABS(LUNIN):
8C> - If ABS(LUNIN) points to a file that was previously opened for
9C> input using subroutine openbf(), then data values are read from
10C> the current data subset.
11C> - If ABS(LUNIN) points to a file that was previously opened for
12C> output using subroutine openbf(), then data values are written to
13C> the current data subset.
14C>
15C> <p>This subroutine is specifically designed for use with Table B
16C> mnemonics which are part of a delayed-replication sequence, or for
17C> which there is no replication at all. See also subroutines ufbrep(),
18C> ufbseq() and ufbstp(), which can also be used to read/write one or
19C> more data values from/to a data subset but are designed for
20C> different use cases. A more detailed discussion of
21C> these different use cases, including examples, is available in
22C> [DX BUFR Tables](@ref ufbsubs).
23C>
24C> @author J. Woollen
25C> @date 1994-01-06
26C>
27C> @param[in] LUNIN -- integer: Absolute value is Fortran logical
28C> unit number for BUFR file
29C> @param[in,out] USR -- real*8(*,*): Data values
30C> - If ABS(LUNIN) was opened for input, then
31C> USR is output from this subroutine and
32C> contains data values that were read
33C> from the current data subset.
34C> - If ABS(LUNIN) was opened for output, then
35C> USR is input to this subroutine and
36C> contains data values that are to be
37C> written to the current data subset.
38C> @param[in] I1 -- integer: Actual first dimension of USR as allocated
39C> within the calling program
40C> @param[in] I2 -- integer:
41C> - If ABS(LUNIN) was opened for input, then I2
42C> must be set equal to the actual second dimension
43C> of USR as allocated within the calling program
44C> - If ABS(LUNIN) was opened for output, then I2
45C> must be set equal to the number of replications
46C> of STR that are to be written to the data subset
47C> @param[out] IRET -- integer: Number of replications of STR that were
48C> actually read/written from/to the data subset
49C> @param[in] STR -- character*(*): String of blank-separated
50C> Table B mnemonics
51C> in one-to-one correspondence with the number of data
52C> values that will be read/written from/to the data
53C> subset within the first dimension of USR (see
54C> [DX BUFR Tables](@ref dfbftab) for further
55C> information about Table B mnemonics)
56C>
57C> <p>It is the user's responsibility to ensure that USR is dimensioned
58C> sufficiently large enough to accommodate the number of data values
59C> that are to be read from or written to the data subset. Note also
60C> that USR is an array of real*8 values; therefore, any data that are
61C> to be written out as character (i.e. CCITT IA5) values in
62C> BUFR must be converted from character into real*8 format within the
63C> application program before calling this subroutine. Conversely,
64C> when this subroutine is being used to read character values from a
65C> data subset, the value that is returned will be in real*8 format
66C> and must be converted back into character format by the application
67C> program before it can be used as such. Alternatively, there are
68C> different subroutines such as readlc() and writlc() which can be
69C> used to read/write character data directly from/to a data subset
70C> without the need to convert from/to real*8 format as an intermediate
71C> step.
72C>
73C> <p>Numeric (i.e. non-character) data values within USR are always in
74C> the exact units specified for the corresponding mnemonic within the
75C> relevant DX or master BUFR table, without any scale or reference
76C> values applied. Specifically, this means that, when writing
77C> data values into an output subset, the user only needs to store each
78C> respective value into USR using the units specified within the table,
79C> and the BUFRLIB software will take care of any necessary scaling or
80C> referencing of the value before it is actually encoded into BUFR.
81C> Conversely, when reading data values from an input subset, the
82C> values returned in USR are already de-scaled and de-referenced and,
83C> thus, are already in the exact units that were defined for the
84C> corresponding mnemonics within the table.
85C>
86C> <p>"Missing" values in USR are always denoted by a unique
87C> placeholder value. This placeholder value is initially set
88C> to a default value of 10E10_8, but it can be reset to
89C> any substitute value of the user's choice via a separate
90C> call to subroutine setbmiss(). In any case, and whenever this
91C> subroutine is used to read data values from an input subset, any
92C> returned value in USR can be easily checked for equivalence to the
93C> current placeholder value via a call to function ibfms(), and a
94C> positive result means that the value for the corresponding mnemonic
95C> was encoded as "missing" in BUFR (i.e. all bits set to 1) within the
96C> original data subset. Conversely, whenever this subroutine
97C> is used to write data values to an output subset, the current
98C> placeholder value can be obtained via a separate call to function
99C> getbmiss(), and the resulting value can then be stored into the
100C> USR array whereever the user desires a BUFR "missing" value (i.e.
101C> all bits set to 1) to be encoded for the corresponding mnemonic
102C> within the output subset.
103C>
104C> @remarks
105C> - If LUNIN < 0, and if ABS(LUNIN) points to a file that is open
106C> for output (writing BUFR), then the subroutine will treat the file
107C> pointed to by ABS(LUNIN) as though it was open for input (reading
108C> BUFR). This is a special capability for use by some applications
109C> that need to read certain values back out from a BUFR file during
110C> the same time that it is in the process of being written to.
111C> - If ABS(LUNIN) points to a file that is open for input (reading
112C> BUFR), STR may contain a Table D mnemonic that is replicated using
113C> either 8-bit or 16-bit delayed replication (as noted using
114C> replication indicators {} or (), respectively, within the
115C> assocated DX BUFR table), and the corresponding location in USR
116C> will contain the total number of replications of that mnemonic
117C> within the data subset. Note that, when using this option, the
118C> applicable replication indicators must be included in STR
119C> along with the mnemonic itself, as shown in an example in the
120C> discussion of [DX BUFR Tables](@ref ufbsubs).
121C> - If ABS(LUNIN) points to a file that is open for input (reading
122C> BUFR), there are a few additional special mnemonics that can be
123C> included within STR when calling this subroutine, and which in turn
124C> will result in special information being returned within the
125C> corresponding location in USR. These special mnemonics are not
126C> considered to be part of Table B or Table D and therefore do not
127C> need to be definied within the DX or master table file associated
128C> with ABS(LUNIN):
129C> - NUL - returns the "missing" value
130C> - IREC - returns the number of the BUFR message within the
131C> file pointed to by ABS(LUNIN) (counting from the
132C> beginning of the file) in which the current data
133C> subset resides
134C> - ISUB - returns the number of the current data subset within
135C> the BUFR message pointed to by IREC, counting from
136C> the beginning of the message
137C>
138C> <b>Program history log:</b>
139C> | Date | Programmer | Comments |
140C> | -----|------------|----------|
141C> | 1994-01-06 | J. Woollen | Original author |
142C> | 1996-11-25 | J. Woollen | Modified to add a return code when mnemonics are not found when reading |
143C> | 1996-12-17 | J. Woollen | Modified to always initialize USR array to "missing" when BUFR file is being read |
144C> | 1998-07-08 | J. Woollen | Replaced call to Cray library routine ABORT with call to new internal routine bort() |
145C> | 1999-11-18 | J. Woollen | The number of BUFR files which can be opened at one time increased from 10 to 32 |
146C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
147C> | 2003-11-04 | D. Keyser | Unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally |
148C> | 2004-08-18 | J. Ator | Added SAVE for IFIRST1 and IFIRST2 flags |
149C> | 2009-04-21 | J. Ator | Use errwrt() |
150C> | 2014-12-10 | J. Ator | Use modules instead of COMMON blocks |
151C>
152 SUBROUTINE ufbint(LUNIN,USR,I1,I2,IRET,STR)
153
154 USE modv_bmiss
155 USE moda_usrint
156 USE moda_msgcwd
157
158 COMMON /usrstr/ nnod,ncon,nods(20),nodc(10),ivls(10),kons(10)
159 COMMON /quiet / iprt
160
161 CHARACTER*(*) STR
162 CHARACTER*128 BORT_STR1,BORT_STR2,ERRSTR
163 real*8 usr(i1,i2)
164
165 DATA ifirst1/0/,ifirst2/0/
166
167 SAVE ifirst1, ifirst2
168
169C----------------------------------------------------------------------
170C----------------------------------------------------------------------
171
172 iret = 0
173
174C CHECK THE FILE STATUS AND I-NODE
175C --------------------------------
176
177 lunit = abs(lunin)
178 CALL status(lunit,lun,il,im)
179 IF(il.EQ.0) GOTO 900
180 IF(im.EQ.0) GOTO 901
181 IF(inode(lun).NE.inv(1,lun)) GOTO 902
182
183 io = min(max(0,il),1)
184 IF(lunit.NE.lunin) io = 0
185
186 IF(i1.LE.0) THEN
187 IF(iprt.GE.0) THEN
188 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
189 errstr = .LE.'BUFRLIB: UFBINT - 3rd ARG. (INPUT) IS 0, ' //
190 . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
191 CALL errwrt(errstr)
192 CALL errwrt(str)
193 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
194 CALL errwrt(' ')
195 ENDIF
196 GOTO 100
197 ELSEIF(i2.LE.0) THEN
198 IF(iprt.EQ.-1) ifirst1 = 1
199 IF(io.EQ.0 .OR. ifirst1.EQ.0 .OR. iprt.GE.1) THEN
200 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
201 errstr = .LE.'BUFRLIB: UFBINT - 4th ARG. (INPUT) IS 0, ' //
202 . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
203 CALL errwrt(errstr)
204 CALL errwrt(str)
205 IF(iprt.EQ.0 .AND. io.EQ.1) THEN
206 errstr = 'Note: Only the first occurrence of this WARNING ' //
207 . 'message is printed, there may be more. To output all ' //
208 . 'such messages,'
209 CALL errwrt(errstr)
210 errstr = 'modify your application program to add ' //
211 . '"CALL OPENBF(0,''QUIET'',1)" prior to the first call ' //
212 . 'to a BUFRLIB routine.'
213 CALL errwrt(errstr)
214 ENDIF
215 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
216 CALL errwrt(' ')
217 ifirst1 = 1
218 ENDIF
219 GOTO 100
220 ENDIF
221
222C PARSE OR RECALL THE INPUT STRING
223C --------------------------------
224
225 CALL string(str,lun,i1,io)
226
227C INITIALIZE USR ARRAY PRECEEDING AN INPUT OPERATION
228C --------------------------------------------------
229
230 IF(io.EQ.0) THEN
231 DO j=1,i2
232 DO i=1,i1
233 usr(i,j) = bmiss
234 ENDDO
235 ENDDO
236 ENDIF
237
238C CALL THE MNEMONIC READER/WRITER
239C -------------------------------
240
241 CALL ufbrw(lun,usr,i1,i2,io,iret)
242
243C IF INCOMPLETE WRITE TRY TO INITIALIZE REPLICATION SEQUENCE OR RETURN
244C ---------------------------------------------------------------------
245
246 IF(io.EQ.1 .AND. iret.NE.i2 .AND. iret.GE.0) THEN
247 CALL trybump(lunit,lun,usr,i1,i2,io,iret)
248 IF(iret.NE.i2) GOTO 903
249 ELSEIF(iret.EQ.-1) THEN
250 iret = 0
251 ENDIF
252
253 IF(iret.EQ.0) THEN
254 IF(io.EQ.0) THEN
255 IF(iprt.GE.1) THEN
256 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
257 errstr = 'BUFRLIB: UFBINT - NO SPECIFIED VALUES READ IN, ' //
258 . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
259 CALL errwrt(errstr)
260 CALL errwrt(str)
261 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
262 CALL errwrt(' ')
263 ENDIF
264 ELSE
265 IF(iprt.EQ.-1) ifirst2 = 1
266 IF(ifirst2.EQ.0 .OR. iprt.GE.1) THEN
267 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
268 errstr = 'BUFRLIB: UFBINT - NO SPECIFIED VALUES WRITTEN OUT, ' //
269 . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
270 CALL errwrt(errstr)
271 CALL errwrt(str)
272 CALL errwrt('MAY NOT BE IN THE BUFR TABLE(?)')
273 IF(iprt.EQ.0) THEN
274 errstr = 'Note: Only the first occurrence of this WARNING ' //
275 . 'message is printed, there may be more. To output all ' //
276 . 'such messages,'
277 CALL errwrt(errstr)
278 errstr = 'modify your application program to add ' //
279 . '"CALL OPENBF(0,''QUIET'',1)" prior to the first call ' //
280 . 'to a BUFRLIB routine.'
281 CALL errwrt(errstr)
282 ENDIF
283 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
284 CALL errwrt(' ')
285 ifirst2 = 1
286 ENDIF
287 ENDIF
288 ENDIF
289
290C EXITS
291C -----
292
293100 RETURN
294900 CALL bort('BUFRLIB: UFBINT - BUFR FILE IS CLOSED, IT MUST BE'//
295 . ' OPEN')
296901 CALL bort('BUFRLIB: UFBINT - A MESSAGE MUST BE OPEN IN BUFR '//
297 . 'FILE, NONE ARE')
298902 CALL bort('BUFRLIB: UFBINT - LOCATION OF INTERNAL TABLE FOR '//
299 . 'BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN INTERNAL '//
300 . 'SUBSET ARRAY')
301903 WRITE(bort_str1,'("BUFRLIB: UFBINT - MNEMONIC STRING READ IN IS'//
302 . ': ",A)') str
303 WRITE(bort_str2,'(18X,"THE NUMBER OF ''LEVELS'' ACTUALLY '//
304 . 'WRITTEN (",I3,") DOES NOT EQUAL THE NUMBER REQUESTED (",I3,")'//
305 . ' - INCOMPLETE WRITE")') iret,i2
306 CALL bort2(bort_str1,bort_str2)
307 END
subroutine bort2(STR1, STR2)
This subroutine calls subroutine errwrt() to log two error messages, then calls subroutine bort_exit(...
Definition: bort2.f:23
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:42
This module declares and initializes the BMISS variable.
Definition: modv_BMISS.f90:9
real *8, public bmiss
Current placeholder value to represent "missing" data when reading from or writing to BUFR files; thi...
Definition: modv_BMISS.f90:15
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 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:59
subroutine trybump(LUNIT, LUN, USR, I1, I2, IO, IRET)
THIS SUBROUTINE CHECKS THE FIRST NODE ASSOCIATED WITH A CHARACTER STRING (PARSED INTO ARRAYS IN COMMO...
Definition: trybump.f:71
subroutine ufbint(LUNIN, USR, I1, I2, IRET, STR)
This subroutine reads or writes one or more data values from or to the BUFR data subset that is curre...
Definition: ufbint.f:153
subroutine ufbrw(LUN, USR, I1, I2, IO, IRET)
THIS SUBROUTINE WRITES OR READS SPECIFIED VALUES TO OR FROM THE CURRENT BUFR DATA SUBSET WITHIN INTER...
Definition: ufbrw.f:80