NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
misspack.c
Go to the documentation of this file.
1
7#include "grib2_int.h"
8#include <math.h>
9#include <stdlib.h>
10
42void
43misspack(float *fld, g2int ndpts, g2int idrsnum, g2int *idrstmpl,
44 unsigned char *cpack, g2int *lcpack)
45{
46 g2int *ifld, *ifldmiss, *jfld;
47 g2int *jmin, *jmax, *lbit;
48 static g2int zero = 0;
49 g2int *gref, *gwidth, *glen;
50 g2int glength, grpwidth;
51 g2int i, n, iofst, imin, ival1, ival2, isd, minsd, nbitsd = 0;
52 g2int nbitsgref, left, iwmax, ngwidthref, nbitsgwidth, ilmax;
53 g2int nglenref, nglenlast, nbitsglen;
54 g2int j, missopt, nonmiss, itemp, maxorig, nbitorig, miss1, miss2;
55 g2int ngroups, ng, num0, num1, num2;
56 g2int imax, lg, mtemp, ier, igmax;
57 g2int kfildo, minpk, inc, maxgrps, ibit, jbit, kbit, novref, lbitref;
58 float rmissp, rmisss, bscale, dscale, rmin, temp;
59 static float alog2 = ALOG2; /* ln(2.0) */
60 static g2int one = 1;
61
62 bscale = int_power(2.0, -idrstmpl[1]);
63 dscale = int_power(10.0, idrstmpl[2]);
64 missopt = idrstmpl[6];
65 if (missopt != 1 && missopt != 2)
66 {
67 printf("misspack: Unrecognized option.\n");
68 *lcpack = -1;
69 return;
70 }
71 else
72 { /* Get missing values */
73 rdieee(idrstmpl + 7, &rmissp, 1);
74 if (missopt == 2)
75 rdieee(idrstmpl + 8, &rmisss, 1);
76 }
77
78 /* Find min value of non-missing values in the data, AND set up
79 * missing value mapping of the field. */
80 ifldmiss = calloc(ndpts, sizeof(g2int));
81 rmin = 1E+37;
82 if (missopt == 1)
83 { /* Primary missing value only */
84 for (j = 0; j < ndpts; j++)
85 {
86 if (fld[j] == rmissp)
87 {
88 ifldmiss[j] = 1;
89 }
90 else
91 {
92 ifldmiss[j] = 0;
93 if (fld[j] < rmin)
94 rmin = fld[j];
95 }
96 }
97 }
98 if (missopt == 2)
99 { /* Primary and secondary missing values */
100 for (j = 0; j < ndpts; j++)
101 {
102 if (fld[j] == rmissp)
103 {
104 ifldmiss[j] = 1;
105 }
106 else if (fld[j] == rmisss)
107 {
108 ifldmiss[j] = 2;
109 }
110 else
111 {
112 ifldmiss[j] = 0;
113 if (fld[j] < rmin)
114 rmin = fld[j];
115 }
116 }
117 }
118
119 /* Allocate work arrays: Note: -ifldmiss[j],j = 0,ndpts-1 is a map
120 * of original field indicating which of the original data values
121 * are primary missing (1), sencondary missing (2) or non-missing
122 * (0). -jfld[j],j = 0,nonmiss-1 is a subarray of just the
123 * non-missing values from the original field. */
124 iofst = 0;
125 ifld = calloc(ndpts, sizeof(g2int));
126 jfld = calloc(ndpts, sizeof(g2int));
127 gref = calloc(ndpts, sizeof(g2int));
128 gwidth = calloc(ndpts, sizeof(g2int));
129 glen = calloc(ndpts, sizeof(g2int));
130
131 /* Scale original data. */
132 nonmiss = 0;
133 if (idrstmpl[1] == 0)
134 { /* No binary scaling */
135 imin = (g2int)rint(rmin * dscale);
136 rmin = (float)imin;
137 for (j = 0; j < ndpts; j++)
138 {
139 if (ifldmiss[j] == 0)
140 {
141 jfld[nonmiss] = (g2int)rint(fld[j] * dscale) - imin;
142 nonmiss++;
143 }
144 }
145 }
146 else
147 { /* Use binary scaling factor */
148 rmin = rmin * dscale;
149 for (j = 0; j < ndpts; j++)
150 {
151 if (ifldmiss[j] == 0)
152 {
153 jfld[nonmiss] = (g2int)rint(((fld[j] * dscale) - rmin) * bscale);
154 nonmiss++;
155 }
156 }
157 }
158
159 /* Calculate Spatial differences, if using DRS Template 5.3. */
160 if (idrsnum == 3)
161 { /* spatial differences */
162 if (idrstmpl[16] != 1 && idrstmpl[16] != 2)
163 idrstmpl[16] = 2;
164 if (idrstmpl[16] == 1)
165 { /* first order */
166 ival1 = jfld[0];
167 for (j = nonmiss - 1; j > 0; j--)
168 jfld[j] = jfld[j] - jfld[j - 1];
169 jfld[0] = 0;
170 }
171 else if (idrstmpl[16] == 2)
172 { /* second order */
173 ival1 = jfld[0];
174 ival2 = jfld[1];
175 for (j = nonmiss - 1; j > 1; j--)
176 jfld[j] = jfld[j] - (2 * jfld[j - 1]) + jfld[j - 2];
177 jfld[0] = 0;
178 jfld[1] = 0;
179 }
180
181 /* Subtract min value from spatial diff field. */
182 isd = idrstmpl[16];
183 minsd = jfld[isd];
184 for (j = isd; j < nonmiss; j++)
185 if (jfld[j] < minsd)
186 minsd = jfld[j];
187 for (j = isd; j < nonmiss; j++)
188 jfld[j] = jfld[j] - minsd;
189
190 /* Find num of bits need to store minsd and add 1 extra bit to
191 * indicate sign. */
192 temp = log((double)(abs(minsd) + 1)) / alog2;
193 nbitsd = (g2int)ceil(temp) + 1;
194
195 /* Find num of bits need to store ifld[0] (and ifld[1] if
196 * using 2nd order differencing). */
197 maxorig = ival1;
198 if (idrstmpl[16] == 2 && ival2 > ival1)
199 maxorig = ival2;
200 temp = log((double)(maxorig + 1)) / alog2;
201 nbitorig = (g2int)ceil(temp) + 1;
202 if (nbitorig > nbitsd)
203 nbitsd = nbitorig;
204
205 /* increase number of bits to even multiple of 8 (octet) */
206 if (nbitsd % 8)
207 nbitsd = nbitsd + (8 - (nbitsd % 8));
208
209 /* Store extra spatial differencing info into the packed data
210 * section. */
211 if (nbitsd != 0)
212 {
213 /* pack first original value */
214 if (ival1 >= 0)
215 {
216 sbit(cpack, &ival1, iofst, nbitsd);
217 iofst = iofst + nbitsd;
218 }
219 else
220 {
221 sbit(cpack, &one, iofst, 1);
222 iofst = iofst + 1;
223 itemp = abs(ival1);
224 sbit(cpack, &itemp, iofst, nbitsd - 1);
225 iofst = iofst + nbitsd - 1;
226 }
227 if (idrstmpl[16] == 2)
228 {
229 /* pack second original value */
230 if (ival2 >= 0)
231 {
232 sbit(cpack, &ival2, iofst, nbitsd);
233 iofst = iofst + nbitsd;
234 }
235 else
236 {
237 sbit(cpack, &one, iofst, 1);
238 iofst = iofst + 1;
239 itemp = abs(ival2);
240 sbit(cpack, &itemp, iofst, nbitsd - 1);
241 iofst = iofst + nbitsd - 1;
242 }
243 }
244 /* pack overall min of spatial differences */
245 if (minsd >= 0)
246 {
247 sbit(cpack, &minsd, iofst, nbitsd);
248 iofst = iofst + nbitsd;
249 }
250 else
251 {
252 sbit(cpack, &one, iofst, 1);
253 iofst = iofst + 1;
254 itemp = abs(minsd);
255 sbit(cpack, &itemp, iofst, nbitsd - 1);
256 iofst = iofst + nbitsd - 1;
257 }
258 }
259 } /* end of spatial diff section */
260
261 /* Expand non-missing data values to original grid. */
262 miss1 = jfld[0];
263 for (j = 0; j < nonmiss; j++)
264 if (jfld[j] < miss1)
265 miss1 = jfld[j];
266 miss1--;
267 miss2 = miss1 - 1;
268 n = 0;
269 for (j = 0; j < ndpts; j++)
270 {
271 if (ifldmiss[j] == 0)
272 {
273 ifld[j] = jfld[n];
274 n++;
275 }
276 else if (ifldmiss[j] == 1)
277 {
278 ifld[j] = miss1;
279 }
280 else if (ifldmiss[j] == 2)
281 {
282 ifld[j] = miss2;
283 }
284 }
285
286 /* Determine Groups to be used. Use Dr. Glahn's algorithm for
287 * determining grouping. */
288 kfildo = 6;
289 minpk = 10;
290 inc = 1;
291 maxgrps = (ndpts / minpk) + 1;
292 jmin = calloc(maxgrps, sizeof(g2int));
293 jmax = calloc(maxgrps, sizeof(g2int));
294 lbit = calloc(maxgrps, sizeof(g2int));
295 pack_gp(&kfildo, ifld, &ndpts, &missopt, &minpk, &inc, &miss1, &miss2,
296 jmin, jmax, lbit, glen, &maxgrps, &ngroups, &ibit, &jbit,
297 &kbit, &novref, &lbitref, &ier);
298 for (ng = 0; ng < ngroups; ng++)
299 glen[ng] = glen[ng] + novref;
300 free(jmin);
301 free(jmax);
302 free(lbit);
303
304 /* For each group, find the group's reference value (min) and the
305 * number of bits needed to hold the remaining values. */
306 n = 0;
307 for (ng = 0; ng < ngroups; ng++)
308 {
309 /* how many of each type? */
310 num0 = num1 = num2 = 0;
311 for (j = n; j < n + glen[ng]; j++)
312 {
313 if (ifldmiss[j] == 0)
314 num0++;
315 if (ifldmiss[j] == 1)
316 num1++;
317 if (ifldmiss[j] == 2)
318 num2++;
319 }
320 if (num0 == 0)
321 { /* all missing values */
322 if (num1 == 0)
323 { /* all secondary missing */
324 gref[ng] = -2;
325 gwidth[ng] = 0;
326 }
327 else if (num2 == 0)
328 { /* all primary missing */
329 gref[ng] = -1;
330 gwidth[ng] = 0;
331 }
332 else
333 { /* both primary and secondary */
334 gref[ng] = 0;
335 gwidth[ng] = 1;
336 }
337 }
338 else
339 { /* contains some non-missing data */
340 /* find max and min values of group */
341 gref[ng] = 2147483647;
342 imax = -2147483647;
343 j = n;
344 for (lg = 0; lg < glen[ng]; lg++)
345 {
346 if (ifldmiss[j] == 0)
347 {
348 if (ifld[j] < gref[ng])
349 gref[ng] = ifld[j];
350 if (ifld[j] > imax)
351 imax = ifld[j];
352 }
353 j++;
354 }
355 if (missopt == 1)
356 imax = imax + 1;
357 if (missopt == 2)
358 imax = imax + 2;
359 /* calc num of bits needed to hold data */
360 if (gref[ng] != imax)
361 {
362 temp = log((double)(imax - gref[ng] + 1)) / alog2;
363 gwidth[ng] = (g2int)ceil(temp);
364 }
365 else
366 {
367 gwidth[ng] = 0;
368 }
369 }
370 /* Subtract min from data */
371 j = n;
372 mtemp = (g2int)int_power(2., gwidth[ng]);
373 for (lg = 0; lg < glen[ng]; lg++)
374 {
375 if (ifldmiss[j] == 0) /* non-missing */
376 ifld[j] = ifld[j] - gref[ng];
377 else if (ifldmiss[j] == 1) /* primary missing */
378 ifld[j] = mtemp - 1;
379 else if (ifldmiss[j] == 2) /* secondary missing */
380 ifld[j] = mtemp - 2;
381 j++;
382 }
383 /* increment fld array counter */
384 n = n + glen[ng];
385 }
386
387 /* Find max of the group references and calc num of bits needed to
388 * pack each groups reference value, then pack up group reference
389 * values. */
390 igmax = gref[0];
391 for (j = 1; j < ngroups; j++)
392 if (gref[j] > igmax)
393 igmax = gref[j];
394 if (missopt == 1)
395 igmax = igmax + 1;
396 if (missopt == 2)
397 igmax = igmax + 2;
398 if (igmax != 0)
399 {
400 temp = log((double)(igmax + 1)) / alog2;
401 nbitsgref = (g2int)ceil(temp);
402 /* reset the ref values of any "missing only" groups. */
403 mtemp = (g2int)int_power(2., nbitsgref);
404 for (j = 0; j < ngroups; j++)
405 {
406 if (gref[j] == -1)
407 gref[j] = mtemp - 1;
408 if (gref[j] == -2)
409 gref[j] = mtemp - 2;
410 }
411 sbits(cpack, gref, iofst, nbitsgref, 0, ngroups);
412 itemp = nbitsgref * ngroups;
413 iofst = iofst + itemp;
414 /* Pad last octet with Zeros, if necessary. */
415 if ((itemp % 8) != 0)
416 {
417 left = 8 - (itemp % 8);
418 sbit(cpack, &zero, iofst, left);
419 iofst = iofst + left;
420 }
421 }
422 else
423 {
424 nbitsgref = 0;
425 }
426
427 /* Find max/min of the group widths and calc num of bits needed to
428 * pack each groups width value, then pack up group width
429 * values. */
430 iwmax = gwidth[0];
431 ngwidthref = gwidth[0];
432 for (j = 1; j < ngroups; j++)
433 {
434 if (gwidth[j] > iwmax)
435 iwmax = gwidth[j];
436 if (gwidth[j] < ngwidthref)
437 ngwidthref = gwidth[j];
438 }
439 if (iwmax != ngwidthref)
440 {
441 temp = log((double)(iwmax - ngwidthref + 1)) / alog2;
442 nbitsgwidth = (g2int)ceil(temp);
443 for (i = 0; i < ngroups; i++)
444 gwidth[i] = gwidth[i] - ngwidthref;
445 sbits(cpack, gwidth, iofst, nbitsgwidth, 0, ngroups);
446 itemp = nbitsgwidth * ngroups;
447 iofst = iofst + itemp;
448 /* Pad last octet with Zeros, if necessary. */
449 if ((itemp % 8) != 0)
450 {
451 left = 8 - (itemp % 8);
452 sbit(cpack, &zero, iofst, left);
453 iofst = iofst + left;
454 }
455 }
456 else
457 {
458 nbitsgwidth = 0;
459 for (i = 0; i < ngroups; i++)
460 gwidth[i] = 0;
461 }
462
463 /* Find max/min of the group lengths and calc num of bits needed
464 * to pack each groups length value, then pack up group length
465 * values. */
466 ilmax = glen[0];
467 nglenref = glen[0];
468 for (j = 1; j < ngroups - 1; j++)
469 {
470 if (glen[j] > ilmax)
471 ilmax = glen[j];
472 if (glen[j] < nglenref)
473 nglenref = glen[j];
474 }
475 nglenlast = glen[ngroups - 1];
476 if (ilmax != nglenref)
477 {
478 temp = log((double)(ilmax - nglenref + 1)) / alog2;
479 nbitsglen = (g2int)ceil(temp);
480 for (i = 0; i < ngroups - 1; i++)
481 glen[i] = glen[i] - nglenref;
482 sbits(cpack, glen, iofst, nbitsglen, 0, ngroups);
483 itemp = nbitsglen * ngroups;
484 iofst = iofst + itemp;
485 /* Pad last octet with Zeros, if necessary. */
486 if ((itemp % 8) != 0)
487 {
488 left = 8 - (itemp % 8);
489 sbit(cpack, &zero, iofst, left);
490 iofst = iofst + left;
491 }
492 }
493 else
494 {
495 nbitsglen = 0;
496 for (i = 0; i < ngroups; i++)
497 glen[i] = 0;
498 }
499
500 /* For each group, pack data values. */
501 n = 0;
502 for (ng = 0; ng < ngroups; ng++)
503 {
504 glength = glen[ng] + nglenref;
505 if (ng == (ngroups - 1))
506 glength = nglenlast;
507 grpwidth = gwidth[ng] + ngwidthref;
508 if (grpwidth != 0)
509 {
510 sbits(cpack, ifld + n, iofst, grpwidth, 0, glength);
511 iofst = iofst + (grpwidth * glength);
512 }
513 n = n + glength;
514 }
515
516 /* Pad last octet with Zeros, if necessary, */
517 if ((iofst % 8) != 0)
518 {
519 left = 8 - (iofst % 8);
520 sbit(cpack, &zero, iofst, left);
521 iofst = iofst + left;
522 }
523 *lcpack = iofst / 8;
524
525 if (ifld)
526 free(ifld);
527 if (jfld)
528 free(jfld);
529 if (ifldmiss)
530 free(ifldmiss);
531 if (gref)
532 free(gref);
533 if (gwidth)
534 free(gwidth);
535 if (glen)
536 free(glen);
537
538 /* Fill in ref value and number of bits in Template 5.2. */
539 mkieee(&rmin, idrstmpl, 1); /* ensure reference value is IEEE format */
540 idrstmpl[3] = nbitsgref;
541 idrstmpl[4] = 0; /* original data were reals */
542 idrstmpl[5] = 1; /* general group splitting */
543 idrstmpl[9] = ngroups; /* Number of groups */
544 idrstmpl[10] = ngwidthref; /* reference for group widths */
545 idrstmpl[11] = nbitsgwidth; /* num bits used for group widths */
546 idrstmpl[12] = nglenref; /* Reference for group lengths */
547 idrstmpl[13] = 1; /* length increment for group lengths */
548 idrstmpl[14] = nglenlast; /* True length of last group */
549 idrstmpl[15] = nbitsglen; /* num bits used for group lengths */
550 if (idrsnum == 3)
551 idrstmpl[17] = nbitsd / 8; /* num bits used for extra spatial differencing values */
552}
void sbits(unsigned char *out, g2int *in, g2int iskip, g2int nbits, g2int nskip, g2int n)
Store arbitrary size values into a packed bit string, taking the low order bits from each value in th...
Definition gbits.c:178
void sbit(unsigned char *out, g2int *in, g2int iskip, g2int nbits)
Store arbitrary size values into a packed bit string, taking the low order bits from each value in th...
Definition gbits.c:38
int64_t g2int
Long integer type.
Definition grib2.h:32
Header file with internal function prototypes NCEPLIBS-g2c library.
void mkieee(float *a, g2int *rieee, g2int num)
Store a list of real values in 32-bit IEEE floating point format.
Definition mkieee.c:22
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition int_power.c:18
int pack_gp(g2int *kfildo, g2int *ic, g2int *nxy, g2int *is523, g2int *minpk, g2int *inc, g2int *missp, g2int *misss, g2int *jmin, g2int *jmax, g2int *lbit, g2int *nov, g2int *ndg, g2int *lx, g2int *ibit, g2int *jbit, g2int *kbit, g2int *novref, g2int *lbitref, g2int *ier)
Determines groups of variable size, but at least of size minpk, the associated max (jmax( )) and min ...
Definition pack_gp.c:255
#define ALOG2
ln(2.0)
Definition grib2_int.h:30
void rdieee(g2int *rieee, float *a, g2int num)
Read a list of real values in 32-bit IEEE floating point format.
Definition rdieee.c:20
void misspack(float *fld, g2int ndpts, g2int idrsnum, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
Pack a data field using a complex packing algorithm.
Definition misspack.c:43