1 !*****************************************************************************!
2 ! Subroutine PARSE_TABLE !
5 ! Read the Vtable, and fill arrays in the TABLE module with the Vtable !
6 ! information. Broadly, the Vtable file is how the user tells the !
7 ! program what fields to extract from the archive files. !
10 ! Input: DEBUG_LEVEL: 0 = no prints, bigger numbers = more prints !
18 ! - File "Vtable" is opened, read, and closed as Fortran unit 10. !
20 ! - Various prints, especially if DEBUG_PRINT = .TRUE. !
22 ! - Abort for some miscellaneous error conditions. !
24 ! - Variables in module TABLE are filled., specifically, variables !
28 ! - Arrays in module TABLE are filled., specifically, arrays !
41 ! Author: Kevin W. Manning !
43 ! Summer 1998, and continuing !
46 !*****************************************************************************!
48 subroutine parse_table(debug_level,vtable_columns)
52 integer :: debug_level
54 character(LEN=255) :: string = ' '
56 integer :: istart, ibar, i, j, ipcount
57 integer :: jstart, jbar, jmax, tot_bars
58 integer :: vtable_columns
59 integer :: nstart, maxtmp
67 ! Open the file called "Vtable"
69 open(10, file='Vtable', status='old', form='formatted', iostat=ierr)
71 ! Check to see that the OPEN worked without error.
74 inquire(file='Vtable', exist=LEXIST)
75 call mprintf(.true.,STDOUT," ***** ERROR in Subroutine PARSE_TABLE:")
76 call mprintf(.true.,LOGFILE," ***** ERROR in Subroutine PARSE_TABLE:")
78 call mprintf(.true.,STDOUT,"Problem opening file Vtable.")
79 call mprintf(.true.,STDOUT,"File ''Vtable'' does not exist.")
80 call mprintf(.true.,LOGFILE,"Problem opening file Vtable.")
81 call mprintf(.true.,LOGFILE,"File ''Vtable'' does not exist.")
83 call mprintf(.true.,STDOUT,"Problem opening file Vtable.")
84 call mprintf(.true.,STDOUT,"File Vtable exists, but Fortran OPEN statement")
85 call mprintf(.true.,STDOUT,"failed with error %i",i1=ierr)
86 call mprintf(.true.,LOGFILE,"Problem opening file Vtable.")
87 call mprintf(.true.,LOGFILE,"File Vtable exists, but Fortran OPEN statement")
88 call mprintf(.true.,LOGFILE,"failed with error %i",i1=ierr)
90 call mprintf(.true.,ERROR," ***** Stopping in Subroutine PARSE_TABLE")
93 ! First, read past the headers, i.e., skip lines until we hit the first
94 ! line beginning with '-'
95 do while (string(1:1).ne.'-')
96 read(10,'(A255)', iostat=ierr) string
97 call mprintf ((ierr /= 0),ERROR,"Read error 1 in PARSE_TABLE.")
101 ! Now interpret everything from here to the next '-' line:
103 RDLOOP : do while (string(1:1).ne.'-')
104 read(10,'(A255)', iostat=ierr) string
105 call mprintf ((ierr /= 0),ERROR,"Read error 2 in PARSE_TABLE.")
106 if (string(1:1).eq.'#') cycle RDLOOP
107 if (len_trim(string) == 0) cycle RDLOOP
108 if (string(1:1).eq.'-') then
109 ! Skip over internal header lines
111 read(10,'(A255)', iostat=ierr) string
112 if (ierr /= 0) exit RDLOOP
113 if (len_trim(string) == 0) then
119 do while (string(1:1).ne.'-')
120 read(10,'(A255)', iostat=ierr) string
121 call mprintf ((ierr /= 0),ERROR,"Read error 3 in PARSE_TABLE.")
125 elseif (string(1:1).ne.'-') then
126 ! This is a line of values to interpret and parse.
127 maxvar = maxvar + 1 ! increment the variable count
129 ! --- Determine Grib1 or Grib2
130 ! If there are seven fields this is a Grib1 Vtable,
131 ! if there are eleven fields this is a Grib2 Vtable.
136 do j = 1, vtable_columns
137 ! The fields are delimited by '|'
138 jbar = index(string(jstart:255),'|') + jstart - 2
140 if (jstart.gt.jmax) then
148 call mprintf((tot_bars.eq.7.and.vtable_columns.eq.11),ERROR, &
149 'Vtable does not contain Grib2 decoding information.'// &
150 '11 columns of information is expected.'// &
151 '*** stopping parse_table ***')
155 ! There are seven fields (Grib1) or eleven fields (Grib2) to each line.
156 PLOOP : do i = 1, vtable_columns
157 ! The fields are delimited by '|'
159 ibar = index(string(istart:255),'|') + istart - 2
162 ! The first field is the Grib1 param code number:
164 if (string(istart:ibar) == ' ') then
165 gcode(maxvar) = blankcode
166 elseif (scan(string(istart:ibar),'*') /= 0) then
167 call mprintf(.true.,ERROR,'Parse_table: Please give a '// &
168 'Grib1 parm code rather than $ in the first column of Vtable '// &
169 '*** stopping in parse_table ***')
171 read(string(istart:ibar), * ) gcode(maxvar)
175 ! The second field is the Grib1 level type:
177 if (string(istart:ibar) == ' ') then
178 if (lcode(maxvar) /= blankcode) then
179 call mprintf(.true.,ERROR,'Parse_table: '// &
180 'Please supply a Grib1 level type in the Vtable: %s '// &
181 '*** stopping in parse_table ***',s1=string)
183 lcode(maxvar) = blankcode
185 elseif (scan(string(istart:ibar),'*') /= 0) then
186 call mprintf(.true.,ERROR,'Parse_table: '// &
187 "Used a * in Grib1 level type...don't do this! "// &
188 '*** stopping in parse_table ***')
190 read(string(istart:ibar), *) lcode(maxvar)
194 ! The third field is the Level 1 value, which may be '*':
196 if (string(istart:ibar) == ' ') then
197 level1(maxvar) = blankcode
198 elseif (scan(string(istart:ibar),'*') == 0) then
199 read(string(istart:ibar), *) level1(maxvar)
201 level1(maxvar) = splatcode
205 ! The fourth field is the Level 2 value, which may be blank:
207 if (string(istart:ibar) == ' ') then
208 if ( (lcode(maxvar) == 112) .or.&
209 (lcode(maxvar) == 116) ) then
210 call mprintf(.true.,ERROR,'Parse_table: '// &
211 'Level Code expects two Level values. '// &
212 '*** stopping in parse_table ***')
214 level2(maxvar) = blankcode
216 elseif (scan(string(istart:ibar),'*') /= 0) then
217 call mprintf(.true.,ERROR,'Parse_table: '// &
218 'Please give a Level 2 value (or blank), rather * in Vtable column 4 '// &
219 '*** stopping in parse_table ***')
221 read(string(istart:ibar), *) level2(maxvar)
225 ! The fifth field is the param name:
227 if (string(istart:ibar).ne.' ') then
229 do while (string(istart+nstart:istart+nstart).eq.' ')
232 namvar(maxvar) = string(istart+nstart:ibar)
234 call mprintf(.true.,ERROR,'Parse_table: '// &
235 'A field name is missing in the Vtable. '// &
236 '*** stopping in parse_table ***')
240 ! The sixth field is the Units string, which may be blank:
242 if (string(istart:ibar).ne.' ') then
244 do while (string(istart+nstart:istart+nstart).eq.' ')
247 Dunits(maxvar) = string(istart+nstart:ibar)
253 ! The seventh field is the description string, which may be blank:
255 if (string(istart:ibar).ne.' ') then
257 do while (string(istart+nstart:istart+nstart).eq.' ')
260 Ddesc(maxvar) = string(istart+nstart:ibar)
262 ! If the description string is not blank, this is a
263 ! field we want to output. In that case, copy the
264 ! param name to the MAXOUT array:
266 nameout(maxout) = namvar(maxvar)
267 unitout(maxout) = Dunits(maxvar)
268 descout(maxout) = Ddesc(maxvar)
275 ! The eighth field is the Grib2 Product Discipline (see the
276 ! Product Definition Template, Table 4.2).
279 !read(string(istart:ibar), * ,eor=995) g2code(1,maxvar)
281 if (string(istart:ibar) == ' ') then
282 g2code(1,maxvar) = blankcode
283 elseif (scan(string(istart:ibar),'*') /= 0) then
284 call mprintf(.true.,STDOUT," ERROR reading Grib2 Discipline")
285 call mprintf(.true.,STDOUT, &
286 "This Grib2 Vtable line is incorrectly specified:")
287 call mprintf(.true.,STDOUT," %s",s1=string)
288 call mprintf(.true.,LOGFILE," ERROR reading Grib2 Discipline")
289 call mprintf(.true.,LOGFILE, &
290 "This Grib2 Vtable line is incorrectly specified:")
291 call mprintf(.true.,LOGFILE," %s",s1=string)
292 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
294 read(string(istart:ibar), *) g2code(1,maxvar)
298 ! The ninth field is the Grib2 Parameter Category per Discipline.
300 if (string(istart:ibar) == ' ') then
301 g2code(2,maxvar) = blankcode
302 elseif (scan(string(istart:ibar),'*') /= 0) then
303 call mprintf(.true.,STDOUT," ERROR reading Grib2 Category")
304 call mprintf(.true.,STDOUT, &
305 "This Grib2 Vtable line is incorrectly specified:")
306 call mprintf(.true.,STDOUT," %s",s1=string)
307 call mprintf(.true.,LOGFILE," ERROR reading Grib2 Category")
308 call mprintf(.true.,LOGFILE, &
309 "This Grib2 Vtable line is incorrectly specified:")
310 call mprintf(.true.,LOGFILE," %s",s1=string)
311 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
313 read(string(istart:ibar), * ) g2code(2,maxvar)
316 elseif (i.eq.10) then
317 ! The tenth field is the Grib2 Parameter Number per Category.
319 if (string(istart:ibar) == ' ') then
320 g2code(3,maxvar) = blankcode
321 elseif (scan(string(istart:ibar),'*') /= 0) then
322 call mprintf(.true.,STDOUT, &
323 " ERROR reading Grib2 Parameter Number ")
324 call mprintf(.true.,STDOUT, &
325 "This Grib2 Vtable line is incorrectly specified:")
326 call mprintf(.true.,STDOUT," %s",s1=string)
327 call mprintf(.true.,LOGFILE, &
328 " ERROR reading Grib2 Parameter Number ")
329 call mprintf(.true.,LOGFILE, &
330 "This Grib2 Vtable line is incorrectly specified:")
331 call mprintf(.true.,LOGFILE," %s",s1=string)
332 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
334 read(string(istart:ibar), * ) g2code(3,maxvar)
337 elseif (i.eq.11) then
338 ! The eleventh field is the Grib2 Level Type (see the Product
339 ! Definition Template, Table 4.5).
341 if (string(istart:ibar) == ' ') then
342 if (g2code(4,maxvar) /= blankcode) then
343 call mprintf(.true.,STDOUT," ERROR reading Grib2 Level Type ")
344 call mprintf(.true.,STDOUT, &
345 "This Grib2 Vtable line is incorrectly specified:")
346 call mprintf(.true.,STDOUT," %s",s1=string)
347 call mprintf(.true.,LOGFILE," ERROR reading Grib2 Level Type ")
348 call mprintf(.true.,LOGFILE, &
349 "This Grib2 Vtable line is incorrectly specified:")
350 call mprintf(.true.,LOGFILE," %s",s1=string)
351 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
353 g2code(4,maxvar) = blankcode
355 elseif (scan(string(istart:ibar),'*') /= 0) then
356 call mprintf(.true.,STDOUT,"ERROR in Subroutine Parse_table: ")
357 call mprintf(.true.,STDOUT, &
358 "Used a * in Grib2 level type...don't do this! ")
359 call mprintf(.true.,STDOUT," %s ",s1=string)
360 call mprintf(.true.,LOGFILE,"ERROR in Subroutine Parse_table: ")
361 call mprintf(.true.,LOGFILE, &
362 "Used a * in Grib2 level type...don't do this! ")
363 call mprintf(.true.,LOGFILE," %s ",s1=string)
364 call mprintf(.true.,ERROR," ***** Abort in Subroutine PARSE_TABLE")
366 read(string(istart:ibar), *) g2code(4,maxvar)
373 enddo PLOOP ! 1,vtable_columns
377 ! Now we have finished reading the file.
380 ! Now remove duplicates from the NAMEOUT array. Duplicates may arise
381 ! when we have the same name referred to by different level or parameter
382 ! codes in some dataset.
387 if ((nameout(i).eq.nameout(j)).and.(nameout(j).ne.' ')) then
388 call mprintf(.true.,DEBUG, &
389 "Duplicate name. Removing %s from output list.",s1=nameout(j))
390 nameout(j:maxlines-1) = nameout(j+1:maxlines)
391 unitout(j:maxlines-1) = unitout(j+1:maxlines)
392 descout(j:maxlines-1) = descout(j+1:maxlines)
398 ! Compute a priority level based on position in the table:
401 ! Priorities are used only for surface fields. If it is not a
402 ! surface fields, the priority is assigned a value of 100.
404 ! For surface fields, priorities are assigned values of 100, 101,
405 ! 102, etc. in the order the field names appear in the Vtable.
409 if (lcode(i).eq.105) then
410 ipcount = ipcount + 1
412 elseif (lcode(i).eq.116.and.level1(i).le.50.and.level2(i).eq.0) then
413 ipcount = ipcount + 1
420 if (debug_level .gt. 0) then
421 write(*,'(//"Read from file ''Vtable'' by subroutine PARSE_TABLE:")')
423 if (vtable_columns.eq.11) then
424 write(*,'(4I6, 3x,A10, 4I6)')&
425 gcode(i), lcode(i), level1(i), level2(i), namvar(i), &
426 g2code(1,i), g2code(2,i), g2code(3,i), g2code(4,i)
428 write(*,'(4I6, 3x,A10)')&
429 gcode(i), lcode(i), level1(i), level2(i), namvar(i)
435 end subroutine parse_table