NCEPLIBS-g2c  1.8.0
specpack.c
Go to the documentation of this file.
1 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <math.h>
10 #include "grib2_int.h"
11 
32 void
33 specpack(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:33
Header file with internal function prototypes NCEPLIBS-g2c library.
void mkieee(float *a, g2int *rieee, g2int num)
This subroutine stores 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)
This subroutine packs up a data field using the simple packing algorithm as defined in the GRIB2 docu...
Definition: simpack.c:34
void specpack(float *fld, g2int ndpts, g2int JJ, g2int KK, g2int MM, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This subroutine packs a spectral data field using the complex packing algorithm for spherical harmoni...
Definition: specpack.c:33