4 #define RMISS -9.9999e+30 7 static int32_t ERROR_SUPPRESS = 0;
9 #define CHECK_ERROR(status) \ 11 if (status != NC_NOERR) { \ 12 if ( ! ERROR_SUPPRESS ) { \ 13 fprintf(stderr, "Error: at l%d in %s\n", __LINE__, __FILE__); \ 14 fprintf(stderr, " %s\n", nc_strerror(status)); \ 20 #define NCTYPE2TYPE(nctype, type) \ 30 type = File_INTEGER2; \ 33 fprintf(stderr, "unsuppoted data type: %d\n", xtype); \ 38 #define TYPE2NCTYPE(type, nctype) \ 48 fprintf(stderr, "unsuppoted data type: %d\n", xtype); \ 54 #define DEFAULT_DEFLATE_LEVEL 2 106 fprintf(stderr,
"exceed max number of file limit\n");
111 strcpy(_fname, fname);
112 if (fname[len-3] !=
'.' || fname[len-2] !=
'n' || fname[len-1] !=
'c' )
113 strcat(_fname,
".nc");
121 CHECK_ERROR( nc_create(_fname, NC_CLOBBER, &ncid) );
123 CHECK_ERROR( nc_create(_fname, NC_CLOBBER|NC_NETCDF4, &ncid) );
130 fprintf(stderr,
"invalid mode type\n");
135 files[nfile]->
ncid = ncid;
138 files[nfile]->defmode = 1;
151 if ( strcmp(filetype,
"netcdf") != 0 )
return SUCCESS_CODE;
153 if ( strcmp(key,
"deflate_level") == 0 ) {
171 int dimids[
MAX_RANK], tdim, uldims[NC_MAX_DIMS];
177 ERROR_SUPPRESS = suppress;
180 ncid = files[fid]->
ncid;
181 CHECK_ERROR( nc_inq_varid(ncid, varname, &varid) );
186 strcpy(dinfo->
varname, varname);
192 CHECK_ERROR( nc_inq_vartype(ncid, varid, &xtype) );
195 CHECK_ERROR( nc_inq_varndims(ncid, varid, &rank) );
196 CHECK_ERROR( nc_inq_vardimid(ncid, varid, dimids) );
204 for ( i=0; i<n; i++ ) {
205 if ( uldims[i] == dimids[0] ) {
211 fprintf(stderr,
"rank exceeds limit: %d\n", rank);
214 dinfo->
rank = tdim >= 0 ? rank -1 : rank;
216 for (i=0; i<dinfo->
rank; i++) {
218 CHECK_ERROR( nc_inq_dim(ncid, dimids[rank-i-1], name, &size) );
231 strcat(name,
"_bnds");
251 size_t *start, *count;
256 ncid = files[dinfo->
fid]->
ncid;
259 CHECK_ERROR( nc_inq_varndims(ncid, varid, &rank) );
260 start = (
size_t*) malloc(
sizeof(
size_t)*rank);
261 count = (
size_t*) malloc(
sizeof(
size_t)*rank);
262 for (i=0; i<dinfo->
rank; i++) {
264 start[rank -i-1] = 0;
265 count[rank -i-1] = dinfo->
dim_size[i];
267 if (rank > dinfo->
rank) {
268 start[0] = dinfo->
step - 1;
271 switch ( precision ) {
273 status = nc_get_vara_double(ncid, varid, start, count, (
double*)var);
279 status = nc_get_vara_float(ncid, varid, start, count, (
float*)var);
287 fprintf(stderr,
"unsuppoted data precision: %d\n", precision );
303 ncid = files[fid]->
ncid;
305 CHECK_ERROR( nc_inq_attlen(ncid, NC_GLOBAL, key, &l) );
308 CHECK_ERROR( nc_get_att_text(ncid, NC_GLOBAL, key, value) );
323 ncid = files[fid]->
ncid;
325 CHECK_ERROR( nc_inq_attlen(ncid, NC_GLOBAL, key, &l) );
327 CHECK_ERROR( nc_get_att_int(ncid, NC_GLOBAL, key, value) );
341 ncid = files[fid]->
ncid;
343 CHECK_ERROR( nc_inq_attlen(ncid, NC_GLOBAL, key, &l) );
345 CHECK_ERROR( nc_get_att_float(ncid, NC_GLOBAL, key, value) );
359 ncid = files[fid]->
ncid;
361 CHECK_ERROR( nc_inq_attlen(ncid, NC_GLOBAL, key, &l) );
363 CHECK_ERROR( nc_get_att_double(ncid, NC_GLOBAL, key, value) );
375 ncid = files[fid]->
ncid;
378 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
380 CHECK_ERROR( nc_put_att_text(ncid, NC_GLOBAL, key, strlen(value), value) );
393 ncid = files[fid]->
ncid;
396 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
398 CHECK_ERROR( nc_put_att_int(ncid, NC_GLOBAL, key, NC_INT, len, value) );
411 ncid = files[fid]->
ncid;
414 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
416 CHECK_ERROR( nc_put_att_float(ncid, NC_GLOBAL, key, NC_FLOAT, len, value) );
429 ncid = files[fid]->
ncid;
432 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
434 CHECK_ERROR( nc_put_att_double(ncid, NC_GLOBAL, key, NC_DOUBLE, len, value) );
442 strcpy(files[fid]->time_units, time_units);
457 ncid = files[fid]->
ncid;
461 if ( nc_inq_attid(ncid, varid, key, &attid) == NC_NOERR )
465 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
468 CHECK_ERROR( nc_put_att_text(ncid, varid, key, strlen(val), val) );
483 int ncid, dimid, varid;
487 ncid = files[fid]->
ncid;
489 if ( nc_inq_varid(ncid, name, &varid) == NC_NOERR )
493 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
496 if ( nc_inq_dimid(ncid, dim_name, &dimid) != NC_NOERR )
497 CHECK_ERROR( nc_def_dim(ncid, dim_name, size, &dimid) );
500 CHECK_ERROR( nc_def_var(ncid, name, xtype, 1, &dimid, &varid) );
501 CHECK_ERROR( nc_put_att_text(ncid, varid,
"long_name", strlen(desc), desc) );
502 CHECK_ERROR( nc_put_att_text(ncid, varid,
"units", strlen(units), units) );
506 files[fid]->defmode = 0;
509 switch ( precision ) {
511 CHECK_ERROR( nc_put_var_double(ncid, varid, (
double*)val) );
514 CHECK_ERROR( nc_put_var_float(ncid, varid, (
float*)val) );
517 fprintf(stderr,
"unsuppoted data precision: %d\n", precision);
534 int ncid, *dimids, varid;
539 ncid = files[fid]->
ncid;
541 if ( nc_inq_varid(ncid, name, &varid) == NC_NOERR )
545 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
548 dimids = malloc(
sizeof(
int)*ndims);
549 for (i=0; i<ndims; i++)
550 CHECK_ERROR( nc_inq_dimid(ncid, dim_names[i], dimids+ndims-i-1) );
554 CHECK_ERROR( nc_def_var(ncid, name, xtype, ndims, dimids, &varid) );
555 CHECK_ERROR( nc_put_att_text(ncid, varid,
"long_name", strlen(desc), desc) );
556 CHECK_ERROR( nc_put_att_text(ncid, varid,
"units", strlen(units), units) );
561 files[fid]->defmode = 0;
564 switch ( precision ) {
566 CHECK_ERROR( nc_put_var_double(ncid, varid, (
double*)val) );
569 CHECK_ERROR( nc_put_var_float(ncid, varid, (
float*)val) );
572 fprintf(stderr,
"unsuppoted data precision: %d\n", precision);
590 int ncid, varid, acid, *acdimids;
591 int dimids[NC_MAX_DIMS], dimid;
605 fprintf(stderr,
"exceed max number of variable limit\n");
610 ncid = files[fid]->
ncid;
613 vars[nvar]->
ncid = ncid;
614 vars[nvar]->
t = NULL;
615 vars[nvar]->
start = NULL;
616 vars[nvar]->
count = NULL;
619 if (files[fid]->defmode == 0) {
CHECK_ERROR( nc_redef(ncid) ); files[fid]->defmode = 1; }
624 for ( i=0; i<nt; i++ ) {
625 if ( tdims[i] != NULL &&
626 tdims[i]->ncid == ncid &&
627 tdims[i]->tint == tint ) {
628 vars[nvar]->
t = tdims[i];
632 if ( vars[nvar]->t == NULL ) {
634 tdims[nt]->
ncid = ncid;
635 tdims[nt]->
count = -1;
636 tdims[nt]->
tint = tint;
639 strcpy(tname,
"time");
641 sprintf(tname,
"time%d", nt);
642 strcpy(tdims[nt]->name, tname);
644 CHECK_ERROR( nc_def_dim(ncid, tname, 0, &tdimid) );
645 tdims[nt]->
dimid = tdimid;
646 CHECK_ERROR( nc_def_var(ncid, tname, NC_DOUBLE, 1, &tdimid, &tvarid) );
647 tdims[nt]->
varid = tvarid;
649 CHECK_ERROR( nc_put_att_text(ncid, tvarid,
"long_name", strlen(buf), buf) );
650 CHECK_ERROR( nc_put_att_text(ncid, tvarid,
"units", strlen(files[fid]->time_units), files[fid]->time_units) );
652 if ( nc_inq_dimid(ncid,
"nv", &(dimids[1])) != NC_NOERR )
653 CHECK_ERROR( nc_def_dim(ncid,
"nv", 2, &(dimids[1])) );
654 sprintf(buf,
"%s_bnds", tname);
655 CHECK_ERROR( nc_put_att_text(ncid, tvarid,
"bounds", strlen(buf), buf) );
657 CHECK_ERROR( nc_def_var(ncid, buf, NC_DOUBLE, 2, dimids, &tvarid) );
658 tdims[nt]->
bndsid = tvarid;
659 CHECK_ERROR( nc_put_att_text(ncid, tvarid,
"units", strlen(files[fid]->time_units), files[fid]->time_units) );
661 vars[nvar]->
t = tdims[nt];
670 dimids[0] = vars[nvar]->
t->
dimid;
673 for (i=ndims-n; i<ndims; i++) dimids[i] = -1;
677 for (i=0; i<n; i++) {
679 if ( nc_inq_dimid(ncid, dims[i], &dimid) == NC_NOERR ) {
682 for (k=0; k<nndims; k++) {
683 if (dimid == dimids[k]) {
689 dimids[ndims-(++nndims)] = dimid;
695 acdimids = (
int*) malloc((
sizeof(
int)*m));
696 CHECK_ERROR( nc_inq_vardimid(ncid, acid, acdimids) );
697 for (j=m-1; j>=0; j--) {
699 for (k=0; k<ndims; k++) {
700 if (acdimids[j] == dimids[k]) {
706 if ( nndims >= ndims ) {
707 fprintf(stderr,
"Error: invalid associated coordinates\n");
710 dimids[ndims-(++nndims)] = acdimids[j];
720 fprintf(stderr,
"Error: invalid associated coordinates: %d %d\n", ndims, nndims);
725 CHECK_ERROR( nc_def_var(ncid, varname, xtype, ndims, dimids, &varid) );
728 CHECK_ERROR( nc_put_att_text(ncid, varid,
"long_name", strlen(desc), desc) );
729 CHECK_ERROR( nc_put_att_text(ncid, varid,
"units", strlen(units), units) );
730 CHECK_ERROR( nc_put_att_double(ncid, varid, _FillValue, xtype, 1, &rmiss) );
731 CHECK_ERROR( nc_put_att_double(ncid, varid,
"missing_value", xtype, 1, &rmiss) );
733 strcpy(coord, dims[0]);
735 if (strlen(coord)+strlen(dims[i])+1 <
File_HMID) {
737 strcat(coord, dims[i]);
740 if ( ndims > n && strlen(coord)+6 <
File_HMID) {
742 strcat(coord, vars[nvar]->t->name);
744 CHECK_ERROR( nc_put_att_text(ncid, varid,
"coordinates", strlen(coord), coord) );
749 sprintf(buf,
"%s: mean", vars[nvar]->t->name);
750 CHECK_ERROR( nc_put_att_text(ncid, varid,
"cell_methods", strlen(buf), buf) );
754 vars[nvar]->
start = (
size_t*) malloc(
sizeof(
size_t)*ndims);
755 vars[nvar]->
count = (
size_t*) malloc(
sizeof(
size_t)*ndims);
756 for ( i=0; i<ndims; i++ ) {
757 CHECK_ERROR( nc_inq_dimlen(ncid, dimids[i], &size) );
758 vars[nvar]->
count[i] = size;
759 vars[nvar]->
start[i] = 0;
761 if ( tint > 0.0 ) vars[nvar]->
count[0] = 1;
765 if ( files[fid]->deflate_level > 0 ) {
766 CHECK_ERROR( nc_def_var_chunking(ncid, varid, NC_CHUNKED, vars[nvar]->count) );
767 CHECK_ERROR( nc_def_var_deflate(ncid, varid, 0, 1, files[fid]->deflate_level) );
771 vars[nvar]->
varid = varid;
789 ncid = vars[vid]->
ncid;
792 if ( files[fid]->defmode == 1) {
CHECK_ERROR( nc_enddef(ncid) ); files[fid]->defmode = 0; }
795 varid = vars[vid]->
varid;
796 if ( vars[vid]->t != NULL ) {
797 if ( vars[vid]->t->
count < 0 ||
798 t_end > vars[vid]->
t->
t +
TEPS ) {
800 vars[vid]->
t->
t = t_end;
802 index[0] = vars[vid]->
t->
count;
803 CHECK_ERROR( nc_put_var1_double(ncid, vars[vid]->t->
varid, index, &t_end) );
805 CHECK_ERROR( nc_put_var1_double(ncid, vars[vid]->t->bndsid, index, &t_start) );
807 CHECK_ERROR( nc_put_var1_double(ncid, vars[vid]->t->bndsid, index, &t_end) );
810 size_t nt = vars[vid]->
t->
count + 1;
817 for(n=nt-1;n>=0;n--) {
818 if ( fabs(t[n]-t_end) <
TEPS ) {
819 vars[vid]->
start[0] = n;
825 fprintf(stderr,
"cannot find time: %f\n", t_end);
826 fprintf(stderr,
" time count is : %d, last time is: %f, diff is: %e\n", vars[vid]->t->
count < 0, vars[vid]->
t->
t, vars[vid]->
t->
t-t_end);
827 fprintf(stderr,
" time is: ");
828 for (n=0;n<nt;n++) fprintf(stderr,
"%f, ", t[n]);
829 fprintf(stderr,
"\n");
837 CHECK_ERROR( nc_put_vara_double(ncid, varid, vars[vid]->start, vars[vid]->count, (
double*)var) );
840 CHECK_ERROR( nc_put_vara_float(ncid, varid, vars[vid]->start, vars[vid]->count, (
float*)var) );
843 fprintf(stderr,
"unsuppoted data precision: %d\n", precision);
858 ncid = files[fid]->
ncid;
863 for (i=0; i<nvar; i++) {
864 if ( vars[i] != NULL && vars[i]->ncid == ncid ) {
865 free( vars[i]->start );
866 free( vars[i]->count );
872 for (i=0; i<nt; i++) {
873 if ( tdims[i] != NULL && tdims[i]->ncid == ncid ) {
int32_t dim_size[MAX_RANK]
char dim_name[File_HSHORT *MAX_RANK]
char description[File_HMID]
char time_units[File_HMID]
char varname[File_HSHORT]