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 = 100
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 outout
175 integer , parameter :: maxlvl = 100
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)'
188 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
191 if (debug_level .gt. 50 ) then
197 hdate = '0000-00-00_00:00:00'
208 ! write(6,'("j = ",i4," level1 = ",i8," level2 = ",i8)') j, &
209 ! level1(j), level2(j)
212 !/* IOS Return Codes from BACIO: */
213 !/* 0 All was well */
214 !/* -1 Tried to open read only _and_ write only */
215 !/* -2 Tried to read and write in the same call */
216 !/* -3 Internal failure in name processing */
217 !/* -4 Failure in opening file */
218 !/* -5 Tried to read on a write-only file */
219 !/* -6 Failed in read to find the 'start' location */
220 !/* -7 Tried to write to a read only file */
221 !/* -8 Failed in write to find the 'start' location */
222 !/* -9 Error in close */
223 !/* -10 Read or wrote fewer data than requested */
225 !if ireaderr =1 we have hit the end of a file.
226 !if ireaderr =2 we have hit the end of all the files.
229 if ( debug_level .gt. 100 ) verbose = .true.
230 if (verbose) write(6,*) 'begin r_grib2, flnm = ',gribflnm
231 ! Open a byte-addressable file.
232 CALL BAOPENR(junit,gribflnm,IOS)
234 if (verbose) write(6,*) 'back from baopenr, ios = ',ios
238 ! Search opend file for the next GRIB2 messege (record).
239 if (verbose) write(6,*) 'calling skgb'
240 call skgb(junit,iseek,msk1,lskip,lgrib)
242 ! Check for EOF, or problem
247 ! Check size, if needed allocate more memory.
248 if (lgrib.gt.currlen) then
249 if (allocated(cgrib)) deallocate(cgrib)
250 allocate(cgrib(lgrib),stat=is)
251 !print *,'G2 allocate(cgrib(lgrib)) status: ',IS
255 ! Read a given number of bytes from unblocked file.
256 call baread(junit,lskip,lgrib,lengrib,cgrib)
258 if (lgrib.ne.lengrib) then
259 print *,'G2 r_grib2: IO Error.',lgrib,".ne.",lengrib
265 if (verbose) PRINT *,'G2 GRIB MESSAGE ',icount,' starts at',lskip+1
268 call gb_info(cgrib,lengrib,listsec0,listsec1, &
269 numfields,numlocal,maxlocal,ierr)
271 write(*,*) ' ERROR querying GRIB2 message = ',ierr
276 grib_edition=listsec0(2)
277 if (grib_edition.ne.2) then
281 ! Additional print statments for developer.
283 print *,'G2 SECTION 0: ',(listsec0(j),j=1,3)
284 print *,'G2 SECTION 1: ',(listsec1(j),j=1,13)
285 print *,'G2 Contains ',numlocal,' Local Sections ', &
286 ' and ',numfields,' data fields.'
290 ! Once per file fill in date, model and projection values.
295 ! Build the 19-character date string, based on GRIB2 header date
296 ! and time information, including forecast time information:
299 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
301 if (debug_level .gt. 100 ) then
302 write(6,*) 'gfld%version = ',gfld%version
303 if (gfld%discipline .eq. 0) then
304 string = 'Meteorological products'
305 else if (gfld%discipline .eq. 1) then
306 string = 'Hydrological products'
307 else if (gfld%discipline .eq. 2) then
308 string = 'Land Surface products'
310 string = 'See code table 0.0'
312 write(6,*) 'Discipline = ',gfld%discipline,' ',string
313 write(6,*) 'gfld%idsect(1) = ',gfld%idsect(1)
314 write(6,*) 'gfld%idsect(2) = ',gfld%idsect(2)
315 write(6,*) 'gfld%idsect(3) = ',gfld%idsect(3)
316 write(6,*) 'gfld%idsect(4) = ',gfld%idsect(4)
317 write(6,*) 'gfld%idsect(5) = ',gfld%idsect(5)
318 write(6,*) 'gfld%idsect(6) = ',gfld%idsect(6)
319 write(6,*) 'gfld%idsect(7) = ',gfld%idsect(7)
320 write(6,*) 'gfld%idsect(8) = ',gfld%idsect(8)
321 write(6,*) 'gfld%idsect(9) = ',gfld%idsect(9)
322 write(6,*) 'gfld%idsect(10) = ',gfld%idsect(10)
323 write(6,*) 'gfld%idsect(11) = ',gfld%idsect(11)
324 write(6,*) 'gfld%idsect(12) = ',gfld%idsect(12)
325 write(6,*) 'gfld%idsect(13) = ',gfld%idsect(13)
327 write(6,*) 'gfld%idsectlen = ',gfld%idsectlen
328 write(6,*) 'gfld%locallen = ',gfld%locallen
329 write(6,*) 'gfld%ifldnum = ',gfld%ifldnum
330 write(6,*) 'gfld%ngrdpts = ',gfld%ngrdpts
331 write(6,*) 'gfld%numoct_opt = ',gfld%numoct_opt
332 write(6,*) 'gfld%interp_opt = ',gfld%interp_opt
334 write(6,*) 'gfld%griddef = ',gfld%griddef
335 if (gfld%igdtnum .eq. 0) then
336 string = 'Lat/Lon cylindrical equidistant'
337 else if (gfld%igdtnum .eq. 1) then
338 string = 'Rotated Lat/Lon'
339 else if (gfld%igdtnum .eq. 2) then
340 string = 'Stretched Lat/Lon'
341 else if (gfld%igdtnum .eq. 20) then
342 string = 'Polar Stereographic'
343 else if (gfld%igdtnum .eq. 30) then
344 string = 'Lambert Conformal'
345 else if (gfld%igdtnum .eq. 40) then
346 string = 'Gaussian Lat/Lon'
347 else if (gfld%igdtnum .eq. 50) then
348 string = 'Spherical harmonic coefficients'
350 string = 'see code table 3.1'
352 write(6,*) 'Grid Template number = ',gfld%igdtnum,' ',string
353 write(6,*) 'gfld%igdtlen = ',gfld%igdtlen
354 do i = 1, gfld%igdtlen
355 write(6,*) 'gfld%igdtmpl(',i,') = ',gfld%igdtmpl(i)
358 write(6,*) 'gfld%ipdtnum = ',gfld%ipdtnum
359 write(6,*) 'gfld%ipdtlen = ',gfld%ipdtlen
360 if ( gfld%ipdtnum .eq. 0 ) then
361 do i = 1, gfld%ipdtlen
362 write(6,*) 'gfld%ipdtmpl(',i,') = ',gfld%ipdtmpl(i)
365 write(6,*) 'gfld%num_coord = ',gfld%num_coord
366 write(6,*) 'gfld%ndpts = ',gfld%ndpts
367 write(6,*) 'gfld%idrtnum = ',gfld%idrtnum
368 write(6,*) 'gfld%idrtlen = ',gfld%idrtlen
369 write(6,*) 'gfld%expanded = ',gfld%expanded
370 write(6,*) 'gfld%ibmap = ',gfld%ibmap
373 if (debug_level .le. 50) then
374 write(6,*) '---------------------------------------------------------------------------------------'
375 write(6,*) ' rec Prod Cat Param Lvl Lvl Lvl Prod Name Time Fcst'
376 write(6,*) ' num Disc num code one two Templ hour'
377 write(6,*) '---------------------------------------------------------------------------------------'
380 year =gfld%idsect(6) !(FOUR-DIGIT) YEAR OF THE DATA
381 month =gfld%idsect(7) ! MONTH OF THE DATA
382 day =gfld%idsect(8) ! DAY OF THE DATA
383 hour =gfld%idsect(9) ! HOUR OF THE DATA
384 minute=gfld%idsect(10) ! MINUTE OF THE DATA
385 second=gfld%idsect(11) ! SECOND OF THE DATA
389 ! Extract forecast time.
390 if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
391 fcst = gfld%ipdtmpl(9)
392 else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
393 fcst = gfld%ipdtmpl(9) / 60.
394 else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
395 fcst = gfld%ipdtmpl(9) * 24.
400 ! Compute valid time.
403 print *, 'ymd',gfld%idsect(6),gfld%idsect(7),gfld%idsect(8)
404 print *, 'hhmm ',gfld%idsect(9),gfld%idsect(10)
407 call build_hdate(hdate,year,month,day,hour,minute,second)
408 if (verbose) print *, 'G2 hdate = ',hdate
409 ! call geth_newdate(hdate,hdate,3600*fcst) ! no need for thin in print
410 ! print *, 'G2 hdate (fcst?) = ',hdate
414 ! Indicator of the source (center) of the data.
415 icenter = gfld%idsect(1)
417 ! Indicator of model (or whatever) which generated the data.
418 iprocess = gfld%ipdtmpl(5)
421 if (icenter.eq.7) then
422 if (iprocess.eq.83 .or. iprocess.eq.84) then
423 map%source = 'NCEP NAM Model'
424 elseif (iprocess.eq.81) then
425 map%source = 'NCEP GFS Model'
426 elseif (iprocess.eq.82) then
427 map%source = 'NCEP GFS GDAS'
428 elseif (iprocess.eq.96) then
429 map%source = 'NCEP GFS Model'
430 elseif (iprocess.eq.86 .or. iprocess.eq.100) then
431 map%source = 'NCEP RUC Model' ! 60 km
432 elseif (iprocess.eq.101) then
433 map%source = 'NCEP RUC Model' ! 40 km
434 elseif (iprocess.eq.105) then
435 map%source = 'NCEP RUC Model' ! 20 km
436 elseif (iprocess.eq.107) then
437 map%source = 'NCEP GEFS'
438 elseif (iprocess.eq.109) then
439 map%source = 'NCEP RTMA'
440 elseif (iprocess.eq.140) then
441 map%source = 'NCEP NARR'
442 elseif (iprocess.eq.44) then
443 map%source = 'NCEP SST Analysis'
444 elseif (iprocess.eq.70) then
445 map%source = 'GFDL Hurricane Model'
446 elseif (iprocess.eq.80) then
447 map%source = 'NCEP GFS Ensemble'
448 elseif (iprocess.eq.107) then ! renumbered as of 23 Feb 2010
449 map%source = 'NCEP GFS Ensemble'
450 elseif (iprocess.eq.129) then
451 map%source = 'NCEP GODAS'
452 elseif (iprocess.eq.25) then
453 map%source = 'NCEP SNOW COVER ANALYSIS'
455 map%source = 'unknown model from NCEP'
456 write (6,*) 'unknown NCEP model, iprocess = ',iprocess
458 else if (icenter .eq. 57) then
459 if (iprocess .eq. 87) then
460 map%source = 'AFWA AGRMET'
464 else if (icenter .eq. 58) then
465 map%source = 'US Navy FNOC'
466 else if (icenter .eq. 98) then
468 else if (icenter .eq. 34) then
470 else if (icenter .eq. 74 .or. icenter .eq. 75 ) then
473 map%source = 'unknown model and orig center'
478 ! Store information about the grid on which the data is.
479 ! This stuff gets stored in the MAP variable, as defined in
482 map%startloc = 'SWCORNER'
484 if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
486 map%nx = gfld%igdtmpl(8)
487 map%ny = gfld%igdtmpl(9)
488 map%dx = gfld%igdtmpl(17)
489 map%dy = gfld%igdtmpl(18)
490 map%lat1 = gfld%igdtmpl(12)
491 map%lon1 = gfld%igdtmpl(13)
493 if ((gfld%igdtmpl(10) .eq. 0).OR. &
494 (gfld%igdtmpl(10) .eq. 255)) THEN
495 ! Scale lat/lon values to 0-180, default range is 1e6.
496 map%lat1 = map%lat1/scale_factor
497 map%lon1 = map%lon1/scale_factor
498 ! Scale dx/dy values to degrees, default range is 1e6.
499 map%dx = map%dx/scale_factor
500 map%dy = map%dy/scale_factor
502 ! Basic angle and subdivisions are non-zero (not tested)
503 map%lat1 = map%lat1 * &
504 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
505 map%lon1 = map%lon1 * &
506 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
508 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
510 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
513 elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
515 map%nx = gfld%igdtmpl(8)
516 map%ny = gfld%igdtmpl(9)
517 map%lov = gfld%igdtmpl(14)
518 map%truelat1 = gfld%igdtmpl(19)
519 map%truelat2 = gfld%igdtmpl(20)
520 map%dx = gfld%igdtmpl(15)
521 map%dy = gfld%igdtmpl(16)
522 map%lat1 = gfld%igdtmpl(10)
523 map%lon1 = gfld%igdtmpl(11)
525 elseif(gfld%igdtnum.eq.40) then ! Gaussian Grid (we will call it lat/lon)
527 map%nx = gfld%igdtmpl(8)
528 map%ny = gfld%igdtmpl(9)
529 map%dx = gfld%igdtmpl(17)
530 map%dy = gfld%igdtmpl(18) ! ?not in Grid Definition Template 3.40 doc
531 map%lat1 = gfld%igdtmpl(12)
532 map%lon1 = gfld%igdtmpl(13)
534 ! Scale dx/dy values to degrees, default range is 1e6.
535 if (map%dx.gt.10000) then
536 map%dx = map%dx/scale_factor
538 if (map%dy.gt.10000) then
539 map%dy = (map%dy/scale_factor)*(-1)
542 ! Scale lat/lon values to 0-180, default range is 1e6.
543 if (map%lat1.ge.scale_factor) then
544 map%lat1 = map%lat1/scale_factor
546 if (map%lon1.ge.scale_factor) then
547 map%lon1 = map%lon1/scale_factor
549 print *,'Gaussian Grid: Dx,Dy,lat,lon',map%dx,map%dy, &
552 elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
554 map%nx = gfld%igdtmpl(8)
555 map%ny = gfld%igdtmpl(9)
556 !map%lov = gfld%igdtmpl(x) ! ?not in Grid Definition Template 3.20 doc
559 !map%dx = gfld%igdtmpl(x)
560 !map%dy = gfld%igdtmpl(x)
561 map%lat1 = gfld%igdtmpl(10)
562 map%lon1 = gfld%igdtmpl(11)
565 print*, 'GRIB2 Unknown Projection: ',gfld%igdtnum
566 print*, 'see Code Table 3.1: Grid Definition Template No'
574 ! Continue to unpack GRIB2 field.
575 if (debug_level .gt. 100) write(6,*) 'numfields = ',numfields
576 do n=1,numfields ! e.g. U and V would =2, otherwise its usually =1
577 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
579 write(*,*) ' ERROR extracting field gf_getfld = ',ierr
583 ! ------------------------------------
584 ! Additional print information for developer.
585 pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1), &
587 if (debug_level .gt. 50 ) then
589 ! print *,'G2 FIELD ',n
591 write(*,'(/,"GRIB2 SECTION 0 - INDICATOR SECTION:")')
592 write(*,'(5x,"Discipline"'//pstring) gfld%discipline
593 write(*,'(5x,"GRIB Edition Number"'//pstring) gfld%version
594 write(*,'(5x,"GRIB length"'//pstring) lengrib
595 write(*,'(/,"GRIB2 SECTION 1 - IDENTIFICATION SECTION:")')
596 write(*,'(5x,"Length of Section"'//pstring) gfld%idsectlen
597 write(*,'(5x,"Originating Center ID"'//pstring) &
599 write(*,'(5x,"Subcenter ID"'//pstring) gfld%idsect(2)
600 write(*,'(5x,"GRIB Master Table Version"'//pstring) &
602 write(*,'(5x,"GRIB Local Table Version"'//pstring) &
604 write(*,'(5x,"Significance of Reference Time"'//pstring) &
606 write(*,'(5x,"Year"'//pstring) gfld%idsect(6)
607 write(*,'(5x,"Month"'//pstring) gfld%idsect(7)
608 write(*,'(5x,"Day"'//pstring) gfld%idsect(8)
609 write(*,'(5x,"Hour"'//pstring) gfld%idsect(9)
610 write(*,'(5x,"Minute"'//pstring) gfld%idsect(10)
611 write(*,'(5x,"Second"'//pstring) gfld%idsect(11)
612 write(*,'(5x,"Production Status of data"'//pstring) &
614 write(*,'(5x,"Type of processed data"'//pstring) &
616 ! print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
618 write(*,'(/,"GRIB2 SECTION 2 - LOCAL SECTION:")')
619 write(*,'(5x,"Length of Section 2"'//pstring) gfld%locallen
620 if ( associated(gfld%local).AND.gfld%locallen.gt.0 ) then
621 do j = 1, gfld%locallen
622 write(*,'(5x,"Local value "'//astring) gfld%local(j)
624 ! print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
626 write(*,'(/,"GRIB2 SECTION 3 - GRID DEFINITION SECTION:")')
627 ! write(*,'(5x,"Length of Section 3"'//pstring) gfld%unknown
628 write(*,'(5x,"Source of grid definition"'&
629 //pstring) gfld%griddef
630 write(*,'(5x,"Number of grid points"'//pstring) gfld%ngrdpts
631 write(*,'(5x,"Number of octets for addnl points"'//pstring) &
633 write(*,'(5x,"Interpretation list"'//pstring) &
635 write(*,'(5x,"Grid Definition Template Number"'//pstring) &
637 if (gfld%igdtnum .eq. 0 .or. gfld%igdtnum .eq. 1 .or. &
638 gfld%igdtnum .eq. 2 .or. gfld%igdtnum .eq. 3 ) then
639 if (gfld%igdtnum .eq. 0 ) then
640 write(*,'(5x,"Lat/Lon or Cylindrical Equidistant Grid")')
641 else if (gfld%igdtnum .eq. 1 ) then
642 write(*,'(5x,"Rotated Lat/Lon or Cylind. Equi. Grid")')
643 else if (gfld%igdtnum .eq. 2 ) then
644 write(*,'(5x,"Stretched Lat/Lon or Cylind. Equi. Grid")')
645 else if (gfld%igdtnum .eq. 3 ) then
646 write(*,'(5x,"Stretched and Rotated Lat/Lon Grid")')
648 write(*,'(10x,"Shape of the Earth"'//pstring) &
650 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
652 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
654 write(*,'(10x,"Scale factor of major axis"'//pstring) &
656 write(*,'(10x,"Scaled value of major axis"'//pstring) &
658 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
660 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
662 write(*,'(10x,"Ni - points along a parallel"'//pstring) &
664 write(*,'(10x,"Nj - points along a meridian"'//pstring) &
666 write(*,'(10x,"Basic angle of initial domain"'//pstring)&
668 write(*,'(10x,"Subdivisions of basic angle"'//pstring) &
670 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(12)
671 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(13)
672 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
674 write(*,'(10x,"La2"'//pstring) gfld%igdtmpl(15)
675 write(*,'(10x,"Lo2"'//pstring) gfld%igdtmpl(16)
676 write(*,'(10x,"Di - i-dir increment"'//pstring) &
678 write(*,'(10x,"Dj - j-dir increment"'//pstring) &
680 write(*,'(10x,"Scanning mode"'//pstring) &
682 if (gfld%igdtnum .eq. 1) then
683 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
685 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
687 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
689 else if (gfld%igdtnum .eq. 2) then
690 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
692 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
694 write(*,'(10x,"Stretching factor"'//pstring) &
696 else if (gfld%igdtnum .eq. 3) then
697 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
699 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
701 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
703 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
705 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
707 write(*,'(10x,"Stretching factor"'//pstring) &
710 else if (gfld%igdtnum .eq. 10) then
711 write(*,'(5x,"Mercator Grid")')
712 else if (gfld%igdtnum .eq. 20 .or. gfld%igdtnum .eq. 30) then
713 if (gfld%igdtnum .eq. 20) then
714 write(*,'(5x,"Polar Stereographic Grid")')
715 else if (gfld%igdtnum .eq. 30) then
716 write(*,'(5x,"Lambert Conformal Grid")')
718 write(*,'(10x,"Shape of the Earth"'//pstring) &
720 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
722 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
724 write(*,'(10x,"Scale factor of major axis"'//pstring) &
726 write(*,'(10x,"Scaled value of major axis"'//pstring) &
728 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
730 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
732 write(*,'(10x,"Nx"'//pstring) gfld%igdtmpl(8)
733 write(*,'(10x,"Ny"'//pstring) gfld%igdtmpl(9)
734 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(10)
735 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(11)
736 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
738 write(*,'(10x,"LaD"'//pstring) gfld%igdtmpl(13)
739 write(*,'(10x,"LoV"'//pstring) gfld%igdtmpl(14)
740 write(*,'(10x,"Dx"'//pstring) gfld%igdtmpl(15)
741 write(*,'(10x,"Dy"'//pstring) gfld%igdtmpl(16)
742 write(*,'(10x,"Projection Center Flag"'//pstring) &
744 write(*,'(10x,"Scanning mode"'//pstring) &
746 if (gfld%igdtnum .eq. 30) then
747 write(*,'(10x,"Latin 1 "'//pstring) &
749 write(*,'(10x,"Latin 2 "'//pstring) &
751 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
753 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
756 else if (gfld%igdtnum .eq. 40 .or. gfld%igdtnum .eq. 41) then
757 if (gfld%igdtnum .eq. 40) then
758 write(*,'(5x,"Gaussian Lat/Lon Grid")')
759 else if (gfld%igdtnum .eq. 41) then
760 write(*,'(5x,"Rotated Gaussian Lat/Lon Grid")')
761 else if (gfld%igdtnum .eq. 42) then
762 write(*,'(5x,"Stretched Gaussian Lat/Lon Grid")')
763 else if (gfld%igdtnum .eq. 43) then
764 write(*,'(5x,"Stretched and Rotated Gaussian Lat/Lon ")')
767 do j = 1, gfld%igdtlen
768 write(*,'(5x,"Grid Definition Template entry "'//pstring) &
772 ! print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts, &
773 ! gfld%numoct_opt,gfld%interp_opt, &
775 ! print *,'G2 GRID TEMPLATE 3.',gfld%igdtnum,': ', &
776 ! (gfld%igdtmpl(j),j=1,gfld%igdtlen)
777 if ( gfld%num_opt .eq. 0 ) then
778 ! print *,'G2 NO Section 3 List Defining No. of Data Points.'
780 print *,'G2 Section 3 Optional List: ', &
781 (gfld%list_opt(j),j=1,gfld%num_opt)
783 write(*,'(/,"GRIB2 SECTION 4 - PRODUCT DEFINITION SECTION:")')
784 ! write(*,'(5x,"Length of Section 4"'//pstring) gfld%unknown
785 write(*,'(5x,"Product Definition Template Number"'//pstring)&
787 do j = 1, gfld%ipdtlen
789 string = '(5x,"Template Entry '//tmp4 // '"'
790 write(*,string//pstring) gfld%ipdtmpl(j)
792 ! print *,'G2 PRODUCT TEMPLATE 4.',gfld%ipdtnum,': ', &
793 ! (gfld%ipdtmpl(j),j=1,gfld%ipdtlen)
795 !call prlevel(gfld%ipdtnum,gfld%ipdtmpl,labbrev)
796 !call prvtime(gfld%ipdtnum,gfld%ipdtmpl,listsec1,tabbrev)
797 write(*,'(5x,"Product Abbreviated Name",t50,":",a14)')&
799 ! print *,'G2 TEXT: ',pabbrev,trim(labbrev)," ",trim(tabbrev)
801 if ( gfld%num_coord .eq. 0 ) then
802 ! print *,'G2 NO Optional Vertical Coordinate List.'
804 print *,'G2 Section 4 Optional Coordinates: ', &
805 (gfld%coord_list(j),j=1,gfld%num_coord)
807 ! if ( gfld%ibmap .ne. 255 ) then
808 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
809 ! ' with BIT-MAP ',gfld%ibmap
811 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
814 write(*,'(/,"GRIB2 SECTION 5 - DATA REPRESENTATION SECTION:")')
815 write(*,'(5x,"Data Representation Template Number"'//pstring)&
817 do j = 1, gfld%idrtlen
819 string = '(5x,"Template Entry '//tmp4 // '"'
820 write(*,string//pstring) gfld%idrtmpl(j)
822 ! print *,'G2 DRS TEMPLATE 5.',gfld%idrtnum,': ', &
823 ! (gfld%idrtmpl(j),j=1,gfld%idrtlen)
825 ! if ( gfld%ipdtnum .eq. 0 ) then
826 ! if (gfld%ipdtmpl(1) .eq. 0 ) then
827 ! write(6,*) 'Temperature'
828 ! else if (gfld%ipdtmpl(1) .eq. 1 ) then
829 ! write(6,*) 'Moisture'
830 ! else if (gfld%ipdtmpl(1) .eq. 2 ) then
831 ! write(6,*) 'Momentum'
832 ! else if (gfld%ipdtmpl(1) .eq. 3 ) then
837 write(*,'(/,"GRIB2 SECTION 6 - BIT-MAP SECTION:")')
838 write(*,'(5x,"Bit-map indicator"'//pstring) &
845 if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
846 if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
850 write(*,'(/,"GRIB2 SECTION 7 - DATA SECTION:")')
852 write(*,'(5x,"Minimum Data Value "'//rstring)&
854 write(*,'(5x,"Maximum Data Value "'//rstring)&
856 ! print *,'G2 Data Values:'
857 ! write(*,fmt='("G2 MIN=",f21.8," AVE=",f21.8, &
858 ! " MAX=",f21.8)') fldmin,sum/gfld%ndpts,fldmax
859 if (debug_level .gt. 100 ) then
860 print*, 'gfld%fld = ',gfld%fld
862 ! write(*,*) j, gfld%fld(j)
865 endif ! Additional Print information
866 ! ------------------------------------
867 if ( debug_level .le. 50) then
868 if(gfld%ipdtmpl(10).eq.100) then ! pressure level
869 level=gfld%ipdtmpl(12) * &
870 (10. ** (-1. * gfld%ipdtmpl(11)))
871 else if(gfld%ipdtmpl(10).eq.101 .or.& ! sea level, sfc, or trop
872 gfld%ipdtmpl(10).eq.1 .or. gfld%ipdtmpl(10).eq.7) then
875 level=gfld%ipdtmpl(12)
877 if (gfld%ipdtmpl(13) .eq. 255) then
880 lvl2 = gfld%ipdtmpl(15)
882 ! Account for multiple forecast hours in one file
883 if (gfld%ipdtnum.eq.0 .or. gfld%ipdtnum.eq.1 .or. gfld%ipdtnum.eq. 8) then
884 ! Product Definition Template 4.0, 4.1, 4.8
885 ! Extract forecast time.
886 if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
887 fcst = gfld%ipdtmpl(9)
888 else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
889 fcst = gfld%ipdtmpl(9) / 60.
890 else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
891 fcst = gfld%ipdtmpl(9) * 24.
897 write(6,987) itot,gfld%discipline,gfld%ipdtmpl(1), &
898 gfld%ipdtmpl(2),gfld%ipdtmpl(10),int(level),&
899 lvl2,gfld%ipdtnum,pabbrev,hdate,fcst
900 987 format(2i4,i5,i4,i8,i8,i8,i8,3x,a10,a20,i5.2)
903 ! Deallocate arrays decoding GRIB2 record.
910 if (debug_level .gt. 50) &
911 print *, 'G2 total number of fields found = ',itot
913 CALL BACLOSE(junit,IOS)
917 print *,'open status failed because',ios
918 hdate = '9999-99-99_99:99:99'
920 endif ! ireaderr check
922 END subroutine r_grib2
924 !*****************************************************************************!
925 ! Subroutine edition_num !
928 ! Read one record from the input GRIB2 file. Based on the information in !
929 ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
930 ! the GRIB2 record is one to process or to skip. If the field is one we !
931 ! want to keep, extract the data from the GRIB2 record, and pass the data !
932 ! back to the calling routine. !
936 ! JUNIT : "Unit Number" to open and read from. Not really a Fortran !
937 ! unit number, since we do not do Fortran I/O for the GRIB2 !
938 ! files. Nor is it a UNIX File Descriptor returned from a C !
939 ! OPEN statement. It is really just an array index to the !
940 ! array (IUARR) where the UNIX File Descriptor values are !
942 ! GRIB2FILE: File name to open, if it is not already open. !
945 ! GRIB_EDITION: Set to 1 for GRIB and set to 2 for GRIB2 !
946 ! IERR : Error flag: 0 - no error on read from GRIB2 file. !
947 ! 1 - Hit the end of the GRIB2 file. !
948 ! 2 - The file GRIBFLNM we tried to open does !
950 ! Author: Paula McCaslin !
953 !*****************************************************************************!
955 SUBROUTINE edition_num(junit, gribflnm, grib_edition, ireaderr)
960 parameter(msk1=32000,msk2=4000)
961 character(len=1),allocatable,dimension(:) :: cgrib
962 integer :: listsec0(3)
963 integer :: listsec1(13)
964 character(len=*) :: gribflnm
965 integer :: lskip, lgrib
967 integer :: grib_edition
968 integer :: i, j, ireaderr
971 character(len=4) :: ctemp
972 character(len=4),parameter :: grib='GRIB',c7777='7777'
974 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
984 !/* IOS Return Codes from BACIO: */
985 !/* 0 All was well */
986 !/* -1 Tried to open read only _and_ write only */
987 !/* -2 Tried to read and write in the same call */
988 !/* -3 Internal failure in name processing */
989 !/* -4 Failure in opening file */
990 !/* -5 Tried to read on a write-only file */
991 !/* -6 Failed in read to find the 'start' location */
992 !/* -7 Tried to write to a read only file */
993 !/* -8 Failed in write to find the 'start' location */
994 !/* -9 Error in close */
995 !/* -10 Read or wrote fewer data than requested */
997 !if ireaderr =1 we have hit the end of a file.
998 !if ireaderr =2 we have hit the end of all the files.
999 !if ireaderr =3 beginning characters 'GRIB' not found
1001 ! write(6,*) 'junit = ',junit,' gribflnm = ',gribflnm
1003 ! Open a byte-addressable file.
1004 CALL BAOPENR(junit,gribflnm,IOS) ! from w3lib
1005 ! write(6,*) 'ios = ',ios
1008 ! Search opend file for the next GRIB2 messege (record).
1009 call skgb(junit,iseek,msk1,lskip,lgrib)
1011 ! Check for EOF, or problem
1012 if (lgrib.eq.0) then
1013 write(*,'("\n\tThere is a problem with the input file.")')
1014 write(*,'("\tPerhaps it is not a Grib2 file?\n")')
1015 STOP "Grib2 file or date problem, stopping in edition_num."
1018 ! Check size, if needed allocate more memory.
1019 if (lgrib.gt.currlen) then
1020 if (allocated(cgrib)) deallocate(cgrib)
1021 allocate(cgrib(lgrib),stat=is)
1025 ! Read a given number of bytes from unblocked file.
1026 call baread(junit,lskip,lgrib,lengrib,cgrib)
1028 ! Check for beginning of GRIB message in the first 100 bytes
1031 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
1032 if (ctemp.eq.grib ) then
1037 if (istart.eq.0) then
1039 print*, "The beginning 4 characters >GRIB< were not found."
1042 ! Unpack Section 0 - Indicator Section to extract GRIB edition field
1044 call gbyte(cgrib,discipline,iofst,8) ! Discipline
1046 call gbyte(cgrib,grib_edition,iofst,8) ! GRIB edition number
1048 print *, 'ungrib - grib edition num', grib_edition
1049 CALL BACLOSE(junit,IOS)
1051 else if (ios .eq. -4) then
1052 print *,'edition_num: unable to open ',gribflnm
1055 print *,'edition_num: open status failed because',ios,gribflnm
1057 endif ! ireaderr check
1059 END subroutine edition_num
1060 subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2, a3, h3, i3, l3, &
1063 character(len=*) , optional :: a1, a2, a3
1064 character(len=*), optional :: h1, h2, h3
1065 integer , optional :: i1, i2, i3
1066 logical, optional :: l1, l2, l3
1067 character(len=*), optional :: hlast
1069 character(len=100) :: hold
1072 if (present(hlast)) then
1079 numarg = narg + ioff
1082 LOOP : do while ( i <= numarg)
1085 if (present(i1)) then
1086 call checkiarg(i, a1, i1, ierr)
1087 elseif (present(h1)) then
1088 call checkharg(i, a1, h1, ierr)
1089 elseif (present(l1)) then
1090 call checklarg(i, a1, l1, ierr)
1092 if (ierr.eq.0) cycle LOOP
1094 if (present(i2)) then
1095 call checkiarg(i, a2, i2, ierr)
1096 elseif (present(h2)) then
1097 call checkharg(i, a2, h2, ierr)
1098 elseif (present(l2)) then
1099 call checklarg(i, a2, l2, ierr)
1101 if (ierr.eq.0) cycle LOOP
1103 if (present(i3)) then
1104 call checkiarg(i, a3, i3, ierr)
1105 elseif (present(h3)) then
1106 call checkharg(i, a3, h3, ierr)
1107 elseif (present(l3)) then
1108 call checklarg(i, a3, l3, ierr)
1110 if (ierr.eq.0) cycle LOOP
1113 call getarg(1, hold)
1114 write(*, '("arg = ", A)') trim(hold)
1120 if (present(hlast)) then
1124 call getarg(narg, hlast)
1129 subroutine checkiarg(c, a, i, ierr)
1131 character(len=*) :: a
1134 character(len=100) :: hold
1137 call getarg(c, hold)
1139 if ('-'//a.eq.trim(hold)) then
1141 call getarg(c, hold)
1145 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1146 hold = hold(len_trim(a)+2: len(hold))
1152 end subroutine checkiarg
1153 subroutine checkharg(c, a, h, ierr)
1155 character(len=*) :: a
1156 character(len=*) :: h
1158 character(len=100) :: hold
1161 call getarg(c, hold)
1163 if ('-'//a.eq.trim(hold)) then
1165 call getarg(c, hold)
1169 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1170 hold = hold(len_trim(a)+2: len(hold))
1176 end subroutine checkharg
1178 subroutine checklarg(c, a, l, ierr)
1180 character(len=*) :: a
1183 character(len=100) :: hold
1186 call getarg(c, hold)
1187 if ('-'//a.eq.trim(hold)) then
1193 end subroutine checklarg
1195 end subroutine parse_args