Re: [Netcdf] Re: nccat file

Folks,

Attached is nccat.c which came from Charles R. Denham, copyright
1991. 

David
-- 
David Ovens              e-mail: ovens@xxxxxxxxxxxxxxxxxxxx
Research Meteorologist    phone: (206) 685-8108
Dept of Atm. Sciences      plan: Real-time MM5 forecasting for the
Box 351640                        Pacific Northwest
University of Washington          http://www.atmos.washington.edu/mm5rt
Seattle, WA  98195               Weather Graphics and Loops
                                  http://www.atmos.washington.edu/~ovens/loops

On Thu, Oct 05, 2006 at 01:59:51PM +1300, Mark Hadfield wrote:
> araligin@xxxxxxxxxxxxx wrote:
> >Hi,
> >
> >  Can anybody tell me where I can find the nccat utility to download and 
> >  how to
> >install it. I don'nt have the function nccat on my system.
> >
> >
> >  
> I had never heard of nccat. Google found something of this name
> 
>    
> http://woodshole.er.usgs.gov/staffpages/cdenham/public_html/NCTools/nccat.c.txt
> 
> but it's rather old and superseded, I should think, but the ncrcat and 
> ncecat commands in the NCO (netCDF Operators) suite. See...
> 
>    http://nco.sourceforge.net/
> 
> NCO is exceedingly useful and can be made to run on pretty much any system.
> 
> -- 
> Mark Hadfield          "Kei puwaha te tai nei, Hoea tahi tatou"
> m.hadfield@xxxxxxxxxx
> National Institute for Water and Atmospheric Research (NIWA)
> 
> 

> _______________________________________________
> Netcdf mailing list
> Netcdf@xxxxxxxxxxxxxxxxxxxxxxxxx
> http://mail.atmos.washington.edu/cgi-bin/mailman/listinfo/netcdf
/* compile this with cc -o nccat nccat.c -I/usr/local/include -lnetcdf
 *      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");
        
}