1 | #include <stdio.h> |
---|
2 | #include <stdlib.h> |
---|
3 | #include "dprints.h" /* for dprints */ |
---|
4 | #include "gribfuncs.h" /* prototypes */ |
---|
5 | /* REVISION/MODIFICATION HISTORY: |
---|
6 | 03/07/94 written by Mugur Georgescu CSC, Monterey CA |
---|
7 | 02/01/96 modified by Steve Lowe SAIC, Monterey CA |
---|
8 | 06/18/96 modified by Alice T. Nakajima (ATN), SAIC, Monterey CA |
---|
9 | 01/22/98 ATN, MRY SAIC |
---|
10 | 04/22/98 ATN change requirement for using extensions. |
---|
11 | * |
---|
12 | ************************************************************************ |
---|
13 | * A. FUNCTION gribgetpds |
---|
14 | * Decode the Product Definition Section (PDS) from the provided |
---|
15 | * pointer location and store the info in the internal PDS structure. |
---|
16 | * |
---|
17 | * INTERFACE: |
---|
18 | * int gribgetpds (curr_ptr, pds, errmsg) |
---|
19 | * |
---|
20 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
21 | * (I) char *curr_ptr; pointer to first octet of PDS |
---|
22 | * (O) PDS_INPUT *pds; empty PDS structure to be filled |
---|
23 | * (O) char *errmsg; returned filled if error occurred |
---|
24 | * |
---|
25 | * RETURN CODE: |
---|
26 | * 0> Always, PDS info stored in Pds structure; |
---|
27 | ************************************************************************ |
---|
28 | */ |
---|
29 | int get_factor(int unit); |
---|
30 | #if PROTOTYPE_NEEDED |
---|
31 | int gribgetpds ( char *curr_ptr, PDS_INPUT *pds, char *errmsg) |
---|
32 | #else |
---|
33 | |
---|
34 | int gribgetpds ( curr_ptr, pds, errmsg) |
---|
35 | char *curr_ptr; |
---|
36 | PDS_INPUT *pds; |
---|
37 | char *errmsg; |
---|
38 | #endif |
---|
39 | { |
---|
40 | char *in = curr_ptr; /* pointer to the message */ |
---|
41 | unsigned long skip=0; /* bits to be skipped */ |
---|
42 | unsigned long something; /* value extracted from message */ |
---|
43 | int sign; /* sign + or - */ |
---|
44 | int unit; |
---|
45 | int P1, P2; |
---|
46 | |
---|
47 | DPRINT0 ("Entering gribgetpds()\n"); |
---|
48 | /* |
---|
49 | * |
---|
50 | * A.1 FUNCTION gbyte !3-byte PDS length |
---|
51 | */ |
---|
52 | gbyte(in,&something,&skip,24); |
---|
53 | DPRINT0 ("pds->uslength\n"); |
---|
54 | pds->uslength = (unsigned short) something; |
---|
55 | |
---|
56 | /* |
---|
57 | * |
---|
58 | * A.2 FUNCTION gbyte !parameter table version |
---|
59 | */ |
---|
60 | gbyte(in,&something,&skip,8); |
---|
61 | DPRINT0 ("pds->usParm_tbl\n"); |
---|
62 | pds->usParm_tbl = (unsigned short) something; |
---|
63 | |
---|
64 | /* |
---|
65 | * |
---|
66 | * A.3 FUNCTION gbyte !center identification |
---|
67 | */ |
---|
68 | gbyte(in,&something,&skip,8); |
---|
69 | DPRINT0 ("pds->usCenter_id\n"); |
---|
70 | pds->usCenter_id = (unsigned short) something; |
---|
71 | |
---|
72 | /* |
---|
73 | * |
---|
74 | * A.4 FUNCTION gbyte !generating process id |
---|
75 | */ |
---|
76 | gbyte(in,&something,&skip,8); |
---|
77 | DPRINT0 ("pds->usProc_id\n"); |
---|
78 | pds->usProc_id = (unsigned short) something; |
---|
79 | |
---|
80 | /* |
---|
81 | * |
---|
82 | * A.5 FUNCTION gbyte !grid identification |
---|
83 | */ |
---|
84 | gbyte(in,&something,&skip,8); |
---|
85 | DPRINT0 ("pds->usGrid_id\n"); |
---|
86 | pds->usGrid_id = (unsigned short) something; |
---|
87 | |
---|
88 | /* |
---|
89 | * |
---|
90 | * A.6 FUNCTION gbyte !flag of GDS, BMS presence |
---|
91 | */ |
---|
92 | gbyte(in,&something,&skip,8); |
---|
93 | DPRINT0 ("pds->usGds_bms_id\n"); |
---|
94 | pds->usGds_bms_id = (unsigned short) something; |
---|
95 | |
---|
96 | /* |
---|
97 | * |
---|
98 | * A.7 FUNCTION gbyte !parameter indicator and units |
---|
99 | */ |
---|
100 | gbyte(in,&something,&skip,8); |
---|
101 | DPRINT0 ("pds->usParm_id\n"); |
---|
102 | pds->usParm_id = (unsigned short) something; |
---|
103 | |
---|
104 | /* |
---|
105 | * |
---|
106 | * A.8 FUNCTION gbyte !level type indicator |
---|
107 | */ |
---|
108 | gbyte(in,&something,&skip,8); |
---|
109 | DPRINT0 ("pds->usLevel_id\n"); |
---|
110 | pds->usLevel_id = (unsigned short) something; |
---|
111 | |
---|
112 | /* switch on Level_id to determine if level or layer */ |
---|
113 | /* |
---|
114 | * |
---|
115 | * A.9 SWITCH (level_id) |
---|
116 | */ |
---|
117 | switch(pds->usLevel_id) |
---|
118 | { |
---|
119 | case 101: /* layer between two isobaric surfaces */ |
---|
120 | case 104: /* layer between two specified altitudes */ |
---|
121 | case 106: /* layer between two specified height levels above ground */ |
---|
122 | case 108: /* layer between two sigma levels */ |
---|
123 | case 110: /* layer between two hybrid levels */ |
---|
124 | case 112: /* layer between two depths below land surface */ |
---|
125 | case 114: /* layer between two isentropic levels */ |
---|
126 | case 121: /* layer between two isobaric surfaces (high precision) */ |
---|
127 | case 128: /* layer between two sigma levels (high precision) */ |
---|
128 | case 141: /* layer between two isobaric surfaces (mixed precision) */ |
---|
129 | /* |
---|
130 | * layer: |
---|
131 | * FUNCTION gbyte !top of layer |
---|
132 | * FUNCTION gbyte !bottom of layer |
---|
133 | */ |
---|
134 | gbyte(in,&something,&skip,8); |
---|
135 | DPRINT0 ("pds->usHeight1\n"); |
---|
136 | pds->usHeight1 = (unsigned short) something; /* top layer */ |
---|
137 | gbyte(in,&something,&skip,8); |
---|
138 | DPRINT0 ("pds->usHeight2\n"); |
---|
139 | pds->usHeight2 = (unsigned short) something; /* bottom layer */ |
---|
140 | break; |
---|
141 | |
---|
142 | default: /* all others (levels) */ |
---|
143 | /* |
---|
144 | * default: !assume a level |
---|
145 | * FUNCTION gbyte !level value |
---|
146 | * SET Height2 to ZERO |
---|
147 | */ |
---|
148 | gbyte(in,&something,&skip,16); |
---|
149 | DPRINT0 ("pds->usHeight1\n"); |
---|
150 | pds->usHeight1 = (unsigned short) something; |
---|
151 | pds->usHeight2 = 0.0; |
---|
152 | break; |
---|
153 | } |
---|
154 | /* |
---|
155 | * A.9 ENDSWITCH |
---|
156 | */ |
---|
157 | |
---|
158 | /* |
---|
159 | * |
---|
160 | * A.10 FUNCTION gbyte !year of Reference Data/Time |
---|
161 | */ |
---|
162 | gbyte(in,&something,&skip,8); |
---|
163 | DPRINT0 ("pds->usYear\n"); |
---|
164 | pds->usYear = (unsigned short) something; |
---|
165 | |
---|
166 | /* |
---|
167 | * |
---|
168 | * A.11 FUNCTION gbyte !month of Reference Data/Time |
---|
169 | */ |
---|
170 | gbyte(in,&something,&skip,8); |
---|
171 | DPRINT0 ("pds->usMonth\n"); |
---|
172 | pds->usMonth = (unsigned short) something; |
---|
173 | |
---|
174 | /* |
---|
175 | * |
---|
176 | * A.12 FUNCTION gbyte !day of Reference Data/Time |
---|
177 | */ |
---|
178 | gbyte(in,&something,&skip,8); |
---|
179 | DPRINT0 ("pds->usDay\n"); |
---|
180 | pds->usDay = (unsigned short) something; |
---|
181 | |
---|
182 | /* |
---|
183 | * |
---|
184 | * A.13 FUNCTION gbyte !hour of Reference Data/Time |
---|
185 | */ |
---|
186 | gbyte(in,&something,&skip,8); |
---|
187 | DPRINT0 ("pds->usHour\n"); |
---|
188 | pds->usHour = (unsigned short) something; |
---|
189 | |
---|
190 | /* |
---|
191 | * |
---|
192 | * A.14 FUNCTION gbyte !minute of Reference Data/Time |
---|
193 | */ |
---|
194 | gbyte(in,&something,&skip,8); |
---|
195 | DPRINT0 ("pds->usMinute\n"); |
---|
196 | pds->usMinute = (unsigned short) something; |
---|
197 | |
---|
198 | /* |
---|
199 | * |
---|
200 | * A.15 FUNCTION gbyte !forecast time unit |
---|
201 | */ |
---|
202 | gbyte(in,&something,&skip,8); |
---|
203 | DPRINT0 ("pds->usFcst_unit_id\n"); |
---|
204 | pds->usFcst_unit_id = (unsigned short) something; |
---|
205 | |
---|
206 | /* |
---|
207 | * |
---|
208 | * A.16 FUNCTION gbyte !forecast period 1 |
---|
209 | */ |
---|
210 | gbyte(in,&something,&skip,8); |
---|
211 | DPRINT0 ("pds->usP1\n"); |
---|
212 | pds->usP1 = (unsigned short) something; |
---|
213 | |
---|
214 | /* |
---|
215 | * |
---|
216 | * A.17 FUNCTION gbyte !forecast period 2 |
---|
217 | */ |
---|
218 | gbyte(in,&something,&skip,8); |
---|
219 | DPRINT0 ("pds->usP2\n"); |
---|
220 | pds->usP2 = (unsigned short) something; |
---|
221 | |
---|
222 | /* |
---|
223 | * |
---|
224 | * A.18 FUNCTION gbyte !time range indicator |
---|
225 | */ |
---|
226 | gbyte(in,&something,&skip,8); |
---|
227 | DPRINT0 ("pds->usTime_range\n"); |
---|
228 | pds->usTime_range = (unsigned short) something; |
---|
229 | |
---|
230 | /* |
---|
231 | * |
---|
232 | * A.19 FUNCTION gbyte !#included in average |
---|
233 | */ |
---|
234 | gbyte(in,&something,&skip,16); |
---|
235 | DPRINT0 ("pds->usTime_range_avg\n"); |
---|
236 | pds->usTime_range_avg = (unsigned short) something; |
---|
237 | |
---|
238 | /* |
---|
239 | * |
---|
240 | * A.20 FUNCTION gbyte !#missing from average |
---|
241 | */ |
---|
242 | gbyte(in,&something,&skip,8); |
---|
243 | DPRINT0 ("pds->usTime_range_mis\n"); |
---|
244 | pds->usTime_range_mis = (unsigned short) something; |
---|
245 | |
---|
246 | /* |
---|
247 | * |
---|
248 | * A.21 FUNCTION gbyte !century of Reference Data/Time |
---|
249 | */ |
---|
250 | gbyte(in,&something,&skip,8); |
---|
251 | DPRINT0 ("pds->usCentury\n"); |
---|
252 | pds->usCentury = (unsigned short) something; |
---|
253 | |
---|
254 | /* |
---|
255 | * |
---|
256 | * A.22 FUNCTION gbyte !originating Sub-Center (Oct 26) |
---|
257 | */ |
---|
258 | gbyte(in,&something,&skip,8); |
---|
259 | DPRINT0 ("pds->usCenter_sub (Oct 26)\n"); |
---|
260 | pds->usCenter_sub = (unsigned short) something; |
---|
261 | |
---|
262 | /* |
---|
263 | * |
---|
264 | * A.23 FUNCTION gbyte !decimal scale factor |
---|
265 | */ |
---|
266 | gbyte(in,&something,&skip,16); |
---|
267 | DPRINT0 ("Sign & pds->sDec_sc_fctr\n"); |
---|
268 | sign = (int)(something >> 15) & 1; /* sign bit*/ |
---|
269 | pds->sDec_sc_fctr = (short) (something) & 32767; /* Decimal sclfctr D */ |
---|
270 | if(sign) /* negative Dec. sclfctr*/ |
---|
271 | pds->sDec_sc_fctr = - pds->sDec_sc_fctr; /* multiply by -1 */ |
---|
272 | |
---|
273 | /* |
---|
274 | * This is the WSI extension for forecast time unit |
---|
275 | */ |
---|
276 | |
---|
277 | if (pds->usTime_range == 255) |
---|
278 | { |
---|
279 | |
---|
280 | /* Skip ahead to byte 41 */ |
---|
281 | skip += 96; |
---|
282 | |
---|
283 | /* Get forecast time unit for P1 from byte 41 */ |
---|
284 | gbyte(in,&something,&skip,8); |
---|
285 | unit = (unsigned short)something; |
---|
286 | |
---|
287 | /* Get P1 */ |
---|
288 | gbyte(in,&something,&skip,32); |
---|
289 | P1 = (unsigned int)something; |
---|
290 | pds->usP1 = get_factor(unit)*P1; |
---|
291 | |
---|
292 | /* Get forecast time unit for P2 from byte 46 */ |
---|
293 | gbyte(in,&something,&skip,8); |
---|
294 | unit = (unsigned short)something; |
---|
295 | |
---|
296 | /* Get P2 */ |
---|
297 | gbyte(in,&something,&skip,32); |
---|
298 | P2 = (unsigned int)something; |
---|
299 | pds->usP2 = get_factor(unit)*P2; |
---|
300 | |
---|
301 | /* Get Time Range Indicator */ |
---|
302 | gbyte(in,&something,&skip,8); |
---|
303 | pds->usTime_range = (unsigned short)something; |
---|
304 | |
---|
305 | /* |
---|
306 | * Set forecast time unit to seconds, since we've converted usP1 and usP2 |
---|
307 | * to seconds. |
---|
308 | */ |
---|
309 | pds->usFcst_unit_id = 254; |
---|
310 | } |
---|
311 | |
---|
312 | /* |
---|
313 | * A.26 DEBUG Print |
---|
314 | */ |
---|
315 | DPRINT0 ("Exiting gribgetpds(), status=0\n"); |
---|
316 | |
---|
317 | /* |
---|
318 | * |
---|
319 | * A.27 RETURN 0 !success |
---|
320 | */ |
---|
321 | return(0); |
---|
322 | /* |
---|
323 | * END OF FUNCTION |
---|
324 | * |
---|
325 | * |
---|
326 | */ |
---|
327 | } |
---|
328 | /***************************************************************************** |
---|
329 | * |
---|
330 | * returns the multiplication factor to convert grib forecast times to |
---|
331 | * seconds. |
---|
332 | * |
---|
333 | * Input: |
---|
334 | * unit_id - grib forecast unit id, from Table 4. |
---|
335 | * |
---|
336 | * Return: |
---|
337 | * conversion factor |
---|
338 | *****************************************************************************/ |
---|
339 | int get_factor(int unit) |
---|
340 | { |
---|
341 | int factor; |
---|
342 | |
---|
343 | switch (unit) { |
---|
344 | case 0: |
---|
345 | factor = 60; |
---|
346 | break; |
---|
347 | case 1: |
---|
348 | factor = 60*60; |
---|
349 | break; |
---|
350 | case 2: |
---|
351 | factor = 60*60*24; |
---|
352 | break; |
---|
353 | case 10: |
---|
354 | factor = 60*60*3; |
---|
355 | break; |
---|
356 | case 11: |
---|
357 | factor = 60*60*3; |
---|
358 | break; |
---|
359 | case 12: |
---|
360 | factor = 60*60*12; |
---|
361 | break; |
---|
362 | case 50: |
---|
363 | /* This is a WSI (non-standard) time unit of 5 minutes */ |
---|
364 | factor = 5*60; |
---|
365 | break; |
---|
366 | case 254: |
---|
367 | factor = 1; |
---|
368 | break; |
---|
369 | default: |
---|
370 | fprintf(stderr,"Invalid unit for forecast time: %d\n",unit); |
---|
371 | factor = 0; |
---|
372 | } |
---|
373 | return factor; |
---|
374 | } |
---|