PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/WPS/geogrid/src/source_data_module.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 3622 lines | 2434 code | 531 blank | 657 comment | 712 complexity | 3a35ef6a6616356155eb80c46f76cdc4 MD5 | raw file
Possible License(s): AGPL-1.0
  1. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2. ! Module: source_data_module
  3. !
  4. ! Description:
  5. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  6. module source_data_module
  7. use hash_module
  8. use list_module
  9. use module_debug
  10. use misc_definitions_module
  11. ! Parameters
  12. integer, parameter :: RETURN_LANDMASK = 0, &
  13. RETURN_DOMCAT_LM = 1, &
  14. RETURN_DFDX_LM = 2, &
  15. RETURN_DFDY_LM = 3, &
  16. RETURN_FIELDNAME = 4, &
  17. RETURN_DOMCAT = 5, &
  18. RETURN_DFDX = 6, &
  19. RETURN_DFDY = 7
  20. integer, parameter :: MAX_LANDMASK_CATEGORIES = 100
  21. ! Module variables
  22. integer :: num_entries
  23. integer :: next_field = 1
  24. integer :: output_field_state = RETURN_LANDMASK
  25. integer, pointer, dimension(:) :: source_proj, source_wordsize, source_endian, source_fieldtype, &
  26. source_dest_fieldtype, source_priority, source_tile_x, source_tile_y, &
  27. source_tile_z, source_tile_z_start, source_tile_z_end, source_tile_bdr, &
  28. source_category_min, source_category_max, source_smooth_option, &
  29. source_smooth_passes, source_output_stagger, source_row_order
  30. integer :: source_iswater, source_islake, source_isice, source_isurban, source_isoilwater
  31. real, pointer, dimension(:) :: source_dx, source_dy, source_known_x, source_known_y, &
  32. source_known_lat, source_known_lon, source_masked, source_truelat1, source_truelat2, &
  33. source_stdlon, source_scale_factor, source_missing_value, source_fill_missing
  34. character (len=128), pointer, dimension(:) :: source_fieldname, source_path, source_interp_string, &
  35. source_dominant_category, source_dominant_only, source_dfdx, source_dfdy, &
  36. source_z_dim_name, source_units, source_descr, source_geotiff_file
  37. character (len=128) :: source_mminlu
  38. logical, pointer, dimension(:) :: is_proj, is_wordsize, is_endian, is_fieldtype, &
  39. is_dest_fieldtype, is_priority, is_tile_x, is_tile_y, is_tile_z, &
  40. is_tile_z_start, is_tile_z_end, is_tile_bdr, is_category_min, &
  41. is_category_max, is_masked, &
  42. is_dx, is_dy, is_known_x, is_known_y, &
  43. is_known_lat, is_known_lon, is_truelat1, is_truelat2, is_stdlon, &
  44. is_scale_factor, is_fieldname, is_path, is_dominant_category, &
  45. is_dominant_only, is_dfdx, is_dfdy, is_z_dim_name, &
  46. is_smooth_option, is_smooth_passes, is_signed, is_missing_value, &
  47. is_fill_missing, is_halt_missing, is_output_stagger, is_row_order, &
  48. is_units, is_descr, is_subgrid, is_geotiff
  49. type (list), pointer, dimension(:) :: source_res_path, source_interp_option, source_landmask_land, &
  50. source_landmask_water
  51. type (hashtable) :: bad_files ! Track which files produce errors when we try to open them
  52. type (hashtable) :: duplicate_fnames ! Remember which output fields we have returned
  53. contains
  54. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  55. ! Name: get_datalist
  56. !
  57. ! Purpose:
  58. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  59. subroutine get_datalist()
  60. use gridinfo_module
  61. use stringutil
  62. implicit none
  63. ! Parameters
  64. integer, parameter :: BUFSIZE = 256
  65. ! Local variables
  66. integer :: nparams, idx, eos, ispace, comma, i, j, funit
  67. logical :: have_specification, is_used
  68. character (len=128) :: res_string, path_string, interp_string, landmask_string
  69. character (len=BUFSIZE) :: buffer
  70. nparams = 0
  71. num_entries = 0
  72. do funit=10,100
  73. inquire(unit=funit, opened=is_used)
  74. if (.not. is_used) exit
  75. end do
  76. open(funit,file=trim(opt_geogrid_tbl_path)//'GEOGRID.TBL',form='formatted',status='old',err=1000)
  77. !
  78. ! We will first go through the file to determine how many field
  79. ! specifications there are
  80. !
  81. 10 read(funit,'(a)',end=20,err=1001) buffer
  82. call despace(buffer)
  83. ! Is this line a comment?
  84. if (buffer(1:1) == '#') then
  85. ! Are we beginning a new field specification?
  86. else if (index(buffer,'=====') /= 0) then
  87. if (nparams > 0) num_entries = num_entries + 1
  88. nparams = 0
  89. else
  90. eos = index(buffer,'#')
  91. if (eos /= 0) buffer(eos:BUFSIZE) = ' '
  92. ! Does this line contain at least one parameter specification?
  93. if (index(buffer,'=') /= 0) then
  94. nparams = nparams + 1
  95. end if
  96. end if
  97. go to 10
  98. 20 rewind(funit)
  99. ! In case the last entry ended without a ======== line
  100. if (nparams > 0) num_entries = num_entries + 1
  101. call mprintf(.true.,STDOUT,'Parsed %i entries in GEOGRID.TBL', i1=num_entries)
  102. !
  103. ! Now that we know how many fields the user has specified, allocate
  104. ! the properly sized arrays
  105. !
  106. allocate(source_wordsize(num_entries))
  107. allocate(source_endian(num_entries))
  108. allocate(source_fieldtype(num_entries))
  109. allocate(source_dest_fieldtype(num_entries))
  110. allocate(source_proj(num_entries))
  111. allocate(source_priority(num_entries))
  112. allocate(source_dx(num_entries))
  113. allocate(source_dy(num_entries))
  114. allocate(source_known_x(num_entries))
  115. allocate(source_known_y(num_entries))
  116. allocate(source_known_lat(num_entries))
  117. allocate(source_known_lon(num_entries))
  118. allocate(source_truelat1(num_entries))
  119. allocate(source_truelat2(num_entries))
  120. allocate(source_stdlon(num_entries))
  121. allocate(source_fieldname(num_entries))
  122. allocate(source_path(num_entries))
  123. allocate(source_interp_string(num_entries))
  124. allocate(source_tile_x(num_entries))
  125. allocate(source_tile_y(num_entries))
  126. allocate(source_tile_z(num_entries))
  127. allocate(source_tile_z_start(num_entries))
  128. allocate(source_tile_z_end(num_entries))
  129. allocate(source_category_min(num_entries))
  130. allocate(source_category_max(num_entries))
  131. allocate(source_tile_bdr(num_entries))
  132. allocate(source_masked(num_entries))
  133. allocate(source_output_stagger(num_entries))
  134. allocate(source_row_order(num_entries))
  135. allocate(source_dominant_category(num_entries))
  136. allocate(source_dominant_only(num_entries))
  137. allocate(source_dfdx(num_entries))
  138. allocate(source_dfdy(num_entries))
  139. allocate(source_scale_factor(num_entries))
  140. allocate(source_z_dim_name(num_entries))
  141. allocate(source_units(num_entries))
  142. allocate(source_descr(num_entries))
  143. allocate(source_smooth_option(num_entries))
  144. allocate(source_smooth_passes(num_entries))
  145. allocate(source_missing_value(num_entries))
  146. allocate(source_fill_missing(num_entries))
  147. allocate(source_res_path(num_entries))
  148. allocate(source_interp_option(num_entries))
  149. allocate(source_landmask_land(num_entries))
  150. allocate(source_landmask_water(num_entries))
  151. allocate(source_geotiff_file(num_entries))
  152. do i=1,num_entries
  153. call list_init(source_res_path(i))
  154. call list_init(source_interp_option(i))
  155. call list_init(source_landmask_land(i))
  156. call list_init(source_landmask_water(i))
  157. end do
  158. allocate(is_wordsize(num_entries))
  159. allocate(is_endian(num_entries))
  160. allocate(is_fieldtype(num_entries))
  161. allocate(is_dest_fieldtype(num_entries))
  162. allocate(is_proj(num_entries))
  163. allocate(is_priority(num_entries))
  164. allocate(is_dx(num_entries))
  165. allocate(is_dy(num_entries))
  166. allocate(is_known_x(num_entries))
  167. allocate(is_known_y(num_entries))
  168. allocate(is_known_lat(num_entries))
  169. allocate(is_known_lon(num_entries))
  170. allocate(is_truelat1(num_entries))
  171. allocate(is_truelat2(num_entries))
  172. allocate(is_stdlon(num_entries))
  173. allocate(is_fieldname(num_entries))
  174. allocate(is_path(num_entries))
  175. allocate(is_tile_x(num_entries))
  176. allocate(is_tile_y(num_entries))
  177. allocate(is_tile_z(num_entries))
  178. allocate(is_tile_z_start(num_entries))
  179. allocate(is_tile_z_end(num_entries))
  180. allocate(is_category_min(num_entries))
  181. allocate(is_category_max(num_entries))
  182. allocate(is_tile_bdr(num_entries))
  183. allocate(is_masked(num_entries))
  184. allocate(is_halt_missing(num_entries))
  185. allocate(is_output_stagger(num_entries))
  186. allocate(is_row_order(num_entries))
  187. allocate(is_dominant_category(num_entries))
  188. allocate(is_dominant_only(num_entries))
  189. allocate(is_dfdx(num_entries))
  190. allocate(is_dfdy(num_entries))
  191. allocate(is_scale_factor(num_entries))
  192. allocate(is_z_dim_name(num_entries))
  193. allocate(is_units(num_entries))
  194. allocate(is_descr(num_entries))
  195. allocate(is_smooth_option(num_entries))
  196. allocate(is_smooth_passes(num_entries))
  197. allocate(is_signed(num_entries))
  198. allocate(is_missing_value(num_entries))
  199. allocate(is_fill_missing(num_entries))
  200. allocate(is_subgrid(num_entries))
  201. allocate(is_geotiff(num_entries))
  202. source_wordsize=0
  203. source_endian=0
  204. source_fieldtype=0
  205. source_dest_fieldtype=0
  206. source_proj=0
  207. source_priority=0
  208. source_dx=0
  209. source_dy=0
  210. source_known_x=0
  211. source_known_y=0
  212. source_known_lat=0
  213. source_known_lon=0
  214. source_truelat1=0
  215. source_truelat2=0
  216. source_stdlon=0
  217. source_fieldname=' '
  218. source_path=' '
  219. source_interp_string=' '
  220. source_tile_x=0
  221. source_tile_y=0
  222. source_tile_z=0
  223. source_tile_z_start=0
  224. source_tile_z_end=0
  225. source_category_min=0
  226. source_category_max=0
  227. source_tile_bdr=0
  228. source_masked=0
  229. source_output_stagger=0
  230. source_row_order=0
  231. source_dominant_category=' '
  232. source_dominant_only=' '
  233. source_dfdx=' '
  234. source_dfdy=' '
  235. source_scale_factor=0
  236. source_z_dim_name=' '
  237. source_units=' '
  238. source_descr=' '
  239. source_smooth_option=0
  240. source_smooth_passes=0
  241. source_missing_value=0
  242. source_fill_missing=0
  243. is_wordsize=.false.
  244. is_endian=.false.
  245. is_fieldtype=.false.
  246. is_dest_fieldtype=.false.
  247. is_proj=.false.
  248. is_priority=.false.
  249. is_dx=.false.
  250. is_dy=.false.
  251. is_known_x=.false.
  252. is_known_y=.false.
  253. is_known_lat=.false.
  254. is_known_lon=.false.
  255. is_truelat1=.false.
  256. is_truelat2=.false.
  257. is_stdlon=.false.
  258. is_fieldname=.false.
  259. is_path=.false.
  260. is_tile_x=.false.
  261. is_tile_y=.false.
  262. is_tile_z=.false.
  263. is_tile_z_start=.false.
  264. is_tile_z_end=.false.
  265. is_category_min=.false.
  266. is_category_max=.false.
  267. is_tile_bdr=.false.
  268. is_masked=.false.
  269. is_halt_missing=.false.
  270. is_output_stagger=.false.
  271. is_row_order=.false.
  272. is_dominant_category=.false.
  273. is_dominant_only=.false.
  274. is_dfdx=.false.
  275. is_dfdy=.false.
  276. is_scale_factor=.false.
  277. is_z_dim_name=.false.
  278. is_units=.false.
  279. is_descr=.false.
  280. is_smooth_option=.false.
  281. is_smooth_passes=.false.
  282. is_signed=.false.
  283. is_missing_value=.false.
  284. is_fill_missing=.false.
  285. is_subgrid=.false.
  286. write(source_mminlu,'(a4)') 'USGS'
  287. source_iswater = 16
  288. source_islake = -1
  289. source_isice = 24
  290. source_isurban = 1
  291. source_isoilwater = 14
  292. !
  293. ! Actually read and save the specifications
  294. !
  295. nparams = 0
  296. i = 1
  297. 30 buffer = ' '
  298. read(funit,'(a)',end=40,err=1001) buffer
  299. call despace(buffer)
  300. ! Is this line a comment?
  301. if (buffer(1:1) == '#') then
  302. ! Do nothing.
  303. ! Are we beginning a new field specification?
  304. else if (index(buffer,'=====') /= 0) then !{
  305. if (nparams > 0) i = i + 1
  306. nparams = 0
  307. if (i <= num_entries) then
  308. !BUG: Are these initializations needed now that we've added initializations for
  309. ! all options after their initial allocation above?
  310. is_path(i) = .false.
  311. is_masked(i) = .false.
  312. is_halt_missing(i) = .false.
  313. is_output_stagger(i) = .false.
  314. is_dominant_category(i) = .false.
  315. is_dominant_only(i) = .false.
  316. is_dfdx(i) = .false.
  317. is_dfdy(i) = .false.
  318. is_dest_fieldtype(i) = .false.
  319. is_priority(i) = .false.
  320. is_z_dim_name(i) = .false.
  321. is_smooth_option(i) = .false.
  322. is_smooth_passes(i) = .false.
  323. is_fill_missing(i) = .false.
  324. is_subgrid(i) = .false.
  325. end if
  326. else
  327. ! Check whether the current line is a comment
  328. if (buffer(1:1) /= '#') then
  329. have_specification = .true.
  330. else
  331. have_specification = .false.
  332. end if
  333. ! If only part of the line is a comment, just turn the comment into spaces
  334. eos = index(buffer,'#')
  335. if (eos /= 0) buffer(eos:BUFSIZE) = ' '
  336. do while (have_specification) !{
  337. ! If this line has no semicolon, it may contain a single specification,
  338. ! so we set have_specification = .false. to prevent the line from being
  339. ! processed again and "pretend" that the last character was a semicolon
  340. eos = index(buffer,';')
  341. if (eos == 0) then
  342. have_specification = .false.
  343. eos = BUFSIZE
  344. end if
  345. idx = index(buffer(1:eos-1),'=')
  346. if (idx /= 0) then !{
  347. nparams = nparams + 1
  348. if (index('name',trim(buffer(1:idx-1))) /= 0) then
  349. ispace = idx+1
  350. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  351. ispace = ispace + 1
  352. end do
  353. is_fieldname(i) = .true.
  354. source_fieldname(i) = ' '
  355. source_fieldname(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
  356. else if (index('priority',trim(buffer(1:idx-1))) /= 0) then
  357. is_priority(i) = .true.
  358. read(buffer(idx+1:eos-1),'(i10)') source_priority(i)
  359. else if (index('dest_type',trim(buffer(1:idx-1))) /= 0) then
  360. if (index('continuous',trim(buffer(idx+1:eos-1))) /= 0) then
  361. is_dest_fieldtype(i) = .true.
  362. source_dest_fieldtype(i) = CONTINUOUS
  363. else if (index('categorical',trim(buffer(idx+1:eos-1))) /= 0) then
  364. is_dest_fieldtype(i) = .true.
  365. source_dest_fieldtype(i) = CATEGORICAL
  366. end if
  367. else if (index('interp_option',trim(buffer(1:idx-1))) /= 0) then
  368. ispace = idx+1
  369. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  370. ispace = ispace + 1
  371. end do
  372. interp_string = ' '
  373. interp_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
  374. ispace = index(interp_string,':')
  375. if (ispace /= 0) then
  376. write(res_string,'(a)') interp_string(1:ispace-1)
  377. else
  378. res_string = 'default'
  379. end if
  380. write(interp_string,'(a)') trim(interp_string(ispace+1:128))
  381. if (list_search(source_interp_option(i), ckey=res_string, cvalue=interp_string)) then
  382. call mprintf(.true., WARN, &
  383. 'In GEOGRID.TBL entry %i, multiple interpolation methods are '// &
  384. 'given for resolution %s. %s will be used.', &
  385. i1=i, s1=trim(res_string), s2=trim(interp_string))
  386. else
  387. call list_insert(source_interp_option(i), ckey=res_string, cvalue=interp_string)
  388. end if
  389. else if (index('smooth_option',trim(buffer(1:idx-1))) /= 0) then
  390. if ((index('1-2-1',trim(buffer(idx+1:eos-1))) /= 0) .and. &
  391. (len_trim(buffer(idx+1:eos-1)) == len('1-2-1'))) then
  392. is_smooth_option(i) = .true.
  393. source_smooth_option(i) = ONETWOONE
  394. else if ((index('smth-desmth',trim(buffer(idx+1:eos-1))) /= 0) .and. &
  395. (len_trim(buffer(idx+1:eos-1)) == len('smth-desmth'))) then
  396. is_smooth_option(i) = .true.
  397. source_smooth_option(i) = SMTHDESMTH
  398. else if ((index('smth-desmth_special',trim(buffer(idx+1:eos-1))) /= 0) .and. &
  399. (len_trim(buffer(idx+1:eos-1)) == len('smth-desmth_special'))) then
  400. is_smooth_option(i) = .true.
  401. source_smooth_option(i) = SMTHDESMTH_SPECIAL
  402. end if
  403. else if (index('smooth_passes',trim(buffer(1:idx-1))) /= 0) then
  404. is_smooth_passes(i) = .true.
  405. read(buffer(idx+1:eos-1),'(i10)') source_smooth_passes(i)
  406. else if (index('rel_path',trim(buffer(1:idx-1))) /= 0) then
  407. ispace = idx+1
  408. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  409. ispace = ispace + 1
  410. end do
  411. path_string = ' '
  412. path_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
  413. if (path_string(ispace-idx-1:ispace-idx-1) /= '/') &
  414. path_string(ispace-idx:ispace-idx) = '/'
  415. if (path_string(1:1) == '/') then
  416. path_string(1:127) = path_string(2:128)
  417. path_string(128:128) = ' '
  418. end if
  419. ispace = index(path_string,':')
  420. if (ispace /= 0) then
  421. write(res_string,'(a)') path_string(1:ispace-1)
  422. else
  423. res_string = 'default'
  424. end if
  425. write(path_string,'(a)') trim(geog_data_path)//trim(path_string(ispace+1:128))
  426. if (list_search(source_res_path(i), ckey=res_string, cvalue=path_string)) then
  427. call mprintf(.true., WARN, &
  428. 'In GEOGRID.TBL entry %i, multiple paths are given for '// &
  429. 'resolution %s. %s will be used.', &
  430. i1=i, s1=trim(res_string), s2=trim(path_string))
  431. else
  432. call list_insert(source_res_path(i), ckey=res_string, cvalue=path_string)
  433. end if
  434. else if (index('abs_path',trim(buffer(1:idx-1))) /= 0) then
  435. ispace = idx+1
  436. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  437. ispace = ispace + 1
  438. end do
  439. path_string = ' '
  440. path_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
  441. if (path_string(ispace-idx-1:ispace-idx-1) /= '/') &
  442. path_string(ispace-idx:ispace-idx) = '/'
  443. ispace = index(path_string,':')
  444. if (ispace /= 0) then
  445. write(res_string,'(a)') path_string(1:ispace-1)
  446. else
  447. res_string = 'default'
  448. end if
  449. write(path_string,'(a)') trim(path_string(ispace+1:128))
  450. if (list_search(source_res_path(i), ckey=res_string, cvalue=path_string)) then
  451. call mprintf(.true., WARN, &
  452. 'In GEOGRID.TBL entry %i, multiple paths are given for '// &
  453. 'resolution %s. %s will be used.', &
  454. i1=i, s1=trim(res_string), s2=trim(path_string))
  455. else
  456. call list_insert(source_res_path(i), ckey=res_string, cvalue=path_string)
  457. end if
  458. else if (index('output_stagger',trim(buffer(1:idx-1))) /= 0) then
  459. if (index('M',trim(buffer(idx+1:eos-1))) /= 0) then
  460. is_output_stagger(i) = .true.
  461. source_output_stagger(i) = M
  462. else if (index('U',trim(buffer(idx+1:eos-1))) /= 0) then
  463. is_output_stagger(i) = .true.
  464. source_output_stagger(i) = U
  465. else if (index('V',trim(buffer(idx+1:eos-1))) /= 0) then
  466. is_output_stagger(i) = .true.
  467. source_output_stagger(i) = V
  468. else if (index('HH',trim(buffer(idx+1:eos-1))) /= 0) then
  469. is_output_stagger(i) = .true.
  470. source_output_stagger(i) = HH
  471. else if (index('VV',trim(buffer(idx+1:eos-1))) /= 0) then
  472. is_output_stagger(i) = .true.
  473. source_output_stagger(i) = VV
  474. end if
  475. else if ((index('landmask_water',trim(buffer(1:idx-1))) /= 0) .and. &
  476. (len_trim(buffer(1:idx-1)) == 14)) then
  477. ispace = idx+1
  478. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  479. ispace = ispace + 1
  480. end do
  481. landmask_string = ' '
  482. landmask_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
  483. ispace = index(landmask_string,':')
  484. if (ispace /= 0) then
  485. write(res_string,'(a)') landmask_string(1:ispace-1)
  486. else
  487. res_string = 'default'
  488. end if
  489. write(landmask_string,'(a)') trim(landmask_string(ispace+1:128))
  490. if (list_search(source_landmask_water(i), ckey=res_string, cvalue=landmask_string)) then
  491. call mprintf(.true., WARN, &
  492. 'In GEOGRID.TBL entry %i, multiple landmask category specifications are given for '// &
  493. 'resolution %s. %s will be used.', &
  494. i1=i, s1=trim(res_string), s2=trim(landmask_string))
  495. else
  496. call list_insert(source_landmask_water(i), ckey=res_string, cvalue=landmask_string)
  497. end if
  498. else if ((index('landmask_land',trim(buffer(1:idx-1))) /= 0) .and. &
  499. (len_trim(buffer(1:idx-1)) == 13)) then
  500. ispace = idx+1
  501. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  502. ispace = ispace + 1
  503. end do
  504. landmask_string = ' '
  505. landmask_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
  506. ispace = index(landmask_string,':')
  507. if (ispace /= 0) then
  508. write(res_string,'(a)') landmask_string(1:ispace-1)
  509. else
  510. res_string = 'default'
  511. end if
  512. write(landmask_string,'(a)') trim(landmask_string(ispace+1:128))
  513. if (list_search(source_landmask_land(i), ckey=res_string, cvalue=landmask_string)) then
  514. call mprintf(.true., WARN, &
  515. 'In GEOGRID.TBL entry %i, multiple landmask category specifications are given for '// &
  516. 'resolution %s. %s will be used.', &
  517. i1=i, s1=trim(res_string), s2=trim(landmask_string))
  518. else
  519. call list_insert(source_landmask_land(i), ckey=res_string, cvalue=landmask_string)
  520. end if
  521. else if ((index('masked',trim(buffer(1:idx-1))) /= 0) .and. &
  522. (len_trim(buffer(1:idx-1)) == 6)) then
  523. if (index('water',trim(buffer(idx+1:eos-1))) /= 0) then
  524. is_masked(i) = .true.
  525. source_masked(i) = 0.
  526. else if (index('land',trim(buffer(idx+1:eos-1))) /= 0) then
  527. is_masked(i) = .true.
  528. source_masked(i) = 1.
  529. end if
  530. else if (index('fill_missing',trim(buffer(1:idx-1))) /= 0) then
  531. is_fill_missing(i) = .true.
  532. read(buffer(idx+1:eos-1),*) source_fill_missing(i)
  533. else if (index('halt_on_missing',trim(buffer(1:idx-1))) /= 0) then
  534. if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
  535. is_halt_missing(i) = .true.
  536. else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
  537. is_halt_missing(i) = .false.
  538. end if
  539. else if (index('dominant_category',trim(buffer(1:idx-1))) /= 0) then
  540. ispace = idx+1
  541. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  542. ispace = ispace + 1
  543. end do
  544. is_dominant_category(i) = .true.
  545. source_dominant_category(i) = ' '
  546. source_dominant_category(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
  547. else if (index('dominant_only',trim(buffer(1:idx-1))) /= 0) then
  548. ispace = idx+1
  549. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  550. ispace = ispace + 1
  551. end do
  552. is_dominant_only(i) = .true.
  553. source_dominant_only(i) = ' '
  554. source_dominant_only(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
  555. else if (index('df_dx',trim(buffer(1:idx-1))) /= 0) then
  556. ispace = idx+1
  557. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  558. ispace = ispace + 1
  559. end do
  560. is_dfdx(i) = .true.
  561. source_dfdx(i) = ' '
  562. source_dfdx(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
  563. else if (index('df_dy',trim(buffer(1:idx-1))) /= 0) then
  564. ispace = idx+1
  565. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  566. ispace = ispace + 1
  567. end do
  568. is_dfdy(i) = .true.
  569. source_dfdy(i) = ' '
  570. source_dfdy(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
  571. else if (index('z_dim_name',trim(buffer(1:idx-1))) /= 0) then
  572. ispace = idx+1
  573. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  574. ispace = ispace + 1
  575. end do
  576. is_z_dim_name(i) = .true.
  577. source_z_dim_name(i) = ' '
  578. source_z_dim_name(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
  579. else if (index('subgrid',trim(buffer(1:idx-1))) /= 0) then
  580. ispace = idx+1
  581. do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
  582. ispace = ispace + 1
  583. end do
  584. if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
  585. is_subgrid(i) = .true.
  586. else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
  587. is_subgrid(i) = .false.
  588. end if
  589. else
  590. call mprintf(.true., WARN, 'In GEOGRID.TBL, unrecognized option %s in '// &
  591. 'entry %i.',i1=idx, s1=buffer(i:idx-1))
  592. end if
  593. end if !} index(buffer(1:eos-1),'=') /= 0
  594. buffer = buffer(eos+1:BUFSIZE)
  595. end do ! while eos /= 0 }
  596. end if !} index(buffer, '=====') /= 0
  597. go to 30
  598. 40 close(funit)
  599. ! Check the user specifications for gross errors
  600. if ( .not. check_data_specification() ) then
  601. call datalist_destroy()
  602. call mprintf(.true.,ERROR,'Errors were found in either index files or GEOGRID.TBL.')
  603. end if
  604. call hash_init(bad_files)
  605. return
  606. 1000 call mprintf(.true.,ERROR,'Could not open GEOGRID.TBL')
  607. 1001 call mprintf(.true.,ERROR,'Encountered error while reading GEOGRID.TBL')
  608. end subroutine get_datalist
  609. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  610. ! Name: get_source_params
  611. !
  612. ! Purpose: For each field, this routine reads in the metadata in the index file
  613. ! for the first available resolution of data specified by res_string. Also
  614. ! based on res_string, this routine sets the interpolation sequence for the
  615. ! field. This routine should be called prior to processing a field for each
  616. ! domain.
  617. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  618. subroutine get_source_params(res_string)
  619. use stringutil
  620. #ifdef _HAS_GEOTIFF
  621. use geotiff_module, only : open_geotiff,merge_geotiff_header
  622. #endif
  623. implicit none
  624. ! Parameters
  625. integer, parameter :: BUFSIZE = 256
  626. ! Arguments
  627. character (len=128), intent(in) :: res_string
  628. ! Local variables
  629. integer :: idx, i, is, ie, ispace, eos, iquoted, funit
  630. character (len=128) :: temp_data, temp_interp
  631. character (len=256) :: test_fname
  632. character (len=BUFSIZE) :: buffer
  633. logical :: have_specification, is_used
  634. ! For each entry in the GEOGRID.TBL file
  635. do idx=1,num_entries
  636. ! Initialize metadata
  637. is_wordsize(idx) = .false.
  638. is_endian(idx) = .false.
  639. is_row_order(idx) = .false.
  640. is_fieldtype(idx) = .false.
  641. is_proj(idx) = .false.
  642. is_dx(idx) = .false.
  643. is_dy(idx) = .false.
  644. is_known_x(idx) = .false.
  645. is_known_y(idx) = .false.
  646. is_known_lat(idx) = .false.
  647. is_known_lon(idx) = .false.
  648. is_truelat1(idx) = .false.
  649. is_truelat2(idx) = .false.
  650. is_stdlon(idx) = .false.
  651. is_tile_x(idx) = .false.
  652. is_tile_y(idx) = .false.
  653. is_tile_z(idx) = .false.
  654. is_tile_z_start(idx) = .false.
  655. is_tile_z_end(idx) = .false.
  656. is_category_min(idx) = .false.
  657. is_category_max(idx) = .false.
  658. is_tile_bdr(idx) = .false.
  659. is_fieldname(idx) = .false.
  660. is_scale_factor(idx) = .false.
  661. is_units(idx) = .false.
  662. is_descr(idx) = .false.
  663. is_signed(idx) = .false.
  664. is_missing_value(idx) = .false.
  665. is_geotiff(idx) = .false.
  666. ! Set the interpolator sequence for the field to be the first value in res_string that matches
  667. ! the resolution keyword for an interp_sequence specification
  668. is = 1
  669. ie = index(res_string(is:128),'+') - 1
  670. if (ie <= 0) ie = 128
  671. temp_interp = res_string(is:ie)
  672. do while (.not. list_search(source_interp_option(idx), ckey=temp_interp, cvalue=source_interp_string(idx)) &
  673. .and. is <= 128)
  674. call mprintf(.true., INFORM, 'For %s, couldn''t find interpolator sequence for '// &
  675. 'resolution %s.', &
  676. s1=trim(source_fieldname(idx)), s2=trim(temp_interp))
  677. is = ie+2
  678. ie = is + index(res_string(is:128),'+') - 2
  679. if (ie - is <= 0) ie = 128
  680. temp_interp = res_string(is:ie)
  681. end do
  682. if (is > 128) then
  683. temp_interp = 'default'
  684. if (list_search(source_interp_option(idx), ckey=temp_interp, cvalue=source_interp_string(idx))) then
  685. call mprintf(.true., INFORM, 'Using default interpolator sequence for %s.', &
  686. s1=trim(source_fieldname(idx)))
  687. else
  688. call mprintf(.true., ERROR, 'Could not find interpolator sequence for requested resolution for %s.'// &
  689. ' The sources specified in namelist.wps is not listed in GEOGRID.TBL.', &
  690. s1=trim(source_fieldname(idx)))
  691. end if
  692. else
  693. call mprintf(.true., INFORM, 'Using %s interpolator sequence for %s.', &
  694. s1=temp_interp, s2=trim(source_fieldname(idx)))
  695. end if
  696. ! Set the data source for the field to be the first value in res_string that matches
  697. ! the resolution keyword for an abs_path or rel_path specification
  698. is = 1
  699. ie = index(res_string(is:128),'+') - 1
  700. if (ie <= 0) ie = 128
  701. temp_data = res_string(is:ie)
  702. do while (.not. list_search(source_res_path(idx), ckey=temp_data, cvalue=source_path(idx)) &
  703. .and. is <= 128)
  704. call mprintf(.true., INFORM, 'For %s, couldn''t find %s data source.', &
  705. s1=trim(source_fieldname(idx)), s2=trim(temp_data))
  706. is = ie+2
  707. ie = is + index(res_string(is:128),'+') - 2
  708. if (ie - is <= 0) ie = 128
  709. temp_data = res_string(is:ie)
  710. end do
  711. if (is > 128) then
  712. temp_data = 'default'
  713. if (list_search(source_res_path(idx), ckey=temp_data, cvalue=source_path(idx))) then
  714. call mprintf(.true., INFORM, 'Using default data source for %s.', &
  715. s1=trim(source_fieldname(idx)))
  716. else
  717. call mprintf(.true., ERROR, 'Could not find data resolution for requested resolution for %s. '// &
  718. 'The source specified in namelist.wps is not listed in GEOGRID.TBL.', &
  719. s1=trim(source_fieldname(idx)))
  720. end if
  721. else
  722. call mprintf(.true., INFORM, 'Using %s data source for %s.', &
  723. s1=temp_data, s2=trim(source_fieldname(idx)))
  724. end if
  725. call mprintf(trim(temp_data) /= trim(temp_interp),WARN,'For %s, using %s data source with %s interpolation sequence.', &
  726. s1=source_fieldname(idx), s2=temp_data, s3=temp_interp)
  727. write(test_fname, '(a)') trim(source_path(idx))//'index'
  728. !
  729. ! Open the index file for the data source for this field, and read in metadata specs
  730. !
  731. do funit=10,100
  732. inquire(unit=funit, opened=is_used)
  733. if (.not. is_used) exit
  734. end do
  735. open(funit,file=trim(test_fname),form='formatted',status='old',err=1000)
  736. 30 buffer = ' '
  737. read(funit,'(a)',end=40, err=1001) buffer
  738. call despace(buffer)
  739. ! Is this line a comment?
  740. if (buffer(1:1) == '#') then
  741. ! Do nothing.
  742. else
  743. have_specification = .true.
  744. ! If only part of the line is a comment, just turn the comment into spaces
  745. eos = index(buffer,'#')
  746. if (eos /= 0) buffer(eos:BUFSIZE) = ' '
  747. do while (have_specification) !{
  748. ! If this line has no semicolon, it may contain a single specification,
  749. ! so we set have_specification = .false. to prevent the line from being
  750. ! processed again and pretend that the last character was a semicolon
  751. eos = index(buffer,';')
  752. if (eos == 0) then
  753. have_specification = .false.
  754. eos = BUFSIZE
  755. end if
  756. i = index(buffer(1:eos-1),'=')
  757. if (i /= 0) then !{
  758. if (index('projection',trim(buffer(1:i-1))) /= 0) then
  759. if (index('lambert',trim(buffer(i+1:eos-1))) /= 0) then
  760. is_proj(idx) = .true.
  761. source_proj(idx) = PROJ_LC
  762. else if (index('polar_wgs84',trim(buffer(i+1:eos-1))) /= 0 .and. &
  763. len_trim('polar_wgs84') == len_trim(buffer(i+1:eos-1))) then
  764. is_proj(idx) = .true.
  765. source_proj(idx) = PROJ_PS_WGS84
  766. else if (index('albers_nad83',trim(buffer(i+1:eos-1))) /= 0 .and. &
  767. len_trim('albers_nad83') == len_trim(buffer(i+1:eos-1))) then
  768. is_proj(idx) = .true.
  769. source_proj(idx) = PROJ_ALBERS_NAD83
  770. else if (index('polar',trim(buffer(i+1:eos-1))) /= 0 .and. &
  771. len_trim('polar') == len_trim(buffer(i+1:eos-1))) then
  772. is_proj(idx) = .true.
  773. source_proj(idx) = PROJ_PS
  774. else if (index('mercator',trim(buffer(i+1:eos-1))) /= 0) then
  775. is_proj(idx) = .true.
  776. source_proj(idx) = PROJ_MERC
  777. else if (index('regular_ll',trim(buffer(i+1:eos-1))) /= 0) then
  778. is_proj(idx) = .true.
  779. source_proj(idx) = PROJ_LATLON
  780. end if
  781. else if (index('type',trim(buffer(1:i-1))) /= 0) then
  782. if (index('continuous',trim(buffer(i+1:eos-1))) /= 0) then
  783. is_fieldtype(idx) = .true.
  784. source_fieldtype(idx) = CONTINUOUS
  785. else if (index('categorical',trim(buffer(i+1:eos-1))) /= 0) then
  786. is_fieldtype(idx) = .true.
  787. source_fieldtype(idx) = CATEGORICAL
  788. end if
  789. else if (index('signed',trim(buffer(1:i-1))) /= 0) then
  790. if (index('yes',trim(buffer(i+1:eos-1))) /= 0) then
  791. is_signed(idx) = .true.
  792. else if (index('no',trim(buffer(i+1:eos-1))) /= 0) then
  793. is_signed(idx) = .false.
  794. end if
  795. else if (index('units',trim(buffer(1:i-1))) /= 0) then
  796. ispace = i+1
  797. iquoted = 0
  798. do while (((ispace < eos) .and. (buffer(ispace:ispace) /= ' ')) .or. (iquoted == 1))
  799. if (buffer(ispace:ispace) == '"' .or. buffer(ispace:ispace) == '''') iquoted = mod(iquoted+1,2)
  800. ispace = ispace + 1
  801. end do
  802. is_units(idx) = .true.
  803. source_units(idx) = ' '
  804. if (buffer(i+1:i+1) == '"' .or. buffer(i+1:i+1) == '''') i = i + 1
  805. if (buffer(ispace-1:ispace-1) == '"' .or. buffer(ispace-1:ispace-1) == '''') ispace = ispace - 1
  806. source_units(idx)(1:ispace-i) = buffer(i+1:ispace-1)
  807. else if (index('description',trim(buffer(1:i-1))) /= 0) then
  808. ispace = i+1
  809. iquoted = 0
  810. do while (((ispace < eos) .and. (buffer(ispace:ispace) /= ' ')) .or. (iquoted == 1))
  811. if (buffer(ispace:ispace) == '"' .or. buffer(ispace:ispace) == '''') iquoted = mod(iquoted+1,2)
  812. ispace = ispace + 1
  813. end do
  814. is_descr(idx) = .true.
  815. source_descr(idx) = ' '
  816. if (buffer(i+1:i+1) == '"' .or. buffer(i+1:i+1) == '''') i = i + 1
  817. if (buffer(ispace-1:ispace-1) == '"' .or. buffer(ispace-1:ispace-1) == '''') ispace = ispace - 1
  818. source_descr(idx)(1:ispace-i) = buffer(i+1:ispace-1)
  819. else if (index('mminlu',trim(buffer(1:i-1))) /= 0) then
  820. ispace = i+1
  821. iquoted = 0
  822. do while (((ispace < eos) .and. (buffer(ispace:ispace) /= ' ')) .or. (iquoted == 1))
  823. if (buffer(ispace:ispace) == '"' .or. buffer(ispace:ispace) == '''') iquoted = mod(iquoted+1,2)
  824. ispace = ispace + 1
  825. end do
  826. if (buffer(i+1:i+1) == '"' .or. buffer(i+1:i+1) == '''') i = i + 1
  827. if (buffer(ispace-1:ispace-1) == '"' .or. buffer(ispace-1:ispace-1) == '''') ispace = ispace - 1
  828. source_mminlu(1:ispace-i) = buffer(i+1:ispace-1)
  829. else if (index('iswater',trim(buffer(1:i-1))) /= 0) then
  830. read(buffer(i+1:eos-1),*) source_iswater
  831. else if (index('islake',trim(buffer(1:i-1))) /= 0) then
  832. read(buffer(i+1:eos-1),*) source_islake
  833. else if (index('isice',trim(buffer(1:i-1))) /= 0) then
  834. read(buffer(i+1:eos-1),*) source_isice
  835. else if (index('isurban',trim(buffer(1:i-1))) /= 0) then
  836. read(buffer(i+1:eos-1),*) source_isurban
  837. else if (index('isoilwater',trim(buffer(1:i-1))) /= 0) then
  838. read(buffer(i+1:eos-1),*) source_isoilwater
  839. else if (index('dx',trim(buffer(1:i-1))) /= 0) then
  840. is_dx(idx) = .true.
  841. read(buffer(i+1:eos-1),*) source_dx(idx)
  842. else if (index('dy',trim(buffer(1:i-1))) /= 0) then
  843. is_dy(idx) = .true.
  844. read(buffer(i+1:eos-1),*) source_dy(idx)
  845. else if (index('known_x',trim(buffer(1:i-1))) /= 0) then
  846. is_known_x(idx) = .true.
  847. read(buffer(i+1:eos-1),*) source_known_x(idx)
  848. else if (index('known_y',trim(buffer(1:i-1))) /= 0) then
  849. is_known_y(idx) = .true.
  850. read(buffer(i+1:eos-1),*) source_known_y(idx)
  851. else if (index('known_lat',trim(buffer(1:i-1))) /= 0) then
  852. is_known_lat(idx) = .true.
  853. read(buffer(i+1:eos-1),*) source_known_lat(idx)
  854. else if (index('known_lon',trim(buffer(1:i-1))) /= 0) then
  855. is_known_lon(idx) = .true.
  856. read(buffer(i+1:eos-1),*) source_known_lon(idx)
  857. else if (index('stdlon',trim(buffer(1:i-1))) /= 0) then
  858. is_stdlon(idx) = .true.
  859. read(buffer(i+1:eos-1),*) source_stdlon(idx)
  860. else if (index('truelat1',trim(buffer(1:i-1))) /= 0) then
  861. is_truelat1(idx) = .true.
  862. read(buffer(i+1:eos-1),*) source_truelat1(idx)
  863. else if (index('truelat2',trim(buffer(1:i-1))) /= 0) then
  864. is_truelat2(idx) = .true.
  865. read(buffer(i+1:eos-1),*) source_truelat2(idx)
  866. else if (index('wordsize',trim(buffer(1:i-1))) /= 0) then
  867. is_wordsize(idx) = .true.
  868. read(buffer(i+1:eos-1),'(i10)') source_wordsize(idx)
  869. else if (index('endian',trim(buffer(1:i-1))) /= 0) then
  870. if (index('big',trim(buffer(i+1:eos-1))) /= 0) then
  871. is_endian(idx) = .true.
  872. source_endian(idx) = BIG_ENDIAN
  873. else if (index('little',trim(buffer(i+1:eos-1))) /= 0) then
  874. is_endian(idx) = .true.
  875. source_endian(idx) = LITTLE_ENDIAN
  876. else
  877. call mprintf(.true.,WARN,'Invalid value for keyword ''endian'' '// &
  878. 'specified in index file. BIG_ENDIAN will be used.')
  879. end if
  880. else if (index('row_order',trim(buffer(1:i-1))) /= 0) then
  881. if (index('bottom_top',trim(buffer(i+1:eos-1))) /= 0) then
  882. is_row_order(idx) = .true.
  883. source_row_order(idx) = BOTTOM_TOP
  884. else if (index('top_bottom',trim(buffer(i+1:eos-1))) /= 0) then
  885. is_row_order(idx) = .true.
  886. source_row_order(idx) = TOP_BOTTOM
  887. end if
  888. else if (index('tile_x',trim(buffer(1:i-1))) /= 0) then
  889. is_tile_x(idx) = .true.
  890. read(buffer(i+1:eos-1),'(i10)') source_tile_x(idx)
  891. else if (index('tile_y',trim(buffer(1:i-1))) /= 0) then
  892. is_tile_y(idx) = .true.
  893. read(buffer(i+1:eos-1),'(i10)') source_tile_y(idx)
  894. else if (index('tile_z',trim(buffer(1:i-1))) /= 0) then
  895. is_tile_z(idx) = .true.
  896. read(buffer(i+1:eos-1),'(i10)') source_tile_z(idx)
  897. else if (index('tile_z_start',trim(buffer(1:i-1))) /= 0) then
  898. is_tile_z_start(idx) = .true.
  899. read(buffer(i+1:eos-1),'(i10)') source_tile_z_start(idx)
  900. else if (index('tile_z_end',trim(buffer(1:i-1))) /= 0) then
  901. is_tile_z_end(idx) = .true.
  902. read(buffer(i+1:eos-1),'(i10)') source_tile_z_end(idx)
  903. else if (index('category_min',trim(buffer(1:i-1))) /= 0) then
  904. is_category_min(idx) = .true.
  905. read(buffer(i+1:eos-1),'(i10)') source_category_min(idx)
  906. else if (index('category_max',trim(buffer(1:i-1))) /= 0) then
  907. is_category_max(idx) = .true.
  908. read(buffer(i+1:eos-1),'(i10)') source_category_max(idx)
  909. else if (index('tile_bdr',trim(buffer(1:i-1))) /= 0) then
  910. is_tile_bdr(idx) = .true.
  911. read(buffer(i+1:eos-1),'(i10)') source_tile_bdr(idx)
  912. else if (index('missing_value',trim(buffer(1:i-1))) /= 0) then
  913. is_missing_value(idx) = .true.
  914. read(buffer(i+1:eos-1),*) source_missing_value(idx)
  915. else if (index('scale_factor',trim(buffer(1:i-1))) /= 0) then
  916. is_scale_factor(idx) = .true.
  917. read(buffer(i+1:eos-1),*) source_scale_factor(idx)
  918. else if (index('geotiff',trim(buffer(1:i-1))) /= 0) then
  919. is_geotiff(idx) = .true.
  920. read(buffer(i+1:eos-1),*) source_geotiff_file(idx)
  921. else
  922. call mprintf(.true., WARN, 'In %s, unrecognized option %s in entry %i.', &
  923. s1=trim(test_fname), s2=buffer(1:i-1), i1=i)
  924. end if
  925. end if !} index(buffer(1:eos-1),'=') /= 0
  926. buffer = buffer(eos+1:BUFSIZE)
  927. end do ! while eos /= 0 }
  928. end if !} index(buffer, '=====') /= 0
  929. go to 30
  930. 40 continue
  931. #ifdef _HAS_GEOTIFF
  932. if(is_geotiff(idx)) then
  933. if(source_geotiff_file(idx)(1:1) .ne. '/')then
  934. source_geotiff_file(idx)=TRIM(source_path(idx))//TRIM(source_geotiff_file(idx))
  935. endif
  936. call open_geotiff(source_geotiff_file(idx))
  937. call merge_geotiff_header(source_geotiff_file(idx),is_proj(idx),source_proj(idx),&
  938. is_fieldtype(idx),source_fieldtype(idx), &
  939. is_units(idx),source_units(idx), &
  940. is_descr(idx),source_descr(idx),is_dx(idx), &
  941. source_dx(idx),is_dy(idx),source_dy(idx), &
  942. is_known_x(idx),source_known_x(idx), &
  943. is_known_y(idx),source_known_y(idx), &
  944. is_known_lat(idx),source_known_lat(idx), &
  945. is_known_lon(idx),source_known_lon(idx), &
  946. is_stdlon(idx),source_stdlon(idx), &
  947. is_truelat1(idx),source_truelat1(idx), &
  948. is_truelat2(idx),source_truelat2(idx), &
  949. is_row_order(idx),source_row_order(idx), &
  950. is_tile_x(idx),source_tile_x(idx), &
  951. is_tile_y(idx),source_tile_y(idx), &
  952. is_tile_z(idx),source_tile_z(idx), &
  953. is_tile_z_start(idx),source_tile_z_start(idx), &
  954. is_tile_z_end(idx), source_tile_z_end(idx), &
  955. is_category_min(idx),source_category_min(idx), &
  956. is_category_max(idx),source_category_max(idx), &
  957. is_tile_bdr(idx),source_tile_bdr(idx), &
  958. is_missing_value(idx),source_missing_value(idx))
  959. is_wordsize(idx)=.true.
  960. source_wordsize(idx)=4
  961. is_scale_factor(idx)=.true.
  962. source_scale_factor(idx)=1.
  963. call mprintf(.true.,INFORM,'For geotiff file, %s, using the following parameters:', &
  964. s1=TRIM(source_geotiff_file(idx)))
  965. if(is_descr(idx)) &
  966. call mprintf(.true.,INFORM,'description=%s',s1=TRIM(source_descr(idx)))
  967. if(is_units(idx)) &
  968. call mprintf(.true.,INFORM,'units=%s',s1=TRIM(source_units(idx)))
  969. if(is_proj(idx)) &
  970. call mprintf(.true.,INFORM,'proj=%i',i1=source_proj(idx))
  971. if(is_stdlon(idx)) &
  972. call mprintf(.true.,INFORM,'stdlon=%f',f1=source_stdlon(idx))
  973. if(is_truelat1(idx)) &
  974. call mprintf(.true.,INFORM,'truelat1=%f',f1=source_truelat1(idx))
  975. if(is_truelat2(idx)) &
  976. call mprintf(.true.,INFORM,'truelat2=%f',f1=source_truelat2(idx))
  977. if(is_dx(idx)) &
  978. call mprintf(.true.,INFORM,'dx=%f',f1=source_dx(idx))
  979. if(is_dy(idx)) &
  980. call mprintf(.true.,INFORM,'dy=%f',f1=source_dy(idx))
  981. if(is_known_x(idx)) &
  982. call mprintf(.true.,INFORM,'known_x=%f',f1=source_known_x(idx))
  983. if(is_known_y(idx)) &
  984. call mprintf(.true.,INFORM,'known_y=%f',f1=source_known_y(idx))
  985. if(is_known_lon(idx)) &
  986. call mprintf(.true.,INFORM,'known_lon=%f',f1=source_known_lon(idx))
  987. if(is_known_lat(idx)) &
  988. call mprintf(.true.,INFORM,'known_lat=%f',f1=source_known_lat(idx))
  989. if(is_fieldtype(idx)) &
  990. call mprintf(.true.,INFORM,'fieldtype=%i',i1=source_fieldtype(idx))
  991. if(is_category_min(idx)) &
  992. call mprintf(.true.,INFORM,'category_min=%i',i1=source_category_min(idx))
  993. if(is_category_max(idx)) &
  994. call mprintf(.true.,INFORM,'category_max=%i',i1=source_category_max(idx))
  995. if(is_row_order(idx)) &
  996. call mprintf(.true.,INFORM,'row_order=%i',i1=source_row_order(idx))
  997. if(is_tile_x(idx)) &
  998. call mprintf(.true.,INFORM,'tile_x=%i',i1=source_tile_x(idx))
  999. if(is_tile_y(idx)) &
  1000. call mprintf(.true.,INFORM,'tile_y=%i',i1=source_tile_y(idx))
  1001. if(is_tile_z(idx)) &
  1002. call mprintf(.true.,INFORM,'tile_z=%i',i1=source_tile_z(idx))
  1003. if(is_tile_bdr(idx)) &
  1004. call mprintf(.true.,INFORM,'tile_bdr=%i',i1=source_tile_bdr(idx))
  1005. if(is_missing_value(idx)) &
  1006. call mprintf(.true.,INFORM,'missing_value=%f',f1=source_missing_value(idx))
  1007. endif
  1008. #else
  1009. if(is_geotiff(idx)) then
  1010. call mprintf(.true.,ERROR,'A geotiff file has been specified in %s, '// &
  1011. 'but geogrid has not been compiled with geotiff '// &
  1012. 'support.',s1=trim(test_fname))
  1013. endif
  1014. #endif
  1015. close(funit)
  1016. end do
  1017. return
  1018. 1000 call mprintf(.true.,ERROR,'Could not open %s', s1=trim(test_fname))
  1019. 1001 call mprintf(.true.,ERROR,'Encountered error while reading %s', s1=trim(test_fname))
  1020. end subroutine get_source_params
  1021. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1022. ! Name: datalist_destroy()
  1023. !
  1024. ! Purpose: This routine deallocates any memory that was allocated by the
  1025. ! get_datalist() subroutine.
  1026. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1027. subroutine datalist_destroy()
  1028. #ifdef _HAVE_GEOTIFF
  1029. use geotiff_module, only : destroy_all
  1030. #endif
  1031. implicit none
  1032. ! Local variables
  1033. integer :: i
  1034. #ifdef _HAVE_GEOTIFF
  1035. call destroy_all()
  1036. #endif
  1037. if (associated(source_wordsize)) then
  1038. deallocate(source_wordsize)
  1039. deallocate(source_endian)
  1040. deallocate(source_fieldtype)
  1041. deallocate(source_dest_fieldtype)
  1042. deallocate(source_proj)
  1043. deallocate(source_priority)
  1044. deallocate(source_dx)
  1045. deallocate(source_dy)
  1046. deallocate(source_known_x)
  1047. deallocate(source_known_y)
  1048. deallocate(source_known_lat)
  1049. deallocate(source_known_lon)
  1050. deallocate(source_truelat1)
  1051. deallocate(source_truelat2)
  1052. deallocate(source_stdlon)
  1053. deallocate(source_fieldname)
  1054. deallocate(source_path)
  1055. deallocate(source_interp_string)
  1056. deallocate(source_tile_x)
  1057. deallocate(source_tile_y)
  1058. deallocate(source_tile_z)
  1059. deallocate(source_tile_z_start)
  1060. deallocate(source_tile_z_end)
  1061. deallocate(source_tile_bdr)
  1062. deallocate(source_category_min)
  1063. deallocate(source_category_max)
  1064. deallocate(source_masked)
  1065. deallocate(source_output_stagger)
  1066. deallocate(source_row_order)
  1067. deallocate(source_dominant_category)
  1068. deallocate(source_dominant_only)
  1069. deallocate(source_dfdx)
  1070. deallocate(source_dfdy)
  1071. deallocate(source_scale_factor)
  1072. deallocate(source_z_dim_name)
  1073. deallocate(source_smooth_option)
  1074. deallocate(source_smooth_passes)
  1075. deallocate(source_units)
  1076. deallocate(source_descr)
  1077. deallocate(source_missing_value)
  1078. deallocate(source_fill_missing)
  1079. do i=1,num_entries
  1080. call list_destroy(source_res_path(i))
  1081. call list_destroy(source_interp_option(i))
  1082. call list_destroy(source_landmask_land(i))
  1083. call list_destroy(source_landmask_water(i))
  1084. end do
  1085. deallocate(source_res_path)
  1086. deallocate(source_interp_option)
  1087. deallocate(source_landmask_land)
  1088. deallocate(source_landmask_water)
  1089. deallocate(is_wordsize)
  1090. deallocate(is_endian)
  1091. deallocate(is_fieldtype)
  1092. deallocate(is_dest_fieldtype)
  1093. deallocate(is_proj)
  1094. deallocate(is_priority)
  1095. deallocate(is_dx)
  1096. deallocate(is_dy)
  1097. deallocate(is_known_x)
  1098. deallocate(is_known_y)
  1099. deallocate(is_known_lat)
  1100. deallocate(is_known_lon)
  1101. deallocate(is_truelat1)
  1102. deallocate(is_truelat2)
  1103. deallocate(is_stdlon)
  1104. deallocate(is_fieldname)
  1105. deallocate(is_path)
  1106. deallocate(is_tile_x)
  1107. deallocate(is_tile_y)
  1108. deallocate(is_tile_z)
  1109. deallocate(is_tile_z_start)
  1110. deallocate(is_tile_z_end)
  1111. deallocate(is_tile_bdr)
  1112. deallocate(is_category_min)
  1113. deallocate(is_category_max)
  1114. deallocate(is_masked)
  1115. deallocate(is_halt_missing)
  1116. deallocate(is_output_stagger)
  1117. deallocate(is_row_order)
  1118. deallocate(is_dominant_category)
  1119. deallocate(is_dominant_only)
  1120. deallocate(is_dfdx)
  1121. deallocate(is_dfdy)
  1122. deallocate(is_scale_factor)
  1123. deallocate(is_z_dim_name)
  1124. deallocate(is_smooth_option)
  1125. deallocate(is_smooth_passes)
  1126. deallocate(is_signed)
  1127. deallocate(is_units)
  1128. deallocate(is_descr)
  1129. deallocate(is_missing_value)
  1130. deallocate(is_fill_missing)
  1131. end if
  1132. call hash_destroy(bad_files)
  1133. end subroutine datalist_destroy
  1134. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1135. ! Name: reset_next_field
  1136. !
  1137. ! Purpose: To reset the pointer to the next field in the list of fields
  1138. ! specified by the user.
  1139. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1140. subroutine reset_next_field()
  1141. implicit none
  1142. next_field = 1
  1143. end subroutine reset_next_field
  1144. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1145. ! Name: get_next_fieldname
  1146. !
  1147. ! Purpose: Calling this routine results in field_name being set to the name of
  1148. ! the field currently pointed to. If istatus /= 0 upon return, an error
  1149. ! occurred, and the value of field_name is undefined.
  1150. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1151. subroutine get_next_fieldname(field_name, istatus)
  1152. implicit none
  1153. ! Arguments
  1154. integer, intent(out) :: istatus
  1155. character (len=128), intent(out) :: field_name
  1156. istatus = 1
  1157. if (next_field <= num_entries) then
  1158. field_name = source_fieldname(next_field)
  1159. next_field = next_field + 1
  1160. istatus = 0
  1161. end if
  1162. end subroutine get_next_fieldname
  1163. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1164. ! Name: get_next_output_fieldname
  1165. !
  1166. ! Purpose:
  1167. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1168. recursive subroutine get_next_output_fieldname(nest_num, field_name, ndims, &
  1169. min_cat, max_cat, &
  1170. istagger, memorder, dimnames, units, &
  1171. description, subgrid_var, istatus)
  1172. use gridinfo_module
  1173. implicit none
  1174. #include "wrf_io_flags.h"
  1175. ! Arguments
  1176. integer, intent(in) :: nest_num
  1177. integer, intent(out) :: istatus, ndims, istagger, min_cat, max_cat
  1178. logical, intent(out) :: subgrid_var
  1179. character (len=128), intent(out) :: memorder, field_name, units, description
  1180. character (len=128), dimension(3), intent(out) :: dimnames
  1181. ! Local variables
  1182. integer :: temp_fieldtype
  1183. integer, dimension(MAX_LANDMASK_CATEGORIES) :: landmask
  1184. logical :: is_water_mask, is_dom_only
  1185. character (len=128) :: domcat_name, dfdx_name, dfdy_name
  1186. character (len=256) :: temphash
  1187. istatus = 1
  1188. if (output_field_state == RETURN_LANDMASK) then
  1189. call hash_init(duplicate_fnames)
  1190. call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
  1191. if (istatus == 0) then
  1192. temphash(129:256) = ' '
  1193. temphash(1:128) = field_name(1:128)
  1194. call hash_insert(duplicate_fnames, temphash)
  1195. call get_domcategory_name(field_name, domcat_name, is_dom_only, istatus)
  1196. ! We will only save the dominant category
  1197. if (is_dom_only .and. (istatus == 0)) then
  1198. output_field_state = RETURN_DOMCAT_LM
  1199. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1200. min_cat, max_cat, istagger, &
  1201. memorder, dimnames, units, description, &
  1202. subgrid_var, istatus)
  1203. return
  1204. else
  1205. ndims = 2
  1206. min_cat = 1
  1207. max_cat = 1
  1208. temp_fieldtype = iget_fieldtype(field_name, istatus)
  1209. if (istatus == 0) then
  1210. if (temp_fieldtype == CONTINUOUS) then
  1211. call get_max_levels(field_name, min_cat, max_cat, istatus)
  1212. else if (temp_fieldtype == CATEGORICAL) then
  1213. call get_max_categories(field_name, min_cat, max_cat, istatus)
  1214. end if
  1215. if (max_cat - min_cat > 0) ndims = 3
  1216. end if
  1217. call get_output_stagger(field_name, istagger, istatus)
  1218. if (istagger == M) then
  1219. dimnames(1) = 'west_east'
  1220. dimnames(2) = 'south_north'
  1221. else if (istagger == U) then
  1222. dimnames(1) = 'west_east_stag'
  1223. dimnames(2) = 'south_north'
  1224. else if (istagger == V) then
  1225. dimnames(1) = 'west_east'
  1226. dimnames(2) = 'south_north_stag'
  1227. else if (istagger == HH) then
  1228. dimnames(1) = 'west_east'
  1229. dimnames(2) = 'south_north'
  1230. else if (istagger == VV) then
  1231. dimnames(1) = 'west_east'
  1232. dimnames(2) = 'south_north'
  1233. end if
  1234. if (ndims == 2) then
  1235. memorder = 'XY '
  1236. dimnames(3) = ' '
  1237. else if (ndims == 3) then
  1238. memorder = 'XYZ'
  1239. call get_z_dim_name(field_name, dimnames(3), istatus)
  1240. istatus = 0
  1241. else
  1242. memorder = ' '
  1243. dimnames(3) = ' '
  1244. end if
  1245. subgrid_var=is_subgrid_var(field_name)
  1246. if ( subgrid_var ) then
  1247. call get_subgrid_dim_name(dimnames(1:2))
  1248. end if
  1249. call get_source_units(field_name, 1, units, istatus)
  1250. if (istatus /= 0) units = '-'
  1251. call get_source_descr(field_name, 1, description, istatus)
  1252. if (istatus /= 0) description = '-'
  1253. istatus = 0
  1254. output_field_state = RETURN_DOMCAT_LM
  1255. end if
  1256. else
  1257. output_field_state = RETURN_FIELDNAME
  1258. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1259. min_cat, max_cat, istagger, &
  1260. memorder, dimnames, units, description, &
  1261. subgrid_var, istatus)
  1262. return
  1263. end if
  1264. else if (output_field_state == RETURN_FIELDNAME) then
  1265. call get_next_fieldname(field_name, istatus)
  1266. temphash(129:256) = ' '
  1267. temphash(1:128) = field_name(1:128)
  1268. if (istatus == 0 .and. (.not. hash_search(duplicate_fnames, temphash))) then
  1269. call hash_insert(duplicate_fnames, temphash)
  1270. call get_domcategory_name(field_name, domcat_name, is_dom_only, istatus)
  1271. ! We will only save the dominant category
  1272. if (is_dom_only .and. (istatus == 0)) then
  1273. output_field_state = RETURN_DOMCAT
  1274. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1275. min_cat, max_cat, istagger, &
  1276. memorder, dimnames, units, description, &
  1277. subgrid_var, istatus)
  1278. return
  1279. ! Return the fractional field
  1280. else
  1281. ndims = 2
  1282. min_cat = 1
  1283. max_cat = 1
  1284. temp_fieldtype = iget_fieldtype(field_name, istatus)
  1285. if (istatus == 0) then
  1286. if (temp_fieldtype == CONTINUOUS) then
  1287. call get_max_levels(field_name, min_cat, max_cat, istatus)
  1288. else if (temp_fieldtype == CATEGORICAL) then
  1289. call get_max_categories(field_name, min_cat, max_cat, istatus)
  1290. end if
  1291. if (max_cat - min_cat > 0) ndims = 3
  1292. end if
  1293. call get_output_stagger(field_name, istagger, istatus)
  1294. if (istagger == M) then
  1295. dimnames(1) = 'west_east'
  1296. dimnames(2) = 'south_north'
  1297. else if (istagger == U) then
  1298. dimnames(1) = 'west_east_stag'
  1299. dimnames(2) = 'south_north'
  1300. else if (istagger == V) then
  1301. dimnames(1) = 'west_east'
  1302. dimnames(2) = 'south_north_stag'
  1303. else if (istagger == HH) then
  1304. dimnames(1) = 'west_east'
  1305. dimnames(2) = 'south_north'
  1306. else if (istagger == VV) then
  1307. dimnames(1) = 'west_east'
  1308. dimnames(2) = 'south_north'
  1309. end if
  1310. if (ndims == 2) then
  1311. memorder = 'XY '
  1312. dimnames(3) = ' '
  1313. else if (ndims == 3) then
  1314. memorder = 'XYZ'
  1315. call get_z_dim_name(field_name, dimnames(3), istatus)
  1316. istatus = 0
  1317. else
  1318. memorder = ' '
  1319. dimnames(3) = ' '
  1320. end if
  1321. subgrid_var=is_subgrid_var(field_name)
  1322. if ( subgrid_var ) then
  1323. call get_subgrid_dim_name(dimnames(1:2))
  1324. end if
  1325. call get_source_units(field_name, 1, units, istatus)
  1326. if (istatus /= 0) units = '-'
  1327. call get_source_descr(field_name, 1, description, istatus)
  1328. if (istatus /= 0) description = '-'
  1329. istatus = 0
  1330. output_field_state = RETURN_DOMCAT
  1331. end if
  1332. else if (istatus /= 0) then
  1333. output_field_state = RETURN_LANDMASK
  1334. call hash_destroy(duplicate_fnames)
  1335. return
  1336. else if (hash_search(duplicate_fnames, temphash)) then
  1337. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1338. min_cat, max_cat, istagger, &
  1339. memorder, dimnames, units, description, &
  1340. subgrid_var, istatus)
  1341. return
  1342. end if
  1343. else if (output_field_state == RETURN_DOMCAT .or. &
  1344. output_field_state == RETURN_DOMCAT_LM ) then
  1345. if (output_field_state == RETURN_DOMCAT) then
  1346. next_field = next_field - 1
  1347. call get_next_fieldname(field_name, istatus)
  1348. else
  1349. call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
  1350. end if
  1351. if (istatus == 0) then
  1352. call get_domcategory_name(field_name, domcat_name, is_dom_only, istatus)
  1353. if (istatus == 0) then
  1354. ndims = 2
  1355. min_cat = 1
  1356. max_cat = 1
  1357. call get_output_stagger(field_name, istagger, istatus)
  1358. if (istagger == M) then
  1359. dimnames(1) = 'west_east'
  1360. dimnames(2) = 'south_north'
  1361. else if (istagger == U) then
  1362. dimnames(1) = 'west_east_stag'
  1363. dimnames(2) = 'south_north'
  1364. else if (istagger == V) then
  1365. dimnames(1) = 'west_east'
  1366. dimnames(2) = 'south_north_stag'
  1367. else if (istagger == HH) then
  1368. dimnames(1) = 'west_east'
  1369. dimnames(2) = 'south_north'
  1370. else if (istagger == VV) then
  1371. dimnames(1) = 'west_east'
  1372. dimnames(2) = 'south_north'
  1373. end if
  1374. dimnames(3) = ' '
  1375. memorder = 'XY '
  1376. subgrid_var=is_subgrid_var(field_name)
  1377. if ( subgrid_var ) then
  1378. call get_subgrid_dim_name(dimnames(1:2))
  1379. end if
  1380. field_name = domcat_name
  1381. units = 'category'
  1382. description = 'Dominant category'
  1383. if (output_field_state == RETURN_DOMCAT) then
  1384. output_field_state = RETURN_DFDX
  1385. else
  1386. output_field_state = RETURN_DFDX_LM
  1387. end if
  1388. else
  1389. if (output_field_state == RETURN_DOMCAT) then
  1390. output_field_state = RETURN_DFDX
  1391. else
  1392. output_field_state = RETURN_DFDX_LM
  1393. end if
  1394. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1395. min_cat, max_cat, istagger, &
  1396. memorder, dimnames, units, description, &
  1397. subgrid_var, istatus)
  1398. return
  1399. end if
  1400. else
  1401. call mprintf(.true., ERROR, 'get_next_output_fieldname(): In state DOMCAT, '// &
  1402. 'but no field name is found.')
  1403. end if
  1404. else if (output_field_state == RETURN_DFDX .or. &
  1405. output_field_state == RETURN_DFDX_LM) then
  1406. if (output_field_state == RETURN_DFDX) then
  1407. next_field = next_field - 1
  1408. call get_next_fieldname(field_name, istatus)
  1409. else
  1410. call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
  1411. end if
  1412. if (istatus == 0) then
  1413. call get_dfdx_name(field_name, dfdx_name, istatus)
  1414. if (istatus == 0) then
  1415. ndims = 2
  1416. min_cat = 1
  1417. max_cat = 1
  1418. temp_fieldtype = iget_fieldtype(field_name, istatus)
  1419. if (istatus == 0) then
  1420. if (temp_fieldtype == CONTINUOUS) then
  1421. call get_max_levels(field_name, min_cat, max_cat, istatus)
  1422. else if (temp_fieldtype == CATEGORICAL) then
  1423. call get_max_categories(field_name, min_cat, max_cat, istatus)
  1424. end if
  1425. if (max_cat - min_cat > 0) ndims = 3
  1426. end if
  1427. call get_output_stagger(field_name, istagger, istatus)
  1428. if (istagger == M) then
  1429. dimnames(1) = 'west_east'
  1430. dimnames(2) = 'south_north'
  1431. else if (istagger == U) then
  1432. dimnames(1) = 'west_east_stag'
  1433. dimnames(2) = 'south_north'
  1434. else if (istagger == V) then
  1435. dimnames(1) = 'west_east'
  1436. dimnames(2) = 'south_north_stag'
  1437. else if (istagger == HH) then
  1438. dimnames(1) = 'west_east'
  1439. dimnames(2) = 'south_north'
  1440. else if (istagger == VV) then
  1441. dimnames(1) = 'west_east'
  1442. dimnames(2) = 'south_north'
  1443. end if
  1444. if (ndims == 2) then
  1445. memorder = 'XY '
  1446. dimnames(3) = ' '
  1447. else if (ndims == 3) then
  1448. memorder = 'XYZ'
  1449. call get_z_dim_name(field_name, dimnames(3), istatus)
  1450. istatus = 0
  1451. else
  1452. memorder = ' '
  1453. dimnames(3) = ' '
  1454. end if
  1455. units = '-'
  1456. subgrid_var=is_subgrid_var(field_name)
  1457. if ( subgrid_var ) then
  1458. call get_subgrid_dim_name(dimnames(1:2))
  1459. end if
  1460. field_name = dfdx_name
  1461. description = 'df/dx'
  1462. if (output_field_state == RETURN_DFDX) then
  1463. output_field_state = RETURN_DFDY
  1464. else
  1465. output_field_state = RETURN_DFDY_LM
  1466. end if
  1467. else
  1468. if (output_field_state == RETURN_DFDX) then
  1469. output_field_state = RETURN_DFDY
  1470. else
  1471. output_field_state = RETURN_DFDY_LM
  1472. end if
  1473. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1474. min_cat, max_cat, istagger, &
  1475. memorder, dimnames, units, description, &
  1476. subgrid_var, istatus)
  1477. return
  1478. end if
  1479. else
  1480. call mprintf(.true., ERROR, 'get_next_output_fieldname(): In state DFDX, '// &
  1481. 'but no field name is found.')
  1482. end if
  1483. else if (output_field_state == RETURN_DFDY .or. &
  1484. output_field_state == RETURN_DFDY_LM) then
  1485. if (output_field_state == RETURN_DFDY) then
  1486. next_field = next_field - 1
  1487. call get_next_fieldname(field_name, istatus)
  1488. else
  1489. call get_landmask_field(geog_data_res(nest_num), field_name, is_water_mask, landmask, istatus)
  1490. end if
  1491. if (istatus == 0) then
  1492. call get_dfdy_name(field_name, dfdy_name, istatus)
  1493. if (istatus == 0) then
  1494. ndims = 2
  1495. min_cat = 1
  1496. max_cat = 1
  1497. temp_fieldtype = iget_fieldtype(field_name, istatus)
  1498. if (istatus == 0) then
  1499. if (temp_fieldtype == CONTINUOUS) then
  1500. call get_max_levels(field_name, min_cat, max_cat, istatus)
  1501. else if (temp_fieldtype == CATEGORICAL) then
  1502. call get_max_categories(field_name, min_cat, max_cat, istatus)
  1503. end if
  1504. if (max_cat - min_cat > 0) ndims = 3
  1505. end if
  1506. call get_output_stagger(field_name, istagger, istatus)
  1507. if (istagger == M) then
  1508. dimnames(1) = 'west_east'
  1509. dimnames(2) = 'south_north'
  1510. else if (istagger == U) then
  1511. dimnames(1) = 'west_east_stag'
  1512. dimnames(2) = 'south_north'
  1513. else if (istagger == V) then
  1514. dimnames(1) = 'west_east'
  1515. dimnames(2) = 'south_north_stag'
  1516. else if (istagger == HH) then
  1517. dimnames(1) = 'west_east'
  1518. dimnames(2) = 'south_north'
  1519. else if (istagger == VV) then
  1520. dimnames(1) = 'west_east'
  1521. dimnames(2) = 'south_north'
  1522. end if
  1523. if (ndims == 2) then
  1524. memorder = 'XY '
  1525. dimnames(3) = ' '
  1526. else if (ndims == 3) then
  1527. memorder = 'XYZ'
  1528. call get_z_dim_name(field_name, dimnames(3), istatus)
  1529. istatus = 0
  1530. else
  1531. memorder = ' '
  1532. dimnames(3) = ' '
  1533. end if
  1534. subgrid_var=is_subgrid_var(field_name)
  1535. if ( subgrid_var ) then
  1536. call get_subgrid_dim_name(dimnames(1:2))
  1537. end if
  1538. field_name = dfdy_name
  1539. units = '-'
  1540. description = 'df/dy'
  1541. output_field_state = RETURN_FIELDNAME
  1542. else
  1543. output_field_state = RETURN_FIELDNAME
  1544. call get_next_output_fieldname(nest_num, field_name, ndims, &
  1545. min_cat, max_cat, istagger, &
  1546. memorder, dimnames, units, description, &
  1547. subgrid_var, istatus)
  1548. return
  1549. end if
  1550. else
  1551. call mprintf(.true., ERROR, 'get_next_output_fieldname(): In state DFDY, but no '// &
  1552. 'field name is found.')
  1553. end if
  1554. end if
  1555. end subroutine get_next_output_fieldname
  1556. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1557. ! Name: get_landmask_field
  1558. !
  1559. ! Purpose: To return the name of the field from which the landmask is to be
  1560. ! computed. If no error occurs, is_water_mask is .true. if the landmask
  1561. ! value specifies the value of water, and .false. if the landmask value
  1562. ! specifies the value of land.
  1563. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1564. subroutine get_landmask_field(res_string, landmask_name, is_water_mask, landmask, istatus)
  1565. implicit none
  1566. ! Arguments
  1567. character (len=128), intent(in) :: res_string
  1568. integer, dimension(:), intent(out) :: landmask
  1569. integer, intent(out) :: istatus
  1570. logical, intent(out) :: is_water_mask
  1571. character (len=128), intent(out) :: landmask_name
  1572. ! Local variables
  1573. integer :: j
  1574. integer :: ilen
  1575. integer :: idx
  1576. integer :: is, ie, sos, eos, comma
  1577. character (len=128) :: temp_res, mask_cat_string
  1578. istatus = 1
  1579. do idx=1,num_entries
  1580. if (list_length(source_landmask_land(idx)) > 0) then
  1581. is = 1
  1582. ie = index(res_string(is:128),'+') - 1
  1583. if (ie <= 0) ie = 128
  1584. temp_res = res_string(is:ie)
  1585. do while (.not. list_search(source_landmask_land(idx), ckey=temp_res, cvalue=mask_cat_string) &
  1586. .and. is <= 128)
  1587. is = ie+2
  1588. ie = is + index(res_string(is:128),'+') - 2
  1589. if (ie - is <= 0) ie = 128
  1590. temp_res = res_string(is:ie)
  1591. end do
  1592. if (is > 128) then
  1593. temp_res = 'default'
  1594. if (list_search(source_landmask_land(idx), ckey=temp_res, cvalue=mask_cat_string)) then
  1595. is_water_mask = .false.
  1596. landmask_name = source_fieldname(idx)
  1597. istatus = 0
  1598. end if
  1599. else
  1600. is_water_mask = .false.
  1601. landmask_name = source_fieldname(idx)
  1602. istatus = 0
  1603. end if
  1604. end if
  1605. ! Note: The following cannot be an else-if, since different resolutions of data may
  1606. ! specify, alternately, a land or a water mask, and in general we need to search
  1607. ! both lists
  1608. if (list_length(source_landmask_water(idx)) > 0) then
  1609. is = 1
  1610. ie = index(res_string(is:128),'+') - 1
  1611. if (ie <= 0) ie = 128
  1612. temp_res = res_string(is:ie)
  1613. do while (.not. list_search(source_landmask_water(idx), ckey=temp_res, cvalue=mask_cat_string) &
  1614. .and. is <= 128)
  1615. is = ie+2
  1616. ie = is + index(res_string(is:128),'+') - 2
  1617. if (ie - is <= 0) ie = 128
  1618. temp_res = res_string(is:ie)
  1619. end do
  1620. if (is > 128) then
  1621. temp_res = 'default'
  1622. if (list_search(source_landmask_water(idx), ckey=temp_res, cvalue=mask_cat_string)) then
  1623. is_water_mask = .true.
  1624. landmask_name = source_fieldname(idx)
  1625. istatus = 0
  1626. end if
  1627. else
  1628. is_water_mask = .true.
  1629. landmask_name = source_fieldname(idx)
  1630. istatus = 0
  1631. end if
  1632. end if
  1633. if (istatus == 0) then
  1634. j = 1
  1635. sos = 0
  1636. eos = 128
  1637. comma = index(mask_cat_string(sos+1:eos-1),',')
  1638. do while (comma > 0 .and. j < MAX_LANDMASK_CATEGORIES)
  1639. read(mask_cat_string(sos+1:sos+comma-1),'(i10)') landmask(j)
  1640. sos = sos + comma
  1641. comma = index(mask_cat_string(sos+1:eos-1),',')
  1642. j = j + 1
  1643. end do
  1644. read(mask_cat_string(sos+1:eos-1),'(i10)') landmask(j)
  1645. j = j + 1
  1646. if (j <= MAX_LANDMASK_CATEGORIES) then ! Terminate list with a flag value
  1647. landmask(j) = INVALID
  1648. end if
  1649. exit
  1650. end if
  1651. end do
  1652. end subroutine get_landmask_field
  1653. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1654. ! Name: get_missing_value
  1655. !
  1656. ! Pupose: Return the value used in the source data to indicate missing data.
  1657. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1658. subroutine get_missing_value(fieldnm, ilevel, rmissing, istatus)
  1659. implicit none
  1660. ! Arguments
  1661. integer, intent(in) :: ilevel
  1662. integer, intent(out) :: istatus
  1663. real, intent(out) :: rmissing
  1664. character (len=128), intent(in) :: fieldnm
  1665. ! Local variables
  1666. integer :: idx
  1667. istatus = 1
  1668. do idx=1,num_entries
  1669. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1670. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
  1671. (source_priority(idx) == ilevel)) then
  1672. if (is_missing_value(idx)) then
  1673. rmissing = source_missing_value(idx)
  1674. istatus = 0
  1675. exit
  1676. end if
  1677. end if
  1678. end do
  1679. end subroutine get_missing_value
  1680. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1681. ! Name: get_source_units
  1682. !
  1683. ! Pupose: Return a string giving the units of the specified source data.
  1684. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1685. subroutine get_source_units(fieldnm, ilevel, cunits, istatus)
  1686. implicit none
  1687. ! Arguments
  1688. integer, intent(in) :: ilevel
  1689. integer, intent(out) :: istatus
  1690. character (len=128), intent(in) :: fieldnm
  1691. character (len=128), intent(out) :: cunits
  1692. ! Local variables
  1693. integer :: idx
  1694. istatus = 1
  1695. do idx=1,num_entries
  1696. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1697. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
  1698. (source_priority(idx) == ilevel)) then
  1699. if (is_units(idx)) then
  1700. cunits = source_units(idx)
  1701. istatus = 0
  1702. exit
  1703. end if
  1704. end if
  1705. end do
  1706. end subroutine get_source_units
  1707. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1708. ! Name: get_source_descr
  1709. !
  1710. ! Pupose: Return a string giving a description of the specified source data.
  1711. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1712. subroutine get_source_descr(fieldnm, ilevel, descr, istatus)
  1713. implicit none
  1714. ! Arguments
  1715. integer, intent(in) :: ilevel
  1716. integer, intent(out) :: istatus
  1717. character (len=128), intent(in) :: fieldnm
  1718. character (len=128), intent(out) :: descr
  1719. ! Local variables
  1720. integer :: idx
  1721. istatus = 1
  1722. do idx=1,num_entries
  1723. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1724. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
  1725. (source_priority(idx) == ilevel)) then
  1726. if (is_units(idx)) then
  1727. descr = source_descr(idx)
  1728. istatus = 0
  1729. exit
  1730. end if
  1731. end if
  1732. end do
  1733. end subroutine get_source_descr
  1734. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1735. ! Name: get_missing_fill_value
  1736. !
  1737. ! Pupose: Return the value to fill missing points with.
  1738. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1739. subroutine get_missing_fill_value(fieldnm, rmissing, istatus)
  1740. implicit none
  1741. ! Arguments
  1742. integer, intent(out) :: istatus
  1743. real, intent(out) :: rmissing
  1744. character (len=128), intent(in) :: fieldnm
  1745. ! Local variables
  1746. integer :: idx
  1747. istatus = 1
  1748. do idx=1,num_entries
  1749. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1750. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) ) then
  1751. if (is_fill_missing(idx)) then
  1752. rmissing = source_fill_missing(idx)
  1753. istatus = 0
  1754. exit
  1755. end if
  1756. end if
  1757. end do
  1758. end subroutine get_missing_fill_value
  1759. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1760. ! Name: get_halt_on_missing
  1761. !
  1762. ! Pupose: Returns 1 if the program should halt upon encountering a missing
  1763. ! value in the final output field, and 0 otherwise.
  1764. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1765. subroutine get_halt_on_missing(fieldnm, halt, istatus)
  1766. implicit none
  1767. ! Arguments
  1768. integer, intent(out) :: istatus
  1769. logical, intent(out) :: halt
  1770. character (len=128), intent(in) :: fieldnm
  1771. ! Local variables
  1772. integer :: idx
  1773. istatus = 0
  1774. halt = .false.
  1775. do idx=1,num_entries
  1776. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1777. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) ) then
  1778. if (is_halt_missing(idx)) halt = .true.
  1779. end if
  1780. end do
  1781. end subroutine get_halt_on_missing
  1782. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1783. ! Name: get_masked_value
  1784. !
  1785. ! Pupose: If the field is to be masked by the landmask, returns 0 if the field
  1786. ! is masked over water and 1 if the field is masked over land. If no mask is
  1787. ! to be applied, -1 is returned.
  1788. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1789. subroutine get_masked_value(fieldnm, ilevel, masked, istatus)
  1790. implicit none
  1791. ! Arguments
  1792. integer, intent(in) :: ilevel
  1793. integer, intent(out) :: istatus
  1794. real, intent(out) :: masked
  1795. character (len=128), intent(in) :: fieldnm
  1796. ! Local variables
  1797. integer :: idx
  1798. istatus = 0
  1799. masked = -1.
  1800. do idx=1,num_entries
  1801. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1802. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
  1803. (source_priority(idx) == ilevel)) then
  1804. if (is_masked(idx)) then
  1805. masked = source_masked(idx)
  1806. exit
  1807. end if
  1808. end if
  1809. end do
  1810. end subroutine get_masked_value
  1811. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1812. ! Name: get_max_levels
  1813. !
  1814. ! Purpose: Returns the number of levels for the field given by fieldnm.
  1815. ! The number of levels will generally be specified for continuous fields,
  1816. ! whereas min/max category will generally be specified for categorical ones.
  1817. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1818. subroutine get_max_levels(fieldnm, min_level, max_level, istatus)
  1819. implicit none
  1820. ! Arguments
  1821. integer, intent(out) :: min_level, max_level, istatus
  1822. character (len=128), intent(in) :: fieldnm
  1823. ! Local variables
  1824. integer :: idx
  1825. logical :: have_found_field
  1826. have_found_field = .false.
  1827. istatus = 1
  1828. do idx=1,num_entries
  1829. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1830. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  1831. if (is_dest_fieldtype(idx) .and. (source_dest_fieldtype(idx) /= CONTINUOUS)) then
  1832. call mprintf(.true., WARN, 'In GEOGRID.TBL, destination field type for %s is '// &
  1833. 'not continuous and min/max levels specified.', s1=trim(fieldnm))
  1834. end if
  1835. if (.not. have_found_field) then
  1836. if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
  1837. have_found_field = .true.
  1838. istatus = 0
  1839. min_level = source_tile_z_start(idx)
  1840. max_level = source_tile_z_end(idx)
  1841. else if (is_tile_z(idx)) then
  1842. have_found_field = .true.
  1843. istatus = 0
  1844. min_level = 1
  1845. max_level = source_tile_z(idx)
  1846. end if
  1847. if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
  1848. if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
  1849. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start '// &
  1850. 'and tile_z_end specified for entry %i.',i1=idx)
  1851. end if
  1852. end if
  1853. else
  1854. if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
  1855. if (source_tile_z_start(idx) < min_level) min_level = source_tile_z_start(idx)
  1856. if (source_tile_z_end(idx) > max_level) max_level = source_tile_z_end(idx)
  1857. else if (is_tile_z(idx)) then
  1858. if (min_level > 1) min_level = 1
  1859. if (source_tile_z(idx) > max_level) max_level = source_tile_z(idx)
  1860. end if
  1861. if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
  1862. if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
  1863. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start '// &
  1864. 'and tile_z_end specified for entry %i.',i1=idx)
  1865. end if
  1866. end if
  1867. end if
  1868. end if
  1869. end do
  1870. end subroutine get_max_levels
  1871. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1872. ! Name: get_source_levels
  1873. !
  1874. ! Purpose: Return the min and max z-index for the source data for fieldname
  1875. ! at a specified priority level (compared with the min/max level over
  1876. ! all priority levels, as given by get_max_levels).
  1877. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1878. subroutine get_source_levels(fieldnm, ilevel, min_level, max_level, istatus)
  1879. implicit none
  1880. ! Arguments
  1881. integer, intent(in) :: ilevel
  1882. integer, intent(out) :: min_level, max_level, istatus
  1883. character (len=128), intent(in) :: fieldnm
  1884. ! Local variables
  1885. integer :: idx
  1886. istatus = 1
  1887. do idx=1,num_entries
  1888. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1889. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  1890. if (ilevel == source_priority(idx)) then
  1891. if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
  1892. istatus = 0
  1893. min_level = source_tile_z_start(idx)
  1894. max_level = source_tile_z_end(idx)
  1895. else if (is_tile_z(idx)) then
  1896. istatus = 0
  1897. min_level = 1
  1898. max_level = source_tile_z(idx)
  1899. end if
  1900. if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
  1901. if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
  1902. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start '// &
  1903. 'and tile_z_end specified for entry %i.',i1=idx)
  1904. end if
  1905. end if
  1906. end if
  1907. end if
  1908. end do
  1909. end subroutine get_source_levels
  1910. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1911. ! Name: get_max_categories
  1912. !
  1913. ! Purpose: Returns the minimum category and the maximum category for the field
  1914. ! given by fieldnm.
  1915. ! Min/max category will generally be specified for categorical fields,
  1916. ! whereas the number of levels will generally be specified for continuous
  1917. ! fields.
  1918. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1919. subroutine get_max_categories(fieldnm, min_category, max_category, istatus)
  1920. implicit none
  1921. ! Arguments
  1922. integer, intent(out) :: min_category, max_category, istatus
  1923. character (len=128), intent(in) :: fieldnm
  1924. ! Local variables
  1925. integer :: idx
  1926. logical :: have_found_field
  1927. have_found_field = .false.
  1928. istatus = 1
  1929. do idx=1,num_entries
  1930. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1931. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  1932. if (is_dest_fieldtype(idx) .and. (source_dest_fieldtype(idx) /= CATEGORICAL)) then
  1933. call mprintf(.true., WARN, &
  1934. 'In GEOGRID.TBL, cannot get min/max categories for continuous '// &
  1935. 'field %s at entry %i. Perhaps the user has requested to '// &
  1936. 'perform a strange operation on the field.', s1=trim(fieldnm), i1=idx)
  1937. end if
  1938. if (.not. have_found_field) then
  1939. if (is_category_min(idx) .and. is_category_max(idx)) then
  1940. have_found_field = .true.
  1941. istatus = 0
  1942. min_category = source_category_min(idx)
  1943. max_category = source_category_max(idx)
  1944. else if (is_category_min(idx) .or. is_category_max(idx)) then
  1945. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of min_category and '// &
  1946. 'max_category specified for entry %i.',i1=idx)
  1947. end if
  1948. else
  1949. if (is_category_min(idx) .and. is_category_max(idx)) then
  1950. if (source_category_min(idx) < min_category) min_category = source_category_min(idx)
  1951. if (source_category_max(idx) > max_category) max_category = source_category_max(idx)
  1952. else if (is_category_min(idx) .or. is_category_max(idx)) then
  1953. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of min_category and '// &
  1954. 'max_category specified for entry %i.',i1=idx)
  1955. end if
  1956. end if
  1957. end if
  1958. end do
  1959. end subroutine get_max_categories
  1960. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1961. ! Name: get_source_categories
  1962. !
  1963. ! Purpose: Return the min and max category for the source data for fieldname
  1964. ! at a specified priority level (compared with the min/max category over
  1965. ! all priority levels, as given by get_max_categories).
  1966. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1967. subroutine get_source_categories(fieldnm, ilevel, min_category, max_category, istatus)
  1968. implicit none
  1969. ! Arguments
  1970. integer, intent(in) :: ilevel
  1971. integer, intent(out) :: min_category, max_category, istatus
  1972. character (len=128), intent(in) :: fieldnm
  1973. ! Local variables
  1974. integer :: idx
  1975. istatus = 1
  1976. do idx=1,num_entries
  1977. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  1978. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  1979. if (ilevel == source_priority(idx)) then
  1980. if (is_category_min(idx) .and. is_category_max(idx)) then
  1981. istatus = 0
  1982. min_category = source_category_min(idx)
  1983. max_category = source_category_max(idx)
  1984. else if (is_category_min(idx) .or. is_category_max(idx)) then
  1985. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of min_category '// &
  1986. 'and max_category specified for entry %i.',i1=idx)
  1987. end if
  1988. end if
  1989. end if
  1990. end do
  1991. end subroutine get_source_categories
  1992. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1993. ! Name: get_domcategory_name
  1994. !
  1995. ! Purpose:
  1996. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1997. subroutine get_domcategory_name(fieldnm, domcat_name, ldominant_only, istatus)
  1998. implicit none
  1999. ! Arguments
  2000. integer, intent(out) :: istatus
  2001. logical, intent(out) :: ldominant_only
  2002. character (len=128), intent(in) :: fieldnm
  2003. character (len=128), intent(out) :: domcat_name
  2004. ! Local variables
  2005. integer :: idx
  2006. istatus = 1
  2007. ldominant_only = .false.
  2008. do idx=1,num_entries
  2009. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2010. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2011. if (is_dominant_category(idx)) then
  2012. domcat_name = source_dominant_category(idx)
  2013. istatus = 0
  2014. if (is_dominant_only(idx)) then
  2015. call mprintf(.true., WARN, 'In GEOGRID.TBL, both dominant_category and '// &
  2016. 'dominant_only are specified in entry %i. Using specification '// &
  2017. 'for dominant_category.',i1=idx)
  2018. is_dominant_only(idx) = .false.
  2019. end if
  2020. exit
  2021. else if (is_dominant_only(idx)) then
  2022. domcat_name = source_dominant_only(idx)
  2023. ldominant_only = .true.
  2024. istatus = 0
  2025. exit
  2026. end if
  2027. end if
  2028. end do
  2029. end subroutine get_domcategory_name
  2030. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2031. ! Name: get_dfdx_name
  2032. !
  2033. ! Purpose:
  2034. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2035. subroutine get_dfdx_name(fieldnm, dfdx_name, istatus)
  2036. implicit none
  2037. ! Arguments
  2038. integer, intent(out) :: istatus
  2039. character (len=128), intent(in) :: fieldnm
  2040. character (len=128), intent(out) :: dfdx_name
  2041. ! Local variables
  2042. integer :: idx
  2043. istatus = 1
  2044. do idx=1,num_entries
  2045. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2046. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2047. if (is_dfdx(idx)) then
  2048. dfdx_name = source_dfdx(idx)
  2049. istatus = 0
  2050. exit
  2051. end if
  2052. end if
  2053. end do
  2054. end subroutine get_dfdx_name
  2055. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2056. ! Name: get_dfdy_name
  2057. !
  2058. ! Purpose:
  2059. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2060. subroutine get_dfdy_name(fieldnm, dfdy_name, istatus)
  2061. implicit none
  2062. ! Arguments
  2063. integer, intent(out) :: istatus
  2064. character (len=128), intent(in) :: fieldnm
  2065. character (len=128), intent(out) :: dfdy_name
  2066. ! Local variables
  2067. integer :: idx
  2068. istatus = 1
  2069. do idx=1,num_entries
  2070. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2071. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2072. if (is_dfdy(idx)) then
  2073. dfdy_name = source_dfdy(idx)
  2074. istatus = 0
  2075. exit
  2076. end if
  2077. end if
  2078. end do
  2079. end subroutine get_dfdy_name
  2080. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2081. ! Name: get_z_dim_name
  2082. !
  2083. ! Purpose:
  2084. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2085. subroutine get_z_dim_name(fieldnm, z_dim, istatus)
  2086. implicit none
  2087. ! Arguments
  2088. integer, intent(out) :: istatus
  2089. character (len=128), intent(in) :: fieldnm
  2090. character (len=128), intent(out) :: z_dim
  2091. ! Local variables
  2092. integer :: idx
  2093. istatus = 1
  2094. do idx=1,num_entries
  2095. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2096. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2097. if (is_z_dim_name(idx)) then
  2098. z_dim = source_z_dim_name(idx)
  2099. istatus = 0
  2100. exit
  2101. end if
  2102. end if
  2103. end do
  2104. end subroutine get_z_dim_name
  2105. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2106. ! Name: get_field_scale_factor
  2107. !
  2108. ! Purpose:
  2109. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2110. subroutine get_field_scale_factor(fieldnm, ilevel, scale_factor, istatus)
  2111. implicit none
  2112. ! Arguments
  2113. integer, intent(in) :: ilevel
  2114. integer, intent(out) :: istatus
  2115. real, intent(out) :: scale_factor
  2116. character (len=128), intent(in) :: fieldnm
  2117. ! Local variables
  2118. integer :: idx
  2119. istatus = 1
  2120. do idx=1,num_entries
  2121. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2122. (len_trim(source_fieldname(idx)) == len_trim(fieldnm)) .and. &
  2123. (ilevel == source_priority(idx))) then
  2124. if (is_scale_factor(idx)) then
  2125. scale_factor = source_scale_factor(idx)
  2126. istatus = 0
  2127. end if
  2128. end if
  2129. end do
  2130. end subroutine get_field_scale_factor
  2131. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2132. ! Name: get_output_stagger
  2133. !
  2134. ! Pupose:
  2135. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2136. subroutine get_output_stagger(fieldnm, istagger, istatus)
  2137. use gridinfo_module
  2138. implicit none
  2139. ! Arguments
  2140. integer, intent(out) :: istatus, istagger
  2141. character (len=128), intent(in) :: fieldnm
  2142. ! Local variables
  2143. integer :: idx
  2144. istatus = 1
  2145. do idx=1,num_entries
  2146. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2147. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2148. if (is_output_stagger(idx)) then
  2149. istatus = 0
  2150. istagger = source_output_stagger(idx)
  2151. exit
  2152. else
  2153. if (gridtype == 'C') then
  2154. istatus = 0
  2155. istagger = M
  2156. exit
  2157. else if (gridtype == 'E') then
  2158. istatus = 0
  2159. istagger = HH
  2160. exit
  2161. end if
  2162. end if
  2163. end if
  2164. end do
  2165. end subroutine get_output_stagger
  2166. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2167. ! Name: get_subgrid_dim_name
  2168. !
  2169. ! Pupose:
  2170. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2171. logical function is_subgrid_var(field_name)
  2172. use gridinfo_module
  2173. implicit none
  2174. character(len=128), intent(in) :: field_name
  2175. integer :: idx, nlen
  2176. is_subgrid_var=.false.
  2177. if (((index(trim(field_name),'FXLAT') /= 0) .and. &
  2178. (len_trim(field_name) == len_trim('FXLAT'))) .or. &
  2179. ((index(trim(field_name),'FXLONG') /= 0) .and. &
  2180. (len_trim(field_name) == len_trim('FXLONG'))))then
  2181. is_subgrid_var=.true.
  2182. else
  2183. do idx=1,num_entries
  2184. if ((index(source_fieldname(idx),trim(field_name)) /= 0) .and. &
  2185. (len_trim(source_fieldname(idx)) == len_trim(field_name))) then
  2186. if (is_subgrid(idx)) is_subgrid_var=.true.
  2187. goto 110
  2188. end if
  2189. end do
  2190. end if
  2191. 110 continue
  2192. end function is_subgrid_var
  2193. subroutine get_subgrid_dim_name(dimnames)
  2194. implicit none
  2195. character(len=128),dimension(2),intent(out)::dimnames
  2196. dimnames(1)='west_east_subgrid'
  2197. dimnames(2)='south_north_subgrid'
  2198. end subroutine get_subgrid_dim_name
  2199. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2200. ! Name: get_interp_option
  2201. !
  2202. ! Pupose:
  2203. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2204. subroutine get_interp_option(fieldnm, ilevel, interp_opt, istatus)
  2205. implicit none
  2206. ! Arguments
  2207. integer, intent(in) :: ilevel
  2208. integer, intent(out) :: istatus
  2209. character (len=128), intent(in) :: fieldnm
  2210. character (len=128), intent(out) :: interp_opt
  2211. ! Local variables
  2212. integer :: idx
  2213. istatus = 1
  2214. do idx=1,num_entries
  2215. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2216. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2217. if (ilevel == source_priority(idx)) then
  2218. interp_opt = source_interp_string(idx)
  2219. istatus = 0
  2220. exit
  2221. end if
  2222. end if
  2223. end do
  2224. end subroutine get_interp_option
  2225. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2226. ! Name: get_gcel_threshold
  2227. !
  2228. ! Pupose:
  2229. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2230. subroutine get_gcell_threshold(interp_opt, threshold, istatus)
  2231. implicit none
  2232. ! Arguments
  2233. integer, intent(out) :: istatus
  2234. real, intent(out) :: threshold
  2235. character (len=128), intent(in) :: interp_opt
  2236. ! Local variables
  2237. integer :: i, p1, p2
  2238. istatus = 1
  2239. threshold = 1.0
  2240. i = index(interp_opt,'average_gcell')
  2241. if (i /= 0) then
  2242. ! Move the "average_gcell" option to the beginning
  2243. ! if (i /= 1) then
  2244. ! p1 =
  2245. ! end if
  2246. ! Check for a threshold
  2247. p1 = index(interp_opt(i:128),'(')
  2248. p2 = index(interp_opt(i:128),')')
  2249. if (p1 /= 0 .and. p2 /= 0) then
  2250. read(interp_opt(p1+1:p2-1),*,err=1000) threshold
  2251. else
  2252. call mprintf(.true., WARN, 'Problem with specified threshold '// &
  2253. 'for average_gcell interp option. Setting threshold to 0.0.')
  2254. threshold = 0.0
  2255. end if
  2256. end if
  2257. istatus = 0
  2258. return
  2259. 1000 call mprintf(.true., ERROR, 'Threshold option to average_gcell interpolator '// &
  2260. 'must be a real number, enclosed in parentheses immediately '// &
  2261. 'after keyword "average_gcell"')
  2262. end subroutine get_gcell_threshold
  2263. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2264. ! Name: get_smooth_option
  2265. !
  2266. ! Pupose:
  2267. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2268. subroutine get_smooth_option(fieldnm, smooth_opt, smooth_passes, istatus)
  2269. implicit none
  2270. ! Arguments
  2271. integer, intent(out) :: istatus, smooth_opt, smooth_passes
  2272. character (len=128), intent(in) :: fieldnm
  2273. ! Local variables
  2274. integer :: idx
  2275. istatus = 1
  2276. do idx=1,num_entries
  2277. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2278. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2279. if (is_smooth_option(idx)) then
  2280. istatus = 0
  2281. smooth_opt = source_smooth_option(idx)
  2282. if (is_smooth_passes(idx)) then
  2283. smooth_passes = source_smooth_passes(idx)
  2284. else
  2285. smooth_passes = 1
  2286. end if
  2287. exit
  2288. end if
  2289. end if
  2290. end do
  2291. end subroutine get_smooth_option
  2292. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2293. ! Name: iget_fieldtype
  2294. !
  2295. ! Purpose:
  2296. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2297. function iget_fieldtype(fieldnm, istatus)
  2298. implicit none
  2299. ! Arguments
  2300. integer, intent(out) :: istatus
  2301. character (len=128), intent(in) :: fieldnm
  2302. ! Local variables
  2303. integer :: idx
  2304. ! Return value
  2305. integer :: iget_fieldtype
  2306. istatus = 1
  2307. do idx=1,num_entries
  2308. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2309. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2310. if (is_dest_fieldtype(idx)) then
  2311. iget_fieldtype = source_dest_fieldtype(idx)
  2312. istatus = 0
  2313. exit
  2314. end if
  2315. end if
  2316. end do
  2317. end function iget_fieldtype
  2318. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2319. ! Name: iget_source_fieldtype
  2320. !
  2321. ! Purpose: Given a resolution, in degrees, and the name of a field, this
  2322. ! function returns the type (categorical, continuous, etc.) of the source
  2323. ! data that will be used. This may, in general, depend on the field name
  2324. ! and the resolution; for example, near 30 second resolution, land use data
  2325. ! may come from a categorical field, whereas for lower resolutions, it may
  2326. ! come from arrays of land use fractions for each category.
  2327. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2328. function iget_source_fieldtype(fieldnm, ilevel, istatus)
  2329. implicit none
  2330. ! Arguments
  2331. integer, intent(in) :: ilevel
  2332. integer, intent(out) :: istatus
  2333. character (len=128), intent(in) :: fieldnm
  2334. ! Return value
  2335. integer :: iget_source_fieldtype
  2336. ! Local variables
  2337. integer :: idx
  2338. ! Find information about the source tiles for the specified fieldname
  2339. istatus = 1
  2340. do idx=1,num_entries
  2341. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2342. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2343. if (ilevel == source_priority(idx)) then
  2344. istatus = 0
  2345. iget_source_fieldtype = source_fieldtype(idx)
  2346. exit
  2347. end if
  2348. end if
  2349. end do
  2350. end function iget_source_fieldtype
  2351. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2352. ! Name: get_data_tile
  2353. !
  2354. ! Purpose:
  2355. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2356. subroutine get_data_tile(xlat, xlon, ilevel, field_name, &
  2357. file_name, array, start_x_dim, end_x_dim, start_y_dim, &
  2358. end_y_dim, start_z_dim, end_z_dim, npts_bdr, &
  2359. istatus)
  2360. #ifdef _HAS_GEOTIFF
  2361. use geotiff_module, only : read_geogrid_tile
  2362. #endif
  2363. implicit none
  2364. ! Arguments
  2365. integer, intent(in) :: ilevel
  2366. integer, intent(out) :: istatus
  2367. integer, intent(out) :: start_x_dim, end_x_dim, &
  2368. start_y_dim, end_y_dim, &
  2369. start_z_dim, end_z_dim, &
  2370. npts_bdr
  2371. real, intent(in) :: xlat, xlon ! Location that tile should contain
  2372. real, pointer, dimension(:,:,:) :: array ! The array to be allocated by this routine
  2373. character (len=128), intent(in) :: field_name
  2374. character (len=256), intent(out) :: file_name
  2375. ! Local variables
  2376. integer :: j, k
  2377. integer :: local_wordsize, local_endian, sign_convention, irow_order, strlen
  2378. integer :: xdim,ydim,zdim
  2379. real :: scalefac
  2380. real, allocatable, dimension(:) :: temprow
  2381. logical :: geotiff
  2382. character(len=256) :: gtiff_file
  2383. geotiff=is_geotiff_file(field_name,ilevel)
  2384. call get_tile_fname(file_name, xlat, xlon, ilevel, field_name, istatus)
  2385. if (.not.geotiff .and. index(file_name, 'OUTSIDE') /= 0) then
  2386. istatus = 1
  2387. return
  2388. else if (hash_search(bad_files, file_name)) then
  2389. istatus = 1
  2390. return
  2391. end if
  2392. call get_tile_dimensions(xlat, xlon, start_x_dim, end_x_dim, start_y_dim, end_y_dim, &
  2393. start_z_dim, end_z_dim, npts_bdr, local_wordsize, local_endian, &
  2394. sign_convention, ilevel, field_name, istatus)
  2395. xdim = (end_x_dim-start_x_dim+1)
  2396. ydim = (end_y_dim-start_y_dim+1)
  2397. zdim = (end_z_dim-start_z_dim+1)
  2398. if (associated(array)) deallocate(array)
  2399. allocate(array(xdim,ydim,zdim))
  2400. call get_row_order(field_name, ilevel, irow_order, istatus)
  2401. if (istatus /= 0) irow_order = BOTTOM_TOP
  2402. call s_len(file_name,strlen)
  2403. scalefac = 1.0
  2404. if(geotiff) then
  2405. #ifdef _HAS_GEOTIFF
  2406. call get_geotiff_filename(field_name,ilevel,gtiff_file,istatus)
  2407. if(istatus.ne.0)then
  2408. call mprintf(.true.,ERROR,"Could not find geotiff file for "// &
  2409. TRIM(field_name))
  2410. endif
  2411. call read_geogrid_tile(gtiff_file,start_x_dim,end_x_dim, &
  2412. start_y_dim,end_y_dim, &
  2413. start_z_dim,end_z_dim,array,istatus)
  2414. #else
  2415. call mprintf(.true.,ERROR,"GEOTIFF file specified for %s, but geogrid not "// &
  2416. "compiled with geotiff support.",s1=trim(field_name))
  2417. #endif
  2418. else
  2419. call read_geogrid(file_name, strlen, array, xdim, ydim, zdim, &
  2420. sign_convention, local_endian, scalefac, local_wordsize, istatus)
  2421. endif
  2422. if (irow_order == TOP_BOTTOM) then
  2423. allocate(temprow(xdim))
  2424. do k=1,zdim
  2425. do j=1,ydim
  2426. if (ydim-j+1 <= j) exit
  2427. temprow(1:xdim) = array(1:xdim,j,k)
  2428. array(1:xdim,j,k) = array(1:xdim,ydim-j+1,k)
  2429. array(1:xdim,ydim-j+1,k) = temprow(1:xdim)
  2430. end do
  2431. end do
  2432. deallocate(temprow)
  2433. end if
  2434. if (istatus /= 0) then
  2435. start_x_dim = INVALID
  2436. start_y_dim = INVALID
  2437. end_x_dim = INVALID
  2438. end_y_dim = INVALID
  2439. call hash_insert(bad_files, file_name)
  2440. end if
  2441. end subroutine get_data_tile
  2442. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2443. ! Name: get_row_order
  2444. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2445. subroutine get_row_order(fieldnm, ilevel, irow_order, istatus)
  2446. implicit none
  2447. ! Arguments
  2448. integer, intent(in) :: ilevel
  2449. character (len=128), intent(in) :: fieldnm
  2450. integer, intent(out) :: irow_order, istatus
  2451. ! Local variables
  2452. integer :: idx
  2453. istatus = 1
  2454. do idx=1,num_entries
  2455. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2456. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2457. if (ilevel == source_priority(idx)) then
  2458. if (is_row_order(idx)) then
  2459. irow_order = source_row_order(idx)
  2460. istatus = 0
  2461. exit
  2462. end if
  2463. end if
  2464. end if
  2465. end do
  2466. end subroutine get_row_order
  2467. logical function is_geotiff_file(fieldname,ilevel)
  2468. implicit none
  2469. character(len=*),intent(in)::fieldname
  2470. integer,intent(in)::ilevel
  2471. integer::idx
  2472. is_geotiff_file=.false.
  2473. do idx=1,num_entries
  2474. if ((index(source_fieldname(idx),trim(fieldname)) /= 0) .and. &
  2475. (len_trim(source_fieldname(idx)) == len_trim(fieldname)) .and. &
  2476. (ilevel == source_priority(idx))) then
  2477. is_geotiff_file = is_geotiff(idx)
  2478. exit
  2479. endif
  2480. enddo
  2481. end function is_geotiff_file
  2482. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2483. ! Name: get_tile_dimensions
  2484. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2485. subroutine get_tile_dimensions(xlat, xlon, start_x_dim, end_x_dim, start_y_dim, end_y_dim, &
  2486. start_z_dim, end_z_dim, npts_bdr, bytes_per_datum, endianness, &
  2487. sign_convention, ilevel, fieldnm, istatus)
  2488. use llxy_module
  2489. implicit none
  2490. ! Arguments
  2491. integer, intent(in) :: ilevel
  2492. integer, intent(out) :: start_x_dim, end_x_dim, &
  2493. start_y_dim, end_y_dim, &
  2494. start_z_dim, end_z_dim, &
  2495. npts_bdr, &
  2496. bytes_per_datum, endianness, &
  2497. sign_convention, istatus
  2498. real, intent(in) :: xlat, xlon
  2499. character (len=128), intent(in) :: fieldnm
  2500. ! Local variables
  2501. integer :: idx, current_domain
  2502. real :: rx, ry
  2503. istatus = 1
  2504. do idx=1,num_entries
  2505. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2506. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2507. if (ilevel == source_priority(idx)) then
  2508. istatus = 0
  2509. exit
  2510. end if
  2511. end if
  2512. end do
  2513. if (istatus /= 0) then
  2514. start_x_dim = 1
  2515. start_y_dim = 1
  2516. start_z_dim = 1
  2517. end_x_dim = 1
  2518. end_y_dim = 1
  2519. end_z_dim = 1
  2520. bytes_per_datum = 0
  2521. return
  2522. end if
  2523. current_domain = iget_selected_domain()
  2524. call select_domain(SOURCE_PROJ)
  2525. call lltoxy(xlat, xlon, rx, ry, M)
  2526. call select_domain(current_domain)
  2527. start_x_dim = source_tile_x(idx) * nint(real(floor((rx-0.5) / real(source_tile_x(idx))))) + 1
  2528. end_x_dim = start_x_dim + source_tile_x(idx) - 1
  2529. start_y_dim = source_tile_y(idx) * nint(real(floor((ry-0.5) / real(source_tile_y(idx))))) + 1
  2530. end_y_dim = start_y_dim + source_tile_y(idx) - 1
  2531. if (is_tile_z_start(idx) .and. is_tile_z_end(idx)) then
  2532. start_z_dim = source_tile_z_start(idx)
  2533. end_z_dim = source_tile_z_end(idx)
  2534. else if (is_tile_z(idx)) then
  2535. start_z_dim = 1
  2536. end_z_dim = source_tile_z(idx)
  2537. end if
  2538. if (.not. (is_tile_z_start(idx) .and. is_tile_z_end(idx))) then
  2539. if (is_tile_z_start(idx) .or. is_tile_z_end(idx)) then
  2540. call mprintf(.true., ERROR, 'In GEOGRID.TBL, only one of tile_z_start and '// &
  2541. 'tile_z_end specified for entry %i.',i1=idx)
  2542. end if
  2543. end if
  2544. if (is_tile_bdr(idx)) then
  2545. npts_bdr = source_tile_bdr(idx)
  2546. else
  2547. npts_bdr = 0
  2548. end if
  2549. start_x_dim = start_x_dim - npts_bdr
  2550. end_x_dim = end_x_dim + npts_bdr
  2551. start_y_dim = start_y_dim - npts_bdr
  2552. end_y_dim = end_y_dim + npts_bdr
  2553. if (is_wordsize(idx)) then
  2554. bytes_per_datum = source_wordsize(idx)
  2555. else
  2556. bytes_per_datum = 1
  2557. call mprintf(.true.,ERROR,'In GEOGRID.TBL, no wordsize specified for data in entry %i.',i1=idx)
  2558. end if
  2559. if (is_endian(idx)) then
  2560. endianness = source_endian(idx)
  2561. else
  2562. endianness = BIG_ENDIAN
  2563. end if
  2564. if (is_signed(idx)) then
  2565. sign_convention = 1
  2566. else
  2567. sign_convention = 0
  2568. end if
  2569. end subroutine get_tile_dimensions
  2570. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2571. ! Name: get_tile_fname
  2572. !
  2573. ! Purpose:
  2574. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2575. subroutine get_tile_fname(test_fname, xlat, xlon, ilevel, fieldname, istatus)
  2576. use llxy_module
  2577. use gridinfo_module
  2578. implicit none
  2579. ! Arguments
  2580. integer, intent(in) :: ilevel
  2581. integer, intent(out) :: istatus
  2582. real, intent(in) :: xlat, xlon
  2583. character (len=*), intent(in) :: fieldname
  2584. character (len=256), intent(out) :: test_fname
  2585. ! Local variables
  2586. integer :: current_domain, idx
  2587. real :: rx, ry
  2588. istatus = 1
  2589. write(test_fname, '(a)') 'TILE.OUTSIDE.DOMAIN'
  2590. do idx=1,num_entries
  2591. if ((index(source_fieldname(idx),trim(fieldname)) /= 0) .and. &
  2592. (len_trim(source_fieldname(idx)) == len_trim(fieldname))) then
  2593. if (ilevel == source_priority(idx)) then
  2594. istatus = 0
  2595. exit
  2596. end if
  2597. end if
  2598. end do
  2599. if (istatus /= 0) return
  2600. current_domain = iget_selected_domain()
  2601. call select_domain(SOURCE_PROJ)
  2602. call lltoxy(xlat, xlon, rx, ry, M)
  2603. call select_domain(current_domain)
  2604. ! rx = real(source_tile_x(idx)) * real(floor((rx-0.5*source_dx(idx))/ real(source_tile_x(idx)))) + 1.0
  2605. ! ry = real(source_tile_y(idx)) * real(floor((ry-0.5*source_dy(idx))/ real(source_tile_y(idx)))) + 1.0
  2606. rx = real(source_tile_x(idx)) * real(floor((rx-0.5) / real(source_tile_x(idx)))) + 1.0
  2607. ry = real(source_tile_y(idx)) * real(floor((ry-0.5) / real(source_tile_y(idx)))) + 1.0
  2608. if (rx > 0. .and. ry > 0. .and. &
  2609. nint(rx)+source_tile_x(idx)-1 < 100000 .and. &
  2610. nint(ry)+source_tile_y(idx)-1 < 100000) then
  2611. write(test_fname, '(a,i5.5,a1,i5.5,a1,i5.5,a1,i5.5)') trim(source_path(idx)), &
  2612. nint(rx),'-',nint(rx)+source_tile_x(idx)-1,'.',nint(ry),'-',nint(ry)+source_tile_y(idx)-1
  2613. else
  2614. write(test_fname,'(a,i10,a1,i10,a1,i10,a1,i10)') trim(source_path(idx)), &
  2615. nint(rx),'-',nint(rx)+source_tile_x(idx)-1,'.',nint(ry),'-',nint(ry)+source_tile_y(idx)-1
  2616. endif
  2617. end subroutine get_tile_fname
  2618. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2619. ! Name: get_source_resolution
  2620. !
  2621. ! Purpose:
  2622. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2623. subroutine get_source_resolution(fieldnm, ilevel, src_dx, src_dy, istatus)
  2624. implicit none
  2625. ! Arguments
  2626. integer, intent(in) :: ilevel
  2627. integer, intent(out) :: istatus
  2628. real, intent(out) :: src_dx, src_dy
  2629. character (len=*), intent(in) :: fieldnm
  2630. ! Local variables
  2631. integer :: idx
  2632. istatus = 1
  2633. do idx=1,num_entries
  2634. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2635. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2636. if (ilevel == source_priority(idx)) then
  2637. if (is_dx(idx) .and. is_dy(idx)) then
  2638. src_dx = source_dx(idx)
  2639. src_dy = source_dy(idx)
  2640. if (source_proj(idx) /= PROJ_LATLON) then
  2641. src_dx = src_dx / 111000.
  2642. src_dy = src_dy / 111000.
  2643. end if
  2644. istatus = 0
  2645. exit
  2646. end if
  2647. end if
  2648. end if
  2649. end do
  2650. end subroutine get_source_resolution
  2651. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2652. ! Name: get_data_projection
  2653. !
  2654. ! Purpose: To acquire the parameters necessary in defining the grid on which
  2655. ! the user-specified data for field 'fieldnm' are given.
  2656. !
  2657. ! NOTES: If the routine successfully acquires values for all necessary
  2658. ! parameters, istatus is set to 0. In case of an error,
  2659. ! OR IF THE USER HAS NOT SPECIFIED A TILE OF DATA FOR FIELDNM,
  2660. ! istatus is set to 1.
  2661. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2662. subroutine get_data_projection(fieldnm, iproj, stand_lon, truelat1, truelat2, &
  2663. dxkm, dykm, known_x, known_y, known_lat, known_lon, ilevel, istatus)
  2664. implicit none
  2665. ! Arguments
  2666. integer, intent(in) :: ilevel
  2667. integer, intent(out) :: iproj, istatus
  2668. real, intent(out) :: stand_lon, truelat1, truelat2, dxkm, dykm, &
  2669. known_x, known_y, known_lat, known_lon
  2670. character (len=*), intent(in) :: fieldnm
  2671. ! Local variables
  2672. integer :: idx
  2673. istatus = 1
  2674. do idx=1,num_entries
  2675. if ((index(source_fieldname(idx),trim(fieldnm)) /= 0) .and. &
  2676. (len_trim(source_fieldname(idx)) == len_trim(fieldnm))) then
  2677. if (ilevel == source_priority(idx)) then
  2678. istatus = 0
  2679. if (is_proj(idx)) then
  2680. iproj = source_proj(idx)
  2681. else
  2682. iproj = 1
  2683. call mprintf(.true., ERROR, &
  2684. 'In GEOGRID.TBL, no specification for projection in entry %i.',i1=idx)
  2685. end if
  2686. if (is_known_x(idx)) then
  2687. known_x = source_known_x(idx)
  2688. else
  2689. known_x = 1.
  2690. call mprintf(.true., ERROR, &
  2691. 'In GEOGRID.TBL, no specification for known_x in entry %i.',i1=idx)
  2692. end if
  2693. if (is_known_y(idx)) then
  2694. known_y = source_known_y(idx)
  2695. else
  2696. known_y = 1.
  2697. call mprintf(.true., ERROR, &
  2698. 'In GEOGRID.TBL, no specification for known_y in entry %i.',i1=idx)
  2699. end if
  2700. if (is_known_lat(idx)) then
  2701. known_lat = source_known_lat(idx)
  2702. else
  2703. known_lat = 1.
  2704. call mprintf(.true., ERROR, &
  2705. 'In GEOGRID.TBL, no specification for known_lat in entry %i.',i1=idx)
  2706. end if
  2707. if (is_known_lon(idx)) then
  2708. known_lon = source_known_lon(idx)
  2709. else
  2710. known_lon = 1.
  2711. call mprintf(.true., ERROR, &
  2712. 'In GEOGRID.TBL, no specification for known_lon in entry %i.',i1=idx)
  2713. end if
  2714. if (is_truelat1(idx)) then
  2715. truelat1 = source_truelat1(idx)
  2716. else if (is_proj(idx) .and. source_proj(idx) /= PROJ_LATLON) then
  2717. truelat1 = 1.
  2718. call mprintf(.true., WARN, &
  2719. 'In GEOGRID.TBL, no specification for truelat1 in entry %i.',i1=idx)
  2720. end if
  2721. if (is_truelat2(idx)) then
  2722. truelat2 = source_truelat2(idx)
  2723. else if (is_proj(idx) .and. source_proj(idx) /= PROJ_LATLON) then
  2724. truelat2 = 1.
  2725. call mprintf(.true., WARN, &
  2726. 'In GEOGRID.TBL, no specification for truelat2 in entry %i.',i1=idx)
  2727. end if
  2728. if (is_stdlon(idx)) then
  2729. stand_lon = source_stdlon(idx)
  2730. else if (is_proj(idx) .and. source_proj(idx) /= PROJ_LATLON) then
  2731. stand_lon = 1.
  2732. call mprintf(.true., WARN, &
  2733. 'In GEOGRID.TBL, no specification for stdlon in entry %i.',i1=idx)
  2734. end if
  2735. if (is_dx(idx)) then
  2736. dxkm = source_dx(idx)
  2737. else
  2738. dxkm = 1.
  2739. call mprintf(.true., ERROR, &
  2740. 'In GEOGRID.TBL, no specification for dx in entry %i.',i1=idx)
  2741. end if
  2742. if (is_dy(idx)) then
  2743. dykm = source_dy(idx)
  2744. else
  2745. dykm = 1.
  2746. call mprintf(.true., ERROR, &
  2747. 'In GEOGRID.TBL, no specification for dy in entry %i.',i1=idx)
  2748. end if
  2749. exit
  2750. end if
  2751. end if
  2752. end do
  2753. end subroutine get_data_projection
  2754. subroutine get_geotiff_filename(field_name,ilevel,file_name,istatus)
  2755. implicit none
  2756. character(len=*),intent(in)::field_name
  2757. integer,intent(in)::ilevel
  2758. character(len=*),intent(out)::file_name
  2759. integer,intent(out)::istatus
  2760. integer::idx
  2761. istatus=1
  2762. do idx=1,num_entries
  2763. if ((index(source_fieldname(idx),trim(field_name)) /= 0) .and. &
  2764. (len_trim(source_fieldname(idx)) == len_trim(field_name))) then
  2765. if (ilevel == source_priority(idx)) then
  2766. if (is_geotiff(idx)) then
  2767. file_name=trim(source_geotiff_file(idx))
  2768. istatus = 0
  2769. exit
  2770. end if
  2771. end if
  2772. end if
  2773. end do
  2774. end subroutine get_geotiff_filename
  2775. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2776. ! Name: check_data_specification
  2777. !
  2778. ! Purpose: To check for obvious errors in the user source data specifications.
  2779. ! Returns .true. if specification passes all checks, and .false. otherwise.
  2780. ! For failing checks, diagnostic messages are printed.
  2781. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2782. function check_data_specification( )
  2783. implicit none
  2784. ! Return value
  2785. logical :: check_data_specification
  2786. ! Local variables
  2787. integer :: i, j, istatus
  2788. integer, pointer, dimension(:) :: priorities
  2789. real :: rmissing
  2790. logical :: begin_priority, halt
  2791. character (len=128) :: cur_name
  2792. check_data_specification = .false.
  2793. ! Check that each specification has a name, priority level, and path
  2794. do i=1,num_entries
  2795. if (.not. is_fieldname(i)) then
  2796. call mprintf(.true., ERROR, &
  2797. 'In GEOGRID.TBL, specification %i does not have a name.',i1=i)
  2798. end if
  2799. if (.not. is_priority(i)) then
  2800. call mprintf(.true., ERROR, &
  2801. 'In GEOGRID.TBL, specification %i does not have a priority.',i1=i)
  2802. end if
  2803. if (list_length(source_res_path(i)) == 0) then
  2804. call mprintf(.true., ERROR, &
  2805. 'In GEOGRID.TBL, no path (relative or absolute) is specified '// &
  2806. 'for entry %i.',i1=i)
  2807. end if
  2808. end do
  2809. ! The fill_missing and halt_on_missing options are mutually exclusive
  2810. do i=1,num_entries
  2811. call get_halt_on_missing(source_fieldname(i), halt, istatus)
  2812. call get_missing_fill_value(source_fieldname(i), rmissing, istatus)
  2813. if (halt .and. (istatus == 0)) then
  2814. call mprintf(.true., ERROR, 'In GEOGRID.TBL, the halt_on_missing and fill_missing '// &
  2815. 'options are mutually exclusive, but both are given for field %s', &
  2816. s1=trim(source_fieldname(i)))
  2817. end if
  2818. end do
  2819. ! Check that the field from which landmask is calculated is not output on a staggering
  2820. do i=1,num_entries
  2821. if (list_length(source_landmask_land(i)) > 0 .or. list_length(source_landmask_water(i)) > 0) then
  2822. if (is_output_stagger(i)) then
  2823. if (source_output_stagger(i) /= M) then
  2824. call mprintf(.true., ERROR, 'In GEOGRID.TBL, landmask cannot be derived from '// &
  2825. 'a field that is computed on a staggered grid at entry %i.',i1=i)
  2826. end if
  2827. end if
  2828. end if
  2829. end do
  2830. ! Also check that any field that is to be masked by the landmask is not output on a staggering
  2831. do i=1,num_entries
  2832. if (is_masked(i) .and. is_output_stagger(i)) then
  2833. if (source_output_stagger(i) /= M) then
  2834. call mprintf(.true., ERROR, 'In GEOGRID.TBL, landmask cannot be used with '// &
  2835. 'a field that is computed on a staggered grid at entry %i.',i1=i)
  2836. end if
  2837. end if
  2838. end do
  2839. allocate(priorities(num_entries))
  2840. ! Now check that priorities for each source are unique and in the interval [1,n], n <= num_entries
  2841. do i=1,num_entries
  2842. priorities = 0
  2843. cur_name = source_fieldname(i)
  2844. do j=1,num_entries
  2845. if (source_fieldname(j) == cur_name) then
  2846. if (source_priority(j) > num_entries .or. source_priority(j) < 1) then
  2847. call mprintf(.true., ERROR, 'In GEOGRID.TBL, priorities for %s do not '// &
  2848. 'form a sequence 1,2,...,n.', s1=trim(cur_name))
  2849. else
  2850. if (priorities(source_priority(j)) == 1) then
  2851. call mprintf(.true., ERROR, 'In GEOGRID.TBL, more than one entry for %s '// &
  2852. 'has priority %i.', s1=trim(cur_name), i1=source_priority(j))
  2853. else
  2854. priorities(source_priority(j)) = 1
  2855. end if
  2856. end if
  2857. end if
  2858. end do
  2859. begin_priority = .false.
  2860. do j=num_entries,1,-1
  2861. if (.not.begin_priority .and. priorities(j) == 1) then
  2862. begin_priority = .true.
  2863. else if (begin_priority .and. priorities(j) == 0) then
  2864. call mprintf(.true., ERROR, 'In GEOGRID.TBL, no entry for %s has '// &
  2865. 'priority %i, but an entry has priority %i.', &
  2866. s1=trim(cur_name), i1=j, i2=j+1)
  2867. end if
  2868. end do
  2869. end do
  2870. deallocate(priorities)
  2871. ! Units must match for all priority levels of a field
  2872. do i=1,num_entries
  2873. if (source_priority(i) == 1) then
  2874. do j=1,num_entries
  2875. if ((source_fieldname(i) == source_fieldname(j)) .and. &
  2876. (source_units(i) /= source_units(j))) then
  2877. call mprintf(.true., ERROR, 'In GEOGRID.TBL, units for %s at entry %i '// &
  2878. 'do not match units at entry %i (%s)', &
  2879. s1=trim(source_fieldname(i)), i1=j, i2=i, s2=trim(source_units(i)))
  2880. end if
  2881. end do
  2882. end if
  2883. end do
  2884. ! Make sure that user has not asked to calculate landmask from a continuous field
  2885. do i=1,num_entries
  2886. if (is_dest_fieldtype(i)) then
  2887. if (source_dest_fieldtype(i) == CONTINUOUS) then
  2888. if (list_length(source_landmask_water(i)) > 0 .or. list_length(source_landmask_land(i)) > 0) then
  2889. call mprintf(.true., ERROR, 'In GEOGRID.TBL, landmask cannot be '// &
  2890. 'calculated from a continuous destination field at entry %i.',i1=i)
  2891. end if
  2892. end if
  2893. end if
  2894. end do
  2895. ! category min/max is not set in GEOGRID.TBL, where this subroutine is called... this causes
  2896. ! periodic crashes due to if's on unset memory
  2897. !
  2898. ! ! If either min_category or max_category is specified, then both must be specified
  2899. ! do i=1,num_entries
  2900. ! if (is_category_min(i) .or. is_category_max(i)) then
  2901. ! if (.not. is_category_min(i)) then
  2902. ! call mprintf(.true., ERROR, 'In GEOGRID.TBL, for index file of data at '// &
  2903. ! 'entry %i, category_max is specified, but category_min is '// &
  2904. ! 'not. Both must be specified.',i1=i)
  2905. ! else if (.not. is_category_max(i)) then
  2906. ! call mprintf(.true., ERROR, 'In GEOGRID.TBL, for index file of data at '// &
  2907. ! 'entry %i, category_min is specified, but category_max is '// &
  2908. ! 'not. Both must be specified.',i1=i)
  2909. ! end if
  2910. ! end if
  2911. ! end do
  2912. !
  2913. ! ! For continuous data, (category_max - category_min + 1) should equal tile_z
  2914. ! do i=1,num_entries
  2915. ! if (is_fieldtype(i)) then
  2916. ! if (source_fieldtype(i) == CONTINUOUS) then
  2917. ! if (is_category_max(i) .and. is_category_min(i) .and. is_tile_z(i)) then
  2918. ! if (source_tile_z(i) /= (source_category_max(i) - source_category_min(i) + 1)) then
  2919. ! call mprintf(.true., ERROR, 'In GEOGRID.TBL, tile_z must equal '// &
  2920. ! '(category_max - category_min + 1) at entry %i.',i1=i)
  2921. ! end if
  2922. ! else if (is_category_max(i) .and. is_category_min(i) .and. &
  2923. ! is_tile_z_start(i) .and. is_tile_z_end(i)) then
  2924. ! if (source_tile_z_end(i) /= source_category_max(i) .or. &
  2925. ! source_tile_z_start(i) /= source_category_min(i)) then
  2926. ! call mprintf(.true., ERROR, 'In GEOGRID.TBL, tile_z_end must equal '// &
  2927. ! 'category_max, and tile_z_start must equal category_min '// &
  2928. ! 'at entry %i.',i1=i)
  2929. ! end if
  2930. ! end if
  2931. ! end if
  2932. ! end if
  2933. ! end do
  2934. ! Make sure that user has not named a dominant category or computed slope field
  2935. ! the same as a fractional field
  2936. do i=1,num_entries
  2937. if (source_dominant_category(i) == source_fieldname(i)) then
  2938. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category cannot have '// &
  2939. 'the same name as the field at entry %i.',i1=i)
  2940. end if
  2941. do j=1,num_entries
  2942. if (.not. is_dominant_only(i)) then
  2943. if (is_dfdx(j)) then
  2944. if (source_dfdx(j) == source_fieldname(i)) then
  2945. call mprintf(.true., ERROR, 'In GEOGRID.TBL, field name at entry %i '// &
  2946. 'cannot have the same name as the slope field df_dx at entry %i.', &
  2947. i1=i, i2=j)
  2948. end if
  2949. end if
  2950. if (is_dfdy(j)) then
  2951. if (source_dfdy(j) == source_fieldname(i)) then
  2952. call mprintf(.true., ERROR, 'In GEOGRID.TBL, field name at entry %i '// &
  2953. 'cannot have the same name as the slope field df_dy at entry %i.', &
  2954. i1=i, i2=j)
  2955. end if
  2956. end if
  2957. if (is_dfdx(j) .and. is_dominant_category(i)) then
  2958. if (source_dfdx(j) == source_dominant_category(i)) then
  2959. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
  2960. 'entry %i cannot have the same name as the slope field df_dx '// &
  2961. 'at entry %i.',i1=i, i2=j)
  2962. end if
  2963. end if
  2964. if (is_dfdy(j) .and. is_dominant_category(i)) then
  2965. if (source_dfdy(j) == source_dominant_category(i)) then
  2966. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
  2967. 'entry %i cannot have the same name as the slope field '// &
  2968. 'df_dy at entry %i.',i1=i, i2=j)
  2969. end if
  2970. end if
  2971. else
  2972. if (is_dfdx(j)) then
  2973. if (source_dfdx(j) == source_dominant_only(i)) then
  2974. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
  2975. 'entry %i cannot have the same name as the slope field '// &
  2976. 'df_dx at entry %i.',i1=i, i2=j)
  2977. end if
  2978. end if
  2979. if (is_dfdy(j)) then
  2980. if (source_dfdy(j) == source_dominant_only(i)) then
  2981. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant field name at '// &
  2982. 'entry %i cannot have the same name as the slope field '// &
  2983. 'df_dy at entry %i.',i1=i, i2=j)
  2984. end if
  2985. end if
  2986. end if
  2987. if (i /= j) then
  2988. if (is_dfdx(i)) then
  2989. if (is_dfdx(j)) then
  2990. if (source_dfdx(j) == source_dfdx(i)) then
  2991. call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dx at '// &
  2992. 'entry %i cannot have the same name as the slope '// &
  2993. 'field df_dx at entry %i.',i1=i, i2=j)
  2994. end if
  2995. end if
  2996. if (is_dfdy(j)) then
  2997. if (source_dfdy(j) == source_dfdx(i)) then
  2998. call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dx at '// &
  2999. 'entry %i cannot have the same name as the slope field '// &
  3000. 'df_dy at entry %i.',i1=i, i2=j)
  3001. end if
  3002. end if
  3003. end if
  3004. if (is_dfdy(i)) then
  3005. if (is_dfdx(j)) then
  3006. if (source_dfdx(j) == source_dfdy(i)) then
  3007. call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dy at '// &
  3008. 'entry %i cannot have the same name as the slope field '// &
  3009. 'df_dx at entry %i.',i1=i, i2=j)
  3010. end if
  3011. end if
  3012. if (is_dfdy(j)) then
  3013. if (source_dfdy(j) == source_dfdy(i)) then
  3014. call mprintf(.true., ERROR, 'In GEOGRID.TBL, slope field df_dy at '// &
  3015. 'entry %i cannot have the same name as the slope field '// &
  3016. 'df_dy at entry %i.',i1=i, i2=j)
  3017. end if
  3018. end if
  3019. end if
  3020. if (is_dominant_category(i)) then
  3021. if (source_dominant_category(i) == source_fieldname(j)) then ! Possible exception
  3022. if (.not. (is_dominant_only(j) .and. (source_dominant_category(i) /= source_dominant_only(j)))) then
  3023. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category at '// &
  3024. 'entry %i cannot have the same name as the field at '// &
  3025. 'entry %i.',i1=i, i2=j)
  3026. end if
  3027. else if (is_dominant_category(j) .and. &
  3028. (source_dominant_category(i) == source_dominant_category(j))) then
  3029. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category at entry '// &
  3030. '%i cannot have the same name as dominant category at '// &
  3031. 'entry %i.',i1=i, i2=j)
  3032. else if (is_dominant_only(j) .and. &
  3033. (source_dominant_category(i) == source_dominant_only(j))) then
  3034. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant category at '// &
  3035. 'entry %i cannot have the same name as dominant_only '// &
  3036. 'category at entry %i.',i1=i, i2=j)
  3037. end if
  3038. else if (is_dominant_only(i)) then
  3039. if (source_dominant_only(i) == source_fieldname(j)) then ! Possible exception
  3040. if (.not. (is_dominant_only(j) .and. (source_dominant_only(i) /= source_dominant_only(j)))) then
  3041. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant_only category '// &
  3042. 'at entry %i cannot have the same name as the field at '// &
  3043. 'entry %i.',i1=i, i2=j)
  3044. end if
  3045. else if (is_dominant_category(j) .and. &
  3046. (source_dominant_only(i) == source_dominant_category(j))) then
  3047. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant_only category '// &
  3048. 'at entry %i cannot have the same name as dominant '// &
  3049. 'category at entry %i.',i1=i, i2=j)
  3050. else if (is_dominant_only(j) .and. &
  3051. (source_dominant_only(i) == source_dominant_only(j))) then
  3052. call mprintf(.true., ERROR, 'In GEOGRID.TBL, dominant_only category '// &
  3053. 'at entry %i cannot have the same name as dominant_only '// &
  3054. 'category at entry %i.',i1=i, i2=j)
  3055. end if
  3056. end if
  3057. end if
  3058. end do
  3059. end do
  3060. check_data_specification = .true.
  3061. end function check_data_specification
  3062. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  3063. ! Name: s_len
  3064. !
  3065. ! Purpose: This routine receives a fortran string, and returns the number of
  3066. ! characters in the string before the first "space" is encountered. It
  3067. ! considers ascii characters 33 to 126 to be valid characters, and ascii
  3068. ! 0 to 32, and 127 to be "space" characters.
  3069. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  3070. subroutine s_len(string, s_length)
  3071. implicit none
  3072. ! Arguments
  3073. character (len=*), intent(in) :: string
  3074. integer, intent(out) :: s_length
  3075. ! Local variables
  3076. integer :: i, len_str, aval
  3077. logical :: space
  3078. space = .false.
  3079. i = 1
  3080. len_str = len(string)
  3081. s_length = len_str
  3082. do while ((i .le. len_str) .and. (.not. space))
  3083. aval = ichar(string(i:i))
  3084. if ((aval .lt. 33) .or. (aval .gt. 126)) then
  3085. s_length = i - 1
  3086. space = .true.
  3087. endif
  3088. i = i + 1
  3089. enddo
  3090. end subroutine s_len
  3091. end module source_data_module