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)
53 integer :: debug_level
55 character(LEN=255) :: string = ' '
57 integer :: istart, ibar, i, j, ipcount
58 integer :: jstart, jbar, jmax, tot_bars
59 integer :: vtable_columns
60 integer :: nstart, maxtmp
62 character(len=9) :: tmp9
69 ! Open the file called "Vtable"
71 open(10, file='Vtable', status='old', form='formatted', iostat=ierr)
73 ! Check to see that the OPEN worked without error.
76 inquire(file='Vtable', exist=LEXIST)
77 call mprintf(.true.,STDOUT," ***** ERROR in Subroutine PARSE_TABLE:")
78 call mprintf(.true.,LOGFILE," ***** ERROR in Subroutine PARSE_TABLE:")
80 call mprintf(.true.,STDOUT,"Problem opening file Vtable.")
81 call mprintf(.true.,STDOUT,"File ''Vtable'' does not exist.")
82 call mprintf(.true.,LOGFILE,"Problem opening file Vtable.")
83 call mprintf(.true.,LOGFILE,"File ''Vtable'' does not exist.")
85 call mprintf(.true.,STDOUT,"Problem opening file Vtable.")
86 call mprintf(.true.,STDOUT,"File Vtable exists, but Fortran OPEN statement")
87 call mprintf(.true.,STDOUT,"failed with error %i",i1=ierr)
88 call mprintf(.true.,LOGFILE,"Problem opening file Vtable.")
89 call mprintf(.true.,LOGFILE,"File Vtable exists, but Fortran OPEN statement")
90 call mprintf(.true.,LOGFILE,"failed with error %i",i1=ierr)
92 call mprintf(.true.,ERROR," ***** Stopping in Subroutine PARSE_TABLE")
95 ! First, read past the headers, i.e., skip lines until we hit the first
96 ! line beginning with '-'
97 do while (string(1:1).ne.'-')
98 read(10,'(A255)', iostat=ierr) string
99 call mprintf ((ierr /= 0),ERROR,"Read error 1 in PARSE_TABLE.")
103 ! Now interpret everything from here to the next '-' line:
105 RDLOOP : do while (string(1:1).ne.'-')
106 read(10,'(A255)', iostat=ierr) string
107 call mprintf ((ierr /= 0),ERROR,"Read error 2 in PARSE_TABLE.")
108 if (string(1:1).eq.'#') cycle RDLOOP
109 if (len_trim(string) == 0) cycle RDLOOP
110 if (string(1:1).eq.'-') then
111 ! Skip over internal header lines
113 read(10,'(A255)', iostat=ierr) string
114 if (ierr /= 0) exit RDLOOP
115 if (len_trim(string) == 0) then
117 else if (string(1:1) == '#') then
123 do while (string(1:1).ne.'-')
124 read(10,'(A255)', iostat=ierr) string
125 call mprintf ((ierr /= 0),ERROR,"Read error 3 in PARSE_TABLE.")
129 elseif (string(1:1).ne.'-') then
130 ! This is a line of values to interpret and parse.
131 maxvar = maxvar + 1 ! increment the variable count
133 ! --- Determine Grib1 or Grib2
134 ! If there are seven fields this is a Grib1 Vtable,
135 ! if there are eleven fields this is a Grib2 Vtable.
140 do j = 1, vtable_columns
141 ! The fields are delimited by '|'
142 jbar = index(string(jstart:255),'|') + jstart - 2
144 if (jstart.gt.jmax) then
152 call mprintf((tot_bars.eq.7.and.vtable_columns.ge.11),ERROR, &
153 'Vtable does not contain Grib2 decoding information.'// &
154 ' 11 or 12 columns of information is expected.'// &
155 ' *** stopping parse_table ***')
159 ! There are seven fields (Grib1) or eleven fields (Grib2) to each line.
160 PLOOP : do i = 1, vtable_columns
161 ! The fields are delimited by '|'
163 ibar = index(string(istart:255),'|') + istart - 2
166 ! The first field is the Grib1 param code number:
168 if (string(istart:ibar) == ' ') then
169 gcode(maxvar) = blankcode
170 elseif (scan(string(istart:ibar),'*') /= 0) then
171 call mprintf(.true.,ERROR,'Parse_table: Please give a '// &
172 'Grib1 parm code rather than $ in the first column of Vtable '// &
173 '*** stopping in parse_table ***')
175 read(string(istart:ibar), * ) gcode(maxvar)
179 ! The second field is the Grib1 level type:
181 if (string(istart:ibar) == ' ') then
182 if (lcode(maxvar) /= blankcode) then
183 call mprintf(.true.,ERROR,'Parse_table: '// &
184 'Please supply a Grib1 level type in the Vtable: %s '// &
185 '*** stopping in parse_table ***',s1=string)
187 lcode(maxvar) = blankcode
189 elseif (scan(string(istart:ibar),'*') /= 0) then
190 call mprintf(.true.,ERROR,'Parse_table: '// &
191 "Used a * in Grib1 level type...don't do this! "// &
192 '*** stopping in parse_table ***')
194 read(string(istart:ibar), *) lcode(maxvar)
198 ! The third field is the Level 1 value, which may be '*':
200 if (string(istart:ibar) == ' ') then
201 level1(maxvar) = blankcode
202 elseif (scan(string(istart:ibar),'*') == 0) then
203 read(string(istart:ibar), *) level1(maxvar)
205 level1(maxvar) = splatcode
209 ! The fourth field is the Level 2 value, which may be blank:
211 if (string(istart:ibar) == ' ') then
212 if ( (lcode(maxvar) == 112) .or.&
213 (lcode(maxvar) == 116) ) then
214 call mprintf(.true.,ERROR,'Parse_table: '// &
215 'Level Code expects two Level values. '// &
216 '*** stopping in parse_table ***')
218 level2(maxvar) = blankcode
220 elseif (scan(string(istart:ibar),'*') /= 0) then
221 call mprintf(.true.,ERROR,'Parse_table: '// &
222 'Please give a Level 2 value (or blank), rather * in Vtable column 4 '// &
223 '*** stopping in parse_table ***')
225 read(string(istart:ibar), *) level2(maxvar)
229 ! The fifth field is the param name:
231 if (string(istart:ibar).ne.' ') then
233 do while (string(istart+nstart:istart+nstart).eq.' ')
236 namvar(maxvar) = string(istart+nstart:ibar)
238 call mprintf(.true.,ERROR,'Parse_table: '// &
239 'A field name is missing in the Vtable. '// &
240 '*** stopping in parse_table ***')
244 ! The sixth field is the Units string, which may be blank:
246 if (string(istart:ibar).ne.' ') then
248 do while (string(istart+nstart:istart+nstart).eq.' ')
251 Dunits(maxvar) = string(istart+nstart:ibar)
257 ! The seventh field is the description string, which may be blank:
259 if (string(istart:ibar).ne.' ') then
261 do while (string(istart+nstart:istart+nstart).eq.' ')
264 Ddesc(maxvar) = string(istart+nstart:ibar)
266 ! If the description string is not blank, this is a
267 ! field we want to output. In that case, copy the
268 ! param name to the MAXOUT array:
270 nameout(maxout) = namvar(maxvar)
271 unitout(maxout) = Dunits(maxvar)
272 descout(maxout) = Ddesc(maxvar)
279 ! The eighth field is the Grib2 Product Discipline (see the
280 ! Product Definition Template, Table 4.2).
283 !read(string(istart:ibar), * ,eor=995) g2code(1,maxvar)
285 if (string(istart:ibar) == ' ') then
286 g2code(1,maxvar) = blankcode
287 elseif (scan(string(istart:ibar),'*') /= 0) then
288 call mprintf(.true.,STDOUT," ERROR reading Grib2 Discipline")
289 call mprintf(.true.,STDOUT, &
290 "This Grib2 Vtable line is incorrectly specified:")
291 call mprintf(.true.,STDOUT," %s",s1=string)
292 call mprintf(.true.,LOGFILE," ERROR reading Grib2 Discipline")
293 call mprintf(.true.,LOGFILE, &
294 "This Grib2 Vtable line is incorrectly specified:")
295 call mprintf(.true.,LOGFILE," %s",s1=string)
296 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
298 read(string(istart:ibar), *) g2code(1,maxvar)
302 ! The ninth field is the Grib2 Parameter Category per Discipline.
304 if (string(istart:ibar) == ' ') then
305 g2code(2,maxvar) = blankcode
306 elseif (scan(string(istart:ibar),'*') /= 0) then
307 call mprintf(.true.,STDOUT," ERROR reading Grib2 Category")
308 call mprintf(.true.,STDOUT, &
309 "This Grib2 Vtable line is incorrectly specified:")
310 call mprintf(.true.,STDOUT," %s",s1=string)
311 call mprintf(.true.,LOGFILE," ERROR reading Grib2 Category")
312 call mprintf(.true.,LOGFILE, &
313 "This Grib2 Vtable line is incorrectly specified:")
314 call mprintf(.true.,LOGFILE," %s",s1=string)
315 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
317 read(string(istart:ibar), * ) g2code(2,maxvar)
320 elseif (i.eq.10) then
321 ! The tenth field is the Grib2 Parameter Number per Category.
323 if (string(istart:ibar) == ' ') then
324 g2code(3,maxvar) = blankcode
325 elseif (scan(string(istart:ibar),'*') /= 0) then
326 call mprintf(.true.,STDOUT, &
327 " ERROR reading Grib2 Parameter Number ")
328 call mprintf(.true.,STDOUT, &
329 "This Grib2 Vtable line is incorrectly specified:")
330 call mprintf(.true.,STDOUT," %s",s1=string)
331 call mprintf(.true.,LOGFILE, &
332 " ERROR reading Grib2 Parameter Number ")
333 call mprintf(.true.,LOGFILE, &
334 "This Grib2 Vtable line is incorrectly specified:")
335 call mprintf(.true.,LOGFILE," %s",s1=string)
336 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
338 read(string(istart:ibar), * ) g2code(3,maxvar)
341 elseif (i.eq.11) then
342 ! The eleventh field is the Grib2 Level Type (see the Product
343 ! Definition Template, Table 4.5).
345 if (string(istart:ibar) == ' ') then
346 if (g2code(4,maxvar) /= blankcode) then
347 call mprintf(.true.,STDOUT," ERROR reading Grib2 Level Type ")
348 call mprintf(.true.,STDOUT, &
349 "This Grib2 Vtable line is incorrectly specified:")
350 call mprintf(.true.,STDOUT," %s",s1=string)
351 call mprintf(.true.,LOGFILE," ERROR reading Grib2 Level Type ")
352 call mprintf(.true.,LOGFILE, &
353 "This Grib2 Vtable line is incorrectly specified:")
354 call mprintf(.true.,LOGFILE," %s",s1=string)
355 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
357 g2code(4,maxvar) = blankcode
359 elseif (scan(string(istart:ibar),'*') /= 0) then
360 call mprintf(.true.,STDOUT,"ERROR in Subroutine Parse_table: ")
361 call mprintf(.true.,STDOUT, &
362 "Used a * in Grib2 level type...don't do this! ")
363 call mprintf(.true.,STDOUT," %s ",s1=string)
364 call mprintf(.true.,LOGFILE,"ERROR in Subroutine Parse_table: ")
365 call mprintf(.true.,LOGFILE, &
366 "Used a * in Grib2 level type...don't do this! ")
367 call mprintf(.true.,LOGFILE," %s ",s1=string)
368 call mprintf(.true.,ERROR," ***** Abort in Subroutine PARSE_TABLE")
370 read(string(istart:ibar), *) g2code(4,maxvar)
373 elseif (i.eq.12) then
374 ! The twelfth field is the Grib2 Product Definition Template number
375 ! Defaults to template 4.0, an instantaneous horizontal field.
376 ! The only other supported value is 8 - an accumulated or averaged field.
378 if (istart .lt. ibar) then
379 if (string(istart:ibar) == ' ') then
381 elseif (scan(string(istart:ibar),'*') /= 0) then
382 call mprintf(.true.,STDOUT, &
383 " ERROR reading Grib2 Parameter Number ")
384 call mprintf(.true.,STDOUT, &
385 "This Grib2 Vtable line is incorrectly specified:")
386 call mprintf(.true.,STDOUT," %s",s1=string)
387 call mprintf(.true.,LOGFILE, &
388 " ERROR reading Grib2 Parameter Number ")
389 call mprintf(.true.,LOGFILE, &
390 "This Grib2 Vtable line is incorrectly specified:")
391 call mprintf(.true.,LOGFILE," %s",s1=string)
392 call mprintf(.true.,ERROR,"Stopping in PARSE_TABLE")
394 read(string(istart:ibar), * ) g2code(5,maxvar)
396 else ! occurs when 11 columns are in the Vtable rather than 12.
404 enddo PLOOP ! 1,vtable_columns
408 ! Now we have finished reading the file.
411 ! Now remove duplicates from the NAMEOUT array. Duplicates may arise
412 ! when we have the same name referred to by different level or parameter
413 ! codes in some dataset.
418 if ((nameout(i).eq.nameout(j)).and.(nameout(j).ne.' ')) then
419 call mprintf(.true.,DEBUG, &
420 "Duplicate name. Removing %s from output list.",s1=nameout(j))
421 nameout(j:maxlines-1) = nameout(j+1:maxlines)
422 unitout(j:maxlines-1) = unitout(j+1:maxlines)
423 descout(j:maxlines-1) = descout(j+1:maxlines)
429 ! Compute a priority level based on position in the table:
432 ! Priorities are used only for surface fields. If it is not a
433 ! surface fields, the priority is assigned a value of 100.
435 ! For surface fields, priorities are assigned values of 100, 101,
436 ! 102, etc. in the order the field names appear in the Vtable.
440 if ((lcode(i).eq.105).or.(lcode(i).eq.118)) then
441 ipcount = ipcount + 1
443 elseif (lcode(i).eq.116.and.level1(i).le.50.and.level2(i).eq.0) then
444 ipcount = ipcount + 1
451 if (debug_level .gt. 0) then
452 write(*,'(//"Read from file ''Vtable'' by subroutine PARSE_TABLE:")')
453 call mprintf(.true.,DEBUG, &
454 "Read from file Vtable by subroutine PARSE_TABLE:")
456 if (vtable_columns.ge.11) then
457 write(*,'(4I6, 3x,A10, 5I6)')&
458 gcode(i), lcode(i), level1(i), level2(i), namvar(i), &
459 g2code(1,i), g2code(2,i), g2code(3,i), g2code(4,i), g2code(5,i)
460 write(tmp9,'(i9)') gcode(i)
461 call mprintf(.true.,DEBUG,'%s ',s1=tmp9(4:9),newline=.false.)
462 write(tmp9,'(i9)') lcode(i)
463 call mprintf(.true.,DEBUG,'%s ',s1=tmp9(4:9),newline=.false.)
464 write(tmp9,'(i9)') level1(i)
465 call mprintf(.true.,DEBUG,'%s ',s1=tmp9(4:9),newline=.false.)
466 write(tmp9,'(i9)') level2(i)
467 call mprintf(.true.,DEBUG,'%s ',s1=tmp9(4:9),newline=.false.)
468 write(tmp9,'(a9)') namvar(i)(1:9)
469 call right_justify(tmp9,9)
470 call mprintf(.true.,DEBUG,tmp9,newline=.false.)
472 write(tmp9,'(i9)') g2code(j,i)
473 call mprintf(.true.,DEBUG,'%s ',s1=tmp9(4:9),newline=.false.)
475 call mprintf(.true.,DEBUG,' ',newline=.true.)
477 write(*,'(4I6, 3x,A10)')&
478 gcode(i), lcode(i), level1(i), level2(i), namvar(i)
484 end subroutine parse_table