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