*IF DEF,C84_1A,OR,DEF,FLDOP,OR,DEF,FLDMOD UIE3F404.39
C ******************************COPYRIGHT****************************** GTS2F400.7399
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. GTS2F400.7400
C GTS2F400.7401
C Use, duplication or disclosure of this code is subject to the GTS2F400.7402
C restrictions as set forth in the contract. GTS2F400.7403
C GTS2F400.7404
C Meteorological Office GTS2F400.7405
C London Road GTS2F400.7406
C BRACKNELL GTS2F400.7407
C Berkshire UK GTS2F400.7408
C RG12 2SZ GTS2F400.7409
C GTS2F400.7410
C If no contract has been raised with this copy of the code, the use, GTS2F400.7411
C duplication or disclosure of it is strictly prohibited. Permission GTS2F400.7412
C to do so must first be obtained in writing from the Head of Numerical GTS2F400.7413
C Modelling at the above address. GTS2F400.7414
C ******************************COPYRIGHT****************************** GTS2F400.7415
C GTS2F400.7416
CLL SUBROUTINE PP2GRIB------------------------------------------------ PP2GRIBA.3
CLL PP2GRIBA.4
CLL Purpose: PP2GRIBA.5
CLL to code pp_header and un-packed data into grib PP2GRIBA.6
CLL PP2GRIBA.7
CLL Written by G.Ross/ P.Smith PP2GRIBA.8
CLL PP2GRIBA.9
CLL Model Modification history from model version 3.3: PP2GRIBA.10
CLL version Date PP2GRIBA.11
CLL 3.4 6/10/94 : Correct so that able to encode data other GRS3F304.1
CLL than just CF (m08) fields ie climate data. GRS3F304.2
CLL Also return error code and message. GRS3F304.3
CLL 3.4 2/12/94 : Extra argument introduced in subroutine GDG6F304.1
CLL CODER. MSG_LVL set to 2 ie Errors only GDG6F304.2
! 4.0 20/01/95 : Further changes to improve encoding of climate GRS3F400.1
! fields in grib & correct errors. (R. A. Stratton) GRS3F400.2
! 4.0 23/03/95 : Allow alternative packing method to be used for GRS3F400.3
! ppxref profile 6. (R.A.Stratton) GRS3F400.4
! 4.5 20/03/98 Correction for year 2K. GDG0F405.4
! Author D.M. Goddard GDG0F405.5
CLL PP2GRIBA.12
CLL Programming standard: Unified Model Documentation Paper No 3 PP2GRIBA.13
CLL PP2GRIBA.14
CLL System component: PP2GRIBA.15
CLL PP2GRIBA.16
CLL System task: PP2GRIBA.17
CLL PP2GRIBA.18
CLL Documentation: PP2GRIBA.19
CLL PP2GRIBA.20
CLLEND--------------------------------------------------------- PP2GRIBA.21
C*L Arguments:------------------------------------------------- PP2GRIBA.22
SUBROUTINE PP2GRIB(FIELD,WORK_ARRAY,MAXDIM,NUM_CRAY_WORDS, 2,2PP2GRIBA.23
& GRIB_PACKING,ILABEL,RLABEL, GRS3F400.5
& ICODE,CMESSAGE) GRS3F400.6
INTEGER PP2GRIBA.25
& MAXDIM PP2GRIBA.26
& ,NUM_CRAY_WORDS PP2GRIBA.27
& ,ILABEL(45) PP2GRIBA.28
& ,WORK_ARRAY(MAXDIM) PP2GRIBA.29
& ,GRIB_PACKING ! IN - profile for packing GRS3F400.7
& ,ICODE ! out - error code GRS3F304.5
REAL PP2GRIBA.30
& FIELD(MAXDIM) PP2GRIBA.31
& ,RLABEL(19) PP2GRIBA.32
CHARACTER*80 GRS3F304.6
& CMESSAGE ! out - error message GRS3F304.7
PP2GRIBA.33
EXTERNAL CODER,STASH_GRIB,GRIB_TIME_INT GRS3F400.8
PP2GRIBA.35
c LOCAL VARIABLES PP2GRIBA.36
INTEGER IDIM PP2GRIBA.37
; ,BLOCK0(4) PP2GRIBA.38
; ,BLOCK1(21) PP2GRIBA.39
; ,BLOCK2(30) PP2GRIBA.40
; ,BLOCK3(2) PP2GRIBA.41
; ,BLOCK4(2) PP2GRIBA.42
; ,BITMAP(MAXDIM) PP2GRIBA.43
; ,WORK1(288) PP2GRIBA.44
; ,WORK2(500) PP2GRIBA.45
; ,ERROR PP2GRIBA.46
; ,ERROR_UNIT PP2GRIBA.47
; ,QUASI(1) PP2GRIBA.48
; ,LENVRT PP2GRIBA.49
; ,WIDTH PP2GRIBA.50
; ,WORDSZ PP2GRIBA.52
; ,LENQ PP2GRIBA.53
; ,LENGRB PP2GRIBA.54
INTEGER GRS3F400.9
; STASH_SECT_NO GRS3F400.10
; ,STASH_ITEM_NO PP2GRIBA.58
; ,TABLE2_VERSION PP2GRIBA.59
; ,TABLE2_ENTRY PP2GRIBA.60
& ,IB ,IC, BBB, ICENTURY GRS3F400.11
& ,D_TIME, T_UNITS GRS3F304.10
& ,MSG_LVL GDG6F304.4
& ,IFLAG_MAX, IFLAG_MIN, IFLAG_VERTM ! flags for processing GRS3F400.12
& ,IFLAG_MEAN ,IFLAG_ZONAL ! code GRS3F400.13
& ,IREM GRS3F400.14
LOGICAL OROW PP2GRIBA.61
; ,OBITMAP PP2GRIBA.62
REAL VERTCO(4) GRS3F400.15
; ,WORKR(288) PP2GRIBA.64
; ,BLOCKR(20) PP2GRIBA.65
; ,STORE(MAXDIM) PP2GRIBA.66
& ,FMAX ,FMIN, RANGE GRS3F304.11
& ,DLONZ GRS3F400.16
PARAMETER(MSG_LVL=2) ! Errors only GDG6F304.5
GRS3F400.17
! -------------------------------------------------------------------- GRS3F400.18
! initialise variables for call to coder GRS3F400.19
GRS3F400.20
ICODE=0 GRS3F400.21
ERROR=0 PP2GRIBA.68
ERROR_UNIT=6 PP2GRIBA.69
LENQ = 1 GRS3F400.22
WORDSZ = 64 GRS3F400.23
LENGRB = MAXDIM GRS3F400.24
GRS3F400.25
IDIM = ILABEL(18)*ILABEL(19) ! length of field GRS3F304.12
GRS3F400.26
! -------------------------------------------------------------------- GRS3F400.27
! Method of grib packing GRS3F400.28
! ----------------------- GRS3F400.29
! PPXREF profiles 1-5 - use binary accuracy method (requires less space) GRS3F400.30
! 6 - use width method, with simple packing to be GRS3F400.31
! the similar to the ECMWF MARS archive. GRS3F400.32
! GRS3F400.33
! Note in the case of -99 in a binary accuracy profile ie no packing, GRS3F400.34
! use width =30, the maximum value which can safely be used with 32 GRS3F400.35
! bit numbers. GRS3F400.36
! GRS3F400.37
IF (GRIB_PACKING.eq.6) THEN ! Width method GRS3F400.38
GRS3F400.39
OROW = .FALSE. ! Simple packing GRS3F400.40
OBITMAP = .FALSE. ! Do not use bitmap. GRS3F400.41
BLOCK0(4)=0 GRS3F400.42
WIDTH = NINT(RLABEL(6)) ! required width GRS3F400.43
IF (WIDTH.GT.30.or.WIDTH.LE.0) THEN ! check sensible value GRS3F400.44
WIDTH=30 GRS3F400.45
ENDIF GRS3F400.46
ELSE ! binary accuracy method GRS3F400.47
GRS3F400.48
OROW = .TRUE. ! Row by row packing GRS3F400.49
OBITMAP = .TRUE. ! use bitmap for fields with GRS3F400.50
! missing data. GRS3F400.51
BLOCK0(4) = NINT(RLABEL(6)) ! Binary accuracy - power of 2 GRS3F400.52
WIDTH=0 GRS3F400.53
IF (BLOCK0(4).eq.-99) THEN ! use maximum number of bits GRS3F400.54
WIDTH = 30 GRS3F400.55
ENDIF GRS3F400.56
ENDIF GRS3F400.57
GRS3F400.58
! -------------------------------------------------------------------- GRS3F400.59
! SET UP VARIABLES FOR GRIB CODING ROUTINE GRS3F400.60
! GRS3F400.61
! Section 0 GRS3F400.62
! ------------- GRS3F400.63
! GRS3F400.64
BLOCK0(1) = 1 ! GRIB Edition number PP2GRIBA.84
STASH_SECT_NO = ILABEL(42)/1000 PP2GRIBA.85
STASH_ITEM_NO = MOD(ILABEL(42),1000) PP2GRIBA.86
CALL STASH_GRIB
(STASH_SECT_NO,STASH_ITEM_NO, PP2GRIBA.87
* TABLE2_VERSION,TABLE2_ENTRY,ERROR) PP2GRIBA.88
BLOCK0(2) = TABLE2_VERSION ! table 2 version number PP2GRIBA.89
BLOCK0(3) = 0 !length of message (OUTPUT ONLY) PP2GRIBA.90
! BLOCK0(4) set above GRS3F400.65
PP2GRIBA.92
! Section 1 GRS3F400.66
! ------------ GRS3F400.67
PP2GRIBA.114
BLOCK1(1) = 74 ! ORIGINATING CENTRE PP2GRIBA.115
BLOCK1(2) = 45 ! MODEL IDENT NUMBER PP2GRIBA.116
BLOCK1(3) = 42 ! Grid ident number PP2GRIBA.117
GRS3F400.68
! Bit map GRS3F400.69
GRS3F400.70
IF (OBITMAP) THEN PP2GRIBA.118
ICNT=0 PP2GRIBA.119
! WRITE(6,*)' @@ MISSING DATA BIT-MAPPING rmdi ',RLABEL(18) GIE0F403.477
DO II=1,IDIM PP2GRIBA.121
IF (FIELD(II) .NE. RLABEL(18)) THEN GRS3F304.15
ICNT=ICNT+1 PP2GRIBA.123
STORE(ICNT)=FIELD(II) PP2GRIBA.124
BITMAP(II)=1 PP2GRIBA.125
ELSE PP2GRIBA.126
BITMAP(II)=0 PP2GRIBA.127
END IF PP2GRIBA.128
ENDDO PP2GRIBA.129
LEN_BITMAP = IDIM PP2GRIBA.130
IDIM = ICNT PP2GRIBA.131
IF (IDIM .NE. LEN_BITMAP) then ! bitmap required GRS3F400.71
BLOCK1(4) = 192 ! Block ident flags PP2GRIBA.134
ELSE ! no bitmap required GRS3F400.72
LEN_BITMAP = 1 PP2GRIBA.137
BLOCK1(4) = 128 ! Block ident flags PP2GRIBA.138
ENDIF PP2GRIBA.139
ELSE PP2GRIBA.140
! GRS3F400.73
! Profile 6 - attempt to resemble grib in MARS archive GRS3F400.74
! replace missing data values by 0.0 - not an ideal solution GRS3F400.75
! but loose all accuaracy if keep UM missing data indicator. GRS3F400.76
! GRS3F400.77
DO IJ=1,IDIM PP2GRIBA.141
STORE(IJ)=FIELD(IJ) PP2GRIBA.142
IF (field(ij).eq.RLABEL(18)) store(IJ)=0.0 GRS3F400.78
ENDDO PP2GRIBA.143
LEN_BITMAP = 1 PP2GRIBA.144
BLOCK1(4) = 128 ! Block ident flags PP2GRIBA.145
END IF PP2GRIBA.146
GRS3F400.79
BLOCK1(5) = TABLE2_ENTRY !parameter identification PP2GRIBA.147
! ------------------------------------------------------------------ GRS3F400.80
! Make use of LBPROC information ILABEL(25) GRS3F400.81
! GRS3F400.82
! Note not worked out a way of storing max and min information in GRS3F400.83
! grib header GRS3F400.84
GRS3F304.21
IFLAG_MAX=0 GRS3F400.85
IFLAG_MIN=0 GRS3F400.86
IFLAG_VERTM=0 GRS3F400.87
IFLAG_MEAN=0 GRS3F400.88
IFLAG_ZONAL=0 GRS3F400.89
IREM=ILABEL(25) GRS3F400.90
IF(IREM.GE.8192) THEN ! maximum value GRS3F400.91
IFLAG_MAX=1 GRS3F400.92
IREM=IREM-8192 GRS3F400.93
ENDIF GRS3F304.51
IF(IREM.GE.4096) THEN ! minimum value GRS3F400.94
IFLAG_MIN=1 GRS3F400.95
IREM=IREM-4096 GRS3F400.96
ENDIF GRS3F400.97
IF(IREM.GE.2048) THEN ! vertical mean GRS3F400.98
IFLAG_VERTM=1 GRS3F400.99
IREM=IREM-2048 GRS3F400.100
ENDIF GRS3F400.101
! 1024 - difference between fields at 2 levels (not used in UM) GRS3F400.102
! 512 - Square root of field ( not used in UM) GRS3F400.103
! 256 - product of fields not used in UM output GRS3F400.104
IF(IREM.GE.128) THEN ! time mean GRS3F400.105
IFLAG_MEAN=1 GRS3F400.106
IREM=IREM-128 GRS3F400.107
ENDIF GRS3F400.108
IF(IREM.GE.64) THEN ! Zonal mean GRS3F400.109
IFLAG_ZONAL=1 GRS3F400.110
ENDIF GRS3F400.111
! 32, 16, 8, 4, 2 & 1 not used in UM output GRS3F400.112
! ------------------------------------------------------------------ GRS3F304.53
! GRS3F304.54
! Level type information GRS3F304.55
GRS3F304.56
IF (ILABEL(26) .EQ. 9) THEN PP2GRIBA.149
IF (IFLAG_VERTM.EQ.1) THEN GRS3F400.113
BLOCK1(6) = 110 ! vertical mean hybrid coordinates GRS3F400.114
! Using code for layer information GRS3F400.115
ELSE GRS3F400.116
BLOCK1(6) = 109 ! Hybrid coordinates GRS3F400.117
ENDIF GRS3F400.118
ELSE IF (ILABEL(26) .EQ. 8) THEN GRS3F304.58
IF (IFLAG_VERTM.EQ.1) THEN GRS3F400.119
BLOCK1(6) = 121 ! vertical mean pressure coordinates GRS3F400.120
! Using code for layer information GRS3F400.121
ELSE GRS3F400.122
BLOCK1(6) = 100 ! pressure coordinates GRS3F400.123
ENDIF GRS3F400.124
ELSE IF (ILABEL(26) .EQ. 1) THEN GRS3F304.60
BLOCK1(6) = 105 ! Height coordinates GRS3F304.61
ELSE IF (ILABEL(26) .EQ. 128) THEN GRS3F304.62
BLOCK1(6) = 102 ! Mean sea level pressure GRS3F304.63
ELSE IF (ILABEL(26) .EQ. 129) THEN GRS3F304.64
BLOCK1(6) = 1 ! surface GRS3F304.65
ELSE IF (ILABEL(26) .EQ. 130) THEN GRS3F304.66
BLOCK1(6) = 7 ! tropopause level GRS3F304.67
ELSE IF (ILABEL(26) .EQ. 131) THEN GRS3F304.68
BLOCK1(6) = 6 ! Max wind GRS3F304.69
ELSE IF (ILABEL(26) .EQ. 132) THEN GRS3F304.70
BLOCK1(6) = 4 ! Freezing level ? GRS3F304.71
ELSE IF (ILABEL(26) .EQ. 10) THEN GRS3F304.72
BLOCK1(6) = 107 ! Sigma coordinates GRS3F304.73
ELSE IF (ILABEL(26) .EQ. 6) THEN GRS3F400.125
BLOCK1(6) = 111 ! depth below land surface GRS3F400.126
! used for soil levels GRS3F400.127
ELSE IF (ILABEL(26) .EQ. 133) THEN ! top of atmosphere GRS3F400.128
BLOCK1(6) = 8 ! nominal top of atmosphere GRS3F400.129
ELSE IF (ILABEL(26) .EQ. 275) THEN ! canopy height GRS3F400.130
BLOCK1(6) = 1 ! At present redefine as surface GRS3F400.131
ELSE IF (ILABEL(26) .EQ. 0) THEN GRS3F400.132
BLOCK1(6) = 0 ! Unspecified GRS3F400.133
ELSE PP2GRIBA.164
CMESSAGE='PP2GRIB : unrecognised level coordinate' GRS3F304.77
END IF PP2GRIBA.166
GRS3F304.78
! Additional level information GRS3F400.134
GRS3F400.135
IF (IFLAG_VERTM.EQ.1) THEN GRS3F400.136
IF (ILABEL(26).eq.9) THEN GRS3F400.137
! Note pp headers may not contain top level info as they should GRS3F400.138
BLOCK1(7) = 19 ! fixed at present GRS3F400.139
BLOCK1(8) =ILABEL(33) ! bottom level number GRS3F400.140
ELSE IF (ILABEL(26).eq.8) THEN GRS3F400.141
BLOCK1(7) = NINT(1100. - RLABEL(8)) ! Top pressure GRS3F400.142
BLOCK1(8) = NINT(1100. - RLABEL(7)) ! bottom pressure GRS3F400.143
ENDIF GRS3F400.144
ELSE PP2GRIBA.176
IF (ILABEL(26).eq.9) THEN GRS3F400.145
BLOCK1(7) =ILABEL(33) ! model level number GRS3F400.146
BLOCK1(8) =0 GRS3F400.147
ELSEIF (ILABEL(26).eq.8) THEN GRS3F400.148
BLOCK1(7) =ILABEL(33) ! Pressure in hPa GRS3F400.149
BLOCK1(8) =0 GRS3F400.150
ELSE GRS3F400.151
BLOCK1(7) = 0 ! Level descriptor GRS3F400.152
BLOCK1(8) = 0 ! " " (overflow) GRS3F400.153
ENDIF GRS3F400.154
ENDIF GRS3F400.155
GRS3F304.79
! ------------------------------------------------------------------ GRS3F304.80
! Time and date information GRS3F304.81
! GRS3F304.82
! First use LBTIM to determine how to work out time date GRS3F304.83
GRS3F304.84
BBB=MOD(ILABEL(13),100) GRS3F304.85
IC=MOD(ILABEL(13),10) GRS3F304.86
IB=(BBB-IC)/10 GRS3F304.87
GDG0F405.6
! work out century using ilabel(7) GDG0F405.7
ICENTURY=(ILABEL(7)-1)/100 + 1 GDG0F405.8
GRS3F400.160
! 1. Model time no year and month GRS3F400.161
! --------------------------------- GRS3F400.162
IF (IC.EQ.0) THEN GRS3F400.163
CMESSAGE='PP2GRIB : cannot code date/time ' GRS3F304.89
ICODE=1 GRS3F304.90
WRITE(6,*)'PP2GRIB: not able to code at present' GIE0F403.478
GRS3F304.92
! 2. Normal 365 day calendar GRS3F400.164
! -------------------------- GRS3F400.165
! At present assumes all fields are forecasts not means GRS3F400.166
GRS3F304.94
ELSE IF(IC.EQ.1) THEN GRS3F400.167
GRS3F304.97
! a) normal forecasts less than 10 days GRS3F400.168
GRS3F400.169
IF (ILABEL(14).lt.256) THEN GRS3F400.170
BLOCK1(17) = 0 ! Time range indicator GRS3F400.171
GRS3F400.172
! b) Copes with periods up to 65535 hours (2730 days or 7 years) GRS3F400.173
GRS3F400.174
ELSE IF (ILABEL(14).ge.256.and.ILABEL(14).lt.65535) THEN GRS3F400.175
BLOCK1(17) = 10 ! uses two octets for P1 GRS3F400.176
GRS3F400.177
! c) Periods longer than 7 years GRS3F400.178
ELSE GRS3F400.179
CMESSAGE='PP2GRIB : cannot code forecast period ' GRS3F400.180
ICODE=1 GRS3F400.181
WRITE(6,*)'PP2GRIB: cannot code forecast period ',ilabel(14) GIE0F403.479
ENDIF GRS3F400.183
GRS3F400.184
BLOCK1(9) = ILABEL(7)-(ICENTURY-1)*100 ! year GRS3F400.185
BLOCK1(10) = ILABEL(8) ! Month GRS3F304.99
BLOCK1(11) = ILABEL(9) ! Day GRS3F304.100
BLOCK1(12) = ILABEL(10) ! hour GRS3F304.101
BLOCK1(13) = 0 ! minute GRS3F304.102
BLOCK1(14) = 1 ! time unit GRS3F304.103
BLOCK1(15) = ILABEL(14) ! P1 (F/C period in hours) GRS3F304.104
BLOCK1(16) = 0 ! P2 GRS3F304.105
BLOCK1(18) = 0 ! number of averages GRS3F400.186
BLOCK1(19) = ICENTURY ! Century of reference time GRS3F400.187
GRS3F304.109
! 3. 360 day year - normal climate run calendar GRS3F400.188
! --------------------------------------------- GRS3F400.189
GRS3F304.111
ELSE IF (IC.EQ.2) THEN GRS3F400.190
GRS3F304.114
IF (ib.eq.1) THEN ! forecast fields GRS3F304.115
! As many climate runs exceed 7 years all forecast periods are GRS3F400.191
! recoded as analyses. GRS3F400.192
GRS3F400.193
BLOCK1(17) = 0 ! Time range indicator GRS3F304.116
! GRS3F400.194
BLOCK1(9) = ILABEL(1)-(ICENTURY-1)*100 ! Year in ref cent GRS3F400.195
BLOCK1(10) = ILABEL(2) ! Month GRS3F400.196
BLOCK1(11) = ILABEL(3) ! Day GRS3F400.197
BLOCK1(12) = ILABEL(4) ! hour GRS3F400.198
BLOCK1(13) = ILABEL(5) ! minute GRS3F400.199
BLOCK1(14) = 1 ! time unit GRS3F304.117
BLOCK1(15) = 0 ! P1 GRS3F400.200
BLOCK1(16) = 0 ! P2 GRS3F400.201
BLOCK1(18) = 0 ! number of averages GRS3F304.118
BLOCK1(19) = ICENTURY ! Century of reference time GRS3F400.202
GRS3F304.139
ELSE IF (ib.eq. 2) THEN ! Time average GRS3F304.140
GRS3F304.141
BLOCK1(17) = 3 ! Time range indicator GRS3F304.142
BLOCK1(9) = ILABEL(1)-(ICENTURY-1)*100 ! year GRS3F400.203
BLOCK1(10) = ILABEL(2) ! Month GRS3F304.144
BLOCK1(11) = ILABEL(3) ! Day GRS3F304.145
BLOCK1(12) = ILABEL(4) ! hour GRS3F304.146
BLOCK1(13) = ILABEL(5) ! minute GRS3F304.147
! Work out p2 and appropriate units for p2 GRS3F400.204
CALL GRIB_TIME_INT
(ILABEL(1),ILABEL(2),ILABEL(3),ILABEL(4), GRS3F304.148
& ILABEL(5),ILABEL(7),ILABEL(8),ILABEL(9),ILABEL(10), GRS3F304.149
& ILABEL(11),.TRUE.,D_TIME,T_UNITS) GRS3F304.150
GRS3F400.205
BLOCK1(14) = T_UNITS ! time units GRS3F304.151
BLOCK1(16) = D_TIME ! P2 GRS3F304.152
BLOCK1(15) = 0 ! P1 GRS3F304.153
BLOCK1(18) = 1 ! number of averages GRS3F304.154
BLOCK1(19) = ICENTURY ! Century of reference time GRS3F400.206
GRS3F304.156
else ! cannot code GRS3F304.157
WRITE(6,*)'Not able to code for date type ib =',ib GIE0F403.480
CMESSAGE='PP2GRIB: error for date time' GRS3F304.159
ICODE=1 GRS3F304.160
ENDIF GRS3F304.161
ELSE GRS3F304.162
WRITE(6,*)'Not able to code for date type ic =',ic GIE0F403.481
CMESSAGE='PP2GRIB: error for date time' GRS3F304.164
ICODE=1 GRS3F304.165
ENDIF GRS3F304.166
GRS3F304.167
BLOCK1(20) = 0 ! Decimal scale factor PP2GRIBA.191
BLOCK1(21) = 21 ! Length of BLOCK1 GRS3F400.207
PP2GRIBA.193
! -------------------------------------------------------------------- GRS3F400.208
! Section 2 information GRS3F400.209
! ---------------------- GRS3F400.210
IF (BLOCK1(6) .EQ. 109) THEN PP2GRIBA.194
BLOCK2(1) = 2 ! Number of vert coord parms PP2GRIBA.195
BLOCK2(2) = 53 ! PV, PL or 255 PP2GRIBA.196
LENVRT = 2 PP2GRIBA.197
VERTCO(1) = RLABEL(9) ! A COORDINATE PP2GRIBA.198
VERTCO(2) = RLABEL(7) ! B COORDINATE PP2GRIBA.199
! Can be uncommented when values for rlabel(1) & rlabel(2) are coded GRS3F400.211
! ELSE IF (BLOCK1(6) .EQ. 110) THEN GRS3F400.212
! BLOCK2(1) = 4 ! Number of vert coord parms GRS3F400.213
! BLOCK2(2) = 53 ! PV, PL or 255 GRS3F400.214
! LENVRT = 4 GRS3F400.215
! VERTCO(1) = RLABEL(10) ! A COORDINATE top GRS3F400.216
! VERTCO(2) = RLABEL(8) ! B COORDINATE top GRS3F400.217
! VERTCO(3) = RLABEL(1) ! A COORDINATE bottom (not coded) GRS3F400.218
! VERTCO(4) = RLABEL(2) ! B COORDINATE bottom (not coded) GRS3F400.219
ELSE PP2GRIBA.200
BLOCK2(1) = 0 ! Number of vert coord parms PP2GRIBA.201
BLOCK2(2) = 255 ! PV, PL or 255 PP2GRIBA.202
LENVRT = 1 GRS3F400.220
VERTCO(1) = 0. ! A COORDINATE PP2GRIBA.204
VERTCO(2) = 0. ! B COORDINATE PP2GRIBA.205
END IF PP2GRIBA.206
GRS3F400.221
BLOCK2(3) = 0 ! representation type ie lat longrid GRS3F400.222
BLOCK2(4) = ILABEL(19) ! Number of cols PP2GRIBA.208
BLOCK2(5) = ILABEL(18) ! Number of rows PP2GRIBA.209
BLOCK2(6) = NINT((RLABEL(14)+RLABEL(15))*1000) ! Lat 1st pt. PP2GRIBA.210
IF (BLOCK2(6).GT.180000.0) THEN PP2GRIBA.211
BLOCK2(6) = BLOCK2(6)-180000.0 PP2GRIBA.212
END IF PP2GRIBA.213
IF (IFLAG_ZONAL.EQ.1) THEN ! zonal means GRS3F400.223
BLOCK2(7) = NINT(RLABEL(16)*1000) ! Lon 1st pt. GRS3F400.224
BLOCK2(10) = NINT(RLABEL(17)*1000) ! lon last pt. GRS3F400.225
BLOCK2(11) = ABS(NINT((RLABEL(17)-RLABEL(16))*1000)) ! dlon GRS3F400.226
ELSE GRS3F400.227
BLOCK2(7) = NINT((RLABEL(16)+RLABEL(17))*1000) ! Lon 1st pt. GRS3F400.228
BLOCK2(10) = NINT((RLABEL(16)+(ILABEL(19)*RLABEL(17)))*1000) GRS3F400.229
! ! Lon of extreme point GRS3F400.230
BLOCK2(11) = ABS(NINT(RLABEL(17)*1000)) GRS3F400.231
! ! Horizontal dirn increment GRS3F400.232
ENDIF GRS3F400.233
IF (BLOCK2(7).GT.360000.0) THEN PP2GRIBA.215
BLOCK2(7) = BLOCK2(7)-360000.0 PP2GRIBA.216
END IF PP2GRIBA.217
IF (BLOCK2(10).GT.360000.0) THEN GRS3F400.234
BLOCK2(10) = BLOCK2(10)-360000.0 GRS3F400.235
END IF GRS3F400.236
BLOCK2(8) = 128 ! resolution and component flags PP2GRIBA.218
BLOCK2(9) = NINT((RLABEL(14)+(ILABEL(18)*RLABEL(15)))*1000) PP2GRIBA.219
! Lat of extreme point GRS3F400.237
IF (BLOCK2(9).GT.180000.0) THEN PP2GRIBA.221
BLOCK2(9) = BLOCK2(9)-180000.0 PP2GRIBA.222
END IF PP2GRIBA.223
BLOCK2(12) = ABS(NINT(RLABEL(15)*1000)) PP2GRIBA.231
! ! Vertical dirn increment GRS3F400.238
! Scanning mode flags GRS3F400.239
! west to east is positive GRS3F400.240
! If grid scans from west to east bit 1 is 0 GRS3F400.241
! if grid scans from east to west bit 1 is 1 ie add 128 GRS3F400.242
! south to north is positive GRS3F400.243
! if grid scans from north to south bit 2 is 0 GRS3F400.244
! if grid scans from south to north bit 2 is 1 ie add 64 GRS3F400.245
GRS3F400.246
BLOCK2(13) = 0 ! Scanning mode flags PP2GRIBA.233
IF (IFLAG_ZONAL.EQ.1) THEN GRS3F400.247
DLONZ=RLABEL(17)-RLABEL(16) GRS3F400.248
IF (DLONZ .LT. 0.0) BLOCK2(13) = BLOCK2(13) +128 GRS3F400.249
ELSE GRS3F400.250
IF (RLABEL(17) .LT. 0.0) BLOCK2(13) = BLOCK2(13) + 128 GRS3F400.251
ENDIF GRS3F400.252
IF (RLABEL(15) .GT. 0.0) BLOCK2(13) = BLOCK2(13) + 64 GRS3F400.253
GRS3F400.254
BLOCK2(14) = -NINT(RLABEL(11)*1000) ! Lat S Pole PP2GRIBA.236
BLOCK2(15) = -NINT(RLABEL(12)*1000) ! Lon S Pole PP2GRIBA.237
BLOCK2(16) = 0 PP2GRIBA.238
BLOCK2(17) = 0 PP2GRIBA.239
BLOCK2(18) = 0 PP2GRIBA.240
BLOCK2(19) = 0 PP2GRIBA.241
BLOCK2(20) = 0 PP2GRIBA.242
PP2GRIBA.243
! Section 3 GRS3F400.255
! ---------- GRS3F400.256
GRS3F400.257
BLOCK3(1)=0 GRS3F400.258
BLOCK3(2)=0 GRS3F400.259
GRS3F400.260
! Section 4 GRS3F400.261
! ---------- GRS3F400.262
GRS3F400.263
IF (OROW) THEN PP2GRIBA.244
BLOCK4(1) = 80 ! row by row packing PP2GRIBA.246
ELSE PP2GRIBA.247
BLOCK4(1) = 0 ! simple packing PP2GRIBA.249
END IF PP2GRIBA.250
BLOCK4(2) = 0 PP2GRIBA.251
PP2GRIBA.252
! ------------------------------------------------------------------- GRS3F400.264
GRS3F304.169
! Call grib encoder GRS3F304.170
GRS3F304.171
IF (ICODE.EQ.0) THEN GRS3F304.172
CALL CODER(
STORE,IDIM,VERTCO,LENVRT,BITMAP,LEN_BITMAP,QUASI,LENQ, GRS3F304.173
* WIDTH,WORDSZ,BLOCK0,BLOCK1,BLOCK2,BLOCK3,BLOCK4, PP2GRIBA.261
* BLOCKR,WORK_ARRAY,LENGRB,NUM_CRAY_WORDS, PP2GRIBA.262
* ERROR,WORK1,WORK2,WORKR,ERROR_UNIT,MSG_LVL) GDG6F304.6
GRS3F400.265
GRS3F400.266
IF (WIDTH.gt.30) then GRS3F400.267
CMESSAGE='PP2GRIB: trying to use more than 30 bits for grib' GRS3F400.268
ICODE=0 ! don't enforce failure at the moment GRS3F304.176
WRITE(6,*)'WARNING: grib requires more than 30 bits for accuracy', GIE0F403.482
& WIDTH,' stash code ',ILABEL(42) GRS3F400.270
ENDIF GRS3F304.179
ELSE GRS3F304.180
WRITE(6,*)'PP2GRIB: CODER not called for field ',ilabel(
42) GIE0F403.483
WRITE(6,*)CMESSAGE GIE0F403.484
ENDIF GRS3F304.182
GRS3F400.273
! set output length in header GRS3F400.274
GRS3F304.183
ILABEL(15) = NUM_CRAY_WORDS PP2GRIBA.265
PP2GRIBA.266
RETURN PP2GRIBA.267
END PP2GRIBA.268
CLL SUBROUTINE GRIB_STASH--------------------------------------------- PP2GRIBA.269
CLL PP2GRIBA.270
CLL Purpose: PP2GRIBA.271
CLL GRIB_STASH is a subroutine to indentify the stash parameter PP2GRIBA.272
CLL value and section number from the grib header codes PP2GRIBA.273
CLL PP2GRIBA.274
CLL octet 4 of the grib product definition section is the version PP2GRIBA.275
CLL number of the table 2 (parameter code description) PP2GRIBA.276
CLL values from 128 to 254 are available for local use, and we PP2GRIBA.277
CLL use them to describe the stash section number of the field. for PP2GRIBA.278
CLL each stash section number there are two octet 4 values. the first PP2GRIBA.279
CLL is for stash parameter values from 0 to 255, the second for values PP2GRIBA.280
CLL 256 to 511. PP2GRIBA.281
CLL octet 9 is the code value in table 2, ie stash parameter value, or PP2GRIBA.282
CLL stash parameter value -256 if it is more than 255. PP2GRIBA.283
CLL PP2GRIBA.284
CLL Written by G.Ross/ P.Smith PP2GRIBA.285
CLL PP2GRIBA.286
CLL Model Modification history from model version 3.3: PP2GRIBA.287
CLL version Date PP2GRIBA.288
CLL PP2GRIBA.289
CLL Programming standard: Unified Model Documentation Paper No 3 PP2GRIBA.290
CLL PP2GRIBA.291
CLL System component: PP2GRIBA.292
CLL PP2GRIBA.293
CLL System task: PP2GRIBA.294
CLL PP2GRIBA.295
CLL Documentation: PP2GRIBA.296
CLL PP2GRIBA.297
CLLEND--------------------------------------------------------- PP2GRIBA.298
C*L Arguments:------------------------------------------------- PP2GRIBA.299
SUBROUTINE GRIB_STASH(GRIB_BLOCK1_OCTET4,GRIB_BLOCK1_OCTET9, PP2GRIBA.300
* STASH_SECTION_NUMBER,STASH_ITEM_NUMBER, PP2GRIBA.301
* ERROR) PP2GRIBA.302
INTEGER PP2GRIBA.303
* GRIB_BLOCK1_OCTET4 ! OCTET 4 FROM GRIB PDB INPUT PP2GRIBA.304
* ,GRIB_BLOCK1_OCTET9 ! OCTET 9 FROM GRIB PDB INPUT PP2GRIBA.305
* ,STASH_SECTION_NUMBER ! STASH SECTION NUMBER OUTPUT PP2GRIBA.306
* ,STASH_ITEM_NUMBER ! STASH PARAMETER VALUE OUTPUT PP2GRIBA.307
* ,ERROR ! ERROR OUTPUT CODE OUTPUT PP2GRIBA.308
C LOCAL VARIABLES PP2GRIBA.309
INTEGER PP2GRIBA.310
* CARRY ! CARRY VALUE FROM ODD VALUES OF GRIB_BLOCK1_OCTET4 PP2GRIBA.311
C**** PP2GRIBA.312
IF(GRIB_BLOCK1_OCTET4.LT.128.OR.GRIB_BLOCK1_OCTET4.GT.253) THEN PP2GRIBA.313
ERROR = 99 PP2GRIBA.314
RETURN PP2GRIBA.315
ENDIF PP2GRIBA.316
CARRY = MOD(GRIB_BLOCK1_OCTET4,2) PP2GRIBA.317
STASH_SECTION_NUMBER = INT((GRIB_BLOCK1_OCTET4 - 128)/2) PP2GRIBA.318
STASH_ITEM_NUMBER = GRIB_BLOCK1_OCTET9 + CARRY*256 PP2GRIBA.319
RETURN PP2GRIBA.320
C**** PP2GRIBA.321
END PP2GRIBA.322
CLL SUBROUTINE STASH_GRIB--------------------------------------------- PP2GRIBA.323
CLL PP2GRIBA.324
CLL Purpose: PP2GRIBA.325
CLL STASH_GRIB is a subroutine to code the stash section number and PP2GRIBA.326
CLL parameter value in elements of the grib header. PP2GRIBA.327
CLL PP2GRIBA.328
CLL octet 4 of the grib product definition section is the version PP2GRIBA.329
CLL number of the table 2 (parameter code description) PP2GRIBA.330
CLL values from 128 to 254 areavailable for local use, and we PP2GRIBA.331
CLL use them to describe the stash section number of the field. for PP2GRIBA.332
CLL each stash section number there are two octet 4 values. the first PP2GRIBA.333
CLL is for stash parameter values from 0 to 255, the second for values PP2GRIBA.334
CLL 256 to 511. PP2GRIBA.335
CLL octet 9 is the code value in table 2, ie stash parameter value, or PP2GRIBA.336
CLL stash parameter value -256 if it is more than 255. PP2GRIBA.337
CLL PP2GRIBA.338
CLL PP2GRIBA.339
CLL Written by G.Ross/ P.Smith PP2GRIBA.340
CLL PP2GRIBA.341
CLL Model Modification history from model version 3.3: PP2GRIBA.342
CLL version Date PP2GRIBA.343
CLL PP2GRIBA.344
CLL Programming standard: Unified Model Documentation Paper No 3 PP2GRIBA.345
CLL PP2GRIBA.346
CLL System component: PP2GRIBA.347
CLL PP2GRIBA.348
CLL System task: PP2GRIBA.349
CLL PP2GRIBA.350
CLL Documentation: PP2GRIBA.351
CLL PP2GRIBA.352
CLLEND--------------------------------------------------------- PP2GRIBA.353
C*L Arguments:------------------------------------------------- PP2GRIBA.354
SUBROUTINE STASH_GRIB(STASH_SECTION_NUMBER,STASH_ITEM_NUMBER, 1PP2GRIBA.355
* GRIB_BLOCK1_OCTET4,GRIB_BLOCK1_OCTET9, PP2GRIBA.356
* ERROR) PP2GRIBA.357
INTEGER PP2GRIBA.358
* STASH_SECTION_NUMBER ! STASH SECTION NUMBER INPUT PP2GRIBA.359
* ,STASH_ITEM_NUMBER ! STASH PARAMETER VALUE INPUT PP2GRIBA.360
* ,GRIB_BLOCK1_OCTET4 ! OCTET 4 FROM GRIB PDB OUTPUT PP2GRIBA.361
* ,GRIB_BLOCK1_OCTET9 ! OCTET 9 FROM GRIB PDB OUTPUT PP2GRIBA.362
* ,ERROR ! ERROR OUTPUT CODE OUTPUT PP2GRIBA.363
C LOCAL VARIABLES PP2GRIBA.364
INTEGER PP2GRIBA.365
* CARRY ! CARRY VALUE FROM ODD VALUES OF GRIB_BLOCK1_OCTET4 PP2GRIBA.366
C**** PP2GRIBA.367
IF(STASH_ITEM_NUMBER.GT.511.OR.STASH_ITEM_NUMBER.LT.0) THEN PP2GRIBA.368
ERROR = 999 PP2GRIBA.369
RETURN PP2GRIBA.370
ELSE IF(STASH_ITEM_NUMBER.GT.255) THEN PP2GRIBA.371
CARRY = 1 PP2GRIBA.372
GRIB_BLOCK1_OCTET9 = STASH_ITEM_NUMBER - 256 PP2GRIBA.373
ELSE PP2GRIBA.374
CARRY = 0 PP2GRIBA.375
GRIB_BLOCK1_OCTET9 = STASH_ITEM_NUMBER PP2GRIBA.376
ENDIF PP2GRIBA.377
IF((STASH_SECTION_NUMBER.GE.0).AND. PP2GRIBA.378
* (STASH_SECTION_NUMBER.LE.62)) THEN PP2GRIBA.379
GRIB_BLOCK1_OCTET4 = STASH_SECTION_NUMBER*2 + 128 + CARRY PP2GRIBA.380
ELSE PP2GRIBA.381
ERROR = 999 PP2GRIBA.382
ENDIF PP2GRIBA.383
RETURN PP2GRIBA.384
C**** PP2GRIBA.385
END PP2GRIBA.386
*ENDIF PP2GRIBA.387