⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compack.f

📁 计算线性趋势 回归系数 主要用于气象站点值的线性趋势计算
💻 F
字号:
      subroutine compack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)!$$$  SUBPROGRAM DOCUMENTATION BLOCK!                .      .    .                                       .! SUBPROGRAM:    compack!   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2000-06-21!! ABSTRACT: This subroutine packs up a data field using a complex!   packing algorithm as defined in the GRIB2 documention.  It!   supports GRIB2 complex packing templates with or without!   spatial differences (i.e. DRTs 5.2 and 5.3).!   It also fills in GRIB2 Data Representation Template 5.2 or 5.3 !   with the appropriate values.!! PROGRAM HISTORY LOG:! 2000-06-21  Gilbert!! USAGE:    CALL compack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack)!   INPUT ARGUMENT LIST:!     fld()    - Contains the data values to pack!     ndpts    - The number of data values in array fld()!     idrsnum  - Data Representation Template number 5.N!                Must equal 2 or 3.!     idrstmpl - Contains the array of values for Data Representation!                Template 5.2 or 5.3!                (1) = Reference value - ignored on input!                (2) = Binary Scale Factor!                (3) = Decimal Scale Factor!                    .!                    .!                (7) = Missing value management!                (8) = Primary missing value!                (9) = Secondary missing value!                    .!                    .!               (17) = Order of Spatial Differencing  ( 1 or 2 )!                    .!                    .!!   OUTPUT ARGUMENT LIST: !     idrstmpl - Contains the array of values for Data Representation!                Template 5.3!                (1) = Reference value - set by compack routine.!                (2) = Binary Scale Factor - unchanged from input!                (3) = Decimal Scale Factor - unchanged from input!                    .!                    .!     cpack    - The packed data field (character*1 array)!     lcpack   - length of packed field cpack().!! REMARKS: None!! ATTRIBUTES:!   LANGUAGE: XL Fortran 90!   MACHINE:  IBM SP!!$$$      integer,intent(in) :: ndpts,idrsnum      real,intent(in) :: fld(ndpts)      character(len=1),intent(out) :: cpack(*)      integer,intent(inout) :: idrstmpl(*)      integer,intent(out) :: lcpack      real(4) :: ref      integer(4) :: iref      integer,allocatable :: ifld(:)      integer,allocatable :: jmin(:),jmax(:),lbit(:)      integer,parameter :: zero=0      integer,allocatable :: gref(:),gwidth(:),glen(:)      integer :: glength,grpwidth      logical :: simple_alg = .false.            alog2=alog(2.0)      bscale=2.0**real(-idrstmpl(2))      dscale=10.0**real(idrstmpl(3))!!  Find max and min values in the data!      rmax=fld(1)      rmin=fld(1)      do j=2,ndpts        if (fld(j).gt.rmax) rmax=fld(j)        if (fld(j).lt.rmin) rmin=fld(j)      enddo!!  If max and min values are not equal, pack up field.!  If they are equal, we have a constant field, and the reference!  value (rmin) is the value for each point in the field and!  set nbits to 0.!      if (rmin.ne.rmax) then        iofst=0        allocate(ifld(ndpts))        allocate(gref(ndpts))        allocate(gwidth(ndpts))        allocate(glen(ndpts))        !        !  Scale original data        !        if (idrstmpl(2).eq.0) then        !  No binary scaling           imin=nint(rmin*dscale)           !imax=nint(rmax*dscale)           rmin=real(imin)           do j=1,ndpts             ifld(j)=nint(fld(j)*dscale)-imin           enddo        else                              !  Use binary scaling factor           rmin=rmin*dscale           !rmax=rmax*dscale           do j=1,ndpts             ifld(j)=nint(((fld(j)*dscale)-rmin)*bscale)           enddo        endif        !        !  Calculate Spatial differences, if using DRS Template 5.3        !        if (idrsnum.eq.3) then        ! spatial differences           if (idrstmpl(17).ne.1.and.idrstmpl(17).ne.2) idrstmpl(17)=2           if (idrstmpl(17).eq.1) then      ! first order              ival1=ifld(1)              do j=ndpts,2,-1                 ifld(j)=ifld(j)-ifld(j-1)              enddo              ifld(1)=0           elseif (idrstmpl(17).eq.2) then      ! second order              ival1=ifld(1)              ival2=ifld(2)              do j=ndpts,3,-1                 ifld(j)=ifld(j)-(2*ifld(j-1))+ifld(j-2)              enddo              ifld(1)=0              ifld(2)=0           endif           !           !  subtract min value from spatial diff field           !           isd=idrstmpl(17)+1           minsd=minval(ifld(isd:ndpts))           do j=isd,ndpts              ifld(j)=ifld(j)-minsd           enddo           !           !   find num of bits need to store minsd and add 1 extra bit           !   to indicate sign           !           temp=alog(real(abs(minsd)+1))/alog2           nbitsd=ceiling(temp)+1           !           !   find num of bits need to store ifld(1) ( and ifld(2)           !   if using 2nd order differencing )           !           maxorig=ival1           if (idrstmpl(17).eq.2.and.ival2.gt.ival1) maxorig=ival2           temp=alog(real(maxorig+1))/alog2           nbitorig=ceiling(temp)+1           if (nbitorig.gt.nbitsd) nbitsd=nbitorig           !   increase number of bits to even multiple of 8 ( octet )           if (mod(nbitsd,8).ne.0) nbitsd=nbitsd+(8-mod(nbitsd,8))           !           !  Store extra spatial differencing info into the packed           !  data section.           !           if (nbitsd.ne.0) then              !   pack first original value              if (ival1.ge.0) then                 call sbyte(cpack,ival1,iofst,nbitsd)                 iofst=iofst+nbitsd              else                 call sbyte(cpack,1,iofst,1)                 iofst=iofst+1                 call sbyte(cpack,iabs(ival1),iofst,nbitsd-1)                 iofst=iofst+nbitsd-1              endif              if (idrstmpl(17).eq.2) then               !  pack second original value                 if (ival2.ge.0) then                    call sbyte(cpack,ival2,iofst,nbitsd)                    iofst=iofst+nbitsd                 else                    call sbyte(cpack,1,iofst,1)                    iofst=iofst+1                    call sbyte(cpack,iabs(ival2),iofst,nbitsd-1)                    iofst=iofst+nbitsd-1                 endif              endif              !  pack overall min of spatial differences              if (minsd.ge.0) then                 call sbyte(cpack,minsd,iofst,nbitsd)                 iofst=iofst+nbitsd              else                 call sbyte(cpack,1,iofst,1)                 iofst=iofst+1                 call sbyte(cpack,iabs(minsd),iofst,nbitsd-1)                 iofst=iofst+nbitsd-1              endif           endif         !print *,'SDp ',ival1,ival2,minsd,nbitsd        endif     !  end of spatial diff section        !        !   Determine Groups to be used.        !        if ( simple_alg ) then           !  set group length to 10 :  calculate number of groups           !  and length of last group           ngroups=ndpts/10           glen(1:ngroups)=10           itemp=mod(ndpts,10)           if (itemp.ne.0) then              ngroups=ngroups+1              glen(ngroups)=itemp           endif        else           ! Use Dr. Glahn's algorithm for determining grouping.           !           kfildo=6           minpk=10           inc=1           maxgrps=(ndpts/minpk)+1           allocate(jmin(maxgrps))           allocate(jmax(maxgrps))           allocate(lbit(maxgrps))           missopt=0           call pack_gp(kfildo,ifld,ndpts,missopt,minpk,inc,miss1,miss2,     &                  jmin,jmax,lbit,glen,maxgrps,ngroups,ibit,jbit,     &                  kbit,novref,lbitref,ier)           !print *,'SAGier = ',ier,ibit,jbit,kbit,novref,lbitref           do ng=1,ngroups              glen(ng)=glen(ng)+novref           enddo           deallocate(jmin)           deallocate(jmax)           deallocate(lbit)        endif        !          !  For each group, find the group's reference value        !  and the number of bits needed to hold the remaining values        !        n=1        do ng=1,ngroups           !    find max and min values of group           gref(ng)=ifld(n)           imax=ifld(n)           j=n+1           do lg=2,glen(ng)              if (ifld(j).lt.gref(ng)) gref(ng)=ifld(j)               if (ifld(j).gt.imax) imax=ifld(j)               j=j+1           enddo           !   calc num of bits needed to hold data           if ( gref(ng).ne.imax ) then              temp=alog(real(imax-gref(ng)+1))/alog2              gwidth(ng)=ceiling(temp)           else              gwidth(ng)=0           endif           !   Subtract min from data           j=n           do lg=1,glen(ng)              ifld(j)=ifld(j)-gref(ng)              j=j+1           enddo           !   increment fld array counter           n=n+glen(ng)        enddo        !          !  Find max of the group references and calc num of bits needed         !  to pack each groups reference value, then        !  pack up group reference values        !        !write(77,*)'GREFS: ',(gref(j),j=1,ngroups)        igmax=maxval(gref(1:ngroups))        if (igmax.ne.0) then           temp=alog(real(igmax+1))/alog2           nbitsgref=ceiling(temp)           call sbytes(cpack,gref,iofst,nbitsgref,0,ngroups)           itemp=nbitsgref*ngroups           iofst=iofst+itemp           !         Pad last octet with Zeros, if necessary,           if (mod(itemp,8).ne.0) then              left=8-mod(itemp,8)              call sbyte(cpack,zero,iofst,left)              iofst=iofst+left           endif        else           nbitsgref=0        endif        !        !  Find max/min of the group widths and calc num of bits needed        !  to pack each groups width value, then        !  pack up group width values        !        !write(77,*)'GWIDTHS: ',(gwidth(j),j=1,ngroups)        iwmax=maxval(gwidth(1:ngroups))        ngwidthref=minval(gwidth(1:ngroups))        if (iwmax.ne.ngwidthref) then           temp=alog(real(iwmax-ngwidthref+1))/alog2           nbitsgwidth=ceiling(temp)           do i=1,ngroups              gwidth(i)=gwidth(i)-ngwidthref           enddo           call sbytes(cpack,gwidth,iofst,nbitsgwidth,0,ngroups)           itemp=nbitsgwidth*ngroups           iofst=iofst+itemp           !         Pad last octet with Zeros, if necessary,           if (mod(itemp,8).ne.0) then              left=8-mod(itemp,8)              call sbyte(cpack,zero,iofst,left)              iofst=iofst+left           endif        else           nbitsgwidth=0           gwidth(1:ngroups)=0        endif        !        !  Find max/min of the group lengths and calc num of bits needed        !  to pack each groups length value, then        !  pack up group length values        !        !write(77,*)'GLENS: ',(glen(j),j=1,ngroups)        ilmax=maxval(glen(1:ngroups-1))        nglenref=minval(glen(1:ngroups-1))        nglenlast=glen(ngroups)        if (ilmax.ne.nglenref) then           temp=alog(real(ilmax-nglenref+1))/alog2           nbitsglen=ceiling(temp)           do i=1,ngroups-1              glen(i)=glen(i)-nglenref           enddo           call sbytes(cpack,glen,iofst,nbitsglen,0,ngroups)           itemp=nbitsglen*ngroups           iofst=iofst+itemp           !         Pad last octet with Zeros, if necessary,           if (mod(itemp,8).ne.0) then              left=8-mod(itemp,8)              call sbyte(cpack,zero,iofst,left)              iofst=iofst+left           endif        else           nbitsglen=0           glen(1:ngroups)=0        endif        !        !  For each group, pack data values        !        !write(77,*)'IFLDS: ',(ifld(j),j=1,ndpts)        n=1        ij=0        do ng=1,ngroups           glength=glen(ng)+nglenref           if (ng.eq.ngroups ) glength=nglenlast           grpwidth=gwidth(ng)+ngwidthref       !write(77,*)'NGP ',ng,grpwidth,glength,gref(ng)           if ( grpwidth.ne.0 ) then              call sbytes(cpack,ifld(n),iofst,grpwidth,0,glength)              iofst=iofst+(grpwidth*glength)           endif           do kk=1,glength              ij=ij+1       !write(77,*)'SAG ',ij,fld(ij),ifld(ij),gref(ng),bscale,rmin,dscale           enddo           n=n+glength        enddo        !         Pad last octet with Zeros, if necessary,        if (mod(iofst,8).ne.0) then           left=8-mod(iofst,8)           call sbyte(cpack,zero,iofst,left)           iofst=iofst+left        endif        lcpack=iofst/8        !        if ( allocated(ifld) ) deallocate(ifld)        if ( allocated(gref) ) deallocate(gref)        if ( allocated(gwidth) ) deallocate(gwidth)        if ( allocated(glen) ) deallocate(glen)      else           !   Constant field ( max = min )        nbits=0        lcpack=0        nbitsgref=0        ngroups=0      endif!!  Fill in ref value and number of bits in Template 5.2!      call mkieee(rmin,ref,1)   ! ensure reference value is IEEE format!      call gbyte(ref,idrstmpl(1),0,32)      iref=transfer(ref,iref)      idrstmpl(1)=iref      idrstmpl(4)=nbitsgref      idrstmpl(5)=0         ! original data were reals      idrstmpl(6)=1         ! general group splitting      idrstmpl(7)=0         ! No internal missing values      idrstmpl(8)=0         ! Primary missing value      idrstmpl(9)=0         ! secondary missing value      idrstmpl(10)=ngroups          ! Number of groups      idrstmpl(11)=ngwidthref       ! reference for group widths      idrstmpl(12)=nbitsgwidth      ! num bits used for group widths      idrstmpl(13)=nglenref         ! Reference for group lengths      idrstmpl(14)=1                ! length increment for group lengths      idrstmpl(15)=nglenlast        ! True length of last group      idrstmpl(16)=nbitsglen        ! num bits used for group lengths      if (idrsnum.eq.3) then         idrstmpl(18)=nbitsd/8      ! num bits used for extra spatial                                    ! differencing values      endif      return      end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -