/**************************************************************************
*
* Filename: nc2sdr.c
*
* Author: Ian Adams, Naval Research Laboratory
* (ian DOT adams AT nrl DOT navy DOT mil)
*
* Date: 2008.01.23
*
* Description: Dump netCDF packed SDRs into WindSat binary format.
* This code will unpack netCDF files of WindSat SDRs and
* write out a binary file of the WindSat SDR record
* structure. The default is to extract both forward and
* aft swaths, to match previous SDR releases. The behavior
* can be changed by commenting the default "#define NDC"
* and uncommenting the #define directive for the desired
* swath.
*
* This code requires a C99 compliant compiler, and has been
* tested with Sun Studio 11 (Sparc and x64) and gcc 4.0.1
* (Mac OS X PPC and x86).
*
* Compile: Sun Studio
* cc -I/path/to/netcdf/header -L/path/to/netcdf/lib \
* nc2sdr.c -o nc2sdr -lnetcdf
*
* GCC
* gcc -std=c99 -I/path/to/netcdf/header -L/path/to/netcdf/lib \
* nc2sdr.c -o nc2sdr -lnetcdf
*
* Execute: nc2sdr
*
* **Disclaimer**
* The entire source has been provided in a single file for
* ease of download an compilation, despite the author's
* desire to partition the code into separate source files
* and headers. Also, this code will only write out data in
* native endian format. If there are any problems/issues,
* please direct all correspondence to the author.
*
* Revision
* history:
*
* 2009.01.05 I. Adams, Naval Research Laboratory
* Removed bug added during testing. Effect of bug resulted
* in an exception and program termination for any MidRes
* file, and empty 6.8-GHz Tbs for LowRes output.
*
**************************************************************************/
#include
#include
#include
#include
#include
/* Constants */
/* Dimensions*/
#define FWD (80)
#define AFT (41)
#define TDC (FWD + AFT)
#define VH (2)
#define VHUF (4)
#define COORD_3D (3)
#define NFREQ (5)
#define NCH (16)
#define RDIM3 (3)
#define RDIM6 (6)
#define ONE (1)
/* Fill values */
#define NOVAL (-9999)
#define NOVAL_B (-99)
#define NOVAL_Z (0)
#define NOVAL_LW (127)
#define NOVAL_S (7)
#define MAX_FILENAME_LEN (2048)
/* Error codes for not-netCDF errors. */
#define NDC_ERR (2) /* Incompatible number of downcounts. */
#define FA_ERR (3) /* Var not prepended by 'aft' or 'fore' (lazy check a/f) */
#define OUTFILE_OPEN_ERR (6) /* Failed to open output file. */
#define OUTFILE_WRITE_ERR (7) /* Failed to write all records to output file. */
/* Define portion (or all -- default) of swath to be read. */
#define NUMDC (TDC) /* Extract both fwd and aft swath. */
//#define NUMDC (FWD) /* Extract fwd swath. */
//#define NUMDC (AFT) /* Extract aft swath. */
/* Macros */
/* Error checking macro */
#define ISERR(err) ((err) != NC_NOERR)
#define DCERR(numdc) ((numdc != TDC) && (numdc != FWD) && (numdc != AFT))
/* SDR record type */
typedef struct SDR {
double jd2000;
float tbs[NCH];
float scanAngle;
float lat;
float lon;
float eia[NFREQ];
float pra[NFREQ];
float caa;
int16_t reserved1[6];
float rlos[COORD_3D];
float rsat[COORD_3D];
int16_t reserved2[6];
int32_t scan;
int8_t reserved3;
int8_t land2water;
int8_t water2land;
int8_t surfaceType;
int32_t errorFlag;
int32_t downcount;
int32_t sunGlint;
int32_t reserved4;
int16_t reserved5[3];
int16_t spare;
} SDRRecord;
#define recSize (sizeof(SDRRecord))
/* Function prototypes. */
/* Read and write functions*/
int32_t extract_scan_downcount(int32_t, size_t, size_t, SDRRecord *);
int32_t extract_sdrs(int32_t, size_t, size_t, SDRRecord *, int32_t);
int32_t write_records(char *, size_t, size_t, SDRRecord *);
/* Utility functions*/
int32_t init_records(size_t, size_t, SDRRecord *);
int32_t extract_float(int32_t, char *, size_t, size_t, size_t, float *);
int32_t extract_double(int32_t, char *, size_t, size_t, size_t, double *);
int32_t extract_int8(int32_t, char *, size_t, size_t, size_t, int8_t *);
int32_t extract_int32(int32_t, char *, size_t, size_t, size_t, int32_t *);
int main(int argc, const char *argv[]) {
char *inFilename;
char *outFilename;
int32_t ncstat, ncid, dimid, status, lr;
size_t nscan;
SDRRecord *sdrRecs;
if (argc != 3) {
printf("USAGE: nc2sdr \n");
return 0;
}
inFilename = (char *) argv[1];
outFilename = (char *) argv[2];
lr = check_lowres(inFilename);
/* Open netCDF file */
ncstat = nc_open(inFilename, NC_NOWRITE, &ncid);
if (ISERR(ncstat)) {
fprintf(stderr, "\nERROR: Failed to open %s.\n", inFilename);
return ncstat;
}
/* Retrieve number of scans */
ncstat = nc_inq_dimid(ncid, "nscan", &dimid);
if (ISERR(ncstat)) {
fprintf(stderr, "\nERROR: Failed to extract dimid for 'nscan'\n.");
return ncstat;
}
ncstat = nc_inq_dimlen(ncid, dimid, &nscan);
if (ISERR(ncstat)) {
fprintf(stderr, "\nERROR: Failed to extract dimemsion 'nscan'\n.");
return ncstat;
}
/* Allocate sdrRecs */
sdrRecs = (SDRRecord *) malloc(nscan * NUMDC * recSize);
if (sdrRecs == NULL) {
fprintf(stderr, "\nERROR: Failed to allocate sdrRecs.\n");
return ncstat;
}
/* Initialize records */
status = init_records(nscan, NUMDC, sdrRecs);
if (status != 0) {
fprintf(stderr, "\nERROR: Failed to initialize records.\n");
return status;
}
/* Retrieve variable data */
/* Get scans and downcounts first. */
ncstat = extract_scan_downcount(ncid, nscan, NUMDC, sdrRecs);
if (ISERR(ncstat)) {
fprintf(stderr, "\nERROR: Failed to extract scan and downcount.\n");
return ncstat;
}
/* Read scans. */
ncstat = extract_sdrs(ncid, nscan, NUMDC, sdrRecs, lr);
if (ISERR(ncstat)) {
fprintf(stderr, "\nERROR: Failed to extract SDRs.\n");
return ncstat;
}
/* Write records to binary file. */
status = write_records(outFilename, nscan, NUMDC, sdrRecs);
if (status != 0) {
fprintf(stderr, "\nERROR: Failed to write %s.\n", outFilename);
return status;
}
free(sdrRecs);
sdrRecs = NULL;
return NC_NOERR;
}
/* Function definitions. */
int32_t init_records(size_t nscan, size_t numdc, SDRRecord *sdrRecs) {
/* init_records: Initialize records by filling with appropriate novals.
Arguments:
nscan: number of scans
numdc: number of downcounts
sdrRecs: array of SDRRecord
*/
if (DCERR(numdc)) return NDC_ERR;
for (size_t nrec = 0; nrec < nscan*numdc; nrec++) {
sdrRecs[nrec].jd2000 = NOVAL;
for (size_t chnl = 0; chnl < NCH; chnl++)
sdrRecs[nrec].tbs[chnl] = NOVAL;
sdrRecs[nrec].lat = NOVAL;
sdrRecs[nrec].lon = NOVAL;
for (size_t nf = 0; nf < NFREQ; nf++)
sdrRecs[nrec].eia[nf] = NOVAL_Z;
for (size_t nf = 0; nf < NFREQ; nf++)
sdrRecs[nrec].pra[nf] = NOVAL_Z;
sdrRecs[nrec].caa = NOVAL;
for (size_t rd = 0; rd < RDIM6; rd++)
sdrRecs[nrec].reserved1[rd] = NOVAL;
for (size_t d3 = 0; d3 < COORD_3D; d3++)
sdrRecs[nrec].rlos[d3] = NOVAL;
for (size_t d3 = 0; d3 < COORD_3D; d3++)
sdrRecs[nrec].rsat[d3] = NOVAL;
for (size_t rd = 0; rd < RDIM6; rd++)
sdrRecs[nrec].reserved2[rd] = NOVAL;
sdrRecs[nrec].scan = NOVAL;
sdrRecs[nrec].reserved3 = NOVAL_B;
sdrRecs[nrec].land2water = NOVAL_LW;
sdrRecs[nrec].water2land = NOVAL_LW;
sdrRecs[nrec].surfaceType = NOVAL_S;
sdrRecs[nrec].errorFlag = NOVAL_Z;
sdrRecs[nrec].downcount = NOVAL;
sdrRecs[nrec].sunGlint = NOVAL;
sdrRecs[nrec].reserved4 = NOVAL;
for (size_t rd = 0; rd < RDIM3; rd++)
sdrRecs[nrec].reserved5[rd] = NOVAL;
sdrRecs[nrec].spare = NOVAL;
}
return 0;
}
int32_t extract_scan_downcount(int32_t ncid, size_t nscan,
size_t numdc, SDRRecord *sdrRecs) {
/* extract_scan_downcount: Extract scan and downcounts and fill
SDR structure.
Arguments:
ncid: netcdf file id
nscan: number of scans
numdc: number of downcounts
sdrRecs: array of SDRRecord
Return:
error code: See #define directives or netcdf.h for codes.
*/
int32_t varid, ncstat;
int32_t scan[nscan];
int16_t dcFwd[FWD];
int16_t dcAft[AFT];
size_t recnum;
size_t shift = 0;
if (DCERR(numdc)) return NDC_ERR;
/* Extract scan and downcount */
ncstat = nc_inq_varid(ncid, "scan", &varid);
if (ISERR(ncstat)) return ncstat;
ncstat = nc_get_var_int(ncid, varid, scan);
if (ISERR(ncstat)) return ncstat;
if ((numdc == FWD) || (numdc == TDC)) {
ncstat += nc_inq_varid(ncid, "fore_downcount", &varid);
if (ISERR(ncstat)) return ncstat;
ncstat += nc_get_var_short(ncid, varid, dcFwd);
if (ISERR(ncstat)) return ncstat;
}
if ((numdc == AFT) || (numdc == TDC)) {
ncstat += nc_inq_varid(ncid, "aft_downcount", &varid);
if (ISERR(ncstat)) return ncstat;
ncstat = nc_get_var_short(ncid, varid, dcAft);
if (ISERR(ncstat)) return ncstat;
}
if (numdc == TDC) shift = FWD;
/* Fill scan and downcount fields of structure. */
for (size_t sn = 0; sn < nscan; sn++) {
if ((numdc == FWD) || (numdc == TDC)) {
for (size_t dcf = 0; dcf < FWD; dcf++) {
recnum = sn * numdc + dcf;
sdrRecs[recnum].scan = scan[sn];
sdrRecs[recnum].downcount = dcFwd[dcf];
}
}
if ((numdc == AFT) || (numdc == TDC)) {
for (size_t dca = 0; dca < AFT; dca++) {
recnum = sn * numdc + dca + shift;
sdrRecs[recnum].scan = scan[sn];
sdrRecs[recnum].downcount = dcAft[dca];
}
}
}
return NC_NOERR;
}
int32_t extract_sdrs(int32_t ncid, size_t nscan,
size_t numdc, SDRRecord *sdrRecs, int32_t lr) {
/* extract_sdrs: Extract sdrs from netcdf file and fill SDR
structure.
Arguments:
ncid: netcdf file id
nscan: number of scans
numdc: number of downcounts
sdrRecs: array of SDRRecord
lr: low res flag (1 = low res, 0 = mid/high res)
Return:
error code: See #define directives or netcdf.h for codes.
*/
int32_t ncstat;
if (DCERR(numdc)) return NDC_ERR;
/* Forward portion of scan */
if ((numdc == FWD) || (numdc == TDC)) {
ncstat = extract_double(ncid, "fore_jd", nscan, numdc,
ONE, &sdrRecs[0].jd2000);
if (ISERR(ncstat)) return ncstat;
if (lr) {
ncstat = extract_float(ncid, "fore_rad068", nscan, numdc,
VH, &sdrRecs[0].tbs[0]);
if (ISERR(ncstat)) return ncstat;
}
ncstat = extract_float(ncid, "fore_rad107", nscan, numdc,
VHUF, &sdrRecs[0].tbs[2]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_rad187", nscan, numdc,
VHUF, &sdrRecs[0].tbs[6]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_rad238", nscan, numdc,
VH, &sdrRecs[0].tbs[10]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_rad370", nscan, numdc,
VHUF, &sdrRecs[0].tbs[12]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_scanangle", nscan, numdc,
ONE, &sdrRecs[0].scanAngle);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_lat", nscan, numdc,
ONE, &sdrRecs[0].lat);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_lon", nscan, numdc,
ONE, &sdrRecs[0].lon);
if (ISERR(ncstat)) return ncstat;
if (lr) {
ncstat = extract_float(ncid, "fore_eia068", nscan, numdc,
ONE, &sdrRecs[0].eia[0]);
if (ISERR(ncstat)) return ncstat;
}
ncstat = extract_float(ncid, "fore_eia107", nscan, numdc,
ONE, &sdrRecs[0].eia[1]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_eia187", nscan, numdc,
ONE, &sdrRecs[0].eia[2]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_eia238", nscan, numdc,
ONE, &sdrRecs[0].eia[3]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_eia370", nscan, numdc,
ONE, &sdrRecs[0].eia[4]);
if (ISERR(ncstat)) return ncstat;
if (lr) {
ncstat = extract_float(ncid, "fore_pra068", nscan, numdc,
ONE, &sdrRecs[0].pra[0]);
if (ISERR(ncstat)) return ncstat;
}
ncstat = extract_float(ncid, "fore_pra107", nscan, numdc,
ONE, &sdrRecs[0].pra[1]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_pra187", nscan, numdc,
ONE, &sdrRecs[0].pra[2]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_pra238", nscan, numdc,
ONE, &sdrRecs[0].pra[3]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_pra370", nscan, numdc,
ONE, &sdrRecs[0].pra[4]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_caa", nscan, numdc,
ONE, &sdrRecs[0].caa);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_rlos", nscan, numdc,
COORD_3D, &sdrRecs[0].rlos[0]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "fore_rsat", nscan, numdc,
COORD_3D, &sdrRecs[0].rsat[0]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int8(ncid, "fore_land2water", nscan, numdc,
ONE, &sdrRecs[0].land2water);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int8(ncid, "fore_water2land", nscan, numdc,
ONE, &sdrRecs[0].water2land);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int8(ncid, "fore_surface", nscan, numdc,
ONE, &sdrRecs[0].surfaceType);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int32(ncid, "fore_sdr_qc_flags", nscan, numdc,
ONE, &sdrRecs[0].errorFlag);
if (ISERR(ncstat)) return ncstat;
}
/* Aft portion of scan. */
if ((numdc == AFT) || (numdc == TDC)) {
ncstat = extract_double(ncid, "aft_jd", nscan, numdc,
ONE, &sdrRecs[0].jd2000);
if (ISERR(ncstat)) return ncstat;
if (lr) {
ncstat = extract_float(ncid, "aft_rad068", nscan, numdc,
VH, &sdrRecs[0].tbs[0]);
if (ISERR(ncstat)) return ncstat;
}
ncstat = extract_float(ncid, "aft_rad107", nscan, numdc,
VHUF, &sdrRecs[0].tbs[2]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_rad187", nscan, numdc,
VHUF, &sdrRecs[0].tbs[6]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_rad238", nscan, numdc,
VH, &sdrRecs[0].tbs[10]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_rad370", nscan, numdc,
VHUF, &sdrRecs[0].tbs[12]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_scanangle", nscan, numdc,
ONE, &sdrRecs[0].scanAngle);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_lat", nscan, numdc,
ONE, &sdrRecs[0].lat);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_lon", nscan, numdc,
ONE, &sdrRecs[0].lon);
if (ISERR(ncstat)) return ncstat;
if (lr) {
ncstat = extract_float(ncid, "aft_eia068", nscan, numdc,
ONE, &sdrRecs[0].eia[0]);
if (ISERR(ncstat)) return ncstat;
}
ncstat = extract_float(ncid, "aft_eia107", nscan, numdc,
ONE, &sdrRecs[0].eia[1]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_eia187", nscan, numdc,
ONE, &sdrRecs[0].eia[2]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_eia238", nscan, numdc,
ONE, &sdrRecs[0].eia[3]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_eia370", nscan, numdc,
ONE, &sdrRecs[0].eia[4]);
if (ISERR(ncstat)) return ncstat;
if (lr) {
ncstat = extract_float(ncid, "aft_pra068", nscan, numdc,
ONE, &sdrRecs[0].pra[0]);
if (ISERR(ncstat)) return ncstat;
}
ncstat = extract_float(ncid, "aft_pra107", nscan, numdc,
ONE, &sdrRecs[0].pra[1]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_pra187", nscan, numdc,
ONE, &sdrRecs[0].pra[2]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_pra238", nscan, numdc,
ONE, &sdrRecs[0].pra[3]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_pra370", nscan, numdc,
ONE, &sdrRecs[0].pra[4]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_caa", nscan, numdc,
ONE, &sdrRecs[0].caa);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_rlos", nscan, numdc,
COORD_3D, &sdrRecs[0].rlos[0]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_float(ncid, "aft_rsat", nscan, numdc,
COORD_3D, &sdrRecs[0].rsat[0]);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int8(ncid, "aft_land2water", nscan, numdc,
ONE, &sdrRecs[0].land2water);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int8(ncid, "aft_water2land", nscan, numdc,
ONE, &sdrRecs[0].water2land);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int8(ncid, "aft_surface", nscan, numdc,
ONE, &sdrRecs[0].surfaceType);
if (ISERR(ncstat)) return ncstat;
ncstat = extract_int32(ncid, "aft_sdr_qc_flags", nscan, numdc,
ONE, &sdrRecs[0].errorFlag);
if (ISERR(ncstat)) return ncstat;
}
return NC_NOERR;
}
int32_t write_records(char * fname, size_t nscan, size_t numdc, SDRRecord *sdrRecs) {
int32_t count, wcount;
FILE *fptr = NULL;
count = nscan * numdc;
fptr = fopen(fname, "wb");
if (fptr == NULL) return OUTFILE_OPEN_ERR;
wcount = fwrite(sdrRecs, recSize, count, fptr);
if (wcount != count) return OUTFILE_WRITE_ERR;
fclose(fptr);
return 0;
}
/* SDR field extraction functions. */
int32_t extract_float(int32_t ncid, char *field, size_t nscan,
size_t numdc, size_t dim3, float *recPtr) {
/* extract_float: Extract float field from netcdf file and fill SDR
structure.
Arguments:
ncid: netcdf file id
field: name of field to extract
nscan: number of scans
numdc: number of downcounts
dim3: size of third dimension (dim3 = 1 for 2d arrays)
recPtr: pointer to desired field of first record to fill
Return:
error code: See #define directives or netcdf.h for codes.
*/
const int32_t skip = recSize / sizeof(float);
int32_t varid, ncstat;
size_t recnum, fldrec;
int32_t ndc, shift, nc;
int32_t cs = 0;
if (DCERR(numdc)) return NDC_ERR;
if (numdc == TDC) cs = 1;
if (field[0] == 'a') {
ndc = AFT;
shift = cs * FWD;
nc = AFT + (FWD * cs);
}
else if (field[0] == 'f') {
ndc = FWD;
shift = 0;
nc = FWD + (AFT * cs);
}
else return FA_ERR;
float sdrField[nscan * ndc * dim3];
ncstat = nc_inq_varid(ncid, field, &varid);
if (ISERR(ncstat)) return ncstat;
ncstat = nc_get_var_float(ncid, varid, sdrField);
if (ISERR(ncstat)) return ncstat;
for (size_t ii = 0; ii < nscan; ii++) {
for (size_t jj = 0; jj < ndc; jj++) {
recnum = ii * nc + jj + shift;
for (size_t kk = 0; kk < dim3; kk++) {
fldrec = (ii * ndc * dim3) + (jj * dim3) + kk;
*(recPtr + (recnum * skip) + kk) = sdrField[fldrec];
}
}
}
return NC_NOERR;
}
int32_t extract_double(int32_t ncid, char *field, size_t nscan,
size_t numdc, size_t dim3, double *recPtr) {
/* extract_double: Extract float field from netcdf file and fill SDR
structure.
Arguments:
ncid: netcdf file id
field: name of field to extract
nscan: number of scans
numdc: number of downcounts
dim3: size of third dimension (dim3 = 1 for 2d arrays)
recPtr: pointer to desired field of first record to fill
Return:
error code: See #define directives or netcdf.h for codes.
*/
const int32_t skip = recSize / sizeof(double);
int32_t varid, ncstat;
size_t recnum, fldrec;
int32_t ndc, shift, nc;
int32_t cs = 0;
if (DCERR(numdc)) return NDC_ERR;
if (numdc == TDC) cs = 1;
if (field[0] == 'a') {
ndc = AFT;
shift = cs * FWD;
nc = AFT + (FWD * cs);
}
else if (field[0] == 'f') {
ndc = FWD;
shift = 0;
nc = FWD + (AFT * cs);
}
else return FA_ERR;
double sdrField[nscan * ndc * dim3];
ncstat = nc_inq_varid(ncid, field, &varid);
if (ISERR(ncstat)) return ncstat;
ncstat = nc_get_var_double(ncid, varid, sdrField);
if (ISERR(ncstat)) return ncstat;
for (size_t ii = 0; ii < nscan; ii++) {
for (size_t jj = 0; jj < ndc; jj++) {
recnum = ii * nc + jj + shift;
for (size_t kk = 0; kk < dim3; kk++) {
fldrec = (ii * ndc * dim3) + (jj * dim3) + kk;
*(recPtr + (recnum * skip) + kk) = sdrField[fldrec];
}
}
}
return NC_NOERR;
}
int32_t extract_int8(int32_t ncid, char *field, size_t nscan,
size_t numdc, size_t dim3, int8_t *recPtr) {
/* extract_byte: Extract float field from netcdf file and fill SDR
structure.
Arguments:
ncid: netcdf file id
field: name of field to extract
nscan: number of scans
numdc: number of downcounts
dim3: size of third dimension (dim3 = 1 for 2d arrays)
recPtr: pointer to desired field of first record to fill
Return:
error code: See #define directives or netcdf.h for codes.
*/
const int32_t skip = recSize / sizeof(int8_t);
int32_t varid, ncstat;
size_t recnum, fldrec;
int32_t ndc, shift, nc;
int32_t cs = 0;
if (DCERR(numdc)) return NDC_ERR;
if (numdc == TDC) cs = 1;
if (field[0] == 'a') {
ndc = AFT;
shift = cs * FWD;
nc = AFT + (FWD * cs);
}
else if (field[0] == 'f') {
ndc = FWD;
shift = 0;
nc = FWD + (AFT * cs);
}
else return FA_ERR;
int8_t sdrField[nscan * ndc * dim3];
ncstat = nc_inq_varid(ncid, field, &varid);
if (ISERR(ncstat)) return ncstat;
ncstat = nc_get_var_schar(ncid, varid, sdrField);
if (ISERR(ncstat)) return ncstat;
for (size_t ii = 0; ii < nscan; ii++) {
for (size_t jj = 0; jj < ndc; jj++) {
recnum = ii * nc + jj + shift;
for (size_t kk = 0; kk < dim3; kk++) {
fldrec = (ii * ndc * dim3) + (jj * dim3) + kk;
*(recPtr + (recnum * skip) + kk) = sdrField[fldrec];
}
}
}
return NC_NOERR;
}
int32_t extract_int32(int32_t ncid, char *field, size_t nscan,
size_t numdc, size_t dim3, int32_t *recPtr) {
/* extract_int32: Extract float field from netcdf file and fill SDR
structure.
Arguments:
ncid: netcdf file id
field: name of field to extract
nscan: number of scans
numdc: number of downcounts
dim3: size of third dimension (dim3 = 1 for 2d arrays)
recPtr: pointer to desired field of first record to fill
Return:
error code: See #define directives or netcdf.h for codes.
*/
const int32_t skip = recSize / sizeof(int32_t);
int32_t varid, ncstat;
size_t recnum, fldrec;
int32_t ndc, shift, nc;
int32_t cs = 0;
if (DCERR(numdc)) return NDC_ERR;
if (numdc == TDC) cs = 1;
if (field[0] == 'a') {
ndc = AFT;
shift = cs * FWD;
nc = AFT + (FWD * cs);
}
else if (field[0] == 'f') {
ndc = FWD;
shift = 0;
nc = FWD + (AFT * cs);
}
else return FA_ERR;
int32_t sdrField[nscan * ndc * dim3];
ncstat = nc_inq_varid(ncid, field, &varid);
if (ISERR(ncstat)) return ncstat;
ncstat = nc_get_var_int(ncid, varid, sdrField);
if (ISERR(ncstat)) return ncstat;
for (size_t ii = 0; ii < nscan; ii++) {
for (size_t jj = 0; jj < ndc; jj++) {
recnum = ii * nc + jj + shift;
for (size_t kk = 0; kk < dim3; kk++) {
fldrec = (ii * ndc * dim3) + (jj * dim3) + kk;
*(recPtr + (recnum * skip) + kk) = sdrField[fldrec];
}
}
}
return NC_NOERR;
}
int check_lowres(char *filename) {
/* Check input filename to see if file contains 6.8 GHz data. */
char buf[MAX_FILENAME_LEN];
char key[] = "sdrLowRes";
const int32_t nchar = sizeof(key) - 1;
sprintf(buf, "%s", filename);
for (size_t ii = 0; ii < MAX_FILENAME_LEN - nchar - 1; ii++) {
if (strncmp(key, &buf[ii], nchar) == 0) return 1;
}
return 0;
}