PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/WPS/ungrib/src/g2print.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 1196 lines | 792 code | 141 blank | 263 comment | 150 complexity | d501b34c6a0789e56ee41889b96e6bbf MD5 | raw file
Possible License(s): AGPL-1.0
  1. !*****************************************************************************!
  2. program g2print !
  3. ! !
  4. use table
  5. use gridinfo
  6. use filelist
  7. use datarray
  8. implicit none
  9. interface
  10. subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2,&
  11. a3, h3, i3, l3, hlast)
  12. integer :: err
  13. character(len=*) , optional :: a1, a2, a3
  14. character(len=*), optional :: h1, h2, h3
  15. integer , optional :: i1, i2, i3
  16. logical, optional :: l1, l2, l3
  17. character(len=*), optional :: hlast
  18. end subroutine parse_args
  19. end interface
  20. integer :: nunit1 = 12
  21. character(LEN=120) :: gribflnm
  22. integer :: iprint
  23. integer , parameter :: maxlvl = 100
  24. real :: startlat, startlon, deltalat, deltalon
  25. real :: level
  26. character (LEN=9) :: field
  27. character (LEN=3) :: out_format
  28. logical :: readit
  29. integer, dimension(255) :: iuarr = 0
  30. character (LEN=19) :: HSTART, HEND, HDATE
  31. character(LEN=19) :: hsave = '0000-00-00_00:00:00'
  32. integer :: itime
  33. integer :: ntimes
  34. integer :: interval
  35. integer :: ierr
  36. logical :: ordered_by_date
  37. integer :: debug_level
  38. integer :: grib_version
  39. integer :: vtable_columns
  40. character(len=30) :: hopt
  41. logical :: ivb = .FALSE.
  42. logical :: idb = .FALSE.
  43. ! -----------------
  44. gribflnm = ' '
  45. call parse_args(ierr, a1='v', l1=ivb, a2='V', l2=idb, hlast=gribflnm)
  46. if (ierr.ne.0) then
  47. call getarg(0, hopt)
  48. write(*,'(//,"Usage: ", A, " [-v] [-V] file",/)') trim(hopt)
  49. write(*,'(" -v : Print more information about the GRIB records")')
  50. write(*,'(" -V : Print way too much information about the GRIB&
  51. & records")')
  52. write(*,'(" file : GRIB file to read"//)')
  53. stop
  54. endif
  55. ! -----------------
  56. ! Determine GRIB Edition number
  57. grib_version=0
  58. call edition_num(nunit1, trim(gribflnm), grib_version, ierr)
  59. if (ierr.eq.3) STOP 'GRIB file problem'
  60. debug_level = 0
  61. if (ivb) debug_level = 51
  62. if (idb) debug_level = 101
  63. write(6,*) 'reading from grib file = ',gribflnm
  64. LOOP1 : DO
  65. ! At the beginning of LOOP1, we are at a new time period.
  66. ! Clear the storage arrays and associated level information.
  67. ! If we need to read a new grib record, then read one.
  68. if (grib_version.ne.2) then
  69. ! write(6,*) 'calling r_grib1 with iunit ', nunit1
  70. ! write(6,*) 'flnm = ',gribflnm
  71. write(6,*) 'This is a Grib1 file. Please use g1print.\n'
  72. stop
  73. ! Read one record at a time from GRIB1 (and older Editions)
  74. ! call r_grib1(nunit1, gribflnm, level, field, &
  75. ! hdate, debug_level, ierr, iuarr, iprint)
  76. else
  77. ! Read one file of records from GRIB2.
  78. if (debug_level .gt. 100) write(6,*) 'calling r_grib2'
  79. call r_grib2(nunit1, gribflnm, hdate, &
  80. grib_version, debug_level, ierr)
  81. endif
  82. if (ierr.eq.1) then
  83. ! We have hit the end of a file. Exit LOOP1.
  84. exit LOOP1
  85. endif
  86. enddo LOOP1
  87. if (grib_version.ne.2) then
  88. call c_close(iuarr(nunit1), iprint, ierr)
  89. iuarr(nunit1) = 0
  90. endif
  91. ! And Now we are done:
  92. print*,' '
  93. print*,' '
  94. print*,' Successful completion of g2print '
  95. contains
  96. subroutine sort_filedates
  97. implicit none
  98. integer :: n
  99. logical :: done
  100. if (nfiles > 1) then
  101. done = .FALSE.
  102. do while ( .not. done)
  103. done = .TRUE.
  104. do n = 1, nfiles-1
  105. if (filedates(n) > filedates(n+1)) then
  106. filedates(size(filedates)) = filedates(n)
  107. filedates(n) = filedates(n+1)
  108. filedates(n+1) = filedates(size(filedates))
  109. filedates(size(filedates)) = '0000-00-00 00:00:00.0000'
  110. done = .FALSE.
  111. endif
  112. enddo
  113. enddo
  114. endif
  115. end subroutine sort_filedates
  116. end program g2print
  117. !*****************************************************************************!
  118. SUBROUTINE r_grib2(junit, gribflnm, hdate, &
  119. grib_edition, debug_level, ireaderr)
  120. use grib_mod
  121. use params
  122. use table ! Included to define g2code
  123. use gridinfo ! Included to define map%
  124. real, allocatable, dimension(:) :: hold_array
  125. parameter(msk1=32000,msk2=4000)
  126. character(len=1),allocatable,dimension(:) :: cgrib
  127. integer :: listsec0(3)
  128. integer :: listsec1(13)
  129. integer year, month, day, hour, minute, second, fcst
  130. character(len=*) :: gribflnm
  131. character(len=*) :: hdate
  132. character(len=8) :: pabbrev
  133. character(len=20) :: labbrev
  134. character(len=80) :: tabbrev
  135. integer :: lskip, lgrib
  136. integer :: junit, itot, icount, iseek
  137. integer :: grib_edition
  138. integer :: i, j, ireaderr, ith
  139. integer :: currlen
  140. logical :: unpack, expand
  141. type(gribfield) :: gfld
  142. real :: level
  143. real :: scale_factor
  144. integer :: iplvl, lvl2
  145. ! For subroutine outout
  146. integer , parameter :: maxlvl = 100
  147. real , dimension(maxlvl) :: plvl
  148. integer :: nlvl
  149. integer , dimension(maxlvl) :: level_array
  150. logical :: verbose=.false.
  151. logical :: first = .true.
  152. integer :: debug_level
  153. character(len=4) :: tmp4
  154. character(len=40) :: string
  155. character(len=13) :: pstring = ',t50,":",i14)'
  156. character(len=15) :: rstring = ',t50,":",f14.5)'
  157. ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  158. ! SET ARGUMENTS
  159. if (debug_level .gt. 50 ) then
  160. unpack=.true.
  161. else
  162. unpack=.false.
  163. endif
  164. expand=.true.
  165. hdate = '0000-00-00_00:00:00'
  166. ierr=0
  167. itot=0
  168. icount=0
  169. iseek=0
  170. lskip=0
  171. lgrib=0
  172. currlen=0
  173. ith=1
  174. scale_factor = 1e6
  175. ! do j = 1,10
  176. ! write(6,'("j = ",i4," level1 = ",i8," level2 = ",i8)') j, &
  177. ! level1(j), level2(j)
  178. ! enddo
  179. !/* IOS Return Codes from BACIO: */
  180. !/* 0 All was well */
  181. !/* -1 Tried to open read only _and_ write only */
  182. !/* -2 Tried to read and write in the same call */
  183. !/* -3 Internal failure in name processing */
  184. !/* -4 Failure in opening file */
  185. !/* -5 Tried to read on a write-only file */
  186. !/* -6 Failed in read to find the 'start' location */
  187. !/* -7 Tried to write to a read only file */
  188. !/* -8 Failed in write to find the 'start' location */
  189. !/* -9 Error in close */
  190. !/* -10 Read or wrote fewer data than requested */
  191. !if ireaderr =1 we have hit the end of a file.
  192. !if ireaderr =2 we have hit the end of all the files.
  193. if ( debug_level .gt. 100 ) verbose = .true.
  194. if (verbose) write(6,*) 'begin r_grib2, flnm = ',gribflnm
  195. ! Open a byte-addressable file.
  196. CALL BAOPENR(junit,gribflnm,IOS)
  197. first = .true.
  198. if (verbose) write(6,*) 'back from baopenr, ios = ',ios
  199. if (ios.eq.0) then
  200. VERSION: do
  201. ! Search opend file for the next GRIB2 messege (record).
  202. if (verbose) write(6,*) 'calling skgb'
  203. call skgb(junit,iseek,msk1,lskip,lgrib)
  204. ! Check for EOF, or problem
  205. if (lgrib.eq.0) then
  206. exit
  207. endif
  208. ! Check size, if needed allocate more memory.
  209. if (lgrib.gt.currlen) then
  210. if (allocated(cgrib)) deallocate(cgrib)
  211. allocate(cgrib(lgrib),stat=is)
  212. !print *,'G2 allocate(cgrib(lgrib)) status: ',IS
  213. currlen=lgrib
  214. endif
  215. ! Read a given number of bytes from unblocked file.
  216. call baread(junit,lskip,lgrib,lengrib,cgrib)
  217. if (lgrib.ne.lengrib) then
  218. print *,'G2 r_grib2: IO Error.',lgrib,".ne.",lengrib
  219. stop 9
  220. endif
  221. iseek=lskip+lgrib
  222. icount=icount+1
  223. if (verbose) PRINT *,'G2 GRIB MESSAGE ',icount,' starts at',lskip+1
  224. ! Unpack GRIB2 field
  225. call gb_info(cgrib,lengrib,listsec0,listsec1, &
  226. numfields,numlocal,maxlocal,ierr)
  227. if (ierr.ne.0) then
  228. write(*,*) ' ERROR querying GRIB2 message = ',ierr
  229. stop 10
  230. endif
  231. itot=itot+numfields
  232. grib_edition=listsec0(2)
  233. if (grib_edition.ne.2) then
  234. exit VERSION
  235. endif
  236. ! Additional print statments for developer.
  237. if (verbose) then
  238. print *,'G2 SECTION 0: ',(listsec0(j),j=1,3)
  239. print *,'G2 SECTION 1: ',(listsec1(j),j=1,13)
  240. print *,'G2 Contains ',numlocal,' Local Sections ', &
  241. ' and ',numfields,' data fields.'
  242. endif
  243. ! ----
  244. ! Once per file fill in date, model and projection values.
  245. if (first) then
  246. first = .false.
  247. ! Build the 19-character date string, based on GRIB2 header date
  248. ! and time information, including forecast time information:
  249. n=1
  250. call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
  251. if (debug_level .gt. 100 ) then
  252. write(6,*) 'gfld%version = ',gfld%version
  253. if (gfld%discipline .eq. 0) then
  254. string = 'Meteorological products'
  255. else if (gfld%discipline .eq. 1) then
  256. string = 'Hydrological products'
  257. else if (gfld%discipline .eq. 2) then
  258. string = 'Land Surface products'
  259. else
  260. string = 'See code table 0.0'
  261. endif
  262. write(6,*) 'Discipline = ',gfld%discipline,' ',string
  263. write(6,*) 'gfld%idsect(1) = ',gfld%idsect(1)
  264. write(6,*) 'gfld%idsect(2) = ',gfld%idsect(2)
  265. write(6,*) 'gfld%idsect(3) = ',gfld%idsect(3)
  266. write(6,*) 'gfld%idsect(4) = ',gfld%idsect(4)
  267. write(6,*) 'gfld%idsect(5) = ',gfld%idsect(5)
  268. write(6,*) 'gfld%idsect(6) = ',gfld%idsect(6)
  269. write(6,*) 'gfld%idsect(7) = ',gfld%idsect(7)
  270. write(6,*) 'gfld%idsect(8) = ',gfld%idsect(8)
  271. write(6,*) 'gfld%idsect(9) = ',gfld%idsect(9)
  272. write(6,*) 'gfld%idsect(10) = ',gfld%idsect(10)
  273. write(6,*) 'gfld%idsect(11) = ',gfld%idsect(11)
  274. write(6,*) 'gfld%idsect(12) = ',gfld%idsect(12)
  275. write(6,*) 'gfld%idsect(13) = ',gfld%idsect(13)
  276. write(6,*) 'gfld%idsectlen = ',gfld%idsectlen
  277. write(6,*) 'gfld%locallen = ',gfld%locallen
  278. write(6,*) 'gfld%ifldnum = ',gfld%ifldnum
  279. write(6,*) 'gfld%ngrdpts = ',gfld%ngrdpts
  280. write(6,*) 'gfld%numoct_opt = ',gfld%numoct_opt
  281. write(6,*) 'gfld%interp_opt = ',gfld%interp_opt
  282. write(6,*) 'gfld%griddef = ',gfld%griddef
  283. if (gfld%igdtnum .eq. 0) then
  284. string = 'Lat/Lon cylindrical equidistant'
  285. else if (gfld%igdtnum .eq. 1) then
  286. string = 'Rotated Lat/Lon'
  287. else if (gfld%igdtnum .eq. 2) then
  288. string = 'Stretched Lat/Lon'
  289. else if (gfld%igdtnum .eq. 20) then
  290. string = 'Polar Stereographic'
  291. else if (gfld%igdtnum .eq. 30) then
  292. string = 'Lambert Conformal'
  293. else if (gfld%igdtnum .eq. 40) then
  294. string = 'Gaussian Lat/Lon'
  295. else if (gfld%igdtnum .eq. 50) then
  296. string = 'Spherical harmonic coefficients'
  297. else
  298. string = 'see code table 3.1'
  299. endif
  300. write(6,*) 'Grid Template number = ',gfld%igdtnum,' ',string
  301. write(6,*) 'gfld%igdtlen = ',gfld%igdtlen
  302. do i = 1, gfld%igdtlen
  303. write(6,*) 'gfld%igdtmpl(',i,') = ',gfld%igdtmpl(i)
  304. enddo
  305. write(6,*) 'gfld%ipdtnum = ',gfld%ipdtnum
  306. write(6,*) 'gfld%ipdtlen = ',gfld%ipdtlen
  307. if ( gfld%ipdtnum .eq. 0 ) then
  308. do i = 1, gfld%ipdtlen
  309. write(6,*) 'gfld%ipdtmpl(',i,') = ',gfld%ipdtmpl(i)
  310. enddo
  311. endif
  312. write(6,*) 'gfld%num_coord = ',gfld%num_coord
  313. write(6,*) 'gfld%ndpts = ',gfld%ndpts
  314. write(6,*) 'gfld%idrtnum = ',gfld%idrtnum
  315. write(6,*) 'gfld%idrtlen = ',gfld%idrtlen
  316. write(6,*) 'gfld%expanded = ',gfld%expanded
  317. write(6,*) 'gfld%ibmap = ',gfld%ibmap
  318. endif
  319. if (debug_level .le. 50) then
  320. write(6,*) '---------------------------------------------------------------------------------------'
  321. write(6,*) ' rec Prod Cat Param Lvl Lvl Lvl Prod Name Time Fcst'
  322. write(6,*) ' num Disc num code one two Templ hour'
  323. write(6,*) '---------------------------------------------------------------------------------------'
  324. endif
  325. year =gfld%idsect(6) !(FOUR-DIGIT) YEAR OF THE DATA
  326. month =gfld%idsect(7) ! MONTH OF THE DATA
  327. day =gfld%idsect(8) ! DAY OF THE DATA
  328. hour =gfld%idsect(9) ! HOUR OF THE DATA
  329. minute=gfld%idsect(10) ! MINUTE OF THE DATA
  330. second=gfld%idsect(11) ! SECOND OF THE DATA
  331. fcst = 0
  332. ! Extract forecast time.
  333. if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
  334. fcst = gfld%ipdtmpl(9)
  335. else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
  336. fcst = gfld%ipdtmpl(9) / 60.
  337. else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
  338. fcst = gfld%ipdtmpl(9) * 24.
  339. else
  340. fcst = 999
  341. endif
  342. ! Compute valid time.
  343. if (verbose) then
  344. print *, 'ymd',gfld%idsect(6),gfld%idsect(7),gfld%idsect(8)
  345. print *, 'hhmm ',gfld%idsect(9),gfld%idsect(10)
  346. endif
  347. call build_hdate(hdate,year,month,day,hour,minute,second)
  348. if (verbose) print *, 'G2 hdate = ',hdate
  349. ! call geth_newdate(hdate,hdate,3600*fcst) ! no need for thin in print
  350. ! print *, 'G2 hdate (fcst?) = ',hdate
  351. !--
  352. ! Indicator of the source (center) of the data.
  353. icenter = gfld%idsect(1)
  354. ! Indicator of model (or whatever) which generated the data.
  355. iprocess = gfld%ipdtmpl(5)
  356. if (icenter.eq.7) then
  357. if (iprocess.eq.83 .or. iprocess.eq.84) then
  358. map%source = 'NCEP NAM Model'
  359. elseif (iprocess.eq.81) then
  360. map%source = 'NCEP GFS Model'
  361. elseif (iprocess.eq.82) then
  362. map%source = 'NCEP GFS GDAS'
  363. elseif (iprocess.eq.96) then
  364. map%source = 'NCEP GFS Model'
  365. elseif (iprocess.eq.86 .or. iprocess.eq.100) then
  366. map%source = 'NCEP RUC Model' ! 60 km
  367. elseif (iprocess.eq.101) then
  368. map%source = 'NCEP RUC Model' ! 40 km
  369. elseif (iprocess.eq.105) then
  370. map%source = 'NCEP RUC Model' ! 20 km
  371. elseif (iprocess.eq.107) then
  372. map%source = 'NCEP GEFS'
  373. elseif (iprocess.eq.109) then
  374. map%source = 'NCEP RTMA'
  375. elseif (iprocess.eq.140) then
  376. map%source = 'NCEP NARR'
  377. elseif (iprocess.eq.44) then
  378. map%source = 'NCEP SST Analysis'
  379. elseif (iprocess.eq.70) then
  380. map%source = 'GFDL Hurricane Model'
  381. elseif (iprocess.eq.80) then
  382. map%source = 'NCEP GFS Ensemble'
  383. elseif (iprocess.eq.107) then ! renumbered as of 23 Feb 2010
  384. map%source = 'NCEP GFS Ensemble'
  385. elseif (iprocess.eq.129) then
  386. map%source = 'NCEP GODAS'
  387. elseif (iprocess.eq.25) then
  388. map%source = 'NCEP SNOW COVER ANALYSIS'
  389. else
  390. map%source = 'unknown model from NCEP'
  391. write (6,*) 'unknown NCEP model, iprocess = ',iprocess
  392. end if
  393. else if (icenter .eq. 57) then
  394. if (iprocess .eq. 87) then
  395. map%source = 'AFWA AGRMET'
  396. else
  397. map%source = 'AFWA'
  398. endif
  399. else if (icenter .eq. 58) then
  400. map%source = 'US Navy FNOC'
  401. else if (icenter .eq. 98) then
  402. map%source = 'ECMWF'
  403. else if (icenter .eq. 34) then
  404. map%source = 'JMA'
  405. else if (icenter .eq. 74 .or. icenter .eq. 75 ) then
  406. map%source = 'UKMO'
  407. else
  408. map%source = 'unknown model and orig center'
  409. end if
  410. !--
  411. ! Store information about the grid on which the data is.
  412. ! This stuff gets stored in the MAP variable, as defined in
  413. ! module GRIDINFO.
  414. map%startloc = 'SWCORNER'
  415. if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
  416. map%igrid = 0
  417. map%nx = gfld%igdtmpl(8)
  418. map%ny = gfld%igdtmpl(9)
  419. map%dx = gfld%igdtmpl(17)
  420. map%dy = gfld%igdtmpl(18)
  421. map%lat1 = gfld%igdtmpl(12)
  422. map%lon1 = gfld%igdtmpl(13)
  423. if ((gfld%igdtmpl(10) .eq. 0).OR. &
  424. (gfld%igdtmpl(10) .eq. 255)) THEN
  425. ! Scale lat/lon values to 0-180, default range is 1e6.
  426. map%lat1 = map%lat1/scale_factor
  427. map%lon1 = map%lon1/scale_factor
  428. ! Scale dx/dy values to degrees, default range is 1e6.
  429. map%dx = map%dx/scale_factor
  430. map%dy = map%dy/scale_factor
  431. else
  432. ! Basic angle and subdivisions are non-zero (not tested)
  433. map%lat1 = map%lat1 * &
  434. (gfld%igdtmpl(11)/gfld%igdtmpl(10))
  435. map%lon1 = map%lon1 * &
  436. (gfld%igdtmpl(11)/gfld%igdtmpl(10))
  437. map%dx = map%dx * &
  438. (gfld%igdtmpl(11)/gfld%igdtmpl(10))
  439. map%dy = map%dy * &
  440. (gfld%igdtmpl(11)/gfld%igdtmpl(10))
  441. endif
  442. elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
  443. map%igrid = 3
  444. map%nx = gfld%igdtmpl(8)
  445. map%ny = gfld%igdtmpl(9)
  446. map%lov = gfld%igdtmpl(14)
  447. map%truelat1 = gfld%igdtmpl(19)
  448. map%truelat2 = gfld%igdtmpl(20)
  449. map%dx = gfld%igdtmpl(15)
  450. map%dy = gfld%igdtmpl(16)
  451. map%lat1 = gfld%igdtmpl(10)
  452. map%lon1 = gfld%igdtmpl(11)
  453. elseif(gfld%igdtnum.eq.40) then ! Gaussian Grid (we will call it lat/lon)
  454. map%igrid = 0
  455. map%nx = gfld%igdtmpl(8)
  456. map%ny = gfld%igdtmpl(9)
  457. map%dx = gfld%igdtmpl(17)
  458. map%dy = gfld%igdtmpl(18) ! ?not in Grid Definition Template 3.40 doc
  459. map%lat1 = gfld%igdtmpl(12)
  460. map%lon1 = gfld%igdtmpl(13)
  461. ! Scale dx/dy values to degrees, default range is 1e6.
  462. if (map%dx.gt.10000) then
  463. map%dx = map%dx/scale_factor
  464. endif
  465. if (map%dy.gt.10000) then
  466. map%dy = (map%dy/scale_factor)*(-1)
  467. endif
  468. ! Scale lat/lon values to 0-180, default range is 1e6.
  469. if (map%lat1.ge.scale_factor) then
  470. map%lat1 = map%lat1/scale_factor
  471. endif
  472. if (map%lon1.ge.scale_factor) then
  473. map%lon1 = map%lon1/scale_factor
  474. endif
  475. print *,'Gaussian Grid: Dx,Dy,lat,lon',map%dx,map%dy, &
  476. map%lat1,map%lon1
  477. elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
  478. map%igrid = 5
  479. map%nx = gfld%igdtmpl(8)
  480. map%ny = gfld%igdtmpl(9)
  481. !map%lov = gfld%igdtmpl(x) ! ?not in Grid Definition Template 3.20 doc
  482. map%truelat1 = 60.
  483. map%truelat2 = 91.
  484. !map%dx = gfld%igdtmpl(x)
  485. !map%dy = gfld%igdtmpl(x)
  486. map%lat1 = gfld%igdtmpl(10)
  487. map%lon1 = gfld%igdtmpl(11)
  488. else
  489. print*, 'GRIB2 Unknown Projection: ',gfld%igdtnum
  490. print*, 'see Code Table 3.1: Grid Definition Template No'
  491. endif
  492. call gf_free(gfld)
  493. endif
  494. ! ----
  495. ! Continue to unpack GRIB2 field.
  496. if (debug_level .gt. 100) write(6,*) 'numfields = ',numfields
  497. do n=1,numfields ! e.g. U and V would =2, otherwise its usually =1
  498. call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
  499. if (ierr.ne.0) then
  500. write(*,*) ' ERROR extracting field gf_getfld = ',ierr
  501. cycle
  502. endif
  503. ! ------------------------------------
  504. ! Additional print information for developer.
  505. pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1), &
  506. gfld%ipdtmpl(2))
  507. if (debug_level .gt. 50 ) then
  508. print *
  509. ! print *,'G2 FIELD ',n
  510. if (n==1) then
  511. write(*,'(/,"GRIB2 SECTION 0 - INDICATOR SECTION:")')
  512. write(*,'(5x,"Discipline"'//pstring) gfld%discipline
  513. write(*,'(5x,"GRIB Edition Number"'//pstring) gfld%version
  514. write(*,'(5x,"GRIB length"'//pstring) lengrib
  515. write(*,'(/,"GRIB2 SECTION 1 - IDENTIFICATION SECTION:")')
  516. write(*,'(5x,"Length of Section"'//pstring) gfld%idsectlen
  517. write(*,'(5x,"Originating Center ID"'//pstring) &
  518. gfld%idsect(1)
  519. write(*,'(5x,"Subcenter ID"'//pstring) gfld%idsect(2)
  520. write(*,'(5x,"GRIB Master Table Version"'//pstring) &
  521. gfld%idsect(3)
  522. write(*,'(5x,"GRIB Local Table Version"'//pstring) &
  523. gfld%idsect(4)
  524. write(*,'(5x,"Significance of Reference Time"'//pstring) &
  525. gfld%idsect(5)
  526. write(*,'(5x,"Year"'//pstring) gfld%idsect(6)
  527. write(*,'(5x,"Month"'//pstring) gfld%idsect(7)
  528. write(*,'(5x,"Day"'//pstring) gfld%idsect(8)
  529. write(*,'(5x,"Hour"'//pstring) gfld%idsect(9)
  530. write(*,'(5x,"Minute"'//pstring) gfld%idsect(10)
  531. write(*,'(5x,"Second"'//pstring) gfld%idsect(11)
  532. write(*,'(5x,"Production Status of data"'//pstring) &
  533. gfld%idsect(12)
  534. write(*,'(5x,"Type of processed data"'//pstring) &
  535. gfld%idsect(13)
  536. ! print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
  537. endif
  538. write(*,'(/,"GRIB2 SECTION 2 - LOCAL SECTION:")')
  539. write(*,'(5x,"Length of Section 2"'//pstring) gfld%locallen
  540. if ( associated(gfld%local).AND.gfld%locallen.gt.0 ) then
  541. do j = 1, gfld%locallen
  542. write(*,'(5x,"Local value "'//pstring) gfld%local(j)
  543. enddo
  544. ! print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
  545. endif
  546. write(*,'(/,"GRIB2 SECTION 3 - GRID DEFINITION SECTION:")')
  547. ! write(*,'(5x,"Length of Section 3"'//pstring) gfld%unknown
  548. write(*,'(5x,"Source of grid definition"'&
  549. //pstring) gfld%griddef
  550. write(*,'(5x,"Number of grid points"'//pstring) gfld%ngrdpts
  551. write(*,'(5x,"Number of octets for addnl points"'//pstring) &
  552. gfld%numoct_opt
  553. write(*,'(5x,"Interpretation list"'//pstring) &
  554. gfld%interp_opt
  555. write(*,'(5x,"Grid Definition Template Number"'//pstring) &
  556. gfld%igdtnum
  557. if (gfld%igdtnum .eq. 0 .or. gfld%igdtnum .eq. 1 .or. &
  558. gfld%igdtnum .eq. 2 .or. gfld%igdtnum .eq. 3 ) then
  559. if (gfld%igdtnum .eq. 0 ) then
  560. write(*,'(5x,"Lat/Lon or Cylindrical Equidistant Grid")')
  561. else if (gfld%igdtnum .eq. 1 ) then
  562. write(*,'(5x,"Rotated Lat/Lon or Cylind. Equi. Grid")')
  563. else if (gfld%igdtnum .eq. 2 ) then
  564. write(*,'(5x,"Stretched Lat/Lon or Cylind. Equi. Grid")')
  565. else if (gfld%igdtnum .eq. 3 ) then
  566. write(*,'(5x,"Stretched and Rotated Lat/Lon Grid")')
  567. endif
  568. write(*,'(10x,"Shape of the Earth"'//pstring) &
  569. gfld%igdtmpl(1)
  570. write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
  571. gfld%igdtmpl(2)
  572. write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
  573. gfld%igdtmpl(3)
  574. write(*,'(10x,"Scale factor of major axis"'//pstring) &
  575. gfld%igdtmpl(4)
  576. write(*,'(10x,"Scaled value of major axis"'//pstring) &
  577. gfld%igdtmpl(5)
  578. write(*,'(10x,"Scale factor of minor axis"'//pstring) &
  579. gfld%igdtmpl(6)
  580. write(*,'(10x,"Scaled value of minor axis"'//pstring) &
  581. gfld%igdtmpl(7)
  582. write(*,'(10x,"Ni - points along a parallel"'//pstring) &
  583. gfld%igdtmpl(8)
  584. write(*,'(10x,"Nj - points along a meridian"'//pstring) &
  585. gfld%igdtmpl(9)
  586. write(*,'(10x,"Basic angle of initial domain"'//pstring)&
  587. gfld%igdtmpl(10)
  588. write(*,'(10x,"Subdivisions of basic angle"'//pstring) &
  589. gfld%igdtmpl(11)
  590. write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(12)
  591. write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(13)
  592. write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
  593. gfld%igdtmpl(14)
  594. write(*,'(10x,"La2"'//pstring) gfld%igdtmpl(15)
  595. write(*,'(10x,"Lo2"'//pstring) gfld%igdtmpl(16)
  596. write(*,'(10x,"Di - i-dir increment"'//pstring) &
  597. gfld%igdtmpl(17)
  598. write(*,'(10x,"Dj - j-dir increment"'//pstring) &
  599. gfld%igdtmpl(18)
  600. write(*,'(10x,"Scanning mode"'//pstring) &
  601. gfld%igdtmpl(19)
  602. if (gfld%igdtnum .eq. 1) then
  603. write(*,'(10x,"Lat of southern pole of project"'//pstring)&
  604. gfld%igdtmpl(20)
  605. write(*,'(10x,"Lon of southern pole of project"'//pstring)&
  606. gfld%igdtmpl(21)
  607. write(*,'(10x,"Angle of rotation of projection"'//pstring)&
  608. gfld%igdtmpl(22)
  609. else if (gfld%igdtnum .eq. 2) then
  610. write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
  611. gfld%igdtmpl(20)
  612. write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
  613. gfld%igdtmpl(21)
  614. write(*,'(10x,"Stretching factor"'//pstring) &
  615. gfld%igdtmpl(22)
  616. else if (gfld%igdtnum .eq. 3) then
  617. write(*,'(10x,"Lat of southern pole of project"'//pstring)&
  618. gfld%igdtmpl(20)
  619. write(*,'(10x,"Lon of southern pole of project"'//pstring)&
  620. gfld%igdtmpl(21)
  621. write(*,'(10x,"Angle of rotation of projection"'//pstring)&
  622. gfld%igdtmpl(22)
  623. write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
  624. gfld%igdtmpl(23)
  625. write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
  626. gfld%igdtmpl(24)
  627. write(*,'(10x,"Stretching factor"'//pstring) &
  628. gfld%igdtmpl(25)
  629. endif
  630. else if (gfld%igdtnum .eq. 10) then
  631. write(*,'(5x,"Mercator Grid")')
  632. else if (gfld%igdtnum .eq. 20 .or. gfld%igdtnum .eq. 30) then
  633. if (gfld%igdtnum .eq. 20) then
  634. write(*,'(5x,"Polar Stereographic Grid")')
  635. else if (gfld%igdtnum .eq. 30) then
  636. write(*,'(5x,"Lambert Conformal Grid")')
  637. endif
  638. write(*,'(10x,"Shape of the Earth"'//pstring) &
  639. gfld%igdtmpl(1)
  640. write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
  641. gfld%igdtmpl(2)
  642. write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
  643. gfld%igdtmpl(3)
  644. write(*,'(10x,"Scale factor of major axis"'//pstring) &
  645. gfld%igdtmpl(4)
  646. write(*,'(10x,"Scaled value of major axis"'//pstring) &
  647. gfld%igdtmpl(5)
  648. write(*,'(10x,"Scale factor of minor axis"'//pstring) &
  649. gfld%igdtmpl(6)
  650. write(*,'(10x,"Scaled value of minor axis"'//pstring) &
  651. gfld%igdtmpl(7)
  652. write(*,'(10x,"Nx"'//pstring) gfld%igdtmpl(8)
  653. write(*,'(10x,"Ny"'//pstring) gfld%igdtmpl(9)
  654. write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(10)
  655. write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(11)
  656. write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
  657. gfld%igdtmpl(12)
  658. write(*,'(10x,"LaD"'//pstring) gfld%igdtmpl(13)
  659. write(*,'(10x,"LoV"'//pstring) gfld%igdtmpl(14)
  660. write(*,'(10x,"Dx"'//pstring) gfld%igdtmpl(15)
  661. write(*,'(10x,"Dy"'//pstring) gfld%igdtmpl(16)
  662. write(*,'(10x,"Projection Center Flag"'//pstring) &
  663. gfld%igdtmpl(17)
  664. write(*,'(10x,"Scanning mode"'//pstring) &
  665. gfld%igdtmpl(18)
  666. if (gfld%igdtnum .eq. 30) then
  667. write(*,'(10x,"Latin 1 "'//pstring) &
  668. gfld%igdtmpl(19)
  669. write(*,'(10x,"Latin 2 "'//pstring) &
  670. gfld%igdtmpl(20)
  671. write(*,'(10x,"Lat of southern pole of project"'//pstring)&
  672. gfld%igdtmpl(21)
  673. write(*,'(10x,"Lon of southern pole of project"'//pstring)&
  674. gfld%igdtmpl(22)
  675. endif
  676. else if (gfld%igdtnum .eq. 40 .or. gfld%igdtnum .eq. 41) then
  677. if (gfld%igdtnum .eq. 40) then
  678. write(*,'(5x,"Gaussian Lat/Lon Grid")')
  679. else if (gfld%igdtnum .eq. 41) then
  680. write(*,'(5x,"Rotated Gaussian Lat/Lon Grid")')
  681. else if (gfld%igdtnum .eq. 42) then
  682. write(*,'(5x,"Stretched Gaussian Lat/Lon Grid")')
  683. else if (gfld%igdtnum .eq. 43) then
  684. write(*,'(5x,"Stretched and Rotated Gaussian Lat/Lon ")')
  685. endif
  686. else
  687. do j = 1, gfld%igdtlen
  688. write(*,'(5x,"Grid Definition Template entry "'//pstring) &
  689. gfld%igdtmpl(j)
  690. enddo
  691. endif
  692. ! print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts, &
  693. ! gfld%numoct_opt,gfld%interp_opt, &
  694. ! gfld%igdtnum
  695. ! print *,'G2 GRID TEMPLATE 3.',gfld%igdtnum,': ', &
  696. ! (gfld%igdtmpl(j),j=1,gfld%igdtlen)
  697. if ( gfld%num_opt .eq. 0 ) then
  698. ! print *,'G2 NO Section 3 List Defining No. of Data Points.'
  699. else
  700. print *,'G2 Section 3 Optional List: ', &
  701. (gfld%list_opt(j),j=1,gfld%num_opt)
  702. endif
  703. write(*,'(/,"GRIB2 SECTION 4 - PRODUCT DEFINITION SECTION:")')
  704. ! write(*,'(5x,"Length of Section 4"'//pstring) gfld%unknown
  705. write(*,'(5x,"Product Definition Template Number"'//pstring)&
  706. gfld%ipdtnum
  707. do j = 1, gfld%ipdtlen
  708. write(tmp4,'(i4)') j
  709. string = '(5x,"Template Entry '//tmp4 // '"'
  710. write(*,string//pstring) gfld%ipdtmpl(j)
  711. enddo
  712. ! print *,'G2 PRODUCT TEMPLATE 4.',gfld%ipdtnum,': ', &
  713. ! (gfld%ipdtmpl(j),j=1,gfld%ipdtlen)
  714. !call prlevel(gfld%ipdtnum,gfld%ipdtmpl,labbrev)
  715. !call prvtime(gfld%ipdtnum,gfld%ipdtmpl,listsec1,tabbrev)
  716. write(*,'(5x,"Product Abbreviated Name",t50,":",a14)')&
  717. pabbrev
  718. ! print *,'G2 TEXT: ',pabbrev,trim(labbrev)," ",trim(tabbrev)
  719. if ( gfld%num_coord .eq. 0 ) then
  720. ! print *,'G2 NO Optional Vertical Coordinate List.'
  721. else
  722. print *,'G2 Section 4 Optional Coordinates: ', &
  723. (gfld%coord_list(j),j=1,gfld%num_coord)
  724. endif
  725. ! if ( gfld%ibmap .ne. 255 ) then
  726. ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
  727. ! ' with BIT-MAP ',gfld%ibmap
  728. ! else
  729. ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
  730. ! ' NO BIT-MAP '
  731. ! endif
  732. write(*,'(/,"GRIB2 SECTION 5 - DATA REPRESENTATION SECTION:")')
  733. write(*,'(5x,"Data Representation Template Number"'//pstring)&
  734. gfld%idrtnum
  735. do j = 1, gfld%idrtlen
  736. write(tmp4,'(i4)') j
  737. string = '(5x,"Template Entry '//tmp4 // '"'
  738. write(*,string//pstring) gfld%idrtmpl(j)
  739. enddo
  740. ! print *,'G2 DRS TEMPLATE 5.',gfld%idrtnum,': ', &
  741. ! (gfld%idrtmpl(j),j=1,gfld%idrtlen)
  742. ! if ( gfld%ipdtnum .eq. 0 ) then
  743. ! if (gfld%ipdtmpl(1) .eq. 0 ) then
  744. ! write(6,*) 'Temperature'
  745. ! else if (gfld%ipdtmpl(1) .eq. 1 ) then
  746. ! write(6,*) 'Moisture'
  747. ! else if (gfld%ipdtmpl(1) .eq. 2 ) then
  748. ! write(6,*) 'Momentum'
  749. ! else if (gfld%ipdtmpl(1) .eq. 3 ) then
  750. ! write(6,*) 'Mass'
  751. ! endif
  752. ! endif
  753. write(*,'(/,"GRIB2 SECTION 6 - BIT-MAP SECTION:")')
  754. write(*,'(5x,"Bit-map indicator"'//pstring) &
  755. gfld%ibmap
  756. fldmax=gfld%fld(1)
  757. fldmin=gfld%fld(1)
  758. sum=gfld%fld(1)
  759. do j=2,gfld%ndpts
  760. if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
  761. if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
  762. sum=sum+gfld%fld(j)
  763. enddo ! gfld%ndpts
  764. write(*,'(/,"GRIB2 SECTION 7 - DATA SECTION:")')
  765. write(*,'(5x,"Minimum Data Value "'//rstring)&
  766. fldmin
  767. write(*,'(5x,"Maximum Data Value "'//rstring)&
  768. fldmax
  769. ! print *,'G2 Data Values:'
  770. ! write(*,fmt='("G2 MIN=",f21.8," AVE=",f21.8, &
  771. ! " MAX=",f21.8)') fldmin,sum/gfld%ndpts,fldmax
  772. if (debug_level .gt. 100 ) then
  773. print*, 'gfld%fld = ',gfld%fld
  774. ! do j=1,gfld%ndpts
  775. ! write(*,*) j, gfld%fld(j)
  776. ! enddo
  777. endif
  778. endif ! Additional Print information
  779. ! ------------------------------------
  780. if ( debug_level .le. 50) then
  781. if(gfld%ipdtmpl(10).eq.100) then ! pressure level
  782. level=gfld%ipdtmpl(12) * &
  783. (10. ** (-1. * gfld%ipdtmpl(11)))
  784. else if(gfld%ipdtmpl(10).eq.101 .or.& ! sea level, sfc, or trop
  785. gfld%ipdtmpl(10).eq.1 .or. gfld%ipdtmpl(10).eq.7) then
  786. level = 0
  787. else
  788. level=gfld%ipdtmpl(12)
  789. endif
  790. if (gfld%ipdtmpl(13) .eq. 255) then
  791. lvl2 = 0
  792. else
  793. lvl2 = gfld%ipdtmpl(15)
  794. endif
  795. ! Account for multiple forecast hours in one file
  796. if (gfld%ipdtnum.eq.0 .or. gfld%ipdtnum.eq.1 .or. gfld%ipdtnum.eq. 8) then
  797. ! Product Definition Template 4.0, 4.1, 4.8
  798. ! Extract forecast time.
  799. if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
  800. fcst = gfld%ipdtmpl(9)
  801. else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
  802. fcst = gfld%ipdtmpl(9) / 60.
  803. else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
  804. fcst = gfld%ipdtmpl(9) * 24.
  805. else
  806. fcst = 999
  807. endif
  808. endif
  809. write(6,987) itot,gfld%discipline,gfld%ipdtmpl(1), &
  810. gfld%ipdtmpl(2),gfld%ipdtmpl(10),int(level),&
  811. lvl2,gfld%ipdtnum,pabbrev,hdate,fcst
  812. 987 format(2i4,i5,i4,i8,i8,i8,i8,3x,a10,a20,i5.2)
  813. endif
  814. ! Deallocate arrays decoding GRIB2 record.
  815. call gf_free(gfld)
  816. enddo ! 1,numfields
  817. enddo VERSION ! skgb
  818. if (debug_level .gt. 50) &
  819. print *, 'G2 total number of fields found = ',itot
  820. CALL BACLOSE(junit,IOS)
  821. ireaderr=1
  822. else
  823. print *,'open status failed because',ios
  824. hdate = '9999-99-99_99:99:99'
  825. ireaderr=2
  826. endif ! ireaderr check
  827. END subroutine r_grib2
  828. !*****************************************************************************!
  829. ! Subroutine edition_num !
  830. ! !
  831. ! Purpose: !
  832. ! Read one record from the input GRIB2 file. Based on the information in !
  833. ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
  834. ! the GRIB2 record is one to process or to skip. If the field is one we !
  835. ! want to keep, extract the data from the GRIB2 record, and pass the data !
  836. ! back to the calling routine. !
  837. ! !
  838. ! Argument list: !
  839. ! Input: !
  840. ! JUNIT : "Unit Number" to open and read from. Not really a Fortran !
  841. ! unit number, since we do not do Fortran I/O for the GRIB2 !
  842. ! files. Nor is it a UNIX File Descriptor returned from a C !
  843. ! OPEN statement. It is really just an array index to the !
  844. ! array (IUARR) where the UNIX File Descriptor values are !
  845. ! stored. !
  846. ! GRIB2FILE: File name to open, if it is not already open. !
  847. ! !
  848. ! Output: !
  849. ! GRIB_EDITION: Set to 1 for GRIB and set to 2 for GRIB2 !
  850. ! IERR : Error flag: 0 - no error on read from GRIB2 file. !
  851. ! 1 - Hit the end of the GRIB2 file. !
  852. ! 2 - The file GRIBFLNM we tried to open does !
  853. ! not exist. !
  854. ! Author: Paula McCaslin !
  855. ! NOAA/FSL !
  856. ! Sept 2004 !
  857. !*****************************************************************************!
  858. SUBROUTINE edition_num(junit, gribflnm, grib_edition, ireaderr)
  859. use grib_mod
  860. use params
  861. parameter(msk1=32000,msk2=4000)
  862. character(len=1),allocatable,dimension(:) :: cgrib
  863. integer :: listsec0(3)
  864. integer :: listsec1(13)
  865. character(len=*) :: gribflnm
  866. integer :: lskip, lgrib
  867. integer :: junit
  868. integer :: grib_edition
  869. integer :: i, j, ireaderr
  870. integer :: currlen
  871. character(len=4) :: ctemp
  872. character(len=4),parameter :: grib='GRIB',c7777='7777'
  873. ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  874. ! SET ARGUMENTS
  875. itot=0
  876. icount=0
  877. iseek=0
  878. lskip=0
  879. lgrib=0
  880. currlen=0
  881. !/* IOS Return Codes from BACIO: */
  882. !/* 0 All was well */
  883. !/* -1 Tried to open read only _and_ write only */
  884. !/* -2 Tried to read and write in the same call */
  885. !/* -3 Internal failure in name processing */
  886. !/* -4 Failure in opening file */
  887. !/* -5 Tried to read on a write-only file */
  888. !/* -6 Failed in read to find the 'start' location */
  889. !/* -7 Tried to write to a read only file */
  890. !/* -8 Failed in write to find the 'start' location */
  891. !/* -9 Error in close */
  892. !/* -10 Read or wrote fewer data than requested */
  893. !if ireaderr =1 we have hit the end of a file.
  894. !if ireaderr =2 we have hit the end of all the files.
  895. !if ireaderr =3 beginning characters 'GRIB' not found
  896. ! write(6,*) 'junit = ',junit,' gribflnm = ',gribflnm
  897. ! Open a byte-addressable file.
  898. CALL BAOPENR(junit,gribflnm,IOS) ! from w3lib
  899. ! write(6,*) 'ios = ',ios
  900. if (ios.eq.0) then
  901. ! Search opend file for the next GRIB2 messege (record).
  902. call skgb(junit,iseek,msk1,lskip,lgrib)
  903. ! Check for EOF, or problem
  904. if (lgrib.eq.0) then
  905. write(*,'("\n\tThere is a problem with the input file.")')
  906. write(*,'("\tPerhaps it is not a Grib2 file?\n")')
  907. STOP "Grib2 file or date problem, stopping in edition_num."
  908. endif
  909. ! Check size, if needed allocate more memory.
  910. if (lgrib.gt.currlen) then
  911. if (allocated(cgrib)) deallocate(cgrib)
  912. allocate(cgrib(lgrib),stat=is)
  913. currlen=lgrib
  914. endif
  915. ! Read a given number of bytes from unblocked file.
  916. call baread(junit,lskip,lgrib,lengrib,cgrib)
  917. ! Check for beginning of GRIB message in the first 100 bytes
  918. istart=0
  919. do j=1,100
  920. ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
  921. if (ctemp.eq.grib ) then
  922. istart=j
  923. exit
  924. endif
  925. enddo
  926. if (istart.eq.0) then
  927. ireaderr=3
  928. print*, "The beginning 4 characters >GRIB< were not found."
  929. endif
  930. ! Unpack Section 0 - Indicator Section to extract GRIB edition field
  931. iofst=8*(istart+5)
  932. call gbyte(cgrib,discipline,iofst,8) ! Discipline
  933. iofst=iofst+8
  934. call gbyte(cgrib,grib_edition,iofst,8) ! GRIB edition number
  935. print *, 'ungrib - grib edition num', grib_edition
  936. CALL BACLOSE(junit,IOS)
  937. ireaderr=1
  938. else if (ios .eq. -4) then
  939. print *,'edition_num: unable to open ',gribflnm
  940. stop 'edition_num'
  941. else
  942. print *,'edition_num: open status failed because',ios,gribflnm
  943. ireaderr=2
  944. endif ! ireaderr check
  945. END subroutine edition_num
  946. subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2, a3, h3, i3, l3, &
  947. hlast)
  948. integer :: err
  949. character(len=*) , optional :: a1, a2, a3
  950. character(len=*), optional :: h1, h2, h3
  951. integer , optional :: i1, i2, i3
  952. logical, optional :: l1, l2, l3
  953. character(len=*), optional :: hlast
  954. character(len=100) :: hold
  955. integer :: ioff = 0
  956. if (present(hlast)) then
  957. ioff = -1
  958. endif
  959. err = 0
  960. narg = iargc()
  961. numarg = narg + ioff
  962. i = 1
  963. LOOP : do while ( i <= numarg)
  964. ierr = 1
  965. if (present(i1)) then
  966. call checkiarg(i, a1, i1, ierr)
  967. elseif (present(h1)) then
  968. call checkharg(i, a1, h1, ierr)
  969. elseif (present(l1)) then
  970. call checklarg(i, a1, l1, ierr)
  971. endif
  972. if (ierr.eq.0) cycle LOOP
  973. if (present(i2)) then
  974. call checkiarg(i, a2, i2, ierr)
  975. elseif (present(h2)) then
  976. call checkharg(i, a2, h2, ierr)
  977. elseif (present(l2)) then
  978. call checklarg(i, a2, l2, ierr)
  979. endif
  980. if (ierr.eq.0) cycle LOOP
  981. if (present(i3)) then
  982. call checkiarg(i, a3, i3, ierr)
  983. elseif (present(h3)) then
  984. call checkharg(i, a3, h3, ierr)
  985. elseif (present(l3)) then
  986. call checklarg(i, a3, l3, ierr)
  987. endif
  988. if (ierr.eq.0) cycle LOOP
  989. err = 1
  990. call getarg(1, hold)
  991. write(*, '("arg = ", A)') trim(hold)
  992. exit LOOP
  993. enddo LOOP
  994. if (present(hlast)) then
  995. if (narg.eq.0) then
  996. err = 1
  997. else
  998. call getarg(narg, hlast)
  999. endif
  1000. endif
  1001. contains
  1002. subroutine checkiarg(c, a, i, ierr)
  1003. integer :: c
  1004. character(len=*) :: a
  1005. integer :: i
  1006. character(len=100) :: hold
  1007. ierr = 1
  1008. call getarg(c, hold)
  1009. if ('-'//a.eq.trim(hold)) then
  1010. c = c + 1
  1011. call getarg(c, hold)
  1012. read(hold, *) i
  1013. c = c + 1
  1014. ierr = 0
  1015. elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
  1016. hold = hold(len_trim(a)+2: len(hold))
  1017. read(hold, *) i
  1018. c = c + 1
  1019. ierr = 0
  1020. endif
  1021. end subroutine checkiarg
  1022. subroutine checkharg(c, a, h, ierr)
  1023. integer :: c
  1024. character(len=*) :: a
  1025. character(len=*) :: h
  1026. character(len=100) :: hold
  1027. ierr = 1
  1028. call getarg(c, hold)
  1029. if ('-'//a.eq.trim(hold)) then
  1030. c = c + 1
  1031. call getarg(c, hold)
  1032. h = trim(hold)
  1033. c = c + 1
  1034. ierr = 0
  1035. elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
  1036. hold = hold(len_trim(a)+2: len(hold))
  1037. h = trim(hold)
  1038. c = c + 1
  1039. ierr = 0
  1040. endif
  1041. end subroutine checkharg
  1042. subroutine checklarg(c, a, l, ierr)
  1043. integer :: c
  1044. character(len=*) :: a
  1045. logical :: l
  1046. character(len=100) :: hold
  1047. ierr = 1
  1048. call getarg(c, hold)
  1049. if ('-'//a.eq.trim(hold)) then
  1050. l = .TRUE.
  1051. c = c + 1
  1052. ierr = 0
  1053. endif
  1054. end subroutine checklarg
  1055. end subroutine parse_args