1 !*****************************************************************************!
11 subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2,&
12 a3, h3, i3, l3, hlast)
14 character(len=*) , optional :: a1, a2, a3
15 character(len=*), optional :: h1, h2, h3
16 integer , optional :: i1, i2, i3
17 logical, optional :: l1, l2, l3
18 character(len=*), optional :: hlast
19 end subroutine parse_args
22 integer :: nunit1 = 12
23 character(LEN=120) :: gribflnm
27 integer , parameter :: maxlvl = 100
29 real :: startlat, startlon, deltalat, deltalon
31 character (LEN=9) :: field
32 character (LEN=3) :: out_format
36 integer, dimension(255) :: iuarr = 0
38 character (LEN=19) :: HSTART, HEND, HDATE
39 character(LEN=19) :: hsave = '0000-00-00_00:00:00'
44 logical :: ordered_by_date
45 integer :: debug_level
46 integer :: grib_version
47 integer :: vtable_columns
49 character(len=30) :: hopt
50 logical :: ivb = .FALSE.
51 logical :: idb = .FALSE.
56 call parse_args(ierr, a1='v', l1=ivb, a2='V', l2=idb, hlast=gribflnm)
59 write(*,'(//,"Usage: ", A, " [-v] [-V] file",/)') trim(hopt)
60 write(*,'(" -v : Print more information about the GRIB records")')
61 write(*,'(" -V : Print way too much information about the GRIB&
63 write(*,'(" file : GRIB file to read"//)')
68 ! Determine GRIB Edition number
70 call edition_num(nunit1, trim(gribflnm), grib_version, ierr)
71 if (ierr.eq.3) STOP 'GRIB file problem'
75 if (ivb) debug_level = 51
76 if (idb) debug_level = 101
77 write(6,*) 'reading from grib file = ',gribflnm
80 ! At the beginning of LOOP1, we are at a new time period.
81 ! Clear the storage arrays and associated level information.
83 ! If we need to read a new grib record, then read one.
85 if (grib_version.ne.2) then
86 write(6,*) 'calling r_grib1 with iunit ', nunit1
87 write(6,*) 'flnm = ',gribflnm
88 write(6,*) 'GRIB 1 not yet supported in this code'
90 ! Read one record at a time from GRIB1 (and older Editions)
91 ! call r_grib1(nunit1, gribflnm, level, field, &
92 ! hdate, debug_level, ierr, iuarr, iprint)
95 ! Read one file of records from GRIB2.
96 if (debug_level .gt. 100) write(6,*) 'calling r_grib2'
97 call r_grib2(nunit1, gribflnm, hdate, &
98 grib_version, debug_level, ierr)
103 ! We have hit the end of a file. Exit LOOP1.
109 if (grib_version.ne.2) then
110 call cclose(iuarr(nunit1), iprint, ierr)
114 ! And Now we are done:
118 print*,' Successful completion of g2print '
121 subroutine sort_filedates
128 do while ( .not. done)
131 if (filedates(n) > filedates(n+1)) then
132 filedates(size(filedates)) = filedates(n)
133 filedates(n) = filedates(n+1)
134 filedates(n+1) = filedates(size(filedates))
135 filedates(size(filedates)) = '0000-00-00 00:00:00.0000'
141 end subroutine sort_filedates
145 !*****************************************************************************!
147 SUBROUTINE r_grib2(junit, gribflnm, hdate, &
148 grib_edition, debug_level, ireaderr)
152 use table ! Included to define cg2code
153 use gridinfo ! Included to define map%
154 use storage_module ! Included sub put_storage
156 real, allocatable, dimension(:) :: hold_array
157 parameter(msk1=32000,msk2=4000)
158 character(len=1),allocatable,dimension(:) :: cgrib
159 integer :: listsec0(3)
160 integer :: listsec1(13)
161 integer year, month, day, hour, minute, second, fcst
162 character(len=*) :: gribflnm
163 character(len=*) :: hdate
164 character(len=8) :: pabbrev
165 character(len=20) :: labbrev
166 character(len=80) :: tabbrev
167 integer :: lskip, lgrib
168 integer :: junit, itot, icount, iseek
169 integer :: grib_edition
170 integer :: i, j, ireaderr, ith
172 logical :: unpack, expand
173 type(gribfield) :: gfld
174 ! For subroutine put_storage
178 character (len=9) :: my_field
179 ! For subroutine outout
180 integer , parameter :: maxlvl = 100
181 real , dimension(maxlvl) :: plvl
183 integer , dimension(maxlvl) :: level_array
184 logical :: verbose=.false.
185 integer :: debug_level
186 character(len=4) :: tmp4
187 character(len=40) :: string
188 character(len=13) :: pstring = ',t50,":",i14)'
189 character(len=15) :: rstring = ',t50,":",f14.5)'
191 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
233 if (verbose) write(6,*) 'back from baopenr, ios = ',ios
237 ! Search opend file for the next GRIB2 messege (record).
238 if (verbose) write(6,*) 'calling skgb'
239 call skgb(junit,iseek,msk1,lskip,lgrib)
241 ! Check for EOF, or problem
246 ! Check size, if needed allocate more memory.
247 if (lgrib.gt.currlen) then
248 if (allocated(cgrib)) deallocate(cgrib)
249 allocate(cgrib(lgrib),stat=is)
250 !print *,'G2 allocate(cgrib(lgrib)) status: ',IS
254 ! Read a given number of bytes from unblocked file.
255 call baread(junit,lskip,lgrib,lengrib,cgrib)
257 if (lgrib.ne.lengrib) then
258 print *,'G2 r_grib2: IO Error.',lgrib,".ne.",lengrib
264 if (verbose) PRINT *,'G2 GRIB MESSAGE ',icount,' starts at',lskip+1
267 call gb_info(cgrib,lengrib,listsec0,listsec1, &
268 numfields,numlocal,maxlocal,ierr)
270 write(*,*) ' ERROR querying GRIB2 message = ',ierr
275 grib_edition=listsec0(2)
276 if (grib_edition.ne.2) then
280 ! Additional print statments for developer.
282 print *,'G2 SECTION 0: ',(listsec0(j),j=1,3)
283 print *,'G2 SECTION 1: ',(listsec1(j),j=1,13)
284 print *,'G2 Contains ',numlocal,' Local Sections ', &
285 ' and ',numfields,' data fields.'
289 ! Once per file fill in date, model and projection values.
291 if (lskip.lt.10) then
293 ! Build the 19-character date string, based on GRIB2 header date
294 ! and time information, including forecast time information:
297 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
299 if (debug_level .gt. 100 ) then
300 write(6,*) 'gfld%version = ',gfld%version
301 if (gfld%discipline .eq. 0) then
302 string = 'Meteorological products'
303 else if (gfld%discipline .eq. 1) then
304 string = 'Hydrological products'
305 else if (gfld%discipline .eq. 2) then
306 string = 'Land Surface products'
308 string = 'See code table 0.0'
310 write(6,*) 'Discipline = ',gfld%discipline,' ',string
311 write(6,*) 'gfld%idsect(1) = ',gfld%idsect(1)
312 write(6,*) 'gfld%idsect(2) = ',gfld%idsect(2)
313 write(6,*) 'gfld%idsect(3) = ',gfld%idsect(3)
314 write(6,*) 'gfld%idsect(4) = ',gfld%idsect(4)
315 write(6,*) 'gfld%idsect(5) = ',gfld%idsect(5)
316 write(6,*) 'gfld%idsect(6) = ',gfld%idsect(6)
317 write(6,*) 'gfld%idsect(7) = ',gfld%idsect(7)
318 write(6,*) 'gfld%idsect(8) = ',gfld%idsect(8)
319 write(6,*) 'gfld%idsect(9) = ',gfld%idsect(9)
320 write(6,*) 'gfld%idsect(10) = ',gfld%idsect(10)
321 write(6,*) 'gfld%idsect(11) = ',gfld%idsect(11)
322 write(6,*) 'gfld%idsect(12) = ',gfld%idsect(12)
323 write(6,*) 'gfld%idsect(13) = ',gfld%idsect(13)
325 write(6,*) 'gfld%idsectlen = ',gfld%idsectlen
326 write(6,*) 'gfld%locallen = ',gfld%locallen
327 write(6,*) 'gfld%ifldnum = ',gfld%ifldnum
328 write(6,*) 'gfld%ngrdpts = ',gfld%ngrdpts
329 write(6,*) 'gfld%numoct_opt = ',gfld%numoct_opt
330 write(6,*) 'gfld%interp_opt = ',gfld%interp_opt
332 write(6,*) 'gfld%griddef = ',gfld%griddef
333 if (gfld%igdtnum .eq. 0) then
334 string = 'Lat/Lon cylindrical equidistant'
335 else if (gfld%igdtnum .eq. 1) then
336 string = 'Rotated Lat/Lon'
337 else if (gfld%igdtnum .eq. 2) then
338 string = 'Stretched Lat/Lon'
339 else if (gfld%igdtnum .eq. 20) then
340 string = 'Polar Stereographic'
341 else if (gfld%igdtnum .eq. 30) then
342 string = 'Lambert Conformal'
343 else if (gfld%igdtnum .eq. 40) then
344 string = 'Gaussian Lat/Lon'
345 else if (gfld%igdtnum .eq. 50) then
346 string = 'Spherical harmonic coefficients'
348 string = 'see code table 3.1'
350 write(6,*) 'Grid Template number = ',gfld%igdtnum,' ',string
351 write(6,*) 'gfld%igdtlen = ',gfld%igdtlen
352 do i = 1, gfld%igdtlen
353 write(6,*) 'gfld%igdtmpl(',i,') = ',gfld%igdtmpl(i)
356 write(6,*) 'gfld%ipdtnum = ',gfld%ipdtnum
357 write(6,*) 'gfld%ipdtlen = ',gfld%ipdtlen
358 if ( gfld%ipdtnum .eq. 0 ) then
359 do i = 1, gfld%ipdtlen
360 write(6,*) 'gfld%ipdtmpl(',i,') = ',gfld%ipdtmpl(i)
363 write(6,*) 'gfld%num_coord = ',gfld%num_coord
364 write(6,*) 'gfld%ndpts = ',gfld%ndpts
365 write(6,*) 'gfld%idrtnum = ',gfld%idrtnum
366 write(6,*) 'gfld%idrtlen = ',gfld%idrtlen
367 write(6,*) 'gfld%expanded = ',gfld%expanded
368 write(6,*) 'gfld%ibmap = ',gfld%ibmap
371 if (debug_level .le. 50) then
372 write(6,*) '---------------------------------------------------------------------------'
373 write(6,*) ' rec Prod Cat Param Lvl Lvl Lvl Name Time Fcst'
374 write(6,*) ' num Disc num code one two hour'
375 write(6,*) '---------------------------------------------------------------------------'
378 year =gfld%idsect(6) !(FOUR-DIGIT) YEAR OF THE DATA
379 month =gfld%idsect(7) ! MONTH OF THE DATA
380 day =gfld%idsect(8) ! DAY OF THE DATA
381 hour =gfld%idsect(9) ! HOUR OF THE DATA
382 minute=gfld%idsect(10) ! MINUTE OF THE DATA
383 second=gfld%idsect(11) ! SECOND OF THE DATA
386 ! Parse the forecast time info from Sect 4.
387 if (gfld%ipdtnum.eq.0) then ! Product Definition Template 4.0
389 ! Extract forecast time.
390 fcst = gfld%ipdtmpl(9)
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 thin 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 if (iprocess.eq.83 .or. iprocess.eq.84) then
417 map%source = 'NCEP NAM Model'
418 elseif (iprocess.eq.81) then
419 map%source = 'NCEP GFS Model'
420 elseif (iprocess.eq.96) then
421 map%source = 'NCEP GFS Model'
422 elseif (iprocess.eq.86 .or. iprocess.eq.100) then
423 map%source = 'NCEP RUC Model' ! 60 km
424 elseif (iprocess.eq.101) then
425 map%source = 'NCEP RUC Model' ! 40 km
426 elseif (iprocess.eq.105) then
427 map%source = 'NCEP RUC Model' ! 20 km
428 elseif (iprocess.eq.109) then
429 map%source = 'NCEP RTMA'
430 elseif (iprocess.eq.140) then
431 map%source = 'NCEP NARR'
433 map%source = 'unknown model from NCEP'
434 write (6,*) 'unknown NCEP model, iprocess = ',iprocess
436 else if (icenter .eq. 57) then
437 if (iprocess .eq. 87) then
438 map%source = 'AFWA AGRMET'
442 else if (icenter .eq. 98) then
445 map%source = 'unknown model and orig center'
450 ! Store information about the grid on which the data is.
451 ! This stuff gets stored in the MAP variable, as defined in
454 map%startloc = 'SWCORNER'
456 if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
458 map%nx = gfld%igdtmpl(8)
459 map%ny = gfld%igdtmpl(9)
460 map%dx = gfld%igdtmpl(17)
461 map%dy = gfld%igdtmpl(18)
462 map%lat1 = gfld%igdtmpl(12)
463 map%lon1 = gfld%igdtmpl(13)
465 ! Scale dx/dy values to degrees, default range is 1e6.
466 if (map%dx.gt.10000) then
467 map%dx = map%dx/scale_factor
469 if (map%dy.gt.10000) then
470 map%dy = (map%dy/scale_factor)*(-1)
473 ! Scale lat/lon values to 0-180, default range is 1e6.
474 if (map%lat1.ge.scale_factor) then
475 map%lat1 = map%lat1/scale_factor
477 if (map%lon1.ge.scale_factor) then
478 map%lon1 = map%lon1/scale_factor
481 ! if (iprocess.eq.81 .and. map%dy.eq.0) then !Hack for AFWA.
486 elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
488 map%nx = gfld%igdtmpl(8)
489 map%ny = gfld%igdtmpl(9)
490 map%lov = gfld%igdtmpl(14)
491 map%truelat1 = gfld%igdtmpl(19)
492 map%truelat2 = gfld%igdtmpl(20)
493 map%dx = gfld%igdtmpl(15)
494 map%dy = gfld%igdtmpl(16)
495 map%lat1 = gfld%igdtmpl(10)
496 map%lon1 = gfld%igdtmpl(11)
498 elseif(gfld%igdtnum.eq.40) then ! Gaussian Grid (we will call it lat/lon)
500 map%nx = gfld%igdtmpl(8)
501 map%ny = gfld%igdtmpl(9)
502 map%dx = gfld%igdtmpl(17)
503 map%dy = gfld%igdtmpl(18) ! ?not in Grid Definition Template 3.40 doc
504 map%lat1 = gfld%igdtmpl(12)
505 map%lon1 = gfld%igdtmpl(13)
507 ! Scale dx/dy values to degrees, default range is 1e6.
508 if (map%dx.gt.10000) then
509 map%dx = map%dx/scale_factor
511 if (map%dy.gt.10000) then
512 map%dy = (map%dy/scale_factor)*(-1)
515 ! Scale lat/lon values to 0-180, default range is 1e6.
516 if (map%lat1.ge.scale_factor) then
517 map%lat1 = map%lat1/scale_factor
519 if (map%lon1.ge.scale_factor) then
520 map%lon1 = map%lon1/scale_factor
522 print *,'Gaussian Grid: Dx,Dy,lat,lon',map%dx,map%dy, &
525 elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
527 map%nx = gfld%igdtmpl(8)
528 map%ny = gfld%igdtmpl(9)
529 !map%lov = gfld%igdtmpl(x) ! ?not in Grid Definition Template 3.20 doc
532 !map%dx = gfld%igdtmpl(x)
533 !map%dy = gfld%igdtmpl(x)
534 map%lat1 = gfld%igdtmpl(10)
535 map%lon1 = gfld%igdtmpl(11)
538 print*, 'GRIB2 Unknown Projection: ',gfld%igdtnum
539 print*, 'see Code Table 3.1: Grid Definition Template No'
546 ! Continue to unpack GRIB2 field.
547 if (debug_level .gt. 100) write(6,*) 'numfields = ',numfields
548 do n=1,numfields ! e.g. U and V would =2, otherwise its usually =1
549 call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
551 write(*,*) ' ERROR extracting field gf_getfld = ',ierr
555 ! ------------------------------------
556 ! Additional print information for developer.
557 pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1), &
559 if (debug_level .gt. 50 ) then
561 ! print *,'G2 FIELD ',n
563 write(*,'(/,"GRIB2 SECTION 0 - INDICATOR SECTION:")')
564 write(*,'(5x,"Discipline"'//pstring) gfld%discipline
565 write(*,'(5x,"GRIB Edition Number"'//pstring) gfld%version
566 write(*,'(5x,"GRIB length"'//pstring) lengrib
567 write(*,'(/,"GRIB2 SECTION 1 - IDENTIFICATION SECTION:")')
568 write(*,'(5x,"Length of Section"'//pstring) gfld%idsectlen
569 write(*,'(5x,"Originating Center ID"'//pstring) &
571 write(*,'(5x,"Subcenter ID"'//pstring) gfld%idsect(2)
572 write(*,'(5x,"GRIB Master Table Version"'//pstring) &
574 write(*,'(5x,"GRIB Local Table Version"'//pstring) &
576 write(*,'(5x,"Significance of Reference Time"'//pstring) &
578 write(*,'(5x,"Year"'//pstring) gfld%idsect(6)
579 write(*,'(5x,"Month"'//pstring) gfld%idsect(7)
580 write(*,'(5x,"Day"'//pstring) gfld%idsect(8)
581 write(*,'(5x,"Hour"'//pstring) gfld%idsect(9)
582 write(*,'(5x,"Minute"'//pstring) gfld%idsect(10)
583 write(*,'(5x,"Second"'//pstring) gfld%idsect(11)
584 write(*,'(5x,"Production Status of data"'//pstring) &
586 write(*,'(5x,"Type of processed data"'//pstring) &
588 ! print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
590 write(*,'(/,"GRIB2 SECTION 2 - LOCAL SECTION:")')
591 write(*,'(5x,"Length of Section 2"'//pstring) gfld%locallen
592 if ( associated(gfld%local).AND.gfld%locallen.gt.0 ) then
593 do j = 1, gfld%locallen
594 write(*,'(5x,"Local value "'//pstring) gfld%local(j)
596 ! print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
598 write(*,'(/,"GRIB2 SECTION 3 - GRID DEFINITION SECTION:")')
599 ! write(*,'(5x,"Length of Section 3"'//pstring) gfld%unknown
600 write(*,'(5x,"Source of grid definition"'&
601 //pstring) gfld%griddef
602 write(*,'(5x,"Number of grid points"'//pstring) gfld%ngrdpts
603 write(*,'(5x,"Number of octets for addnl points"'//pstring) &
605 write(*,'(5x,"Interpretation list"'//pstring) &
607 write(*,'(5x,"Grid Definition Template Number"'//pstring) &
609 if (gfld%igdtnum .eq. 0 .or. gfld%igdtnum .eq. 1 .or. &
610 gfld%igdtnum .eq. 2 .or. gfld%igdtnum .eq. 3 ) then
611 if (gfld%igdtnum .eq. 0 ) then
612 write(*,'(5x,"Lat/Lon or Cylindrical Equidistant Grid")')
613 else if (gfld%igdtnum .eq. 1 ) then
614 write(*,'(5x,"Rotated Lat/Lon or Cylind. Equi. Grid")')
615 else if (gfld%igdtnum .eq. 2 ) then
616 write(*,'(5x,"Stretched Lat/Lon or Cylind. Equi. Grid")')
617 else if (gfld%igdtnum .eq. 3 ) then
618 write(*,'(5x,"Stretched and Rotated Lat/Lon Grid")')
620 write(*,'(10x,"Shape of the Earth"'//pstring) &
622 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
624 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
626 write(*,'(10x,"Scale factor of major axis"'//pstring) &
628 write(*,'(10x,"Scaled value of major axis"'//pstring) &
630 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
632 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
634 write(*,'(10x,"Ni - points along a parallel"'//pstring) &
636 write(*,'(10x,"Nj - points along a meridian"'//pstring) &
638 write(*,'(10x,"Basic angle of initial domain"'//pstring)&
640 write(*,'(10x,"Subdivisions of basic angle"'//pstring) &
642 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(12)
643 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(13)
644 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
646 write(*,'(10x,"La2"'//pstring) gfld%igdtmpl(15)
647 write(*,'(10x,"Lo2"'//pstring) gfld%igdtmpl(16)
648 write(*,'(10x,"Di - i-dir increment"'//pstring) &
650 write(*,'(10x,"Dj - j-dir increment"'//pstring) &
652 write(*,'(10x,"Scanning mode"'//pstring) &
654 if (gfld%igdtnum .eq. 1) then
655 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
657 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
659 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
661 else if (gfld%igdtnum .eq. 2) then
662 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
664 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
666 write(*,'(10x,"Stretching factor"'//pstring) &
668 else if (gfld%igdtnum .eq. 3) then
669 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
671 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
673 write(*,'(10x,"Angle of rotation of projection"'//pstring)&
675 write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
677 write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
679 write(*,'(10x,"Stretching factor"'//pstring) &
682 else if (gfld%igdtnum .eq. 10) then
683 write(*,'(5x,"Mercator Grid")')
684 else if (gfld%igdtnum .eq. 20 .or. gfld%igdtnum .eq. 30) then
685 if (gfld%igdtnum .eq. 20) then
686 write(*,'(5x,"Polar Stereographic Grid")')
687 else if (gfld%igdtnum .eq. 30) then
688 write(*,'(5x,"Lambert Conformal Grid")')
690 write(*,'(10x,"Shape of the Earth"'//pstring) &
692 write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
694 write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
696 write(*,'(10x,"Scale factor of major axis"'//pstring) &
698 write(*,'(10x,"Scaled value of major axis"'//pstring) &
700 write(*,'(10x,"Scale factor of minor axis"'//pstring) &
702 write(*,'(10x,"Scaled value of minor axis"'//pstring) &
704 write(*,'(10x,"Nx"'//pstring) gfld%igdtmpl(8)
705 write(*,'(10x,"Ny"'//pstring) gfld%igdtmpl(9)
706 write(*,'(10x,"La1"'//pstring) gfld%igdtmpl(10)
707 write(*,'(10x,"Lo1"'//pstring) gfld%igdtmpl(11)
708 write(*,'(10x,"Resolution and Component",t50,":",B14.8)')&
710 write(*,'(10x,"LaD"'//pstring) gfld%igdtmpl(13)
711 write(*,'(10x,"LoV"'//pstring) gfld%igdtmpl(14)
712 write(*,'(10x,"Dx"'//pstring) gfld%igdtmpl(15)
713 write(*,'(10x,"Dy"'//pstring) gfld%igdtmpl(16)
714 write(*,'(10x,"Projection Center Flag"'//pstring) &
716 write(*,'(10x,"Scanning mode"'//pstring) &
718 if (gfld%igdtnum .eq. 30) then
719 write(*,'(10x,"Latin 1 "'//pstring) &
721 write(*,'(10x,"Latin 2 "'//pstring) &
723 write(*,'(10x,"Lat of southern pole of project"'//pstring)&
725 write(*,'(10x,"Lon of southern pole of project"'//pstring)&
728 else if (gfld%igdtnum .eq. 40 .or. gfld%igdtnum .eq. 41) then
729 if (gfld%igdtnum .eq. 40) then
730 write(*,'(5x,"Gaussian Lat/Lon Grid")')
731 else if (gfld%igdtnum .eq. 41) then
732 write(*,'(5x,"Rotated Gaussian Lat/Lon Grid")')
733 else if (gfld%igdtnum .eq. 42) then
734 write(*,'(5x,"Stretched Gaussian Lat/Lon Grid")')
735 else if (gfld%igdtnum .eq. 43) then
736 write(*,'(5x,"Stretched and Rotated Gaussian Lat/Lon ")')
739 do j = 1, gfld%igdtlen
740 write(*,'(5x,"Grid Definition Template entry "'//pstring) &
744 ! print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts, &
745 ! gfld%numoct_opt,gfld%interp_opt, &
747 ! print *,'G2 GRID TEMPLATE 3.',gfld%igdtnum,': ', &
748 ! (gfld%igdtmpl(j),j=1,gfld%igdtlen)
749 if ( gfld%num_opt .eq. 0 ) then
750 ! print *,'G2 NO Section 3 List Defining No. of Data Points.'
752 print *,'G2 Section 3 Optional List: ', &
753 (gfld%list_opt(j),j=1,gfld%num_opt)
755 write(*,'(/,"GRIB2 SECTION 4 - PRODUCT DEFINITION SECTION:")')
756 ! write(*,'(5x,"Length of Section 4"'//pstring) gfld%unknown
757 write(*,'(5x,"Product Definition Template Number"'//pstring)&
759 do j = 1, gfld%ipdtlen
761 string = '(5x,"Template Entry '//tmp4 // '"'
762 write(*,string//pstring) gfld%ipdtmpl(j)
764 ! print *,'G2 PRODUCT TEMPLATE 4.',gfld%ipdtnum,': ', &
765 ! (gfld%ipdtmpl(j),j=1,gfld%ipdtlen)
767 !call prlevel(gfld%ipdtnum,gfld%ipdtmpl,labbrev)
768 !call prvtime(gfld%ipdtnum,gfld%ipdtmpl,listsec1,tabbrev)
769 write(*,'(5x,"Product Abbreviated Name",t50,":",a14)')&
771 ! print *,'G2 TEXT: ',pabbrev,trim(labbrev)," ",trim(tabbrev)
773 if ( gfld%num_coord .eq. 0 ) then
774 ! print *,'G2 NO Optional Vertical Coordinate List.'
776 print *,'G2 Section 4 Optional Coordinates: ', &
777 (gfld%coord_list(j),j=1,gfld%num_coord)
779 ! if ( gfld%ibmap .ne. 255 ) then
780 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
781 ! ' with BIT-MAP ',gfld%ibmap
783 ! print *,'G2 Num. of Data Points = ',gfld%ndpts, &
786 write(*,'(/,"GRIB2 SECTION 5 - DATA REPRESENTATION SECTION:")')
787 write(*,'(5x,"Data Representation Template Number"'//pstring)&
789 do j = 1, gfld%idrtlen
791 string = '(5x,"Template Entry '//tmp4 // '"'
792 write(*,string//pstring) gfld%idrtmpl(j)
794 ! print *,'G2 DRS TEMPLATE 5.',gfld%idrtnum,': ', &
795 ! (gfld%idrtmpl(j),j=1,gfld%idrtlen)
797 ! if ( gfld%ipdtnum .eq. 0 ) then
798 ! if (gfld%ipdtmpl(1) .eq. 0 ) then
799 ! write(6,*) 'Temperature'
800 ! else if (gfld%ipdtmpl(1) .eq. 1 ) then
801 ! write(6,*) 'Moisture'
802 ! else if (gfld%ipdtmpl(1) .eq. 2 ) then
803 ! write(6,*) 'Momentum'
804 ! else if (gfld%ipdtmpl(1) .eq. 3 ) then
809 write(*,'(/,"GRIB2 SECTION 6 - BIT-MAP SECTION:")')
810 write(*,'(5x,"Bit-map indicator"'//pstring) &
817 if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
818 if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
822 write(*,'(/,"GRIB2 SECTION 7 - DATA SECTION:")')
824 write(*,'(5x,"Minimum Data Value "'//rstring)&
826 write(*,'(5x,"Maximum Data Value "'//rstring)&
828 ! print *,'G2 Data Values:'
829 ! write(*,fmt='("G2 MIN=",f21.8," AVE=",f21.8, &
830 ! " MAX=",f21.8)') fldmin,sum/gfld%ndpts,fldmax
831 if (debug_level .gt. 100 ) then
832 print*, 'gfld%fld = ',gfld%fld
834 ! write(*,*) j, gfld%fld(j)
837 endif ! Additional Print information
838 ! ------------------------------------
839 if ( debug_level .le. 50) then
840 write(6,987) itot,gfld%discipline,gfld%ipdtmpl(1), &
841 gfld%ipdtmpl(2),gfld%ipdtmpl(10),gfld%ipdtmpl(12),&
842 gfld%ipdtmpl(15),pabbrev,hdate,fcst
843 987 format(2i4,i5,i4,i8,i8,i8,a10,a20,i5.2)
849 ! Deallocate arrays decoding GRIB2 record.
855 if (debug_level .gt. 50) &
856 print *, 'G2 total number of fields found = ',itot
859 CALL BACLOSE(junit,IOS)
863 print *,'open status failed because',ios
864 hdate = '9999-99-99_99:99:99'
866 endif ! ireaderr check
868 END subroutine r_grib2
870 !*****************************************************************************!
871 ! Subroutine edition_num !
874 ! Read one record from the input GRIB2 file. Based on the information in !
875 ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
876 ! the GRIB2 record is one to process or to skip. If the field is one we !
877 ! want to keep, extract the data from the GRIB2 record, and pass the data !
878 ! back to the calling routine. !
882 ! JUNIT : "Unit Number" to open and read from. Not really a Fortran !
883 ! unit number, since we do not do Fortran I/O for the GRIB2 !
884 ! files. Nor is it a UNIX File Descriptor returned from a C !
885 ! OPEN statement. It is really just an array index to the !
886 ! array (IUARR) where the UNIX File Descriptor values are !
888 ! GRIB2FILE: File name to open, if it is not already open. !
891 ! GRIB_EDITION: Set to 1 for GRIB and set to 2 for GRIB2 !
892 ! IERR : Error flag: 0 - no error on read from GRIB2 file. !
893 ! 1 - Hit the end of the GRIB2 file. !
894 ! 2 - The file GRIBFLNM we tried to open does !
896 ! Author: Paula McCaslin !
899 !*****************************************************************************!
901 SUBROUTINE edition_num(junit, gribflnm, grib_edition, ireaderr)
906 parameter(msk1=32000,msk2=4000)
907 character(len=1),allocatable,dimension(:) :: cgrib
908 integer :: listsec0(3)
909 integer :: listsec1(13)
910 character(len=*) :: gribflnm
911 integer :: lskip, lgrib
913 integer :: grib_edition
914 integer :: i, j, ireaderr
917 character(len=4) :: ctemp
918 character(len=4),parameter :: grib='GRIB',c7777='7777'
920 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
931 !/* IOS Return Codes from BACIO: */
932 !/* 0 All was well */
933 !/* -1 Tried to open read only _and_ write only */
934 !/* -2 Tried to read and write in the same call */
935 !/* -3 Internal failure in name processing */
936 !/* -4 Failure in opening file */
937 !/* -5 Tried to read on a write-only file */
938 !/* -6 Failed in read to find the 'start' location */
939 !/* -7 Tried to write to a read only file */
940 !/* -8 Failed in write to find the 'start' location */
941 !/* -9 Error in close */
942 !/* -10 Read or wrote fewer data than requested */
944 !if ireaderr =1 we have hit the end of a file.
945 !if ireaderr =2 we have hit the end of all the files.
946 !if ireaderr =3 beginning characters 'GRIB' not found
948 ! write(6,*) 'junit = ',junit,' gribflnm = ',gribflnm
950 ! Open a byte-addressable file.
951 CALL BAOPENR(junit,gribflnm,IOS) ! from w3lib
952 ! write(6,*) 'ios = ',ios
955 ! Search opend file for the next GRIB2 messege (record).
956 call skgb(junit,iseek,msk1,lskip,lgrib)
958 ! Check for EOF, or problem
960 STOP "Grib2 file or date problem, stopping in edition_num."
963 ! Check size, if needed allocate more memory.
964 if (lgrib.gt.currlen) then
965 if (allocated(cgrib)) deallocate(cgrib)
966 allocate(cgrib(lgrib),stat=is)
970 ! Read a given number of bytes from unblocked file.
971 call baread(junit,lskip,lgrib,lengrib,cgrib)
973 ! Check for beginning of GRIB message in the first 100 bytes
976 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
977 if (ctemp.eq.grib ) then
982 if (istart.eq.0) then
984 print*, "The beginning 4 characters >GRIB< were not found."
987 ! Unpack Section 0 - Indicator Section to extract GRIB edition field
989 call gbyte(cgrib,discipline,iofst,8) ! Discipline
991 call gbyte(cgrib,grib_edition,iofst,8) ! GRIB edition number
993 print *, 'ungrib - grib edition num', grib_edition
995 CALL BACLOSE(junit,IOS)
997 else if (ios .eq. -4) then
998 print *,'edition_num: unable to open ',gribflnm
1001 print *,'edition_num: open status failed because',ios,gribflnm
1003 endif ! ireaderr check
1005 END subroutine edition_num
1006 subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2, a3, h3, i3, l3, &
1009 character(len=*) , optional :: a1, a2, a3
1010 character(len=*), optional :: h1, h2, h3
1011 integer , optional :: i1, i2, i3
1012 logical, optional :: l1, l2, l3
1013 character(len=*), optional :: hlast
1015 character(len=100) :: hold
1018 if (present(hlast)) then
1025 numarg = narg + ioff
1028 LOOP : do while ( i <= numarg)
1031 if (present(i1)) then
1032 call checkiarg(i, a1, i1, ierr)
1033 elseif (present(h1)) then
1034 call checkharg(i, a1, h1, ierr)
1035 elseif (present(l1)) then
1036 call checklarg(i, a1, l1, ierr)
1038 if (ierr.eq.0) cycle LOOP
1040 if (present(i2)) then
1041 call checkiarg(i, a2, i2, ierr)
1042 elseif (present(h2)) then
1043 call checkharg(i, a2, h2, ierr)
1044 elseif (present(l2)) then
1045 call checklarg(i, a2, l2, ierr)
1047 if (ierr.eq.0) cycle LOOP
1049 if (present(i3)) then
1050 call checkiarg(i, a3, i3, ierr)
1051 elseif (present(h3)) then
1052 call checkharg(i, a3, h3, ierr)
1053 elseif (present(l3)) then
1054 call checklarg(i, a3, l3, ierr)
1056 if (ierr.eq.0) cycle LOOP
1059 call getarg(1, hold)
1060 write(*, '("arg = ", A)') trim(hold)
1066 if (present(hlast)) then
1070 call getarg(narg, hlast)
1075 subroutine checkiarg(c, a, i, ierr)
1077 character(len=*) :: a
1080 character(len=100) :: hold
1083 call getarg(c, hold)
1085 if ('-'//a.eq.trim(hold)) then
1087 call getarg(c, hold)
1091 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1092 hold = hold(len_trim(a)+2: len(hold))
1098 end subroutine checkiarg
1099 subroutine checkharg(c, a, h, ierr)
1101 character(len=*) :: a
1102 character(len=*) :: h
1104 character(len=100) :: hold
1107 call getarg(c, hold)
1109 if ('-'//a.eq.trim(hold)) then
1111 call getarg(c, hold)
1115 elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1116 hold = hold(len_trim(a)+2: len(hold))
1122 end subroutine checkharg
1124 subroutine checklarg(c, a, l, ierr)
1126 character(len=*) :: a
1129 character(len=100) :: hold
1132 call getarg(c, hold)
1133 if ('-'//a.eq.trim(hold)) then
1139 end subroutine checklarg
1141 end subroutine parse_args