1 !*****************************************************************************!
9 subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2,&
10 a3, h3, i3, l3, hlast)
12 character(len=*) , optional :: a1, a2, a3
13 character(len=*), optional :: h1, h2, h3
14 integer , optional :: i1, i2, i3
15 logical, optional :: l1, l2, l3
16 character(len=*), optional :: hlast
17 end subroutine parse_args
20 integer :: nunit1 = 12
21 character(LEN=120) :: gribflnm
25 integer , parameter :: maxlvl = 150
27 real :: startlat, startlon, deltalat, deltalon
29 character (LEN=9) :: field
30 character (LEN=3) :: out_format
34 integer, dimension(255) :: iuarr = 0
36 character (LEN=19) :: HSTART, HEND, HDATE
37 character(LEN=19) :: hsave = '0000-00-00_00:00:00'
42 logical :: ordered_by_date
43 integer :: debug_level
44 integer :: grib_version
45 integer :: vtable_columns
47 character(len=30) :: hopt
48 logical :: ivb = .FALSE.
49 logical :: idb = .FALSE.
54 call parse_args(ierr, a1='v', l1=ivb, a2='V', l2=idb, hlast=gribflnm)
57 write(*,'(//,"Usage: ", A, " [-v] [-V] file",/)') trim(hopt)
58 write(*,'(" -v : Print more information about the GRIB records")')
59 write(*,'(" -V : Print way too much information about the GRIB&
61 write(*,'(" file : GRIB file to read"//)')
66 ! Determine GRIB Edition number
68 call edition_num(nunit1, trim(gribflnm), grib_version, ierr)
69 if (ierr.eq.3) STOP 'GRIB file problem'
73 if (ivb) debug_level = 51
74 if (idb) debug_level = 101
75 write(6,*) 'reading from grib file = ',gribflnm
78 ! At the beginning of LOOP1, we are at a new time period.
79 ! Clear the storage arrays and associated level information.
81 ! If we need to read a new grib record, then read one.
83 if (grib_version.ne.2) then
84 ! write(6,*) 'calling r_grib1 with iunit ', nunit1
85 ! write(6,*) 'flnm = ',gribflnm
86 write(6,*) 'This is a Grib1 file. Please use g1print.\n'
88 ! Read one record at a time from GRIB1 (and older Editions)
89 ! call r_grib1(nunit1, gribflnm, level, field, &
90 ! hdate, debug_level, ierr, iuarr, iprint)
93 ! Read one file of records from GRIB2.
94 if (debug_level .gt. 100) write(6,*) 'calling r_grib2'
95 call r_grib2(nunit1, gribflnm, hdate, &
96 grib_version, debug_level, ierr)
101 ! We have hit the end of a file. Exit LOOP1.
107 if (grib_version.ne.2) then
108 call c_close(iuarr(nunit1), iprint, ierr)
112 ! And Now we are done:
116 print*,' Successful completion of g2print '
119 subroutine sort_filedates
126 do while ( .not. done)
129 if (filedates(n) > filedates(n+1)) then
130 filedates(size(filedates)) = filedates(n)
131 filedates(n) = filedates(n+1)
132 filedates(n+1) = filedates(size(filedates))
133 filedates(size(filedates)) = '0000-00-00 00:00:00.0000'
139 end subroutine sort_filedates
143 !*****************************************************************************!
145 SUBROUTINE r_grib2(junit, gribflnm, hdate, &
146 grib_edition, debug_level, ireaderr)
150 use table ! Included to define g2code
151 use gridinfo ! Included to define map%
153 real, allocatable, dimension(:) :: hold_array
154 parameter(msk1=32000,msk2=4000)
155 character(len=1),allocatable,dimension(:) :: cgrib
156 integer :: listsec0(3)
157 integer :: listsec1(13)
158 integer year, month, day, hour, minute, second, fcst
159 character(len=*) :: gribflnm
160 character(len=*) :: hdate
161 character(len=8) :: pabbrev
162 character(len=20) :: labbrev
163 character(len=80) :: tabbrev
164 integer :: lskip, lgrib
165 integer :: junit, itot, icount, iseek
166 integer :: grib_edition
167 integer :: i, j, ireaderr, ith
169 logical :: unpack, expand
170 type(gribfield) :: gfld
173 integer :: iplvl, lvl2
174 ! For subroutine output
175 integer , parameter :: maxlvl = 150
176 real , dimension(maxlvl) :: plvl
178 integer , dimension(maxlvl) :: level_array
179 logical :: verbose=.false.
180 logical :: first = .true.
181 integer :: debug_level
182 character(len=4) :: tmp4
183 character(len=40) :: string
184 character(len=13) :: pstring = ',t50,":",i14)'
185 character(len=15) :: rstring = ',t50,":",f14.5)'
186 character(len=13) :: astring = ',t50,":",a14)'
187 character(len=15) :: estring = ',t50,":",e14.5)'
189 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
192 if (debug_level .gt. 50 ) then
198 hdate = '0000-00-00_00:00:00'
209 ! write(6,'("j = ",i4," level1 = ",i8," level2 = ",i8)') j, &
210 ! level1(j), level2(j)
213 !/* IOS Return Codes from BACIO: */
214 !/* 0 All was well */
215 !/* -1 Tried to open read only _and_ write only */
216 !/* -2 Tried to read and write in the same call */
217 !/* -3 Internal failure in name processing */
218 !/* -4 Failure in opening file */
219 !/* -5 Tried to read on a write-only file */
220 !/* -6 Failed in read to find the 'start' location */
221 !/* -7 Tried to write to a read only file */
222 !/* -8 Failed in write to find the 'start' location */
223 !/* -9 Error in close */
224 !/* -10 Read or wrote fewer data than requested */
226 !if ireaderr =1 we have hit the end of a file.
227 !if ireaderr =2 we have hit the end of all the files.
230 if ( debug_level .gt. 100 ) verbose = .true.
231 if (verbose) write(6,*) 'begin r_grib2, flnm = ',gribflnm
232 ! Open a byte-addressable file.
233 CALL BAOPENR(junit,gribflnm,IOS)
235 if (verbose) write(6,*) 'back from baopenr, ios = ',ios
239 ! Search opend file for the next GRIB2 messege (record).
240 if (verbose) write(6,*) 'calling skgb'
241 call skgb(junit,iseek,msk1,lskip,lgrib)
243 ! Check for EOF, or problem
248 ! Check size, if needed allocate more memory.
249 if (lgrib.gt.currlen) then
250 if (allocated(cgrib)) deallocate(cgrib)
251 allocate(cgrib(lgrib),stat=is)
252 !print *,'G2 allocate(cgrib(lgrib)) status: ',IS
256 ! Read a given number of bytes from unblocked file.
257 call baread(junit,lskip,lgrib,lengrib,cgrib)
259 if (lgrib.ne.lengrib) then
260 print *,'G2 r_grib2: IO Error.',lgrib,".ne.",lengrib
266 if (verbose) PRINT *,'G2 GRIB MESSAGE ',icount,' starts at',lskip+1
269 call gb_info(cgrib,lengrib,listsec0,listsec1, &
270 numfields,numlocal,maxlocal,ierr)
272 write(*,*) ' ERROR querying GRIB2 message = ',ierr
277 grib_edition=listsec0(2)
278 if (grib_edition.ne.2) then
282 ! Additional print statments for developer.
284 print *,'G2 SECTION 0: ',(listsec0(j),j=1,3)
285 print *,'G2 SECTION 1: ',(listsec1(j),j=1,13)
286 print *,'G2 Contains ',numlocal,' Local Sections ', &
287 ' and ',numfields,' data fields.'
291 ! Once per file fill in date, model and projection values.
296 ! Build the 19-character date string, based on GRIB2 header date
297 ! and time information, including forecast time information:
300 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
302 if (debug_level .gt. 100 ) then
303 write(6,*) 'gfld%version = ',gfld%version
304 if (gfld%discipline .eq. 0) then
305 string = 'Meteorological products'
306 else if (gfld%discipline .eq. 1) then
307 string = 'Hydrological products'
308 else if (gfld%discipline .eq. 2) then
309 string = 'Land Surface products'
311 string = 'See code table 0.0'
313 write(6,*) 'Discipline = ',gfld%discipline,' ',string
314 write(6,*) 'gfld%idsect(1) = ',gfld%idsect(1)
315 write(6,*) 'gfld%idsect(2) = ',gfld%idsect(2)
316 write(6,*) 'gfld%idsect(3) = ',gfld%idsect(3)
317 write(6,*) 'gfld%idsect(4) = ',gfld%idsect(4)
318 write(6,*) 'gfld%idsect(5) = ',gfld%idsect(5)
319 write(6,*) 'gfld%idsect(6) = ',gfld%idsect(6)
320 write(6,*) 'gfld%idsect(7) = ',gfld%idsect(7)
321 write(6,*) 'gfld%idsect(8) = ',gfld%idsect(8)
322 write(6,*) 'gfld%idsect(9) = ',gfld%idsect(9)
323 write(6,*) 'gfld%idsect(10) = ',gfld%idsect(10)
324 write(6,*) 'gfld%idsect(11) = ',gfld%idsect(11)
325 write(6,*) 'gfld%idsect(12) = ',gfld%idsect(12)
326 write(6,*) 'gfld%idsect(13) = ',gfld%idsect(13)
328 write(6,*) 'gfld%idsectlen = ',gfld%idsectlen
329 write(6,*) 'gfld%locallen = ',gfld%locallen
330 write(6,*) 'gfld%ifldnum = ',gfld%ifldnum
331 write(6,*) 'gfld%ngrdpts = ',gfld%ngrdpts
332 write(6,*) 'gfld%numoct_opt = ',gfld%numoct_opt
333 write(6,*) 'gfld%interp_opt = ',gfld%interp_opt
335 write(6,*) 'gfld%griddef = ',gfld%griddef
336 if (gfld%igdtnum .eq. 0) then
337 string = 'Lat/Lon cylindrical equidistant'
338 else if (gfld%igdtnum .eq. 1) then
339 string = 'Rotated Lat/Lon'
340 else if (gfld%igdtnum .eq. 2) then
341 string = 'Stretched Lat/Lon'
342 else if (gfld%igdtnum .eq. 20) then
343 string = 'Polar Stereographic'
344 else if (gfld%igdtnum .eq. 30) then
345 string = 'Lambert Conformal'
346 else if (gfld%igdtnum .eq. 40) then
347 string = 'Gaussian Lat/Lon'
348 else if (gfld%igdtnum .eq. 50) then
349 string = 'Spherical harmonic coefficients'
351 string = 'see code table 3.1'
353 write(6,*) 'Grid Template number = ',gfld%igdtnum,' ',string
354 write(6,*) 'gfld%igdtlen = ',gfld%igdtlen
355 do i = 1, gfld%igdtlen
356 write(6,*) 'gfld%igdtmpl(',i,') = ',gfld%igdtmpl(i)
359 write(6,*) 'gfld%ipdtnum = ',gfld%ipdtnum
360 write(6,*) 'gfld%ipdtlen = ',gfld%ipdtlen
361 if ( gfld%ipdtnum .eq. 0 ) then
362 do i = 1, gfld%ipdtlen
363 write(6,*) 'gfld%ipdtmpl(',i,') = ',gfld%ipdtmpl(i)
366 write(6,*) 'gfld%num_coord = ',gfld%num_coord
367 write(6,*) 'gfld%ndpts = ',gfld%ndpts
368 write(6,*) 'gfld%idrtnum = ',gfld%idrtnum
369 write(6,*) 'gfld%idrtlen = ',gfld%idrtlen
370 write(6,*) 'gfld%expanded = ',gfld%expanded
371 write(6,*) 'gfld%ibmap = ',gfld%ibmap
374 year =gfld%idsect(6) !(FOUR-DIGIT) YEAR OF THE DATA
375 month =gfld%idsect(7) ! MONTH OF THE DATA
376 day =gfld%idsect(8) ! DAY OF THE DATA
377 hour =gfld%idsect(9) ! HOUR OF THE DATA
378 minute=gfld%idsect(10) ! MINUTE OF THE DATA
379 second=gfld%idsect(11) ! SECOND OF THE DATA
383 ! Extract forecast time.
384 if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
385 fcst = gfld%ipdtmpl(9)
386 else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
387 fcst = gfld%ipdtmpl(9) / 60.
388 else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
389 fcst = gfld%ipdtmpl(9) * 24.
394 ! Compute valid time.
397 print *, 'ymd',gfld%idsect(6),gfld%idsect(7),gfld%idsect(8)
398 print *, 'hhmm ',gfld%idsect(9),gfld%idsect(10)
401 call build_hdate(hdate,year,month,day,hour,minute,second)
402 if (verbose) print *, 'G2 hdate = ',hdate
403 ! call geth_newdate(hdate,hdate,3600*fcst) ! no need for this in print
404 ! print *, 'G2 hdate (fcst?) = ',hdate
408 ! Indicator of the source (center) of the data.
409 icenter = gfld%idsect(1)
411 ! Indicator of model (or whatever) which generated the data.
412 iprocess = gfld%ipdtmpl(5)
415 if (icenter.eq.7) then
416 ! Values obtained from http://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html
417 ! Note that NCEP recycles process numbers. This may cause labelling issues for
419 if (iprocess.eq.81) then
420 map%source = 'NCEP GFS Analysis'
421 elseif (iprocess.eq.82) then
422 map%source = 'NCEP GFS GDAS/FNL'
423 elseif (iprocess.eq.83) then
424 map%source = 'NCEP HRRR Model'
425 elseif (iprocess.eq.84) then
426 map%source = 'NCEP MESO NAM Model'
427 elseif (iprocess.eq.89) then
428 map%source = 'NCEP NMM '
429 elseif (iprocess.eq.96) then
430 map%source = 'NCEP GFS Model'
431 elseif (iprocess.eq.86 .or. iprocess.eq.100) then
432 map%source = 'NCEP RUC Model' ! 60 km
433 elseif (iprocess.eq.101) then
434 map%source = 'NCEP RUC Model' ! 40 km
435 elseif (iprocess.eq.105) then
436 if (year .gt. 2011) then
437 map%source = 'NCEP RAP Model'
439 map%source = 'NCEP RUC Model' ! 20 km
441 elseif (iprocess.eq.107) then
442 map%source = 'NCEP GEFS'
443 elseif (iprocess.eq.109) then
444 map%source = 'NCEP RTMA'
445 elseif (iprocess.eq.140) then
446 map%source = 'NCEP NARR'
447 elseif (iprocess.eq.44) then
448 map%source = 'NCEP SST Analysis'
449 elseif (iprocess.eq.70) then
450 map%source = 'GFDL Hurricane Model'
451 elseif (iprocess.eq.80) then
452 map%source = 'NCEP GFS Ensemble'
453 elseif (iprocess.eq.107) then ! renumbered as of 23 Feb 2010
454 map%source = 'NCEP GFS Ensemble'
455 elseif (iprocess.eq.111) then
456 map%source = 'NCEP NMMB Model'
457 elseif (iprocess.eq.112) then
458 map%source = 'NCEP WRF-NMM Model'
459 elseif (iprocess.eq.116) then
460 map%source = 'NCEP WRF-ARW Model'
461 elseif (iprocess.eq.129) then
462 map%source = 'NCEP GODAS'
463 elseif (iprocess.eq.197) then
464 map%source = 'NCEP CDAS CFSV2'
465 elseif (iprocess.eq.25) then
466 map%source = 'NCEP SNOW COVER ANALYSIS'
468 map%source = 'unknown model from NCEP'
469 write (6,*) 'unknown NCEP model, iprocess = ',iprocess
471 else if (icenter .eq. 57) then
472 if (iprocess .eq. 87) then
473 map%source = 'AFWA AGRMET'
477 else if (icenter .eq. 58) then
478 map%source = 'US Navy FNOC'
479 else if (icenter .eq. 98) then
481 else if (icenter .eq. 34) then
483 else if (icenter .eq. 74 .or. icenter .eq. 75 ) then
486 map%source = 'unknown model and orig center'
488 write (6,*) ' ',map%source
490 if (debug_level .le. 50) then
491 write(6,'(a)') '---------------------------------------------------------------------------------------'
492 write(6,'(a)') ' rec Prod Cat Param Lvl Lvl Lvl Prod Name Time Fcst'
493 write(6,'(a)') ' num Disc num code one two Templ hour'
494 write(6,'(a)') '---------------------------------------------------------------------------------------'
500 ! Store information about the grid on which the data is.
501 ! This stuff gets stored in the MAP variable, as defined in
504 map%startloc = 'SWCORNER'
506 if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
508 map%nx = gfld%igdtmpl(8)
509 map%ny = gfld%igdtmpl(9)
510 map%dx = gfld%igdtmpl(17)
511 map%dy = gfld%igdtmpl(18)
512 map%lat1 = gfld%igdtmpl(12)
513 map%lon1 = gfld%igdtmpl(13)
515 if ((gfld%igdtmpl(10) .eq. 0).OR. &
516 (gfld%igdtmpl(10) .eq. 255)) THEN
517 ! Scale lat/lon values to 0-180, default range is 1e6.
518 map%lat1 = map%lat1/scale_factor
519 map%lon1 = map%lon1/scale_factor
520 ! Scale dx/dy values to degrees, default range is 1e6.
521 map%dx = map%dx/scale_factor
522 map%dy = map%dy/scale_factor
524 ! Basic angle and subdivisions are non-zero (not tested)
525 map%lat1 = map%lat1 * &
526 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
527 map%lon1 = map%lon1 * &
528 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
530 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
532 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
535 elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
537 map%nx = gfld%igdtmpl(8)
538 map%ny = gfld%igdtmpl(9)
539 map%lov = gfld%igdtmpl(14)
540 map%truelat1 = gfld%igdtmpl(19)
541 map%truelat2 = gfld%igdtmpl(20)
542 map%dx = gfld%igdtmpl(15)
543 map%dy = gfld%igdtmpl(16)
544 map%lat1 = gfld%igdtmpl(10)
545 map%lon1 = gfld%igdtmpl(11)
547 elseif(gfld%igdtnum.eq.40) then ! Gaussian Grid (we will call it lat/lon)
549 map%nx = gfld%igdtmpl(8)
550 map%ny = gfld%igdtmpl(9)
551 map%dx = gfld%igdtmpl(17)
552 map%dy = gfld%igdtmpl(18) ! ?not in Grid Definition Template 3.40 doc
553 map%lat1 = gfld%igdtmpl(12)
554 map%lon1 = gfld%igdtmpl(13)
556 ! Scale dx/dy values to degrees, default range is 1e6.
557 if (map%dx.gt.10000) then
558 map%dx = map%dx/scale_factor
560 if (map%dy.gt.10000) then
561 map%dy = (map%dy/scale_factor)*(-1)
564 ! Scale lat/lon values to 0-180, default range is 1e6.
565 if (abs(map%lat1).ge.scale_factor) then
566 map%lat1 = map%lat1/scale_factor
568 if (map%lon1.ge.scale_factor) then
569 map%lon1 = map%lon1/scale_factor
571 print *,'Gaussian Grid: Dx,Dy,lat,lon',map%dx,map%dy, &
574 elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
576 map%nx = gfld%igdtmpl(8)
577 map%ny = gfld%igdtmpl(9)
578 !map%lov = gfld%igdtmpl(x) ! ?not in Grid Definition Template 3.20 doc
581 !map%dx = gfld%igdtmpl(x)
582 !map%dy = gfld%igdtmpl(x)
583 map%lat1 = gfld%igdtmpl(10)
584 map%lon1 = gfld%igdtmpl(11)
587 print*, 'GRIB2 Unknown Projection: ',gfld%igdtnum
588 print*, 'see Code Table 3.1: Grid Definition Template No'
596 ! Continue to unpack GRIB2 field.
597 if (debug_level .gt. 100) write(6,*) 'numfields = ',numfields
598 NUM_FIELDS: do n = 1, numfields
599 ! e.g. U and V would =2, otherwise its usually =1
600 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
602 write(*,*) ' ERROR extracting field gf_getfld = ',ierr
606 ! ------------------------------------
607 ! Additional print information for developer.
608 pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1), &
610 if (debug_level .gt. 50 ) then
612 ! print *,'G2 FIELD ',n
614 write(*,'(/,"GRIB2 SECTION 0 - INDICATOR SECTION:")')
615 write(*,'(5x,"Discipline"'//pstring) gfld%discipline
616 write(*,'(5x,"GRIB Edition Number"'//pstring) gfld%version
617 write(*,'(5x,"GRIB length"'//pstring) lengrib
618 write(*,'(/,"GRIB2 SECTION 1 - IDENTIFICATION SECTION:")')
619 write(*,'(5x,"Length of Section"'//pstring) gfld%idsectlen
620 write(*,'(5x,"Originating Center ID"'//pstring) &
622 write(*,'(5x,"Subcenter ID"'//pstring) gfld%idsect(2)
623 write(*,'(5x,"GRIB Master Table Version"'//pstring) &
625 write(*,'(5x,"GRIB Local Table Version"'//pstring) &
627 write(*,'(5x,"Significance of Reference Time"'//pstring) &
629 write(*,'(5x,"Year"'//pstring) gfld%idsect(6)
630 write(*,'(5x,"Month"'//pstring) gfld%idsect(7)
631 write(*,'(5x,"Day"'//pstring) gfld%idsect(8)
632 write(*,'(5x,"Hour"'//pstring) gfld%idsect(9)
633 write(*,'(5x,"Minute"'//pstring) gfld%idsect(10)
634 write(*,'(5x,"Second"'//pstring) gfld%idsect(11)
635 write(*,'(5x,"Production Status of data"'//pstring) &
637 write(*,'(5x,"Type of processed data"'//pstring) &
639 ! print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
641 write(*,'(/,"GRIB2 SECTION 2 - LOCAL SECTION:")')
642 write(*,'(5x,"Length of Section 2"'//pstring) gfld%locallen
643 if ( associated(gfld%local).AND.gfld%locallen.gt.0 ) then
644 do j = 1, gfld%locallen
645 write(*,'(5x,"Local value "'//astring) gfld%local(j)
647 ! print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
649 write(*,'(/,"GRIB2 SECTION 3 - GRID DEFINITION SECTION:")')
650 ! write(*,'(5x,"Length of Section 3"'//pstring) gfld%unknown
651 write(*,'(5x,"Source of grid definition"'&
652 //pstring) gfld%griddef
653 write(*,'(5x,"Number of grid points"'//pstring) gfld%ngrdpts
654 write(*,'(5x,"Number of octets for addnl points"'//pstring) &
656 write(*,'(5x,"Interpretation list"'//pstring) &
658 write(*,'(5x,"Grid Definition Template Number"'//pstring) &
660 if (gfld%igdtnum .eq. 0 .or. gfld%igdtnum .eq. 1 .or. &
661 gfld%igdtnum .eq. 2 .or. gfld%igdtnum .eq. 3 ) then
662 if (gfld%igdtnum .eq. 0 ) then
663 write(*,'(5x,"Lat/Lon or Cylindrical Equidistant Grid")')
664 else if (gfld%igdtnum .eq. 1 ) then
665 write(*,'(5x,"Rotated Lat/Lon or Cylind. Equi. Grid")')
666 else if (gfld%igdtnum .eq. 2 ) then
667 write(*,'(5x,"Stretched Lat/Lon or Cylind. Equi. Grid")')
668 else if (gfld%igdtnum .eq. 3 ) then
669 write(*,'(5x,"Stretched and Rotated Lat/Lon Grid")')
671 write(*,'(10x,"Shape of the Earth"'//pstring) &
673 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
675 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
677 write(*,'(10x,"Scale factor of major axis"'//pstring) &
679 write(*,'(10x,"Scaled value of major axis"'//pstring) &
681 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
683 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
685 write(*,'(10x,"Ni - points along a parallel"'//pstring) &
687 write(*,'(10x,"Nj - points along a meridian"'//pstring) &
689 write(*,'(10x,"Basic angle of initial domain"'//pstring)&
691 write(*,'(10x,"Subdivisions of basic angle"'//pstring) &
693 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(12)
694 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(13)
695 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
697 write(*,'(10x,"La2"'//pstring) gfld%igdtmpl(15)
698 write(*,'(10x,"Lo2"'//pstring) gfld%igdtmpl(16)
699 write(*,'(10x,"Di - i-dir increment"'//pstring) &
701 write(*,'(10x,"Dj - j-dir increment"'//pstring) &
703 write(*,'(10x,"Scanning mode"'//pstring) &
705 if (gfld%igdtnum .eq. 1) then
706 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
708 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
710 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
712 else if (gfld%igdtnum .eq. 2) then
713 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
715 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
717 write(*,'(10x,"Stretching factor"'//pstring) &
719 else if (gfld%igdtnum .eq. 3) then
720 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
722 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
724 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
726 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
728 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
730 write(*,'(10x,"Stretching factor"'//pstring) &
733 else if (gfld%igdtnum .eq. 10) then
734 write(*,'(5x,"Mercator Grid")')
735 else if (gfld%igdtnum .eq. 20 .or. gfld%igdtnum .eq. 30) then
736 if (gfld%igdtnum .eq. 20) then
737 write(*,'(5x,"Polar Stereographic Grid")')
738 else if (gfld%igdtnum .eq. 30) then
739 write(*,'(5x,"Lambert Conformal Grid")')
741 write(*,'(10x,"Shape of the Earth"'//pstring) &
743 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
745 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
747 write(*,'(10x,"Scale factor of major axis"'//pstring) &
749 write(*,'(10x,"Scaled value of major axis"'//pstring) &
751 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
753 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
755 write(*,'(10x,"Nx"'//pstring) gfld%igdtmpl(8)
756 write(*,'(10x,"Ny"'//pstring) gfld%igdtmpl(9)
757 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(10)
758 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(11)
759 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
761 write(*,'(10x,"LaD"'//pstring) gfld%igdtmpl(13)
762 write(*,'(10x,"LoV"'//pstring) gfld%igdtmpl(14)
763 write(*,'(10x,"Dx"'//pstring) gfld%igdtmpl(15)
764 write(*,'(10x,"Dy"'//pstring) gfld%igdtmpl(16)
765 write(*,'(10x,"Projection Center Flag"'//pstring) &
767 write(*,'(10x,"Scanning mode"'//pstring) &
769 if (gfld%igdtnum .eq. 30) then
770 write(*,'(10x,"Latin 1 "'//pstring) &
772 write(*,'(10x,"Latin 2 "'//pstring) &
774 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
776 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
779 else if (gfld%igdtnum .eq. 40 .or. gfld%igdtnum .eq. 41) then
780 if (gfld%igdtnum .eq. 40) then
781 write(*,'(5x,"Gaussian Lat/Lon Grid")')
782 else if (gfld%igdtnum .eq. 41) then
783 write(*,'(5x,"Rotated Gaussian Lat/Lon Grid")')
784 else if (gfld%igdtnum .eq. 42) then
785 write(*,'(5x,"Stretched Gaussian Lat/Lon Grid")')
786 else if (gfld%igdtnum .eq. 43) then
787 write(*,'(5x,"Stretched and Rotated Gaussian Lat/Lon ")')
790 do j = 1, gfld%igdtlen
791 write(*,'(5x,"Grid Definition Template entry "'//pstring) &
795 ! print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts, &
796 ! gfld%numoct_opt,gfld%interp_opt, &
798 ! print *,'G2 GRID TEMPLATE 3.',gfld%igdtnum,': ', &
799 ! (gfld%igdtmpl(j),j=1,gfld%igdtlen)
800 if ( gfld%num_opt .eq. 0 ) then
801 ! print *,'G2 NO Section 3 List Defining No. of Data Points.'
803 print *,'G2 Section 3 Optional List: ', &
804 (gfld%list_opt(j),j=1,gfld%num_opt)
806 write(*,'(/,"GRIB2 SECTION 4 - PRODUCT DEFINITION SECTION:")')
807 ! write(*,'(5x,"Length of Section 4"'//pstring) gfld%unknown
808 write(*,'(5x,"Product Definition Template Number"'//pstring)&
810 do j = 1, gfld%ipdtlen
812 string = '(5x,"Template Entry '//tmp4 // '"'
813 write(*,string//pstring) gfld%ipdtmpl(j)
815 ! print *,'G2 PRODUCT TEMPLATE 4.',gfld%ipdtnum,': ', &
816 ! (gfld%ipdtmpl(j),j=1,gfld%ipdtlen)
818 !call prlevel(gfld%ipdtnum,gfld%ipdtmpl,labbrev)
819 !call prvtime(gfld%ipdtnum,gfld%ipdtmpl,listsec1,tabbrev)
820 write(*,'(5x,"Product Abbreviated Name",t50,":",a14)')&
822 ! print *,'G2 TEXT: ',pabbrev,trim(labbrev)," ",trim(tabbrev)
824 if ( gfld%num_coord .eq. 0 ) then
825 ! print *,'G2 NO Optional Vertical Coordinate List.'
827 print *,'G2 Section 4 Optional Coordinates: ', &
828 (gfld%coord_list(j),j=1,gfld%num_coord)
830 ! if ( gfld%ibmap .ne. 255 ) then
831 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
832 ! ' with BIT-MAP ',gfld%ibmap
834 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
837 write(*,'(/,"GRIB2 SECTION 5 - DATA REPRESENTATION SECTION:")')
838 write(*,'(5x,"Data Representation Template Number"'//pstring)&
840 do j = 1, gfld%idrtlen
842 string = '(5x,"Template Entry '//tmp4 // '"'
843 write(*,string//pstring) gfld%idrtmpl(j)
845 ! print *,'G2 DRS TEMPLATE 5.',gfld%idrtnum,': ', &
846 ! (gfld%idrtmpl(j),j=1,gfld%idrtlen)
848 ! if ( gfld%ipdtnum .eq. 0 ) then
849 ! if (gfld%ipdtmpl(1) .eq. 0 ) then
850 ! write(6,*) 'Temperature'
851 ! else if (gfld%ipdtmpl(1) .eq. 1 ) then
852 ! write(6,*) 'Moisture'
853 ! else if (gfld%ipdtmpl(1) .eq. 2 ) then
854 ! write(6,*) 'Momentum'
855 ! else if (gfld%ipdtmpl(1) .eq. 3 ) then
860 write(*,'(/,"GRIB2 SECTION 6 - BIT-MAP SECTION:")')
861 write(*,'(5x,"Bit-map indicator"'//pstring) &
868 if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
869 if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
873 write(*,'(/,"GRIB2 SECTION 7 - DATA SECTION:")')
875 if ( fldmax .lt. -1.e10 ) then
876 write(*,'(5x,"Minimum Data Value "'//estring)&
879 write(*,'(5x,"Minimum Data Value "'//rstring)&
882 if ( fldmax .gt. 1.e10 ) then
883 write(*,'(5x,"Maximum Data Value "'//estring)&
886 write(*,'(5x,"Maximum Data Value "'//rstring)&
889 ! print *,'G2 Data Values:'
890 ! write(*,fmt='("G2 MIN=",f21.8," AVE=",f21.8, &
891 ! " MAX=",f21.8)') fldmin,sum/gfld%ndpts,fldmax
892 if (debug_level .gt. 100 ) then
893 print*, 'gfld%fld = ',gfld%fld
895 ! write(*,*) j, gfld%fld(j)
898 endif ! Additional Print information
899 ! ------------------------------------
900 if ( debug_level .le. 50) then
901 if(gfld%ipdtmpl(10).eq.100) then ! pressure level
902 level=gfld%ipdtmpl(12) * &
903 (10. ** (-1. * gfld%ipdtmpl(11)))
904 else if(gfld%ipdtmpl(10).eq.101 .or.& ! sea level, sfc, or trop
905 gfld%ipdtmpl(10).eq.1 .or. gfld%ipdtmpl(10).eq.7) then
907 else if(gfld%ipdtmpl(10).eq.106) then ! below ground sfc is in cm in Vtable
908 level= 100. * gfld%ipdtmpl(12)*(10.**(-1.*gfld%ipdtmpl(11)))
910 level=gfld%ipdtmpl(12) * 10.** (-1.*gfld%ipdtmpl(11))
912 if (gfld%ipdtmpl(13) .eq. 255) then
914 else if(gfld%ipdtmpl(10).eq.106) then ! below ground sfc is in cm in Vtable
915 lvl2 = 100. * gfld%ipdtmpl(15) * 10.** (-1.*gfld%ipdtmpl(14))
917 lvl2 = gfld%ipdtmpl(15) * 10.** (-1.*gfld%ipdtmpl(14))
919 ! Account for multiple forecast hours in one file
920 if (gfld%ipdtnum.eq.0 .or. gfld%ipdtnum.eq.1 .or. gfld%ipdtnum.eq. 8) then
921 ! Product Definition Template 4.0, 4.1, 4.8
922 ! Extract forecast time.
923 if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
924 fcst = gfld%ipdtmpl(9)
925 else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
926 fcst = gfld%ipdtmpl(9) / 60.
927 else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
928 fcst = gfld%ipdtmpl(9) * 24.
934 ! Non-standard Product Definition Templates need to be reported
936 if ( gfld%ipdtnum .eq. 8 ) then
938 else if ( gfld%ipdtnum .eq. 1 ) then
941 write(6,987) itot,gfld%discipline,gfld%ipdtmpl(1), &
942 gfld%ipdtmpl(2),gfld%ipdtmpl(10),int(level),&
943 lvl2,gfld%ipdtnum,pabbrev,hdate,fcst,string
944 987 format(2i4,i5,i4,i8,i8,i8,i8,3x,a10,a20,i5.2,a10)
948 ! Deallocate arrays decoding GRIB2 record.
955 if (debug_level .gt. 50) &
956 print *, 'G2 total number of fields found = ',itot
958 CALL BACLOSE(junit,IOS)
962 print *,'open status failed because',ios
963 hdate = '9999-99-99_99:99:99'
965 endif ! ireaderr check
967 END subroutine r_grib2
969 !*****************************************************************************!
970 ! Subroutine edition_num !
973 ! Read one record from the input GRIB2 file. Based on the information in !
974 ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
975 ! the GRIB2 record is one to process or to skip. If the field is one we !
976 ! want to keep, extract the data from the GRIB2 record, and pass the data !
977 ! back to the calling routine. !
981 ! JUNIT : "Unit Number" to open and read from. Not really a Fortran !
982 ! unit number, since we do not do Fortran I/O for the GRIB2 !
983 ! files. Nor is it a UNIX File Descriptor returned from a C !
984 ! OPEN statement. It is really just an array index to the !
985 ! array (IUARR) where the UNIX File Descriptor values are !
987 ! GRIB2FILE: File name to open, if it is not already open. !
990 ! GRIB_EDITION: Set to 1 for GRIB and set to 2 for GRIB2 !
991 ! IERR : Error flag: 0 - no error on read from GRIB2 file. !
992 ! 1 - Hit the end of the GRIB2 file. !
993 ! 2 - The file GRIBFLNM we tried to open does !
995 ! Author: Paula McCaslin !
998 !*****************************************************************************!
1000 SUBROUTINE edition_num(junit, gribflnm, grib_edition, ireaderr)
1005 parameter(msk1=32000,msk2=4000)
1006 character(len=1),allocatable,dimension(:) :: cgrib
1007 integer :: listsec0(3)
1008 integer :: listsec1(13)
1009 character(len=*) :: gribflnm
1010 integer :: lskip, lgrib
1012 integer :: grib_edition
1013 integer :: i, j, ireaderr
1016 character(len=4) :: ctemp
1017 character(len=4),parameter :: grib='GRIB',c7777='7777'
1019 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1029 !/* IOS Return Codes from BACIO: */
1030 !/* 0 All was well */
1031 !/* -1 Tried to open read only _and_ write only */
1032 !/* -2 Tried to read and write in the same call */
1033 !/* -3 Internal failure in name processing */
1034 !/* -4 Failure in opening file */
1035 !/* -5 Tried to read on a write-only file */
1036 !/* -6 Failed in read to find the 'start' location */
1037 !/* -7 Tried to write to a read only file */
1038 !/* -8 Failed in write to find the 'start' location */
1039 !/* -9 Error in close */
1040 !/* -10 Read or wrote fewer data than requested */
1042 !if ireaderr =1 we have hit the end of a file.
1043 !if ireaderr =2 we have hit the end of all the files.
1044 !if ireaderr =3 beginning characters 'GRIB' not found
1046 ! write(6,*) 'junit = ',junit,' gribflnm = ',gribflnm
1048 ! Open a byte-addressable file.
1049 CALL BAOPENR(junit,gribflnm,IOS) ! from w3lib
1050 ! write(6,*) 'ios = ',ios
1053 ! Search opend file for the next GRIB2 messege (record).
1054 call skgb(junit,iseek,msk1,lskip,lgrib)
1056 ! Check for EOF, or problem
1057 if (lgrib.eq.0) then
1058 write(*,'("\n\tThere is a problem with the input file.")')
1059 write(*,'("\tPerhaps it is not a Grib2 file?\n")')
1060 STOP "Grib2 file or date problem, stopping in edition_num."
1063 ! Check size, if needed allocate more memory.
1064 if (lgrib.gt.currlen) then
1065 if (allocated(cgrib)) deallocate(cgrib)
1066 allocate(cgrib(lgrib),stat=is)
1070 ! Read a given number of bytes from unblocked file.
1071 call baread(junit,lskip,lgrib,lengrib,cgrib)
1073 ! Check for beginning of GRIB message in the first 100 bytes
1076 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
1077 if (ctemp.eq.grib ) then
1082 if (istart.eq.0) then
1084 print*, "The beginning 4 characters >GRIB< were not found."
1087 ! Unpack Section 0 - Indicator Section to extract GRIB edition field
1089 call gbyte(cgrib,discipline,iofst,8) ! Discipline
1091 call gbyte(cgrib,grib_edition,iofst,8) ! GRIB edition number
1093 print *, 'ungrib - grib edition num', grib_edition
1094 CALL BACLOSE(junit,IOS)
1096 else if (ios .eq. -4) then
1097 print *,'edition_num: unable to open ',gribflnm
1100 print *,'edition_num: open status failed because',ios,gribflnm
1102 endif ! ireaderr check
1104 END subroutine edition_num
1105 subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2, a3, h3, i3, l3, &
1108 character(len=*) , optional :: a1, a2, a3
1109 character(len=*), optional :: h1, h2, h3
1110 integer , optional :: i1, i2, i3
1111 logical, optional :: l1, l2, l3
1112 character(len=*), optional :: hlast
1114 character(len=100) :: hold
1117 if (present(hlast)) then
1124 numarg = narg + ioff
1127 LOOP : do while ( i <= numarg)
1130 if (present(i1)) then
1131 call checkiarg(i, a1, i1, ierr)
1132 elseif (present(h1)) then
1133 call checkharg(i, a1, h1, ierr)
1134 elseif (present(l1)) then
1135 call checklarg(i, a1, l1, ierr)
1137 if (ierr.eq.0) cycle LOOP
1139 if (present(i2)) then
1140 call checkiarg(i, a2, i2, ierr)
1141 elseif (present(h2)) then
1142 call checkharg(i, a2, h2, ierr)
1143 elseif (present(l2)) then
1144 call checklarg(i, a2, l2, ierr)
1146 if (ierr.eq.0) cycle LOOP
1148 if (present(i3)) then
1149 call checkiarg(i, a3, i3, ierr)
1150 elseif (present(h3)) then
1151 call checkharg(i, a3, h3, ierr)
1152 elseif (present(l3)) then
1153 call checklarg(i, a3, l3, ierr)
1155 if (ierr.eq.0) cycle LOOP
1158 call getarg(1, hold)
1159 write(*, '("arg = ", A)') trim(hold)
1165 if (present(hlast)) then
1169 call getarg(narg, hlast)
1174 subroutine checkiarg(c, a, i, ierr)
1176 character(len=*) :: a
1179 character(len=100) :: hold
1182 call getarg(c, hold)
1184 if ('-'//a.eq.trim(hold)) then
1186 call getarg(c, hold)
1190 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1191 hold = hold(len_trim(a)+2: len(hold))
1197 end subroutine checkiarg
1198 subroutine checkharg(c, a, h, ierr)
1200 character(len=*) :: a
1201 character(len=*) :: h
1203 character(len=100) :: hold
1206 call getarg(c, hold)
1208 if ('-'//a.eq.trim(hold)) then
1210 call getarg(c, hold)
1214 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1215 hold = hold(len_trim(a)+2: len(hold))
1221 end subroutine checkharg
1223 subroutine checklarg(c, a, l, ierr)
1225 character(len=*) :: a
1228 character(len=100) :: hold
1231 call getarg(c, hold)
1232 if ('-'//a.eq.trim(hold)) then
1238 end subroutine checklarg
1240 end subroutine parse_args