1 !*****************************************************************************!
2 ! Subroutine RD_GRIB2 !
5 ! Read one record from the input GRIB2 file. Based on the information in !
6 ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
7 ! the GRIB2 record is one to process or to skip. If the field is one we !
8 ! want to keep, extract the data from the GRIB2 record, and store the data !
9 ! in the ungrib memory structure. !
13 ! junit : "Unit Number" to open and read from. Not really a Fortran !
14 ! unit number, since we do not do Fortran I/O for the GRIB2 !
15 ! files. Nor is it a UNIX File Descriptor returned from a C !
16 ! OPEN statement. It is really just an array index to the !
17 ! array (IUARR) where the UNIX File Descriptor values are !
19 ! gribflnm : File name to open, if it is not already open. !
20 ! debug_level : Integer for various amounts of printout. !
24 ! hdate : The (up to)19-character date of the field to process. !
25 ! grib_edition : Version of the gribfile (1 or 2) !
26 ! ireaderr : Error flag: 0 - no error on read from GRIB2 file. !
27 ! 1 - Hit the end of the GRIB2 file. !
28 ! 2 - The file GRIBFLNM we tried to open does !
32 ! Author: Paula McCaslin, NOAA/FSL, Sept 2004 !
33 ! Code is based on code developed by Steve Gilbert NCEP & Kevin Manning NCAR !
34 ! Adapted for WPS: Jim Bresch, NCAR/MMM. Sept 2006 !
35 !*****************************************************************************!
37 SUBROUTINE rd_grib2(junit, gribflnm, hdate,
38 & grib_edition, ireaderr, debug_level)
42 use table ! Included to define g2code
43 use gridinfo ! Included to define map%
44 use storage_module ! Included sub put_storage
47 real, allocatable, dimension(:) :: hold_array
48 parameter(msk1=32000,msk2=4000)
49 character(len=1),allocatable,dimension(:) :: cgrib
50 integer :: listsec0(3)
51 integer :: listsec1(13)
52 integer year, month, day, hour, minute, second, fcst
53 character(len=*) :: gribflnm
54 character(len=*) :: hdate
55 character(len=8) :: pabbrev
56 character(len=20) :: labbrev
57 character(len=80) :: tabbrev
58 integer :: lskip, lgrib
59 integer :: junit, itot, icount, iseek
60 integer :: grib_edition
61 integer :: i, j, ireaderr, ith , debug_level
63 logical :: unpack, expand
64 type(gribfield) :: gfld
65 ! For subroutine put_storage
69 character (len=9) :: my_field
70 character (len=8) :: tmp8
71 ! For subroutine outout
72 integer , parameter :: maxlvl = 100
73 real , dimension(maxlvl) :: plvl
75 integer , dimension(maxlvl) :: level_array
76 logical :: first = .true.
78 C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
83 hdate = '0000-00-00_00:00:00'
93 call mprintf(.true.,DEBUG,"Begin rd_grib2", newline=.true.)
95 !/* IOS Return Codes from BACIO: */
97 !/* -1 Tried to open read only _and_ write only */
98 !/* -2 Tried to read and write in the same call */
99 !/* -3 Internal failure in name processing */
100 !/* -4 Failure in opening file */
101 !/* -5 Tried to read on a write-only file */
102 !/* -6 Failed in read to find the 'start' location */
103 !/* -7 Tried to write to a read only file */
104 !/* -8 Failed in write to find the 'start' location */
105 !/* -9 Error in close */
106 !/* -10 Read or wrote fewer data than requested */
108 !if ireaderr =1 we have hit the end of a file.
109 !if ireaderr =2 we have hit the end of all the files.
112 ! Open a byte-addressable file.
113 CALL BAOPENR(junit,gribflnm,IOS)
118 ! Search opend file for the next GRIB2 messege (record).
119 call skgb(junit,iseek,msk1,lskip,lgrib)
121 ! Check for EOF, or problem
126 ! Check size, if needed allocate more memory.
127 if (lgrib.gt.currlen) then
128 if (allocated(cgrib)) deallocate(cgrib)
129 allocate(cgrib(lgrib),stat=is)
130 !print *,'G2 allocate(cgrib(lgrib)) status: ',IS
134 ! Read a given number of bytes from unblocked file.
135 call baread(junit,lskip,lgrib,lengrib,cgrib)
137 call mprintf ((lgrib.ne.lengrib),ERROR,
138 & "rd_grib2: IO Error. %i .ne. %i ", newline=.true.,
139 & i1=lgrib,i2=lengrib)
144 call mprintf (.true.,DEBUG,
145 & "G2 GRIB MESSAGE %i starts at %i ", newline=.true.,
146 & i1=icount,i2=lskip+1)
149 call gb_info(cgrib,lengrib,listsec0,listsec1,
150 & numfields,numlocal,maxlocal,ierr)
151 call mprintf((ierr.ne.0),ERROR,
152 & " ERROR querying GRIB2 message = %i",newline=.true.,i1=ierr)
155 grib_edition=listsec0(2)
156 if (grib_edition.ne.2) then
160 ! Additional print statments for developer.
161 !MGD if ( debug_level .GT. 100 ) then
162 !MGD print *,'G2 SECTION 0: ',(listsec0(j),j=1,3)
163 !MGD print *,'G2 SECTION 1: ',(listsec1(j),j=1,13)
164 !MGD print *,'G2 Contains ',numlocal,' Local Sections ',
165 !MGD & ' and ',numfields,' data fields.'
170 ! Once per file fill in date, model and projection values.
175 ! Build the 19-character date string, based on GRIB2 header date
176 ! and time information, including forecast time information:
179 call gf_getfld(cgrib,lengrib,n,.FALSE.,expand,gfld,ierr)
180 year =gfld%idsect(6) !(FOUR-DIGIT) YEAR OF THE DATA
181 month =gfld%idsect(7) ! MONTH OF THE DATA
182 day =gfld%idsect(8) ! DAY OF THE DATA
183 hour =gfld%idsect(9) ! HOUR OF THE DATA
184 minute=gfld%idsect(10) ! MINUTE OF THE DATA
185 second=gfld%idsect(11) ! SECOND OF THE DATA
189 ! Extract forecast time.
190 if ( gfld%ipdtmpl(8) .eq. 1 ) then ! time units are hours
191 fcst = gfld%ipdtmpl(9)
192 else if ( gfld%ipdtmpl(8) .eq. 0 ) then ! minutes
193 fcst = gfld%ipdtmpl(9) / 60.
194 else if ( gfld%ipdtmpl(8) .eq. 2 ) then ! days
195 fcst = gfld%ipdtmpl(9) * 24.
197 call mprintf(.true.,ERROR,
198 & "Time unit in ipdtmpl(8), %i is not suported",
199 & newline=.true.,i1=gfld%ipdtmpl(8))
202 ! Compute valid time.
204 !print *, 'ymd',gfld%idsect(6),gfld%idsect(7),gfld%idsect(8)
205 !print *, 'hhmm ',gfld%idsect(9),gfld%idsect(10)
207 call build_hdate(hdate,year,month,day,hour,minute,second)
208 call mprintf(.true.,DEBUG,"G2 hdate = %s ", newline=.true.,
210 call geth_newdate(hdate,hdate,3600*fcst)
211 call mprintf(.true.,DEBUG,"G2 hdate (fcst?) = %s ",
212 & newline=.true., s1=hdate)
216 ! Indicator of the source (center) of the data.
217 icenter = gfld%idsect(1)
219 ! Indicator of model (or whatever) which generated the data.
220 iprocess = gfld%ipdtmpl(5)
223 if (icenter.eq.7) then
224 if (iprocess.eq.83 .or. iprocess.eq.84) then
225 map%source = 'NCEP MESO NAM Model'
226 elseif (iprocess.eq.81) then
227 map%source = 'NCEP GFS Analysis'
228 elseif (iprocess.eq.82) then
229 map%source = 'NCEP GFS GDAS/FNL'
230 elseif (iprocess.eq.89) then
231 map%source = 'NCEP NMM '
232 elseif (iprocess.eq.96) then
233 map%source = 'NCEP GFS Model'
234 elseif (iprocess.eq.86 .or. iprocess.eq.100) then
235 map%source = 'NCEP RUC Model' ! 60 km
236 elseif (iprocess.eq.101) then
237 map%source = 'NCEP RUC Model' ! 40 km
238 elseif (iprocess.eq.105) then
239 map%source = 'NCEP RUC Model' ! 20 km
240 elseif (iprocess.eq.107) then
241 map%source = 'NCEP GEFS'
242 elseif (iprocess.eq.109) then
243 map%source = 'NCEP RTMA'
244 elseif (iprocess.eq.140) then
245 map%source = 'NCEP NARR'
246 elseif (iprocess.eq.44) then
247 map%source = 'NCEP SST Analysis'
248 elseif (iprocess.eq.70) then
249 map%source = 'GFDL Hurricane Model'
250 elseif (iprocess.eq.80) then
251 map%source = 'NCEP GFS Ensemble'
252 elseif (iprocess.eq.107) then ! renumbered as of 23 Feb 2010
253 map%source = 'NCEP GFS Ensemble'
254 elseif (iprocess.eq.129) then
255 map%source = 'NCEP GODAS'
256 elseif (iprocess.eq.25) then
257 map%source = 'NCEP SNOW COVER ANALYSIS'
259 map%source = 'unknown model from NCEP'
260 call mprintf(.true.,STDOUT,
261 & "unknown model from NCEP %i ",newline=.true.,
263 call mprintf(.true.,LOGFILE,
264 & "unknown model from NCEP %i ",newline=.true.,
267 else if (icenter .eq. 57) then
268 if (iprocess .eq. 87) then
269 map%source = 'AFWA AGRMET'
273 else if ( icenter .eq. 58 ) then
274 map%source = 'US Navy FNOC'
275 else if (icenter .eq. 59) then
276 if (iprocess .eq. 125) then
277 map%source = 'NOAA GSD Rapid Refresh'
278 else if (iprocess .eq. 105) then
279 map%source = 'NOAA GSD'
281 print *,'Unknown GSD source'
284 else if (icenter .eq. 60) then
286 else if (icenter .eq. 98) then
288 else if (icenter .eq. 34) then
290 else if (icenter .eq. 74 .or. icenter .eq. 75 ) then
293 map%source = 'unknown model and orig center'
295 call mprintf(.true.,DEBUG,"G2 source is = %s ",
296 & newline=.true., s1=map%source)
300 ! Store information about the grid containing the data.
301 ! This stuff gets stored in the MAP variable, as defined in
304 map%startloc = 'SWCORNER'
305 map%grid_wind = .true.
307 if (gfld%igdtnum.eq.0) then ! Lat/Lon grid aka Cylindrical Equidistant
309 map%nx = gfld%igdtmpl(8)
310 map%ny = gfld%igdtmpl(9)
311 map%dx = gfld%igdtmpl(17)
312 map%dy = gfld%igdtmpl(18)
313 map%lat1 = gfld%igdtmpl(12)
314 map%lon1 = gfld%igdtmpl(13)
315 write(tmp8,'(b8.8)') gfld%igdtmpl(14)
316 if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
317 map%r_earth = earth_radius (gfld%igdtmpl(1),
318 & gfld%igdtmpl(2),gfld%igdtmpl(3))
320 ! Fix for NCEP 1/12 degree grids (e.g. rtgsst)
321 if (icenter .eq. 7 .and. map%dx .eq. 83000. .and. map%nx
325 map%dx = 83333.333 * sign(1.0,map%dx)
326 map%dy = 83333.333 * sign(1.0,map%dy)
329 if ((gfld%igdtmpl(10) .eq. 0).OR.
330 & (gfld%igdtmpl(10) .eq. 255)) THEN
331 ! Scale lat/lon values to 0-180, default range is 1e6.
332 map%lat1 = map%lat1/scale_factor
333 map%lon1 = map%lon1/scale_factor
334 ! Scale dx/dy values to degrees, default range is 1e6.
335 map%dx = map%dx/scale_factor
336 map%dy = map%dy/scale_factor
338 ! Basic angle and subdivisions are non-zero (not tested)
339 map%lat1 = map%lat1 *
340 & (gfld%igdtmpl(11)/gfld%igdtmpl(10))
341 map%lon1 = map%lon1 *
342 & (gfld%igdtmpl(11)/gfld%igdtmpl(10))
344 & (gfld%igdtmpl(11)/gfld%igdtmpl(10))
346 & (gfld%igdtmpl(11)/gfld%igdtmpl(10))
347 call mprintf(.true.,STDOUT,"WARNING - Basic angle option
348 &has not been tested, continuing anyway")
349 call mprintf(.true.,LOGFILE,"WARNING - Basic angle option
350 & has not been tested, continuing anyway")
354 ! The following is needed for NCEP GFS, 0.5 degree output. The j-scan is in the -y direction.
355 ! In WPS, the sign of dy indicates the direction of the scan.
356 write(tmp8,'(b8.8)') gfld%igdtmpl(19)
357 read(tmp8,'(1x,i1)') jscan
358 if ( jscan .eq. 0 .and. map%dy .gt. 0. ) then
359 map%dy = -1. * map%dy
361 ! if ( map%lat1 .gt. gfld%igdtmpl(15) .and.
362 ! & map%dy .gt. 0. ) then
363 ! map%dy = -1. * map%dy
364 ! write(6,*) 'Resetting map%dy for iprocess = ',iprocess
367 elseif (gfld%igdtnum.eq.20) then ! Polar-Stereographic Grid.
369 map%nx = gfld%igdtmpl(8)
370 map%ny = gfld%igdtmpl(9)
371 map%lov = gfld%igdtmpl(14) / scale_factor
374 map%dx = gfld%igdtmpl(15) / scale_factor
375 map%dy = gfld%igdtmpl(16) / scale_factor
376 map%lat1 = gfld%igdtmpl(10) / scale_factor
377 map%lon1 = gfld%igdtmpl(11) / scale_factor
378 write(tmp8,'(b8.8)') gfld%igdtmpl(12)
379 if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
380 map%r_earth = earth_radius (gfld%igdtmpl(1),
381 & gfld%igdtmpl(2),gfld%igdtmpl(3))
383 elseif (gfld%igdtnum.eq.30) then ! Lambert Conformal Grid
385 map%nx = gfld%igdtmpl(8)
386 map%ny = gfld%igdtmpl(9)
387 map%lov = gfld%igdtmpl(14) / scale_factor
388 map%truelat1 = gfld%igdtmpl(19) / scale_factor
389 map%truelat2 = gfld%igdtmpl(20) / scale_factor
390 map%dx = gfld%igdtmpl(15) / scale_factor
391 map%dy = gfld%igdtmpl(16) / scale_factor
392 map%lat1 = gfld%igdtmpl(10) / scale_factor
393 map%lon1 = gfld%igdtmpl(11) / scale_factor
394 write(tmp8,'(b8.8)') gfld%igdtmpl(12)
395 if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
396 map%r_earth = earth_radius (gfld%igdtmpl(1),
397 & gfld%igdtmpl(2),gfld%igdtmpl(3))
399 elseif(gfld%igdtnum.eq.40) then ! Gaussian Grid (we will call it lat/lon)
401 map%nx = gfld%igdtmpl(8) ! Ni - # of points along a parallel
402 map%ny = gfld%igdtmpl(9) ! Nj - # of points along meridian
403 map%dx = gfld%igdtmpl(17) ! Di - i direction increment
404 map%dy = gfld%igdtmpl(18) ! N - # of parallels between pole and equator
405 map%lat1 = gfld%igdtmpl(12) ! La1 - lat of 1st grid point
406 map%lon1 = gfld%igdtmpl(13) ! Lo1 - lon of 1st grid point
407 write(tmp8,'(b8.8)') gfld%igdtmpl(14) ! resolution/component flag
408 if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
409 map%r_earth = earth_radius (gfld%igdtmpl(1),
410 & gfld%igdtmpl(2),gfld%igdtmpl(3))
412 ! Scale dx/dy values to degrees, default range is 1e6.
413 if (map%dx.gt.10000) then
414 map%dx = map%dx/scale_factor
416 if (map%dy.gt.10000) then
417 map%dy = (map%dy/scale_factor)*(-1)
420 ! Scale lat/lon values to 0-180, default range is 1e6.
421 if (map%lat1.ge.scale_factor) then
422 map%lat1 = map%lat1/scale_factor
424 if (map%lon1.ge.scale_factor) then
425 map%lon1 = map%lon1/scale_factor
427 if ( debug_level .gt. 2 ) then
428 call mprintf(.true.,DEBUG,
429 & "Gaussian Grid: Dx,Dy,lat,lon,nlats %f %f %f %f %i ",
430 & newline=.true.,f1=map%dx,f2=map%dy,f3=map%lat1,f4=map%lon1,
435 call mprintf(.true.,STDOUT,"GRIB2 Unknown Projection: %i",
436 & newline=.true.,i1=gfld%igdtnum)
437 call mprintf(.true.,STDOUT,
438 & "see Code Table 3.1: Grid Definition Template Number",
440 call mprintf(.true.,LOGFILE,
441 & "GRIB2 Unknown Projection: %i",
442 & newline=.true.,i1=gfld%igdtnum)
443 call mprintf(.true.,LOGFILE,
444 & "see Code Table 3.1: Grid Definition Template Number",
448 call mprintf(.true.,DEBUG,"G2 igrid = %i , dx = %f , dy = %
449 &f ", newline=.true., i1 = map%igrid, f1=map%dx, f2=map%dy)
451 if (icenter.eq.7) then
452 call ncep_grid_num (gfld%igdtnum)
455 ! Deallocate arrays decoding GRIB2 record.
461 ! Continue to unpack GRIB2 field.
462 do n=1,numfields ! e.g. U and V would =2, otherwise its usually =1
463 call gf_getfld(cgrib,lengrib,n,.FALSE.,expand,gfld,ierr)
465 write(*,*) ' ERROR extracting field gf_getfld = ',ierr
469 ! The JMA GSM has two different grids in the same GRIB file, so we need
470 ! to process the map info for each field separately. If any other centers do
471 ! this, then processing will need to be added here, too.
473 if (icenter .eq. 34 .and. gfld%igdtnum.eq.0) then
474 map%nx = gfld%igdtmpl(8)
475 map%ny = gfld%igdtmpl(9)
476 map%dx = gfld%igdtmpl(17)
477 map%dy = gfld%igdtmpl(18)
478 ! Scale dx/dy values to degrees, default range is 1e6.
479 if (map%dx.gt.10000) then
480 map%dx = map%dx/scale_factor
482 if (map%dy.gt.10000) then
483 map%dy = map%dy/scale_factor
485 write(tmp8,'(b8.8)') gfld%igdtmpl(19)
486 read(tmp8,'(1x,i1)') jscan
487 write(0,*) 'gfld%igdtmpl(19) = ',gfld%igdtmpl(19),
489 if ( jscan .eq. 0 .and. map%dy .gt. 0. ) then
490 map%dy = -1. * map%dy
494 ! ------------------------------------
495 ! Additional print information for developer.
496 if ( debug_level .GT. 1000 ) then
498 !MGD print *,'G2 FIELD ',n
500 !MGD print *,'G2 SECTION 0: ',gfld%discipline,gfld%version
501 !MGD print *,'G2 SECTION 1: ',(gfld%idsect(j),j=1,gfld%idsectlen)
503 !MGD if ( associated(gfld%local).AND.gfld%locallen.gt.0 ) then
504 !MGD print *,'G2 SECTION 2: ',(gfld%local(j),j=1,gfld%locallen)
506 !MGD print *,'G2 SECTION 3: ',gfld%griddef,gfld%ngrdpts,
507 !MGD & gfld%numoct_opt,gfld%interp_opt,
509 !MGD print *,'G2 GRID TEMPLATE 3.',gfld%igdtnum,': ',
510 !MGD & (gfld%igdtmpl(j),j=1,gfld%igdtlen)
511 !MGD if ( gfld%num_opt .eq. 0 ) then
512 !MGD print *,'G2 NO Section 3 List Defining No. of Data Points.'
514 !MGD print *,'G2 Section 3 Optional List: ',
515 !MGD & (gfld%list_opt(j),j=1,gfld%num_opt)
517 !MGD print *,'G2 PRODUCT TEMPLATE 4.',gfld%ipdtnum,': ',
518 !MGD & (gfld%ipdtmpl(j),j=1,gfld%ipdtlen)
520 pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1),
522 !call prlevel(gfld%ipdtnum,gfld%ipdtmpl,labbrev)
523 !call prvtime(gfld%ipdtnum,gfld%ipdtmpl,listsec1,tabbrev)
524 !MGD print *,'G2 TEXT: ',pabbrev,trim(labbrev)," ",trim(tabbrev)
526 !MGD if ( gfld%num_coord .eq. 0 ) then
527 !MGD print *,'G2 NO Optional Vertical Coordinate List.'
529 !MGD print *,'G2 Section 4 Optional Coordinates: ',
530 !MGD & (gfld%coord_list(j),j=1,gfld%num_coord)
532 if ( gfld%ibmap .ne. 255 ) then
533 call mprintf(.true.,DEBUG,
534 & 'G2 Num. of Data Points = %i with BIT-MAP %i',
535 & newline=.true., i1=gfld%ndpts, i2=gfld%ibmap)
537 call mprintf(.true.,DEBUG,
538 & 'G2 Num. of Data Points = %i NO BIT-MAP',
539 & newline=.true., i1=gfld%ndpts)
541 !MGD print *,'G2 DRS TEMPLATE 5.',gfld%idrtnum,': ',
542 !MGD & (gfld%idrtmpl(j),j=1,gfld%idrtlen)
547 if (gfld%fld(j).gt.fldmax) fldmax=gfld%fld(j)
548 if (gfld%fld(j).lt.fldmin) fldmin=gfld%fld(j)
552 !MGD print *,'G2 Data Values:'
553 call mprintf(.true.,DEBUG,'G2 MIN=%f AVE=%f MAX=%f',
554 & newline=.true., f1=fldmin, f2=sum/gfld%ndpts, f3=fldmax)
555 !do j=1,gfld%ndpts\20
556 ! write(*,*) j, gfld%fld(j)
558 endif ! Additional Print information
559 ! ------------------------------------
562 ! write(6,'(a10,4i8)') namvar(i),(g2code(j,i),j=1,4)
564 !MGD if (debug_level .gt. 50) then
565 !MGD write(6,*) 'looking for ',gfld%discipline,gfld%ipdtmpl(1),
566 !MGD & gfld%ipdtmpl(2),gfld%ipdtmpl(10)
568 call mprintf(.true.,DEBUG,"G2 Searching the g2code array (Vta
569 &ble) for this grib field %i %i %i %i ", newline=.true.,
570 & i1 = gfld%discipline, i2 = gfld%ipdtmpl(1),
571 & i3 = gfld%ipdtmpl(2), i4 = gfld%ipdtmpl(10) )
573 ! Test this data record against list of desired variables
576 MATCH_LOOP: do i=1,maxvar ! Max variables found in Vtable,
577 ! maxvar is defined in table.mod
579 if ( gfld%discipline .eq. g2code(1,i) .and. !Discipline
580 & gfld%ipdtmpl(1) .eq. g2code(2,i) .and. !Category
581 & gfld%ipdtmpl(2) .eq. g2code(3,i) .and. !Parameter
582 & gfld%ipdtmpl(10) .eq. g2code(4,i) .and. !Elevation
583 & gfld%ipdtnum .eq. g2code(5,i)) then !Template
586 call gf_getfld(cgrib,lengrib,n,.TRUE.,expand,gfld,ierr)
587 pabbrev=param_get_abbrev(gfld%discipline,gfld%ipdtmpl(1),
590 !my_field (e.g. RH, TMP, similar to, but not the same as pabbrev)
593 !MGD if (debug_level .gt. 50) then
594 !MGD write(6,*) 'namvar(i) = ',namvar(i),' pabbrev = ',pabbrev
595 !MGD write(6,*) 'Parameter = ',gfld%ipdtmpl(2)
599 ! need to match up soil levels with those requested.
600 ! For the Vtable levels, -88 = all levels, -99 = missing. The units
601 ! vary depending on the level code (e.g. 106 = cm, 103 = m).
602 if ( gfld%ipdtmpl(10) .eq. 106 ) then
603 TMP8LOOP: do j = 1, maxvar
604 if ((g2code(4,j) .eq. 106) .and.
605 & (gfld%ipdtmpl(2) .eq. g2code(3,j)) .and.
606 & (gfld%ipdtmpl(12) .eq. level1(j)) .and.
607 & ((gfld%ipdtmpl(15) .eq. level2(j)) .or.
608 & (level2(j) .le. -88))) then
613 if (j .gt. maxvar ) then
614 write(6,'(a,i6,a,i6,a)') 'Subsoil level ',
615 & gfld%ipdtmpl(12),' to ',gfld%ipdtmpl(15),
616 & ' in the GRIB2 file, was not found in the Vtable'
619 !MGD if (debug_level .gt. 50) write(6,*) 'my_field is now ',my_field
622 ! Level (eg. 10000 mb)
623 if(gfld%ipdtmpl(10).eq.100) then
624 ! Pressure level (range from 1000mb to 0mb)
625 level=gfld%ipdtmpl(12) *
626 & (10. ** (-1. * gfld%ipdtmpl(11)))
627 elseif(gfld%ipdtmpl(10).eq.105) then
628 ! Hybrid level (range from 1 to N)
629 level=gfld%ipdtmpl(12)
630 elseif(gfld%ipdtmpl(10).eq.104) then
631 ! Sigma level (range from 10000 to 0)
632 level=gfld%ipdtmpl(12)
633 elseif(gfld%ipdtmpl(10).eq.101) then
636 elseif(gfld%ipdtmpl(10).eq.106.or.
637 & gfld%ipdtmpl(10).eq.1) then
638 ! Misc near ground/surface levels
640 elseif(gfld%ipdtmpl(10).eq.6) then
642 level=6. ! .06 mb should never be used by anyone
643 elseif(gfld%ipdtmpl(10).eq.7) then
645 level=7. ! .07 mb should never be used by anyone
647 ! Misc near ground/surface levels
652 ! Store the unpacked 2D slab from the GRIB2 record
653 allocate(hold_array(gfld%ngrdpts))
655 hold_array(j)=gfld%fld(j)
658 ! Some grids need to be reordered. Until we get an example, this is
660 ! call reorder_it (hold_array, map%nx, map%ny, map%dx,
663 ! When we have reached this point, we have a data array ARRAY
664 ! which has some data we want to save, with field name FIELD
665 ! at pressure level LEVEL (Pa). Dimensions of this data are
666 ! map%nx and map%ny. Put this data into storage.
668 !print *,'call put_storage',iplvl,my_field,hold_array(55),ith
669 !e.g. call put_storage(200100, 'RH', my_field, 1, ith)
670 call put_storage(iplvl,my_field,
671 & reshape(hold_array(1:map%nx*map%ny),
672 & (/map%nx, map%ny/)), map%nx,map%ny)
673 deallocate(hold_array)
675 ! If Specific Humidity is present on hybrid levels AND
676 ! upper-air RH is missing, see if we can compute RH from
678 if (.not. is_there(iplvl, 'RH') .and.
679 & is_there(iplvl, 'SH') .and.
680 & is_there(iplvl, 'TT') .and.
681 & is_there(iplvl, 'P')) then
682 call g2_compute_rh_spechumd_upa(map%nx,map%ny,iplvl)
683 !call llstor_remove(iplvl, 'SH') !We are done with SH
689 endif ! Selected param.
694 ! Deallocate arrays decoding GRIB2 record.
703 if ( debug_level .gt. 100 ) then
704 call mprintf (.true.,DEBUG,
705 & "G2 total number of fields found = %i ",newline=.true.,i1=itot)
708 CALL BACLOSE(junit,IOS)
710 nullify(gfld%local) ! must be nullified before opening next file
713 call mprintf (.true.,DEBUG,"open status failed because %i ",
714 & newline=.true., i1=ios)
715 hdate = '9999-99-99_99:99:99'
717 endif ! ireaderr check
719 END subroutine rd_grib2
721 !*****************************************************************************!
722 ! Subroutine edition_num !
725 ! Read one record from the input GRIB2 file. Based on the information in !
726 ! the GRIB2 header and the user-defined Vtable, decide whether the field in!
727 ! the GRIB2 record is one to process or to skip. If the field is one we !
728 ! want to keep, extract the data from the GRIB2 record, and pass the data !
729 ! back to the calling routine. !
733 ! JUNIT : "Unit Number" to open and read from. Not really a Fortran !
734 ! unit number, since we do not do Fortran I/O for the GRIB2 !
735 ! files. Nor is it a UNIX File Descriptor returned from a C !
736 ! OPEN statement. It is really just an array index to the !
737 ! array (IUARR) where the UNIX File Descriptor values are !
739 ! GRIB2FILE: File name to open, if it is not already open. !
742 ! GRIB_EDITION: Set to 1 for GRIB and set to 2 for GRIB2 !
743 ! IERR : Error flag: 0 - no error on read from GRIB2 file. !
744 ! 1 - Hit the end of the GRIB2 file. !
745 ! 2 - The file GRIBFLNM we tried to open does !
747 ! Author: Paula McCaslin !
750 !*****************************************************************************!
752 SUBROUTINE edition_num(junit, gribflnm,
753 & grib_edition, ireaderr)
759 parameter(msk1=32000,msk2=4000)
760 character(len=1),allocatable,dimension(:) :: cgrib
761 integer :: listsec0(3)
762 integer :: listsec1(13)
763 character(len=*) :: gribflnm
764 integer :: lskip, lgrib
766 integer :: grib_edition
767 integer :: i, j, ireaderr
770 character(len=4) :: ctemp
771 character(len=4),parameter :: grib='GRIB',c7777='7777'
773 C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
783 !/* IOS Return Codes from BACIO: */
784 !/* 0 All was well */
785 !/* -1 Tried to open read only _and_ write only */
786 !/* -2 Tried to read and write in the same call */
787 !/* -3 Internal failure in name processing */
788 !/* -4 Failure in opening file */
789 !/* -5 Tried to read on a write-only file */
790 !/* -6 Failed in read to find the 'start' location */
791 !/* -7 Tried to write to a read only file */
792 !/* -8 Failed in write to find the 'start' location */
793 !/* -9 Error in close */
794 !/* -10 Read or wrote fewer data than requested */
796 !if ireaderr =1 we have hit the end of a file.
797 !if ireaderr =2 we have hit the end of all the files.
798 !if ireaderr =3 beginning characters 'GRIB' not found
800 ! Open a byte-addressable file.
801 CALL BAOPENR(junit,gribflnm,IOS)
804 ! Search opend file for the next GRIB2 messege (record).
805 call skgb(junit,iseek,msk1,lskip,lgrib)
807 ! Check for EOF, or problem
808 call mprintf((lgrib.eq.0),ERROR,
809 & "Grib2 file or date problem, stopping in edition_num.",
812 ! Check size, if needed allocate more memory.
813 if (lgrib.gt.currlen) then
814 if (allocated(cgrib)) deallocate(cgrib)
815 allocate(cgrib(lgrib),stat=is)
819 ! Read a given number of bytes from unblocked file.
820 call baread(junit,lskip,lgrib,lengrib,cgrib)
822 ! Check for beginning of GRIB message in the first 100 bytes
825 ctemp=cgrib(j)//cgrib(j+1)//cgrib(j+2)//cgrib(j+3)
826 if (ctemp.eq.grib ) then
831 if (istart.eq.0) then
833 print*, "The beginning 4 characters >GRIB< were not found."
836 ! Unpack Section 0 - Indicator Section to extract GRIB edition field
838 call gbyte(cgrib,discipline,iofst,8) ! Discipline
840 call gbyte(cgrib,grib_edition,iofst,8) ! GRIB edition number
842 print *, 'ungrib - grib edition num', grib_edition
843 CALL BACLOSE(junit,IOS)
845 else if (ios .eq. -4) then
846 call mprintf(.true.,ERROR,
847 & "edition_num: unable to open %s",newline=.true.,s1=gribflnm)
849 print *,'edition_num: open status failed because',ios,gribflnm
851 endif ! ireaderr check
853 END subroutine edition_num
855 !*****************************************************************************!
857 SUBROUTINE g2_compute_rh_spechumd_upa(ix, jx, iiplvl)
858 ! Compute relative humidity from specific humidity in the upper air.
863 real :: lat1, lon1, dx, dy
864 real, dimension(ix,jx) :: T, P, RH, Q
866 real, parameter :: svp1=611.2
867 real, parameter :: svp2=17.67
868 real, parameter :: svp3=29.65
869 real, parameter :: svpt0=273.15
870 real, parameter :: eps = 0.622
872 real startlat, startlon, deltalat, deltalon
874 call get_storage(iiplvl, 'P', P, ix, jx)
875 call get_storage(iiplvl, 'TT', T, ix, jx)
876 call get_storage(iiplvl, 'SH', Q, ix, jx)
878 rh=1.E2*(p*q/(q*(1.-eps)+eps))/(svp1*exp(svp2*(t-svpt0)/(T-svp3)))
880 call put_storage(iiplvl, 'RH', rh, ix, jx)
882 end subroutine g2_compute_rh_spechumd_upa
884 !*****************************************************************************!
886 subroutine ncep_grid_num (pnum)
888 ! Grib2 doesn't have a grid-number entry, so we have to figure it out
890 use gridinfo ! Included to define map%
892 real, parameter :: eps = .01
893 character (len=8) :: tmp8
895 ! write(6,*) 'begin ncep_grid_num'
896 ! write(6,*) 'dx = ',map%dx,' pnum = ',pnum,' nx = ',map%nx
898 if (pnum .eq. 30) then
899 if ( abs(map%dx - 12.19058) .lt. eps .and. map%nx .eq. 614) then
900 write(tmp8,'("GRID 218")')
901 else if (abs(map%dx - 40.63525) .lt. eps
902 & .and. map%nx .eq. 185) then
903 write(tmp8,'("GRID 212")')
904 else if (abs(map%dx - 40.63525) .lt. eps
905 & .and. map%nx .eq. 151) then
906 write(tmp8,'("GRID 236")')
907 else if (abs(map%dx - 81.2705) .lt. eps
908 & .and. map%nx .eq. 93) then
909 write(tmp8,'("GRID 211")')
910 else if (abs (map%dx - 32.46341) .lt. eps
911 & .and. map%nx .eq. 349) then
912 write(tmp8,'("GRID 221")')
913 else if (abs(map%dx - 20.317625) .lt. eps
914 & .and. map%nx .eq. 301) then
915 write(tmp8,'("GRID 252")')
917 else if (pnum .eq. 20) then
918 if (abs(map%dx - 15.0) .lt. eps) then
919 write(tmp8,'("GRID 88")')
921 else if (pnum .eq. 0) then
922 if (abs(map%dx - 1.) .lt. eps .and. map%nx .eq. 360) then
923 write(tmp8,'("GRID 3")')
924 else if (abs(map%dx - 0.5) .lt. eps .and. map%nx .eq. 720) then
925 write(tmp8,'("GRID 4")')
928 map%source(25:32) = tmp8
929 ! write(6,*) 'map%source = ',map%source
930 end subroutine ncep_grid_num
931 !*****************************************************************************!
933 function earth_radius (icode, iscale, irad_m)
934 ! Grib2 Code Table 3.2. Returns the spherical earth's radius in km.
938 integer :: iscale, irad_m
939 if ( icode .eq. 0 ) then
940 earth_radius = 6367470. * .001
941 else if ( icode .eq. 1) then
942 earth_radius = 0.001 * float(irad_m) / 10**iscale
943 else if ( icode .eq. 6 ) then
944 earth_radius = 6371229. * .001
945 else if ( icode .eq. 8 ) then
946 earth_radius = 6371200. * .001
948 call mprintf(.true.,ERROR,
949 & "unknown earth radius for code %i",newline=.true.,i1=icode)
951 end function earth_radius