!----------------------------------------------------------------------- subroutine gribit(gribi,lbm,idrt,im,jm,mxbit,colat1, & ilpds,iptv,icen,igen,ibms,ipu,itl,il1,il2, & iyr,imo,idy,ihr,iftu,ip1,ip2,itr, & ina,inm,icen2,ids,iens, & xlat1,xlon1,delx,dely,orient,proj, & grib,lgrib,ierr) !$$$ subprogram documentation block ! ! subprogram: gribit create grib message ! prgmmr: iredell org: w/nmc23 date: 92-10-31 ! ! abstract: create a grib message from a full field. ! at present, only global latlon grids and gaussian grids ! and regional polar projections are allowed. ! ! program history log: ! 92-10-31 iredell ! 94-05-04 juang (for gsm and rsm use) ! 97-09-17 iredell made y2k compliant ! ! usage: call gribit(f,lbm,idrt,im,jm,mxbit,colat1, ! & ilpds,iptv,icen,igen,ibms,ipu,itl,il1,il2, ! & iyr,imo,idy,ihr,iftu,ip1,ip2,itr, ! & ina,inm,icen2,ids,iens, ! & xlat1,xlon1,delx,dely,orient,proj, ! & grib,lgrib,ierr) ! input argument list: ! f - real (im*jm) field data to pack into grib message ! lbm - logical (im*jm) bitmap to use if ibms=1 ! idrt - integer data representation type ! (0 for latlon or 4 for gaussian or 5 for polar) ! im - integer longitudinal dimension ! jm - integer latitudinal dimension ! mxbit - integer maximum number of bits to use (0 for no limit) ! colat1 - real first colatitude of grid if idrt=4 (radians) ! ilpds - integer length of the pds (usually 28) ! iptv - integer parameter table version (usually 1) ! icen - integer forecast center (usually 7) ! igen - integer model generating code ! ibms - integer bitmap flag (0 for no bitmap) ! ipu - integer parameter and unit indicator ! itl - integer type of level indicator ! il1 - integer first level value (0 for single level) ! il2 - integer second level value ! iyr - integer 4-digit year ! imo - integer month ! idy - integer day ! ihr - integer hour ! iftu - integer forecast time unit (1 for hour) ! ip1 - integer first time period ! ip2 - integer second time period (0 for single period) ! itr - integer time range indicator (10 for single period) ! ina - integer number included in average ! inm - integer number missing from average ! icen2 - integer forecast subcenter ! (usually 0 but 1 for reanal or 2 for ensemble) ! ids - integer decimal scaling ! iens - integer (5) ensemble extended pds values ! (application,type,identification,product,smoothing) ! (used only if icen2=2 and ilpds>=45) ! xlat1 - real first point of regional latitude (radians) ! xlon1 - real first point of regional longitude (radians) ! delx - real dx on 60n for regional (m) ! dely - real dy on 60n for regional (m) ! proj - real polar projection flag 0 for north 1 for south ! orient - real orientation of regional domain ! ! output argument list: ! grib - character (lgrib) grib message ! lgrib - integer length of grib message ! (no more than 100+ilpds+im*jm*(mxbit+1)/8) ! ierr - integer error code (0 for success) ! ! subprograms called: ! getbit - compute number of bits and round data appropriately ! w3fi68 - make general pds ! pdsens - make ensemble pds ! w3fi72 - engrib data into a grib1 message ! ! attributes: ! language: cray fortran ! !$$$ use machine use namelist_def, only : climate implicit none !! integer itr,ip2,inm,ina,ihr,idy,ip1,iftu,ids,icen2,ilpds,icen, & iptv,im,idrt,mxbit,jm,il2,il1,imo,iyr,ibms,igen,itl,ipu, & icy,iyc,nbit,nbm,jp2,jp1,ipx,jtr,kclust,nfo,kmembr, & kprob,ilast,iresfl,igrid,iscan,i,ierr,nf,igds11,igds09, & igds10,loni,lon1,lati,igds12,jftu,lat1,lgrib real (kind=kind_io8) pi,xprob,fmax,fmin real (kind=kind_io8) proj,xlon1,xlat1,colat1, & orient,dely,delx integer iens(5) real (kind=kind_io4) gribi(im*jm) ! real (kind=kind_io8) f(im*jm) logical(1) lbm(im*jm) character grib(*) integer ibm(im*jm*ibms+1-ibms),ipds(100),igds(100),ibds(100) real (kind=kind_io8) fr(im*jm) character pds(ilpds) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! determine grid parameters ! do i=1,im*jm ! f(i)=gribi(i) ! enddo !sela write(0,*) 'gribit top' pi=acos(-1.) nf=im*jm if(idrt.eq.0) then if(im.eq.144.and.jm.eq.73) then igrid=2 elseif(im.eq.360.and.jm.eq.181) then igrid=3 else igrid=255 endif iresfl=128 iscan=0 lat1=nint(90.e3) lon1=0 lati=nint(180.e3/(jm-1)) loni=nint(360.e3/im) igds09=-lat1 igds10=-loni igds11=lati igds12=loni elseif(idrt.eq.4) then if(im.eq.192.and.jm.eq.94) then igrid=98 elseif(im.eq.384.and.jm.eq.190) then igrid=126 else igrid=255 endif iresfl=128 iscan=0 lat1=nint(90.e3-180.e3/pi*colat1) lon1=0 lati=jm/2 loni=nint(360.e3/im) igds09=-lat1 igds10=-loni igds11=lati igds12=loni elseif(idrt.eq.5) then ! polar projection igrid=255 iresfl=0 iscan=2 lat1=180.e3/pi*xlat1 lon1=180.e3/pi*xlon1 igds09=orient*1.e3 igds10=delx igds11=dely igds12=proj else ierr=40 return endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! reset forecast hour units in case of overflow jftu=iftu jp1=ip1 jp2=ip2 jtr=itr ipx=max(ip1,ip2) if (climate) then jp1 = ipx jp2 = 0 jtr = 10 else !cc if(itr.ge.2.and.itr.le.5.and.ipx.ge.256) then !cc jp1=ip2 !cc jp2=0 !cc jtr=10 !cc endif if(iftu.eq.1) then if((itr.ge.2.and.itr.le.5.and.ipx.ge.256).or.ipx.ge.65536) & then if(mod(ip1,24)+mod(ip2,24).eq.0.and.ipx.lt.24*256) then jftu=2 jp1=ip1/24 jp2=ip2/24 elseif(mod(ip1,12)+mod(ip2,12).eq.0.and.ipx.lt.12*256) & then jftu=12 jp1=ip1/12 jp2=ip2/12 elseif(mod(ip1,6)+mod(ip2,6).eq.0.and.ipx.lt.6*256) then jftu=11 jp1=ip1/6 jp2=ip2/6 elseif(mod(ip1,3)+mod(ip2,3).eq.0.and.ipx.lt.3*256) then jftu=10 jp1=ip1/3 jp2=ip2/3 else jp1=ipx jp2=0 jtr=10 endif endif endif endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! fix year and century iyc=mod(iyr-1,100)+1 icy=(iyr-1)/100+1 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! fill pds parameters ipds(01)=ilpds ! length of pds ipds(02)=iptv ! parameter table version id ipds(03)=icen ! center id ipds(04)=igen ! generating model id ipds(05)=igrid ! grid id ipds(06)=1 ! gds flag ipds(07)=ibms ! bms flag ipds(08)=ipu ! parameter unit id ipds(09)=itl ! type of level id ipds(10)=il1 ! level 1 or 0 ipds(11)=il2 ! level 2 ipds(12)=iyc ! year ipds(13)=imo ! month ipds(14)=idy ! day ipds(15)=ihr ! hour ipds(16)=0 ! minute ipds(17)=jftu ! forecast time unit id ipds(18)=jp1 ! time period 1 ipds(19)=jp2 ! time period 2 or 0 ipds(20)=jtr ! time range indicator ipds(21)=ina ! number in average ipds(22)=inm ! number missing ipds(23)=icy ! century ipds(24)=icen2 ! forecast subcenter ipds(25)=ids ! decimal scaling ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! fill gds and bds parameters igds(01)=0 ! number of vertical coords igds(02)=255 ! vertical coord flag igds(03)=idrt ! data representation type igds(04)=im ! east-west points igds(05)=jm ! north-south points igds(06)=lat1 ! latitude of origin igds(07)=lon1 ! longitude of origin igds(08)=iresfl ! resolution flag igds(09)=igds09 ! latitude of end or orientation igds(10)=igds10 ! longitude of end or dx in meter on 60n igds(11)=igds11 ! lat increment or gaussian lats or dy in meter igds(12)=igds12 ! longitude increment or projection igds(13)=iscan ! scanning mode flags igds(14:18)=0 ! not used ibds(1:9)=0 ! bds flags ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! fill bitmap and count valid data. reset bitmap flag if all valid. nbm=nf if(ibms.ne.0) then nbm=0 do i=1,nf if(lbm(i)) then ibm(i)=1 nbm=nbm+1 else ibm(i)=0 endif enddo if(nbm.eq.nf) ipds(7)=0 endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! round data and determine number of bits !sela write(0,*) 'gribit getbit' if(nbm.eq.0) then do i=1,nf fr(i)=0. enddo nbit=0 else call getbitl(ipds(7),0,ids,nf,ibm,gribi,fr,fmin,fmax,nbit) ! write(0,'("getbit:",4i4,4x,2i4,4x,2g16.6)') ! & ipu,itl,il1,il2,ids,nbit,fmin,fmax !sela write(66,'(g20.10)') fmin if(mxbit.gt.0) nbit=min(nbit,mxbit) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! create product definition section !sela write(0,*) 'gribit w3fi68' call w3fi68(ipds,pds) if(icen2.eq.2.and.ilpds.ge.45) then ilast=45 call pdsens(iens,kprob,xprob,kclust,kmembr,ilast,pds) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! create grib message !sela write(0,*) 'gribit w3fi72' call w3fi72(0,fr,0,nbit,1,ipds,pds, & 1,255,igds,0,0,ibm,nf,ibds, & nfo,grib,lgrib,ierr) !sela write(0,*) 'gribit end' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return end subroutine getbitl(ibm,ibs,ids,len,mg,g,ground,gmin,gmax,nbit) !$$$ subprogram documentation block ! ! subprogram: getbit compute number of bits and round field. ! prgmmr: iredell org: w/nmc23 date: 92-10-31 ! ! abstract: the number of bits required to pack a given field ! for particular binary and decimal scalings is computed. ! the field is rounded off to the decimal scaling for packing. ! the minimum and maximum rounded field values are also returned. ! grib bitmap masking for valid data is optionally used. ! ! program history log: ! 96-09-16 iredell ! ! usage: call gtbits(ibm,ibs,ids,len,mg,g,gmin,gmax,nbit) ! input argument list: ! ibm - integer bitmap flag (=0 for no bitmap) ! ibs - integer binary scaling ! (e.g. ibs=3 to round field to nearest eighth value) ! ids - integer decimal scaling ! (e.g. ids=3 to round field to nearest milli-value) ! (note that ids and ibs can both be nonzero, ! e.g. ids=1 and ibs=1 rounds to the nearest twentieth) ! len - integer length of the field and bitmap ! mg - integer (len) bitmap if ibm=1 (0 to skip, 1 to keep) ! g - real (len) field ! ! output argument list: ! ground - real (len) field rounded to decimal and binary scaling ! (set to zero where bitmap is 0 if ibm=1) ! gmin - real minimum valid rounded field value ! gmax - real maximum valid rounded field value ! nbit - integer number of bits to pack ! ! attributes: ! language: cray fortran ! !$$$ use machine, only : kind_io4 ! implicit none integer len,ibm,ibs,ids,nbit integer, dimension(len) :: mg real gmax,gmin real (kind=kind_io4), dimension(len) :: g real, dimension(len) :: ground ! real s,si integer i,i1 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! round field and determine extremes where bitmap is on s = 2.**ibs*10.**ids si = 1.0 / s if(ibm == 0) then ground(1) = nint(g(1)*s)*si gmax = ground(1) gmin = ground(1) do i=2,len ground(i) = nint(g(i)*s)*si gmax = max(gmax,ground(i)) gmin = min(gmin,ground(i)) enddo else i1=1 dowhile(i1 <= len .and. mg(i1) == 0) i1 = i1+1 enddo if(i1 <= len) then do i=1,i1-1 ground(i) = 0. enddo ground(i1) = nint(g(i1)*s)*si gmax = ground(i1) gmin = ground(i1) do i=i1+1,len if(mg(i) /= 0) then ground(i) = nint(g(i)*s)*si gmax = max(gmax,ground(i)) gmin = min(gmin,ground(i)) else ground(i) = 0. endif enddo else do i=1,len ground(i) = 0. enddo gmax = 0. gmin = 0. endif endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! compute number of bits nbit = log((gmax-gmin)*s+0.9)/log(2.)+1. ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return end