subroutine makepds(idisc,idsect,ipdsnum,ipdstmpl,ibmap,
     &                     idrsnum,idrstmpl,kpds,iret)
C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    makepds
C   PRGMMR: Gilbert        ORG: W/NP11     DATE: 2003-06-12
C
C ABSTRACT: This routine creates a GRIB1 PDS (Section 1)
C   from appropriate information from a GRIB2 Product Definition Template.
C
C PROGRAM HISTORY LOG:
C 2003-06-12  Gilbert
C 2005-04-19  Gilbert    - Changed scaling factor used with potential
C                          vorticity surfaces.
C 2007-05-08  VUONG      - Add Product Definition Template entries
C                          120 - Ice Concentration Analysis
C                          121 - Western North Atlantic Regional Wave Model
C                          122 - Alaska Waters Regional Wave Model
C                          123 - North Atlantic Hurricane Wave Model
C                          124 - Eastern North Pacific Regional Wave Model
C                          131 - Great Lake Wave Model
C                           88 - NOAA Wave Watch III (NWW3)
C                           45 - Coastal Ocean Circulation
C                           47 - HYCOM - North Pacific basin
C 2007-05-14  Boi Vuong  - Added Time Range Indicator 51 (Climatological
C                          Mean Value)
C 2007-10-24  Boi Vuong  - Added level 8 (Nominal top of atmosphere)
C 2009-05-19  Boi Vuong  - Added levels 10(Entire Atmosphere), 11(Cumulonimbus
C                          Base),12(Cumulonimbus Top) and level 126(Isobaric Pa)
C 2009-12-14  Boi Vuong  - Added check for WAFS to use PDT 4.15 for Icing,
C                          Turbulence and Cumulonimbus
C 2010-08-10  Boi Vuong  - Added check for FNMOC to use TMP as TMAX and TMIN
C                        - Renoved check WAFS MAX wind level
C
C USAGE:    CALL makepds(idisc,idsect,ipdsnum,ipdstmpl,ibmap,
C                        idrsnum,idrstmpl,kpds,iret)
C   INPUT ARGUMENT LIST:
C     idisc      - GRIB2 discipline from Section 0.
C     idsect()   - GRIB2 Section 1 info.
C                idsect(1)=Id of orginating centre (Common Code Table C-1)
C                idsect(2)=Id of orginating sub-centre (local table)
C                idsect(3)=GRIB Master Tables Version Number (Code Table 1.0)
C                idsect(4)=GRIB Local Tables Version Number (Code Table 1.1)
C                idsect(5)=Significance of Reference Time (Code Table 1.2)
C                idsect(6)=Reference Time - Year (4 digits)
C                idsect(7)=Reference Time - Month
C                idsect(8)=Reference Time - Day
C                idsect(9)=Reference Time - Hour
C                idsect(10)=Reference Time - Minute
C                idsect(11)=Reference Time - Second
C                idsect(12)=Production status of data (Code Table 1.3)
C                idsect(13)=Type of processed data (Code Table 1.4)
C     ipdsnum    - GRIB2 Product Definition Template Number
C     ipdstmpl() - GRIB2 Product Definition Template entries for PDT 4.ipdsnum
C     ibmap      - GRIB2 bitmap indicator from octet 6, Section 6.
C     idrsnum    - GRIB2 Data Representation Template Number
C     idrstmpl() - GRIB2 Data Representation Template entries
C
C   OUTPUT ARGUMENT LIST:
C     kpds()     - GRIB1 PDS info as specified in W3FI63.
C          (1)   - ID OF CENTER
C          (2)   - GENERATING PROCESS ID NUMBER
C          (3)   - GRID DEFINITION
C          (4)   - GDS/BMS FLAG (RIGHT ADJ COPY OF OCTET 8)
C          (5)   - INDICATOR OF PARAMETER
C          (6)   - TYPE OF LEVEL
C          (7)   - HEIGHT/PRESSURE , ETC OF LEVEL
C          (8)   - YEAR INCLUDING (CENTURY-1)
C          (9)   - MONTH OF YEAR
C          (10)  - DAY OF MONTH
C          (11)  - HOUR OF DAY
C          (12)  - MINUTE OF HOUR
C          (13)  - INDICATOR OF FORECAST TIME UNIT
C          (14)  - TIME RANGE 1
C          (15)  - TIME RANGE 2
C          (16)  - TIME RANGE FLAG
C          (17)  - NUMBER INCLUDED IN AVERAGE
C          (18)  - VERSION NR OF GRIB SPECIFICATION
C          (19)  - VERSION NR OF PARAMETER TABLE
C          (20)  - NR MISSING FROM AVERAGE/ACCUMULATION
C          (21)  - CENTURY OF REFERENCE TIME OF DATA
C          (22)  - UNITS DECIMAL SCALE FACTOR
C          (23)  - SUBCENTER NUMBER
C     iret       - Error return value:
C                  0  = Successful
C                  1  = Don't know what to do with pre-defined bitmap.
C                  2  = Unrecognized GRIB2 PDT 4.ipdsnum
C
C REMARKS:  Use pds2pdtens for ensemble related PDS
C
C ATTRIBUTES:
C   LANGUAGE: Fortran 90
C   MACHINE:  IBM SP
C
C$$$
        
        use params

        integer,intent(in) :: idsect(*),ipdstmpl(*),idrstmpl(*)
        integer,intent(in) :: ipdsnum,idisc,idrsnum,ibmap
        integer,intent(out) :: kpds(*)
        integer,intent(out) :: iret

        iret=0
        kpds(1:24)=0
        if ( (ipdsnum.lt.0).OR.(ipdsnum.gt.15) ) then
           print *,'makepds: Don:t know GRIB2 PDT 4.',ipdsnum
           iret=2
           return
        endif

        kpds(1)=idsect(1)
        kpds(2)=ipdstmpl(5)
        kpds(3)=255
        kpds(4)=128
        if ( ibmap.ne.255 ) kpds(4)=kpds(4)+64
        if ( ibmap.ge.1.AND.ibmap.le.253 ) then
           print *,'makepds: Don:t know about predefined bit-map ',ibmap
           iret=1
           return
        endif
        call param_g2_to_g1(idisc,ipdstmpl(1),ipdstmpl(2),kpds(5),
     &                      kpds(19))
C
C  Special parameters for ICAO WAFS (Max Icing, TP and CAT)
C
        If (ipdstmpl(16).eq.2.and.ipdstmpl(1).eq.19.and.
     &      ipdstmpl(2).eq.20) kpds(5) = 169
        If (ipdstmpl(16).eq.2.and.ipdstmpl(1).eq.19.and.
     &      ipdstmpl(2).eq.21) kpds(5) = 171
        If (ipdstmpl(16).eq.2.and.ipdstmpl(1).eq.19.and.
     &      ipdstmpl(2).eq.22) kpds(5) = 173
C
C  Special parameters for ICAO Height at CB Base and Top
C  in GRIB1 Table 140
C
        If (ipdstmpl(1).eq.3.and.ipdstmpl(2).eq.3) then
           If (ipdstmpl(10).eq.11) then
              kpds(19) = 140
              kpds(5)  = 179
           end if
           If (ipdstmpl(10).eq.12) then
             kpds(19) = 140
             kpds(5)  = 180
           end if
        end if
C
        call levelcnv(ipdstmpl,kpds(6),kpds(7))      ! level
        kpds(8)=mod(idsect(6),100)
        if ( kpds(8).eq.0 ) kpds(8)=100
        kpds(9)=idsect(7)                            ! Year
        kpds(10)=idsect(8)                           ! Month
        kpds(11)=idsect(9)                           ! Day
        kpds(12)=idsect(10)                          ! Hour
        if ( ipdstmpl(8).ne.13 ) then
           kpds(13)=ipdstmpl(8)                      ! Time Unit
        else
           kpds(13)=254
        endif
        kpds(14)=ipdstmpl(9)                         ! P1
        if ( ipdsnum.le.7 ) then                     ! P2
           kpds(15)=0
           kpds(16)=0
           kpds(20)=0
           if ( kpds(14).eq.0 ) kpds(16)=1
           if ( kpds(14).gt.255 ) kpds(16)=10
           if ( ipdstmpl(5).eq.77.OR.ipdstmpl(5).eq.81.OR.
     &          ipdstmpl(5).eq.96.OR.ipdstmpl(5).eq.80.OR.
     &          ipdstmpl(5).eq.82.OR.ipdstmpl(5).eq.120.OR.
     &          ipdstmpl(5).eq.47.OR.ipdstmpl(5).eq.11 ) then 
              kpds(16)=10
           end if
           if (ipdstmpl(5).eq.84.AND.kpds(5).eq.154)kpds(16) = 10
C
C          NOAA Wave Watch III and Coastal Ocean Circulation
C          and Alaska Waters Regional Wave Model
C
           if ( ipdstmpl(5).eq.88.OR.ipdstmpl(5).eq.121
     &          .OR.ipdstmpl(5).eq.122.OR.ipdstmpl(5).eq.123
     &          .OR.ipdstmpl(5).eq.124.OR.ipdstmpl(5).eq.125
     &          .OR.ipdstmpl(5).eq.131.OR.ipdstmpl(5).eq.45
     &          .OR.ipdstmpl(5).eq.11 ) then
              kpds(16) = 0
C
C Level Surface set to 1
C
              if (kpds(5).eq.80.OR.kpds(5).eq.82.OR.
     &             kpds(5).eq.88.OR.kpds(5).eq.49.OR.
     &             kpds(5).eq.50) kpds(7)=1  ! Level Surface
              if (ipdstmpl(5).eq.122.OR.ipdstmpl(5).eq.124.OR.
     &            ipdstmpl(5).eq.131.OR.ipdstmpl(5).eq.123.OR.
     &            ipdstmpl(5).eq.125.OR.ipdstmpl(5).eq.88.OR.
     &            ipdstmpl(5).eq.121) kpds(7)=1
              if (idsect(1).eq.54.AND.ipdstmpl(5).eq.45) kpds(16) = 10
           endif
        else
           selectcase (ipdsnum)
            case(8)
              ipos=24
            case(9)
              ipos=31
            case(10)
              ipos=25
            case(11)
              ipos=27
            case(12)
              ipos=26
            case(13)
              ipos=40
            case(14)
              ipos=39
           end select
           kpds(15)=ipdstmpl(ipos+3)+kpds(14)
           selectcase (ipdstmpl(ipos))
            case (255)
              kpds(16)=2
            case (0)
              kpds(16)=3
            case (1)
              kpds(16)=4
            case (2)
              kpds(16)=2
            case (3)
              kpds(16)=2
            case (4)
              kpds(16)=5
            case (51)
              kpds(16)=51
           end select
           kpds(20)=ipdstmpl(ipos-1)
        endif
C
C   Special case for FNMOC (TMAX and TMIN)
C
        if (ipdstmpl(4).eq.58 .AND. ipdsnum.eq.11 .AND.
     &     (ipdstmpl(1).eq.0
     &     .AND.ipdstmpl(2).eq.0).AND.(ipdstmpl(10).eq.103)) then
           kpds(16) = 2
C   For Maximum Temperature
        If (ipdstmpl(27).eq.2 .AND. ipdstmpl(1).eq.0 .AND.
     &      ipdstmpl(2).eq.0) kpds(5) = 15
C   For Minimum Temperature
        If (ipdstmpl(27).eq.3 .AND. ipdstmpl(1).eq.0 .AND.
     &      ipdstmpl(2).eq.0) kpds(5) = 16
        end if
C
C   Special case for WAFS (Mean/MAx IP,CTP and CAT)
C
        if (ipdstmpl(5).eq.96.AND.((ipdstmpl(1).eq.19)
     &     .AND.(ipdstmpl(2).eq.20.or.ipdstmpl(2).eq.21.or.
     &     ipdstmpl(2).eq.22)).AND.(ipdstmpl(10).eq.100)) then
           kpds(16) = 10
        end if
C
        kpds(17)=0
        kpds(18)=1                                   ! GRIB edition
        kpds(21)=(idsect(6)/100)+1                   ! Century
        if ( kpds(8).eq.100 ) kpds(21)=idsect(6)/100
        kpds(22)=idrstmpl(3)                         ! Decimal scale factor
        kpds(23)=idsect(2)                           ! Sub-center
        return
        end


        subroutine levelcnv(ipdstmpl,ltype,lval)
C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    levelcnv
C   PRGMMR: Gilbert        ORG: W/NP11     DATE: 2003-06-12
C
C ABSTRACT: this routine converts Level/layer information
C   from a GRIB2 Product Definition Template to GRIB1 
C   Level type and Level value.
C
C PROGRAM HISTORY LOG:
C 2003-06-12  Gilbert
C 2007-10-24  Boi Vuong  - Added level 8 (Nominal top of atmosphere)
C
C USAGE:    CALL levelcnv(ipdstmpl,ltype,lval)
C   INPUT ARGUMENT LIST:
C     ipdstmpl() - GRIB2 Product Definition Template values
C
C   OUTPUT ARGUMENT LIST:      (INCLUDING WORK ARRAYS)
C     ltype    - GRIB1 level type (PDS octet 10)
C     lval     - GRIB1 level/layer value(s) (PDS octets 11 and 12)
C
C REMARKS: LIST CAVEATS, OTHER HELPFUL HINTS OR INFORMATION
C
C ATTRIBUTES:
C   LANGUAGE: Fortran 90
C   MACHINE:  IBM SP
C
C$$$

        integer,intent(in) :: ipdstmpl(*)
        integer,intent(out) :: ltype,lval

        ltype=255
        lval=0
        ltype1=ipdstmpl(10)
        ltype2=ipdstmpl(13)

        if ( ltype1.eq.10.AND.ltype2.eq.255 ) then
           ltype=200
           lval=0
        elseif ( ltype1.eq.11.AND.ltype2.eq.255 ) then
           ltype=216
           lval=0
        elseif ( ltype1.eq.12.AND.ltype2.eq.255 ) then
           ltype=217
           lval=0
        elseif ( ltype1.lt.100.AND.ltype2.eq.255 ) then
           ltype=ltype1
           lval=0
        elseif ( ltype1.eq.1.AND.ltype2.eq.8 ) then
           ltype=ltype1
           lval=0
        elseif ( ltype1.eq.10.AND.ltype2.eq.255 ) then
           ltype=200
           lval=0
        elseif ( ltype1.ge.200.AND.ltype2.eq.255 ) then
           ltype=ltype1
           lval=0
        elseif (ltype1.eq.100.AND.ltype2.eq.255 ) then
           ltype=100
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1/100.)
        elseif (ltype1.eq.100.AND.ltype2.eq.100 ) then
           ltype=101
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1/1000.)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2/1000.)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.101.AND.ltype2.eq.255 ) then
           ltype=102
           lval=0
        elseif (ltype1.eq.102.AND.ltype2.eq.255 ) then
           ltype=103
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1)
        elseif (ltype1.eq.102.AND.ltype2.eq.102 ) then
           ltype=104
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.103.AND.ltype2.eq.255 ) then
           ltype=105
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1)
        elseif (ltype1.eq.103.AND.ltype2.eq.103 ) then
           ltype=106
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1/100.)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2/100.)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.104.AND.ltype2.eq.255 ) then
           ltype=107
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1*10000.)
        elseif (ltype1.eq.104.AND.ltype2.eq.104 ) then
           ltype=108
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1*100.)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2*100.)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.105.AND.ltype2.eq.255 ) then
           ltype=109
           lval=ipdstmpl(12)
        elseif (ltype1.eq.105.AND.ltype2.eq.105 ) then
           ltype=110
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.106.AND.ltype2.eq.255 ) then
           ltype=111
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1*100.)
        elseif (ltype1.eq.106.AND.ltype2.eq.106 ) then
           ltype=112
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1*100.)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2*100.)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.107.AND.ltype2.eq.255 ) then
           ltype=113
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1)
        elseif (ltype1.eq.107.AND.ltype2.eq.107 ) then
           ltype=114
           rscal1=10.**(-ipdstmpl(11))
           lval1=475-nint(real(ipdstmpl(12))*rscal1)
           rscal2=10.**(-ipdstmpl(14))
           lval2=475-nint(real(ipdstmpl(15))*rscal2)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.108.AND.ltype2.eq.255 ) then
           ltype=115
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1/100.)
        elseif (ltype1.eq.108.AND.ltype2.eq.108 ) then
           ltype=116
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1/100.)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2/100.)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.109.AND.ltype2.eq.255 ) then
           ltype=117
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1*1000000000.)
        elseif (ltype1.eq.111.AND.ltype2.eq.255 ) then
           ltype=119
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1*10000.)
        elseif (ltype1.eq.111.AND.ltype2.eq.111 ) then
           ltype=120
           rscal1=10.**(-ipdstmpl(11))
           lval1=nint(real(ipdstmpl(12))*rscal1*100.)
           rscal2=10.**(-ipdstmpl(14))
           lval2=nint(real(ipdstmpl(15))*rscal2*100.)
           lval=(lval1*256)+lval2
        elseif (ltype1.eq.160.AND.ltype2.eq.255 ) then
           ltype=160
           rscal1=10.**(-ipdstmpl(11))
           lval=nint(real(ipdstmpl(12))*rscal1)
        else
           print *,'levelcnv: GRIB2 Levels ',ltype1,ltype2,
     &             ' not recognized.'
           ltype=255
        endif

!  High resolution stuff
!        elseif (ltype.eq.121) then
!           ipdstmpl(10)=100
!           ipdstmpl(12)=(1100+(lval/256))*100
!           ipdstmpl(13)=100
!           ipdstmpl(15)=(1100+mod(lval,256))*100
!        elseif (ltype.eq.125) then
!           ipdstmpl(10)=103
!           ipdstmpl(11)=-2
!           ipdstmpl(12)=lval
!        elseif (ltype.eq.128) then
!           ipdstmpl(10)=104
!           ipdstmpl(11)=-3
!           ipdstmpl(12)=1100+(lval/256)
!           ipdstmpl(13)=104
!           ipdstmpl(14)=-3
!           ipdstmpl(15)=1100+mod(lval,256)
!        elseif (ltype.eq.141) then
!           ipdstmpl(10)=100
!           ipdstmpl(12)=(lval/256)*100
!           ipdstmpl(13)=100
!           ipdstmpl(15)=(1100+mod(lval,256))*100

        return
        end