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