/************************************************************************** * * 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; }