NCEPLIBS-ip 4.0.0
ipxwafs.f90
1 SUBROUTINE ipxwafs(IDIR, NUMPTS_THIN, NUMPTS_FULL, KM, NUM_OPT, &
2 OPT_PTS, IGDTLEN, IGDTMPL_THIN, DATA_THIN, &
3 IGDTMPL_FULL, DATA_FULL, IRET)
4!$$$ SUBPROGRAM DOCUMENTATION BLOCK
5!
6! SUBPROGRAM: IPXWAFS EXPAND OR CONTRACT WAFS GRIDS
7! PRGMMR: IREDELL ORG: W/NMC23 DATE: 96-04-10
8!
9! ABSTRACT: THIS SUBPROGRAM TRANSFORMS BETWEEN THE THINNED WAFS GRIDS
10! USED FOR TRANSMITTING TO THE AVIATION COMMUNITY
11! AND THEIR FULL EXPANSION AS USED FOR GENERAL INTERPOLATION
12! AND GRAPHICS. THE THINNED WAFS GRIDS ARE LATITUDE-LONGITUDE
13! GRIDS WHERE THE NUMBER OF POINTS IN EACH ROW DECREASE
14! TOWARD THE POLE. THIS INFORMATION IS STORED
15! IN THE GRIB 2 GRID DEFINITION TEMPLATE (SECTION 3) STARTING
16! AT OCTET 73. THE FULL GRID COUNTERPARTS HAVE AN EQUAL NUMBER
17! OF POINTS PER ROW. THE TRANSFORM BETWEEN THE FULL
18! AND THINNED WAFS GRID IS DONE BY LINEAR INTERPOLATION
19! AND IS NOT REVERSIBLE. THIS ROUTINE DOES NOT
20! WORK FOR BITMAPPED DATA.
21!
22! PROGRAM HISTORY LOG:
23! 96-04-10 IREDELL - INITIAL VERSION
24! 2015-JULY GAYNO - CONVERT TO GRIB 2
25!
26! USAGE: CALL IPXWAFS(IDIR, NUMPTS_THIN, NUMPTS_FULL, KM, NUM_OPT, &
27! OPT_PTS, IGDTLEN, IGDTMPL_THIN, DATA_THIN, &
28! IGDTMPL_FULL, DATA_FULL, IRET)
29!
30! INPUT ARGUMENT LIST:
31! IDIR - INTEGER TRANSFORM OPTION
32! (+1 TO EXPAND THINNED FIELDS TO FULL FIELDS)
33! (-1 TO CONTRACT FULL FIELDS TO THINNED FIELDS)
34! NUMPTS_THIN - INTEGER NUMBER OF GRID POINTS - THINNED GRID. MUST BE
35! 3447.
36! NUMPTS_FULL - INTEGER NUMBER OF GRID POINTS - FULL GRID. MUST
37! BE 5329 (73^2).
38! KM - INTEGER NUMBER OF FIELDS TO TRANSFORM
39! NUM_OPT - INTEGER NUMBER OF VALUES TO DESCRIBE THE THINNED
40! GRID. MUST BE 73. DIMENSION OF ARRAY OPT_PTS.
41! OPT_PTS - INTEGER (NUM_OPT) NUMBER OF GRID POINTS PER ROW -
42! THINNED GRID - IF IDIR=+1
43! IGDTLEN - INTEGER GRID DEFINTION TEMPLATE ARRAY LENGTH. MUST BE
44! 19 FOR LAT/LON GRIDS. CORRESPONDS TO THE GFLD%IGDTLEN
45! COMPONENT OF THE NCEP G2 LIBRARY GRIDMOD DATA STRUCTURE.
46! SAME FOR THIN AND FULL GRIDS WHICH ARE BOTH LAT/LON.
47! IGDTMPL_THIN - INTEGER (IGDTLEN) GRID DEFINITION TEMPLATE ARRAY -
48! THINNED GRID - IF IDIR=+1. CORRESPONDS TO THE
49! GFLD%IGDTMPL COMPONENT OF THE NCEP G2 LIBRARY
50! GRIDMOD DATA STRUCTURE (SECTION 3 INFO):
51! (1): SHAPE OF EARTH, OCTET 15
52! (2): SCALE FACTOR OF SPHERICAL EARTH RADIUS,
53! OCTET 16
54! (3): SCALED VALUE OF RADIUS OF SPHERICAL EARTH,
55! OCTETS 17-20
56! (4): SCALE FACTOR OF MAJOR AXIS OF ELLIPTICAL EARTH,
57! OCTET 21
58! (5): SCALED VALUE OF MAJOR AXIS OF ELLIPTICAL EARTH,
59! OCTETS 22-25
60! (6): SCALE FACTOR OF MINOR AXIS OF ELLIPTICAL EARTH,
61! OCTET 26
62! (7): SCALED VALUE OF MINOR AXIS OF ELLIPTICAL EARTH,
63! OCTETS 27-30
64! (8): SET TO MISSING FOR THINNED GRID., OCTS 31-34
65! (9): NUMBER OF POINTS ALONG A MERIDIAN, OCTS 35-38
66! (10): BASIC ANGLE OF INITIAL PRODUCTION DOMAIN,
67! OCTETS 39-42.
68! (11): SUBDIVISIONS OF BASIC ANGLE, OCTETS 43-46
69! (12): LATITUDE OF FIRST GRID POINT, OCTETS 47-50
70! (13): LONGITUDE OF FIRST GRID POINT, OCTETS 51-54
71! (14): RESOLUTION AND COMPONENT FLAGS, OCTET 55
72! (15): LATITUDE OF LAST GRID POINT, OCTETS 56-59
73! (16): LONGITUDE OF LAST GRID POINT, OCTETS 60-63
74! (17): SET TO MISSING FOR THINNED GRID, OCTETS 64-67
75! (18): J-DIRECTION INCREMENT, OCTETS 68-71
76! (19): SCANNING MODE, OCTET 72
77! DATA_THIN - REAL (NUMPTS_THIN,KM) THINNED GRID FIELDS IF IDIR=+1
78! IGDTMPL_FULL - INTEGER (IGDTLEN) GRID DEFINITION TEMPLATE ARRAY -
79! FULL GRID - IF IDIR=-1. CORRESPONDS TO THE
80! GFLD%IGDTMPL COMPONENT OF THE NCEP G2 LIBRARY
81! GRIDMOD DATA STRUCTURE. SAME AS IGDTMPL_THIN
82! EXCEPT:
83! (8): NUMBER OF POINTS ALONG A PARALLEL, OCTS 31-34
84! (17): I-DIRECTION INCREMENT, OCTETS 64-67
85! DATA_FULL - REAL (NUMPTS_FULL,KM) FULL GRID FIELDS IF IDIR=-1
86!
87! OUTPUT ARGUMENT LIST:
88! OPT_PTS - INTEGER NUMBER OF GRID POINTS PER ROW - THINNED GRID -
89! IF IDIR=-1
90! IGDTMPL_THIN - INTEGER (IGDTLEN) GRID DEFINITION TEMPLATE ARRAY -
91! THINNED GRID - IF IDIR=-1. CORRESPONDS TO THE
92! GFLD%IGDTMPL COMPONENT OF THE NCEP G2 LIBRARY
93! GRIDMOD DATA STRUCTURE. DEFINED ABOVE.
94! DATA_THIN - REAL (NUMPTS_THIN,KM) THINNED GRID FIELDS IF IDIR=-1
95! IGDTMPL_FULL - INTEGER (IGDTLEN) GRID DEFINITION TEMPLATE ARRAY -
96! FULL GRID - IF IDIR=+1. CORRESPONDS TO THE
97! GFLD%IGDTMPL COMPONENT OF THE NCEP G2 LIBRARY
98! GRIDMOD DATA STRUCTURE. DEFINED ABOVE.
99! DATA_FULL - REAL (NUMPTS_FULL,KM) FULL GRID FIELDS IF IDIR=+1
100! IRET - INTEGER RETURN CODE
101! 0 SUCCESSFUL TRANSFORMATION
102! 1 IMPROPER GRID SPECIFICATION
103!
104! ATTRIBUTES:
105! LANGUAGE: FORTRAN 90
106!
107!$$$
108 IMPLICIT NONE
109!
110 INTEGER, INTENT(IN ) :: NUM_OPT
111 INTEGER, INTENT(INOUT) :: OPT_PTS(NUM_OPT)
112 INTEGER, INTENT(IN ) :: IDIR, KM, NUMPTS_THIN, NUMPTS_FULL
113 INTEGER, INTENT(IN ) :: IGDTLEN
114 INTEGER, INTENT(INOUT) :: IGDTMPL_THIN(IGDTLEN)
115 INTEGER, INTENT(INOUT) :: IGDTMPL_FULL(IGDTLEN)
116 INTEGER, INTENT( OUT) :: IRET
117!
118 REAL, INTENT(INOUT) :: DATA_THIN(NUMPTS_THIN,KM)
119 REAL, INTENT(INOUT) :: DATA_FULL(NUMPTS_FULL,KM)
120!
121 INTEGER, PARAMETER :: MISSING=-1
122!
123 INTEGER :: SCAN_MODE, I, J, K, IDLAT, IDLON
124 INTEGER :: IA, IB, IM, IM1, IM2, NPWAFS(73)
125 INTEGER :: IS1, IS2, ISCAN, ISCALE
126!
127 LOGICAL :: TEST1, TEST2
128!
129 REAL :: DLON, HI
130 REAL :: RAT1, RAT2, RLON1, RLON2
131 REAL :: WA, WB, X1, X2
132!
133 DATA npwafs/ &
134 73, 73, 73, 73, 73, 73, 73, 73, 72, 72, 72, 71, 71, 71, 70,&
135 70, 69, 69, 68, 67, 67, 66, 65, 65, 64, 63, 62, 61, 60, 60,&
136 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43,&
137 42, 40, 39, 38, 36, 35, 33, 32, 30, 29, 28, 26, 25, 23, 22,&
138 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2/
139! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
140! TRANSFORM GDS
141 iret=0
142! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
143! REG LAT/LON GRIDS HAVE 19 GDT ELEMENTS.
144 IF (igdtlen /= 19 .OR. numpts_thin/=3447 .OR. numpts_full/=5329) THEN
145 iret=1
146 RETURN
147 ENDIF
148! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149! EXPAND THINNED GDS TO FULL GDS
150 IF(idir.GT.0) THEN
151 scan_mode=igdtmpl_thin(19)
152 iscale=igdtmpl_thin(10)*igdtmpl_thin(11)
153 IF(iscale==0) iscale=10**6
154 idlat=nint(1.25*float(iscale))
155 test1=all(opt_pts==npwafs)
156 test2=all(opt_pts==npwafs(73:1:-1))
157! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158! SOME CHECKS TO ENSURE THIS IS A WAFS GRID
159 IF(scan_mode==64 .AND. igdtmpl_thin(9)==73 .AND. &
160 idlat==igdtmpl_thin(18) .AND. (test1 .OR. test2) ) THEN
161 igdtmpl_full=igdtmpl_thin
162 im=73
163 igdtmpl_full(8)=im
164 rlon1=float(igdtmpl_full(13))/float(iscale)
165 rlon2=float(igdtmpl_full(16))/float(iscale)
166 iscan=mod(igdtmpl_full(19)/128,2)
167 hi=(-1.)**iscan
168 dlon=hi*(mod(hi*(rlon2-rlon1)-1+3600,360.)+1)/(im-1)
169 igdtmpl_full(17)=nint(dlon*float(iscale))
170 ELSE
171 iret=1
172 ENDIF
173! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174! CONTRACT FULL GDS TO THINNED GDS
175 ELSEIF(idir.LT.0) THEN
176 scan_mode=igdtmpl_full(19)
177 iscale=igdtmpl_full(10)*igdtmpl_full(11)
178 IF(iscale==0) iscale=10**6
179 idlat=nint(1.25*float(iscale))
180 idlon=idlat
181! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
182! SOME CHECKS TO ENSURE THIS IS A WAFS GRID
183 IF(scan_mode==64 .AND. igdtmpl_full(8)==73 .AND. igdtmpl_full(9)==73 .AND. &
184 num_opt==73 .AND. idlat==igdtmpl_full(18) .AND. idlon==igdtmpl_full(17))THEN
185 igdtmpl_thin=igdtmpl_full
186 igdtmpl_thin(8)=missing
187 igdtmpl_thin(17)=missing
188 IF(igdtmpl_thin(12)==0) THEN ! IS LATITUDE OF ROW 1 THE EQUATOR?
189 opt_pts=npwafs
190 ELSE
191 opt_pts=npwafs(73:1:-1)
192 ENDIF
193 ELSE
194 iret=1
195 ENDIF
196 ENDIF
197! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
198! TRANSFORM FIELDS
199 IF(iret.EQ.0) THEN
200! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
201! EXPAND THINNED FIELDS TO FULL FIELDS
202 IF(idir.EQ.1) THEN
203 DO k=1,km
204 is1=0
205 is2=0
206 DO j=1,igdtmpl_full(9)
207 im1=opt_pts(j)
208 im2=igdtmpl_full(8)
209 rat1=float(im1-1)/float(im2-1)
210 DO i=1,im2
211 x1=(i-1)*rat1+1
212 ia=x1
213 ia=min(max(ia,1),im1-1)
214 ib=ia+1
215 wa=ib-x1
216 wb=x1-ia
217 data_full(is2+i,k)=wa*data_thin(is1+ia,k)+wb*data_thin(is1+ib,k)
218 ENDDO
219 is1=is1+im1
220 is2=is2+im2
221 ENDDO
222 ENDDO
223! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
224! CONTRACT FULL FIELDS TO THINNED FIELDS
225 ELSEIF(idir.EQ.-1) THEN
226 DO k=1,km
227 is1=0
228 is2=0
229 DO j=1,igdtmpl_full(9)
230 im1=opt_pts(j)
231 im2=igdtmpl_full(8)
232 rat2=float(im2-1)/float(im1-1)
233 DO i=1,im1
234 x2=(i-1)*rat2+1
235 ia=x2
236 ia=min(max(ia,1),im2-1)
237 ib=ia+1
238 wa=ib-x2
239 wb=x2-ia
240 data_thin(is1+i,k)=wa*data_full(is2+ia,k)+wb*data_full(is2+ib,k)
241 ENDDO
242 is1=is1+im1
243 is2=is2+im2
244 ENDDO
245 ENDDO
246 ENDIF
247 ENDIF
248! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
249 END SUBROUTINE ipxwafs