1 : #include <stdlib.h>
2 : #include "grib2.h"
3 : #include "pdstemplates.h"
4 :
5 :
6 : static const struct pdstemplate templatespds[MAXPDSTEMP] = {
7 : // 4.0: Analysis or Forecast at Horizontal Level/Layer
8 : // at a point in time
9 : {0,15,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4} },
10 : // 4.1: Individual Ensemble Forecast at Horizontal Level/Layer
11 : // at a point in time
12 : {1,18,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1} },
13 : // 4.2: Derived Fcst based on whole Ensemble at Horiz Level/Layer
14 : // at a point in time
15 : {2,17,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1} },
16 : // 4.3: Derived Fcst based on Ensemble cluster over rectangular
17 : // area at Horiz Level/Layer at a point in time
18 : {3,31,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4} },
19 : // 4.4: Derived Fcst based on Ensemble cluster over circular
20 : // area at Horiz Level/Layer at a point in time
21 : {4,30,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4} },
22 : // 4.5: Probablility Forecast at Horiz Level/Layer
23 : // at a point in time
24 : {5,22,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4} },
25 : // 4.6: Percentile Forecast at Horiz Level/Layer
26 : // at a point in time
27 : {6,16,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1} },
28 : // 4.7: Analysis or Forecast Error at Horizontal Level/Layer
29 : // at a point in time
30 : {7,15,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4} },
31 : // 4.8: Ave/Accum/etc... at Horiz Level/Layer
32 : // in a time interval
33 : {8,29,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
34 : // 4.9: Probablility Forecast at Horiz Level/Layer
35 : // in a time interval
36 : {9,36,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
37 : // 4.10: Percentile Forecast at Horiz Level/Layer
38 : // in a time interval
39 : {10,30,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
40 : // 4.11: Individual Ensemble Forecast at Horizontal Level/Layer
41 : // in a time interval
42 : {11,32,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
43 : // 4.12: Derived Fcst based on whole Ensemble at Horiz Level/Layer
44 : // in a time interval
45 : {12,31,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
46 : // 4.13: Derived Fcst based on Ensemble cluster over rectangular
47 : // area at Horiz Level/Layer in a time interval
48 : {13,45,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
49 : // 4.14: Derived Fcst based on Ensemble cluster over circular
50 : // area at Horiz Level/Layer in a time interval
51 : {14,44,1, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} },
52 : // 4.20: Radar Product
53 : {20,19,0, {1,1,1,1,1,-4,4,2,4,2,1,1,1,1,1,2,1,3,2} },
54 : // 4.30: Satellite Product
55 : {30,5,1, {1,1,1,1,1} },
56 : // 4.254: CCITT IA5 Character String
57 : {254,3,0, {1,1,4} },
58 : // 4.1000: Cross section of analysis or forecast
59 : // at a point in time
60 : {1000,9,0, {1,1,1,1,1,2,1,1,4} },
61 : // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast
62 : // in a time interval
63 : {1001,16,0, {1,1,1,1,1,2,1,1,4,4,1,1,1,4,1,4} },
64 : // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast
65 : // over latitude or longitude
66 : {1002,15,0, {1,1,1,1,1,2,1,1,4,1,1,1,4,4,2} },
67 : // 4.1100: Hovmoller-type grid w/ no averaging or other
68 : // statistical processing
69 : {1100,15,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4} },
70 : // 4.1100: Hovmoller-type grid with averaging or other
71 : // statistical processing
72 : {1101,22,0, {1,1,1,1,1,2,1,1,4,1,-1,-4,1,-1,-4,4,1,1,1,4,1,4} }
73 :
74 : } ;
75 :
76 58 : const struct pdstemplate *get_templatespds()
77 : {
78 58 : return templatespds;
79 : }
80 :
81 8 : g2int getpdsindex(g2int number)
82 : ///$$$ SUBPROGRAM DOCUMENTATION BLOCK
83 : // . . . .
84 : // SUBPROGRAM: getpdsindex
85 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2001-06-28
86 : //
87 : // ABSTRACT: This function returns the index of specified Product
88 : // Definition Template 4.NN (NN=number) in array templates.
89 : //
90 : // PROGRAM HISTORY LOG:
91 : // 2001-06-28 Gilbert
92 : //
93 : // USAGE: index=getpdsindex(number)
94 : // INPUT ARGUMENT LIST:
95 : // number - NN, indicating the number of the Product Definition
96 : // Template 4.NN that is being requested.
97 : //
98 : // RETURNS: Index of PDT 4.NN in array templates, if template exists.
99 : // = -1, otherwise.
100 : //
101 : // REMARKS: None
102 : //
103 : // ATTRIBUTES:
104 : // LANGUAGE: C
105 : // MACHINE: IBM SP
106 : //
107 : //$$$/
108 : {
109 8 : g2int j,getpdsindex=-1;
110 :
111 72 : for (j=0;j<MAXPDSTEMP;j++) {
112 72 : if (number == templatespds[j].template_num) {
113 8 : getpdsindex=j;
114 8 : return(getpdsindex);
115 : }
116 : }
117 :
118 0 : return(getpdsindex);
119 : }
120 :
121 :
122 4 : xxtemplate *getpdstemplate(g2int number)
123 : ///$$$ SUBPROGRAM DOCUMENTATION BLOCK
124 : // . . . .
125 : // SUBPROGRAM: getpdstemplate
126 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-11
127 : //
128 : // ABSTRACT: This subroutine returns PDS template information for a
129 : // specified Product Definition Template 4.NN.
130 : // The number of entries in the template is returned along with a map
131 : // of the number of octets occupied by each entry. Also, a flag is
132 : // returned to indicate whether the template would need to be extended.
133 : //
134 : // PROGRAM HISTORY LOG:
135 : // 2000-05-11 Gilbert
136 : //
137 : // USAGE: CALL getpdstemplate(number)
138 : // INPUT ARGUMENT LIST:
139 : // number - NN, indicating the number of the Product Definition
140 : // Template 4.NN that is being requested.
141 : //
142 : // RETURN VALUE:
143 : // - Pointer to the returned template struct.
144 : // Returns NULL pointer, if template not found.
145 : //
146 : // REMARKS: None
147 : //
148 : // ATTRIBUTES:
149 : // LANGUAGE: C
150 : // MACHINE: IBM SP
151 : //
152 : //$$$/
153 : {
154 : g2int index;
155 : xxtemplate *new;
156 :
157 4 : index=getpdsindex(number);
158 :
159 4 : if (index != -1) {
160 4 : new=(xxtemplate *)malloc(sizeof(xxtemplate));
161 4 : new->type=4;
162 4 : new->num=templatespds[index].template_num;
163 4 : new->maplen=templatespds[index].mappdslen;
164 4 : new->needext=templatespds[index].needext;
165 4 : new->map=(g2int *)templatespds[index].mappds;
166 4 : new->extlen=0;
167 4 : new->ext=0; //NULL
168 4 : return(new);
169 : }
170 : else {
171 0 : printf("getpdstemplate: PDS Template 4.%d not defined.\n",(int)number);
172 0 : return(0); //NULL
173 : }
174 :
175 : return(0); //NULL
176 : }
177 :
178 :
179 2 : xxtemplate *extpdstemplate(g2int number,g2int *list)
180 : ///$$$ SUBPROGRAM DOCUMENTATION BLOCK
181 : // . . . .
182 : // SUBPROGRAM: extpdstemplate
183 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-11
184 : //
185 : // ABSTRACT: This subroutine generates the remaining octet map for a
186 : // given Product Definition Template, if required. Some Templates can
187 : // vary depending on data values given in an earlier part of the
188 : // Template, and it is necessary to know some of the earlier entry
189 : // values to generate the full octet map of the Template.
190 : //
191 : // PROGRAM HISTORY LOG:
192 : // 2000-05-11 Gilbert
193 : //
194 : // USAGE: CALL extpdstemplate(number,list)
195 : // INPUT ARGUMENT LIST:
196 : // number - NN, indicating the number of the Product Definition
197 : // Template 4.NN that is being requested.
198 : // list() - The list of values for each entry in the
199 : // the Product Definition Template 4.NN.
200 : //
201 : // RETURN VALUE:
202 : // - Pointer to the returned template struct.
203 : // Returns NULL pointer, if template not found.
204 : //
205 : // ATTRIBUTES:
206 : // LANGUAGE: C
207 : // MACHINE: IBM SP
208 : //
209 : //$$$
210 : {
211 : xxtemplate *new;
212 : g2int index,i,j,k,l;
213 :
214 2 : index=getpdsindex(number);
215 2 : if (index == -1) return(0);
216 :
217 2 : new=getpdstemplate(number);
218 :
219 2 : if ( ! new->needext ) return(new);
220 :
221 2 : if ( number == 3 ) {
222 0 : new->extlen=list[26];
223 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
224 0 : for (i=0;i<new->extlen;i++) {
225 0 : new->ext[i]=1;
226 : }
227 : }
228 2 : else if ( number == 4 ) {
229 0 : new->extlen=list[25];
230 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
231 0 : for (i=0;i<new->extlen;i++) {
232 0 : new->ext[i]=1;
233 : }
234 : }
235 2 : else if ( number == 8 ) {
236 2 : if ( list[21] > 1 ) {
237 0 : new->extlen=(list[21]-1)*6;
238 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
239 0 : for (j=2;j<=list[21];j++) {
240 0 : l=(j-2)*6;
241 0 : for (k=0;k<6;k++) {
242 0 : new->ext[l+k]=new->map[23+k];
243 : }
244 : }
245 : }
246 : }
247 0 : else if ( number == 9 ) {
248 0 : if ( list[28] > 1 ) {
249 0 : new->extlen=(list[28]-1)*6;
250 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
251 0 : for (j=2;j<=list[28];j++) {
252 0 : l=(j-2)*6;
253 0 : for (k=0;k<6;k++) {
254 0 : new->ext[l+k]=new->map[30+k];
255 : }
256 : }
257 : }
258 : }
259 0 : else if ( number == 10 ) {
260 0 : if ( list[22] > 1 ) {
261 0 : new->extlen=(list[22]-1)*6;
262 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
263 0 : for (j=2;j<=list[22];j++) {
264 0 : l=(j-2)*6;
265 0 : for (k=0;k<6;k++) {
266 0 : new->ext[l+k]=new->map[24+k];
267 : }
268 : }
269 : }
270 : }
271 0 : else if ( number == 11 ) {
272 0 : if ( list[24] > 1 ) {
273 0 : new->extlen=(list[24]-1)*6;
274 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
275 0 : for (j=2;j<=list[24];j++) {
276 0 : l=(j-2)*6;
277 0 : for (k=0;k<6;k++) {
278 0 : new->ext[l+k]=new->map[26+k];
279 : }
280 : }
281 : }
282 : }
283 0 : else if ( number == 12 ) {
284 0 : if ( list[23] > 1 ) {
285 0 : new->extlen=(list[23]-1)*6;
286 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
287 0 : for (j=2;j<=list[23];j++) {
288 0 : l=(j-2)*6;
289 0 : for (k=0;k<6;k++) {
290 0 : new->ext[l+k]=new->map[25+k];
291 : }
292 : }
293 : }
294 : }
295 0 : else if ( number == 13 ) {
296 0 : new->extlen=((list[37]-1)*6)+list[26];
297 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
298 0 : if ( list[37] > 1 ) {
299 0 : for (j=2;j<=list[37];j++) {
300 0 : l=(j-2)*6;
301 0 : for (k=0;k<6;k++) {
302 0 : new->ext[l+k]=new->map[39+k];
303 : }
304 : }
305 : }
306 0 : l=(list[37]-1)*6;
307 0 : if ( l<0 ) l=0;
308 0 : for (i=0;i<list[26];i++) {
309 0 : new->ext[l+i]=1;
310 : }
311 : }
312 0 : else if ( number == 14 ) {
313 0 : new->extlen=((list[36]-1)*6)+list[25];
314 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
315 0 : if ( list[36] > 1 ) {
316 0 : for (j=2;j<=list[36];j++) {
317 0 : l=(j-2)*6;
318 0 : for (k=0;k<6;k++) {
319 0 : new->ext[l+k]=new->map[38+k];
320 : }
321 : }
322 : }
323 0 : l=(list[36]-1)*6;
324 0 : if ( l<0 ) l=0;
325 0 : for (i=0;i<list[25];i++) {
326 0 : new->ext[l+i]=1;
327 : }
328 : }
329 0 : else if ( number == 30 ) {
330 0 : new->extlen=list[4]*5;
331 0 : new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
332 0 : for (i=0;i<list[4];i++) {
333 0 : l=i*5;
334 0 : new->ext[l]=2;
335 0 : new->ext[l+1]=2;
336 0 : new->ext[l+2]=1;
337 0 : new->ext[l+3]=1;
338 0 : new->ext[l+4]=4;
339 : }
340 : }
341 2 : return(new);
342 :
343 : }
344 :
|