NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
specpack.c
Go to the documentation of this file.
1
7#include "grib2_int.h"
8#include <math.h>
9#include <stdio.h>
10#include <stdlib.h>
11
32void
33specpack(float *fld, g2int ndpts, g2int JJ, g2int KK, g2int MM,
34 g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
35{
36
37 g2int *ifld, tmplsim[5];
38 float *unpk, *tfld;
39 float *pscale, tscale;
40 g2int Js, Ks, Ms, Ts, Ns, inc, incu, incp, n, Nm, m, ipos;
41
42 Js = idrstmpl[5];
43 Ks = idrstmpl[6];
44 Ms = idrstmpl[7];
45 Ts = idrstmpl[8];
46
47 /* Calculate Laplacian scaling factors for each possible wave
48 * number. */
49 pscale = malloc((JJ + MM + 1) * sizeof(float));
50 tscale = (float)idrstmpl[4] * 1E-6;
51 for (n = Js; n <= JJ + MM; n++)
52 pscale[n] = pow((float)(n * (n + 1)), tscale);
53
54 /* Separate spectral coeffs into two lists; one to contain
55 * unpacked values within the sub-spectrum Js, Ks, Ms, and the
56 * other with values outside of the sub-spectrum to be packed. */
57 tfld = malloc(ndpts * sizeof(float));
58 unpk = malloc(ndpts * sizeof(float));
59 ifld = malloc(ndpts * sizeof(g2int));
60 inc = 0;
61 incu = 0;
62 incp = 0;
63 for (m = 0; m <= MM; m++)
64 {
65 Nm = JJ; /* triangular or trapezoidal */
66 if (KK == JJ + MM)
67 Nm = JJ + m; /* rhombodial */
68 Ns = Js; /* triangular or trapezoidal */
69 if (Ks == Js + Ms)
70 Ns = Js + m; /* rhombodial */
71 for (n = m; n <= Nm; n++)
72 {
73 if (n <= Ns && m <= Ms)
74 { /* save unpacked value */
75 unpk[incu++] = fld[inc++]; /* real part */
76 unpk[incu++] = fld[inc++]; /* imaginary part */
77 }
78 else
79 { /* Save value to be packed and scale Laplacian scale factor. */
80 tfld[incp++] = fld[inc++] * pscale[n]; /* real part */
81 tfld[incp++] = fld[inc++] * pscale[n]; /* imaginary part */
82 }
83 }
84 }
85 free(pscale);
86
87 if (incu != Ts)
88 {
89 printf("specpack: Incorrect number of unpacked values %d given:\n", (int)Ts);
90 printf("specpack: Resetting idrstmpl[8] to %d\n", (int)incu);
91 Ts = incu;
92 }
93
94 /* Add unpacked values to the packed data array in 32-bit IEEE
95 * format. */
96 mkieee(unpk, (g2int *)cpack, Ts);
97 ipos = 4 * Ts;
98
99 /* Scale and pack the rest of the coefficients. */
100 tmplsim[1] = idrstmpl[1];
101 tmplsim[2] = idrstmpl[2];
102 tmplsim[3] = idrstmpl[3];
103 simpack(tfld, ndpts - Ts, tmplsim, cpack + ipos, lcpack);
104 *lcpack = (*lcpack) + ipos;
105
106 /* Fill in Template 5.51. */
107 idrstmpl[0] = tmplsim[0];
108 idrstmpl[1] = tmplsim[1];
109 idrstmpl[2] = tmplsim[2];
110 idrstmpl[3] = tmplsim[3];
111 idrstmpl[8] = Ts;
112 idrstmpl[9] = 1; /* Unpacked spectral data is 32-bit IEEE */
113
114 free(tfld);
115 free(unpk);
116 free(ifld);
117
118 return;
119}
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
void simpack(float *fld, g2int ndpts, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
Packs a data field using the simple packing algorithm.
Definition simpack.c:36
void specpack(float *fld, g2int ndpts, g2int JJ, g2int KK, g2int MM, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
Pack a spectral data field using the complex packing algorithm for spherical harmonic data as defined...
Definition specpack.c:33