1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 ! Module: source_data_module
5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6 module source_data_module
11 use misc_definitions_module
14 integer, parameter :: RETURN_LANDMASK = 0, &
15 RETURN_DOMCAT_LM = 1, &
18 RETURN_FIELDNAME = 4, &
22 integer, parameter :: MAX_LANDMASK_CATEGORIES = 100
25 integer :: num_entries
26 integer :: next_field = 1
27 integer :: output_field_state = RETURN_LANDMASK
28 integer, pointer, dimension(:) :: source_proj, source_wordsize, source_endian, source_fieldtype, &
29 source_dest_fieldtype, source_priority, source_tile_x, source_tile_y, &
30 source_tile_z, source_tile_z_start, source_tile_z_end, source_tile_bdr, &
31 source_category_min, source_category_max, source_smooth_option, &
32 source_smooth_passes, source_output_stagger, source_row_order
33 integer :: source_iswater, source_islake, source_isice, source_isurban, source_isoilwater
34 real, pointer, dimension(:) :: source_dx, source_dy, source_known_x, source_known_y, &
35 source_known_lat, source_known_lon, source_masked, source_truelat1, source_truelat2, &
36 source_stdlon, source_scale_factor, source_missing_value, source_fill_missing
37 character (len=128), pointer, dimension(:) :: source_fieldname, source_path, source_interp_string, &
38 source_dominant_category, source_dominant_only, source_dfdx, source_dfdy, &
39 source_z_dim_name, source_units, source_descr, source_geotiff_file
40 character (len=128) :: source_mminlu
41 logical, pointer, dimension(:) :: is_proj, is_wordsize, is_endian, is_fieldtype, &
42 is_dest_fieldtype, is_priority, is_tile_x, is_tile_y, is_tile_z, &
43 is_tile_z_start, is_tile_z_end, is_tile_bdr, is_category_min, &
44 is_category_max, is_masked, &
45 is_dx, is_dy, is_known_x, is_known_y, &
46 is_known_lat, is_known_lon, is_truelat1, is_truelat2, is_stdlon, &
47 is_scale_factor, is_fieldname, is_path, is_dominant_category, &
48 is_dominant_only, is_dfdx, is_dfdy, is_z_dim_name, &
49 is_smooth_option, is_smooth_passes, is_signed, is_missing_value, &
50 is_fill_missing, is_halt_missing, is_output_stagger, is_row_order, &
51 is_units, is_descr, is_subgrid, is_geotiff
53 type (list), pointer, dimension(:) :: source_res_path, source_interp_option, source_landmask_land, &
55 type (hashtable) :: bad_files ! Track which files produce errors when we try to open them
56 type (hashtable) :: duplicate_fnames ! Remember which output fields we have returned
62 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
66 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
67 subroutine get_datalist()
75 integer, parameter :: BUFSIZE = 256
78 integer :: nparams, idx, eos, ispace, comma, i, j, funit
79 logical :: have_specification, is_used
80 character (len=128) :: res_string, path_string, interp_string, landmask_string
81 character (len=BUFSIZE) :: buffer
87 inquire(unit=funit, opened=is_used)
88 if (.not. is_used) exit
90 open(funit,file=trim(opt_geogrid_tbl_path)//'GEOGRID.TBL',form='formatted',status='old',err=1000)
93 ! We will first go through the file to determine how many field
94 ! specifications there are
96 10 read(funit,'(a)',end=20,err=1001) buffer
99 ! Is this line a comment?
100 if (buffer(1:1) == '#') then
102 ! Are we beginning a new field specification?
103 else if (index(buffer,'=====') /= 0) then
104 if (nparams > 0) num_entries = num_entries + 1
108 eos = index(buffer,'#')
109 if (eos /= 0) buffer(eos:BUFSIZE) = ' '
111 ! Does this line contain at least one parameter specification?
112 if (index(buffer,'=') /= 0) then
113 nparams = nparams + 1
120 ! In case the last entry ended without a ======== line
121 if (nparams > 0) num_entries = num_entries + 1
123 call mprintf(.true.,STDOUT,'Parsed %i entries in GEOGRID.TBL', i1=num_entries)
126 ! Now that we know how many fields the user has specified, allocate
127 ! the properly sized arrays
129 allocate(source_wordsize(num_entries))
130 allocate(source_endian(num_entries))
131 allocate(source_fieldtype(num_entries))
132 allocate(source_dest_fieldtype(num_entries))
133 allocate(source_proj(num_entries))
134 allocate(source_priority(num_entries))
135 allocate(source_dx(num_entries))
136 allocate(source_dy(num_entries))
137 allocate(source_known_x(num_entries))
138 allocate(source_known_y(num_entries))
139 allocate(source_known_lat(num_entries))
140 allocate(source_known_lon(num_entries))
141 allocate(source_truelat1(num_entries))
142 allocate(source_truelat2(num_entries))
143 allocate(source_stdlon(num_entries))
144 allocate(source_fieldname(num_entries))
145 allocate(source_path(num_entries))
146 allocate(source_interp_string(num_entries))
147 allocate(source_tile_x(num_entries))
148 allocate(source_tile_y(num_entries))
149 allocate(source_tile_z(num_entries))
150 allocate(source_tile_z_start(num_entries))
151 allocate(source_tile_z_end(num_entries))
152 allocate(source_category_min(num_entries))
153 allocate(source_category_max(num_entries))
154 allocate(source_tile_bdr(num_entries))
155 allocate(source_masked(num_entries))
156 allocate(source_output_stagger(num_entries))
157 allocate(source_row_order(num_entries))
158 allocate(source_dominant_category(num_entries))
159 allocate(source_dominant_only(num_entries))
160 allocate(source_dfdx(num_entries))
161 allocate(source_dfdy(num_entries))
162 allocate(source_scale_factor(num_entries))
163 allocate(source_z_dim_name(num_entries))
164 allocate(source_units(num_entries))
165 allocate(source_descr(num_entries))
166 allocate(source_smooth_option(num_entries))
167 allocate(source_smooth_passes(num_entries))
168 allocate(source_missing_value(num_entries))
169 allocate(source_fill_missing(num_entries))
170 allocate(source_res_path(num_entries))
171 allocate(source_interp_option(num_entries))
172 allocate(source_landmask_land(num_entries))
173 allocate(source_landmask_water(num_entries))
174 allocate(source_geotiff_file(num_entries))
176 call list_init(source_res_path(i))
177 call list_init(source_interp_option(i))
178 call list_init(source_landmask_land(i))
179 call list_init(source_landmask_water(i))
182 allocate(is_wordsize(num_entries))
183 allocate(is_endian(num_entries))
184 allocate(is_fieldtype(num_entries))
185 allocate(is_dest_fieldtype(num_entries))
186 allocate(is_proj(num_entries))
187 allocate(is_priority(num_entries))
188 allocate(is_dx(num_entries))
189 allocate(is_dy(num_entries))
190 allocate(is_known_x(num_entries))
191 allocate(is_known_y(num_entries))
192 allocate(is_known_lat(num_entries))
193 allocate(is_known_lon(num_entries))
194 allocate(is_truelat1(num_entries))
195 allocate(is_truelat2(num_entries))
196 allocate(is_stdlon(num_entries))
197 allocate(is_fieldname(num_entries))
198 allocate(is_path(num_entries))
199 allocate(is_tile_x(num_entries))
200 allocate(is_tile_y(num_entries))
201 allocate(is_tile_z(num_entries))
202 allocate(is_tile_z_start(num_entries))
203 allocate(is_tile_z_end(num_entries))
204 allocate(is_category_min(num_entries))
205 allocate(is_category_max(num_entries))
206 allocate(is_tile_bdr(num_entries))
207 allocate(is_masked(num_entries))
208 allocate(is_halt_missing(num_entries))
209 allocate(is_output_stagger(num_entries))
210 allocate(is_row_order(num_entries))
211 allocate(is_dominant_category(num_entries))
212 allocate(is_dominant_only(num_entries))
213 allocate(is_dfdx(num_entries))
214 allocate(is_dfdy(num_entries))
215 allocate(is_scale_factor(num_entries))
216 allocate(is_z_dim_name(num_entries))
217 allocate(is_units(num_entries))
218 allocate(is_descr(num_entries))
219 allocate(is_smooth_option(num_entries))
220 allocate(is_smooth_passes(num_entries))
221 allocate(is_signed(num_entries))
222 allocate(is_missing_value(num_entries))
223 allocate(is_fill_missing(num_entries))
224 allocate(is_subgrid(num_entries))
225 allocate(is_geotiff(num_entries))
230 source_dest_fieldtype=0
244 source_interp_string=' '
248 source_tile_z_start=0
250 source_category_min=0
251 source_category_max=0
254 source_output_stagger=0
256 source_dominant_category=' '
257 source_dominant_only=' '
260 source_scale_factor=0
261 source_z_dim_name=' '
264 source_smooth_option=0
265 source_smooth_passes=0
266 source_missing_value=0
267 source_fill_missing=0
272 is_dest_fieldtype=.false.
289 is_tile_z_start=.false.
290 is_tile_z_end=.false.
291 is_category_min=.false.
292 is_category_max=.false.
295 is_halt_missing=.false.
296 is_output_stagger=.false.
298 is_dominant_category=.false.
299 is_dominant_only=.false.
302 is_scale_factor=.false.
303 is_z_dim_name=.false.
306 is_smooth_option=.false.
307 is_smooth_passes=.false.
309 is_missing_value=.false.
310 is_fill_missing=.false.
313 write(source_mminlu,'(a4)') 'USGS'
318 source_isoilwater = 14
321 ! Actually read and save the specifications
326 read(funit,'(a)',end=40,err=1001) buffer
329 ! Is this line a comment?
330 if (buffer(1:1) == '#') then
333 ! Are we beginning a new field specification?
334 else if (index(buffer,'=====') /= 0) then !{
335 if (nparams > 0) i = i + 1
337 if (i <= num_entries) then
338 !BUG: Are these initializations needed now that we've added initializations for
339 ! all options after their initial allocation above?
341 is_masked(i) = .false.
342 is_halt_missing(i) = .false.
343 is_output_stagger(i) = .false.
344 is_dominant_category(i) = .false.
345 is_dominant_only(i) = .false.
348 is_dest_fieldtype(i) = .false.
349 is_priority(i) = .false.
350 is_z_dim_name(i) = .false.
351 is_smooth_option(i) = .false.
352 is_smooth_passes(i) = .false.
353 is_fill_missing(i) = .false.
354 is_subgrid(i) = .false.
358 ! Check whether the current line is a comment
359 if (buffer(1:1) /= '#') then
360 have_specification = .true.
362 have_specification = .false.
365 ! If only part of the line is a comment, just turn the comment into spaces
366 eos = index(buffer,'#')
367 if (eos /= 0) buffer(eos:BUFSIZE) = ' '
369 do while (have_specification) !{
371 ! If this line has no semicolon, it may contain a single specification,
372 ! so we set have_specification = .false. to prevent the line from being
373 ! processed again and "pretend" that the last character was a semicolon
374 eos = index(buffer,';')
376 have_specification = .false.
380 idx = index(buffer(1:eos-1),'=')
382 if (idx /= 0) then !{
383 nparams = nparams + 1
385 if (index('name',trim(buffer(1:idx-1))) /= 0) then
387 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
390 is_fieldname(i) = .true.
391 source_fieldname(i) = ' '
392 source_fieldname(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
394 else if (index('priority',trim(buffer(1:idx-1))) /= 0) then
395 is_priority(i) = .true.
396 read(buffer(idx+1:eos-1),'(i10)') source_priority(i)
398 else if (index('dest_type',trim(buffer(1:idx-1))) /= 0) then
399 if (index('continuous',trim(buffer(idx+1:eos-1))) /= 0) then
400 is_dest_fieldtype(i) = .true.
401 source_dest_fieldtype(i) = CONTINUOUS
402 else if (index('categorical',trim(buffer(idx+1:eos-1))) /= 0) then
403 is_dest_fieldtype(i) = .true.
404 source_dest_fieldtype(i) = CATEGORICAL
407 else if (index('interp_option',trim(buffer(1:idx-1))) /= 0) then
409 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
413 interp_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
414 ispace = index(interp_string,':')
415 if (ispace /= 0) then
416 write(res_string,'(a)') interp_string(1:ispace-1)
418 res_string = 'default'
420 write(interp_string,'(a)') trim(interp_string(ispace+1:128))
421 if (list_search(source_interp_option(i), ckey=res_string, cvalue=interp_string)) then
422 call mprintf(.true., WARN, &
423 'In GEOGRID.TBL entry %i, multiple interpolation methods are '// &
424 'given for resolution %s. %s will be used.', &
425 i1=i, s1=trim(res_string), s2=trim(interp_string))
427 call list_insert(source_interp_option(i), ckey=res_string, cvalue=interp_string)
430 else if (index('smooth_option',trim(buffer(1:idx-1))) /= 0) then
431 if ((index('1-2-1',trim(buffer(idx+1:eos-1))) /= 0) .and. &
432 (len_trim(buffer(idx+1:eos-1)) == len('1-2-1'))) then
433 is_smooth_option(i) = .true.
434 source_smooth_option(i) = ONETWOONE
435 else if ((index('smth-desmth',trim(buffer(idx+1:eos-1))) /= 0) .and. &
436 (len_trim(buffer(idx+1:eos-1)) == len('smth-desmth'))) then
437 is_smooth_option(i) = .true.
438 source_smooth_option(i) = SMTHDESMTH
439 else if ((index('smth-desmth_special',trim(buffer(idx+1:eos-1))) /= 0) .and. &
440 (len_trim(buffer(idx+1:eos-1)) == len('smth-desmth_special'))) then
441 is_smooth_option(i) = .true.
442 source_smooth_option(i) = SMTHDESMTH_SPECIAL
445 else if (index('smooth_passes',trim(buffer(1:idx-1))) /= 0) then
446 is_smooth_passes(i) = .true.
447 read(buffer(idx+1:eos-1),'(i10)') source_smooth_passes(i)
449 else if (index('rel_path',trim(buffer(1:idx-1))) /= 0) then
451 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
455 path_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
456 if (path_string(ispace-idx-1:ispace-idx-1) /= '/') &
457 path_string(ispace-idx:ispace-idx) = '/'
458 if (path_string(1:1) == '/') then
459 path_string(1:127) = path_string(2:128)
460 path_string(128:128) = ' '
462 ispace = index(path_string,':')
463 if (ispace /= 0) then
464 write(res_string,'(a)') path_string(1:ispace-1)
466 res_string = 'default'
468 write(path_string,'(a)') trim(geog_data_path)//trim(path_string(ispace+1:128))
469 if (list_search(source_res_path(i), ckey=res_string, cvalue=path_string)) then
470 call mprintf(.true., WARN, &
471 'In GEOGRID.TBL entry %i, multiple paths are given for '// &
472 'resolution %s. %s will be used.', &
473 i1=i, s1=trim(res_string), s2=trim(path_string))
475 call list_insert(source_res_path(i), ckey=res_string, cvalue=path_string)
478 else if (index('abs_path',trim(buffer(1:idx-1))) /= 0) then
480 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
484 path_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
485 if (path_string(ispace-idx-1:ispace-idx-1) /= '/') &
486 path_string(ispace-idx:ispace-idx) = '/'
487 ispace = index(path_string,':')
488 if (ispace /= 0) then
489 write(res_string,'(a)') path_string(1:ispace-1)
491 res_string = 'default'
493 write(path_string,'(a)') trim(path_string(ispace+1:128))
494 if (list_search(source_res_path(i), ckey=res_string, cvalue=path_string)) then
495 call mprintf(.true., WARN, &
496 'In GEOGRID.TBL entry %i, multiple paths are given for '// &
497 'resolution %s. %s will be used.', &
498 i1=i, s1=trim(res_string), s2=trim(path_string))
500 call list_insert(source_res_path(i), ckey=res_string, cvalue=path_string)
503 else if (index('output_stagger',trim(buffer(1:idx-1))) /= 0) then
504 if (index('M',trim(buffer(idx+1:eos-1))) /= 0) then
505 is_output_stagger(i) = .true.
506 source_output_stagger(i) = M
507 else if (index('U',trim(buffer(idx+1:eos-1))) /= 0) then
508 is_output_stagger(i) = .true.
509 source_output_stagger(i) = U
510 else if (index('V',trim(buffer(idx+1:eos-1))) /= 0) then
511 is_output_stagger(i) = .true.
512 source_output_stagger(i) = V
513 else if (index('HH',trim(buffer(idx+1:eos-1))) /= 0) then
514 is_output_stagger(i) = .true.
515 source_output_stagger(i) = HH
516 else if (index('VV',trim(buffer(idx+1:eos-1))) /= 0) then
517 is_output_stagger(i) = .true.
518 source_output_stagger(i) = VV
521 else if ((index('landmask_water',trim(buffer(1:idx-1))) /= 0) .and. &
522 (len_trim(buffer(1:idx-1)) == 14)) then
524 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
527 landmask_string = ' '
528 landmask_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
529 ispace = index(landmask_string,':')
530 if (ispace /= 0) then
531 write(res_string,'(a)') landmask_string(1:ispace-1)
533 res_string = 'default'
535 write(landmask_string,'(a)') trim(landmask_string(ispace+1:128))
536 if (list_search(source_landmask_water(i), ckey=res_string, cvalue=landmask_string)) then
537 call mprintf(.true., WARN, &
538 'In GEOGRID.TBL entry %i, multiple landmask category specifications are given for '// &
539 'resolution %s. %s will be used.', &
540 i1=i, s1=trim(res_string), s2=trim(landmask_string))
542 call list_insert(source_landmask_water(i), ckey=res_string, cvalue=landmask_string)
545 else if ((index('landmask_land',trim(buffer(1:idx-1))) /= 0) .and. &
546 (len_trim(buffer(1:idx-1)) == 13)) then
548 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
551 landmask_string = ' '
552 landmask_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
553 ispace = index(landmask_string,':')
554 if (ispace /= 0) then
555 write(res_string,'(a)') landmask_string(1:ispace-1)
557 res_string = 'default'
559 write(landmask_string,'(a)') trim(landmask_string(ispace+1:128))
560 if (list_search(source_landmask_land(i), ckey=res_string, cvalue=landmask_string)) then
561 call mprintf(.true., WARN, &
562 'In GEOGRID.TBL entry %i, multiple landmask category specifications are given for '// &
563 'resolution %s. %s will be used.', &
564 i1=i, s1=trim(res_string), s2=trim(landmask_string))
566 call list_insert(source_landmask_land(i), ckey=res_string, cvalue=landmask_string)
569 else if ((index('masked',trim(buffer(1:idx-1))) /= 0) .and. &
570 (len_trim(buffer(1:idx-1)) == 6)) then
571 if (index('water',trim(buffer(idx+1:eos-1))) /= 0) then
572 is_masked(i) = .true.
573 source_masked(i) = 0.
574 else if (index('land',trim(buffer(idx+1:eos-1))) /= 0) then
575 is_masked(i) = .true.
576 source_masked(i) = 1.
579 else if (index('fill_missing',trim(buffer(1:idx-1))) /= 0) then
580 is_fill_missing(i) = .true.
581 read(buffer(idx+1:eos-1),*) source_fill_missing(i)
583 else if (index('halt_on_missing',trim(buffer(1:idx-1))) /= 0) then
584 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
585 is_halt_missing(i) = .true.
586 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
587 is_halt_missing(i) = .false.
590 else if (index('dominant_category',trim(buffer(1:idx-1))) /= 0) then
592 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
595 is_dominant_category(i) = .true.
596 source_dominant_category(i) = ' '
597 source_dominant_category(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
599 else if (index('dominant_only',trim(buffer(1:idx-1))) /= 0) then
601 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
604 is_dominant_only(i) = .true.
605 source_dominant_only(i) = ' '
606 source_dominant_only(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
608 else if (index('df_dx',trim(buffer(1:idx-1))) /= 0) then
610 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
615 source_dfdx(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
617 else if (index('df_dy',trim(buffer(1:idx-1))) /= 0) then
619 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
624 source_dfdy(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
626 else if (index('z_dim_name',trim(buffer(1:idx-1))) /= 0) then
628 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
631 is_z_dim_name(i) = .true.
632 source_z_dim_name(i) = ' '
633 source_z_dim_name(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
635 else if (index('subgrid',trim(buffer(1:idx-1))) /= 0) then
637 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
640 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
641 is_subgrid(i) = .true.
642 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
643 is_subgrid(i) = .false.
647 call mprintf(.true., WARN, 'In GEOGRID.TBL, unrecognized option %s in '// &
648 'entry %i.',i1=idx, s1=buffer(i:idx-1))
652 end if !} index(buffer(1:eos-1),'=') /= 0
654 buffer = buffer(eos+1:BUFSIZE)
655 end do ! while eos /= 0 }
657 end if !} index(buffer, '=====') /= 0
662 ! Check the user specifications for gross errors
663 if ( .not. check_data_specification() ) then
664 call datalist_destroy()
665 call mprintf(.true.,ERROR,'Errors were found in either index files or GEOGRID.TBL.')
668 call hash_init(bad_files)
672 1000 call mprintf(.true.,ERROR,'Could not open GEOGRID.TBL')
674 1001 call mprintf(.true.,ERROR,'Encountered error while reading GEOGRID.TBL')
676 end subroutine get_datalist
679 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
680 ! Name: get_source_params
682 ! Purpose: For each field, this routine reads in the metadata in the index file
683 ! for the first available resolution of data specified by res_string. Also
684 ! based on res_string, this routine sets the interpolation sequence for the
685 ! field. This routine should be called prior to processing a field for each
687 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
688 subroutine get_source_params(res_string)
692 use geotiff_module, only : open_geotiff,merge_geotiff_header
698 integer, parameter :: BUFSIZE = 256
701 character (len=128), intent(in) :: res_string
704 integer :: idx, i, is, ie, ispace, eos, iquoted, funit
705 character (len=128) :: temp_data, temp_interp
706 character (len=256) :: test_fname
707 character (len=BUFSIZE) :: buffer
708 logical :: have_specification, is_used
710 ! For each entry in the GEOGRID.TBL file
713 ! Initialize metadata
714 is_wordsize(idx) = .false.
715 is_endian(idx) = .false.
716 is_row_order(idx) = .false.
717 is_fieldtype(idx) = .false.
718 is_proj(idx) = .false.
721 is_known_x(idx) = .false.
722 is_known_y(idx) = .false.
723 is_known_lat(idx) = .false.
724 is_known_lon(idx) = .false.
725 is_truelat1(idx) = .false.
726 is_truelat2(idx) = .false.
727 is_stdlon(idx) = .false.
728 is_tile_x(idx) = .false.
729 is_tile_y(idx) = .false.
730 is_tile_z(idx) = .false.
731 is_tile_z_start(idx) = .false.
732 is_tile_z_end(idx) = .false.
733 is_category_min(idx) = .false.
734 is_category_max(idx) = .false.
735 is_tile_bdr(idx) = .false.
736 is_fieldname(idx) = .false.
737 is_scale_factor(idx) = .false.
738 is_units(idx) = .false.
739 is_descr(idx) = .false.
740 is_signed(idx) = .false.
741 is_missing_value(idx) = .false.
742 is_geotiff(idx) = .false.
745 ! Set the interpolator sequence for the field to be the first value in res_string that matches
746 ! the resolution keyword for an interp_sequence specification
748 ie = index(res_string(is:128),'+') - 1
749 if (ie <= 0) ie = 128
750 temp_interp = res_string(is:ie)
751 do while (.not. list_search(source_interp_option(idx), ckey=temp_interp, cvalue=source_interp_string(idx)) &
753 call mprintf(.true., INFORM, 'For %s, couldn''t find interpolator sequence for '// &
755 s1=trim(source_fieldname(idx)), s2=trim(temp_interp))
757 ie = is + index(res_string(is:128),'+') - 2
758 if (ie - is <= 0) ie = 128
759 temp_interp = res_string(is:ie)
763 temp_interp = 'default'
764 if (list_search(source_interp_option(idx), ckey=temp_interp, cvalue=source_interp_string(idx))) then
765 call mprintf(.true., INFORM, 'Using default interpolator sequence for %s.', &
766 s1=trim(source_fieldname(idx)))
768 call mprintf(.true., ERROR, 'Could not find interpolator sequence for requested resolution for %s.'// &
769 ' The sources specified in namelist.wps is not listed in GEOGRID.TBL.', &
770 s1=trim(source_fieldname(idx)))
773 call mprintf(.true., INFORM, 'Using %s interpolator sequence for %s.', &
774 s1=temp_interp, s2=trim(source_fieldname(idx)))
777 ! Set the data source for the field to be the first value in res_string that matches
778 ! the resolution keyword for an abs_path or rel_path specification
780 ie = index(res_string(is:128),'+') - 1
781 if (ie <= 0) ie = 128
782 temp_data = res_string(is:ie)
783 do while (.not. list_search(source_res_path(idx), ckey=temp_data, cvalue=source_path(idx)) &
785 call mprintf(.true., INFORM, 'For %s, couldn''t find %s data source.', &
786 s1=trim(source_fieldname(idx)), s2=trim(temp_data))
788 ie = is + index(res_string(is:128),'+') - 2
789 if (ie - is <= 0) ie = 128
790 temp_data = res_string(is:ie)
794 temp_data = 'default'
795 if (list_search(source_res_path(idx), ckey=temp_data, cvalue=source_path(idx))) then
796 call mprintf(.true., INFORM, 'Using default data source for %s.', &
797 s1=trim(source_fieldname(idx)))
799 call mprintf(.true., ERROR, 'Could not find data resolution for requested resolution for %s. '// &
800 'The source specified in namelist.wps is not listed in GEOGRID.TBL.', &
801 s1=trim(source_fieldname(idx)))
804 call mprintf(.true., INFORM, 'Using %s data source for %s.', &
805 s1=temp_data, s2=trim(source_fieldname(idx)))
808 call mprintf(trim(temp_data) /= trim(temp_interp),WARN,'For %s, using %s data source with %s interpolation sequence.', &
809 s1=source_fieldname(idx), s2=temp_data, s3=temp_interp)
811 write(test_fname, '(a)') trim(source_path(idx))//'index'
814 ! Open the index file for the data source for this field, and read in metadata specs
817 inquire(unit=funit, opened=is_used)
818 if (.not. is_used) exit
820 open(funit,file=trim(test_fname),form='formatted',status='old',err=1000)
823 read(funit,'(a)',end=40, err=1001) buffer
826 ! Is this line a comment?
827 if (buffer(1:1) == '#') then
831 have_specification = .true.
833 ! If only part of the line is a comment, just turn the comment into spaces
834 eos = index(buffer,'#')
835 if (eos /= 0) buffer(eos:BUFSIZE) = ' '
837 do while (have_specification) !{
839 ! If this line has no semicolon, it may contain a single specification,
840 ! so we set have_specification = .false. to prevent the line from being
841 ! processed again and pretend that the last character was a semicolon
842 eos = index(buffer,';')
844 have_specification = .false.
848 i = index(buffer(1:eos-1),'=')
852 if (index('projection',trim(buffer(1:i-1))) /= 0) then
853 if (index('lambert',trim(buffer(i+1:eos-1))) /= 0) then
854 is_proj(idx) = .true.
855 source_proj(idx) = PROJ_LC
856 else if (index('polar_wgs84',trim(buffer(i+1:eos-1))) /= 0 .and. &
857 len_trim('polar_wgs84') == len_trim(buffer(i+1:eos-1))) then
858 is_proj(idx) = .true.
859 source_proj(idx) = PROJ_PS_WGS84
860 else if (index('albers_nad83',trim(buffer(i+1:eos-1))) /= 0 .and. &
861 len_trim('albers_nad83') == len_trim(buffer(i+1:eos-1))) then
862 is_proj(idx) = .true.
863 source_proj(idx) = PROJ_ALBERS_NAD83
864 else if (index('polar',trim(buffer(i+1:eos-1))) /= 0 .and. &
865 len_trim('polar') == len_trim(buffer(i+1:eos-1))) then
866 is_proj(idx) = .true.
867 source_proj(idx) = PROJ_PS
868 else if (index('mercator',trim(buffer(i+1:eos-1))) /= 0) then
869 is_proj(idx) = .true.
870 source_proj(idx) = PROJ_MERC
871 else if (index('regular_ll',trim(buffer(i+1:eos-1))) /= 0) then
872 is_proj(idx) = .true.
873 source_proj(idx) = PROJ_LATLON
876 else if (index('type',trim(buffer(1:i-1))) /= 0) then
877 if (index('continuous',trim(buffer(i+1:eos-1))) /= 0) then
878 is_fieldtype(idx) = .true.
879 source_fieldtype(idx) = CONTINUOUS
880 else if (index('categorical',trim(buffer(i+1:eos-1))) /= 0) then
881 is_fieldtype(idx) = .true.
882 source_fieldtype(idx) = CATEGORICAL
885 else if (index('signed',trim(buffer(1:i-1))) /= 0) then
886 if (index('yes',trim(buffer(i+1:eos-1))) /= 0) then
887 is_signed(idx) = .true.
888 else if (index('no',trim(buffer(i+1:eos-1))) /= 0) then
889 is_signed(idx) = .false.
892 else if (index('units',trim(buffer(1:i-1))) /= 0) then
895 do while (((ispace < eos) .and. (buffer(ispace:ispace) /= ' ')) .or. (iquoted == 1))
896 if (buffer(ispace:ispace) == '"' .or. buffer(ispace:ispace) == '''') iquoted = mod(iquoted+1,2)
899 is_units(idx) = .true.
900 source_units(idx) = ' '
901 if (buffer(i+1:i+1) == '"' .or. buffer(i+1:i+1) == '''') i = i + 1
902 if (buffer(ispace-1:ispace-1) == '"' .or. buffer(ispace-1:ispace-1) == '''') ispace = ispace - 1
903 source_units(idx)(1:ispace-i) = buffer(i+1:ispace-1)
905 else if (index('description',trim(buffer(1:i-1))) /= 0) then
908 do while (((ispace < eos) .and. (buffer(ispace:ispace) /= ' ')) .or. (iquoted == 1))
909 if (buffer(ispace:ispace) == '"' .or. buffer(ispace:ispace) == '''') iquoted = mod(iquoted+1,2)
912 is_descr(idx) = .true.
913 source_descr(idx) = ' '
914 if (buffer(i+1:i+1) == '"' .or. buffer(i+1:i+1) == '''') i = i + 1
915 if (buffer(ispace-1:ispace-1) == '"' .or. buffer(ispace-1:ispace-1) == '''') ispace = ispace - 1
916 source_descr(idx)(1:ispace-i) = buffer(i+1:ispace-1)
918 else if (index('mminlu',trim(buffer(1:i-1))) /= 0) then
921 do while (((ispace < eos) .and. (buffer(ispace:ispace) /= ' ')) .or. (iquoted == 1))
922 if (buffer(ispace:ispace) == '"' .or. buffer(ispace:ispace) == '''') iquoted = mod(iquoted+1,2)
925 if (buffer(i+1:i+1) == '"' .or. buffer(i+1:i+1) == '''') i = i + 1
926 if (buffer(ispace-1:ispace-1) == '"' .or. buffer(ispace-1:ispace-1) == '''') ispace = ispace - 1
927 source_mminlu(1:ispace-i) = buffer(i+1:ispace-1)
929 else if (index('iswater',trim(buffer(1:i-1))) /= 0) then
930 read(buffer(i+1:eos-1),*) source_iswater
932 else if (index('islake',trim(buffer(1:i-1))) /= 0) then
933 read(buffer(i+1:eos-1),*) source_islake
935 else if (index('isice',trim(buffer(1:i-1))) /= 0) then
936 read(buffer(i+1:eos-1),*) source_isice
938 else if (index('isurban',trim(buffer(1:i-1))) /= 0) then
939 read(buffer(i+1:eos-1),*) source_isurban
941 else if (index('isoilwater',trim(buffer(1:i-1))) /= 0) then
942 read(buffer(i+1:eos-1),*) source_isoilwater
944 else if (index('dx',trim(buffer(1:i-1))) /= 0) then
946 read(buffer(i+1:eos-1),*) source_dx(idx)
948 else if (index('dy',trim(buffer(1:i-1))) /= 0) then
950 read(buffer(i+1:eos-1),*) source_dy(idx)
952 else if (index('known_x',trim(buffer(1:i-1))) /= 0) then
953 is_known_x(idx) = .true.
954 read(buffer(i+1:eos-1),*) source_known_x(idx)
956 else if (index('known_y',trim(buffer(1:i-1))) /= 0) then
957 is_known_y(idx) = .true.
958 read(buffer(i+1:eos-1),*) source_known_y(idx)
960 else if (index('known_lat',trim(buffer(1:i-1))) /= 0) then
961 is_known_lat(idx) = .true.
962 read(buffer(i+1:eos-1),*) source_known_lat(idx)
964 else if (index('known_lon',trim(buffer(1:i-1))) /= 0) then
965 is_known_lon(idx) = .true.
966 read(buffer(i+1:eos-1),*) source_known_lon(idx)
968 else if (index('stdlon',trim(buffer(1:i-1))) /= 0) then
969 is_stdlon(idx) = .true.
970 read(buffer(i+1:eos-1),*) source_stdlon(idx)
972 else if (index('truelat1',trim(buffer(1:i-1))) /= 0) then
973 is_truelat1(idx) = .true.
974 read(buffer(i+1:eos-1),*) source_truelat1(idx)
976 else if (index('truelat2',trim(buffer(1:i-1))) /= 0) then
977 is_truelat2(idx) = .true.
978 read(buffer(i+1:eos-1),*) source_truelat2(idx)
980 else if (index('wordsize',trim(buffer(1:i-1))) /= 0) then
981 is_wordsize(idx) = .true.
982 read(buffer(i+1:eos-1),'(i10)') source_wordsize(idx)
984 else if (index('endian',trim(buffer(1:i-1))) /= 0) then
985 if (index('big',trim(buffer(i+1:eos-1))) /= 0) then
986 is_endian(idx) = .true.
987 source_endian(idx) = BIG_ENDIAN
988 else if (index('little',trim(buffer(i+1:eos-1))) /= 0) then
989 is_endian(idx) = .true.
990 source_endian(idx) = LITTLE_ENDIAN
992 call mprintf(.true.,WARN,'Invalid value for keyword ''endian'' '// &
993 'specified in index file. BIG_ENDIAN will be used.')
996 else if (index('row_order',trim(buffer(1:i-1))) /= 0) then
997 if (index('bottom_top',trim(buffer(i+1:eos-1))) /= 0) then
998 is_row_order(idx) = .true.
999 source_row_order(idx) = BOTTOM_TOP
1000 else if (index('top_bottom',trim(buffer(i+1:eos-1))) /= 0) then
1001 is_row_order(idx) = .true.
1002 source_row_order(idx) = TOP_BOTTOM
1005 else if (index('tile_x',trim(buffer(1:i-1))) /= 0) then
1006 is_tile_x(idx) = .true.
1007 read(buffer(i+1:eos-1),'(i10)') source_tile_x(idx)
1009 else if (index('tile_y',trim(buffer(1:i-1))) /= 0) then
1010 is_tile_y(idx) = .true.
1011 read(buffer(i+1:eos-1),'(i10)') source_tile_y(idx)
1013 else if (index('tile_z',trim(buffer(1:i-1))) /= 0) then
1014 is_tile_z(idx) = .true.
1015 read(buffer(i+1:eos-1),'(i10)') source_tile_z(idx)
1017 else if (index('tile_z_start',trim(buffer(1:i-1))) /= 0) then
1018 is_tile_z_start(idx) = .true.
1019 read(buffer(i+1:eos-1),'(i10)') source_tile_z_start(idx)
1021 else if (index('tile_z_end',trim(buffer(1:i-1))) /= 0) then
1022 is_tile_z_end(idx) = .true.
1023 read(buffer(i+1:eos-1),'(i10)') source_tile_z_end(idx)
1025 else if (index('category_min',trim(buffer(1:i-1))) /= 0) then
1026 is_category_min(idx) = .true.
1027 read(buffer(i+1:eos-1),'(i10)') source_category_min(idx)
1029 else if (index('category_max',trim(buffer(1:i-1))) /= 0) then
1030 is_category_max(idx) = .true.
1031 read(buffer(i+1:eos-1),'(i10)') source_category_max(idx)
1033 else if (index('tile_bdr',trim(buffer(1:i-1))) /= 0) then
1034 is_tile_bdr(idx) = .true.
1035 read(buffer(i+1:eos-1),'(i10)') source_tile_bdr(idx)
1037 else if (index('missing_value',trim(buffer(1:i-1))) /= 0) then
1038 is_missing_value(idx) = .true.
1039 read(buffer(i+1:eos-1),*) source_missing_value(idx)
1041 else if (index('scale_factor',trim(buffer(1:i-1))) /= 0) then
1042 is_scale_factor(idx) = .true.
1043 read(buffer(i+1:eos-1),*) source_scale_factor(idx)
1045 else if (index('geotiff',trim(buffer(1:i-1))) /= 0) then
1046 is_geotiff(idx) = .true.
1047 read(buffer(i+1:eos-1),*) source_geotiff_file(idx)
1050 call mprintf(.true., WARN, 'In %s, unrecognized option %s in entry %i.', &
1051 s1=trim(test_fname), s2=buffer(1:i-1), i1=i)
1055 end if !} index(buffer(1:eos-1),'=') /= 0
1057 buffer = buffer(eos+1:BUFSIZE)
1058 end do ! while eos /= 0 }
1060 end if !} index(buffer, '=====') /= 0
1068 if(is_geotiff(idx)) then
1069 if(source_geotiff_file(idx)(1:1) .ne. '/')then
1070 source_geotiff_file(idx)=TRIM(source_path(idx))//TRIM(source_geotiff_file(idx))
1072 call open_geotiff(source_geotiff_file(idx))
1073 call merge_geotiff_header(source_geotiff_file(idx),is_proj(idx),source_proj(idx),&
1074 is_fieldtype(idx),source_fieldtype(idx), &
1075 is_units(idx),source_units(idx), &
1076 is_descr(idx),source_descr(idx),is_dx(idx), &
1077 source_dx(idx),is_dy(idx),source_dy(idx), &
1078 is_known_x(idx),source_known_x(idx), &
1079 is_known_y(idx),source_known_y(idx), &
1080 is_known_lat(idx),source_known_lat(idx), &
1081 is_known_lon(idx),source_known_lon(idx), &
1082 is_stdlon(idx),source_stdlon(idx), &
1083 is_truelat1(idx),source_truelat1(idx), &
1084 is_truelat2(idx),source_truelat2(idx), &
1085 is_row_order(idx),source_row_order(idx), &
1086 is_tile_x(idx),source_tile_x(idx), &
1087 is_tile_y(idx),source_tile_y(idx), &
1088 is_tile_z(idx),source_tile_z(idx), &
1089 is_tile_z_start(idx),source_tile_z_start(idx), &
1090 is_tile_z_end(idx), source_tile_z_end(idx), &
1091 is_category_min(idx),source_category_min(idx), &
1092 is_category_max(idx),source_category_max(idx), &
1093 is_tile_bdr(idx),source_tile_bdr(idx), &
1094 is_missing_value(idx),source_missing_value(idx))
1095 is_wordsize(idx)=.true.
1096 source_wordsize(idx)=4
1097 is_scale_factor(idx)=.true.
1098 source_scale_factor(idx)=1.
1099 call mprintf(.true.,INFORM,'For geotiff file, %s, using the following parameters:', &
1100 s1=TRIM(source_geotiff_file(idx)))
1102 call mprintf(.true.,INFORM,'description=%s',s1=TRIM(source_descr(idx)))
1104 call mprintf(.true.,INFORM,'units=%s',s1=TRIM(source_units(idx)))
1106 call mprintf(.true.,INFORM,'proj=%i',i1=source_proj(idx))
1107 if(is_stdlon(idx)) &
1108 call mprintf(.true.,INFORM,'stdlon=%f',f1=source_stdlon(idx))
1109 if(is_truelat1(idx)) &
1110 call mprintf(.true.,INFORM,'truelat1=%f',f1=source_truelat1(idx))
1111 if(is_truelat2(idx)) &
1112 call mprintf(.true.,INFORM,'truelat2=%f',f1=source_truelat2(idx))
1114 call mprintf(.true.,INFORM,'dx=%f',f1=source_dx(idx))
1116 call mprintf(.true.,INFORM,'dy=%f',f1=source_dy(idx))
1117 if(is_known_x(idx)) &
1118 call mprintf(.true.,INFORM,'known_x=%f',f1=source_known_x(idx))
1119 if(is_known_y(idx)) &
1120 call mprintf(.true.,INFORM,'known_y=%f',f1=source_known_y(idx))
1121 if(is_known_lon(idx)) &
1122 call mprintf(.true.,INFORM,'known_lon=%f',f1=source_known_lon(idx))
1123 if(is_known_lat(idx)) &
1124 call mprintf(.true.,INFORM,'known_lat=%f',f1=source_known_lat(idx))
1125 if(is_fieldtype(idx)) &
1126 call mprintf(.true.,INFORM,'fieldtype=%i',i1=source_fieldtype(idx))
1127 if(is_category_min(idx)) &
1128 call mprintf(.true.,INFORM,'category_min=%i',i1=source_category_min(idx))
1129 if(is_category_max(idx)) &
1130 call mprintf(.true.,INFORM,'category_max=%i',i1=source_category_max(idx))
1131 if(is_row_order(idx)) &
1132 call mprintf(.true.,INFORM,'row_order=%i',i1=source_row_order(idx))
1133 if(is_tile_x(idx)) &
1134 call mprintf(.true.,INFORM,'tile_x=%i',i1=source_tile_x(idx))
1135 if(is_tile_y(idx)) &
1136 call mprintf(.true.,INFORM,'tile_y=%i',i1=source_tile_y(idx))
1137 if(is_tile_z(idx)) &
1138 call mprintf(.true.,INFORM,'tile_z=%i',i1=source_tile_z(idx))
1139 if(is_tile_bdr(idx)) &
1140 call mprintf(.true.,INFORM,'tile_bdr=%i',i1=source_tile_bdr(idx))
1141 if(is_missing_value(idx)) &
1142 call mprintf(.true.,INFORM,'missing_value=%f',f1=source_missing_value(idx))
1145 if(is_geotiff(idx)) then
1146 call mprintf(.true.,ERROR,'A geotiff file has been specified in %s, '// &
1147 'but geogrid has not been compiled with geotiff '// &
1148 'support.',s1=trim(test_fname))
1156 1000 call mprintf(.true.,ERROR,'Could not open %s', s1=trim(test_fname))
1157 1001 call mprintf(.true.,ERROR,'Encountered error while reading %s', s1=trim(test_fname))
1159 end subroutine get_source_params
1162 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1163 ! Name: datalist_destroy()
1165 ! Purpose: This routine deallocates any memory that was allocated by the
1166 ! get_datalist() subroutine.
1167 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1168 subroutine datalist_destroy()
1169 #ifdef _HAVE_GEOTIFF
1170 use geotiff_module, only : destroy_all
1177 #ifdef _HAVE_GEOTIFF
1181 if (associated(source_wordsize)) then
1182 deallocate(source_wordsize)
1183 deallocate(source_endian)
1184 deallocate(source_fieldtype)
1185 deallocate(source_dest_fieldtype)
1186 deallocate(source_proj)
1187 deallocate(source_priority)
1188 deallocate(source_dx)
1189 deallocate(source_dy)
1190 deallocate(source_known_x)
1191 deallocate(source_known_y)
1192 deallocate(source_known_lat)
1193 deallocate(source_known_lon)
1194 deallocate(source_truelat1)
1195 deallocate(source_truelat2)
1196 deallocate(source_stdlon)
1197 deallocate(source_fieldname)
1198 deallocate(source_path)
1199 deallocate(source_interp_string)
1200 deallocate(source_tile_x)
1201 deallocate(source_tile_y)
1202 deallocate(source_tile_z)
1203 deallocate(source_tile_z_start)
1204 deallocate(source_tile_z_end)
1205 deallocate(source_tile_bdr)
1206 deallocate(source_category_min)
1207 deallocate(source_category_max)
1208 deallocate(source_masked)
1209 deallocate(source_output_stagger)
1210 deallocate(source_row_order)
1211 deallocate(source_dominant_category)
1212 deallocate(source_dominant_only)
1213 deallocate(source_dfdx)
1214 deallocate(source_dfdy)
1215 deallocate(source_scale_factor)
1216 deallocate(source_z_dim_name)
1217 deallocate(source_smooth_option)
1218 deallocate(source_smooth_passes)
1219 deallocate(source_units)
1220 deallocate(source_descr)
1221 deallocate(source_missing_value)
1222 deallocate(source_fill_missing)
1224 call list_destroy(source_res_path(i))
1225 call list_destroy(source_interp_option(i))
1226 call list_destroy(source_landmask_land(i))
1227 call list_destroy(source_landmask_water(i))
1229 deallocate(source_res_path)
1230 deallocate(source_interp_option)
1231 deallocate(source_landmask_land)
1232 deallocate(source_landmask_water)
1234 deallocate(is_wordsize)
1235 deallocate(is_endian)
1236 deallocate(is_fieldtype)
1237 deallocate(is_dest_fieldtype)
1239 deallocate(is_priority)
1242 deallocate(is_known_x)
1243 deallocate(is_known_y)
1244 deallocate(is_known_lat)
1245 deallocate(is_known_lon)
1246 deallocate(is_truelat1)
1247 deallocate(is_truelat2)
1248 deallocate(is_stdlon)
1249 deallocate(is_fieldname)
1251 deallocate(is_tile_x)
1252 deallocate(is_tile_y)
1253 deallocate(is_tile_z)
1254 deallocate(is_tile_z_start)
1255 deallocate(is_tile_z_end)
1256 deallocate(is_tile_bdr)
1257 deallocate(is_category_min)
1258 deallocate(is_category_max)
1259 deallocate(is_masked)
1260 deallocate(is_halt_missing)
1261 deallocate(is_output_stagger)
1262 deallocate(is_row_order)
1263 deallocate(is_dominant_category)
1264 deallocate(is_dominant_only)
1267 deallocate(is_scale_factor)
1268 deallocate(is_z_dim_name)
1269 deallocate(is_smooth_option)
1270 deallocate(is_smooth_passes)
1271 deallocate(is_signed)
1272 deallocate(is_units)
1273 deallocate(is_descr)
1274 deallocate(is_missing_value)
1275 deallocate(is_fill_missing)
1276 deallocate(is_subgrid)
1279 call hash_destroy(bad_files)
1281 end subroutine datalist_destroy
1284 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1285 ! Name: reset_next_field
1287 ! Purpose: To reset the pointer to the next field in the list of fields
1288 ! specified by the user.
1289 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1290 subroutine reset_next_field()
1296 end subroutine reset_next_field
1299 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1300 ! Name: get_next_fieldname
1302 ! Purpose: Calling this routine results in field_name being set to the name of
1303 ! the field currently pointed to. If istatus /= 0 upon return, an error
1304 ! occurred, and the value of field_name is undefined.
1305 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1306 subroutine get_next_fieldname(field_name, istatus)
1311 integer, intent(out) :: istatus
1312 character (len=128), intent(out) :: field_name
1316 if (next_field <= num_entries) then
1318 field_name = source_fieldname(next_field)
1319 next_field = next_field + 1
1324 end subroutine get_next_fieldname
1327 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1328 ! Name: get_next_output_fieldname
1331 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1332 recursive subroutine get_next_output_fieldname(nest_num, field_name, ndims, &
1334 istagger, memorder, dimnames, units, &
1335 description, sr_x, sr_y, istatus)
1341 #include "wrf_io_flags.h"
1344 integer, intent(in) :: nest_num
1345 integer, intent(out) :: istatus, ndims, istagger, min_cat, max_cat
1346 integer, intent(out) :: sr_x, sr_y
1347 character (len=128), intent(out) :: memorder, field_name, units, description
1348 character (len=128), dimension(3), intent(out) :: dimnames
1351 integer :: temp_fieldtype
1352 integer, dimension(MAX_LANDMASK_CATEGORIES) :: landmask
1353 logical :: is_water_mask, is_dom_only
1354 character (len=128) :: domcat_name, dfdx_name, dfdy_name
1355 character (len=256) :: temphash
1359 if (output_field_state == RETURN_LANDMASK) then
1360 call hash_init(duplicate_fnames)
1361 call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
1362 if (istatus == 0) then
1363 temphash(129:256) = ' '
1364 temphash(1:128) = field_name(1:128)
1365 call hash_insert(duplicate_fnames, temphash)
1366 call get_domcategory_name(field_name, domcat_name, is_dom_only, istatus)
1367 ! We will only save the dominant category
1368 if (is_dom_only .and. (istatus == 0)) then
1369 output_field_state = RETURN_DOMCAT_LM
1370 call get_next_output_fieldname(nest_num, field_name, ndims, &
1371 min_cat, max_cat, istagger, &
1372 memorder, dimnames, units, description, &
1373 sr_x, sr_y, istatus)
1379 temp_fieldtype = iget_fieldtype(field_name, istatus)
1380 if (istatus == 0) then
1381 if (temp_fieldtype == CONTINUOUS) then
1382 call get_max_levels(field_name, min_cat, max_cat, istatus)
1383 else if (temp_fieldtype == CATEGORICAL) then
1384 call get_max_categories(field_name, min_cat, max_cat, istatus)
1386 if (max_cat - min_cat > 0) ndims = 3
1388 call get_output_stagger(field_name, istagger, istatus)
1389 if (istagger == M) then
1390 dimnames(1) = 'west_east'
1391 dimnames(2) = 'south_north'
1392 else if (istagger == U) then
1393 dimnames(1) = 'west_east_stag'
1394 dimnames(2) = 'south_north'
1395 else if (istagger == V) then
1396 dimnames(1) = 'west_east'
1397 dimnames(2) = 'south_north_stag'
1398 else if (istagger == HH) then
1399 dimnames(1) = 'west_east'
1400 dimnames(2) = 'south_north'
1401 else if (istagger == VV) then
1402 dimnames(1) = 'west_east'
1403 dimnames(2) = 'south_north'
1405 if (ndims == 2) then
1408 else if (ndims == 3) then
1410 call get_z_dim_name(field_name, dimnames(3), istatus)
1416 call get_subgrid_dim_name(nest_num, field_name, dimnames(1:2), sr_x, sr_y, istatus)
1417 call get_source_units(field_name, 1, units, istatus)
1418 if (istatus /= 0) units = '-'
1419 call get_source_descr(field_name, 1, description, istatus)
1420 if (istatus /= 0) description = '-'
1422 output_field_state = RETURN_DOMCAT_LM
1425 output_field_state = RETURN_FIELDNAME
1426 call get_next_output_fieldname(nest_num, field_name, ndims, &
1427 min_cat, max_cat, istagger, &
1428 memorder, dimnames, units, description, &
1429 sr_x, sr_y, istatus)
1433 else if (output_field_state == RETURN_FIELDNAME) then
1434 call get_next_fieldname(field_name, istatus)
1435 temphash(129:256) = ' '
1436 temphash(1:128) = field_name(1:128)
1437 if (istatus == 0 .and. (.not. hash_search(duplicate_fnames, temphash))) then
1438 call hash_insert(duplicate_fnames, temphash)
1439 call get_domcategory_name(field_name, domcat_name, is_dom_only, istatus)
1440 ! We will only save the dominant category
1441 if (is_dom_only .and. (istatus == 0)) then
1442 output_field_state = RETURN_DOMCAT
1443 call get_next_output_fieldname(nest_num, field_name, ndims, &
1444 min_cat, max_cat, istagger, &
1445 memorder, dimnames, units, description, &
1446 sr_x, sr_y, istatus)
1449 ! Return the fractional field
1454 temp_fieldtype = iget_fieldtype(field_name, istatus)
1455 if (istatus == 0) then
1456 if (temp_fieldtype == CONTINUOUS) then
1457 call get_max_levels(field_name, min_cat, max_cat, istatus)
1458 else if (temp_fieldtype == CATEGORICAL) then
1459 call get_max_categories(field_name, min_cat, max_cat, istatus)
1461 if (max_cat - min_cat > 0) ndims = 3
1463 call get_output_stagger(field_name, istagger, istatus)
1464 if (istagger == M) then
1465 dimnames(1) = 'west_east'
1466 dimnames(2) = 'south_north'
1467 else if (istagger == U) then
1468 dimnames(1) = 'west_east_stag'
1469 dimnames(2) = 'south_north'
1470 else if (istagger == V) then
1471 dimnames(1) = 'west_east'
1472 dimnames(2) = 'south_north_stag'
1473 else if (istagger == HH) then
1474 dimnames(1) = 'west_east'
1475 dimnames(2) = 'south_north'
1476 else if (istagger == VV) then
1477 dimnames(1) = 'west_east'
1478 dimnames(2) = 'south_north'
1480 if (ndims == 2) then
1483 else if (ndims == 3) then
1485 call get_z_dim_name(field_name, dimnames(3), istatus)
1491 call get_subgrid_dim_name(nest_num, field_name, dimnames(1:2), sr_x, sr_y, istatus)
1492 call get_source_units(field_name, 1, units, istatus)
1493 if (istatus /= 0) units = '-'
1494 call get_source_descr(field_name, 1, description, istatus)
1495 if (istatus /= 0) description = '-'
1497 output_field_state = RETURN_DOMCAT
1499 else if (istatus /= 0) then
1500 output_field_state = RETURN_LANDMASK
1501 call hash_destroy(duplicate_fnames)
1503 else if (hash_search(duplicate_fnames, temphash)) then
1504 call get_next_output_fieldname(nest_num, field_name, ndims, &
1505 min_cat, max_cat, istagger, &
1506 memorder, dimnames, units, description, &
1507 sr_x, sr_y, istatus)
1511 else if (output_field_state == RETURN_DOMCAT .or. &
1512 output_field_state == RETURN_DOMCAT_LM ) then
1513 if (output_field_state == RETURN_DOMCAT) then
1514 next_field = next_field - 1
1515 call get_next_fieldname(field_name, istatus)
1517 call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
1519 if (istatus == 0) then
1520 call get_domcategory_name(field_name, domcat_name, is_dom_only, istatus)
1521 if (istatus == 0) then
1525 call get_output_stagger(field_name, istagger, istatus)
1526 if (istagger == M) then
1527 dimnames(1) = 'west_east'
1528 dimnames(2) = 'south_north'
1529 else if (istagger == U) then
1530 dimnames(1) = 'west_east_stag'
1531 dimnames(2) = 'south_north'
1532 else if (istagger == V) then
1533 dimnames(1) = 'west_east'
1534 dimnames(2) = 'south_north_stag'
1535 else if (istagger == HH) then
1536 dimnames(1) = 'west_east'
1537 dimnames(2) = 'south_north'
1538 else if (istagger == VV) then
1539 dimnames(1) = 'west_east'
1540 dimnames(2) = 'south_north'
1545 call get_subgrid_dim_name(nest_num, field_name, dimnames(1:2), sr_x, sr_y, istatus)
1546 field_name = domcat_name
1548 description = 'Dominant category'
1549 if (output_field_state == RETURN_DOMCAT) then
1550 output_field_state = RETURN_DFDX
1552 output_field_state = RETURN_DFDX_LM
1555 if (output_field_state == RETURN_DOMCAT) then
1556 output_field_state = RETURN_DFDX
1558 output_field_state = RETURN_DFDX_LM
1560 call get_next_output_fieldname(nest_num, field_name, ndims, &
1561 min_cat, max_cat, istagger, &
1562 memorder, dimnames, units, description, &
1563 sr_x, sr_y, istatus)
1567 call mprintf(.true., ERROR, 'get_next_output_fieldname(): In state DOMCAT, '// &
1568 'but no field name is found.')
1571 else if (output_field_state == RETURN_DFDX .or. &
1572 output_field_state == RETURN_DFDX_LM) then
1573 if (output_field_state == RETURN_DFDX) then
1574 next_field = next_field - 1
1575 call get_next_fieldname(field_name, istatus)
1577 call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
1579 if (istatus == 0) then
1580 call get_dfdx_name(field_name, dfdx_name, istatus)
1581 if (istatus == 0) then
1585 temp_fieldtype = iget_fieldtype(field_name, istatus)
1586 if (istatus == 0) then
1587 if (temp_fieldtype == CONTINUOUS) then
1588 call get_max_levels(field_name, min_cat, max_cat, istatus)
1589 else if (temp_fieldtype == CATEGORICAL) then
1590 call get_max_categories(field_name, min_cat, max_cat, istatus)
1592 if (max_cat - min_cat > 0) ndims = 3
1594 call get_output_stagger(field_name, istagger, istatus)
1595 if (istagger == M) then
1596 dimnames(1) = 'west_east'
1597 dimnames(2) = 'south_north'
1598 else if (istagger == U) then
1599 dimnames(1) = 'west_east_stag'
1600 dimnames(2) = 'south_north'
1601 else if (istagger == V) then
1602 dimnames(1) = 'west_east'
1603 dimnames(2) = 'south_north_stag'
1604 else if (istagger == HH) then
1605 dimnames(1) = 'west_east'
1606 dimnames(2) = 'south_north'
1607 else if (istagger == VV) then
1608 dimnames(1) = 'west_east'
1609 dimnames(2) = 'south_north'
1611 if (ndims == 2) then
1614 else if (ndims == 3) then
1616 call get_z_dim_name(field_name, dimnames(3), istatus)
1622 field_name = dfdx_name
1625 call get_subgrid_dim_name(nest_num, field_name, dimnames(1:2), sr_x, sr_y, istatus)
1626 description = 'df/dx'
1627 if (output_field_state == RETURN_DFDX) then
1628 output_field_state = RETURN_DFDY
1630 output_field_state = RETURN_DFDY_LM
1633 if (output_field_state == RETURN_DFDX) then
1634 output_field_state = RETURN_DFDY
1636 output_field_state = RETURN_DFDY_LM
1638 call get_next_output_fieldname(nest_num, field_name, ndims, &
1639 min_cat, max_cat, istagger, &
1640 memorder, dimnames, units, description, &
1641 sr_x, sr_y, istatus)
1645 call mprintf(.true., ERROR, 'get_next_output_fieldname(): In state DFDX, '// &
1646 'but no field name is found.')
1649 else if (output_field_state == RETURN_DFDY .or. &
1650 output_field_state == RETURN_DFDY_LM) then
1651 if (output_field_state == RETURN_DFDY) then
1652 next_field = next_field - 1
1653 call get_next_fieldname(field_name, istatus)
1655 call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
1657 if (istatus == 0) then
1658 call get_dfdy_name(field_name, dfdy_name, istatus)
1659 if (istatus == 0) then
1663 temp_fieldtype = iget_fieldtype(field_name, istatus)
1664 if (istatus == 0) then
1665 if (temp_fieldtype == CONTINUOUS) then
1666 call get_max_levels(field_name, min_cat, max_cat, istatus)
1667 else if (temp_fieldtype == CATEGORICAL) then
1668 call get_max_categories(field_name, min_cat, max_cat, istatus)
1670 if (max_cat - min_cat > 0) ndims = 3
1672 call get_output_stagger(field_name, istagger, istatus)
1673 if (istagger == M) then
1674 dimnames(1) = 'west_east'
1675 dimnames(2) = 'south_north'
1676 else if (istagger == U) then
1677 dimnames(1) = 'west_east_stag'
1678 dimnames(2) = 'south_north'
1679 else if (istagger == V) then
1680 dimnames(1) = 'west_east'
1681 dimnames(2) = 'south_north_stag'
1682 else if (istagger == HH) then
1683 dimnames(1) = 'west_east'
1684 dimnames(2) = 'south_north'
1685 else if (istagger == VV) then
1686 dimnames(1) = 'west_east'
1687 dimnames(2) = 'south_north'
1689 if (ndims == 2) then
1692 else if (ndims == 3) then
1694 call get_z_dim_name(field_name, dimnames(3), istatus)
1701 call get_subgrid_dim_name(nest_num, field_name, dimnames(1:2), sr_x, sr_y, istatus)
1702 field_name = dfdy_name
1704 description = 'df/dy'
1705 output_field_state = RETURN_FIELDNAME
1707 output_field_state = RETURN_FIELDNAME
1708 call get_next_output_fieldname(nest_num, field_name, ndims, &
1709 min_cat, max_cat, istagger, &
1710 memorder, dimnames, units, description, &
1711 sr_x, sr_y, istatus)
1715 call mprintf(.true., ERROR, 'get_next_output_fieldname(): In state DFDY, but no '// &
1716 'field name is found.')
1721 end subroutine get_next_output_fieldname
1724 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1725 ! Name: get_landmask_field
1727 ! Purpose: To return the name of the field from which the landmask is to be
1728 ! computed. If no error occurs, is_water_mask is .true. if the landmask
1729 ! value specifies the value of water, and .false. if the landmask value
1730 ! specifies the value of land.
1731 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1732 subroutine get_landmask_field(res_string, landmask_name, is_water_mask, landmask, istatus)
1737 character (len=128), intent(in) :: res_string
1738 integer, dimension(:), intent(out) :: landmask
1739 integer, intent(out) :: istatus
1740 logical, intent(out) :: is_water_mask
1741 character (len=128), intent(out) :: landmask_name
1747 integer :: is, ie, sos, eos, comma
1748 character (len=128) :: temp_res, mask_cat_string
1752 do idx=1,num_entries
1754 if (list_length(source_landmask_land(idx)) > 0) then
1756 ie = index(res_string(is:128),'+') - 1
1757 if (ie <= 0) ie = 128
1758 temp_res = res_string(is:ie)
1759 do while (.not. list_search(source_landmask_land(idx), ckey=temp_res, cvalue=mask_cat_string) &
1762 ie = is + index(res_string(is:128),'+') - 2
1763 if (ie - is <= 0) ie = 128
1764 temp_res = res_string(is:ie)
1768 temp_res = 'default'
1769 if (list_search(source_landmask_land(idx), ckey=temp_res, cvalue=mask_cat_string)) then
1770 is_water_mask = .false.
1771 landmask_name = source_fieldname(idx)
1775 is_water_mask = .false.
1776 landmask_name = source_fieldname(idx)
1782 ! Note: The following cannot be an else-if, since different resolutions of data may
1783 ! specify, alternately, a land or a water mask, and in general we need to search
1786 if (list_length(source_landmask_water(idx)) > 0) then
1788 ie = index(res_string(is:128),'+') - 1
1789 if (ie <= 0) ie = 128
1790 temp_res = res_string(is:ie)
1791 do while (.not. list_search(source_landmask_water(idx), ckey=temp_res, cvalue=mask_cat_string) &
1794 ie = is + index(res_string(is:128),'+') - 2
1795 if (ie - is <= 0) ie = 128
1796 temp_res = res_string(is:ie)
1800 temp_res = 'default'
1801 if (list_search(source_landmask_water(idx), ckey=temp_res, cvalue=mask_cat_string)) then
1802 is_water_mask = .true.
1803 landmask_name = source_fieldname(idx)
1807 is_water_mask = .true.
1808 landmask_name = source_fieldname(idx)
1813 if (istatus == 0) then
1817 comma = index(mask_cat_string(sos+1:eos-1),',')
1818 do while (comma > 0 .and. j < MAX_LANDMASK_CATEGORIES)
1819 read(mask_cat_string(sos+1:sos+comma-1),'(i10)') landmask(j)
1821 comma = index(mask_cat_string(sos+1:eos-1),',')
1824 read(mask_cat_string(sos+1:eos-1),'(i10)') landmask(j)
1826 if (j <= MAX_LANDMASK_CATEGORIES) then ! Terminate list with a flag value
1827 landmask(j) = INVALID
1834 end subroutine get_landmask_field
1837 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1838 ! Name: get_missing_value
1840 ! Pupose: Return the value used in the source data to indicate missing data.
1841 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1842 subroutine get_missing_value(fieldnm, ilevel, rmissing, istatus)
1847 integer, intent(in) :: ilevel
1848 integer, intent(out) :: istatus
1849 real, intent(out) :: rmissing
1850 character (len=128), intent(in) :: fieldnm
1857 do idx=1,num_entries
1858 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
1859 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
1860 (source_priority(idx) == ilevel)) then
1862 if (is_missing_value(idx)) then
1863 rmissing = source_missing_value(idx)
1871 end subroutine get_missing_value
1874 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1875 ! Name: get_source_units
1877 ! Pupose: Return a string giving the units of the specified source data.
1878 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1879 subroutine get_source_units(fieldnm, ilevel, cunits, istatus)
1884 integer, intent(in) :: ilevel
1885 integer, intent(out) :: istatus
1886 character (len=128), intent(in) :: fieldnm
1887 character (len=128), intent(out) :: cunits
1894 do idx=1,num_entries
1895 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
1896 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
1897 (source_priority(idx) == ilevel)) then
1899 if (is_units(idx)) then
1900 cunits = source_units(idx)
1908 end subroutine get_source_units
1911 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1912 ! Name: get_source_descr
1914 ! Pupose: Return a string giving a description of the specified source data.
1915 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1916 subroutine get_source_descr(fieldnm, ilevel, descr, istatus)
1921 integer, intent(in) :: ilevel
1922 integer, intent(out) :: istatus
1923 character (len=128), intent(in) :: fieldnm
1924 character (len=128), intent(out) :: descr
1931 do idx=1,num_entries
1932 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
1933 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
1934 (source_priority(idx) == ilevel)) then
1936 if (is_units(idx)) then
1937 descr = source_descr(idx)
1945 end subroutine get_source_descr
1948 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1949 ! Name: get_missing_fill_value
1951 ! Pupose: Return the value to fill missing points with.
1952 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1953 subroutine get_missing_fill_value(fieldnm, rmissing, istatus)
1958 integer, intent(out) :: istatus
1959 real, intent(out) :: rmissing
1960 character (len=128), intent(in) :: fieldnm
1967 do idx=1,num_entries
1968 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
1969 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) ) then
1971 if (is_fill_missing(idx)) then
1972 rmissing = source_fill_missing(idx)
1980 end subroutine get_missing_fill_value
1983 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1984 ! Name: get_halt_on_missing
1986 ! Pupose: Returns 1 if the program should halt upon encountering a missing
1987 ! value in the final output field, and 0 otherwise.
1988 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1989 subroutine get_halt_on_missing(fieldnm, halt, istatus)
1994 integer, intent(out) :: istatus
1995 logical, intent(out) :: halt
1996 character (len=128), intent(in) :: fieldnm
2004 do idx=1,num_entries
2005 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2006 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) ) then
2008 if (is_halt_missing(idx)) halt = .true.
2013 end subroutine get_halt_on_missing
2016 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2017 ! Name: get_masked_value
2019 ! Pupose: If the field is to be masked by the landmask, returns 0 if the field
2020 ! is masked over water and 1 if the field is masked over land. If no mask is
2021 ! to be applied, -1 is returned.
2022 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2023 subroutine get_masked_value(fieldnm, ilevel, masked, istatus)
2028 integer, intent(in) :: ilevel
2029 integer, intent(out) :: istatus
2030 real, intent(out) :: masked
2031 character (len=128), intent(in) :: fieldnm
2039 do idx=1,num_entries
2040 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2041 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
2042 (source_priority(idx) == ilevel)) then
2044 if (is_masked(idx)) then
2045 masked = source_masked(idx)
2052 end subroutine get_masked_value
2055 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2056 ! Name: get_max_levels
2058 ! Purpose: Returns the number of levels for the field given by fieldnm.
2059 ! The number of levels will generally be specified for continuous fields,
2060 ! whereas min/max category will generally be specified for categorical ones.
2061 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2062 subroutine get_max_levels(fieldnm, min_level, max_level, istatus)
2067 integer, intent(out) :: min_level, max_level, istatus
2068 character (len=128), intent(in) :: fieldnm
2072 logical :: have_found_field
2074 have_found_field = .false.
2077 do idx=1,num_entries
2078 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2079 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2081 if (is_dest_fieldtype(idx) .and. (source_dest_fieldtype(idx) /= CONTINUOUS)) then
2082 call mprintf(.true., WARN, 'In GEOGRID.TBL, destination field type for %s is '// &
2083 'not continuous and min/max levels specified.', s1=trim(fieldnm))
2085 if (.not. have_found_field) then
2086 if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
2087 have_found_field = .true.
2089 min_level = source_tile_z_start(idx)
2090 max_level = source_tile_z_end(idx)
2091 else if (is_tile_z(idx)) then
2092 have_found_field = .true.
2095 max_level = source_tile_z(idx)
2098 if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
2099 if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
2100 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start '// &
2101 'and tile_z_end specified for entry %i.',i1=idx)
2105 if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
2106 if (source_tile_z_start(idx) < min_level) min_level = source_tile_z_start(idx)
2107 if (source_tile_z_end(idx) > max_level) max_level = source_tile_z_end(idx)
2108 else if (is_tile_z(idx)) then
2109 if (min_level > 1) min_level = 1
2110 if (source_tile_z(idx) > max_level) max_level = source_tile_z(idx)
2113 if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
2114 if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
2115 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start '// &
2116 'and tile_z_end specified for entry %i.',i1=idx)
2124 end subroutine get_max_levels
2127 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2128 ! Name: get_source_levels
2130 ! Purpose: Return the min and max z-index for the source data for fieldname
2131 ! at a specified priority level (compared with the min/max level over
2132 ! all priority levels, as given by get_max_levels).
2133 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2134 subroutine get_source_levels(fieldnm, ilevel, min_level, max_level, istatus)
2139 integer, intent(in) :: ilevel
2140 integer, intent(out) :: min_level, max_level, istatus
2141 character (len=128), intent(in) :: fieldnm
2148 do idx=1,num_entries
2149 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2150 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2151 if (ilevel == source_priority(idx)) then
2153 if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
2155 min_level = source_tile_z_start(idx)
2156 max_level = source_tile_z_end(idx)
2157 else if (is_tile_z(idx)) then
2160 max_level = source_tile_z(idx)
2163 if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
2164 if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
2165 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start '// &
2166 'and tile_z_end specified for entry %i.',i1=idx)
2174 end subroutine get_source_levels
2177 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2178 ! Name: get_max_categories
2180 ! Purpose: Returns the minimum category and the maximum category for the field
2182 ! Min/max category will generally be specified for categorical fields,
2183 ! whereas the number of levels will generally be specified for continuous
2185 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2186 subroutine get_max_categories(fieldnm, min_category, max_category, istatus)
2191 integer, intent(out) :: min_category, max_category, istatus
2192 character (len=128), intent(in) :: fieldnm
2196 logical :: have_found_field
2198 have_found_field = .false.
2201 do idx=1,num_entries
2202 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2203 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2205 if (is_dest_fieldtype(idx) .and. (source_dest_fieldtype(idx) /= CATEGORICAL)) then
2206 call mprintf(.true., WARN, &
2207 'In GEOGRID.TBL, cannot get min/max categories for continuous '// &
2208 'field %s at entry %i. Perhaps the user has requested to '// &
2209 'perform a strange operation on the field.', s1=trim(fieldnm), i1=idx)
2211 if (.not. have_found_field) then
2212 if (is_category_min(idx) .and. is_category_max(idx)) then
2213 have_found_field = .true.
2215 min_category = source_category_min(idx)
2216 max_category = source_category_max(idx)
2217 else if (is_category_min(idx) .or. is_category_max(idx)) then
2218 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of min_category and '// &
2219 'max_category specified for entry %i.',i1=idx)
2222 if (is_category_min(idx) .and. is_category_max(idx)) then
2223 if (source_category_min(idx) < min_category) min_category = source_category_min(idx)
2224 if (source_category_max(idx) > max_category) max_category = source_category_max(idx)
2225 else if (is_category_min(idx) .or. is_category_max(idx)) then
2226 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of min_category and '// &
2227 'max_category specified for entry %i.',i1=idx)
2234 end subroutine get_max_categories
2237 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2238 ! Name: get_source_categories
2240 ! Purpose: Return the min and max category for the source data for fieldname
2241 ! at a specified priority level (compared with the min/max category over
2242 ! all priority levels, as given by get_max_categories).
2243 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2244 subroutine get_source_categories(fieldnm, ilevel, min_category, max_category, istatus)
2249 integer, intent(in) :: ilevel
2250 integer, intent(out) :: min_category, max_category, istatus
2251 character (len=128), intent(in) :: fieldnm
2258 do idx=1,num_entries
2259 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2260 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2261 if (ilevel == source_priority(idx)) then
2263 if (is_category_min(idx) .and. is_category_max(idx)) then
2265 min_category = source_category_min(idx)
2266 max_category = source_category_max(idx)
2267 else if (is_category_min(idx) .or. is_category_max(idx)) then
2268 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of min_category '// &
2269 'and max_category specified for entry %i.',i1=idx)
2276 end subroutine get_source_categories
2279 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2280 ! Name: get_domcategory_name
2283 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2284 subroutine get_domcategory_name(fieldnm, domcat_name, ldominant_only, istatus)
2289 integer, intent(out) :: istatus
2290 logical, intent(out) :: ldominant_only
2291 character (len=128), intent(in) :: fieldnm
2292 character (len=128), intent(out) :: domcat_name
2298 ldominant_only = .false.
2300 do idx=1,num_entries
2301 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2302 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2304 if (is_dominant_category(idx)) then
2305 domcat_name = source_dominant_category(idx)
2307 if (is_dominant_only(idx)) then
2308 call mprintf(.true., WARN, 'In GEOGRID.TBL, both dominant_category and '// &
2309 'dominant_only are specified in entry %i. Using specification '// &
2310 'for dominant_category.',i1=idx)
2311 is_dominant_only(idx) = .false.
2315 else if (is_dominant_only(idx)) then
2316 domcat_name = source_dominant_only(idx)
2317 ldominant_only = .true.
2325 end subroutine get_domcategory_name
2328 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2329 ! Name: get_dfdx_name
2332 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2333 subroutine get_dfdx_name(fieldnm, dfdx_name, istatus)
2338 integer, intent(out) :: istatus
2339 character (len=128), intent(in) :: fieldnm
2340 character (len=128), intent(out) :: dfdx_name
2347 do idx=1,num_entries
2348 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2349 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2351 if (is_dfdx(idx)) then
2352 dfdx_name = source_dfdx(idx)
2360 end subroutine get_dfdx_name
2363 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2364 ! Name: get_dfdy_name
2367 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2368 subroutine get_dfdy_name(fieldnm, dfdy_name, istatus)
2373 integer, intent(out) :: istatus
2374 character (len=128), intent(in) :: fieldnm
2375 character (len=128), intent(out) :: dfdy_name
2382 do idx=1,num_entries
2383 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2384 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2386 if (is_dfdy(idx)) then
2387 dfdy_name = source_dfdy(idx)
2395 end subroutine get_dfdy_name
2398 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2399 ! Name: get_z_dim_name
2402 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2403 subroutine get_z_dim_name(fieldnm, z_dim, istatus)
2408 integer, intent(out) :: istatus
2409 character (len=128), intent(in) :: fieldnm
2410 character (len=128), intent(out) :: z_dim
2417 do idx=1,num_entries
2418 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2419 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2420 if (is_z_dim_name(idx)) then
2421 z_dim = source_z_dim_name(idx)
2428 end subroutine get_z_dim_name
2431 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2432 ! Name: get_field_scale_factor
2435 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2436 subroutine get_field_scale_factor(fieldnm, ilevel, scale_factor, istatus)
2441 integer, intent(in) :: ilevel
2442 integer, intent(out) :: istatus
2443 real, intent(out) :: scale_factor
2444 character (len=128), intent(in) :: fieldnm
2451 do idx=1,num_entries
2452 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2453 (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
2454 (ilevel == source_priority(idx))) then
2456 if (is_scale_factor(idx)) then
2457 scale_factor = source_scale_factor(idx)
2464 end subroutine get_field_scale_factor
2467 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2468 ! Name: get_output_stagger
2471 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2472 subroutine get_output_stagger(fieldnm, istagger, istatus)
2479 integer, intent(out) :: istatus, istagger
2480 character (len=128), intent(in) :: fieldnm
2486 do idx=1,num_entries
2487 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2488 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2490 if (is_output_stagger(idx)) then
2492 istagger = source_output_stagger(idx)
2495 if (gridtype == 'C') then
2499 else if (gridtype == 'E') then
2509 end subroutine get_output_stagger
2512 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2513 ! Name: get_subgrid_dim_name
2516 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2517 subroutine get_subgrid_dim_name(nest_num, field_name, dimnames, &
2518 sub_x, sub_y, istatus)
2523 integer, intent(in) :: nest_num
2524 integer, intent(out) :: sub_x, sub_y, istatus
2525 character(len=128), intent(in) :: field_name
2526 character(len=128), dimension(2), intent(inout) :: dimnames
2527 integer :: idx, nlen
2533 do idx=1,num_entries
2534 if ((index(source_fieldname(idx),trim(field_name)) /= 0) .and. &
2535 (len_trim(source_fieldname(idx)) == len_trim(field_name))) then
2536 if (is_subgrid(idx)) then
2538 if (is_output_stagger(idx)) then
2539 call mprintf(.true.,ERROR,'Cannot use subgrids on variables with staggered grids')
2541 dimnames(1) = trim(dimnames(1))//"_subgrid"
2542 dimnames(2) = trim(dimnames(2))//"_subgrid"
2543 sub_x = subgrid_ratio_x(nest_num)
2544 sub_y = subgrid_ratio_y(nest_num)
2549 end subroutine get_subgrid_dim_name
2552 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2553 ! Name: get_interp_option
2556 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2557 subroutine get_interp_option(fieldnm, ilevel, interp_opt, istatus)
2562 integer, intent(in) :: ilevel
2563 integer, intent(out) :: istatus
2564 character (len=128), intent(in) :: fieldnm
2565 character (len=128), intent(out) :: interp_opt
2571 do idx=1,num_entries
2572 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2573 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2574 if (ilevel == source_priority(idx)) then
2576 interp_opt = source_interp_string(idx)
2584 end subroutine get_interp_option
2587 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2588 ! Name: get_gcel_threshold
2591 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2592 subroutine get_gcell_threshold(interp_opt, threshold, istatus)
2597 integer, intent(out) :: istatus
2598 real, intent(out) :: threshold
2599 character (len=128), intent(in) :: interp_opt
2602 integer :: i, p1, p2
2607 i = index(interp_opt,'average_gcell')
2609 ! Move the "average_gcell" option to the beginning
2614 ! Check for a threshold
2615 p1 = index(interp_opt(i:128),'(')
2616 p2 = index(interp_opt(i:128),')')
2617 if (p1 /= 0 .and. p2 /= 0) then
2618 read(interp_opt(p1+1:p2-1),*,err=1000) threshold
2620 call mprintf(.true., WARN, 'Problem with specified threshold '// &
2621 'for average_gcell interp option. Setting threshold to 0.0.')
2629 1000 call mprintf(.true., ERROR, 'Threshold option to average_gcell interpolator '// &
2630 'must be a real number, enclosed in parentheses immediately '// &
2631 'after keyword "average_gcell"')
2633 end subroutine get_gcell_threshold
2636 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2637 ! Name: get_smooth_option
2640 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2641 subroutine get_smooth_option(fieldnm, smooth_opt, smooth_passes, istatus)
2646 integer, intent(out) :: istatus, smooth_opt, smooth_passes
2647 character (len=128), intent(in) :: fieldnm
2654 do idx=1,num_entries
2655 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2656 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2658 if (is_smooth_option(idx)) then
2660 smooth_opt = source_smooth_option(idx)
2662 if (is_smooth_passes(idx)) then
2663 smooth_passes = source_smooth_passes(idx)
2674 end subroutine get_smooth_option
2677 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2678 ! Name: iget_fieldtype
2681 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2682 function iget_fieldtype(fieldnm, istatus)
2687 integer, intent(out) :: istatus
2688 character (len=128), intent(in) :: fieldnm
2694 integer :: iget_fieldtype
2698 do idx=1,num_entries
2699 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2700 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2702 if (is_dest_fieldtype(idx)) then
2703 iget_fieldtype = source_dest_fieldtype(idx)
2711 end function iget_fieldtype
2714 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2715 ! Name: iget_source_fieldtype
2717 ! Purpose: Given a resolution, in degrees, and the name of a field, this
2718 ! function returns the type (categorical, continuous, etc.) of the source
2719 ! data that will be used. This may, in general, depend on the field name
2720 ! and the resolution; for example, near 30 second resolution, land use data
2721 ! may come from a categorical field, whereas for lower resolutions, it may
2722 ! come from arrays of land use fractions for each category.
2723 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2724 function iget_source_fieldtype(fieldnm, ilevel, istatus)
2729 integer, intent(in) :: ilevel
2730 integer, intent(out) :: istatus
2731 character (len=128), intent(in) :: fieldnm
2734 integer :: iget_source_fieldtype
2739 ! Find information about the source tiles for the specified fieldname
2741 do idx=1,num_entries
2742 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2743 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2744 if (ilevel == source_priority(idx)) then
2746 iget_source_fieldtype = source_fieldtype(idx)
2752 end function iget_source_fieldtype
2755 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2756 ! Name: get_data_tile
2759 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2760 subroutine get_data_tile(xlat, xlon, ilevel, field_name, &
2761 file_name, array, start_x_dim, end_x_dim, start_y_dim, &
2762 end_y_dim, start_z_dim, end_z_dim, npts_bdr, &
2765 use geotiff_module, only : read_geogrid_tile
2770 integer, intent(in) :: ilevel
2771 integer, intent(out) :: istatus
2772 integer, intent(out) :: start_x_dim, end_x_dim, &
2773 start_y_dim, end_y_dim, &
2774 start_z_dim, end_z_dim, &
2776 real, intent(in) :: xlat, xlon ! Location that tile should contain
2777 real, pointer, dimension(:,:,:) :: array ! The array to be allocated by this routine
2778 character (len=128), intent(in) :: field_name
2779 character (len=256), intent(out) :: file_name
2783 integer :: local_wordsize, local_endian, sign_convention, irow_order, strlen
2784 integer :: xdim,ydim,zdim
2786 real, allocatable, dimension(:) :: temprow
2788 character(len=256) :: gtiff_file
2790 geotiff=is_geotiff_file(field_name,ilevel)
2791 call get_tile_fname(file_name, xlat, xlon, ilevel, field_name, istatus)
2792 if (.not.geotiff .and. index(file_name, 'OUTSIDE') /= 0) then
2795 else if (hash_search(bad_files, file_name)) then
2800 call get_tile_dimensions(xlat, xlon, start_x_dim, end_x_dim, start_y_dim, end_y_dim, &
2801 start_z_dim, end_z_dim, npts_bdr, local_wordsize, local_endian, &
2802 sign_convention, ilevel, field_name, istatus)
2804 xdim = (end_x_dim-start_x_dim+1)
2805 ydim = (end_y_dim-start_y_dim+1)
2806 zdim = (end_z_dim-start_z_dim+1)
2808 if (associated(array)) deallocate(array)
2809 allocate(array(xdim,ydim,zdim))
2811 call get_row_order(field_name, ilevel, irow_order, istatus)
2812 if (istatus /= 0) irow_order = BOTTOM_TOP
2814 call s_len(file_name,strlen)
2820 call get_geotiff_filename(field_name,ilevel,gtiff_file,istatus)
2821 if(istatus.ne.0)then
2822 call mprintf(.true.,ERROR,"Could not find geotiff file for "// &
2825 call read_geogrid_tile(gtiff_file,start_x_dim,end_x_dim, &
2826 start_y_dim,end_y_dim, &
2827 start_z_dim,end_z_dim,array,istatus)
2829 call mprintf(.true.,ERROR,"GEOTIFF file specified for %s, but geogrid not "// &
2830 "compiled with geotiff support.",s1=trim(field_name))
2833 call read_geogrid(file_name, strlen, array, xdim, ydim, zdim, &
2834 sign_convention, local_endian, scalefac, local_wordsize, istatus)
2837 if (irow_order == TOP_BOTTOM) then
2838 allocate(temprow(xdim))
2841 if (ydim-j+1 <= j) exit
2842 temprow(1:xdim) = array(1:xdim,j,k)
2843 array(1:xdim,j,k) = array(1:xdim,ydim-j+1,k)
2844 array(1:xdim,ydim-j+1,k) = temprow(1:xdim)
2850 if (istatus /= 0) then
2851 start_x_dim = INVALID
2852 start_y_dim = INVALID
2856 call hash_insert(bad_files, file_name)
2859 end subroutine get_data_tile
2862 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2863 ! Name: get_row_order
2864 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2865 subroutine get_row_order(fieldnm, ilevel, irow_order, istatus)
2870 integer, intent(in) :: ilevel
2871 character (len=128), intent(in) :: fieldnm
2872 integer, intent(out) :: irow_order, istatus
2878 do idx=1,num_entries
2879 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2880 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2881 if (ilevel == source_priority(idx)) then
2882 if (is_row_order(idx)) then
2883 irow_order = source_row_order(idx)
2891 end subroutine get_row_order
2893 logical function is_geotiff_file(fieldname,ilevel)
2895 character(len=*),intent(in)::fieldname
2896 integer,intent(in)::ilevel
2898 is_geotiff_file=.false.
2899 do idx=1,num_entries
2900 if ((index(source_fieldname(idx),trim(fieldname)) /= 0) .and. &
2901 (len_trim(source_fieldname(idx)) == len_trim(fieldname)) .and. &
2902 (ilevel == source_priority(idx))) then
2903 is_geotiff_file = is_geotiff(idx)
2907 end function is_geotiff_file
2910 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2911 ! Name: get_tile_dimensions
2912 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2913 subroutine get_tile_dimensions(xlat, xlon, start_x_dim, end_x_dim, start_y_dim, end_y_dim, &
2914 start_z_dim, end_z_dim, npts_bdr, bytes_per_datum, endianness, &
2915 sign_convention, ilevel, fieldnm, istatus)
2922 integer, intent(in) :: ilevel
2923 integer, intent(out) :: start_x_dim, end_x_dim, &
2924 start_y_dim, end_y_dim, &
2925 start_z_dim, end_z_dim, &
2927 bytes_per_datum, endianness, &
2928 sign_convention, istatus
2929 real, intent(in) :: xlat, xlon
2930 character (len=128), intent(in) :: fieldnm
2933 integer :: idx, current_domain
2937 do idx=1,num_entries
2938 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
2939 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
2940 if (ilevel == source_priority(idx)) then
2947 if (istatus /= 0) then
2958 current_domain = iget_selected_domain()
2959 call select_domain(SOURCE_PROJ)
2960 call lltoxy(xlat, xlon, rx, ry, M)
2961 call select_domain(current_domain)
2963 start_x_dim = source_tile_x(idx) * nint(real(floor((rx-0.5) / real(source_tile_x(idx))))) + 1
2964 end_x_dim = start_x_dim + source_tile_x(idx) - 1
2966 start_y_dim = source_tile_y(idx) * nint(real(floor((ry-0.5) / real(source_tile_y(idx))))) + 1
2967 end_y_dim = start_y_dim + source_tile_y(idx) - 1
2969 if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
2970 start_z_dim = source_tile_z_start(idx)
2971 end_z_dim = source_tile_z_end(idx)
2972 else if (is_tile_z(idx)) then
2974 end_z_dim = source_tile_z(idx)
2977 if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
2978 if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
2979 call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start and '// &
2980 'tile_z_end specified for entry %i.',i1=idx)
2984 if (is_tile_bdr(idx)) then
2985 npts_bdr = source_tile_bdr(idx)
2990 start_x_dim = start_x_dim - npts_bdr
2991 end_x_dim = end_x_dim + npts_bdr
2992 start_y_dim = start_y_dim - npts_bdr
2993 end_y_dim = end_y_dim + npts_bdr
2995 if (is_wordsize(idx)) then
2996 bytes_per_datum = source_wordsize(idx)
2999 call mprintf(.true.,ERROR,'In GEOGRID.TBL, no wordsize specified for data in entry %i.',i1=idx)
3002 if (is_endian(idx)) then
3003 endianness = source_endian(idx)
3005 endianness = BIG_ENDIAN
3008 if (is_signed(idx)) then
3014 end subroutine get_tile_dimensions
3017 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3018 ! Name: get_tile_fname
3021 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3022 subroutine get_tile_fname(test_fname, xlat, xlon, ilevel, fieldname, istatus)
3030 integer, intent(in) :: ilevel
3031 integer, intent(out) :: istatus
3032 real, intent(in) :: xlat, xlon
3033 character (len=*), intent(in) :: fieldname
3034 character (len=256), intent(out) :: test_fname
3037 integer :: current_domain, idx
3041 write(test_fname, '(a)') 'TILE.OUTSIDE.DOMAIN'
3043 do idx=1,num_entries
3044 if ((index(source_fieldname(idx),trim(fieldname)) /= 0) .and. &
3045 (len_trim(source_fieldname(idx)) == len_trim(fieldname))) then
3046 if (ilevel == source_priority(idx)) then
3053 if (istatus /= 0) return
3055 current_domain = iget_selected_domain()
3056 call select_domain(SOURCE_PROJ)
3057 call lltoxy(xlat, xlon, rx, ry, M)
3058 call select_domain(current_domain)
3060 ! rx = real(source_tile_x(idx)) * real(floor((rx-0.5*source_dx(idx))/ real(source_tile_x(idx)))) + 1.0
3061 ! ry = real(source_tile_y(idx)) * real(floor((ry-0.5*source_dy(idx))/ real(source_tile_y(idx)))) + 1.0
3062 rx = real(source_tile_x(idx)) * real(floor((rx-0.5) / real(source_tile_x(idx)))) + 1.0
3063 ry = real(source_tile_y(idx)) * real(floor((ry-0.5) / real(source_tile_y(idx)))) + 1.0
3065 if (rx > 0. .and. ry > 0.) then
3066 write(test_fname, '(a,i5.5,a1,i5.5,a1,i5.5,a1,i5.5)') trim(source_path(idx)), &
3067 nint(rx),'-',nint(rx)+source_tile_x(idx)-1,'.',nint(ry),'-',nint(ry)+source_tile_y(idx)-1
3070 end subroutine get_tile_fname
3073 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3074 ! Name: get_source_resolution
3077 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3078 subroutine get_source_resolution(fieldnm, ilevel, src_dx, src_dy, istatus)
3083 integer, intent(in) :: ilevel
3084 integer, intent(out) :: istatus
3085 real, intent(out) :: src_dx, src_dy
3086 character (len=*), intent(in) :: fieldnm
3092 do idx=1,num_entries
3093 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
3094 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
3095 if (ilevel == source_priority(idx)) then
3096 if (is_dx(idx) .and. is_dy(idx)) then
3097 src_dx = source_dx(idx)
3098 src_dy = source_dy(idx)
3099 if (source_proj(idx) /= PROJ_LATLON) then
3100 src_dx = src_dx / 111000.
3101 src_dy = src_dy / 111000.
3110 end subroutine get_source_resolution
3113 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3114 ! Name: get_data_projection
3116 ! Purpose: To acquire the parameters necessary in defining the grid on which
3117 ! the user-specified data for field 'fieldnm' are given.
3119 ! NOTES: If the routine successfully acquires values for all necessary
3120 ! parameters, istatus is set to 0. In case of an error,
3121 ! OR IF THE USER HAS NOT SPECIFIED A TILE OF DATA FOR FIELDNM,
3122 ! istatus is set to 1.
3123 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3124 subroutine get_data_projection(fieldnm, iproj, stand_lon, truelat1, truelat2, &
3125 dxkm, dykm, known_x, known_y, known_lat, known_lon, ilevel, istatus)
3130 integer, intent(in) :: ilevel
3131 integer, intent(out) :: iproj, istatus
3132 real, intent(out) :: stand_lon, truelat1, truelat2, dxkm, dykm, &
3133 known_x, known_y, known_lat, known_lon
3134 character (len=*), intent(in) :: fieldnm
3140 do idx=1,num_entries
3141 if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
3142 (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
3143 if (ilevel == source_priority(idx)) then
3145 if (is_proj(idx)) then
3146 iproj = source_proj(idx)
3149 call mprintf(.true., ERROR, &
3150 'In GEOGRID.TBL, no specification for projection in entry %i.',i1=idx)
3152 if (is_known_x(idx)) then
3153 known_x = source_known_x(idx)
3156 call mprintf(.true., ERROR, &
3157 'In GEOGRID.TBL, no specification for known_x in entry %i.',i1=idx)
3159 if (is_known_y(idx)) then
3160 known_y = source_known_y(idx)
3163 call mprintf(.true., ERROR, &
3164 'In GEOGRID.TBL, no specification for known_y in entry %i.',i1=idx)
3166 if (is_known_lat(idx)) then
3167 known_lat = source_known_lat(idx)
3170 call mprintf(.true., ERROR, &
3171 'In GEOGRID.TBL, no specification for known_lat in entry %i.',i1=idx)
3173 if (is_known_lon(idx)) then
3174 known_lon = source_known_lon(idx)
3177 call mprintf(.true., ERROR, &
3178 'In GEOGRID.TBL, no specification for known_lon in entry %i.',i1=idx)
3180 if (is_truelat1(idx)) then
3181 truelat1 = source_truelat1(idx)
3182 else if (is_proj(idx) .and. source_proj(idx) /= PROJ_LATLON) then
3184 call mprintf(.true., WARN, &
3185 'In GEOGRID.TBL, no specification for truelat1 in entry %i.',i1=idx)
3187 if (is_truelat2(idx)) then
3188 truelat2 = source_truelat2(idx)
3189 else if (is_proj(idx) .and. source_proj(idx) /= PROJ_LATLON) then
3191 call mprintf(.true., WARN, &
3192 'In GEOGRID.TBL, no specification for truelat2 in entry %i.',i1=idx)
3194 if (is_stdlon(idx)) then
3195 stand_lon = source_stdlon(idx)
3196 else if (is_proj(idx) .and. source_proj(idx) /= PROJ_LATLON) then
3198 call mprintf(.true., WARN, &
3199 'In GEOGRID.TBL, no specification for stdlon in entry %i.',i1=idx)
3201 if (is_dx(idx)) then
3202 dxkm = source_dx(idx)
3205 call mprintf(.true., ERROR, &
3206 'In GEOGRID.TBL, no specification for dx in entry %i.',i1=idx)
3208 if (is_dy(idx)) then
3209 dykm = source_dy(idx)
3212 call mprintf(.true., ERROR, &
3213 'In GEOGRID.TBL, no specification for dy in entry %i.',i1=idx)
3220 end subroutine get_data_projection
3222 subroutine get_geotiff_filename(field_name,ilevel,file_name,istatus)
3224 character(len=*),intent(in)::field_name
3225 integer,intent(in)::ilevel
3226 character(len=*),intent(out)::file_name
3227 integer,intent(out)::istatus
3230 do idx=1,num_entries
3231 if ((index(source_fieldname(idx),trim(field_name)) /= 0) .and. &
3232 (len_trim(source_fieldname(idx)) == len_trim(field_name))) then
3233 if (ilevel == source_priority(idx)) then
3234 if (is_geotiff(idx)) then
3235 file_name=trim(source_geotiff_file(idx))
3242 end subroutine get_geotiff_filename
3244 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3245 ! Name: check_data_specification
3247 ! Purpose: To check for obvious errors in the user source data specifications.
3248 ! Returns .true. if specification passes all checks, and .false. otherwise.
3249 ! For failing checks, diagnostic messages are printed.
3250 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3251 function check_data_specification( )
3256 logical :: check_data_specification
3259 integer :: i, j, istatus
3260 integer, pointer, dimension(:) :: priorities
3262 logical :: begin_priority, halt
3263 character (len=128) :: cur_name
3265 check_data_specification = .false.
3267 ! Check that each specification has a name, priority level, and path
3269 if (.not. is_fieldname(i)) then
3270 call mprintf(.true., ERROR, &
3271 'In GEOGRID.TBL, specification %i does not have a name.',i1=i)
3273 if (.not. is_priority(i)) then
3274 call mprintf(.true., ERROR, &
3275 'In GEOGRID.TBL, specification %i does not have a priority.',i1=i)
3277 if (list_length(source_res_path(i)) == 0) then
3278 call mprintf(.true., ERROR, &
3279 'In GEOGRID.TBL, no path (relative or absolute) is specified '// &
3280 'for entry %i.',i1=i)
3284 ! The fill_missing and halt_on_missing options are mutually exclusive
3286 call get_halt_on_missing(source_fieldname(i), halt, istatus)
3287 call get_missing_fill_value(source_fieldname(i), rmissing, istatus)
3288 if (halt .and. (istatus == 0)) then
3289 call mprintf(.true., ERROR, 'In GEOGRID.TBL, the halt_on_missing and fill_missing '// &
3290 'options are mutually exclusive, but both are given for field %s', &
3291 s1=trim(source_fieldname(i)))
3295 ! Check that the field from which landmask is calculated is not output on a staggering
3297 if (list_length(source_landmask_land(i)) > 0 .or. list_length(source_landmask_water(i)) > 0) then
3298 if (is_output_stagger(i)) then
3299 if (source_output_stagger(i) /= M) then
3300 call mprintf(.true., ERROR, 'In GEOGRID.TBL, landmask cannot be derived from '// &
3301 'a field that is computed on a staggered grid at entry %i.',i1=i)
3307 ! Also check that any field that is to be masked by the landmask is not output on a staggering
3309 if (is_masked(i) .and. is_output_stagger(i)) then
3310 if (source_output_stagger(i) /= M) then
3311 call mprintf(.true., ERROR, 'In GEOGRID.TBL, landmask cannot be used with '// &
3312 'a field that is computed on a staggered grid at entry %i.',i1=i)
3317 allocate(priorities(num_entries))
3319 ! Now check that priorities for each source are unique and in the interval [1,n], n <= num_entries
3322 cur_name = source_fieldname(i)
3324 if (source_fieldname(j) == cur_name) then
3326 if (source_priority(j) > num_entries .or. source_priority(j) < 1) then
3327 call mprintf(.true., ERROR, 'In GEOGRID.TBL, priorities for %s do not '// &
3328 'form a sequence 1,2,...,n.', s1=trim(cur_name))
3331 if (priorities(source_priority(j)) == 1) then
3332 call mprintf(.true., ERROR, 'In GEOGRID.TBL, more than one entry for %s '// &
3333 'has priority %i.', s1=trim(cur_name), i1=source_priority(j))
3336 priorities(source_priority(j)) = 1
3343 begin_priority = .false.
3344 do j=num_entries,1,-1
3345 if (.not.begin_priority .and. priorities(j) == 1) then
3346 begin_priority = .true.
3347 else if (begin_priority .and. priorities(j) == 0) then
3348 call mprintf(.true., ERROR, 'In GEOGRID.TBL, no entry for %s has '// &
3349 'priority %i, but an entry has priority %i.', &
3350 s1=trim(cur_name), i1=j, i2=j+1)
3355 deallocate(priorities)
3357 ! Units must match for all priority levels of a field
3359 if (source_priority(i) == 1) then
3361 if ((source_fieldname(i) == source_fieldname(j)) .and. &
3362 (source_units(i) /= source_units(j))) then
3363 call mprintf(.true., ERROR, 'In GEOGRID.TBL, units for %s at entry %i '// &
3364 'do not match units at entry %i (%s)', &
3365 s1=trim(source_fieldname(i)), i1=j, i2=i, s2=trim(source_units(i)))
3371 ! Make sure that user has not asked to calculate landmask from a continuous field
3373 if (is_dest_fieldtype(i)) then
3374 if (source_dest_fieldtype(i) == CONTINUOUS) then
3375 if (list_length(source_landmask_water(i)) > 0 .or. list_length(source_landmask_land(i)) > 0) then
3376 call mprintf(.true., ERROR, 'In GEOGRID.TBL, landmask cannot be '// &
3377 'calculated from a continuous destination field at entry %i.',i1=i)
3383 ! If either min_category or max_category is specified, then both must be specified
3385 if (is_category_min(i) .or. is_category_max(i)) then
3386 if (.not. is_category_min(i)) then
3387 call mprintf(.true., ERROR, 'In GEOGRID.TBL, for index file of data at '// &
3388 'entry %i, category_max is specified, but category_min is '// &
3389 'not. Both must be specified.',i1=i)
3390 else if (.not. is_category_max(i)) then
3391 call mprintf(.true., ERROR, 'In GEOGRID.TBL, for index file of data at '// &
3392 'entry %i, category_min is specified, but category_max is '// &
3393 'not. Both must be specified.',i1=i)
3398 ! For continuous data, (category_max - category_min + 1) should equal tile_z
3400 if (is_fieldtype(i)) then
3401 if (source_fieldtype(i) == CONTINUOUS) then
3402 if (is_category_max(i) .and. is_category_min(i) .and. is_tile_z(i)) then
3403 if (source_tile_z(i) /= (source_category_max(i) - source_category_min(i) + 1)) then
3404 call mprintf(.true., ERROR, 'In GEOGRID.TBL, tile_z must equal '// &
3405 '(category_max - category_min + 1) at entry %i.',i1=i)
3407 else if (is_category_max(i) .and. is_category_min(i) .and. &
3408 is_tile_z_start(i) .and. is_tile_z_end(i)) then
3409 if (source_tile_z_end(i) /= source_category_max(i) .or. &
3410 source_tile_z_start(i) /= source_category_min(i)) then
3411 call mprintf(.true., ERROR, 'In GEOGRID.TBL, tile_z_end must equal '// &
3412 'category_max, and tile_z_start must equal category_min '// &
3413 'at entry %i.',i1=i)
3420 ! Make sure that user has not named a dominant category or computed slope field
3421 ! the same as a fractional field
3423 if (source_dominant_category(i) == source_fieldname(i)) then
3424 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category cannot have '// &
3425 'the same name as the field at entry %i.',i1=i)
3429 if (.not. is_dominant_only(i)) then
3430 if (is_dfdx(j)) then
3431 if (source_dfdx(j) == source_fieldname(i)) then
3432 call mprintf(.true., ERROR, 'In GEOGRID.TBL, field name at entry %i '// &
3433 'cannot have the same name as the slope field df_dx at entry %i.', &
3437 if (is_dfdy(j)) then
3438 if (source_dfdy(j) == source_fieldname(i)) then
3439 call mprintf(.true., ERROR, 'In GEOGRID.TBL, field name at entry %i '// &
3440 'cannot have the same name as the slope field df_dy at entry %i.', &
3444 if (is_dfdx(j) .and. is_dominant_category(i)) then
3445 if (source_dfdx(j) == source_dominant_category(i)) then
3446 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
3447 'entry %i cannot have the same name as the slope field df_dx '// &
3448 'at entry %i.',i1=i, i2=j)
3451 if (is_dfdy(j) .and. is_dominant_category(i)) then
3452 if (source_dfdy(j) == source_dominant_category(i)) then
3453 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
3454 'entry %i cannot have the same name as the slope field '// &
3455 'df_dy at entry %i.',i1=i, i2=j)
3459 if (is_dfdx(j)) then
3460 if (source_dfdx(j) == source_dominant_only(i)) then
3461 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
3462 'entry %i cannot have the same name as the slope field '// &
3463 'df_dx at entry %i.',i1=i, i2=j)
3466 if (is_dfdy(j)) then
3467 if (source_dfdy(j) == source_dominant_only(i)) then
3468 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
3469 'entry %i cannot have the same name as the slope field '// &
3470 'df_dy at entry %i.',i1=i, i2=j)
3475 if (is_dfdx(i)) then
3476 if (is_dfdx(j)) then
3477 if (source_dfdx(j) == source_dfdx(i)) then
3478 call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dx at '// &
3479 'entry %i cannot have the same name as the slope '// &
3480 'field df_dx at entry %i.',i1=i, i2=j)
3483 if (is_dfdy(j)) then
3484 if (source_dfdy(j) == source_dfdx(i)) then
3485 call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dx at '// &
3486 'entry %i cannot have the same name as the slope field '// &
3487 'df_dy at entry %i.',i1=i, i2=j)
3491 if (is_dfdy(i)) then
3492 if (is_dfdx(j)) then
3493 if (source_dfdx(j) == source_dfdy(i)) then
3494 call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dy at '// &
3495 'entry %i cannot have the same name as the slope field '// &
3496 'df_dx at entry %i.',i1=i, i2=j)
3499 if (is_dfdy(j)) then
3500 if (source_dfdy(j) == source_dfdy(i)) then
3501 call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dy at '// &
3502 'entry %i cannot have the same name as the slope field '// &
3503 'df_dy at entry %i.',i1=i, i2=j)
3507 if (is_dominant_category(i)) then
3508 if (source_dominant_category(i) == source_fieldname(j)) then ! Possible exception
3509 if (.not. (is_dominant_only(j) .and. (source_dominant_category(i) /= source_dominant_only(j)))) then
3510 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category at '// &
3511 'entry %i cannot have the same name as the field at '// &
3512 'entry %i.',i1=i, i2=j)
3514 else if (is_dominant_category(j) .and. &
3515 (source_dominant_category(i) == source_dominant_category(j))) then
3516 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category at entry '// &
3517 '%i cannot have the same name as dominant category at '// &
3518 'entry %i.',i1=i, i2=j)
3519 else if (is_dominant_only(j) .and. &
3520 (source_dominant_category(i) == source_dominant_only(j))) then
3521 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category at '// &
3522 'entry %i cannot have the same name as dominant_only '// &
3523 'category at entry %i.',i1=i, i2=j)
3525 else if (is_dominant_only(i)) then
3526 if (source_dominant_only(i) == source_fieldname(j)) then ! Possible exception
3527 if (.not. (is_dominant_only(j) .and. (source_dominant_only(i) /= source_dominant_only(j)))) then
3528 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant_only category '// &
3529 'at entry %i cannot have the same name as the field at '// &
3530 'entry %i.',i1=i, i2=j)
3532 else if (is_dominant_category(j) .and. &
3533 (source_dominant_only(i) == source_dominant_category(j))) then
3534 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant_only category '// &
3535 'at entry %i cannot have the same name as dominant '// &
3536 'category at entry %i.',i1=i, i2=j)
3537 else if (is_dominant_only(j) .and. &
3538 (source_dominant_only(i) == source_dominant_only(j))) then
3539 call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant_only category '// &
3540 'at entry %i cannot have the same name as dominant_only '// &
3541 'category at entry %i.',i1=i, i2=j)
3548 check_data_specification = .true.
3549 end function check_data_specification
3552 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3555 ! Purpose: This routine receives a fortran string, and returns the number of
3556 ! characters in the string before the first "space" is encountered. It
3557 ! considers ascii characters 33 to 126 to be valid characters, and ascii
3558 ! 0 to 32, and 127 to be "space" characters.
3559 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3560 subroutine s_len(string, s_length)
3565 character (len=*), intent(in) :: string
3566 integer, intent(out) :: s_length
3569 integer :: i, len_str, aval
3574 len_str = len(string)
3576 do while ((i .le. len_str) .and. (.not. space))
3577 aval = ichar(string(i:i))
3578 if ((aval .lt. 33) .or. (aval .gt. 126)) then
3585 end subroutine s_len
3587 end module source_data_module