Fixes to ungrib for compilation on bluevista.
[WPS.git] / ungrib / src / g2print.F90
blobb58d4dd89eb1c4782822a8fdea2de2578e0fa405
1 !*****************************************************************************!
2   program g2print                                                             !
3 !                                                                             !
4   use table
5   use gridinfo
6   use storage_module
7   use filelist
8   use datarray
9   implicit none
10   interface
11      subroutine parse_args(err, a1, h1, i1, l1, a2, h2, i2, l2,&
12           a3, h3, i3, l3, hlast)
13        integer :: err
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
20   end interface
22   integer :: nunit1 = 12
23   character(LEN=120) :: gribflnm 
25   integer :: iprint
27   integer , parameter :: maxlvl = 100
29   real :: startlat, startlon, deltalat, deltalon
30   real :: level
31   character (LEN=9) ::  field
32   character (LEN=3) ::  out_format
34   logical :: readit
36   integer, dimension(255) :: iuarr = 0
38   character (LEN=19) :: HSTART, HEND, HDATE
39   character(LEN=19) :: hsave  = '0000-00-00_00:00:00'
40   integer :: itime
41   integer :: ntimes
42   integer :: interval
43   integer :: ierr
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.
53 ! -----------------
55   gribflnm = '  '
56   call parse_args(ierr, a1='v', l1=ivb, a2='V', l2=idb, hlast=gribflnm)
57   if (ierr.ne.0) then
58      call getarg(0, hopt)
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&
62           & records")')
63      write(*,'("     file : GRIB file to read"//)')
64      stop
65   endif
67 ! -----------------
68 ! Determine GRIB Edition number
69   grib_version=0
70   call edition_num(nunit1, trim(gribflnm), grib_version, ierr)
71   if (ierr.eq.3) STOP 'GRIB file problem' 
74      debug_level = 0
75      if (ivb) debug_level = 51
76      if (idb) debug_level = 101
77      write(6,*) 'reading from grib file = ',gribflnm
79      LOOP1 : DO
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'
89                  stop
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)
93               else 
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)
100               endif
102               if (ierr.eq.1) then 
103                  ! We have hit the end of a file.  Exit LOOP1.
104                  exit LOOP1
105               endif
107      enddo LOOP1
109      if (grib_version.ne.2) then
110         call cclose(iuarr(nunit1), iprint, ierr)
111         iuarr(nunit1) = 0
112      endif 
114 ! And Now we are done:
116    print*,' '
117    print*,' '
118    print*,'  Successful completion of g2print   '
120 contains
121   subroutine sort_filedates
122     implicit none
124     integer :: n
125     logical :: done
126     if (nfiles > 1) then
127        done = .FALSE.
128        do while ( .not. done)
129           done = .TRUE.
130           do n = 1, nfiles-1
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'
136                 done = .FALSE.
137              endif
138           enddo
139        enddo
140     endif
141   end subroutine sort_filedates
143 end program g2print
145 !*****************************************************************************!
146       
147       SUBROUTINE r_grib2(junit, gribflnm, hdate,  &
148         grib_edition, debug_level, ireaderr)
150       use grib_mod
151       use params
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
171       integer :: currlen
172       logical :: unpack, expand
173       type(gribfield) :: gfld
174       ! For subroutine put_storage
175       real :: level
176       real :: scale_factor
177       integer :: iplvl
178       character (len=9) :: my_field
179       ! For subroutine outout
180       integer , parameter :: maxlvl = 100
181       real , dimension(maxlvl) :: plvl
182       integer :: nlvl
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 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
192 !  SET ARGUMENTS
194       call start()
195       unpack=.true.
196       expand=.true.
197       hdate = '0000-00-00_00:00:00'
198       ierr=0
199       itot=0
200       icount=0
201       iseek=0
202       lskip=0
203       lgrib=0
204       currlen=0
205       ith=1
206       scale_factor = 1e6
207 !     do j = 1,10
208 !       write(6,'("j = ",i4," level1 = ",i8," level2 = ",i8)') j, &
209 !         level1(j), level2(j)
210 !     enddo
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
234       if (ios.eq.0) then 
235       VERSION: do
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
242          if (lgrib.eq.0) then
243             exit 
244          endif
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
251             currlen=lgrib
252          endif
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
259             call errexit(9)
260          endif
261          iseek=lskip+lgrib
262          icount=icount+1
264          if (verbose)  PRINT *,'G2 GRIB MESSAGE ',icount,' starts at',lskip+1
266          ! Unpack GRIB2 field
267          call gb_info(cgrib,lengrib,listsec0,listsec1, &
268                       numfields,numlocal,maxlocal,ierr)
269          if (ierr.ne.0) then
270            write(*,*) ' ERROR querying GRIB2 message = ',ierr
271            stop 10
272          endif
273          itot=itot+numfields
275          grib_edition=listsec0(2)
276          if (grib_edition.ne.2) then
277               exit VERSION
278          endif
279          
280          ! Additional print statments for developer.
281          if (verbose) then
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.'
286          endif
288          ! ----
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:
296            n=1
297            call gf_getfld(cgrib,lengrib,n,unpack,expand,gfld,ierr)
298            
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'
307           else 
308             string = 'See code table 0.0'
309           endif
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'
347           else
348             string = 'see code table 3.1'
349           endif
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)
354           enddo
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)
361             enddo
362           endif
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
369           endif
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,*) '---------------------------------------------------------------------------'
376           endif
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
385            fcst = 0
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)
392            endif
394            ! Compute valid time. 
396           if (verbose) then
397             print *, 'ymd',gfld%idsect(6),gfld%idsect(7),gfld%idsect(8)
398             print *, 'hhmm  ',gfld%idsect(9),gfld%idsect(10)
399           endif
400    
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
406            !--
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'
432              else
433                map%source = 'unknown model from NCEP'
434                write (6,*) 'unknown NCEP model, iprocess = ',iprocess
435              end if
436            else if (icenter .eq. 57) then
437              if (iprocess .eq. 87) then
438                map%source = 'AFWA AGRMET'
439              else
440                map%source = 'AFWA'
441              endif
442            else if (icenter .eq. 98) then
443              map%source = 'ECMWF'
444            else
445              map%source = 'unknown model and orig center'
446            end if
448            !--
450            ! Store information about the grid on which the data is. 
451            ! This stuff gets stored in the MAP variable, as defined in 
452            ! module GRIDINFO.
454            map%startloc = 'SWCORNER'
456            if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
457               map%igrid = 0
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
468               endif
469               if (map%dy.gt.10000) then 
470                  map%dy = (map%dy/scale_factor)*(-1)
471               endif
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
476               endif
477               if (map%lon1.ge.scale_factor) then 
478                  map%lon1 = map%lon1/scale_factor
479               endif
481 !             if (iprocess.eq.81 .and. map%dy.eq.0) then !Hack for AFWA.
482 !                map%dx =  0.5
483 !                map%dy = -0.5
484 !             endif
486            elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
487               map%igrid = 3
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)
499               map%igrid = 0
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
510               endif
511               if (map%dy.gt.10000) then 
512                  map%dy = (map%dy/scale_factor)*(-1)
513               endif
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
518               endif
519               if (map%lon1.ge.scale_factor) then 
520                  map%lon1 = map%lon1/scale_factor
521               endif
522            print *,'Gaussian Grid: Dx,Dy,lat,lon',map%dx,map%dy, &
523              map%lat1,map%lon1
525            elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
526               map%igrid = 5
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
530               map%truelat1 = 60.
531               map%truelat2 = 91.
532               !map%dx = gfld%igdtmpl(x)
533               !map%dy = gfld%igdtmpl(x)
534               map%lat1 = gfld%igdtmpl(10)
535               map%lon1 = gfld%igdtmpl(11)
537            else
538               print*, 'GRIB2 Unknown Projection: ',gfld%igdtnum
539               print*, 'see Code Table 3.1: Grid Definition Template No'
540            endif
541          
542          endif
544          ! ----
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)
550            if (ierr.ne.0) then
551              write(*,*) ' ERROR extracting field gf_getfld = ',ierr
552              cycle
553            endif
555 ! ------------------------------------
556          ! Additional print information for developer.
557          pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1),  &
558                                   gfld%ipdtmpl(2))
559          if (debug_level .gt. 50 ) then
560            print *
561 !          print *,'G2 FIELD ',n
562            if (n==1) then
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) &
570                gfld%idsect(1)
571             write(*,'(5x,"Subcenter ID"'//pstring) gfld%idsect(2)
572             write(*,'(5x,"GRIB Master Table Version"'//pstring) &
573             gfld%idsect(3)
574             write(*,'(5x,"GRIB Local Table Version"'//pstring) &
575             gfld%idsect(4)
576             write(*,'(5x,"Significance of Reference Time"'//pstring) &
577             gfld%idsect(5)
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) &
585               gfld%idsect(12)
586             write(*,'(5x,"Type of processed data"'//pstring) &
587               gfld%idsect(13)
588 !           print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
589            endif
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)
595            enddo
596 !             print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
597            endif
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) &
604            gfld%numoct_opt
605            write(*,'(5x,"Interpretation list"'//pstring) &
606            gfld%interp_opt
607            write(*,'(5x,"Grid Definition Template Number"'//pstring) &
608            gfld%igdtnum
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")')
619              endif
620              write(*,'(10x,"Shape of the Earth"'//pstring) &
621                 gfld%igdtmpl(1)
622              write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
623                 gfld%igdtmpl(2)
624              write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
625                 gfld%igdtmpl(3)
626              write(*,'(10x,"Scale factor of major axis"'//pstring) &
627                 gfld%igdtmpl(4)
628              write(*,'(10x,"Scaled value of major axis"'//pstring) &
629                 gfld%igdtmpl(5)
630              write(*,'(10x,"Scale factor of minor axis"'//pstring) &
631                 gfld%igdtmpl(6)
632              write(*,'(10x,"Scaled value of minor axis"'//pstring) &
633                 gfld%igdtmpl(7)
634              write(*,'(10x,"Ni - points along a parallel"'//pstring) &
635                  gfld%igdtmpl(8)
636              write(*,'(10x,"Nj - points along a meridian"'//pstring) &
637                  gfld%igdtmpl(9)
638              write(*,'(10x,"Basic angle of initial domain"'//pstring)&
639                  gfld%igdtmpl(10)
640              write(*,'(10x,"Subdivisions of basic angle"'//pstring) &
641                  gfld%igdtmpl(11)
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)')&
645               gfld%igdtmpl(14)
646              write(*,'(10x,"La2"'//pstring) gfld%igdtmpl(15)
647              write(*,'(10x,"Lo2"'//pstring) gfld%igdtmpl(16)
648              write(*,'(10x,"Di - i-dir increment"'//pstring) &
649                gfld%igdtmpl(17)
650              write(*,'(10x,"Dj - j-dir increment"'//pstring) &
651                gfld%igdtmpl(18)
652              write(*,'(10x,"Scanning mode"'//pstring) &
653                gfld%igdtmpl(19)
654              if (gfld%igdtnum .eq. 1) then
655              write(*,'(10x,"Lat of southern pole of project"'//pstring)&
656                gfld%igdtmpl(20)
657              write(*,'(10x,"Lon of southern pole of project"'//pstring)&
658                gfld%igdtmpl(21)
659              write(*,'(10x,"Angle of rotation of projection"'//pstring)&
660                gfld%igdtmpl(22)
661              else if (gfld%igdtnum .eq. 2) then
662              write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
663                gfld%igdtmpl(20)
664              write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
665                gfld%igdtmpl(21)
666              write(*,'(10x,"Stretching factor"'//pstring) &
667                gfld%igdtmpl(22)
668              else if (gfld%igdtnum .eq. 3) then
669              write(*,'(10x,"Lat of southern pole of project"'//pstring)&
670                gfld%igdtmpl(20)
671              write(*,'(10x,"Lon of southern pole of project"'//pstring)&
672                gfld%igdtmpl(21)
673              write(*,'(10x,"Angle of rotation of projection"'//pstring)&
674                gfld%igdtmpl(22)
675              write(*,'(10x,"Lat of the pole of stretching "'//pstring)&
676                gfld%igdtmpl(23)
677              write(*,'(10x,"Lon of the pole of stretching "'//pstring)&
678                gfld%igdtmpl(24)
679              write(*,'(10x,"Stretching factor"'//pstring) &
680                gfld%igdtmpl(25)
681              endif
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")')
689              endif
690              write(*,'(10x,"Shape of the Earth"'//pstring) &
691                 gfld%igdtmpl(1)
692              write(*,'(10x,"Scale factor of spher. Earth"'//pstring) &
693                 gfld%igdtmpl(2)
694              write(*,'(10x,"Scaled value of spher. Earth"'//pstring) &
695                 gfld%igdtmpl(3)
696              write(*,'(10x,"Scale factor of major axis"'//pstring) &
697                 gfld%igdtmpl(4)
698              write(*,'(10x,"Scaled value of major axis"'//pstring) &
699                 gfld%igdtmpl(5)
700              write(*,'(10x,"Scale factor of minor axis"'//pstring) &
701                 gfld%igdtmpl(6)
702              write(*,'(10x,"Scaled value of minor axis"'//pstring) &
703                 gfld%igdtmpl(7)
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)')&
709               gfld%igdtmpl(12)
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) &
715                gfld%igdtmpl(17)
716              write(*,'(10x,"Scanning mode"'//pstring) &
717                gfld%igdtmpl(18)
718              if (gfld%igdtnum .eq. 30) then
719              write(*,'(10x,"Latin 1 "'//pstring) &
720                gfld%igdtmpl(19)
721              write(*,'(10x,"Latin 2 "'//pstring) &
722                gfld%igdtmpl(20)
723              write(*,'(10x,"Lat of southern pole of project"'//pstring)&
724                gfld%igdtmpl(21)
725              write(*,'(10x,"Lon of southern pole of project"'//pstring)&
726                gfld%igdtmpl(22)
727              endif
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 ")')
737              endif
738            else
739            do j = 1, gfld%igdtlen
740              write(*,'(5x,"Grid Definition Template entry "'//pstring) &
741              gfld%igdtmpl(j)
742            enddo
743            endif
744 !          print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts, &
745 !                                 gfld%numoct_opt,gfld%interp_opt,  &
746 !                                 gfld%igdtnum
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.'
751            else
752              print *,'G2 Section 3 Optional List: ',     &
753                       (gfld%list_opt(j),j=1,gfld%num_opt)
754            endif
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)&
758             gfld%ipdtnum
759             do j = 1, gfld%ipdtlen
760               write(tmp4,'(i4)') j
761               string = '(5x,"Template Entry  '//tmp4 // '"'
762               write(*,string//pstring) gfld%ipdtmpl(j)
763             enddo
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)')&
770            pabbrev
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.'
775            else
776              print *,'G2 Section 4 Optional Coordinates: ',   &
777                    (gfld%coord_list(j),j=1,gfld%num_coord)
778            endif
779 !          if ( gfld%ibmap .ne. 255 ) then
780 !             print *,'G2 Num. of Data Points = ',gfld%ndpts,   &
781 !                  '    with BIT-MAP ',gfld%ibmap
782 !          else
783 !             print *,'G2 Num. of Data Points = ',gfld%ndpts,  &
784 !                     '    NO BIT-MAP '
785 !          endif
786          write(*,'(/,"GRIB2 SECTION 5 - DATA REPRESENTATION SECTION:")')
787          write(*,'(5x,"Data Representation Template Number"'//pstring)&
788             gfld%idrtnum
789             do j = 1, gfld%idrtlen
790               write(tmp4,'(i4)') j
791               string = '(5x,"Template Entry  '//tmp4 // '"'
792               write(*,string//pstring) gfld%idrtmpl(j)
793             enddo
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
805 !         write(6,*) 'Mass'
806 !       endif
807 !      endif
809          write(*,'(/,"GRIB2 SECTION 6 - BIT-MAP SECTION:")')
810          write(*,'(5x,"Bit-map indicator"'//pstring) &
811            gfld%ibmap
813            fldmax=gfld%fld(1)
814            fldmin=gfld%fld(1)
815            sum=gfld%fld(1)
816            do j=2,gfld%ndpts
817              if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
818              if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
819              sum=sum+gfld%fld(j)
820            enddo ! gfld%ndpts
822          write(*,'(/,"GRIB2 SECTION 7 - DATA SECTION:")')
824          write(*,'(5x,"Minimum Data Value "'//rstring)&
825             fldmin
826          write(*,'(5x,"Maximum Data Value "'//rstring)&
827             fldmax
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
833 !           do j=1,gfld%ndpts
834 !              write(*,*) j, gfld%fld(j)
835 !           enddo
836          endif
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)
844          endif
846          enddo ! 1,numfields
849          ! Deallocate arrays decoding GRIB2 record.
850          call gf_free(gfld)
852       enddo VERSION ! skgb
855       if (debug_level .gt. 50) &
856          print *, 'G2 total number of fields found = ',itot
857       call summary()
859       CALL BACLOSE(junit,IOS)
861        ireaderr=1
862       else 
863        print *,'open status failed because',ios
864        hdate = '9999-99-99_99:99:99'
865        ireaderr=2
866       endif ! ireaderr check 
868       END subroutine r_grib2
870 !*****************************************************************************!
871 ! Subroutine edition_num                                                         !
872 !                                                                             !
873 ! Purpose:                                                                    !
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.                                             !
879 !                                                                             !
880 ! Argument list:                                                              !
881 !    Input:                                                                   !
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     !
887 !                 stored.                                                     !
888 !       GRIB2FILE: File name to open, if it is not already open.              !
889 !                                                                             !
890 !    Output:                                                                  !
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    !
895 !                                  not exist.                                 !
896 ! Author: Paula McCaslin                                                      !
897 ! NOAA/FSL                                                                    !
898 ! Sept 2004                                                                   !
899 !*****************************************************************************!
900       
901       SUBROUTINE edition_num(junit, gribflnm, grib_edition, ireaderr)
903       use grib_mod
904       use params
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
912       integer :: junit
913       integer :: grib_edition
914       integer :: i, j, ireaderr
915       integer :: currlen
917       character(len=4) :: ctemp
918       character(len=4),parameter :: grib='GRIB',c7777='7777'
920 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
921 !  SET ARGUMENTS
923       call start()
924       itot=0
925       icount=0
926       iseek=0
927       lskip=0
928       lgrib=0
929       currlen=0
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
953       if (ios.eq.0) then 
955          ! Search opend file for the next GRIB2 messege (record).
956          call skgb(junit,iseek,msk1,lskip,lgrib)
958          ! Check for EOF, or problem
959          if (lgrib.eq.0) then
960             STOP "Grib2 file or date problem, stopping in edition_num."
961          endif
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)
967             currlen=lgrib
968          endif
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
974          istart=0
975          do j=1,100
976             ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
977             if (ctemp.eq.grib ) then
978               istart=j
979               exit
980             endif
981          enddo
982          if (istart.eq.0) then
983             ireaderr=3
984             print*, "The beginning 4 characters >GRIB< were not found."
985          endif
986    
987          ! Unpack Section 0 - Indicator Section to extract GRIB edition field
988          iofst=8*(istart+5)
989          call gbyte(cgrib,discipline,iofst,8)     ! Discipline
990          iofst=iofst+8
991          call gbyte(cgrib,grib_edition,iofst,8)   ! GRIB edition number
993          print *, 'ungrib - grib edition num',  grib_edition
994          call summary()
995          CALL BACLOSE(junit,IOS)
996          ireaderr=1
997       else if (ios .eq. -4) then
998         print *,'edition_num: unable to open ',gribflnm
999         stop 'edition_num'
1000       else 
1001          print *,'edition_num: open status failed because',ios,gribflnm
1002          ireaderr=2
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, &
1007      hlast)
1008   integer :: err
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
1016   integer :: ioff = 0
1018   if (present(hlast)) then
1019      ioff = -1
1020   endif
1022   err = 0
1024   narg = iargc()
1025   numarg = narg + ioff
1027   i = 1
1028   LOOP : do while ( i <= numarg)
1030      ierr = 1
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)
1037      endif
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)
1046      endif
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)
1055      endif
1056      if (ierr.eq.0) cycle LOOP
1058      err = 1
1059      call getarg(1, hold)
1060      write(*, '("arg = ", A)') trim(hold)
1062      exit LOOP
1064   enddo LOOP
1066   if (present(hlast)) then
1067      if (narg.eq.0) then
1068         err = 1
1069      else
1070         call getarg(narg, hlast)
1071      endif
1072   endif
1074 contains
1075   subroutine checkiarg(c, a, i, ierr)
1076     integer :: c
1077     character(len=*) :: a
1078     integer :: i
1080     character(len=100) :: hold
1081     ierr = 1
1083     call getarg(c, hold)
1085     if ('-'//a.eq.trim(hold)) then
1086        c = c + 1
1087        call getarg(c, hold)
1088        read(hold, *) i
1089        c = c + 1
1090        ierr = 0
1091     elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1092        hold = hold(len_trim(a)+2: len(hold))
1093        read(hold, *) i
1094        c = c + 1
1095        ierr = 0
1096     endif
1098   end subroutine checkiarg
1099   subroutine checkharg(c, a, h, ierr)
1100     integer :: c
1101     character(len=*) :: a
1102     character(len=*) :: h
1104     character(len=100) :: hold
1105     ierr = 1
1107     call getarg(c, hold)
1109     if ('-'//a.eq.trim(hold)) then
1110        c = c + 1
1111        call getarg(c, hold)
1112        h = trim(hold)
1113        c = c + 1
1114        ierr = 0
1115     elseif ('-'//a .eq. hold(1:len_trim(a)+1)) then
1116        hold = hold(len_trim(a)+2: len(hold))
1117        h = trim(hold)
1118        c = c + 1
1119        ierr = 0
1120     endif
1122   end subroutine checkharg
1124   subroutine checklarg(c, a, l, ierr)
1125     integer :: c
1126     character(len=*) :: a
1127     logical :: l
1129     character(len=100) :: hold
1130     ierr = 1
1132     call getarg(c, hold)
1133     if ('-'//a.eq.trim(hold)) then
1134        l = .TRUE.
1135        c = c + 1
1136        ierr = 0
1137     endif
1139   end subroutine checklarg
1141 end subroutine parse_args