1 | !***************************************************************************** |
---|
2 | ! |
---|
3 | ! Routine to fill a grib2map structure (linked list). |
---|
4 | ! |
---|
5 | !***************************************************************************** |
---|
6 | |
---|
7 | subroutine load_grib2map(filename, msg, ierr) |
---|
8 | |
---|
9 | USE grib2tbls_types |
---|
10 | Implicit None |
---|
11 | |
---|
12 | character*(*), intent(in) :: filename |
---|
13 | character*(*), intent(inout) :: msg |
---|
14 | integer , intent(out) :: ierr |
---|
15 | integer :: status = 0 |
---|
16 | integer :: fileunit |
---|
17 | logical :: foundunit |
---|
18 | character*(maxLineSize) :: line |
---|
19 | integer :: firstval |
---|
20 | integer :: numtables = 0 |
---|
21 | character*(1) :: delim |
---|
22 | integer :: lastpos |
---|
23 | integer :: pos |
---|
24 | integer :: idx |
---|
25 | integer :: end |
---|
26 | logical :: lerr |
---|
27 | |
---|
28 | ! Open the file |
---|
29 | |
---|
30 | ! First pass: |
---|
31 | ! Scan the file to determine how many tables are included, and how many |
---|
32 | ! entries are in each table. |
---|
33 | ! |
---|
34 | |
---|
35 | ! Find an open fileunit |
---|
36 | foundunit = .false. |
---|
37 | do fileunit = 10,100 |
---|
38 | inquire(unit=fileunit,opened=lerr) |
---|
39 | if (lerr .eqv. .false.) then |
---|
40 | foundunit = .true. |
---|
41 | exit |
---|
42 | endif |
---|
43 | enddo |
---|
44 | if (foundunit .neqv. .true.) then |
---|
45 | write(msg, *)'Could not find unit to open ',filename |
---|
46 | ierr = -1 |
---|
47 | return |
---|
48 | endif |
---|
49 | |
---|
50 | ! Open the file |
---|
51 | open ( unit = fileunit, file=filename, status = 'old', iostat = status) |
---|
52 | if (status .ne. 0) then |
---|
53 | write(msg, *)'Could not open file ',filename |
---|
54 | ierr = -1 |
---|
55 | return |
---|
56 | endif |
---|
57 | |
---|
58 | ! Loop through each line to count the number of tables and entries in |
---|
59 | ! each table. |
---|
60 | |
---|
61 | READLINE: do |
---|
62 | ! |
---|
63 | ! Read the line, skip line if line is comment, blank or invalid |
---|
64 | ! |
---|
65 | read(fileunit,'(A)',iostat=status) line |
---|
66 | line = adjustl(line) |
---|
67 | if (status .lt. 0) then |
---|
68 | exit |
---|
69 | endif |
---|
70 | if (len_trim(line) .eq. 0) then |
---|
71 | cycle READLINE |
---|
72 | endif |
---|
73 | if (line(1:1) .eq. '#') then |
---|
74 | cycle READLINE |
---|
75 | endif |
---|
76 | |
---|
77 | ! |
---|
78 | ! Read the first value in the line |
---|
79 | ! |
---|
80 | read(line,*,iostat=status) firstval |
---|
81 | if (status .ne. 0) then |
---|
82 | print *,'Skipping Invalid line in',trim(filename),':' |
---|
83 | print *,'''',trim(line),'''' |
---|
84 | cycle READLINE |
---|
85 | endif |
---|
86 | |
---|
87 | |
---|
88 | ! |
---|
89 | ! If the first value is -1, weve found a new table. Allocate |
---|
90 | ! a new member in the linked list, and add the information |
---|
91 | ! to that member |
---|
92 | ! |
---|
93 | if (firstval .eq. -1) then |
---|
94 | numtables = numtables + 1 |
---|
95 | |
---|
96 | ! |
---|
97 | ! Create and allocate the next member of the linked list |
---|
98 | ! |
---|
99 | if (.NOT. ASSOCIATED(TblHead)) THEN |
---|
100 | ALLOCATE (TblHead, stat=status) |
---|
101 | if (status .ne. 0) then |
---|
102 | print *,'Could not allocate space for TblHead' |
---|
103 | exit READLINE |
---|
104 | endif |
---|
105 | TblTail => TblHead |
---|
106 | else |
---|
107 | ALLOCATE (TblTail%next, STAT=status) |
---|
108 | if (status .ne. 0) then |
---|
109 | print *,'Could not allocate space for TblTail%next, continuing' |
---|
110 | cycle READLINE |
---|
111 | endif |
---|
112 | TblTail%previous => TblTail |
---|
113 | TblTail => TblTail%next |
---|
114 | endif |
---|
115 | nullify(TblTail%next) |
---|
116 | nullify(TblTail%ParmHead) |
---|
117 | |
---|
118 | ! |
---|
119 | ! Parse the header line |
---|
120 | ! |
---|
121 | lastpos = 0 |
---|
122 | do idx = 1,5 |
---|
123 | pos = index(line(lastpos+1:maxLineSize), "|") |
---|
124 | |
---|
125 | if (pos .lt. 0) then |
---|
126 | print *,'Found invalid header line: ' |
---|
127 | print *,'''',trim(line),'''' |
---|
128 | if (associated(TblTail%previous)) then |
---|
129 | TblTail => TblTail%previous |
---|
130 | else |
---|
131 | nullify(TblTail) |
---|
132 | endif |
---|
133 | cycle READLINE |
---|
134 | endif |
---|
135 | |
---|
136 | SELECT CASE (idx) |
---|
137 | CASE (1) |
---|
138 | ! Do nothing, since this is just the indicator value |
---|
139 | CASE (2) |
---|
140 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%center |
---|
141 | if (status .ne. 0) then |
---|
142 | print *,'Found invalid header line: ' |
---|
143 | print *,'''',trim(line),'''' |
---|
144 | cycle READLINE |
---|
145 | endif |
---|
146 | CASE (3) |
---|
147 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%subcenter |
---|
148 | if (status .ne. 0) then |
---|
149 | print *,'Found invalid header line: ' |
---|
150 | print *,'''',trim(line),'''' |
---|
151 | cycle READLINE |
---|
152 | endif |
---|
153 | CASE (4) |
---|
154 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%MasterTblV |
---|
155 | if (status .ne. 0) then |
---|
156 | print *,'Found invalid header line: ' |
---|
157 | print *,'''',trim(line),'''' |
---|
158 | cycle READLINE |
---|
159 | endif |
---|
160 | CASE (5) |
---|
161 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%LocalTblV |
---|
162 | if (status .ne. 0) then |
---|
163 | print *,'Found invalid header line: ' |
---|
164 | print *,'''',trim(line),'''' |
---|
165 | cycle READLINE |
---|
166 | endif |
---|
167 | END SELECT |
---|
168 | |
---|
169 | lastpos = lastpos+pos |
---|
170 | |
---|
171 | enddo |
---|
172 | |
---|
173 | #ifdef TEST |
---|
174 | ! Test |
---|
175 | print *,'Header Line: ' |
---|
176 | print *,TblTail%center, TblTail%subcenter, TblTail%MasterTblV, & |
---|
177 | TblTail%LocalTblV |
---|
178 | #endif |
---|
179 | |
---|
180 | |
---|
181 | ! |
---|
182 | ! We found the header, cycle so that the header is not interpereted |
---|
183 | ! as a parameter line. |
---|
184 | ! |
---|
185 | cycle READLINE |
---|
186 | |
---|
187 | endif |
---|
188 | |
---|
189 | if (.NOT. ASSOCIATED(TblTail%ParmHead)) then |
---|
190 | ALLOCATE (TblTail%ParmHead, stat=status) |
---|
191 | if (status .ne. 0) then |
---|
192 | print *,'Could not allocate space for TblTail%ParmHead, continuing' |
---|
193 | cycle READLINE |
---|
194 | endif |
---|
195 | TblTail%ParmTail => TblTail%ParmHead |
---|
196 | else |
---|
197 | ALLOCATE (TblTail%ParmTail%next, STAT=status) |
---|
198 | if (status .ne. 0) then |
---|
199 | print *,'Could not allocate space for TblTail%ParmTail%next, continuing' |
---|
200 | cycle READLINE |
---|
201 | endif |
---|
202 | TblTail%ParmTail%previous => TblTail%ParmTail |
---|
203 | TblTail%ParmTail => TblTail%ParmTail%next |
---|
204 | endif |
---|
205 | nullify(TblTail%ParmTail%next) |
---|
206 | |
---|
207 | ! |
---|
208 | ! Parse the Parameter line |
---|
209 | ! |
---|
210 | lastpos = 0 |
---|
211 | do idx = 1,7 |
---|
212 | pos = index(line(lastpos+1:maxLineSize), "|") |
---|
213 | |
---|
214 | if (pos .lt. 0) then |
---|
215 | print *,'Found invalid header line: ' |
---|
216 | print *,'''',trim(line),'''' |
---|
217 | if (associated(TblTail%previous)) then |
---|
218 | TblTail => TblTail%previous |
---|
219 | else |
---|
220 | nullify(TblTail) |
---|
221 | endif |
---|
222 | cycle READLINE |
---|
223 | endif |
---|
224 | |
---|
225 | SELECT CASE (idx) |
---|
226 | CASE (1) |
---|
227 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%ParmTail%Disc |
---|
228 | if (status .ne. 0) then |
---|
229 | print *,'Found invalid line: ' |
---|
230 | print *,'''',trim(line),'''' |
---|
231 | cycle READLINE |
---|
232 | endif |
---|
233 | CASE (2) |
---|
234 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%ParmTail%Category |
---|
235 | if (status .ne. 0) then |
---|
236 | print *,'Found invalid line: ' |
---|
237 | print *,'''',trim(line),'''' |
---|
238 | cycle READLINE |
---|
239 | endif |
---|
240 | CASE (3) |
---|
241 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%ParmTail%ParmNum |
---|
242 | if (status .ne. 0) then |
---|
243 | print *,'Found invalid line: ' |
---|
244 | print *,'''',trim(line),'''' |
---|
245 | cycle READLINE |
---|
246 | endif |
---|
247 | CASE (4) |
---|
248 | TblTail%ParmTail%WRFNameString = & |
---|
249 | trim(adjustl(line(lastpos+1:lastpos+pos-1))) |
---|
250 | CASE (5) |
---|
251 | TblTail%ParmTail%Description = & |
---|
252 | trim(adjustl(line(lastpos+1:lastpos+pos-1))) |
---|
253 | CASE (6) |
---|
254 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%ParmTail%DecScl |
---|
255 | if (status .ne. 0) then |
---|
256 | print *,'Found invalid line: ' |
---|
257 | print *,'''',trim(line),'''' |
---|
258 | cycle READLINE |
---|
259 | endif |
---|
260 | CASE (7) |
---|
261 | read(line(lastpos+1:lastpos+pos-1),*,iostat=status) TblTail%ParmTail%BinScl |
---|
262 | if (status .ne. 0) then |
---|
263 | print *,'Found invalid line: ' |
---|
264 | print *,'''',trim(line),'''' |
---|
265 | cycle READLINE |
---|
266 | endif |
---|
267 | END SELECT |
---|
268 | |
---|
269 | lastpos = lastpos+pos |
---|
270 | |
---|
271 | enddo |
---|
272 | |
---|
273 | #ifdef TEST |
---|
274 | ! Test Code |
---|
275 | delim = '|' |
---|
276 | write(6,'(I4,A1,I4,A1,I4,A1,A12,A1,A42,A1,I4,A1,I4,A1)') & |
---|
277 | TblTail%ParmTail%Disc, delim, & |
---|
278 | TblTail%ParmTail%Category, delim, & |
---|
279 | TblTail%ParmTail%ParmNum, delim, & |
---|
280 | trim(TblTail%ParmTail%WRFNameString), delim, & |
---|
281 | trim(TblTail%ParmTail%Description), delim, & |
---|
282 | TblTail%ParmTail%DecScl, delim, & |
---|
283 | TblTail%ParmTail%BinScl, delim |
---|
284 | #endif |
---|
285 | |
---|
286 | ! |
---|
287 | ! Parse the WRFNameString |
---|
288 | ! |
---|
289 | status = 0 |
---|
290 | lastpos = 0 |
---|
291 | idx = 1 |
---|
292 | do while (pos .gt. 0) |
---|
293 | pos = index(TblTail%ParmTail%WRFNameString(lastpos+1:maxLineSize), ",") |
---|
294 | if (pos .le. 0) then |
---|
295 | end = lastpos+maxLineSize |
---|
296 | else |
---|
297 | end = lastpos+pos-1 |
---|
298 | endif |
---|
299 | read(TblTail%ParmTail%WRFNameString(lastpos+1:end),*) & |
---|
300 | TblTail%ParmTail%WRFNames(idx) |
---|
301 | lastpos = lastpos + pos |
---|
302 | idx = idx + 1 |
---|
303 | enddo |
---|
304 | TblTail%ParmTail%numWRFNames = idx-1 |
---|
305 | |
---|
306 | #ifdef TEST |
---|
307 | write(6,*)'WRFNames: ',& |
---|
308 | (trim(TblTail%ParmTail%WRFNames(idx)),' ', & |
---|
309 | idx=1,TblTail%ParmTail%numWRFNames) |
---|
310 | #endif |
---|
311 | |
---|
312 | enddo READLINE |
---|
313 | |
---|
314 | close ( unit = fileunit) |
---|
315 | |
---|
316 | end subroutine load_grib2map |
---|
317 | |
---|
318 | !***************************************************************************** |
---|
319 | ! |
---|
320 | ! Routine to find and return the grib2 information associated with a WRF |
---|
321 | ! parameter. |
---|
322 | ! |
---|
323 | !***************************************************************************** |
---|
324 | |
---|
325 | subroutine get_parminfo(parmname, center, subcenter, MasterTblV, & |
---|
326 | LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, ierr) |
---|
327 | |
---|
328 | USE grib2tbls_types |
---|
329 | Implicit None |
---|
330 | |
---|
331 | character*(*),intent(in) :: parmname |
---|
332 | integer ,intent(out) :: center, subcenter, MasterTblV, LocalTblV, & |
---|
333 | Disc, Category, ParmNum, DecScl, BinScl |
---|
334 | TYPE (grib2Entries_type), pointer :: ParmPtr |
---|
335 | TYPE (grib2tbls_type) , pointer :: TblPtr |
---|
336 | integer :: idx |
---|
337 | logical :: found |
---|
338 | integer :: ierr |
---|
339 | |
---|
340 | |
---|
341 | ! |
---|
342 | ! Loop through tables |
---|
343 | ! |
---|
344 | |
---|
345 | found = .false. |
---|
346 | TblPtr => TblHead |
---|
347 | TABLE : DO |
---|
348 | |
---|
349 | if ( .not. associated(TblPtr)) then |
---|
350 | exit TABLE |
---|
351 | endif |
---|
352 | |
---|
353 | ! |
---|
354 | ! Loop through parameters |
---|
355 | ! |
---|
356 | ParmPtr => TblPtr%ParmHead |
---|
357 | |
---|
358 | PARAMETER : DO |
---|
359 | |
---|
360 | if ( .not. associated(ParmPtr)) then |
---|
361 | exit PARAMETER |
---|
362 | endif |
---|
363 | |
---|
364 | ! |
---|
365 | ! Loop through WRF parameter names for the table parameter entry |
---|
366 | ! |
---|
367 | WRFNAME : do idx = 1,ParmPtr%numWRFNames |
---|
368 | if (parmname .eq. ParmPtr%WRFNames(idx)) then |
---|
369 | found = .true. |
---|
370 | exit TABLE |
---|
371 | endif |
---|
372 | enddo WRFNAME |
---|
373 | |
---|
374 | ParmPtr => ParmPtr%next |
---|
375 | |
---|
376 | ENDDO PARAMETER |
---|
377 | |
---|
378 | TblPtr => TblPtr%next |
---|
379 | ENDDO TABLE |
---|
380 | |
---|
381 | if (found) then |
---|
382 | center = TblPtr%center |
---|
383 | subcenter = TblPtr%subcenter |
---|
384 | MasterTblV = TblPtr%MasterTblV |
---|
385 | LocalTblV = TblPtr%LocalTblV |
---|
386 | Disc = ParmPtr%Disc |
---|
387 | Category = ParmPtr%Category |
---|
388 | ParmNum = ParmPtr%ParmNum |
---|
389 | DecScl = ParmPtr%DecScl |
---|
390 | BinScl = ParmPtr%BinScl |
---|
391 | ierr = 0 |
---|
392 | else |
---|
393 | ierr = 1 |
---|
394 | endif |
---|
395 | |
---|
396 | end subroutine get_parminfo |
---|
397 | |
---|
398 | !***************************************************************************** |
---|
399 | ! |
---|
400 | ! Routine to free the lists. |
---|
401 | ! |
---|
402 | !***************************************************************************** |
---|
403 | |
---|
404 | subroutine free_grib2map() |
---|
405 | USE grib2tbls_types |
---|
406 | Implicit None |
---|
407 | |
---|
408 | TYPE (grib2Entries_type), pointer :: ParmPtr |
---|
409 | TYPE (grib2Entries_type), pointer :: ParmSave |
---|
410 | TYPE (grib2tbls_type) , pointer :: TblPtr |
---|
411 | TYPE (grib2tbls_type) , pointer :: TblSave |
---|
412 | |
---|
413 | TblPtr => TblHead |
---|
414 | TABLE : DO |
---|
415 | |
---|
416 | if ( .not. associated(TblPtr)) then |
---|
417 | exit TABLE |
---|
418 | endif |
---|
419 | |
---|
420 | ! |
---|
421 | ! Loop through parameters |
---|
422 | ! |
---|
423 | ParmPtr => TblPtr%ParmHead |
---|
424 | |
---|
425 | PARAMETER : DO |
---|
426 | |
---|
427 | if ( .not. associated(ParmPtr)) then |
---|
428 | exit PARAMETER |
---|
429 | endif |
---|
430 | |
---|
431 | ParmSave => ParmPtr%next |
---|
432 | deallocate(ParmPtr) |
---|
433 | ParmPtr => ParmSave |
---|
434 | |
---|
435 | ENDDO PARAMETER |
---|
436 | |
---|
437 | |
---|
438 | TblSave => TblPtr%next |
---|
439 | deallocate(TblPtr) |
---|
440 | TblPtr => TblSave |
---|
441 | |
---|
442 | ENDDO TABLE |
---|
443 | |
---|
444 | end subroutine free_grib2map |
---|