[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[netCDF #PCB-933705]: Compound type example



Hi Gail,

> Good morning. I'm working on an application to write out a compound data
> type to netCDF4. My compound type is of the following form.
> 
> typedef struct
> {
> ushort county_id; /* county FIPS code */
> ushort year; /* year represented by planted/harvested
> acres
> and yield values */
> ubyte prac_code; /* harvest practice code */
> ushort planted_acres[NCROPS]; /* acres planted - per crop (not
> represented
> for hay/alfalfa) */
> ushort harvested_acres[NCROPS]; /* acres harvested - per crop */
> float yield[NCROPS]; /* yield - per crop */
> float percent_comp[NCROPS]; /* percent of composition */
> } crop_harvesting_acreage;
> 
> netcdf crop_attributes_1970_2009 {
> types:
> compound CROP_HARVESTING_ACREAGE {
> ushort county_id ;
> ushort year ;
> ubyte prac_code ;
> ushort planted_acres(29) ;
> ushort harvested_acres(29) ;
> float yield(29) ;
> float percent_comp(29) ;
> }; // CROP_HARVESTING_ACREAGE
> dimensions:
> npractices = 7 ;
> ncounty_ids = UNLIMITED ; // (10 currently)
> nyears = 40 ;
> ncrops = 29 ;
> variables:
> CROP_HARVESTING_ACREAGE crop_harvest(ncounty_ids, nyears,
> npractices) ;
> crop_harvest:long_name = "crop harvest attributes by
> county ID, year and practice" ;
> 
> The variable I'm trying to create has the following dimensions: unlimited,
> 40, 7. I'm writing this data out using nc_put_vara. It appears the
> output netCDF file has picked up my structure correctly, but I keep
> getting erroneous data in the output file. If I print the data out before
> I call nc_put_vara, the data is valid. I've even just tried to write out
> the data will all zeros, but each time there are a few fields that end up
> with incorrect values in the output file. I'm trying to write out a
> variable number of values for the unlimited dimension, but always 40 and 7
> values for the other two dimensions. I'm obviously doing something wrong
> due to the erroneous values in the output netCDF file. And, when I do
> have valid values, they are shifted down two fields in the output file
> .... after the first record is correct.
> 
> Would you happen to have an example of working with compound types and
> writing out variable numbers of values? All the examples I've seen have
> written the entire structure out at once.

The attached program ca2.c shows how this can be done for a smaller
ca.cdl file based on your example.

The ncgen utility helped generate this example, but the process of
generating it also uncovered a couple of ncgen bugs, so thanks for the
example!

--Russ


Russ Rew                                         UCAR Unidata Program
address@hidden                      http://www.unidata.ucar.edu



Ticket Details
===================
Ticket ID: PCB-933705
Department: Support netCDF
Priority: Normal
Status: Closed
netcdf ca2 {
types:
  compound CROP_HARVESTING_ACREAGE {
    ushort county_id ;
    ushort year ;
    ubyte prac_code ;
    ushort planted_acres(3) ;
    ushort harvested_acres(3) ;
    float yield(3) ;
    float percent_comp(3) ;
  }; // CROP_HARVESTING_ACREAGE
dimensions:
        npractices = 1 ;
        ncounty_ids = UNLIMITED ; // (2 currently)
        nyears = 2 ;
variables:
        CROP_HARVESTING_ACREAGE crop_harvest(ncounty_ids, nyears, npractices) ;
                crop_harvest:long_name = "crop harvest attributes by\ncounty 
ID, year and practice" ;
data:

 crop_harvest =
  
    {111, 2011, 13, {11, 12, 13}, {101, 102, 103}, {11.5, 12.5, 13.5}, {0.11, 
0.12, 0.13}},
  
    {222, 2011, 23, {21, 22, 23}, {201, 202, 203}, {21.5, 22.5, 23.5}, {0.21, 
0.22, 0.23}},
  
    {333, 2011, 33, {31, 32, 33}, {301, 302, 303}, {31.5, 32.5, 33.5}, {0.31, 
0.32, 0.33}},
  
    {444, 2011, 43, {41, 42, 43}, {401, 402, 403}, {41.5, 42.5, 43.5}, {0.41, 
0.42, 0.43}} ;
}
#include <stdio.h>
#include <stdlib.h>
#include <netcdf.h>


typedef struct CROP_HARVESTING_ACREAGE {
    unsigned short county_id;
    unsigned short year;
    unsigned char prac_code;
    unsigned short planted_acres[3];
    unsigned short harvested_acres[3];
    float yield[3];
    float percent_comp[3];
} CROP_HARVESTING_ACREAGE;



void
check_err(const int stat, const int line, const char *file) {
    if (stat != NC_NOERR) {
        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, 
nc_strerror(stat));
        fflush(stderr);
        exit(1);
    }
}

int
main() {/* create ca2.nc */

    int  stat;  /* return status */
    int  ncid;  /* netCDF id */

    /* group ids */
    int root_grp;

    /* type ids */
    int CROP_HARVESTING_ACREAGE_typ;

    /* dimension ids */
    int npractices_dim;
    int ncounty_ids_dim;
    int nyears_dim;

    /* dimension lengths */
    size_t npractices_len = 1;
    size_t ncounty_ids_len = NC_UNLIMITED;
    size_t nyears_len = 2;

    /* variable ids */
    int crop_harvest_id;

    /* rank (number of dimensions) for each variable */
#   define RANK_crop_harvest 3

    /* variable shapes */
    int crop_harvest_dims[RANK_crop_harvest];

    /* enter define mode */
    stat = nc_create("ca2.nc", NC_CLOBBER|NC_NETCDF4, &ncid);
    check_err(stat,__LINE__,__FILE__);
    root_grp = ncid;

    stat = nc_def_compound(root_grp, sizeof(CROP_HARVESTING_ACREAGE), 
"CROP_HARVESTING_ACREAGE", &CROP_HARVESTING_ACREAGE_typ);    
check_err(stat,__LINE__,__FILE__);
    {
    static int planted_acres_dims[1] = {
3};    static int harvested_acres_dims[1] = {
3};    static int yield_dims[1] = {
3};    static int percent_comp_dims[1] = {
3};    stat = nc_insert_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, 
"county_id", NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,county_id), NC_USHORT); 
   check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, "year", 
NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,year), NC_USHORT);    
check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, 
"prac_code", NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,prac_code), NC_UBYTE);  
  check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_array_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, 
"planted_acres", NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,planted_acres), 
NC_USHORT, 1, planted_acres_dims);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_array_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, 
"harvested_acres", NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,harvested_acres), 
NC_USHORT, 1, harvested_acres_dims);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_array_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, 
"yield", NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,yield), NC_FLOAT, 1, 
yield_dims);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_array_compound(root_grp, CROP_HARVESTING_ACREAGE_typ, 
"percent_comp", NC_COMPOUND_OFFSET(CROP_HARVESTING_ACREAGE,percent_comp), 
NC_FLOAT, 1, percent_comp_dims);    check_err(stat,__LINE__,__FILE__);
    }


    /* define dimensions */
    stat = nc_def_dim(root_grp, "npractices", npractices_len, &npractices_dim);
    check_err(stat,__LINE__,__FILE__);
    stat = nc_def_dim(root_grp, "ncounty_ids", ncounty_ids_len, 
&ncounty_ids_dim);
    check_err(stat,__LINE__,__FILE__);
    stat = nc_def_dim(root_grp, "nyears", nyears_len, &nyears_dim);
    check_err(stat,__LINE__,__FILE__);

    /* define variables */

    crop_harvest_dims[0] = ncounty_ids_dim;
    crop_harvest_dims[1] = nyears_dim;
    crop_harvest_dims[2] = npractices_dim;
    stat = nc_def_var(root_grp, "crop_harvest", CROP_HARVESTING_ACREAGE_typ, 
RANK_crop_harvest, crop_harvest_dims, &crop_harvest_id);
    check_err(stat,__LINE__,__FILE__);

    /* assign per-variable attributes */
    { /* long_name */
    stat = nc_put_att_text(root_grp, crop_harvest_id, "long_name", 55, "crop 
harvest attributes by\ncounty ID, year and practice");
    check_err(stat,__LINE__,__FILE__);
    }


    /* leave define mode */
    stat = nc_enddef (root_grp);
    check_err(stat,__LINE__,__FILE__);

    /* assign variable data */
    {
    CROP_HARVESTING_ACREAGE crop_harvest_data[4] = {{111, 2011, 13, 11, 12, 13, 
101, 102, 103, 11.5, 12.5, 13.5, 0.11, 0.12, 0.13}, {222, 2011, 23, 21, 22, 23, 
201, 202, 203, 21.5, 22.5, 23.5, 0.21, 0.22, 0.23}, {333, 2011, 33, 31, 32, 33, 
301, 302, 303, 31.5, 32.5, 33.5, 0.31, 0.32, 0.33}, {444, 2011, 43, 41, 42, 43, 
401, 402, 403, 41.5, 42.5, 43.5, 0.41, 0.42, 0.43}} ;
    size_t crop_harvest_startset[3] = {0, 0, 0} ;
    size_t crop_harvest_countset[3] = {2, 2, 1} ;
    stat = nc_put_vara(root_grp, crop_harvest_id, crop_harvest_startset, 
crop_harvest_countset, crop_harvest_data);
    check_err(stat,__LINE__,__FILE__);
    }


    stat = nc_close(root_grp);
    check_err(stat,__LINE__,__FILE__);
    return 0;
}