/* * nccat: Concatenate two netCDF files. * * The NetCDF files must be identical in variable * names and dimensions. Each variable must have * a leftmost NC_UNLIMITED record dimension. * * Copyright (C) 1991 Charles R. Denham, Zydeco. * * Revision: Wednesday, February 1, 1995 3:21:53 PM * * Updated dimensional ints to longs. * NC_VERBOSE addition. * Removed version(). * */ # include # include # include # include "netcdf.h" /* # include "version.c" */ void usage(); int main ( int argc, char * argv[] ) { char dimname[MAX_NC_NAME]; char varname[MAX_NC_NAME]; int cdfid[2]; int varid[2]; int recdim[2], rec[2]; int dim[MAX_NC_DIMS]; long incoord[MAX_NC_DIMS], outcoord[MAX_NC_DIMS]; long incount[MAX_NC_DIMS], outcount[MAX_NC_DIMS]; int ndims, nvars, natts, ngatts; long size, nrecords; long instart, outstart; nc_type datatype[2]; int typelen; char * value; int status; int i, j, n; ncopts = NC_VERBOSE; /* Usage message if too few arguments. */ if (argc < 3) { /* version(); */ usage(); return (0); } /* Open the files. */ cdfid[0] = -1; cdfid[1] = -1; if (!strcmp(argv[1], argv[2])) { printf("Cannot concatenate a file to itself.\n"); } else if ((cdfid[0] = ncopen(argv[1], NC_WRITE)) == -1) { printf("ncopen failure.\n"); } else if ((cdfid[1] = ncopen(argv[2], NC_NOWRITE)) == -1) { printf("ncopen failure.\n"); } /* Inquire. */ else if ((status = ncinquire(cdfid[0], &ndims, &nvars, &ngatts, &recdim[0])) == -1) { printf("ncinquire failure.\n"); } else if ((status = ncinquire(cdfid[1], &ndims, &nvars, &ngatts, &recdim[1])) == -1) { printf("ncinquire failure.\n"); } /* Check for a dimension of NC_UNLIMITED. */ else if (recdim[0] == -1) { printf("No NC_UNLIMITED dimension exists.\n"); } else if (recdim[1] == -1) { printf("No NC_UNLIMITED dimension exists.\n"); } /* Transfer the variables. */ else { ncdiminq(cdfid[0], recdim[0], dimname, &size); outstart = size; instart = 0; ncdiminq(cdfid[1], recdim[1], dimname, &size); nrecords = size; printf("Records to transfer: %d\n", nrecords); printf("Records in result: %d\n", (nrecords + outstart)); printf("Variables to process: %d\n", nvars); for (i = 0; i < nvars; i++) { /* Input hyperslab. */ varid[1] = i; ncvarinq(cdfid[1], varid[1], varname, &datatype[1], &ndims, dim, &natts); status = -1; for (j = 0; j < ndims; j++) { ncdiminq(cdfid[1], dim[j], dimname, &size); incoord[j] = 0; incount[j] = size; if (dim[j] == recdim[1]) { rec[1] = j; incount[j] = 1; status = 0; } } /* Output hyperslab. */ if (!status) { if ((varid[0] = ncvarid(cdfid[0], varname)) != -1) { if ((status = ncvarinq(cdfid[0], varid[0], varname, &datatype[0], &ndims, dim, &natts)) != -1) { status = -1; for (j = 0; j < ndims; j++) { ncdiminq(cdfid[0], dim[j], dimname, &size); outcoord[j] = 0; outcount[j] = size; if (dim[j] == recdim[0]) { rec[0] = j; outcoord[j] = outstart; outcount[j] = 1; status = 0; } } } } } if (status) { printf("No record dimension: %s\n", varname); } else if (datatype[0] != datatype[1]) { printf("Incompatible data types: %s\n", varname); status = -1; } /* Allocate a transfer buffer. */ if (!status) { n = 1; for (j = 0; j < ndims; j++ ) { n *= incount[j]; } typelen = nctypelen(datatype[1]); value = (char *) malloc(typelen * n); /* Read/write with ncvarget/put. */ printf("\t%s; %d to go ...\n", varname, (nvars-i-1)); fflush(stdout); for (j = 0; j < nrecords; j++) { ncvarget(cdfid[1], varid[1], incoord, incount, value); ncvarput(cdfid[0], varid[0], outcoord, outcount, value); /* Prepare for next record. */ incoord[rec[1]]++; outcoord[rec[0]]++; } /* Deallocate the transfer buffer. */ free(value); } } } /* Close the files. */ for (i = 0; i < 2; i++) { if (cdfid[i] != -1) { if ((status = ncclose(cdfid[i])) == -1) { printf("ncclose failure.\n"); } } } return (0); } /* usage: Usage message for the program. */ void usage() { printf("%% Usage:\n"); printf("%% \tnccat infile1 infile2\n"); printf("%% \t\tinfile1: NetCDF filename for input and output.\n"); printf("%% \t\tinfile2: NetCDF filename for input.\n"); printf("%% Purpose:\n"); printf("%% \tConcatenate NetCDF record variables.\n"); printf("%% Example:\n"); printf("%% \tnccat foo.cdf bar.cdf\n"); }