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)'
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 this 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.197) then
453 map%source = 'NCEP CDAS CFSV2'
454 elseif (iprocess.eq.25) then
455 map%source = 'NCEP SNOW COVER ANALYSIS'
457 map%source = 'unknown model from NCEP'
458 write (6,*) 'unknown NCEP model, iprocess = ',iprocess
460 else if (icenter .eq. 57) then
461 if (iprocess .eq. 87) then
462 map%source = 'AFWA AGRMET'
466 else if (icenter .eq. 58) then
467 map%source = 'US Navy FNOC'
468 else if (icenter .eq. 98) then
470 else if (icenter .eq. 34) then
472 else if (icenter .eq. 74 .or. icenter .eq. 75 ) then
475 map%source = 'unknown model and orig center'
480 ! Store information about the grid on which the data is.
481 ! This stuff gets stored in the MAP variable, as defined in
484 map%startloc = 'SWCORNER'
486 if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
488 map%nx = gfld%igdtmpl(8)
489 map%ny = gfld%igdtmpl(9)
490 map%dx = gfld%igdtmpl(17)
491 map%dy = gfld%igdtmpl(18)
492 map%lat1 = gfld%igdtmpl(12)
493 map%lon1 = gfld%igdtmpl(13)
495 if ((gfld%igdtmpl(10) .eq. 0).OR. &
496 (gfld%igdtmpl(10) .eq. 255)) THEN
497 ! Scale lat/lon values to 0-180, default range is 1e6.
498 map%lat1 = map%lat1/scale_factor
499 map%lon1 = map%lon1/scale_factor
500 ! Scale dx/dy values to degrees, default range is 1e6.
501 map%dx = map%dx/scale_factor
502 map%dy = map%dy/scale_factor
504 ! Basic angle and subdivisions are non-zero (not tested)
505 map%lat1 = map%lat1 * &
506 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
507 map%lon1 = map%lon1 * &
508 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
510 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
512 (gfld%igdtmpl(11)/gfld%igdtmpl(10))
515 elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
517 map%nx = gfld%igdtmpl(8)
518 map%ny = gfld%igdtmpl(9)
519 map%lov = gfld%igdtmpl(14)
520 map%truelat1 = gfld%igdtmpl(19)
521 map%truelat2 = gfld%igdtmpl(20)
522 map%dx = gfld%igdtmpl(15)
523 map%dy = gfld%igdtmpl(16)
524 map%lat1 = gfld%igdtmpl(10)
525 map%lon1 = gfld%igdtmpl(11)
527 elseif(gfld%igdtnum.eq.40) then ! Gaussian Grid (we will call it lat/lon)
529 map%nx = gfld%igdtmpl(8)
530 map%ny = gfld%igdtmpl(9)
531 map%dx = gfld%igdtmpl(17)
532 map%dy = gfld%igdtmpl(18) ! ?not in Grid Definition Template 3.40 doc
533 map%lat1 = gfld%igdtmpl(12)
534 map%lon1 = gfld%igdtmpl(13)
536 ! Scale dx/dy values to degrees, default range is 1e6.
537 if (map%dx.gt.10000) then
538 map%dx = map%dx/scale_factor
540 if (map%dy.gt.10000) then
541 map%dy = (map%dy/scale_factor)*(-1)
544 ! Scale lat/lon values to 0-180, default range is 1e6.
545 if (map%lat1.ge.scale_factor) then
546 map%lat1 = map%lat1/scale_factor
548 if (map%lon1.ge.scale_factor) then
549 map%lon1 = map%lon1/scale_factor
551 print *,'Gaussian Grid: Dx,Dy,lat,lon',map%dx,map%dy, &
554 elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
556 map%nx = gfld%igdtmpl(8)
557 map%ny = gfld%igdtmpl(9)
558 !map%lov = gfld%igdtmpl(x) ! ?not in Grid Definition Template 3.20 doc
561 !map%dx = gfld%igdtmpl(x)
562 !map%dy = gfld%igdtmpl(x)
563 map%lat1 = gfld%igdtmpl(10)
564 map%lon1 = gfld%igdtmpl(11)
567 print*, 'GRIB2 Unknown Projection: ',gfld%igdtnum
568 print*, 'see Code Table 3.1: Grid Definition Template No'
576 ! Continue to unpack GRIB2 field.
577 if (debug_level .gt. 100) write(6,*) 'numfields = ',numfields
578 NUM_FIELDS: do n = 1, numfields
579 ! e.g. U and V would =2, otherwise its usually =1
580 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
582 write(*,*) ' ERROR extracting field gf_getfld = ',ierr
586 ! ------------------------------------
587 ! Additional print information for developer.
588 pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1), &
590 if (debug_level .gt. 50 ) then
592 ! print *,'G2 FIELD ',n
594 write(*,'(/,"GRIB2 SECTION 0 - INDICATOR SECTION:")')
595 write(*,'(5x,"Discipline"'//pstring) gfld%discipline
596 write(*,'(5x,"GRIB Edition Number"'//pstring) gfld%version
597 write(*,'(5x,"GRIB length"'//pstring) lengrib
598 write(*,'(/,"GRIB2 SECTION 1 - IDENTIFICATION SECTION:")')
599 write(*,'(5x,"Length of Section"'//pstring) gfld%idsectlen
600 write(*,'(5x,"Originating Center ID"'//pstring) &
602 write(*,'(5x,"Subcenter ID"'//pstring) gfld%idsect(2)
603 write(*,'(5x,"GRIB Master Table Version"'//pstring) &
605 write(*,'(5x,"GRIB Local Table Version"'//pstring) &
607 write(*,'(5x,"Significance of Reference Time"'//pstring) &
609 write(*,'(5x,"Year"'//pstring) gfld%idsect(6)
610 write(*,'(5x,"Month"'//pstring) gfld%idsect(7)
611 write(*,'(5x,"Day"'//pstring) gfld%idsect(8)
612 write(*,'(5x,"Hour"'//pstring) gfld%idsect(9)
613 write(*,'(5x,"Minute"'//pstring) gfld%idsect(10)
614 write(*,'(5x,"Second"'//pstring) gfld%idsect(11)
615 write(*,'(5x,"Production Status of data"'//pstring) &
617 write(*,'(5x,"Type of processed data"'//pstring) &
619 ! print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
621 write(*,'(/,"GRIB2 SECTION 2 - LOCAL SECTION:")')
622 write(*,'(5x,"Length of Section 2"'//pstring) gfld%locallen
623 if ( associated(gfld%local).AND.gfld%locallen.gt.0 ) then
624 do j = 1, gfld%locallen
625 write(*,'(5x,"Local value "'//astring) gfld%local(j)
627 ! print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
629 write(*,'(/,"GRIB2 SECTION 3 - GRID DEFINITION SECTION:")')
630 ! write(*,'(5x,"Length of Section 3"'//pstring) gfld%unknown
631 write(*,'(5x,"Source of grid definition"'&
632 //pstring) gfld%griddef
633 write(*,'(5x,"Number of grid points"'//pstring) gfld%ngrdpts
634 write(*,'(5x,"Number of octets for addnl points"'//pstring) &
636 write(*,'(5x,"Interpretation list"'//pstring) &
638 write(*,'(5x,"Grid Definition Template Number"'//pstring) &
640 if (gfld%igdtnum .eq. 0 .or. gfld%igdtnum .eq. 1 .or. &
641 gfld%igdtnum .eq. 2 .or. gfld%igdtnum .eq. 3 ) then
642 if (gfld%igdtnum .eq. 0 ) then
643 write(*,'(5x,"Lat/Lon or Cylindrical Equidistant Grid")')
644 else if (gfld%igdtnum .eq. 1 ) then
645 write(*,'(5x,"Rotated Lat/Lon or Cylind. Equi. Grid")')
646 else if (gfld%igdtnum .eq. 2 ) then
647 write(*,'(5x,"Stretched Lat/Lon or Cylind. Equi. Grid")')
648 else if (gfld%igdtnum .eq. 3 ) then
649 write(*,'(5x,"Stretched and Rotated Lat/Lon Grid")')
651 write(*,'(10x,"Shape of the Earth"'//pstring) &
653 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
655 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
657 write(*,'(10x,"Scale factor of major axis"'//pstring) &
659 write(*,'(10x,"Scaled value of major axis"'//pstring) &
661 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
663 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
665 write(*,'(10x,"Ni - points along a parallel"'//pstring) &
667 write(*,'(10x,"Nj - points along a meridian"'//pstring) &
669 write(*,'(10x,"Basic angle of initial domain"'//pstring)&
671 write(*,'(10x,"Subdivisions of basic angle"'//pstring) &
673 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(12)
674 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(13)
675 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
677 write(*,'(10x,"La2"'//pstring) gfld%igdtmpl(15)
678 write(*,'(10x,"Lo2"'//pstring) gfld%igdtmpl(16)
679 write(*,'(10x,"Di - i-dir increment"'//pstring) &
681 write(*,'(10x,"Dj - j-dir increment"'//pstring) &
683 write(*,'(10x,"Scanning mode"'//pstring) &
685 if (gfld%igdtnum .eq. 1) then
686 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
688 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
690 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
692 else if (gfld%igdtnum .eq. 2) then
693 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
695 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
697 write(*,'(10x,"Stretching factor"'//pstring) &
699 else if (gfld%igdtnum .eq. 3) then
700 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
702 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
704 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
706 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
708 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
710 write(*,'(10x,"Stretching factor"'//pstring) &
713 else if (gfld%igdtnum .eq. 10) then
714 write(*,'(5x,"Mercator Grid")')
715 else if (gfld%igdtnum .eq. 20 .or. gfld%igdtnum .eq. 30) then
716 if (gfld%igdtnum .eq. 20) then
717 write(*,'(5x,"Polar Stereographic Grid")')
718 else if (gfld%igdtnum .eq. 30) then
719 write(*,'(5x,"Lambert Conformal Grid")')
721 write(*,'(10x,"Shape of the Earth"'//pstring) &
723 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
725 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
727 write(*,'(10x,"Scale factor of major axis"'//pstring) &
729 write(*,'(10x,"Scaled value of major axis"'//pstring) &
731 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
733 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
735 write(*,'(10x,"Nx"'//pstring) gfld%igdtmpl(8)
736 write(*,'(10x,"Ny"'//pstring) gfld%igdtmpl(9)
737 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(10)
738 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(11)
739 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
741 write(*,'(10x,"LaD"'//pstring) gfld%igdtmpl(13)
742 write(*,'(10x,"LoV"'//pstring) gfld%igdtmpl(14)
743 write(*,'(10x,"Dx"'//pstring) gfld%igdtmpl(15)
744 write(*,'(10x,"Dy"'//pstring) gfld%igdtmpl(16)
745 write(*,'(10x,"Projection Center Flag"'//pstring) &
747 write(*,'(10x,"Scanning mode"'//pstring) &
749 if (gfld%igdtnum .eq. 30) then
750 write(*,'(10x,"Latin 1 "'//pstring) &
752 write(*,'(10x,"Latin 2 "'//pstring) &
754 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
756 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
759 else if (gfld%igdtnum .eq. 40 .or. gfld%igdtnum .eq. 41) then
760 if (gfld%igdtnum .eq. 40) then
761 write(*,'(5x,"Gaussian Lat/Lon Grid")')
762 else if (gfld%igdtnum .eq. 41) then
763 write(*,'(5x,"Rotated Gaussian Lat/Lon Grid")')
764 else if (gfld%igdtnum .eq. 42) then
765 write(*,'(5x,"Stretched Gaussian Lat/Lon Grid")')
766 else if (gfld%igdtnum .eq. 43) then
767 write(*,'(5x,"Stretched and Rotated Gaussian Lat/Lon ")')
770 do j = 1, gfld%igdtlen
771 write(*,'(5x,"Grid Definition Template entry "'//pstring) &
775 ! print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts, &
776 ! gfld%numoct_opt,gfld%interp_opt, &
778 ! print *,'G2 GRID TEMPLATE 3.',gfld%igdtnum,': ', &
779 ! (gfld%igdtmpl(j),j=1,gfld%igdtlen)
780 if ( gfld%num_opt .eq. 0 ) then
781 ! print *,'G2 NO Section 3 List Defining No. of Data Points.'
783 print *,'G2 Section 3 Optional List: ', &
784 (gfld%list_opt(j),j=1,gfld%num_opt)
786 write(*,'(/,"GRIB2 SECTION 4 - PRODUCT DEFINITION SECTION:")')
787 ! write(*,'(5x,"Length of Section 4"'//pstring) gfld%unknown
788 write(*,'(5x,"Product Definition Template Number"'//pstring)&
790 do j = 1, gfld%ipdtlen
792 string = '(5x,"Template Entry '//tmp4 // '"'
793 write(*,string//pstring) gfld%ipdtmpl(j)
795 ! print *,'G2 PRODUCT TEMPLATE 4.',gfld%ipdtnum,': ', &
796 ! (gfld%ipdtmpl(j),j=1,gfld%ipdtlen)
798 !call prlevel(gfld%ipdtnum,gfld%ipdtmpl,labbrev)
799 !call prvtime(gfld%ipdtnum,gfld%ipdtmpl,listsec1,tabbrev)
800 write(*,'(5x,"Product Abbreviated Name",t50,":",a14)')&
802 ! print *,'G2 TEXT: ',pabbrev,trim(labbrev)," ",trim(tabbrev)
804 if ( gfld%num_coord .eq. 0 ) then
805 ! print *,'G2 NO Optional Vertical Coordinate List.'
807 print *,'G2 Section 4 Optional Coordinates: ', &
808 (gfld%coord_list(j),j=1,gfld%num_coord)
810 ! if ( gfld%ibmap .ne. 255 ) then
811 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
812 ! ' with BIT-MAP ',gfld%ibmap
814 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
817 write(*,'(/,"GRIB2 SECTION 5 - DATA REPRESENTATION SECTION:")')
818 write(*,'(5x,"Data Representation Template Number"'//pstring)&
820 do j = 1, gfld%idrtlen
822 string = '(5x,"Template Entry '//tmp4 // '"'
823 write(*,string//pstring) gfld%idrtmpl(j)
825 ! print *,'G2 DRS TEMPLATE 5.',gfld%idrtnum,': ', &
826 ! (gfld%idrtmpl(j),j=1,gfld%idrtlen)
828 ! if ( gfld%ipdtnum .eq. 0 ) then
829 ! if (gfld%ipdtmpl(1) .eq. 0 ) then
830 ! write(6,*) 'Temperature'
831 ! else if (gfld%ipdtmpl(1) .eq. 1 ) then
832 ! write(6,*) 'Moisture'
833 ! else if (gfld%ipdtmpl(1) .eq. 2 ) then
834 ! write(6,*) 'Momentum'
835 ! else if (gfld%ipdtmpl(1) .eq. 3 ) then
840 write(*,'(/,"GRIB2 SECTION 6 - BIT-MAP SECTION:")')
841 write(*,'(5x,"Bit-map indicator"'//pstring) &
848 if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
849 if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
853 write(*,'(/,"GRIB2 SECTION 7 - DATA SECTION:")')
855 write(*,'(5x,"Minimum Data Value "'//rstring)&
857 write(*,'(5x,"Maximum Data Value "'//rstring)&
859 ! print *,'G2 Data Values:'
860 ! write(*,fmt='("G2 MIN=",f21.8," AVE=",f21.8, &
861 ! " MAX=",f21.8)') fldmin,sum/gfld%ndpts,fldmax
862 if (debug_level .gt. 100 ) then
863 print*, 'gfld%fld = ',gfld%fld
865 ! write(*,*) j, gfld%fld(j)
868 endif ! Additional Print information
869 ! ------------------------------------
870 if ( debug_level .le. 50) then
871 if(gfld%ipdtmpl(10).eq.100) then ! pressure level
872 level=gfld%ipdtmpl(12) * &
873 (10. ** (-1. * gfld%ipdtmpl(11)))
874 else if(gfld%ipdtmpl(10).eq.101 .or.& ! sea level, sfc, or trop
875 gfld%ipdtmpl(10).eq.1 .or. gfld%ipdtmpl(10).eq.7) then
877 else if(gfld%ipdtmpl(10).eq.106) then ! below ground sfc is in cm in Vtable
878 level= 100. * gfld%ipdtmpl(12)*(10.**(-1.*gfld%ipdtmpl(11)))
880 level=gfld%ipdtmpl(12) * 10.** (-1.*gfld%ipdtmpl(11))
882 if (gfld%ipdtmpl(13) .eq. 255) then
884 else if(gfld%ipdtmpl(10).eq.106) then ! below ground sfc is in cm in Vtable
885 lvl2 = 100. * gfld%ipdtmpl(15) * 10.** (-1.*gfld%ipdtmpl(14))
887 lvl2 = gfld%ipdtmpl(15) * 10.** (-1.*gfld%ipdtmpl(14))
889 ! Account for multiple forecast hours in one file
890 if (gfld%ipdtnum.eq.0 .or. gfld%ipdtnum.eq.1 .or. gfld%ipdtnum.eq. 8) then
891 ! Product Definition Template 4.0, 4.1, 4.8
892 ! Extract forecast time.
893 if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
894 fcst = gfld%ipdtmpl(9)
895 else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
896 fcst = gfld%ipdtmpl(9) / 60.
897 else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
898 fcst = gfld%ipdtmpl(9) * 24.
904 ! Non-standard Product Definition Templates need to be reported
906 if ( gfld%ipdtnum .eq. 8 ) then
908 else if ( gfld%ipdtnum .eq. 1 ) then
911 write(6,987) itot,gfld%discipline,gfld%ipdtmpl(1), &
912 gfld%ipdtmpl(2),gfld%ipdtmpl(10),int(level),&
913 lvl2,gfld%ipdtnum,pabbrev,hdate,fcst,string
914 987 format(2i4,i5,i4,i8,i8,i8,i8,3x,a10,a20,i5.2,a10)
918 ! Deallocate arrays decoding GRIB2 record.
925 if (debug_level .gt. 50) &
926 print *, 'G2 total number of fields found = ',itot
928 CALL BACLOSE(junit,IOS)
932 print *,'open status failed because',ios
933 hdate = '9999-99-99_99:99:99'
935 endif ! ireaderr check
937 END subroutine r_grib2
939 !*****************************************************************************!
940 ! Subroutine edition_num !
943 ! Read one record from the input GRIB2 file. Based on the information in !
944 ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
945 ! the GRIB2 record is one to process or to skip. If the field is one we !
946 ! want to keep, extract the data from the GRIB2 record, and pass the data !
947 ! back to the calling routine. !
951 ! JUNIT : "Unit Number" to open and read from. Not really a Fortran !
952 ! unit number, since we do not do Fortran I/O for the GRIB2 !
953 ! files. Nor is it a UNIX File Descriptor returned from a C !
954 ! OPEN statement. It is really just an array index to the !
955 ! array (IUARR) where the UNIX File Descriptor values are !
957 ! GRIB2FILE: File name to open, if it is not already open. !
960 ! GRIB_EDITION: Set to 1 for GRIB and set to 2 for GRIB2 !
961 ! IERR : Error flag: 0 - no error on read from GRIB2 file. !
962 ! 1 - Hit the end of the GRIB2 file. !
963 ! 2 - The file GRIBFLNM we tried to open does !
965 ! Author: Paula McCaslin !
968 !*****************************************************************************!
970 SUBROUTINE edition_num(junit, gribflnm, grib_edition, ireaderr)
975 parameter(msk1=32000,msk2=4000)
976 character(len=1),allocatable,dimension(:) :: cgrib
977 integer :: listsec0(3)
978 integer :: listsec1(13)
979 character(len=*) :: gribflnm
980 integer :: lskip, lgrib
982 integer :: grib_edition
983 integer :: i, j, ireaderr
986 character(len=4) :: ctemp
987 character(len=4),parameter :: grib='GRIB',c7777='7777'
989 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
999 !/* IOS Return Codes from BACIO: */
1000 !/* 0 All was well */
1001 !/* -1 Tried to open read only _and_ write only */
1002 !/* -2 Tried to read and write in the same call */
1003 !/* -3 Internal failure in name processing */
1004 !/* -4 Failure in opening file */
1005 !/* -5 Tried to read on a write-only file */
1006 !/* -6 Failed in read to find the 'start' location */
1007 !/* -7 Tried to write to a read only file */
1008 !/* -8 Failed in write to find the 'start' location */
1009 !/* -9 Error in close */
1010 !/* -10 Read or wrote fewer data than requested */
1012 !if ireaderr =1 we have hit the end of a file.
1013 !if ireaderr =2 we have hit the end of all the files.
1014 !if ireaderr =3 beginning characters 'GRIB' not found
1016 ! write(6,*) 'junit = ',junit,' gribflnm = ',gribflnm
1018 ! Open a byte-addressable file.
1019 CALL BAOPENR(junit,gribflnm,IOS) ! from w3lib
1020 ! write(6,*) 'ios = ',ios
1023 ! Search opend file for the next GRIB2 messege (record).
1024 call skgb(junit,iseek,msk1,lskip,lgrib)
1026 ! Check for EOF, or problem
1027 if (lgrib.eq.0) then
1028 write(*,'("\n\tThere is a problem with the input file.")')
1029 write(*,'("\tPerhaps it is not a Grib2 file?\n")')
1030 STOP "Grib2 file or date problem, stopping in edition_num."
1033 ! Check size, if needed allocate more memory.
1034 if (lgrib.gt.currlen) then
1035 if (allocated(cgrib)) deallocate(cgrib)
1036 allocate(cgrib(lgrib),stat=is)
1040 ! Read a given number of bytes from unblocked file.
1041 call baread(junit,lskip,lgrib,lengrib,cgrib)
1043 ! Check for beginning of GRIB message in the first 100 bytes
1046 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
1047 if (ctemp.eq.grib ) then
1052 if (istart.eq.0) then
1054 print*, "The beginning 4 characters >GRIB< were not found."
1057 ! Unpack Section 0 - Indicator Section to extract GRIB edition field
1059 call gbyte(cgrib,discipline,iofst,8) ! Discipline
1061 call gbyte(cgrib,grib_edition,iofst,8) ! GRIB edition number
1063 print *, 'ungrib - grib edition num', grib_edition
1064 CALL BACLOSE(junit,IOS)
1066 else if (ios .eq. -4) then
1067 print *,'edition_num: unable to open ',gribflnm
1070 print *,'edition_num: open status failed because',ios,gribflnm
1072 endif ! ireaderr check
1074 END subroutine edition_num
1075 subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2, a3, h3, i3, l3, &
1078 character(len=*) , optional :: a1, a2, a3
1079 character(len=*), optional :: h1, h2, h3
1080 integer , optional :: i1, i2, i3
1081 logical, optional :: l1, l2, l3
1082 character(len=*), optional :: hlast
1084 character(len=100) :: hold
1087 if (present(hlast)) then
1094 numarg = narg + ioff
1097 LOOP : do while ( i <= numarg)
1100 if (present(i1)) then
1101 call checkiarg(i, a1, i1, ierr)
1102 elseif (present(h1)) then
1103 call checkharg(i, a1, h1, ierr)
1104 elseif (present(l1)) then
1105 call checklarg(i, a1, l1, ierr)
1107 if (ierr.eq.0) cycle LOOP
1109 if (present(i2)) then
1110 call checkiarg(i, a2, i2, ierr)
1111 elseif (present(h2)) then
1112 call checkharg(i, a2, h2, ierr)
1113 elseif (present(l2)) then
1114 call checklarg(i, a2, l2, ierr)
1116 if (ierr.eq.0) cycle LOOP
1118 if (present(i3)) then
1119 call checkiarg(i, a3, i3, ierr)
1120 elseif (present(h3)) then
1121 call checkharg(i, a3, h3, ierr)
1122 elseif (present(l3)) then
1123 call checklarg(i, a3, l3, ierr)
1125 if (ierr.eq.0) cycle LOOP
1128 call getarg(1, hold)
1129 write(*, '("arg = ", A)') trim(hold)
1135 if (present(hlast)) then
1139 call getarg(narg, hlast)
1144 subroutine checkiarg(c, a, i, ierr)
1146 character(len=*) :: a
1149 character(len=100) :: hold
1152 call getarg(c, hold)
1154 if ('-'//a.eq.trim(hold)) then
1156 call getarg(c, hold)
1160 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1161 hold = hold(len_trim(a)+2: len(hold))
1167 end subroutine checkiarg
1168 subroutine checkharg(c, a, h, ierr)
1170 character(len=*) :: a
1171 character(len=*) :: h
1173 character(len=100) :: hold
1176 call getarg(c, hold)
1178 if ('-'//a.eq.trim(hold)) then
1180 call getarg(c, hold)
1184 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1185 hold = hold(len_trim(a)+2: len(hold))
1191 end subroutine checkharg
1193 subroutine checklarg(c, a, l, ierr)
1195 character(len=*) :: a
1198 character(len=100) :: hold
1201 call getarg(c, hold)
1202 if ('-'//a.eq.trim(hold)) then
1208 end subroutine checklarg
1210 end subroutine parse_args