1 /* This is part of the netCDF package. Copyright 2008 University
2    Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
3    conditions of use. See www.unidata.ucar.edu for more info.
4 
5    Create a test netCDF-4 file with compression, chunking, endianness
6    settings to test ncdump "-s" option for displaying special
7    attributes.
8 
9    $Id: tst_special_atts.c,v 1.12 2009/01/28 18:19:49 russ Exp $
10 */
11 
12 #include <nc_tests.h>
13 #include "err_macros.h"
14 #include <netcdf.h>
15 
16 #define FILE_NAME "tst_special_atts.nc"
17 #define DIM1_NAME "dim1"
18 #define DIM1_LEN  10
19 #define DIM2_NAME "dim2"
20 #define DIM2_LEN  20
21 #define DIM3_NAME "dim3"
22 #define DIM3_LEN  30
23 #define VAR1_NAME "var1"
24 #define VAR1_RANK 1
25 #define VAR2_NAME "var2"
26 #define VAR2_RANK 2
27 #define VAR3_NAME "var3"
28 #define VAR3_RANK 3
29 #define VAR4_NAME "var4"
30 #define VAR4_RANK 3
31 #define CHUNK1 (DIM1_LEN/2 + 1)
32 #define CHUNK2 (DIM2_LEN/3 + 1)
33 #define CHUNK3 (DIM3_LEN/4 + 1)
34 #define DEFLATE_LEVEL 2
35 #define COMPRESS 1
36 #define TYPE6_NAME "obs_t"
37 
38 int
main(int argc,char ** argv)39 main(int argc, char **argv)
40 {
41    int ncid;
42    int i, j, k, m;
43 
44    int dimids[VAR3_RANK];
45    int var1id, var2id, var3id, var4id, var5id;
46    size_t chunksizes[] = {CHUNK1, CHUNK2, CHUNK3};
47    int data1[DIM1_LEN];
48    int data1_in[DIM1_LEN];
49    int data2[DIM1_LEN][DIM2_LEN];
50    int data2_in[DIM1_LEN][DIM2_LEN];
51    int data3[DIM1_LEN][DIM2_LEN][DIM3_LEN];
52    int data3_in[DIM1_LEN][DIM2_LEN][DIM3_LEN];
53 
54    printf("\n*** Testing '-s' option for special attributes.\n");
55    printf("*** creating special attributes test file %s...", FILE_NAME);
56    if (nc_create(FILE_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR;
57 
58    /* Declare dimensions and variables */
59    if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
60    if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
61    if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
62    if (nc_def_var(ncid, VAR1_NAME, NC_INT, VAR1_RANK, dimids, &var1id)) ERR;
63    if (nc_def_var(ncid, VAR2_NAME, NC_INT, VAR2_RANK, dimids, &var2id)) ERR;
64    if (nc_def_var(ncid, VAR3_NAME, NC_INT, VAR3_RANK, dimids, &var3id)) ERR;
65    if (nc_def_var(ncid, VAR4_NAME, NC_INT, VAR4_RANK, dimids, &var4id)) ERR;
66    {
67 
68        typedef struct obs_t {
69 	   char day;
70 	   short elev;
71 	   int count;
72 	   float relhum;
73 	   double time;
74 	   unsigned char category;
75 	   unsigned short id;
76 	   unsigned int particularity;
77 	   long long attention_span;
78        } obs_t ;
79        nc_type typeid;
80 
81        /* Create a compound type. */
82        if (nc_def_compound(ncid, sizeof(obs_t), TYPE6_NAME, &typeid)) ERR;
83        if (nc_insert_compound(ncid, typeid, "day",
84 			      NC_COMPOUND_OFFSET(struct obs_t, day), NC_BYTE)) ERR;
85        if (nc_insert_compound(ncid, typeid, "elev",
86 			      NC_COMPOUND_OFFSET(struct obs_t, elev), NC_SHORT)) ERR;
87        if (nc_insert_compound(ncid, typeid, "count",
88 			      NC_COMPOUND_OFFSET(struct obs_t, count), NC_INT)) ERR;
89        if (nc_insert_compound(ncid, typeid, "relhum",
90 			      NC_COMPOUND_OFFSET(struct obs_t, relhum),
91 			      NC_FLOAT)) ERR;
92        if (nc_insert_compound(ncid, typeid, "time",
93 			      NC_COMPOUND_OFFSET(struct obs_t, time),
94 			      NC_DOUBLE)) ERR;
95        if (nc_insert_compound(ncid, typeid, "category",
96 			      NC_COMPOUND_OFFSET(struct obs_t, category),
97 			      NC_UBYTE)) ERR;
98        if (nc_insert_compound(ncid, typeid, "id",
99 			      NC_COMPOUND_OFFSET(struct obs_t, id),
100 			      NC_USHORT)) ERR;
101        if (nc_insert_compound(ncid, typeid, "particularity",
102 			      NC_COMPOUND_OFFSET(struct obs_t, particularity),
103 			      NC_UINT)) ERR;
104        if (nc_insert_compound(ncid, typeid, "attention_span",
105 			      NC_COMPOUND_OFFSET(struct obs_t, attention_span),
106 			      NC_INT64)) ERR;
107        /* create a variable of that compound type */
108        if (nc_def_var(ncid, "var5", typeid, VAR1_RANK, dimids, &var5id))
109 	   ERR;
110    }
111 
112    /* Specify contiguous storage and endianness explicitly for var1. */
113    if (nc_def_var_chunking(ncid, var1id, NC_CONTIGUOUS, NULL)) ERR;
114    if (nc_def_var_endian(ncid, var1id, NC_ENDIAN_LITTLE)) ERR;
115 
116    /* Specify chunking for var2, note only uses CHUNK1 and CHUNK2.
117       Also, specify using a checksum for this variable. */
118    if (nc_def_var_chunking(ncid, var2id, NC_CHUNKED, chunksizes)) ERR;
119    if (nc_def_var_fletcher32(ncid, var2id, NC_FLETCHER32)) ERR;
120    if (nc_def_var_endian(ncid, var2id, NC_ENDIAN_BIG)) ERR;
121 
122    /* Use compression but no shuffle for var3, also set to big endian */
123    if (nc_def_var_deflate(ncid, var3id, NC_NOSHUFFLE, COMPRESS, DEFLATE_LEVEL)) ERR;
124    if (nc_def_var_chunking(ncid, var3id, NC_CHUNKED, chunksizes)) ERR;
125    if (nc_def_var_endian(ncid, var3id, NC_ENDIAN_LITTLE)) ERR;
126 
127    /* Use compression, chunking, shuffle filter, and no-fill for var4 */
128    if (nc_def_var_deflate(ncid, var4id, NC_SHUFFLE, COMPRESS, DEFLATE_LEVEL)) ERR;
129    if (nc_def_var_chunking(ncid, var4id, NC_CHUNKED, chunksizes)) ERR;
130    if (nc_def_var_endian(ncid, var4id, NC_ENDIAN_LITTLE)) ERR;
131    if (nc_def_var_fill(ncid, var4id, NC_NOFILL, NULL)) ERR;
132 
133    /* Set endianness, chunking, checksums, shuffle, and compression for var5 */
134    if (nc_def_var_chunking(ncid, var5id, NC_CHUNKED, chunksizes)) ERR;
135    if (nc_def_var_fletcher32(ncid, var5id, NC_FLETCHER32)) ERR;
136    if (nc_def_var_deflate(ncid, var5id, NC_SHUFFLE, COMPRESS, DEFLATE_LEVEL)) ERR;
137 
138    if (nc_enddef(ncid)) ERR;
139 
140    /* Some artificial data */
141    m = 0;
142    for(i = 0; i < DIM1_LEN; i++) {
143        data1[i] = m++;
144        for(j = 0; j < DIM2_LEN; j++) {
145 	   data2[i][j] = m++;
146 	   for(k = 0; k < DIM3_LEN; k++) {
147 	       data3[i][j][k] = m++;
148 	   }
149        }
150    }
151 
152    /* Store data in each variable */
153    if(nc_put_var(ncid, var1id, &data1[0])) ERR;
154    if(nc_put_var(ncid, var2id, &data2[0][0])) ERR;
155    if(nc_put_var(ncid, var3id, &data3[0][0][0])) ERR;
156    if(nc_put_var(ncid, var4id, &data3[0][0][0])) ERR;
157 
158    if (nc_close(ncid)) ERR;
159 
160    /* Check it out. */
161    if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
162    if (nc_inq_varid(ncid, VAR1_NAME, &var1id)) ERR;
163    if (nc_inq_varid(ncid, VAR2_NAME, &var2id)) ERR;
164    if (nc_inq_varid(ncid, VAR3_NAME, &var3id)) ERR;
165    if (nc_inq_varid(ncid, VAR4_NAME, &var4id)) ERR;
166 
167    /* Check chunk sizes */
168    {
169        size_t chunks_in[VAR3_RANK];
170        if (nc_inq_var_chunking(ncid, var2id, NULL, chunks_in)) ERR;
171        for(i = 0; i < VAR2_RANK; i++)
172 	   if(chunks_in[i] != chunksizes[i]) ERR;
173        if (nc_inq_var_chunking(ncid, var3id, NULL, chunks_in)) ERR;
174        for(i = 0; i < VAR3_RANK; i++)
175 	   if(chunks_in[i] != chunksizes[i]) ERR;
176        if (nc_inq_var_chunking(ncid, var4id, NULL, chunks_in)) ERR;
177        for(i = 0; i < VAR4_RANK; i++)
178 	   if(chunks_in[i] != chunksizes[i]) ERR;
179    }
180    if(nc_get_var(ncid, var1id, &data1_in[0])) ERR;
181    for(i = 0; i < DIM1_LEN; i++)
182        if(data1_in[i] != data1[i]) ERR;
183 
184    if(nc_get_var(ncid, var2id, &data2_in[0][0])) ERR;
185    for(i = 0; i < DIM1_LEN; i++)
186        for(j = 0; j < DIM2_LEN; j++)
187 	   if(data2_in[i][j] != data2[i][j]) ERR;
188 
189    if(nc_get_var(ncid, var3id, &data3_in[0][0][0])) ERR;
190    for(i = 0; i < DIM1_LEN; i++)
191        for(j = 0; j < DIM2_LEN; j++)
192 	   for(k = 0; k < DIM3_LEN; k++)
193 	       if(data3_in[i][j][k] != data3[i][j][k]) ERR;
194 
195    if(nc_get_var(ncid, var4id, &data3_in[0][0][0])) ERR;
196    for(i = 0; i < DIM1_LEN; i++)
197        for(j = 0; j < DIM2_LEN; j++)
198 	   for(k = 0; k < DIM3_LEN; k++)
199 	       if(data3_in[i][j][k] != data3[i][j][k]) ERR;
200 
201    SUMMARIZE_ERR;
202    FINAL_RESULTS;
203 }
204