NCEPLIBS-ip 5.3.0
All Data Structures Namespaces Files Functions Variables Pages
ipxwafs.F90
Go to the documentation of this file.
1!> @file
2!> @brief Expand or contract wafs grids.
3!> @author Iredell @date 96-04-10
4
5!> Expand or contract wafs grids.
6!>
7!> This subprogram transforms between the thinned wafs grids used for
8!> transmitting to the aviation community and their full expansion as
9!> used for general interpolation and graphics.
10!>
11!> The thinned wafs grids are latitude-longitude grids where the
12!> number of points in each row decrease toward the pole.
13!>
14!> This information is stored in the grib 2 grid definition template
15!> (section 3) starting at octet 73. The full grid counterparts have
16!> an equal number of points per row. The transform between the full
17!> and thinned wafs grid is done by linear interpolation and is not
18!> reversible.
19!>
20!> This routine does not work for bitmapped data.
21!>
22!> ### Program History Log
23!> Date | Programmer | Comments
24!> -----|------------|---------
25!> 96-04-10 | iredell | initial version
26!> 2015-july | gayno | convert to grib 2
27!>
28!> @param[in] idir integer transform option
29!> - (+1 to expand thinned fields to full fields)
30!> - (-1 to contract full fields to thinned fields)
31!> @param[in] numpts_thin integer number of grid points - thinned
32!> grid. must be 3447.
33!> @param[in] numpts_full integer number of grid points - full
34!> grid. must be 5329 (73^2).
35!> @param[in] km integer number of fields to transform
36!> @param[in] num_opt integer number of values to describe the thinned
37!> grid. must be 73. dimension of array opt_pts.
38!> @param[inout] opt_pts integer (num_opt) number of grid points per
39!> row - thinned grid - if idir=+1
40!> @param[in] igdtlen integer grid defintion template array length.
41!> must be 19 for lat/lon grids. corresponds to the gfld%igdtlen
42!> component of the ncep g2 library gridmod data structure. same for
43!> thin and full grids which are both lat/lon.
44!> @param[inout] igdtmpl_thin integer (igdtlen) grid definition
45!> template array - thinned grid - if idir=+1. corresponds to the
46!> gfld%igdtmpl component of the ncep g2 library gridmod data
47!> structure (section 3 info):
48!> - 1 shape of earth, octet 15
49!> - 2 scale factor of spherical earth radius, octet 16
50!> - 3 scaled value of radius of spherical earth, octets 17-20
51!> - 4 scale factor of major axis of elliptical earth, octet 21
52!> - 5 scaled value of major axis of elliptical earth, octets 22-25
53!> - 6 scale factor of minor axis of elliptical earth, octet 26
54!> - 7 scaled value of minor axis of elliptical earth, octets 27-30
55!> - 8 set to missing for thinned grid., octs 31-34
56!> - 9 number of points along a meridian, octs 35-38
57!> - 10 basic angle of initial production domain, octets 39-42.
58!> - 11 subdivisions of basic angle, octets 43-46
59!> - 12 latitude of first grid point, octets 47-50
60!> - 13 longitude of first grid point, octets 51-54
61!> - 14 resolution and component flags, octet 55
62!> - 15 latitude of last grid point, octets 56-59
63!> - 16 longitude of last grid point, octets 60-63
64!> - 17 set to missing for thinned grid, octets 64-67
65!> - 18 j-direction increment, octets 68-71
66!> - 19 scanning mode, octet 72
67!> @param[inout] data_thin real (numpts_thin,km) thinned grid fields if idir=+1
68
69!> @param[inout] igdtmpl_full integer (igdtlen) grid definition
70!> template array - full grid - if idir=-1. corresponds to the
71!> gfld%igdtmpl component of the ncep g2 library gridmod data
72!> structure. same as igdtmpl_thin except:
73!> - 8 number of points along a parallel, octs 31-34
74!> - 17 i-direction increment, octets 64-67
75!> @param[inout] data_full real (numpts_full,km) full grid fields if idir=-1
76!> @param[out] iret integer return code
77!> - 0 successful transformation
78!> - 1 improper grid specification
79!>
80!> @author Iredell @date 96-04-10
81 SUBROUTINE ipxwafs(IDIR, NUMPTS_THIN, NUMPTS_FULL, KM, NUM_OPT, &
82 OPT_PTS, IGDTLEN, IGDTMPL_THIN, DATA_THIN, &
83 IGDTMPL_FULL, DATA_FULL, IRET)
84 IMPLICIT NONE
85!
86 INTEGER, INTENT(IN ) :: NUM_OPT
87 INTEGER, INTENT(INOUT) :: OPT_PTS(NUM_OPT)
88 INTEGER, INTENT(IN ) :: IDIR, KM, NUMPTS_THIN, NUMPTS_FULL
89 INTEGER, INTENT(IN ) :: IGDTLEN
90 INTEGER, INTENT(INOUT) :: IGDTMPL_THIN(IGDTLEN)
91 INTEGER, INTENT(INOUT) :: IGDTMPL_FULL(IGDTLEN)
92 INTEGER, INTENT( OUT) :: IRET
93!
94 REAL, INTENT(INOUT) :: DATA_THIN(NUMPTS_THIN,KM)
95 REAL, INTENT(INOUT) :: DATA_FULL(NUMPTS_FULL,KM)
96!
97 INTEGER, PARAMETER :: MISSING=-1
98!
99 INTEGER :: SCAN_MODE, I, J, K, IDLAT, IDLON
100 INTEGER :: IA, IB, IM, IM1, IM2, NPWAFS(73)
101 INTEGER :: IS1, IS2, ISCAN, ISCALE
102!
103 LOGICAL :: TEST1, TEST2
104!
105 REAL :: DLON, HI
106 REAL :: RAT1, RAT2, RLON1, RLON2
107 REAL :: WA, WB, X1, X2
108!
109 DATA npwafs/ &
110 73, 73, 73, 73, 73, 73, 73, 73, 72, 72, 72, 71, 71, 71, 70,&
111 70, 69, 69, 68, 67, 67, 66, 65, 65, 64, 63, 62, 61, 60, 60,&
112 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43,&
113 42, 40, 39, 38, 36, 35, 33, 32, 30, 29, 28, 26, 25, 23, 22,&
114 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2/
115! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116! TRANSFORM GDS
117 iret=0
118! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
119! REG LAT/LON GRIDS HAVE 19 GDT ELEMENTS.
120 IF (igdtlen /= 19 .OR. numpts_thin/=3447 .OR. numpts_full/=5329) THEN
121 iret=1
122 RETURN
123 ENDIF
124! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
125! EXPAND THINNED GDS TO FULL GDS
126 IF(idir.GT.0) THEN
127 scan_mode=igdtmpl_thin(19)
128 iscale=igdtmpl_thin(10)*igdtmpl_thin(11)
129 IF(iscale==0) iscale=10**6
130 idlat=nint(1.25*float(iscale))
131 test1=all(opt_pts==npwafs)
132 test2=all(opt_pts==npwafs(73:1:-1))
133! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
134! SOME CHECKS TO ENSURE THIS IS A WAFS GRID
135 IF(scan_mode==64 .AND. igdtmpl_thin(9)==73 .AND. &
136 idlat==igdtmpl_thin(18) .AND. (test1 .OR. test2) ) THEN
137 igdtmpl_full=igdtmpl_thin
138 im=73
139 igdtmpl_full(8)=im
140 rlon1=float(igdtmpl_full(13))/float(iscale)
141 rlon2=float(igdtmpl_full(16))/float(iscale)
142 iscan=mod(igdtmpl_full(19)/128,2)
143 hi=(-1.)**iscan
144 dlon=hi*(mod(hi*(rlon2-rlon1)-1+3600,360.)+1)/(im-1)
145 igdtmpl_full(17)=nint(dlon*float(iscale))
146 ELSE
147 iret=1
148 ENDIF
149! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
150! CONTRACT FULL GDS TO THINNED GDS
151 ELSEIF(idir.LT.0) THEN
152 scan_mode=igdtmpl_full(19)
153 iscale=igdtmpl_full(10)*igdtmpl_full(11)
154 IF(iscale==0) iscale=10**6
155 idlat=nint(1.25*float(iscale))
156 idlon=idlat
157! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158! SOME CHECKS TO ENSURE THIS IS A WAFS GRID
159 IF(scan_mode==64 .AND. igdtmpl_full(8)==73 .AND. igdtmpl_full(9)==73 .AND. &
160 num_opt==73 .AND. idlat==igdtmpl_full(18) .AND. idlon==igdtmpl_full(17))THEN
161 igdtmpl_thin=igdtmpl_full
162 igdtmpl_thin(8)=missing
163 igdtmpl_thin(17)=missing
164 IF(igdtmpl_thin(12)==0) THEN ! IS LATITUDE OF ROW 1 THE EQUATOR?
165 opt_pts=npwafs
166 ELSE
167 opt_pts=npwafs(73:1:-1)
168 ENDIF
169 ELSE
170 iret=1
171 ENDIF
172 ENDIF
173! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174! TRANSFORM FIELDS
175 IF(iret.EQ.0) THEN
176! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
177! EXPAND THINNED FIELDS TO FULL FIELDS
178 IF(idir.EQ.1) THEN
179 DO k=1,km
180 is1=0
181 is2=0
182 DO j=1,igdtmpl_full(9)
183 im1=opt_pts(j)
184 im2=igdtmpl_full(8)
185 rat1=float(im1-1)/float(im2-1)
186 DO i=1,im2
187 x1=(i-1)*rat1+1
188 ia=int(x1)
189 ia=min(max(ia,1),im1-1)
190 ib=ia+1
191 wa=ib-x1
192 wb=x1-ia
193 data_full(is2+i,k)=wa*data_thin(is1+ia,k)+wb*data_thin(is1+ib,k)
194 ENDDO
195 is1=is1+im1
196 is2=is2+im2
197 ENDDO
198 ENDDO
199! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
200! CONTRACT FULL FIELDS TO THINNED FIELDS
201 ELSEIF(idir.EQ.-1) THEN
202 DO k=1,km
203 is1=0
204 is2=0
205 DO j=1,igdtmpl_full(9)
206 im1=opt_pts(j)
207 im2=igdtmpl_full(8)
208 rat2=float(im2-1)/float(im1-1)
209 DO i=1,im1
210 x2=(i-1)*rat2+1
211 ia=int(x2)
212 ia=min(max(ia,1),im2-1)
213 ib=ia+1
214 wa=ib-x2
215 wb=x2-ia
216 data_thin(is1+i,k)=wa*data_full(is2+ia,k)+wb*data_full(is2+ib,k)
217 ENDDO
218 is1=is1+im1
219 is2=is2+im2
220 ENDDO
221 ENDDO
222 ENDIF
223 ENDIF
224! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
225 END SUBROUTINE ipxwafs
subroutine ipxwafs(idir, numpts_thin, numpts_full, km, num_opt, opt_pts, igdtlen, igdtmpl_thin, data_thin, igdtmpl_full, data_full, iret)
Expand or contract wafs grids.
Definition ipxwafs.F90:84