21 #include "chunkspec.h"
27 #define snprintf _snprintf
34 #define COPY_BUFFER_SIZE (5000000)
35 #define COPY_CHUNKCACHE_PREEMPTION (1.0f)
36 #define SAME_AS_INPUT (-1)
37 #define CHUNK_THRESHOLD (8192)
40 #define NC_CLASSIC_MODEL 0x0100
45 static int option_kind = SAME_AS_INPUT;
46 static int option_deflate_level = -1;
48 static int option_fix_unlimdims = 0;
49 static char* option_chunkspec = 0;
50 static size_t option_copy_buffer_size = COPY_BUFFER_SIZE;
51 static size_t option_chunk_cache_size = CHUNK_CACHE_SIZE;
52 static size_t option_chunk_cache_nelems = CHUNK_CACHE_NELEMS;
53 static int option_read_diskless = 0;
54 static int option_write_diskless = 0;
55 static int option_min_chunk_bytes = CHUNK_THRESHOLD;
58 static int option_nlgrps = 0;
60 static char** option_lgrps = 0;
62 static idnode_t* option_grpids = 0;
63 static bool_t option_grpstruct =
false;
64 static int option_nlvars = 0;
65 static char** option_lvars = 0;
67 static bool_t option_varstruct =
false;
68 static int option_compute_chunkcaches = 0;
74 get_grpid(
int igrp,
int parid,
int *ogrpp) {
81 stat = nc_inq_grp_parent(igrp, &inparid);
84 NC_CHECK(nc_inq_grpname(igrp, grpname));
85 NC_CHECK(nc_inq_grp_ncid(parid, grpname, &ogid));
98 val_size(
int grpid,
int varid) {
102 NC_CHECK(
nc_inq_type(grpid, vartype, NULL, &value_size));
111 nc_inq_parid(
int ncid,
const char *fullname,
int *locidp) {
112 char *parent = strdup(fullname);
118 last_slash = strrchr(parent,
'/');
119 if(last_slash == parent || last_slash == NULL) {
121 parent = strdup(slash);
125 NC_CHECK(nc_inq_grp_full_ncid(ncid, parent, locidp));
133 inq_var_chunksize(
int igrp,
int varid,
size_t* chunksizep) {
145 NC_CHECK(
nc_inq_type(igrp, vartype, NULL, &value_size));
148 chunksizes = (
size_t *) emalloc((ndims + 1) *
sizeof(size_t));
156 for(dim = 0; dim < ndims; dim++) {
157 prod *= chunksizes[dim];
170 inq_var_chunking_params(
int igrp,
int ivarid,
int ogrp,
int ovarid,
171 size_t* chunkcache_sizep,
172 size_t *chunkcache_nelemsp,
173 float * chunkcache_preemptionp)
177 size_t *ichunksizes, *ochunksizes;
179 int icontig = 1, ocontig = 1;
182 size_t prod, iprod, oprod;
184 *chunkcache_nelemsp = CHUNK_CACHE_NELEMS;
185 *chunkcache_sizep = CHUNK_CACHE_SIZE;
186 *chunkcache_preemptionp = COPY_CHUNKCACHE_PREEMPTION;
193 if(icontig == 1 && ocontig == 1) {
194 *chunkcache_nelemsp = 0;
195 *chunkcache_sizep = 0;
196 *chunkcache_preemptionp = 0;
201 NC_CHECK(
nc_inq_type(igrp, vartype, NULL, &value_size));
204 if(icontig == 0 && ocontig == 1) {
205 *chunkcache_nelemsp = 1;
206 *chunkcache_sizep = iprod;
207 *chunkcache_preemptionp = 1.0f;
211 ichunksizes = (
size_t *) emalloc((ndims + 1) *
sizeof(size_t));
215 for(dim = 1; dim < ndims; dim++) {
216 ichunksizes[dim] = dim;
223 ochunksizes = (
size_t *) emalloc((ndims + 1) *
sizeof(size_t));
228 for(dim = 0; dim < ndims; dim++) {
229 nelems += 1 + (ichunksizes[dim] - 1) / ochunksizes[dim];
230 iprod *= ichunksizes[dim];
231 oprod *= ochunksizes[dim];
233 prod = iprod + oprod * (nelems - 1);
234 *chunkcache_nelemsp = nelems;
235 *chunkcache_sizep = prod;
242 static int copy_type(
int igrp,
nc_type typeid,
int ogrp);
249 copy_vlen_type(
int igrp,
nc_type itype,
int ogrp)
260 NC_CHECK(
nc_inq_vlen(igrp, itype, name, &size, &ibasetype));
263 NC_CHECK(
nc_inq_type(igrp, ibasetype, basename, &basesize));
267 NC_CHECK(copy_type(igrp, ibasetype, ogrp));
273 NC_CHECK(
nc_def_vlen(ogrp, name, obasetype, &vlen_type));
282 copy_opaque_type(
int igrp,
nc_type itype,
int ogrp)
299 copy_enum_type(
int igrp,
nc_type itype,
int ogrp)
309 NC_CHECK(
nc_inq_enum(igrp, itype, name, &basetype, &basesize, &nmembers));
310 NC_CHECK(
nc_def_enum(ogrp, basetype, name, &otype));
311 for(i = 0; i < nmembers; i++) {
324 copy_compound_type(
int igrp,
nc_type itype,
int ogrp)
336 for (fid = 0; fid < nfields; fid++) {
347 NC_CHECK(
nc_inq_type(igrp, iftype, ftypename, NULL));
353 fdimsizes = (
int *) emalloc((fndims + 1) *
sizeof(int));
368 copy_type(
int igrp,
nc_type typeid,
int ogrp)
373 NC_CHECK(
nc_inq_user_type(igrp,
typeid, NULL, NULL, NULL, NULL, &type_class));
377 NC_CHECK(copy_vlen_type(igrp,
typeid, ogrp));
380 NC_CHECK(copy_opaque_type(igrp,
typeid, ogrp));
383 NC_CHECK(copy_enum_type(igrp,
typeid, ogrp));
386 NC_CHECK(copy_compound_type(igrp,
typeid, ogrp));
399 copy_groups(
int iroot,
int oroot)
407 NC_CHECK(nc_inq_grps_full(iroot, &numgrps, NULL));
409 grpids = emalloc(numgrps *
sizeof(
int));
410 NC_CHECK(nc_inq_grps_full(iroot, NULL, grpids));
412 for(i = 1; i < numgrps; i++) {
416 int ogid = 0, oparid = 0, iparid = 0;
418 NC_CHECK(nc_inq_grpname(grpids[i], grpname));
419 if (option_grpstruct || group_wanted(grpids[i], option_nlgrps, option_grpids)) {
420 NC_CHECK(nc_inq_grpname_full(grpids[i], &len_name, NULL));
421 grpname_full = emalloc(len_name + 1);
422 NC_CHECK(nc_inq_grpname_full(grpids[i], &len_name, grpname_full));
424 NC_CHECK(nc_inq_parid(iroot, grpname_full, &iparid));
425 if (!option_grpstruct && !group_wanted(iparid, option_nlgrps, option_grpids)
426 && iparid != iroot) {
427 error(
"ERROR: trying to copy a group but not the parent: %s", grpname_full);
433 NC_CHECK(nc_inq_parid(oroot, grpname_full, &oparid));
434 NC_CHECK(nc_inq_grpname(grpids[i], grpname));
436 NC_CHECK(nc_def_grp(oparid, grpname, &ogid));
450 copy_types(
int igrp,
int ogrp)
459 NC_CHECK(nc_inq_typeids(igrp, &ntypes, NULL));
463 NC_CHECK(nc_inq_typeids(igrp, &ntypes, types));
464 for (i = 0; i < ntypes; i++) {
465 NC_CHECK(copy_type(igrp, types[i], ogrp));
471 NC_CHECK(nc_inq_grps(igrp, &numgrps, NULL));
473 grpids = (
int *)emalloc(
sizeof(
int) * numgrps);
474 NC_CHECK(nc_inq_grps(igrp, &numgrps, grpids));
475 for(i = 0; i < numgrps; i++) {
476 if (option_grpstruct || group_wanted(grpids[i], option_nlgrps, option_grpids)) {
481 NC_CHECK(get_grpid(grpids[i], ogrp, &ogid));
482 NC_CHECK(copy_types(grpids[i], ogid));
493 copy_var_specials(
int igrp,
int varid,
int ogrp,
int o_varid)
501 size_t *chunkp = (
size_t *) emalloc(ndims *
sizeof(
size_t));
502 int *dimids = (
int *) emalloc(ndims *
sizeof(
int));
505 size_t csprod = val_size(ogrp, o_varid);
506 int is_unlimited = 0;
510 for(idim = 0; idim < ndims; idim++) {
511 int idimid = dimids[idim];
512 int odimid = dimmap_odimid(idimid);
513 size_t chunksize = chunkspec_size(idimid);
515 chunkp[idim] = chunksize;
517 csprod *= chunkp[idim];
518 if(dimmap_ounlim(odimid))
525 if ((csprod < option_min_chunk_bytes && !is_unlimited) || contig == 1
526 || chunkspec_omit() ==
true) {
527 NC_CHECK(nc_def_var_chunking(ogrp, o_varid,
NC_CONTIGUOUS, NULL));
529 NC_CHECK(nc_def_var_chunking(ogrp, o_varid,
NC_CHUNKED, chunkp));
537 int shuffle_in=0, deflate_in=0, deflate_level_in=0;
538 int shuffle_out=0, deflate_out=0, deflate_level_out=0;
539 if(option_deflate_level != 0) {
540 NC_CHECK(
nc_inq_var_deflate(igrp, varid, &shuffle_in, &deflate_in, &deflate_level_in));
541 if(option_deflate_level == -1) {
542 shuffle_out = shuffle_in;
543 deflate_out = deflate_in;
544 deflate_level_out = deflate_level_in;
545 }
else if(option_deflate_level > 0) {
546 shuffle_out = option_shuffle_vars;
548 deflate_level_out = option_deflate_level;
550 NC_CHECK(nc_def_var_deflate(ogrp, o_varid, shuffle_out, deflate_out, deflate_level_out));
556 if(fletcher32 != 0) {
557 NC_CHECK(nc_def_var_fletcher32(ogrp, o_varid, fletcher32));
564 NC_CHECK(nc_def_var_endian(ogrp, o_varid, endianness));
574 set_var_chunked(
int ogrp,
int o_varid)
579 size_t chunk_threshold = CHUNK_THRESHOLD;
581 if(chunkspec_ndims() == 0)
587 int *dimids = (
int *) emalloc(ndims *
sizeof(
int));
591 int is_unlimited = 0;
596 NC_CHECK(
nc_inq_type(ogrp, vartype, NULL, &value_size));
597 varsize = value_size;
603 for(odim = 0; odim < ndims; odim++) {
604 int odimid = dimids[odim];
605 int idimid = dimmap_idimid(odimid);
606 if(dimmap_ounlim(odimid))
609 size_t chunksize = chunkspec_size(idimid);
612 if( (chunksize > 0) || dimmap_ounlim(odimid)) {
620 if(varsize < chunk_threshold && !is_unlimited)
626 size_t *chunkp = (
size_t *) emalloc(ndims *
sizeof(
size_t));
627 for(odim = 0; odim < ndims; odim++) {
628 int odimid = dimids[odim];
629 int idimid = dimmap_idimid(odimid);
630 size_t chunksize = chunkspec_size(idimid);
632 chunkp[odim] = chunksize;
637 NC_CHECK(nc_def_var_chunking(ogrp, o_varid,
NC_CHUNKED, chunkp));
647 set_var_compressed(
int ogrp,
int o_varid)
650 if (option_deflate_level > 0) {
652 NC_CHECK(nc_def_var_deflate(ogrp, o_varid, option_shuffle_vars, deflate, option_deflate_level));
662 free_var_chunk_cache(
int grp,
int varid)
665 size_t chunk_cache_size = 1;
666 size_t cache_nelems = 1;
667 float cache_preemp = 0;
688 copy_dims(
int igrp,
int ogrp)
708 dimids = (
int *) emalloc((ndims + 1) *
sizeof(int));
709 NC_CHECK(nc_inq_dimids(igrp, NULL, dimids, 0));
712 unlimids = (
int *) emalloc((nunlims + 1) *
sizeof(int));
719 for (dgrp = 0; dgrp < ndims; dgrp++) {
731 idimid = dimids[dgrp];
732 for (uld = 0; uld < nunlims; uld++) {
733 if(idimid == unlimids[uld]) {
740 if(unlimid != -1 && (idimid == unlimid)) {
745 stat =
nc_inq_dim(igrp, idimid, name, &length);
747 error(
"dimension \"%s\" requires 64-bit platform", name);
750 o_is_unlim = i_is_unlim;
751 if(i_is_unlim && !option_fix_unlimdims) {
754 NC_CHECK(
nc_def_dim(ogrp, name, length, &odimid));
758 dimmap_store(idimid, odimid, i_is_unlim, o_is_unlim);
771 copy_atts(
int igrp,
int ivar,
int ogrp,
int ovar)
779 for(iatt = 0; iatt < natts; iatt++) {
782 NC_CHECK(nc_copy_att(igrp, ivar, name, ogrp, ovar));
789 copy_var(
int igrp,
int varid,
int ogrp)
802 idimids = (
int *) emalloc((ndims + 1) *
sizeof(int));
803 NC_CHECK(
nc_inq_var(igrp, varid, name, &
typeid, NULL, idimids, &natts));
811 NC_CHECK(
nc_inq_type(igrp,
typeid, type_name, NULL));
817 odimids = (
int *) emalloc((ndims + 1) *
sizeof(int));
818 for(i = 0; i < ndims; i++) {
819 odimids[i] = dimmap_odimid(idimids[i]);
820 if(odimids[i] == -1) {
821 error(
"Oops, no dimension in output associated with input dimid %d", idimids[i]);
826 NC_CHECK(
nc_def_var(ogrp, name, o_typeid, ndims, odimids, &o_varid));
828 NC_CHECK(copy_atts(igrp, varid, ogrp, o_varid));
839 NC_CHECK(copy_var_specials(igrp, varid, ogrp, o_varid));
842 NC_CHECK(set_var_chunked(ogrp, o_varid));
844 NC_CHECK(set_var_compressed(ogrp, o_varid));
856 copy_vars(
int igrp,
int ogrp)
872 for (iv=0; iv < option_nlvars; iv++) {
873 if(nc_inq_gvarid(igrp, option_lvars[iv], &varid) ==
NC_NOERR)
877 NC_CHECK(nc_inq_nvars(igrp, &nvars));
878 for (varid = 0; varid < nvars; varid++) {
879 if (!option_varstruct && option_nlvars > 0 && ! idmember(vlist, varid))
881 NC_CHECK(copy_var(igrp, varid, ogrp));
891 copy_schema(
int igrp,
int ogrp)
898 NC_CHECK(get_grpid(igrp, ogrp, &ogid));
900 NC_CHECK(copy_dims(igrp, ogid));
902 NC_CHECK(copy_vars(igrp, ogid));
909 stat = nc_inq_grps(igrp, &numgrps, NULL);
910 grpids = (
int *)emalloc((numgrps + 1) *
sizeof(int));
911 NC_CHECK(nc_inq_grps(igrp, &numgrps, grpids));
913 for(i = 0; i < numgrps; i++) {
914 if (option_grpstruct || group_wanted(grpids[i], option_nlgrps, option_grpids)) {
915 NC_CHECK(copy_schema(grpids[i], ogid));
926 inq_nvals(
int igrp,
int varid,
long long *nvalsp) {
934 dimids = (
int *) emalloc((ndims + 1) *
sizeof(int));
936 for(dim = 0; dim < ndims; dim++) {
950 copy_var_data(
int igrp,
int varid,
int ogrp) {
956 static void *buf = 0;
968 NC_CHECK(inq_nvals(igrp, varid, &nvalues));
975 value_size = val_size(igrp, varid);
976 if(value_size > option_copy_buffer_size) {
977 option_copy_buffer_size = value_size;
987 if(option_compute_chunkcaches) {
991 size_t chunkcache_size, chunkcache_nelems;
992 float chunkcache_preemption;
993 NC_CHECK(inq_var_chunking_params(igrp, varid, ogrp, ovarid,
996 &chunkcache_preemption));
1000 chunkcache_preemption));
1004 option_chunk_cache_size,
1005 option_chunk_cache_nelems,
1006 COPY_CHUNKCACHE_PREEMPTION));
1013 NC_CHECK(inq_var_chunksize(igrp, varid, &chunksize));
1014 if(chunksize > option_copy_buffer_size) {
1015 option_copy_buffer_size = chunksize;
1020 if(buf && do_realloc) {
1025 buf = emalloc(option_copy_buffer_size);
1026 memset((
void*)buf,0,option_copy_buffer_size);
1030 NC_CHECK(nc_get_iter(igrp, varid, option_copy_buffer_size, &iterp));
1032 start = (
size_t *) emalloc((iterp->rank + 1) *
sizeof(size_t));
1033 count = (
size_t *) emalloc((iterp->rank + 1) *
sizeof(size_t));
1037 while((ntoget = nc_next_iter(iterp, start, count)) > 0) {
1038 NC_CHECK(
nc_get_vara(igrp, varid, start, count, buf));
1039 NC_CHECK(
nc_put_vara(ogrp, ovarid, start, count, buf));
1046 NC_CHECK(
nc_inq_user_type(igrp, vartype, NULL, NULL, NULL, NULL, &vclass));
1061 NC_CHECK(nc_free_iter(iterp));
1069 copy_data(
int igrp,
int ogrp)
1082 idnode_t* vlist = NULL;
1090 vlist = newidlist();
1091 for (iv=0; iv < option_nlvars; iv++) {
1092 if(nc_inq_gvarid(igrp, option_lvars[iv], &varid) ==
NC_NOERR)
1093 idadd(vlist, varid);
1098 NC_CHECK(get_grpid(igrp, ogrp, &ogid));
1101 NC_CHECK(nc_inq_nvars(igrp, &nvars));
1103 for (varid = 0; varid < nvars; varid++) {
1104 if (option_nlvars > 0 && ! idmember(vlist, varid))
1106 if (!group_wanted(igrp, option_nlgrps, option_grpids))
1108 NC_CHECK(copy_var_data(igrp, varid, ogid));
1112 stat = nc_inq_grps(igrp, &numgrps, NULL);
1113 grpids = (
int *)emalloc((numgrps + 1) *
sizeof(int));
1114 NC_CHECK(nc_inq_grps(igrp, &numgrps, grpids));
1116 for(i = 0; i < numgrps; i++) {
1117 if (!option_grpstruct && !group_wanted(grpids[i], option_nlgrps, option_grpids))
1119 NC_CHECK(copy_data(grpids[i], ogid));
1134 NC_CHECK(nc_inq_grps(ncid, &numgrps, NULL));
1137 int *grpids = emalloc(numgrps *
sizeof(
int));
1138 NC_CHECK(nc_inq_grps(ncid, &numgrps, grpids));
1139 for(igrp = 0; igrp < numgrps; igrp++) {
1140 ndims += count_dims(grpids[igrp]);
1156 nc3_special_case(
int ncid,
int kind) {
1160 if (recdimid != -1) {
1163 NC_CHECK(nc_inq_nvars(ncid, &nvars));
1164 for (varid = 0; varid < nvars; varid++) {
1170 dimids = (
int *) emalloc((ndims + 1) *
sizeof(int));
1172 dimids0 = dimids[0];
1174 if(dimids0 == recdimid) {
1197 NC_CHECK(nc_inq_nvars(ncid, &nvars));
1199 *fvars = (
int *) emalloc(nvars *
sizeof(
int));
1201 *rvars = (
int *) emalloc(nvars *
sizeof(
int));
1202 for (varid = 0; varid < nvars; varid++) {
1203 if (isrecvar(ncid, varid)) {
1204 (*rvars)[*nr] = varid;
1207 (*fvars)[*nf] = varid;
1216 copy_fixed_size_data(
int igrp,
int ogrp,
size_t nfixed_vars,
int *fixed_varids) {
1219 for (ivar = 0; ivar < nfixed_vars; ivar++) {
1220 int varid = fixed_varids[ivar];
1221 NC_CHECK(copy_var_data(igrp, varid, ogrp));
1230 copy_rec_var_data(
int ncid,
1240 NC_CHECK(
nc_get_vara(ncid, varid, start, count, buf));
1241 NC_CHECK(
nc_put_vara(ogrp, ovarid, start, count, buf));
1247 copy_record_data(
int ncid,
int ogrp,
size_t nrec_vars,
int *rec_varids) {
1258 buf = (
void **) emalloc(nrec_vars *
sizeof(
void *));
1259 rec_ovarids = (
int *) emalloc(nrec_vars *
sizeof(
int));
1260 start = (
size_t **) emalloc(nrec_vars *
sizeof(
size_t*));
1261 count = (
size_t **) emalloc(nrec_vars *
sizeof(
size_t*));
1263 for (ivar = 0; ivar < nrec_vars; ivar++) {
1272 varid = rec_varids[ivar];
1274 dimids = (
int *) emalloc((1 + ndims) *
sizeof(int));
1275 start[ivar] = (
size_t *) emalloc(ndims *
sizeof(
size_t));
1276 count[ivar] = (
size_t *) emalloc(ndims *
sizeof(
size_t));
1278 value_size = val_size(ncid, varid);
1280 for(ii = 1; ii < ndims; ii++) {
1285 start[ivar][ii] = 0;
1286 count[ivar][ii] = dimlen;
1290 buf[ivar] = (
void *) emalloc(nvals * value_size);
1292 NC_CHECK(
nc_inq_varid(ogrp, varname, &rec_ovarids[ivar]));
1298 for(irec = 0; irec < nrecs; irec++) {
1299 for (ivar = 0; ivar < nrec_vars; ivar++) {
1301 varid = rec_varids[ivar];
1302 ovarid = rec_ovarids[ivar];
1303 start[ivar][0] = irec;
1304 NC_CHECK(copy_rec_var_data(ncid, ogrp, irec, varid, ovarid,
1305 start[ivar], count[ivar], buf[ivar]));
1308 for (ivar = 0; ivar < nrec_vars; ivar++) {
1318 for (ivar = 0; ivar < nrec_vars; ivar++) {
1335 copy(
char* infile,
char* outfile)
1339 int inkind, outkind;
1344 if(option_read_diskless) {
1348 NC_CHECK(
nc_open(infile, open_mode, &igrp));
1363 outkind = option_kind;
1364 if (option_kind == SAME_AS_INPUT) {
1368 if (option_deflate_level > 0 ||
1378 if(option_chunkspec) {
1381 NC_CHECK(chunkspec_parse(igrp, option_chunkspec));
1386 if(missing_vars(igrp, option_nlvars, option_lvars))
1389 if(option_nlgrps > 0) {
1391 error(
"Group list (-g ...) only permitted for netCDF-4 file");
1395 if(grp_matches(igrp, option_nlgrps, option_lgrps, option_grpids) == 0)
1399 if(option_write_diskless)
1418 error(
"nccopy built with --disable-netcdf4, can't create netCDF-4 files");
1422 error(
"bad value (%d) for -k option\n", option_kind);
1425 NC_CHECK(
nc_create(outfile, create_mode, &ogrp));
1432 NC_CHECK(copy_groups(igrp, ogrp));
1433 NC_CHECK(copy_types(igrp, ogrp));
1437 ndims = count_dims(igrp);
1438 NC_CHECK(dimmap_init(ndims));
1439 NC_CHECK(copy_schema(igrp, ogrp));
1446 if(nc3_special_case(igrp, inkind)) {
1447 size_t nfixed_vars, nrec_vars;
1450 NC_CHECK(classify_vars(igrp, &nfixed_vars, &fixed_varids, &nrec_vars, &rec_varids));
1451 NC_CHECK(copy_fixed_size_data(igrp, ogrp, nfixed_vars, fixed_varids));
1452 NC_CHECK(copy_record_data(igrp, ogrp, nrec_vars, rec_varids));
1453 }
else if (nc3_special_case(ogrp, outkind)) {
1454 size_t nfixed_vars, nrec_vars;
1458 NC_CHECK(classify_vars(ogrp, &nfixed_vars, &fixed_varids, &nrec_vars, &rec_varids));
1459 NC_CHECK(copy_fixed_size_data(igrp, ogrp, nfixed_vars, fixed_varids));
1460 NC_CHECK(copy_record_data(igrp, ogrp, nrec_vars, rec_varids));
1462 NC_CHECK(copy_data(igrp, ogrp));
1477 double_with_suffix(
char *str) {
1481 dval = strtod(str, &suffix);
1482 if(dval < 0 || errno != 0)
1512 [-k n] specify kind of netCDF format for output file, default same as input\n\
1513 1 classic, 2 64-bit offset, 3 netCDF-4, 4 netCDF-4 classic model\n\
1514 [-d n] set deflation compression level, default same as input (0=none 9=max)\n\
1515 [-s] add shuffle option to deflation compression\n\
1516 [-c chunkspec] specify chunking for dimensions, e.g. \"dim1/N1,dim2/N2,...\"\n\
1517 [-u] convert unlimited dimensions to fixed-size dimensions in output copy\n\
1518 [-w] write whole output file from diskless netCDF on close\n\
1519 [-v var1,...] include data for only listed variables, but definitions for all variables\n\
1520 [-V var1,...] include definitions and data for only listed variables\n\
1521 [-g grp1,...] include data for only variables in listed groups, but all definitions\n\
1522 [-G grp1,...] include definitions and data only for variables in listed groups\n\
1523 [-m n] set size in bytes of copy buffer, default is 5000000 bytes\n\
1524 [-h n] set size in bytes of chunk_cache for chunked variables\n\
1525 [-e n] set number of elements that chunk_cache can hold\n\
1526 [-r] read whole input file into diskless file on open (classic or 64-bit offset format only)\n\
1527 infile name of netCDF input file\n\
1528 outfile name for netCDF output file\n"
1533 error(
"%s [-k n] [-d n] [-s] [-c chunkspec] [-u] [-w] [-[v|V] varlist] [-[g|G] grplist] [-m n] [-h n] [-e n] [-r] infile outfile\n%s",
1538 main(
int argc,
char**argv)
1540 char* inputfile = NULL;
1541 char* outputfile = NULL;
1583 while ((c = getopt(argc, argv,
"k:d:sum:c:h:e:rwxg:G:v:V:")) != -1) {
1599 struct Kvalues* kvalue;
1600 char *kind_name = (
char *) emalloc(strlen(optarg)+1);
1601 (void)strcpy(kind_name, optarg);
1602 for(kvalue=legalkinds;kvalue->name;kvalue++) {
1603 if(strcmp(kind_name,kvalue->name) == 0) {
1604 option_kind = kvalue->kind;
1608 if(kvalue->name == NULL) {
1609 error(
"invalid format: %s", kind_name);
1614 option_deflate_level = strtol(optarg, NULL, 10);
1615 if(option_deflate_level < 0 || option_deflate_level > 9) {
1616 error(
"invalid deflation level: %d", option_deflate_level);
1623 option_fix_unlimdims = 1;
1627 double dval = double_with_suffix(optarg);
1629 error(
"Suffix used for '-m' option value must be K, M, G, T, or P");
1630 option_copy_buffer_size = dval;
1635 double dval = double_with_suffix(optarg);
1637 error(
"Suffix used for '-h' option value must be K, M, G, T, or P");
1638 option_chunk_cache_size = dval;
1643 double dval = double_with_suffix(optarg);
1645 error(
"Suffix used for '-e' option value must be K, M, G, T, or P");
1646 option_chunk_cache_nelems = (long)dval;
1650 option_read_diskless = 1;
1653 option_write_diskless = 1;
1656 option_compute_chunkcaches = 1;
1660 option_chunkspec = strdup(optarg);
1664 make_lgrps (optarg, &option_nlgrps, &option_lgrps, &option_grpids);
1665 option_grpstruct =
true;
1669 make_lgrps (optarg, &option_nlgrps, &option_lgrps, &option_grpids);
1670 option_grpstruct =
false;
1674 make_lvars (optarg, &option_nlvars, &option_lvars);
1675 option_varstruct =
true;
1679 make_lvars (optarg, &option_nlvars, &option_lvars);
1680 option_varstruct =
false;
1690 error(
"one input file and one output file required");
1692 inputfile = argv[0];
1693 outputfile = argv[1];
1695 if(strcmp(inputfile, outputfile) == 0) {
1696 error(
"output would overwrite input");
1699 if(copy(inputfile, outputfile) !=
NC_NOERR)
EXTERNL int nc_def_enum(int ncid, nc_type base_typeid, const char *name, nc_type *typeidp)
Create an enum type.
#define NC_ENOMEM
Memory allocation (malloc) failure.
EXTERNL int nc_inq_var_endian(int ncid, int varid, int *endianp)
Find the endianness of a variable.
#define NC_CHUNKED
In HDF5 files you can set storage for each variable to be either contiguous or chunked, with nc_def_var_chunking().
EXTERNL int nc_inq_unlimdim(int ncid, int *unlimdimidp)
Find the ID of the unlimited dimension.
EXTERNL int nc_inq_opaque(int ncid, nc_type xtype, char *name, size_t *sizep)
Learn about an opaque type.
EXTERNL int nc_inq_vardimid(int ncid, int varid, int *dimidsp)
Learn the dimension IDs associated with a variable.
#define NC_CONTIGUOUS
In HDF5 files you can set storage for each variable to be either contiguous or chunked, with nc_def_var_chunking().
EXTERNL int nc_def_var(int ncid, const char *name, nc_type xtype, int ndims, const int *dimidsp, int *varidp)
Define a new variable.
#define NC_CLASSIC_MODEL
Enforce classic model.
#define NC_OPAQUE
opaque types
Main header file for the C API.
EXTERNL int nc_free_vlens(size_t len, nc_vlen_t vlens[])
Free an array of vlens given the number of elements and an array.
EXTERNL int nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp)
This is a wrapper for nc_inq_var_all().
EXTERNL int nc_put_vara(int ncid, int varid, const size_t *startp, const size_t *countp, const void *op)
Write an array of values to a variable.
EXTERNL int nc_insert_array_compound(int ncid, nc_type xtype, const char *name, size_t offset, nc_type field_typeid, int ndims, const int *dim_sizes)
Insert a named array field into a compound type.
EXTERNL int nc_inq_varndims(int ncid, int varid, int *ndimsp)
Learn how many dimensions are associated with a variable.
EXTERNL int nc_inq_format(int ncid, int *formatp)
Inquire about the binary format of a netCDF file as presented by the API.
EXTERNL int nc_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep, size_t *base_sizep, size_t *num_membersp)
Learn about a user-define enumeration type.
EXTERNL int nc_def_opaque(int ncid, size_t size, const char *name, nc_type *xtypep)
Create an opaque type.
int nc_type
The nc_type type is just an int.
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
#define NC_NOWRITE
Set read-only access for nc_open().
EXTERNL int nc_def_dim(int ncid, const char *name, size_t len, int *idp)
Define a new dimension.
#define NC_EDIMSIZE
Invalid dimension size.
EXTERNL int nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, float preemption)
#define NC_ENOGRP
No group found.
EXTERNL int nc_inq_vlen(int ncid, nc_type xtype, char *name, size_t *datum_sizep, nc_type *base_nc_typep)
Learn about a VLEN type.
EXTERNL int nc_close(int ncid)
Close an open netCDF dataset.
#define NC_VLEN
vlen (variable-length) types
#define NC_NOSHUFFLE
Control the HDF5 shuffle filter.
EXTERNL int nc_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name, size_t *offsetp, nc_type *field_typeidp, int *ndimsp, int *dim_sizesp)
Get information about one of the fields of a compound type.
EXTERNL int nc_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp)
Create a compound type.
#define NC_FORMAT_64BIT
Format specifier for nc_set_default_format() and returned by nc_inq_format.
This is the type of arrays of vlens.
#define NC_EBADTYPE
Not a netcdf data type.
EXTERNL int nc_inq_compound(int ncid, nc_type xtype, char *name, size_t *sizep, size_t *nfieldsp)
Learn about a compound type.
EXTERNL int nc_inq_var_fletcher32(int ncid, int varid, int *fletcher32p)
Learn the checksum settings for a variable.
#define NC_NOFILL
Argument to nc_set_fill() to turn off filling of data.
EXTERNL int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
#define NC_MAX_NAME
Maximum for classic library.
EXTERNL int nc_inq_vartype(int ncid, int varid, nc_type *xtypep)
Learn the type of a variable.
EXTERNL int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
EXTERNL int nc_free_string(size_t len, char **data)
Free string space allocated by the library.
EXTERNL int nc_inq_varname(int ncid, int varid, char *name)
Learn the name of a variable.
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
#define NC_FORMAT_NETCDF4_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define NC_FORMAT_NETCDF4
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define NC_UNLIMITED
Size argument to nc_def_dim() for an unlimited dimension.
EXTERNL int nc_insert_enum(int ncid, nc_type xtype, const char *name, const void *value)
Insert a named member into a enum type.
EXTERNL int nc_inq_varid(int ncid, const char *name, int *varidp)
Find the ID of a variable, from the name.
EXTERNL int nc_insert_compound(int ncid, nc_type xtype, const char *name, size_t offset, nc_type field_typeid)
Insert a named field into a compound type.
EXTERNL int nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name, void *value)
Learn about a about a member of an enum type.
#define NC_CLOBBER
Destroy existing file.
#define NC_WRITE
Set read-write access for nc_open().
#define NC_ENDIAN_NATIVE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
EXTERNL int nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep, int *deflate_levelp)
Learn the storage and deflate settings for a variable.
EXTERNL int nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp)
Return number and list of unlimited dimensions.
EXTERNL int nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp)
Learn about a variable.
#define NC_NOERR
No Error.
#define NC_ENUM
enum types
#define NC_DISKLESS
Use diskless file.
EXTERNL int nc_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep)
Use this function to define a variable length array type.
EXTERNL int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
EXTERNL int nc_inq_ndims(int ncid, int *ndimsp)
Find the number of dimensions.
EXTERNL int nc_inq_varnatts(int ncid, int varid, int *nattsp)
Learn how many attributes are associated with a variable.
EXTERNL int nc_enddef(int ncid)
Leave define mode.
#define NC_COMPOUND
compound types
EXTERNL int nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
Find the length of a dimension.
EXTERNL int nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size, nc_type *base_nc_typep, size_t *nfieldsp, int *classp)
Learn about a user defined type.
#define NC_GLOBAL
Attribute id to put/get a global attribute.
#define NC_SHUFFLE
Control the HDF5 shuffle filter.
#define NC_FORMAT_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define END_OF_MAIN()
NO_NETCDF_2.
EXTERNL int nc_get_vara(int ncid, int varid, const size_t *startp, const size_t *countp, void *ip)
Read an array of values from a variable.
EXTERNL int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
EXTERNL int nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
Find the name and length of a dimension.
EXTERNL int nc_inq_attname(int ncid, int varid, int attnum, char *name)
Find the name of an attribute.
EXTERNL int nc_inq_typeid(int ncid, const char *name, nc_type *typeidp)
Find a type by name.