#include #include #include #include "grib2.h" void specpack(g2float *fld,g2int ndpts,g2int JJ,g2int KK,g2int MM, g2int *idrstmpl,unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: specpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-19 // // ABSTRACT: This subroutine packs a spectral data field using the complex // packing algorithm for spherical harmonic data as // defined in the GRIB2 Data Representation Template 5.51. // // PROGRAM HISTORY LOG: // 2002-12-19 Gilbert // // USAGE: void specpack(g2float *fld,g2int ndpts,g2int JJ,g2int KK,g2int MM, // g2int *idrstmpl,insigned char *cpack,g2int *lcpack) // INPUT ARGUMENT LIST: // fld[] - Contains the packed data values // ndpts - The number of data values to pack // JJ - J - pentagonal resolution parameter // KK - K - pentagonal resolution parameter // MM - M - pentagonal resolution parameter // idrstmpl - Contains the array of values for Data Representation // Template 5.51 // // OUTPUT ARGUMENT LIST: // cpack - The packed data field (character*1 array) // lcpack - length of packed field cpack(). // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld,tmplsim[5]; g2float bscale,dscale,*unpk,*tfld; g2float *pscale,tscale; g2int Js,Ks,Ms,Ts,Ns,inc,incu,incp,n,Nm,m,ipos; bscale = int_power(2.0,-idrstmpl[1]); dscale = int_power(10.0,idrstmpl[2]); Js=idrstmpl[5]; Ks=idrstmpl[6]; Ms=idrstmpl[7]; Ts=idrstmpl[8]; // // Calculate Laplacian scaling factors for each possible wave number. // pscale=(g2float *)malloc((JJ+MM)*sizeof(g2float)); tscale=(g2float)idrstmpl[4]*1E-6; for (n=Js;n<=JJ+MM;n++) pscale[n]=pow((g2float)(n*(n+1)),tscale); // // Separate spectral coeffs into two lists; one to contain unpacked // values within the sub-spectrum Js, Ks, Ms, and the other with values // outside of the sub-spectrum to be packed. // tfld=(g2float *)malloc(ndpts*sizeof(g2float)); unpk=(g2float *)malloc(ndpts*sizeof(g2float)); ifld=(g2int *)malloc(ndpts*sizeof(g2int)); inc=0; incu=0; incp=0; for (m=0;m<=MM;m++) { Nm=JJ; // triangular or trapezoidal if ( KK == JJ+MM ) Nm=JJ+m; // rhombodial Ns=Js; // triangular or trapezoidal if ( Ks == Js+Ms ) Ns=Js+m; // rhombodial for (n=m;n<=Nm;n++) { if (n<=Ns && m<=Ms) { // save unpacked value unpk[incu++]=fld[inc++]; // real part unpk[incu++]=fld[inc++]; // imaginary part } else { // Save value to be packed and scale // Laplacian scale factor tfld[incp++]=fld[inc++]*pscale[n]; // real part tfld[incp++]=fld[inc++]*pscale[n]; // imaginary part } } } free(pscale); if (incu != Ts) { printf("specpack: Incorrect number of unpacked values %d given:\n",(int)Ts); printf("specpack: Resetting idrstmpl[8] to %d\n",(int)incu); Ts=incu; } // // Add unpacked values to the packed data array in 32-bit IEEE format // mkieee(unpk,(g2int *)cpack,Ts); ipos=4*Ts; // // Scale and pack the rest of the coefficients // tmplsim[1]=idrstmpl[1]; tmplsim[2]=idrstmpl[2]; tmplsim[3]=idrstmpl[3]; simpack(tfld,ndpts-Ts,tmplsim,cpack+ipos,lcpack); *lcpack=(*lcpack)+ipos; // // Fill in Template 5.51 // idrstmpl[0]=tmplsim[0]; idrstmpl[1]=tmplsim[1]; idrstmpl[2]=tmplsim[2]; idrstmpl[3]=tmplsim[3]; idrstmpl[8]=Ts; idrstmpl[9]=1; // Unpacked spectral data is 32-bit IEEE free(tfld); free(unpk); free(ifld); return; }