NCEPLIBS-bufr  12.0.0
igetrfel.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Check whether a specified element refers to
3 C> a previous element within the same subset via an internal bitmap.
4 C>
5 C> @author J Ator @date 2016-05-27
6 
7 C> This function checks whether the input element refers to
8 C> a previous element within the same subset via an internal bitmap.
9 C> If so, then the referenced element is returned. In addition, if
10 C> the input element is a 2-XX-255 marker operator, its scale factor,
11 C> bit width and reference value are set internally to match those
12 C> of the referenced element.
13 C>
14 C> @param[in] N - integer: subset element.
15 C> @param[in] LUN - integer: I/O stream index into internal memory arrays.
16 C>
17 C> @return Subset element referenced by element N within the same subset.
18 C> - 0 input element does not refer to a previous element, or referenced
19 C> element not found.
20 C>
21 C> @author J. Ator @date 2016-05-27
22  INTEGER FUNCTION igetrfel ( N, LUN )
23 
24  USE moda_msgcwd
25  USE moda_usrint
26  USE moda_tables
27  USE moda_bitmaps
28  USE moda_nrv203
29 
30  CHARACTER*128 bort_str
31  CHARACTER*6 cflwopr,adn30,fxy
32  CHARACTER*1 tab
33 
34 C-----------------------------------------------------------------------
35 C-----------------------------------------------------------------------
36 
37  igetrfel = 0
38 
39  node = inv( n, lun )
40 
41  IF ( itp(node) .GT. 1 ) THEN
42  IF ( node .EQ. lstnod ) THEN
43  lstnodct = lstnodct + 1
44  ELSE
45  lstnod = node
46  lstnodct = 1
47  END IF
48 C
49 C Does this subset definition contain any Table C operators
50 C with an X value of 21 or greater?
51 C
52  idxta = 0
53  IF ( ntamc .GT. 0 ) THEN
54  nodtam = lstjpb( node, lun, 'SUB' )
55  DO ii = 1, ntamc
56  IF ( nodtam .EQ. inodtamc(ii) ) THEN
57  idxta = ii
58  ntc = ntco(ii)
59  END IF
60  END DO
61  END IF
62  IF ( ( idxta .GT. 0 ) .AND. ( nbtm .GT. 0 ) ) THEN
63 
64 C Check whether this element references a previous element
65 C in the same subset via an internal bitmap. To do this,
66 C we first need to determine the appropriate "follow"
67 C operator (if any) corresponding to this element.
68 
69  cflwopr = 'XXXXXX'
70  IF ( imrkopr(tag(node)) .EQ. 1 ) THEN
71  cflwopr = tag(node)(1:3) // '000'
72  ELSE
73  CALL nemtab( lun, tag(node), idn, tab, nn )
74  IF ( tab .EQ. 'B' ) THEN
75  fxy = adn30(idn,6)
76  IF ( fxy(2:3) .EQ. '33' ) cflwopr = '222000'
77  END IF
78  END IF
79  IF ( cflwopr .EQ. 'XXXXXX' ) THEN
80  IF ( imrkopr(tag(node)) .EQ. 1 ) GOTO 900
81  RETURN
82  END IF
83 
84 C Now, check whether the appropriate "follow" operator was
85 C actually present in the subset. If there are multiple
86 C occurrences, we want the one that most recently precedes
87 C the element in question.
88 
89  nodflw = 0
90  DO jj = 1, ntc
91  IF ( ( ctco(idxta,jj) .EQ. cflwopr ) .AND.
92  . ( inodtco(idxta,jj) .GE. inode(lun) ) .AND.
93  . ( inodtco(idxta,jj) .LE. isc(inode(lun)) ) .AND.
94  . ( inodtco(idxta,jj) .LT. node ) )
95  . nodflw = inodtco(idxta,jj)
96  ENDDO
97  IF ( nodflw .EQ. 0 ) THEN
98  IF ( imrkopr(tag(node)) .EQ. 1 ) GOTO 901
99  RETURN
100  END IF
101 
102 C We found an appropriate corresponding "follow" operator,
103 C so now we need to look for a bitmap corresponding to
104 C this operator. First, look for a bitmap indicator.
105 
106  nodl236 = 0
107  nodbmap = 0
108  jj = 1
109  DO WHILE ( ( jj .LE. ntc ) .AND.
110  . ( inodtco(idxta,jj) .GE. inode(lun) ) .AND.
111  . ( inodtco(idxta,jj) .LE. isc(inode(lun)) ) .AND.
112  . ( nodbmap .EQ. 0 ) )
113  IF ( ctco(idxta,jj) .EQ. '236000' ) THEN
114  nodl236 = inodtco(idxta,jj)
115  IF ( inodtco(idxta,jj) .EQ. nodflw ) THEN
116  nodbmap = nodflw
117  END IF
118  ELSE IF ( ( ctco(idxta,jj) .EQ. '235000' ) .OR.
119  . ( ctco(idxta,jj) .EQ. '237255' ) ) THEN
120  nodl236 = 0
121  ELSE IF ( ( ctco(idxta,jj) .EQ. '237000' ) .AND.
122  . ( inodtco(idxta,jj) .EQ. nodflw ) .AND.
123  . ( nodl236 .NE. 0 ) ) THEN
124  nodbmap = nodl236
125  END IF
126  jj = jj + 1
127  END DO
128  IF ( nodbmap .EQ. 0 ) THEN
129 
130 C There was no valid bitmap indicator, so we'll just
131 C look for a bitmap after the "follow" indicator.
132 
133  nodbmap = nodflw
134  END IF
135 
136 C Find the corresponding bitmap.
137 
138  nn = 1
139  idxbtm = 0
140  DO WHILE ( ( idxbtm .EQ. 0 ) .AND.
141  . ( nn .LE. nval(lun) ) )
142  IF ( inv( nn, lun ) .GT. nodbmap ) THEN
143  ii = 1
144  DO WHILE ( ( idxbtm .EQ. 0 ) .AND.
145  . ( ii .LE. nbtm ) )
146  IF ( nn .EQ. istbtm(ii) ) THEN
147  idxbtm = ii
148  ELSE
149  ii = ii + 1
150  END IF
151  END DO
152  END IF
153  nn = nn + 1
154  END DO
155  IF ( idxbtm .EQ. 0 ) THEN
156  IF ( imrkopr(tag(node)) .EQ. 1 ) GOTO 902
157  RETURN
158  END IF
159 
160 C Use the bitmap to find the previous element in the
161 C subset that is referenced by the current element.
162 C Search backwards from the start of the bitmap, but
163 C make sure not to cross a 2-35-000 operator.
164 
165  IF ( lstnodct .GT. nbtmse(idxbtm) ) THEN
166  IF ( imrkopr(tag(node)) .EQ. 1 ) GOTO 903
167  RETURN
168  END IF
169  iemrk = iszbtm(idxbtm) - ibtmse(idxbtm,lstnodct) + 1
170  iect = 0
171  DO WHILE ( ( nn .GE. 1 ) .AND. ( igetrfel .EQ. 0 ) )
172  nodnn = inv( nn, lun )
173  IF ( nodnn .LE. nodbmap ) THEN
174  DO jj = 1, ntc
175  IF ( ( nodnn .EQ. inodtco(idxta,jj) ) .AND.
176  . ( ctco(idxta,jj) .EQ. '235000' ) ) THEN
177  IF ( imrkopr(tag(node)) .EQ. 1 ) GOTO 903
178  RETURN
179  END IF
180  END DO
181  IF ( itp(nodnn) .GT. 1 ) THEN
182  iect = iect + 1
183  IF ( iect .EQ. iemrk ) igetrfel = nn
184  END IF
185  END IF
186  nn = nn - 1
187  END DO
188  IF ( igetrfel .EQ. 0 ) THEN
189  IF ( imrkopr(tag(node)) .EQ. 1 ) GOTO 903
190  RETURN
191  END IF
192 
193  IF ( imrkopr(tag(node)) .EQ. 1 ) THEN
194 
195 C This element is a marker operator, so set the scale,
196 C reference value and bit width accordingly based on
197 C those of the previous referenced element.
198 
199  nodrfe = inv( igetrfel, lun )
200  isc(node) = isc(nodrfe)
201  IF ( tag(node)(1:3) .EQ. '225' ) THEN
202  ibt(node) = ibt(nodrfe) + 1
203  irf(node) = -1 * (2 ** ibt(nodrfe))
204  ELSE
205  ibt(node) = ibt(nodrfe)
206  irf(node) = irf(nodrfe)
207  IF ( nnrv .GT. 0 ) THEN
208  DO ii = 1, nnrv
209  IF ( ( nodrfe .NE. inodnrv(ii) ) .AND.
210  . ( tag(nodrfe)(1:8) .EQ. tagnrv(ii) ) .AND.
211  . ( nodrfe .GE. isnrv(ii) ) .AND.
212  . ( nodrfe .LE. ienrv(ii) ) ) THEN
213  irf(node) = int(nrv(ii))
214  RETURN
215  END IF
216  END DO
217  END IF
218  END IF
219  END IF
220 
221  END IF
222  END IF
223 
224  RETURN
225 900 WRITE(bort_str,'("BUFRLB: IGETRFEL - UNABLE TO DETERMINE '//
226  . 'FOLLOW OPERATOR FOR MARKER OPERATOR ",A)') tag(node)
227  CALL bort(bort_str)
228 901 WRITE(bort_str,'("BUFRLB: IGETRFEL - UNABLE TO FIND FOLLOW '//
229  . 'OPERATOR ",A," IN SUBSET")') cflwopr
230  CALL bort(bort_str)
231 902 WRITE(bort_str,'("BUFRLB: IGETRFEL - UNABLE TO FIND BITMAP '//
232  . 'FOR MARKER OPERATOR ",A)') tag(node)
233  CALL bort(bort_str)
234 903 WRITE(bort_str,'("BUFRLB: IGETRFEL - UNABLE TO FIND PREVIOUS '//
235  . 'ELEMENT REFERENCED BY MARKER OPERATOR ",A)') tag(node)
236  CALL bort(bort_str)
237  END
character *(*) function adn30(IDN, L30)
Convert a WMO bit-wise representation of an FXY value to a character string of length 5 or 6.
Definition: adn30.f:23
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
integer function igetrfel(N, LUN)
This function checks whether the input element refers to a previous element within the same subset vi...
Definition: igetrfel.f:23
integer function imrkopr(NEMO)
Check whether a specified mnemonic is a Table C marker operator.
Definition: imrkopr.f:16
function lstjpb(NODE, LUN, JBTYP)
This function searches backwards, beginning from a given node within the jump/link table,...
Definition: lstjpb.f:30
This module contains array and variable declarations used to store bitmaps internally within a data s...
integer, dimension(:), allocatable iszbtm
Size of bitmap (total number of entries, whether "set" (set to a value of 0) or not).
integer lstnod
Most recent jump/link table entry that was processed by function igetrfel() and whose corresponding v...
integer, dimension(:,:), allocatable inodtco
Entries within jump/link table which contain Table C operators.
integer ntamc
Number of Table A mnemonics in jump/link table (up to a maximum of MXTAMC) which contain at least one...
integer, dimension(:), allocatable istbtm
Ordinal position in data subset definition corresponding to the first entry of the bitmap.
integer nbtm
Number of stored bitmaps for the current data subset (up to a maximum of MXBTM).
integer, dimension(:), allocatable inodtamc
Entries within jump/link table which contain Table A mnemonics.
integer, dimension(:,:), allocatable ibtmse
Ordinal positions in bitmap of bits that were "set" (set to a value of 0); these ordinal positions ca...
integer lstnodct
Current count of consecutive occurrences of lstnod.
integer, dimension(:), allocatable nbtmse
Number of "set" entries (set to a value of 0) in the bitmap.
character *6, dimension(:,:), allocatable ctco
Table C operators corresponding to inodtco.
integer, dimension(:), allocatable ntco
Number of Table C operators (with an XX value of 21 or greater) within the data subset definition of ...
This module contains declarations for arrays used to store information about the current BUFR message...
integer, dimension(:), allocatable inode
Table A mnemonic for type of BUFR message.
This module contains array and variable declarations for use with any 2-03-YYY (change reference valu...
integer, dimension(:), allocatable ienrv
End of entry range in jump/link table, within which the corresponding new reference value in nrv will...
character *8, dimension(:), allocatable tagnrv
Table B mnemonic to which the corresponding new reference value in nrv applies.
integer, dimension(:), allocatable isnrv
Start of entry range in jump/link table, within which the corresponding new reference value in nrv wi...
integer nnrv
Number of entries in the jump/link table which contain new reference values (up to a maximum of MXNRV...
integer *8, dimension(:), allocatable nrv
New reference values corresponding to inodnrv.
integer, dimension(:), allocatable inodnrv
Entries within jump/link table which contain new reference values.
This module contains array and variable declarations used to store the internal jump/link table.
integer, dimension(:), allocatable irf
Reference values corresponding to tag and typ:
integer, dimension(:), allocatable isc
Scale factors corresponding to tag and typ:
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
This module contains declarations for arrays used to store data values and associated metadata for th...
integer, dimension(:), allocatable nval
Number of data values in BUFR data subset.
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
subroutine nemtab(LUN, NEMO, IDN, TAB, IRET)
Get information about a descriptor, based on the mnemonic.
Definition: nemtab.f:29