NCEPLIBS-bufr  12.0.0
getcfmng.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Decode the meaning of a numerical value from a code or flag table
3 C>
4 C> @author J. Ator @date 2018-01-11
5 
6 C> This subroutine searches for a specified Table B mnemonic and associated
7 C> value (code figure or bit number) within the master Code/Flag tables,
8 C> and if found returns the associated meaning as a character string.
9 C>
10 C> @param[in] LUNIT -- integer: Fortran logical unit number for
11 C> BUFR file
12 C> @param[in] NEMOI -- character*(*): Mnemonic to search for
13 C> @param[in] IVALI -- integer: Value (code figure or bit number)
14 C> associated with NEMOI
15 C> @param[in] NEMOD -- character*(*): Optional second mnemonic upon
16 C> which the values NEMOI and IVALI depend; set to
17 C> all blank characters if the meanings of NEMOI and
18 C> IVALI do not depend on the value of any other
19 C> mnemonic
20 C> @param[in] IVALD -- integer: Value (code figure or bit number)
21 C> associated with NEMOD; set to (-1) whenever
22 C> NEMOD is set to all blank characters
23 C> @param[out] CMEANG -- character*(*): If the initial search of the
24 C> master Code/Flag tables was successful, then this
25 C> string contains the meaning corresponding to NEMOI
26 C> and IVALI (and to NEMOD and IVALD, if specified).
27 C> However, if the initial search was unsuccessful,
28 C> <b>and</b> if no optional second mnemonic and
29 C> associated value were specified on input,
30 C> <b>and</b> if a second search of the table
31 C> determines that the meaning of NEMOI and IVALI
32 C> indeed depends on one or more other possible
33 C> second mnemonics, then those possible second
34 C. mnemonics are returned within this string, as a
35 C> series of IRET successive 8-byte substrings.
36 C> An example of this scenario is included below
37 C> within the Remarks.
38 C> @param[out] LNMNG -- integer: Length (in bytes) of string returned in
39 C> CMEANG
40 C> @param[out] IRET -- integer: return code
41 C> - 0 = meaning found and stored in CMEANG string
42 C> - -1 = meaning not found
43 C> - >0 = meaning not found, <b>and</b> NEMOD and
44 C> IVALD were not specified on input,
45 C> <b>and</b> the meaning of NEMOI and IVALI
46 C> depends on the value of one of the
47 C> mnemonics stored in the first IRET 8-byte
48 C> substrings of CMEANG
49 C>
50 C> As noted above, this subroutine first does an initial search of
51 C> the master Code/Flag tables based on the mnemonics and values provided.
52 C> The input parameters NEMOI and IVALI specify the mnemonic and
53 C> corresponding numerical code or flag table value for which the meaning
54 C> is sought, and the optional secondary parameters NEMOD and IVALD are
55 C> specified when needed to differentiate between multiple possible
56 C> results. An example of this particular scenario is included below
57 C> within the Remarks. Otherwise, if the meaning of NEMOD and IVALD
58 C> does not depend on the value associated with any other mnemonic, then
59 C> NEMOD should be set to a field of all blank characters, and IVALD
60 C> should be set to a value of (-1).
61 C>
62 C> Subroutine codflg() must be called with a CF value of 'Y' prior to
63 C> calling this subroutine, in order to ensure that master Code/Flag
64 C> tables have been read into internal memory.
65 C>
66 C> This subroutine can be called at any time after a BUFR message
67 C> has been read into internal arrays by one of the BUFRLIB
68 C> [message-reading subroutines](@ref hierarchy), and it
69 C> can be called for any code or flag table mnemonic defined within that
70 C> particular message. In most cases, this means that the mnemonic must
71 C> be contained within the subset definition (Section 3) of that message.
72 C> The only exceptions to this rule are for originating centers,
73 C> originating subcenters, data types and data subtypes, since those can
74 C> also be contained within the identification section (Section 1) of a
75 C> BUFR message.
76 C>
77 C> It is the user's responsibility to provide sufficient allocated
78 C> space in CMEANG for the returned meaning string; otherwise, the
79 C> returned string will be truncated.
80 C>
81 C> @remarks
82 C> - An example of when secondary mnemonics NEMOD and IVALD would be
83 C> required is when a user is searching for the meaning of a numerical
84 C> code table value for an originating sub-center (i.e. mnemonic GSES).
85 C> The meaning of any originating sub-center value depends on the identity
86 C> of the originating center for which the sub-center in question is a
87 C> member, so in order for the subroutine to locate and return the proper
88 C> one, information about the originating center must also be provided. So
89 C> in this case the user would input GSES and the associated numerical
90 C> value as NEMOI and IVALI, respectively, but the user would also need to
91 C> specify an appropriate originating center mnemonic (e.g. GCLONG, OGCE
92 C> or ORIGC) and associated value from the same BUFR message as input
93 C> parameters NEMOD and IVALD, respectively, and then the subroutine will
94 C> be able to locate and return the appropriate meaning string. Otherwise,
95 C> if this information was not provided, the subroutine would return with
96 C> an IRET value of 3, and with each of the mnemonics GCLONG, OGCE and
97 C> ORIGC contained in successive 8-byte substrings of CMEANG (and with a
98 C> corresponding value of 24 returned for LNMNG), as a hint to the user
99 C> that more information needs to be input to the subroutine in order to
100 C> achieve the desired result.
101 C>
102 C> @author J. Ator @date 2018-01-11
103  RECURSIVE SUBROUTINE getcfmng
104  . ( lunit, nemoi, ivali, nemod, ivald, cmeang, lnmng, iret )
105 
106  use bufrlib
107 
108  USE moda_tababd
109  USE modv_im8b
110 
111  COMMON /tablef/ cdmf
112 
113  CHARACTER*(*) nemoi, nemod, cmeang
114 
115  CHARACTER*128 bort_str
116  CHARACTER*8 nemo, my_nemoi, my_nemod
117  CHARACTER*1 cdmf, tab
118 
119  dimension ifxyd(10)
120 
121 C-----------------------------------------------------------------------
122 C-----------------------------------------------------------------------
123 
124 C* Check for I8 integers.
125 
126  IF(im8b) THEN
127  im8b=.false.
128 
129  CALL x84(lunit,my_lunit,1)
130  CALL x84(ivali,my_ivali,1)
131  CALL x84(ivald,my_ivald,1)
132  CALL getcfmng(my_lunit,nemoi,my_ivali,nemod,my_ivald,cmeang,
133  . lnmng,iret)
134  CALL x48(lnmng,lnmng,1)
135  CALL x48(iret,iret,1)
136 
137  im8b=.true.
138  RETURN
139  ENDIF
140 
141  CALL status ( lunit, lun, il, im )
142  IF ( il .EQ. 0 ) GOTO 900
143  IF ( il .GT. 0 ) GOTO 901
144  IF ( im .EQ. 0 ) GOTO 902
145 
146 C* Make sure the appropriate code/flag information has already been
147 C* read into internal memory.
148 
149  IF ( cdmf .NE. 'Y' ) GOTO 903
150 
151  itmp = ireadmt( lun )
152 
153 C* Check the validity of the input mnemonic(s). Include special
154 C* handling for originating centers, originating subcenters, data
155 C* types and data subtypes, since those can be reported in
156 C* Section 1 of a BUFR message as well as in Section 3, so if a
157 C* user requests those mnemonics we can't necessarily assume they
158 C* came from within Section 3.
159 
160  lcmg = len( cmeang )
161 
162  my_nemoi = ' '
163  DO ii = 1, min( 8, len( nemoi ) )
164  my_nemoi(ii:ii) = nemoi(ii:ii)
165  END DO
166  my_nemod = ' '
167  DO ii = 1, min( 8, len( nemod ) )
168  my_nemod(ii:ii) = nemod(ii:ii)
169  END DO
170  IF ( my_nemoi(1:4) .EQ. 'GSES' ) THEN
171  IF ( ( my_nemod(1:6) .EQ. 'GCLONG' ) .OR.
172  . ( my_nemod(1:4) .EQ. 'OGCE' ) .OR.
173  . ( my_nemod(1:5) .EQ. 'ORIGC' ) ) THEN
174  ifxyi = ifxy( '001034' )
175  ifxyd(1) = ifxy( '001035' )
176  ELSE
177  lnmng = min( 24, lcmg )
178  IF ( lnmng .EQ. 24 ) THEN
179  iret = 3
180  cmeang(1:24) = 'GCLONG OGCE ORIGC '
181  ELSE
182  iret = -1
183  END IF
184  RETURN
185  END IF
186  ELSE IF ( my_nemoi(1:6) .EQ. 'GCLONG' ) THEN
187  ifxyi = ifxy( '001031' )
188  ifxyd(1) = (-1)
189  ELSE IF ( my_nemoi(1:4) .EQ. 'OGCE' ) THEN
190  ifxyi = ifxy( '001033' )
191  ifxyd(1) = (-1)
192  ELSE IF ( my_nemoi(1:5) .EQ. 'ORIGC' ) THEN
193  ifxyi = ifxy( '001035' )
194  ifxyd(1) = (-1)
195  ELSE IF ( ( my_nemoi(1:7) .EQ. 'TABLASS' ) .OR.
196  + ( my_nemoi(1:7) .EQ. 'TABLASL' ) ) THEN
197  IF ( ( my_nemod(1:6) .EQ. 'TABLAT' ) ) THEN
198  IF ( my_nemoi(1:7) .EQ. 'TABLASS' ) THEN
199  ifxyi = ifxy( '055021' )
200  ELSE
201  ifxyi = ifxy( '055022' )
202  ENDIF
203  ifxyd(1) = ifxy( '055020' )
204  ELSE
205  lnmng = min( 8, lcmg )
206  IF ( lnmng .EQ. 8 ) THEN
207  iret = 1
208  cmeang(1:8) = 'TABLAT '
209  ELSE
210  iret = -1
211  END IF
212  RETURN
213  END IF
214  ELSE IF ( my_nemoi(1:6) .EQ. 'TABLAT' ) THEN
215  ifxyi = ifxy( '055020' )
216  ifxyd(1) = (-1)
217  ELSE
218  CALL parstr ( my_nemoi, nemo, 1, ntg, ' ', .true. )
219  CALL nemtab ( lun, nemo, ifxyi, tab, n )
220  IF ( ( n .EQ. 0 ) .OR. ( tab .NE. 'B' ) ) GOTO 904
221  IF ( ( tabb( n, lun )(71:74) .NE. 'CODE' ) .AND.
222  . ( tabb( n, lun )(71:74) .NE. 'FLAG' ) ) GOTO 905
223  IF ( my_nemod(1:1) .NE. ' ' ) THEN
224  CALL parstr ( my_nemod, nemo, 1, ntg, ' ', .true. )
225  CALL nemtab ( lun, nemo, ifxyd(1), tab, n )
226  IF ( ( n .EQ. 0 ) .OR. ( tab .NE. 'B' ) ) GOTO 904
227  IF ( ( tabb( n, lun )(71:74) .NE. 'CODE' ) .AND.
228  . ( tabb( n, lun )(71:74) .NE. 'FLAG' ) ) GOTO 905
229  ELSE
230  ifxyd(1) = (-1)
231  END IF
232  END IF
233 
234 C* Search the internal table for the requested meaning.
235 
236  CALL srchtbf_c ( ifxyi, ivali, ifxyd(1), 10, ivald,
237  . cmeang, lcmg, lnmng, iret )
238  IF ( iret .LE. 0 ) RETURN
239 
240 C* The meaning of this value is dependent on the value of another
241 C* mnemonic in the report.
242 
243  iret2 = iret
244  lnmng = 0
245  iret = 0
246  DO ii = 1, iret2
247  CALL numtbd ( lun, ifxyd(ii), nemo, tab, ierbd )
248  IF ( ( ierbd .GT. 0 ) .AND. ( tab .EQ. 'B' ) .AND.
249  . ( lcmg .GE. ( lnmng + 8 ) ) ) THEN
250  iret = iret + 1
251  cmeang(lnmng+1:lnmng+8) = nemo
252  lnmng = lnmng + 8
253  END IF
254  END DO
255  IF ( iret .EQ. 0 ) iret = -1
256 
257  RETURN
258 900 CALL bort('BUFRLIB: GETCFMNG - INPUT BUFR FILE IS CLOSED, IT '//
259  . 'MUST BE OPEN FOR INPUT')
260 901 CALL bort('BUFRLIB: GETCFMNG - INPUT BUFR FILE IS OPEN FOR '//
261  . 'OUTPUT, IT MUST BE OPEN FOR INPUT')
262 902 CALL bort('BUFRLIB: GETCFMNG - A MESSAGE MUST BE OPEN IN '//
263  . 'INPUT BUFR FILE, NONE ARE')
264 903 CALL bort('BUFRLIB: GETCFMNG - TO USE THIS SUBROUTINE, MUST '//
265  . 'FIRST CALL SUBROUTINE CODFLG WITH INPUT ARGUMENT SET TO Y')
266 904 WRITE(bort_str,'("BUFRLIB: GETCFMNG - MNEMONIC ",A,'//
267  . '" NOT FOUND IN TABLE B")') nemo
268  CALL bort(bort_str)
269 905 WRITE(bort_str,'("BUFRLIB: GETCFMNG - MNEMONIC ",A,'//
270  . '" IS NOT A CODE OR FLAG TABLE")') nemo
271  CALL bort(bort_str)
272  END
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
recursive subroutine getcfmng(LUNIT, NEMOI, IVALI, NEMOD, IVALD, CMEANG, LNMNG, IRET)
This subroutine searches for a specified Table B mnemonic and associated value (code figure or bit nu...
Definition: getcfmng.f:105
function ifxy(ADSC)
Convert an FXY value from its 6 character representation to its WMO bit-wise representation.
Definition: ifxy.f:34
integer function ireadmt(LUN)
Check whether master BUFR tables need to be read from the local file system.
Definition: ireadmt.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 array and variable declarations used to store DX BUFR tables internally for mult...
character *128, dimension(:,:), allocatable tabb
Table B entries for each internal I/O stream.
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 ...
subroutine nemtab(LUN, NEMO, IDN, TAB, IRET)
Get information about a descriptor, based on the mnemonic.
Definition: nemtab.f:29
subroutine numtbd(LUN, IDN, NEMO, TAB, IRET)
Search for a Table B or Table D descriptor within the internal DX BUFR tables.
Definition: numtbd.f:24
subroutine parstr(STR, TAGS, MTAG, NTAG, SEP, LIMIT80)
Parse a string containing one or more substrings into an array of substrings.
Definition: parstr.f:24
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 x48(IIN4, IOUT8, NVAL)
Encode one or more 4-byte integer values as 8-byte integer values.
Definition: x48.F:19
subroutine x84(IIN8, IOUT4, NVAL)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x84.F:19