NetCDF 4.9.3
Loading...
Searching...
No Matches
filter_example.c
Go to the documentation of this file.
1/*
2 Copyright 2018, UCAR/Unidata
3 See COPYRIGHT file for copying and redistribution conditions.
4*/
5/*
6This file is the same as nc_test4/test_filter.c
7*/
8
43
44#include "config.h"
45#include <stdio.h>
46#include <string.h>
47#include <stdlib.h>
48
49#include <hdf5.h>
50#include "netcdf.h"
51#include "netcdf_filter.h"
52
53/* The HDF assigned id for bzip compression */
54#define BZIP2_ID 307
55/* The compression level used in this example */
56#define BZIP2_LEVEL 9
57
58#define TESTFILE "bzip2.nc"
59
60/* Point at which we give up */
61#define MAXERRS 8
62
63#define NDIMS 4
64#define DIMSIZE 4
65#define CHUNKSIZE 4 /* Note: not the total size of the chunk, but size wrt a dim*/
66
67static size_t dimsize = DIMSIZE;
68static size_t chunksize = CHUNKSIZE;
69static size_t actualdims = NDIMS;
70
71static size_t actualproduct = 1; /* x-product over dim sizes */
72static size_t chunkproduct = 1; /* x-product over chunksizes */
73
74static size_t dims[NDIMS];
75static size_t chunks[NDIMS];
76
77static int nerrs = 0;
78
79static int ncid, varid;
80static int dimids[NDIMS];
81static float* array = NULL;
82static float* expected = NULL;
83static unsigned int filterid = 0;
84static unsigned int* params = NULL;
85
86/* Forward */
87static void init(int argc, char** argv);
88static int test_bzip2(void);
89static int verifychunks(void);
90
91#define ERRR do { \
92fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
93fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
94 __FILE__, __LINE__); \
95nerrs++;\
96} while (0)
97
98static int
99check(int err,int line)
100{
101 if(err != NC_NOERR) {
102 fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
103 fflush(stderr);
104 exit(1);
105 }
106 return NC_NOERR;
107}
108
109#define CHECK(x) check(x,__LINE__)
110
111/*
112Read the chunking information about the variable
113and verify that it is as expected.
114*/
115
116static int
117verifychunks(void)
118{
119 int i;
120 int store = -1;
121 size_t chunksizes[NDIMS];
122 memset(chunksizes,0,sizeof(chunksizes));
123 CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes));
124 /* Storate must be chunked, not contiguous */
125 if(store != NC_CHUNKED) {
126 fprintf(stderr,"bad chunk store\n");
127 return NC_ESTORAGE;
128 }
129 /* Chunk sizes must match our predefined set */
130 for(i=0;i<actualdims;i++) {
131 if(chunksizes[i] != chunks[i]) {
132 fprintf(stderr,"bad chunk size: %d\n",i);
133 return NC_EBADCHUNK;
134 }
135 }
136 return 1;
137}
138
139/*
140Compare the data we wrote against the data we read.
141*/
142
143static int
144compare(void)
145{
146 int errs = 0;
147 int i;
148 printf("data comparison: |array|=%ld\n",(unsigned long)actualproduct);
149 for(i=0;i<actualproduct;i++) {
150 if(expected[i] != array[i]) {
151 printf("mismatch: array[%d]=%f expected[%d]=%f\n",
152 i,array[i],i,expected[i]);
153 errs++;
154 if(errs >= MAXERRS)
155 break;
156 }
157 }
158 if(errs == 0)
159 printf("no data errors\n");
160 if(actualproduct <= 1)
161 return NC_EBADDIM;
162 return (errs == 0 ? NC_NOERR: NC_EINVAL);
163}
164
165/*
166Create the file, write it, then re-read for comparison.
167*/
168static int
169test_bzip2(void)
170{
171 int i;
172 unsigned int level = BZIP2_LEVEL;
173 size_t nparams = 0;
174
175 printf("\n*** Testing API: bzip2 compression.\n");
176
177 /* Clear the data array */
178 memset(array,0,sizeof(float)*actualproduct);
179
180 /* Create a file */
181 CHECK(nc_create(TESTFILE, NC_NETCDF4|NC_CLOBBER, &ncid));
182
183 /* Do not use fill for this file */
184 CHECK(nc_set_fill(ncid, NC_NOFILL, NULL));
185
186 /* Define the dimensions */
187 for(i=0;i<actualdims;i++) {
188 char dimname[1024];
189 snprintf(dimname,sizeof(dimname),"dim%d",i);
190 CHECK(nc_def_dim(ncid, dimname, dims[i], &dimids[i]));
191 }
192
193 /* Define the variable */
194 CHECK(nc_def_var(ncid, "var", NC_FLOAT, actualdims, dimids, &varid));
195
196 /* Set chunking on the variable */
197 CHECK(nc_def_var_chunking(ncid,varid,NC_CHUNKED,chunks));
198
199 /* Verify that chunking succeeded */
200 if(!verifychunks())
201 return NC_EINVAL;
202 /* Set bzip2 compression for the variable: takes one parameter == level */
203 CHECK(nc_def_var_filter(ncid,varid,BZIP2_ID,1,&level));
204
205 /* Read back the compression info and verify it */
206 level = 0;
207 CHECK(nc_inq_var_filter_info(ncid,varid,BZIP2_ID,&nparams,&level));
208 if(nparams != 1 || level != BZIP2_LEVEL) {
209 printf("test_filter: filter def/inq mismatch\n");
210 return NC_EFILTER;
211 }
212 /* Show the level */
213 printf("show parameters for bzip2: level=%u\n",level);
214 /* Show chunking */
215 printf("show chunks:");
216 for(i=0;i<actualdims;i++)
217 printf("%s%ld",(i==0?" chunks=":","),(unsigned long)chunks[i]);
218 printf("\n");
219
220 /* prepare to write */
221 CHECK(nc_enddef(ncid));
222
223 /* Fill in the array */
224 for(i=0;i<actualproduct;i++)
225 expected[i] = (float)i;
226
227 /* write array */
228 CHECK(nc_put_var(ncid,varid,expected));
229
230 /* Close file */
231 CHECK(nc_close(ncid));
232
233 /* Now re-open and verify */
234 printf("\n*** Testing API: bzip2 decompression.\n");
235
236 /* Clear the data array */
237 memset(array,0,sizeof(float)*actualproduct);
238
239 /* Open the file */
240 CHECK(nc_open(TESTFILE, NC_NOWRITE, &ncid));
241
242 /* Get the variable id */
243 CHECK(nc_inq_varid(ncid, "var", &varid));
244
245 /* Check the compression algorithm */
246 filterid = 0;
247 nparams = 0;
248 params = NULL;
249 CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,NULL));
250 if(filterid == 0) CHECK(NC_ENOFILTER); /* Not defined */
251 if(nparams > 0) {
252 params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
253 if(params == NULL)
254 return NC_ENOMEM;
255 CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
256 }
257 if(filterid != BZIP2_ID) {
258 printf("Bzip2 id mismatch: %d\n",filterid);
259 return NC_EFILTER;
260 }
261 if(nparams != 1 && params != NULL && params[0] != BZIP2_LEVEL) {
262 printf("Compression parameter mismatch\n");
263 return NC_EFILTER;
264 }
265
266 /* Verify chunking */
267 if(!verifychunks())
268 return 0;
269
270 /* Read the data */
271 CHECK(nc_get_var_float(ncid, varid, array));
272
273 /* Close the file */
274 CHECK(nc_close(ncid));
275 return (compare() == NC_NOERR ? 0 : 1);
276}
277
278/**************************************************/
279/* Utilities */
280
281static void
282init(int argc, char** argv)
283{
284 int i;
285 /* Setup various variables */
286 actualproduct = 1;
287 chunkproduct = 1;
288 for(i=0;i<NDIMS;i++) {
289 dims[i] = dimsize;
290 chunks[i] = chunksize;
291 if(i < actualdims) {
292 actualproduct *= dims[i];
293 chunkproduct *= chunks[i];
294 }
295 }
296 /* Allocate max size */
297 array = (float*)calloc(1,sizeof(float)*actualproduct);
298 expected = (float*)calloc(1,sizeof(float)*actualproduct);
299}
300
301/**************************************************/
302int
303main(int argc, char **argv)
304{
305 H5Eprint1(stderr);
306 init(argc,argv);
307 if(test_bzip2() != NC_NOERR) ERRR;
308 exit(nerrs > 0?1:0);
309}
310
EXTERNL int nc_close(int ncid)
Close an open netCDF dataset.
Definition dfile.c:1300
EXTERNL int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition dfile.c:398
EXTERNL int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition dfile.c:1474
EXTERNL int nc_enddef(int ncid)
Leave define mode.
Definition dfile.c:1027
EXTERNL int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
Definition dfile.c:664
EXTERNL int nc_def_dim(int ncid, const char *name, size_t len, int *idp)
Define a new dimension.
Definition ddim.c:121
EXTERNL const char * nc_strerror(int ncerr)
Given an error number, return an error message.
Definition derror.c:87
EXTERNL int nc_inq_varid(int ncid, const char *name, int *varidp)
Find the ID of a variable, from the name.
Definition dvarinq.c:60
EXTERNL int nc_put_var(int ncid, int varid, const void *op)
Write an entire variable with one call.
Definition dvarput.c:922
EXTERNL int nc_inq_var_filter_info(int ncid, int varid, unsigned int id, size_t *nparams, unsigned int *params)
Find the the param info about filter (if any) associated with a variable and with specified id.
Definition dfilter.c:95
EXTERNL int nc_inq_var_filter(int ncid, int varid, unsigned int *idp, size_t *nparams, unsigned int *params)
Find the first filter (if any) associated with a variable.
Definition dfilter.c:167
EXTERNL int nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp)
Get the storage and (for chunked variables) the chunksizes of a variable.
Definition dvarinq.c:466
EXTERNL int nc_def_var(int ncid, const char *name, nc_type xtype, int ndims, const int *dimidsp, int *varidp)
Define a new variable.
Definition dvar.c:214
EXTERNL int nc_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp)
Define storage and, if chunked storage is used, chunking parameters for a variable.
Definition dvar.c:729
Main header file for the C API.
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition netcdf.h:162
#define NC_EFILTER
Filter operation failed.
Definition netcdf.h:523
#define NC_CLOBBER
Destroy existing file.
Definition netcdf.h:138
#define NC_FLOAT
single precision floating point number
Definition netcdf.h:40
#define NC_NOWRITE
Set read-only access for nc_open().
Definition netcdf.h:135
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition netcdf.h:458
#define NC_CHUNKED
In HDF5 files you can set storage for each variable to be either contiguous or chunked,...
Definition netcdf.h:314
#define NC_ESTORAGE
Can't specify both contiguous and chunking.
Definition netcdf.h:516
#define NC_NOFILL
Argument to nc_set_fill() to turn off filling of data.
Definition netcdf.h:123
#define NC_EINVAL
Invalid Argument.
Definition netcdf.h:388
#define NC_NOERR
No Error.
Definition netcdf.h:378
EXTERNL int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int *parms)
Define a new variable filter Assumes HDF5 format using unsigned ints.
Definition dfilter.c:126
#define NC_EBADCHUNK
Bad chunksize.
Definition netcdf.h:517
#define NC_ENOFILTER
Filter not defined on variable.
Definition netcdf.h:527
#define NC_EBADDIM
Invalid dimension id or name.
Definition netcdf.h:421