Here's a simple nccat routine that Chuck Denham
(cdenham@xxxxxxxxxxxxxxxxxx) wrote that I use
all the time.
--
Rich Signell | rsignell@xxxxxxxxxxxxxxxxxx
U.S. Geological Survey | (508) 457-2229 | FAX (508) 457-2310
Quissett Campus | "What you don't know CAN hurt you,
Woods Hole, MA 02543-1598 | only you won't know it. "
/*
* 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.
*
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "netcdf.h"
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];
int incoord[MAX_NC_DIMS], outcoord[MAX_NC_DIMS];
int incount[MAX_NC_DIMS], outcount[MAX_NC_DIMS];
int ndims, nvars, natts, ngatts;
int len, size, nrecords;
int instart, outstart;
nc_type datatype[2];
char * value;
int status;
int i, j, n;
/* Usage message if too few arguments. */
if (argc < 3) {
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");
return (-1);
}
else if ((cdfid[1] = ncopen(argv[2], NC_NOWRITE)) == -1) {
printf("ncopen failure.\n");
return (-1);
}
/* Inquire. */
else if ((status = ncinquire(cdfid[0],
&ndims, &nvars, &ngatts, &recdim[0])) == -1)
{
printf("ncinquire failure.\n");
return (-1);
}
else if ((status = ncinquire(cdfid[1],
&ndims, &nvars, &ngatts, &recdim[1])) == -1)
{
printf("ncinquire failure.\n");
return (-1);
}
/* 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) {
varid[0] = ncvarid(cdfid[0], varname);
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];
}
len = nctypelen(datatype[1]);
value = (char *) malloc(len * 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 (-1);
}
}
}
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 viables.\n");
printf("%% \tThe NetCDF files must be identical in variable\n");
printf("%% \tnames and dimensions. Each variable must have a\n");
printf("%% \tleftmost NC_UNLIMITED record dimension.\n");
printf("%% Example:\n");
printf("%% \tnccat foo.cdf bar.cdf\n");
}