PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/WPS/util/src/plotfmt.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 440 lines | 265 code | 78 blank | 97 comment | 20 complexity | 849da1847ab1f9312ee5d05b69474d53 MD5 | raw file
Possible License(s): AGPL-1.0
  1. program plotfmt
  2. use read_met_module
  3. implicit none
  4. !
  5. ! Utility program to plot up files created by pregrid / SI / ungrib.
  6. ! Uses NCAR graphics routines. If you don't have NCAR Graphics, you're
  7. ! out of luck.
  8. !
  9. INTEGER :: istatus
  10. integer :: idum, ilev
  11. CHARACTER ( LEN =132 ) :: flnm
  12. TYPE (met_data) :: fg_data
  13. !
  14. ! Set up the graceful stop (Sun, SGI, DEC).
  15. !
  16. integer, external :: graceful_stop
  17. #if (defined(_DOUBLEUNDERSCORE) && defined(MACOS)) || defined(NO_SIGNAL)
  18. ! we do not do any signaling
  19. #else
  20. integer, external :: signal
  21. #endif
  22. integer :: iii
  23. #if (defined(_DOUBLEUNDERSCORE) && defined(MACOS)) || defined(NO_SIGNAL)
  24. ! still more no signaling
  25. #else
  26. iii = signal(2, graceful_stop, -1)
  27. #endif
  28. call getarg(1,flnm)
  29. IF ( flnm(1:1) == ' ' ) THEN
  30. print *,'USAGE: plotfmt.exe <filename>'
  31. print *,' where <filename> is the name of an intermediate-format file'
  32. STOP
  33. END IF
  34. call gopks(6,idum)
  35. call gopwk(1,55,1)
  36. call gopwk(2,56,3)
  37. call gacwk(1)
  38. call gacwk(2)
  39. call pcseti('FN', 21)
  40. call pcsetc('FC', '~')
  41. call gscr(1,0, 1.000, 1.000, 1.000)
  42. call gscr(1,1, 0.000, 0.000, 0.000)
  43. call gscr(1,2, 0.900, 0.600, 0.600)
  44. CALL read_met_init(TRIM(flnm), .true., '0000-00-00_00', istatus)
  45. IF ( istatus == 0 ) THEN
  46. CALL read_next_met_field(fg_data, istatus)
  47. DO WHILE (istatus == 0)
  48. ilev = nint(fg_data%xlvl)
  49. if (fg_data%iproj == PROJ_LATLON) then
  50. call plt2d(fg_data%slab, fg_data%nx, fg_data%ny, fg_data%iproj, &
  51. fg_data%startlat, fg_data%startlon, fg_data%deltalon, &
  52. fg_data%deltalat, fg_data%xlonc, fg_data%truelat1, fg_data%truelat2, &
  53. fg_data%field, ilev, fg_data%units, fg_data%version, fg_data%desc, &
  54. fg_data%map_source, TRIM(flnm))
  55. else
  56. call plt2d(fg_data%slab, fg_data%nx, fg_data%ny, fg_data%iproj, &
  57. fg_data%startlat, fg_data%startlon, fg_data%dx, fg_data%dy, fg_data%xlonc, &
  58. fg_data%truelat1, fg_data%truelat2, fg_data%field, ilev, fg_data%units, &
  59. fg_data%version, fg_data%desc, fg_data%map_source, TRIM(flnm))
  60. end if
  61. IF (ASSOCIATED(fg_data%slab)) DEALLOCATE(fg_data%slab)
  62. CALL read_next_met_field(fg_data, istatus)
  63. END DO
  64. CALL read_met_close()
  65. ELSE
  66. print *, 'File = ',TRIM(flnm)
  67. print *, 'Problem with input file, I can''t open it'
  68. STOP
  69. END IF
  70. call stopit
  71. end program plotfmt
  72. subroutine plt2d(tcr2d, iz, jz, llflag, &
  73. lat1, lon1, dx, dy, lov, truelat1, truelat2, &
  74. field, ilev, units, ifv, Desc, source, flnm)
  75. use misc_definitions_module
  76. implicit none
  77. integer :: llflag
  78. integer :: iz, jz, ifv
  79. real, dimension(iz,jz) :: tcr2d(iz,jz)
  80. real :: lat1, lon1, lov, truelat1, truelat2
  81. real :: dx, dy
  82. character(len=*) :: field
  83. character(len=*) :: units
  84. character(len=*) :: Desc
  85. character(len=*) :: source
  86. character(len=30) :: hunit
  87. character(len=32) :: tmp32
  88. character (len=*) :: flnm
  89. integer :: iproj, ierr
  90. real :: pl1, pl2, pl3, pl4, plon, plat, rota, phic
  91. real :: xl, xr, xb, xt, wl, wr, wb, wt, yb
  92. integer :: ml, ih, i, j
  93. integer, parameter :: lwrk = 20000, liwk = 50000
  94. real, dimension(lwrk) :: rwrk
  95. integer, dimension(liwk) :: iwrk
  96. integer :: ilev
  97. integer :: found_it
  98. character(len=8) :: hlev
  99. ! declarations for windowing
  100. integer :: ioff, joff, i1, j1, ix, jx, funit
  101. real, allocatable,dimension(:,:) :: scr2d
  102. logical :: is_used
  103. namelist /plotfmt/ ix, jx, ioff, joff
  104. ! This version allows the plotting of subsets of a lat/lon grid (i.e. NCEP GFS).
  105. ! ix,jx are the dimensions of the subset. ioff,joff are the offsets from 1,1
  106. ix = iz
  107. jx = jz
  108. ioff = 0
  109. joff = 0
  110. ! Read parameters from Fortran namelist
  111. do funit=10,100
  112. inquire(unit=funit, opened=is_used)
  113. if (.not. is_used) exit
  114. end do
  115. open(funit,file='namelist.wps',status='old',form='formatted',err=1000)
  116. read(funit,plotfmt,iostat=found_it)
  117. close(funit)
  118. if(found_it .gt. 0 ) then
  119. print *,'error reading the plotfmt namelist record in namelist.wps'
  120. print *,'you may have: ix, jx, ioff, joff ONLY'
  121. stop 1234
  122. end if
  123. ! ioff = 250 ! e.g. east of the Philippines from 0.5 degree GFS
  124. ! joff = 140
  125. ! ix = 20
  126. ! jx = 20
  127. if (ix+ioff .gt. iz .or. jx+joff .gt. jz) then
  128. ! print *,'map subset is too large. Setting to full domain'
  129. ix = iz
  130. jx = jz
  131. ioff = 0
  132. joff = 0
  133. endif
  134. ! compute upper left point for the map (works for NCEP GFS and godas)
  135. pl1 = lat1 + (joff*dy)
  136. pl2 = lon1 + (ioff*dx)
  137. allocate (scr2d(ix,jx))
  138. do i = 1, ix
  139. do j = 1, jx
  140. i1 = i + ioff
  141. j1 = j + joff
  142. scr2d(i,j) = tcr2d(i1,j1)
  143. enddo
  144. enddo
  145. select case (llflag)
  146. case (PROJ_LATLON)
  147. call fmtxyll(float(ix), float(jx), pl3, pl4, 'CE', pl1, pl2, &
  148. plon, truelat1, truelat2, dx, dy)
  149. plon = (pl2 + pl4) / 2.
  150. plat = 0.
  151. rota = 0.
  152. iproj=8
  153. case (PROJ_MERC)
  154. pl1 = lat1
  155. pl2 = lon1
  156. plon = 0.
  157. call fmtxyll(float(ix), float(jx), pl3, pl4, 'ME', pl1, pl2, &
  158. plon, truelat1, truelat2, dx, dy)
  159. plat = 0.
  160. rota = 0
  161. iproj = 9
  162. case (PROJ_LC)
  163. pl1 = lat1
  164. pl2 = lon1
  165. plon = lov
  166. call fmtxyll(float(ix), float(jx), pl3, pl4, 'LC', pl1, pl2,&
  167. plon, truelat1, truelat2, dx, dy)
  168. plat = truelat1
  169. rota = truelat2
  170. iproj=3
  171. ! This never used to be a problem, but currently we seem to need
  172. ! truelat1 (in plat) differ from truelat2 (in rota) for the
  173. ! NCAR-Graphics map routines to work. Maybe it's just a compiler
  174. ! thing. So if the truelats are the same, we add an epsilon:
  175. if (abs(plat - rota) < 1.E-8) then
  176. plat = plat + 1.E-8
  177. rota = rota - 1.E-8
  178. endif
  179. case (PROJ_PS)
  180. print*, 'ix, jx = ', ix, jx
  181. print*, 'lat1, lon1 = ', lat1, lon1
  182. pl1 = lat1
  183. pl2 = lon1
  184. plon = lov
  185. plat = 90.
  186. print*, 'plon, plat = ', plon, plat
  187. phic = 90.
  188. rota = 0.
  189. call fmtxyll(float(ix), float(jx), pl3, pl4, 'ST', pl1, pl2,&
  190. plon, truelat1, truelat2, dx, dy)
  191. iproj=1
  192. print*, pl1, pl2, pl3, pl4
  193. case default
  194. print*,'Unsupported map projection ',llflag,' in input'
  195. stop
  196. end select
  197. call gsplci(2) ! Use a different color for the map
  198. call supmap(iproj,plat,plon,rota,pl1,pl2,pl3,pl4,2,30,4,0,ierr)
  199. call gsplci(1)
  200. ! call supmap(iproj,plat+0.001,plon,rota-0.001,pl1,pl2,pl3,pl4,2,30,4,0,ierr)
  201. if (ierr.ne.0) then
  202. print*, 'supmap ierr = ', ierr
  203. stop
  204. ! stop
  205. endif
  206. call getset(xl,xr,xb,xt,wl,wr,wb,wt,ml)
  207. write(hlev,'(I8)') ilev
  208. call set(0., 1., 0., 1., 0., 1., 0., 1., 1)
  209. if ( xb .lt. .16 ) then
  210. yb = .16 ! xb depends on the projection, so fix yb and use it for labels
  211. else
  212. yb = xb
  213. endif
  214. call pchiqu(0.1, yb-0.05, hlev//' '//field, .020, 0.0, -1.0)
  215. print*, field//'#'//units//'#'//trim(Desc)
  216. ! call pchiqu(0.1, xb-0.12, Desc, .012, 0.0, -1.0)
  217. hunit = ' '
  218. ih = 0
  219. do i = 1, len(units)
  220. if (units(i:i).eq.'{') then
  221. hunit(ih+1:ih+3) = '~S~'
  222. ih = ih + 3
  223. elseif (units(i:i).eq.'}') then
  224. hunit(ih+1:ih+3) = '~N~'
  225. ih = ih + 3
  226. else
  227. ih = ih + 1
  228. hunit(ih:ih) = units(i:i)
  229. endif
  230. enddo
  231. if ( ifv .le. 3 ) then
  232. tmp32 = 'MM5 intermediate format'
  233. else if ( ifv .eq. 4 ) then
  234. tmp32 = 'SI intermediate format'
  235. else if ( ifv .eq. 5 ) then
  236. tmp32 = 'WPS intermediate format'
  237. endif
  238. call pchiqu(0.1, yb-0.09, hunit, .015, 0.0, -1.0)
  239. call pchiqu(0.1, yb-0.12, Desc, .013, 0.0, -1.0)
  240. call pchiqu(0.6, yb-0.12, source, .013, 0.0, -1.0)
  241. call pchiqu(0.1, yb-0.15, tmp32, .013, 0.0, -1.0)
  242. call pchiqu(0.6, yb-0.15, flnm, .013, 0.0, -1.0)
  243. call set(xl,xr,xb,xt,1.,float(ix),1.,float(jx),ml)
  244. call CPSETI ('SET - Do-SET-Call Flag', 0)
  245. call CPSETR ('SPV - Special Value', -1.E30)
  246. call cpseti('LLP', 3)
  247. if (dy.lt.0.) then
  248. call array_flip(scr2d, ix, jx)
  249. endif
  250. call cprect(scr2d,ix,ix,jx,rwrk,lwrk,iwrk,liwk)
  251. call cpcldr(scr2d,rwrk,iwrk)
  252. call cplbdr(scr2d,rwrk,iwrk)
  253. deallocate (scr2d)
  254. call frame
  255. return
  256. 1000 write(0,*) 'Error opening file namelist.wps, Stopping'
  257. stop 'namelist missing'
  258. end subroutine plt2d
  259. subroutine stopit
  260. call graceful_stop
  261. end
  262. subroutine graceful_stop
  263. call gdawk(2)
  264. call gdawk(1)
  265. call gclwk(2)
  266. call gclwk(1)
  267. call gclks
  268. print*, 'Graceful Stop.'
  269. stop
  270. end subroutine graceful_stop
  271. subroutine fmtxyll(x, y, xlat, xlon, project, glat1, glon1, gclon,&
  272. gtrue1, gtrue2, gdx, gdy)
  273. implicit none
  274. real , intent(in) :: x, y, glat1, glon1, gtrue1, gtrue2, gdx, gdy, gclon
  275. character(len=2), intent(in) :: project
  276. real , intent(out) :: xlat, xlon
  277. real :: gx1, gy1, gkappa
  278. real :: grrth = 6370.
  279. real :: r, y1
  280. integer :: iscan, jscan
  281. real, parameter :: pi = 3.1415926534
  282. real, parameter :: degran = pi/180.
  283. real, parameter :: raddeg = 180./pi
  284. real :: gt
  285. if (project.eq.'CE') then ! Cylindrical Equidistant grid
  286. xlat = glat1 + gdy*(y-1.)
  287. xlon = glon1 + gdx*(x-1.)
  288. elseif (project == "ME") then
  289. gt = grrth * cos(gtrue1*degran)
  290. xlon = glon1 + (gdx*(x-1.)/gt)*raddeg
  291. y1 = gt*alog((1.+sin(glat1*degran))/cos(glat1*degran))/gdy
  292. xlat = 90. - 2. * atan(exp(-gdy*(y+y1-1.)/gt))*raddeg
  293. elseif (project.eq.'ST') then ! Polar Stereographic grid
  294. r = grrth/gdx * tand((90.-glat1)/2.) * (1.+sind(gtrue1))
  295. gx1 = r * sind(glon1-gclon)
  296. gy1 = - r * cosd(glon1-gclon)
  297. r = sqrt((x-1.+gx1)**2 + (y-1+gy1)**2)
  298. xlat = 90. - 2.*atan2d((r*gdx),(grrth*(1.+sind(gtrue1))))
  299. xlon = atan2d((x-1.+gx1),-(y-1.+gy1)) + gclon
  300. elseif (project.eq.'LC') then ! Lambert-conformal grid
  301. call glccone(gtrue1, gtrue2, 1, gkappa)
  302. r = grrth/(gdx*gkappa)*sind(90.-gtrue1) * &
  303. (tand(45.-glat1/2.)/tand(45.-gtrue1/2.)) ** gkappa
  304. gx1 = r*sind(gkappa*(glon1-gclon))
  305. gy1 = -r*cosd(gkappa*(glon1-gclon))
  306. r = sqrt((x-1.+gx1)**2 + (y-1+gy1)**2)
  307. xlat = 90. - 2.*atand(tand(45.-gtrue1/2.)* &
  308. ((r*gkappa*gdx)/(grrth*sind(90.-gtrue1)))**(1./gkappa))
  309. xlon = atan2d((x-1.+gx1),-(y-1.+gy1))/gkappa + gclon
  310. else
  311. write(*,'("Unrecoginzed projection: ", A)') project
  312. write(*,'("Abort in FMTXYLL",/)')
  313. stop
  314. endif
  315. contains
  316. real function sind(theta)
  317. real :: theta
  318. sind = sin(theta*degran)
  319. end function sind
  320. real function cosd(theta)
  321. real :: theta
  322. cosd = cos(theta*degran)
  323. end function cosd
  324. real function tand(theta)
  325. real :: theta
  326. tand = tan(theta*degran)
  327. end function tand
  328. real function atand(x)
  329. real :: x
  330. atand = atan(x)*raddeg
  331. end function atand
  332. real function atan2d(x,y)
  333. real :: x,y
  334. atan2d = atan2(x,y)*raddeg
  335. end function atan2d
  336. subroutine glccone (fsplat,ssplat,sign,confac)
  337. implicit none
  338. real, intent(in) :: fsplat,ssplat
  339. integer, intent(in) :: sign
  340. real, intent(out) :: confac
  341. if (abs(fsplat-ssplat).lt.1.E-3) then
  342. confac = sind(fsplat)
  343. else
  344. confac = log10(cosd(fsplat))-log10(cosd(ssplat))
  345. confac = confac/(log10(tand(45.-float(sign)*fsplat/2.))- &
  346. log10(tand(45.-float(sign)*ssplat/2.)))
  347. endif
  348. end subroutine glccone
  349. end subroutine fmtxyll
  350. subroutine array_flip(array, ix, jx)
  351. implicit none
  352. integer :: ix, jx
  353. real , dimension(ix,jx) :: array
  354. real, dimension(ix) :: hold
  355. integer :: i, j, jj
  356. do j = 1, jx/2
  357. jj = jx+1-j
  358. hold = array(1:ix, j)
  359. array(1:ix,j) = array(1:ix,jj)
  360. array(1:ix,jj) = hold
  361. enddo
  362. end subroutine array_flip