NCEPLIBS-bufr  11.6.0
 All Data Structures Files Functions Variables Pages
ufbint.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Read/write one or more data values from/to a data subset.
3 
4 C> This subroutine reads or writes one or more data values from or to
5 C> the BUFR data subset that is currently open within the BUFRLIB
6 C> internal arrays. The direction of the data transfer is determined
7 C> by the context of ABS(LUNIN):
8 C> - If ABS(LUNIN) points to a file that was previously opened for
9 C> input using subroutine openbf(), then data values are read from
10 C> the current data subset.
11 C> - If ABS(LUNIN) points to a file that was previously opened for
12 C> output using subroutine openbf(), then data values are written to
13 C> the current data subset.
14 C>
15 C> <p>This subroutine is specifically designed for use with Table B
16 C> mnemonics which are part of a delayed-replication sequence, or for
17 C> which there is no replication at all. See also subroutines ufbrep(),
18 C> ufbseq() and ufbstp(), which can also be used to read/write one or
19 C> more data values from/to a data subset but are designed for
20 C> different use cases. A more detailed discussion of
21 C> these different use cases, including examples, is available in
22 C> [DX BUFR Tables](@ref ufbsubs).
23 C>
24 C> @author J. Woollen
25 C> @date 1994-01-06
26 C>
27 C> @param[in] LUNIN -- integer: Absolute value is Fortran logical
28 C> unit number for BUFR file
29 C> @param[in,out] USR -- real*8(*,*): Data values
30 C> - If ABS(LUNIN) was opened for input, then
31 C> USR is output from this subroutine and
32 C> contains data values that were read
33 C> from the current data subset.
34 C> - If ABS(LUNIN) was opened for output, then
35 C> USR is input to this subroutine and
36 C> contains data values that are to be
37 C> written to the current data subset.
38 C> @param[in] I1 -- integer: Actual first dimension of USR as allocated
39 C> within the calling program
40 C> @param[in] I2 -- integer:
41 C> - If ABS(LUNIN) was opened for input, then I2
42 C> must be set equal to the actual second dimension
43 C> of USR as allocated within the calling program
44 C> - If ABS(LUNIN) was opened for output, then I2
45 C> must be set equal to the number of replications
46 C> of STR that are to be written to the data subset
47 C> @param[out] IRET -- integer: Number of replications of STR that were
48 C> actually read/written from/to the data subset
49 C> @param[in] STR -- character*(*): String of blank-separated
50 C> Table B mnemonics
51 C> in one-to-one correspondence with the number of data
52 C> values that will be read/written from/to the data
53 C> subset within the first dimension of USR (see
54 C> [DX BUFR Tables](@ref dfbftab) for further
55 C> information about Table B mnemonics)
56 C>
57 C> <p>It is the user's responsibility to ensure that USR is dimensioned
58 C> sufficiently large enough to accommodate the number of data values
59 C> that are to be read from or written to the data subset. Note also
60 C> that USR is an array of real*8 values; therefore, any data that are
61 C> to be written out as character (i.e. CCITT IA5) values in
62 C> BUFR must be converted from character into real*8 format within the
63 C> application program before calling this subroutine. Conversely,
64 C> when this subroutine is being used to read character values from a
65 C> data subset, the value that is returned will be in real*8 format
66 C> and must be converted back into character format by the application
67 C> program before it can be used as such. Alternatively, there are
68 C> different subroutines such as readlc() and writlc() which can be
69 C> used to read/write character data directly from/to a data subset
70 C> without the need to convert from/to real*8 format as an intermediate
71 C> step.
72 C>
73 C> <p>Numeric (i.e. non-character) data values within USR are always in
74 C> the exact units specified for the corresponding mnemonic within the
75 C> relevant DX or master BUFR table, without any scale or reference
76 C> values applied. Specifically, this means that, when writing
77 C> data values into an output subset, the user only needs to store each
78 C> respective value into USR using the units specified within the table,
79 C> and the BUFRLIB software will take care of any necessary scaling or
80 C> referencing of the value before it is actually encoded into BUFR.
81 C> Conversely, when reading data values from an input subset, the
82 C> values returned in USR are already de-scaled and de-referenced and,
83 C> thus, are already in the exact units that were defined for the
84 C> corresponding mnemonics within the table.
85 C>
86 C> <p>"Missing" values in USR are always denoted by a unique
87 C> placeholder value. This placeholder value is initially set
88 C> to a default value of 10E10_8, but it can be reset to
89 C> any substitute value of the user's choice via a separate
90 C> call to subroutine setbmiss(). In any case, and whenever this
91 C> subroutine is used to read data values from an input subset, any
92 C> returned value in USR can be easily checked for equivalence to the
93 C> current placeholder value via a call to function ibfms(), and a
94 C> positive result means that the value for the corresponding mnemonic
95 C> was encoded as "missing" in BUFR (i.e. all bits set to 1) within the
96 C> original data subset. Conversely, whenever this subroutine
97 C> is used to write data values to an output subset, the current
98 C> placeholder value can be obtained via a separate call to function
99 C> getbmiss(), and the resulting value can then be stored into the
100 C> USR array whereever the user desires a BUFR "missing" value (i.e.
101 C> all bits set to 1) to be encoded for the corresponding mnemonic
102 C> within the output subset.
103 C>
104 C> @remarks
105 C> - If LUNIN < 0, and if ABS(LUNIN) points to a file that is open
106 C> for output (writing BUFR), then the subroutine will treat the file
107 C> pointed to by ABS(LUNIN) as though it was open for input (reading
108 C> BUFR). This is a special capability for use by some applications
109 C> that need to read certain values back out from a BUFR file during
110 C> the same time that it is in the process of being written to.
111 C> - If ABS(LUNIN) points to a file that is open for input (reading
112 C> BUFR), STR may contain a Table D mnemonic that is replicated using
113 C> either 8-bit or 16-bit delayed replication (as noted using
114 C> replication indicators {} or (), respectively, within the
115 C> assocated DX BUFR table), and the corresponding location in USR
116 C> will contain the total number of replications of that mnemonic
117 C> within the data subset. Note that, when using this option, the
118 C> applicable replication indicators must be included in STR
119 C> along with the mnemonic itself, as shown in an example in the
120 C> discussion of [DX BUFR Tables](@ref ufbsubs).
121 C> - If ABS(LUNIN) points to a file that is open for input (reading
122 C> BUFR), there are a few additional special mnemonics that can be
123 C> included within STR when calling this subroutine, and which in turn
124 C> will result in special information being returned within the
125 C> corresponding location in USR. These special mnemonics are not
126 C> considered to be part of Table B or Table D and therefore do not
127 C> need to be definied within the DX or master table file associated
128 C> with ABS(LUNIN):
129 C> - NUL - returns the "missing" value
130 C> - IREC - returns the number of the BUFR message within the
131 C> file pointed to by ABS(LUNIN) (counting from the
132 C> beginning of the file) in which the current data
133 C> subset resides
134 C> - ISUB - returns the number of the current data subset within
135 C> the BUFR message pointed to by IREC, counting from
136 C> the beginning of the message
137 C>
138 C> <b>Program history log:</b>
139 C> | Date | Programmer | Comments |
140 C> | -----|------------|----------|
141 C> | 1994-01-06 | J. Woollen | Original author |
142 C> | 1996-11-25 | J. Woollen | Modified to add a return code when mnemonics are not found when reading |
143 C> | 1996-12-17 | J. Woollen | Modified to always initialize USR array to "missing" when BUFR file is being read |
144 C> | 1998-07-08 | J. Woollen | Replaced call to Cray library routine ABORT with call to new internal routine bort() |
145 C> | 1999-11-18 | J. Woollen | The number of BUFR files which can be opened at one time increased from 10 to 32 |
146 C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
147 C> | 2003-11-04 | D. Keyser | Unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally |
148 C> | 2004-08-18 | J. Ator | Added SAVE for IFIRST1 and IFIRST2 flags |
149 C> | 2009-04-21 | J. Ator | Use errwrt() |
150 C> | 2014-12-10 | J. Ator | Use modules instead of COMMON blocks |
151 C>
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 
169 C----------------------------------------------------------------------
170 C----------------------------------------------------------------------
171 
172  iret = 0
173 
174 C CHECK THE FILE STATUS AND I-NODE
175 C --------------------------------
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 
222 C PARSE OR RECALL THE INPUT STRING
223 C --------------------------------
224 
225  CALL string(str,lun,i1,io)
226 
227 C INITIALIZE USR ARRAY PRECEEDING AN INPUT OPERATION
228 C --------------------------------------------------
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 
238 C CALL THE MNEMONIC READER/WRITER
239 C -------------------------------
240 
241  CALL ufbrw(lun,usr,i1,i2,io,iret)
242 
243 C IF INCOMPLETE WRITE TRY TO INITIALIZE REPLICATION SEQUENCE OR RETURN
244 C ---------------------------------------------------------------------
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 
290 C EXITS
291 C -----
292 
293 100 RETURN
294 900 CALL bort('BUFRLIB: UFBINT - BUFR FILE IS CLOSED, IT MUST BE'//
295  . ' OPEN')
296 901 CALL bort('BUFRLIB: UFBINT - A MESSAGE MUST BE OPEN IN BUFR '//
297  . 'FILE, NONE ARE')
298 902 CALL bort('BUFRLIB: UFBINT - LOCATION OF INTERNAL TABLE FOR '//
299  . 'BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN INTERNAL '//
300  . 'SUBSET ARRAY')
301 903 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 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:79
subroutine bort2(STR1, STR2)
This subroutine calls subroutine errwrt() to log two error messages, then calls subroutine bort_exit(...
Definition: bort2.f:22
This module declares and initializes the BMISS variable.
Definition: modv_BMISS.f90:9
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:58
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:70
subroutine status(LUNIT, LUN, IL, IM)
This subroutine checks whether a specified Fortran logical unit number is currently connected to the ...
Definition: status.f:55
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:41
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:152
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:22