From e44c37caaee037cbfd5dec7d8146916811967d00 Mon Sep 17 00:00:00 2001 From: Pavel Sakov Date: Thu, 18 Aug 2016 12:43:11 +1000 Subject: [PATCH] v. 1.45.2 --- enkf/CHANGELOG | 12 +- enkf/calc/ensobs.c | 18 ++- enkf/common/ncw.c | 228 +++++++++++++++++++++++++++++++++++-- enkf/common/ncw.h | 15 ++- enkf/common/observations.c | 58 +++++----- enkf/common/observations.h | 22 ++-- enkf/common/version.c | 2 +- 7 files changed, 308 insertions(+), 47 deletions(-) diff --git a/enkf/CHANGELOG b/enkf/CHANGELOG index f772b4a6..7cec4bd9 100644 --- a/enkf/CHANGELOG +++ b/enkf/CHANGELOG @@ -1,4 +1,14 @@ -v. 1.46.1 +v. 1.45.2 + PS 18082016 + -- Slightly modified update_HE() and update_Hx() to fix a once-in-a-lifetime + round-off error occuring after writing and reading `fi' to observations.nc + as a float. + -- Changed `id_orig' in observations.nc to correspond to the observation + number as read from data files rather than to the id in + observations-orig.nc (that is, after compacting). + -- Changed the type of fields `type', `product' and `instrument' of struct + observation from int to short int. +v. 1.45.1 PS 17082016 -- Changed enkfprm_check() so that no unnecessary parameters are demanded when calculating ensemble spread only. diff --git a/enkf/calc/ensobs.c b/enkf/calc/ensobs.c index 0fa9952f..ea4e9040 100644 --- a/enkf/calc/ensobs.c +++ b/enkf/calc/ensobs.c @@ -803,7 +803,11 @@ static void das_sortobs_byid(dasystem* das) das->sort_mode = OBS_SORTMODE_ID; } -/** Updates ensemble observations by applying X5 +/** Updates ensemble observations by applying X5. + * + * Both update_HE() and update_Hx() only use the transforms calculated for the + * (int) fj, (int) fi node of the grid. This might be improved in the future to + * yield probably a bit more precise (and better) analysis stats. */ static void update_HE(dasystem* das) { @@ -976,6 +980,12 @@ static void update_HE(dasystem* das) * HE(i, :) = HE(i, :) * X5 */ i = (int) (obs->data[o].fi); + if (i == mni) + /* + * (this can happen once in a lifetime because of the + * round-off due to writing and reading fi as a float) + */ + i--; for (e = 0; e < nmem; ++e) HEi_f[e] = das->S[e][o]; sgemv_(&do_T, &nmem, &nmem, &alpha, X5j[i], &nmem, HEi_f, &inc, &beta, HEi_a, &inc); @@ -1210,6 +1220,12 @@ static void update_Hx(dasystem* das) Hx /= (double) nmem; i = (int) (obs->data[o].fi); + if (i == mni) + /* + * (this can happen once in a lifetime because of the + * round-off due to writing and reading fi as a float) + */ + i--; /* * HE(i, :) += HA(i, :) * b * 1' */ diff --git a/enkf/common/ncw.c b/enkf/common/ncw.c index 3585258b..83a45acb 100644 --- a/enkf/common/ncw.c +++ b/enkf/common/ncw.c @@ -26,7 +26,7 @@ #include #include "ncw.h" -const char ncw_version[] = "1.01"; +const char ncw_version[] = "1.03"; /* This macro is substituted in error messages instead of the name of a * variable in cases when the name could not be found by the variable id. @@ -46,7 +46,7 @@ static void quit_def(char* format, ...) fflush(stdout); - fprintf(stderr, "\nerror: libncw: "); + fprintf(stderr, "\n error: libncw: "); va_start(args, format); vfprintf(stderr, format, args); va_end(args); @@ -425,15 +425,15 @@ void ncw_rename_var(const char fname[], int ncid, const char oldname[], const ch quit("\"%s\": nc_rename_var(): failed for varid = %d (oldname = \"%s\", newname = \"%s\"): %s\n", fname, varid, oldname, newname, nc_strerror(status)); } -void ncw_put_var_int(const char fname[], int ncid, int varid, const int v[]) +void ncw_def_var_deflate(const char fname[], int ncid, int varid, int shuffle, int deflate, int deflate_level) { - int status = nc_put_var_int(ncid, varid, v); + int status = nc_def_var_deflate(ncid, varid, shuffle, deflate, deflate_level); if (status != NC_NOERR) { - char varname[NC_MAX_NAME] = STR_UNKNOWN; + char varname[NC_MAX_NAME] = "STR_UNKNOWN"; - ncw_inq_varname(fname, ncid, varid, varname); - quit("\"%s\": nc_put_var_int(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + _ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": ncw_def_var_deflate(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); } } @@ -461,6 +461,42 @@ void ncw_put_var_short(const char fname[], int ncid, int varid, const short v[]) } } +void ncw_put_var_ushort(const char fname[], int ncid, int varid, const unsigned short v[]) +{ + int status = nc_put_var_ushort(ncid, varid, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_put_var_ushort(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + } +} + +void ncw_put_var_int(const char fname[], int ncid, int varid, const int v[]) +{ + int status = nc_put_var_int(ncid, varid, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_put_var_int(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + } +} + +void ncw_put_var_uint(const char fname[], int ncid, int varid, const unsigned int v[]) +{ + int status = nc_put_var_uint(ncid, varid, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_put_var_uint(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + } +} + void ncw_put_var_float(const char fname[], int ncid, int varid, const float v[]) { int status = nc_put_var_float(ncid, varid, v); @@ -497,6 +533,18 @@ void ncw_get_var_text(const char fname[], int ncid, int varid, char v[]) } } +void ncw_get_var_schar(const char fname[], int ncid, int varid, signed char v[]) +{ + int status = nc_get_var_schar(ncid, varid, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_get_var_schar(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + } +} + void ncw_get_var_short(const char fname[], int ncid, int varid, short int v[]) { int status = nc_get_var_short(ncid, varid, v); @@ -509,6 +557,18 @@ void ncw_get_var_short(const char fname[], int ncid, int varid, short int v[]) } } +void ncw_get_var_ushort(const char fname[], int ncid, int varid, unsigned short int v[]) +{ + int status = nc_get_var_ushort(ncid, varid, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_get_var_ushort(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + } +} + void ncw_get_var_int(const char fname[], int ncid, int varid, int v[]) { int status = nc_get_var_int(ncid, varid, v); @@ -521,6 +581,18 @@ void ncw_get_var_int(const char fname[], int ncid, int varid, int v[]) } } +void ncw_get_var_uint(const char fname[], int ncid, int varid, unsigned int v[]) +{ + int status = nc_get_var_uint(ncid, varid, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_get_var_uint(): failed for varid = %d (varname = \"%s\"): %s\n", fname, varid, varname, nc_strerror(status)); + } +} + void ncw_get_var_float(const char fname[], int ncid, int varid, float v[]) { int status = nc_get_var_float(ncid, varid, v); @@ -585,6 +657,20 @@ void ncw_put_vara_short(const char fname[], int ncid, int varid, const size_t st } } +void ncw_put_vara_ushort(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const unsigned short int v[]) +{ + int status = nc_put_vara_ushort(ncid, varid, start, count, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + int ndims = 0; + + ncw_inq_varname(fname, ncid, varid, varname); + ncw_inq_varndims(fname, ncid, varid, &ndims); + quit("\"%s\": ncw_put_vara_ushort(): failed for varid = %d (varname = \"%s\"), start = %s, count = %s: %s\n", fname, varid, varname, uint2str(ndims, (unsigned int*) start), uint2str(ndims, (unsigned int*) count), nc_strerror(status)); + } +} + void ncw_put_vara_int(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const int v[]) { int status = nc_put_vara_int(ncid, varid, start, count, v); @@ -599,6 +685,20 @@ void ncw_put_vara_int(const char fname[], int ncid, int varid, const size_t star } } +void ncw_put_vara_uint(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const unsigned int v[]) +{ + int status = nc_put_vara_uint(ncid, varid, start, count, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + int ndims = 0; + + ncw_inq_varname(fname, ncid, varid, varname); + ncw_inq_varndims(fname, ncid, varid, &ndims); + quit("\"%s\": ncw_put_vara_uint(): failed for varid = %d (varname = \"%s\"), start = %s, count = %s: %s\n", fname, varid, varname, uint2str(ndims, (unsigned int*) start), uint2str(ndims, (unsigned int*) count), nc_strerror(status)); + } +} + void ncw_put_vara_float(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const float v[]) { int status = nc_put_vara_float(ncid, varid, start, count, v); @@ -861,6 +961,31 @@ void ncw_get_att_text(const char fname[], int ncid, int varid, const char attnam } } +void ncw_get_att_short(const char fname[], int ncid, int varid, const char attname[], short int v[]) +{ + nc_type xtype; + size_t len; + int status; + + ncw_inq_att(fname, ncid, varid, attname, &xtype, &len); + + if (xtype != NC_SHORT) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + _ncw_inq_varname(fname, ncid, varid, varname); + quit("ncw_get_att_short(): failed for varid = %d (varname = \"%s\"), attname = \"%s\": the attribute is of %s type\n", fname, varid, varname, attname, ncw_nctype2str(xtype)); + } + + status = nc_get_att_short(ncid, varid, attname, v); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + _ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_get_att_short(): failed for varid = %d (varname = \"%s\"), attname = \"%s\": %s\n", fname, varid, varname, attname, nc_strerror(status)); + } +} + void ncw_get_att_int(const char fname[], int ncid, int varid, const char attname[], int v[]) { nc_type xtype; @@ -1017,6 +1142,29 @@ void ncw_copy_dims(const char* fname_src, int ncid_src, const char* fname_dst, i } } +/** Copies dimension from one NetCDF file to another. + * + * @param fname_src Source file name + * @param ncid_src Source file id + * @param dimname Dimension name + * @param fname_dst Destination file name + * @param ncid_dst Destination file id + */ +void ncw_copy_dim(const char* fname_src, int ncid_src, const char dimname[], const char* fname_dst, int ncid_dst) +{ + int unlimdimid = -1; + int dimid; + size_t size; + + ncw_inq_unlimdimid(fname_src, ncid_src, &unlimdimid); + ncw_inq_dimid(fname_src, ncid_src, dimname, &dimid); + if (dimid == unlimdimid) + size = NC_UNLIMITED; + else + ncw_inq_dimlen(fname_src, ncid_src, dimid, &size); + ncw_def_dim(fname_dst, ncid_dst, dimname, size, &dimid); +} + /** Copies definition of a specified variable from one NetCDF file to another. * * @param fname_src Source file name @@ -1133,7 +1281,7 @@ void ncw_copy_vardata(const char* fname_src, int ncid_src, int vid_src, const ch nc_redef(ncid_dst); } -/** Copies definition and data for a given variable from one file to another. +/** Copies definitiona and data for a given variable from one file to another. * * @param fname_src Source file name * @param ncid_src Source file id @@ -1150,6 +1298,32 @@ void ncw_copy_var(const char* fname_src, int ncid_src, const char varname[], con ncw_copy_vardata(fname_src, ncid_src, vid_src, fname_dst, ncid_dst); } +/** Set deflation (compression) level for all variables in a file. + * + * @param fname NetCDF file name + * @param ncid NetCDF file id + * @param shuffle Shuffle flag, whatever it means + * @param deflate Flag, turns deflation on/off + * @param deflate_level Compression level + */ +void ncw_def_deflate(const char fname[], int ncid, int shuffle, int deflate, int deflate_level) +{ + int nv = -1; /* total number of variables */ + int vid; + + ncw_inq_nvars(fname, ncid, &nv); + for (vid = 0; vid < nv; ++vid) { + int status = nc_def_var_deflate(ncid, vid, shuffle, deflate, deflate_level); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = "STR_UNKNOWN"; + + _ncw_inq_varname(fname, ncid, vid, varname); + quit("\"%s\": ncw_def_deflate(): failed for \"%s\": %s\n", fname, varname, nc_strerror(status)); + } + } +} + /** Gets the id for the first dimension found to be present in a NetCDF file * out of two dimensions specified by names. Useful for handling both new and * old data formats. @@ -1597,6 +1771,44 @@ void ncw_put_var_float_record(const char fname[], int ncid, int varid, int r, fl } } +/** Checks that the attribute has certain type and length + */ +void ncw_check_att(const char fname[], int ncid, int varid, const char attname[], nc_type att_type, size_t att_len) +{ + nc_type type; + size_t len; + int status = nc_inq_att(ncid, varid, attname, &type, &len); + + if (status != NC_NOERR) { + char varname[NC_MAX_NAME] = STR_UNKNOWN; + + _ncw_inq_varname(fname, ncid, varid, varname); + quit("\"%s\": nc_inq_att(): failed for varid = %d (varname = \"%s\"), attname = \"%s\", atttype = %d: %s\n", fname, varid, varname, attname, ncw_nctype2str(type), nc_strerror(status)); + } + + if (type != att_type) + quit("\"%s\": ncw_check_att(): attribute \"%s\" is supposed to have type \"%s\"; the actual type is \"%s\"\n", fname, attname, ncw_nctype2str(att_type), ncw_nctype2str(type)); + if (len != att_len) + quit("\"%s\": ncw_check_att(): attribute \"%s\" is supposed to have length %z; the actual length is %z\n", fname, attname, att_len, len); +} + +/** Check that the dimension has certain length + */ +void ncw_check_dimlen(const char fname[], int ncid, const char dimname[], size_t dimlen) +{ + size_t len; + int dimid; + int status; + + ncw_inq_dimid(fname, ncid, dimname, &dimid); + status = nc_inq_dimlen(ncid, dimid, &len); + + if (status != NC_NOERR) + quit("\"%s\": nc_inq_dimlen(): failed for dimid = %d (dimname = \"%s\"): %s\n", fname, dimid, dimname, nc_strerror(status)); + if (len != dimlen) + quit("\"%s\": ncw_check_dimlen(): dimension \"%s\" is supposed to have length %zu; the actual length is %zu\n", fname, dimname, dimlen, len); +} + /** Sets the quit function. */ void ncw_set_quitfn(ncw_quit_fn quitfn) diff --git a/enkf/common/ncw.h b/enkf/common/ncw.h index 94229457..f0891363 100644 --- a/enkf/common/ncw.h +++ b/enkf/common/ncw.h @@ -5,7 +5,7 @@ * Created 19/10/2000 * * Author: Pavel Sakov - * CSIRO Marine Research + * Bureau of Meteorology * * Purpose: Simple wrappers to netcdf library procedures for * better error messaging. @@ -52,19 +52,26 @@ void ncw_inq_varndims(const char fname[], int ncid, int varid, int* ndims); void ncw_inq_vardimid(const char fname[], int ncid, int varid, int dimids[]); void ncw_inq_varnatts(const char fname[], int ncid, int varid, int* natts); void ncw_rename_var(const char fname[], int ncid, const char oldname[], const char newname[]); +void ncw_def_var_deflate(const char fname[], int ncid, int varid, int shuffle, int deflate, int deflate_level); void ncw_put_var_text(const char fname[], int ncid, int varid, const char v[]); void ncw_put_var_short(const char fname[], int ncid, int varid, const short int v[]); +void ncw_put_var_ushort(const char fname[], int ncid, int varid, const unsigned short int v[]); void ncw_put_var_int(const char fname[], int ncid, int varid, const int v[]); +void ncw_put_var_uint(const char fname[], int ncid, int varid, const unsigned int v[]); void ncw_put_var_float(const char fname[], int ncid, int varid, const float v[]); void ncw_put_var_double(const char fname[], int ncid, int varid, const double v[]); void ncw_get_var_text(const char fname[], int ncid, int varid, char v[]); +void ncw_get_var_schar(const char fname[], int ncid, int varid, signed char v[]); void ncw_get_var_short(const char fname[], int ncid, int varid, short int v[]); +void ncw_get_var_ushort(const char fname[], int ncid, int varid, unsigned short int v[]); void ncw_get_var_int(const char fname[], int ncid, int varid, int v[]); +void ncw_get_var_uint(const char fname[], int ncid, int varid, unsigned int v[]); void ncw_get_var_float(const char fname[], int ncid, int varid, float v[]); void ncw_get_var_double(const char fname[], int ncid, int varid, double v[]); void ncw_get_var1_double(const char fname[], int ncid, int varid, const size_t len[], double* in); void ncw_put_vara_text(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const char v[]); void ncw_put_vara_short(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const short int v[]); +void ncw_put_vara_ushort(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const unsigned short int v[]); void ncw_put_vara_int(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const int v[]); void ncw_put_vara_float(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const float v[]); void ncw_put_vara_double(const char fname[], int ncid, int varid, const size_t start[], const size_t count[], const double v[]); @@ -84,6 +91,7 @@ void ncw_copy_att(const char fname_src[], int ncid_src, int varid_src, const cha void ncw_rename_att(const char fname[], int ncid, const char varname[], const char oldname[], const char newname[]); void ncw_del_att(const char fname[], int ncid, int varid, const char name[]); void ncw_get_att_text(const char fname[], int ncid, int varid, const char attname[], char v[]); +void ncw_get_att_short(const char fname[], int ncid, int varid, const char attname[], short int v[]); void ncw_get_att_int(const char fname[], int ncid, int varid, const char attname[], int v[]); void ncw_get_att_float(const char fname[], int ncid, int varid, const char attname[], float v[]); void ncw_get_att_double(const char fname[], int ncid, int varid, const char attname[], double v[]); @@ -94,9 +102,11 @@ int ncw_inq_nrecords(const char fname[], int ncid); const char* ncw_nctype2str(nc_type type); size_t ncw_sizeof(nc_type type); void ncw_copy_dims(const char* fname_src, int ncid_src, const char* fname_dst, int ncid_dst); +void ncw_copy_dim(const char* fname_src, int ncid_src, const char dimname[], const char* fname_dst, int ncid_dst); int ncw_copy_vardef(const char* fname_src, int ncid_src, int varid_src, const char* fname_dst, int ncid_dst); void ncw_copy_vardata(const char* fname_src, int ncid_src, int varid_src, const char* fname_dst, int ncid_dst); void ncw_copy_var(const char* fname_src, int ncid_src, const char varname[], const char* fname_dst, int ncid_dst); +void ncw_def_deflate(const char fname[], int ncid, int shuffle, int deflate, int deflate_level); void ncw_inq_dimid2(const char fname[], int ncid, const char dimname1[], const char dimname2[], int* dimid); void ncw_get_att_int2(const char fname[], int ncid, int varid, const char attname1[], const char attname2[], int v[]); void ncw_find_vars(const char fname[], int ncid, int ndims, const int dims[], const char attr[], const void* attval, int* nvars, int** vids); @@ -111,6 +121,9 @@ void ncw_get_var_float_record(const char fname[], int ncid, int varid, int r, fl void ncw_put_var_double_record(const char fname[], int ncid, int varid, int r, double v[]); void ncw_put_var_float_record(const char fname[], int ncid, int varid, int r, float v[]); +void ncw_check_att(const char fname[], int ncid, int varid, const char attname[], nc_type xtype, size_t len); +void ncw_check_dimlen(const char fname[], int ncid, const char dimname[], size_t len); + typedef void (*ncw_quit_fn) (char* format, ...); void ncw_set_quitfn(ncw_quit_fn quit_fn); diff --git a/enkf/common/observations.c b/enkf/common/observations.c index 4a5e7132..7bf993c1 100644 --- a/enkf/common/observations.c +++ b/enkf/common/observations.c @@ -327,8 +327,10 @@ void obs_compact(observations* obs) enkf_flush(); assert(STATUS_OK == 0); qsort(obs->data, obs->nobs, sizeof(observation), comp_obsstatus); - for (i = 0; i < obs->nobs; ++i) + for (i = 0; i < obs->nobs; ++i) { + obs->data[i].id_orig = obs->data[i].id; obs->data[i].id = i; + } enkf_printf("\n"); enkf_flush(); obs->compacted = 1; @@ -437,13 +439,13 @@ void obs_read(observations* obs, char fname[]) int dimid_nobs[1]; size_t nobs; int varid_type, varid_product, varid_instrument, varid_id, varid_idorig, varid_fid, varid_batch, varid_value, varid_std, varid_lon, varid_lat, varid_depth, varid_mdepth, varid_fi, varid_fj, varid_fk, varid_date, varid_status, varid_aux; - int* type; - int* product; - int* instrument; int* id; int* id_orig; - int* fid; - int* batch; + short int* type; + short int* product; + short int* instrument; + short int* fid; + short int* batch; double* value; double* std; double* lon; @@ -497,13 +499,13 @@ void obs_read(observations* obs, char fname[]) ncw_inq_varid(fname, ncid, "status", &varid_status); ncw_inq_varid(fname, ncid, "aux", &varid_aux); - type = malloc(nobs * sizeof(int)); - product = malloc(nobs * sizeof(int)); - instrument = malloc(nobs * sizeof(int)); id = malloc(nobs * sizeof(int)); id_orig = malloc(nobs * sizeof(int)); - fid = malloc(nobs * sizeof(int)); - batch = malloc(nobs * sizeof(int)); + type = malloc(nobs * sizeof(short int)); + product = malloc(nobs * sizeof(short int)); + instrument = malloc(nobs * sizeof(short int)); + fid = malloc(nobs * sizeof(short int)); + batch = malloc(nobs * sizeof(short int)); value = malloc(nobs * sizeof(double)); std = malloc(nobs * sizeof(double)); lon = malloc(nobs * sizeof(double)); @@ -567,13 +569,13 @@ void obs_read(observations* obs, char fname[]) st_add_ifabscent(obs->datafiles, attstr, i); } - ncw_get_var_int(fname, ncid, varid_type, type); - ncw_get_var_int(fname, ncid, varid_product, product); - ncw_get_var_int(fname, ncid, varid_instrument, instrument); ncw_get_var_int(fname, ncid, varid_id, id); ncw_get_var_int(fname, ncid, varid_idorig, id_orig); - ncw_get_var_int(fname, ncid, varid_fid, fid); - ncw_get_var_int(fname, ncid, varid_batch, batch); + ncw_get_var_short(fname, ncid, varid_type, type); + ncw_get_var_short(fname, ncid, varid_product, product); + ncw_get_var_short(fname, ncid, varid_instrument, instrument); + ncw_get_var_short(fname, ncid, varid_fid, fid); + ncw_get_var_short(fname, ncid, varid_batch, batch); ncw_get_var_double(fname, ncid, varid_value, value); ncw_get_var_double(fname, ncid, varid_std, std); ncw_get_var_double(fname, ncid, varid_lon, lon); @@ -649,11 +651,11 @@ void obs_write(observations* obs, char fname[]) int dimid_nobs[1]; int varid_type, varid_product, varid_instrument, varid_id, varid_idorig, varid_fid, varid_batch, varid_value, varid_std, varid_lon, varid_lat, varid_depth, varid_mdepth, varid_fi, varid_fj, varid_fk, varid_date, varid_status, varid_aux; - int* type; - int* product; - int* instrument; int* id; int* id_orig; + short int* type; + short int* product; + short int* instrument; short int* fid; short int* batch; double* value; @@ -681,11 +683,11 @@ void obs_write(observations* obs, char fname[]) ncw_put_att_double(fname, ncid, NC_GLOBAL, "DA_JULDAY", 1, &obs->da_date); ncw_def_dim(fname, ncid, "nobs", nobs, dimid_nobs); + ncw_def_var(fname, ncid, "id", NC_INT, 1, dimid_nobs, &varid_id); + ncw_def_var(fname, ncid, "id_orig", NC_INT, 1, dimid_nobs, &varid_idorig); ncw_def_var(fname, ncid, "type", NC_SHORT, 1, dimid_nobs, &varid_type); ncw_def_var(fname, ncid, "product", NC_SHORT, 1, dimid_nobs, &varid_product); ncw_def_var(fname, ncid, "instrument", NC_SHORT, 1, dimid_nobs, &varid_instrument); - ncw_def_var(fname, ncid, "id", NC_INT, 1, dimid_nobs, &varid_id); - ncw_def_var(fname, ncid, "id_orig", NC_INT, 1, dimid_nobs, &varid_idorig); ncw_def_var(fname, ncid, "fid", NC_SHORT, 1, dimid_nobs, &varid_fid); ncw_def_var(fname, ncid, "batch", NC_SHORT, 1, dimid_nobs, &varid_batch); ncw_def_var(fname, ncid, "value", NC_FLOAT, 1, dimid_nobs, &varid_value); @@ -738,11 +740,11 @@ void obs_write(observations* obs, char fname[]) ncw_enddef(fname, ncid); - type = malloc(nobs * sizeof(int)); - product = malloc(nobs * sizeof(int)); - instrument = malloc(nobs * sizeof(int)); id = malloc(nobs * sizeof(int)); id_orig = malloc(nobs * sizeof(int)); + type = malloc(nobs * sizeof(short int)); + product = malloc(nobs * sizeof(short int)); + instrument = malloc(nobs * sizeof(short int)); fid = malloc(nobs * sizeof(short int)); batch = malloc(nobs * sizeof(short int)); value = malloc(nobs * sizeof(double)); @@ -790,11 +792,11 @@ void obs_write(observations* obs, char fname[]) } assert(ii == nobs); - ncw_put_var_int(fname, ncid, varid_type, type); - ncw_put_var_int(fname, ncid, varid_product, product); - ncw_put_var_int(fname, ncid, varid_instrument, instrument); ncw_put_var_int(fname, ncid, varid_id, id); ncw_put_var_int(fname, ncid, varid_idorig, id_orig); + ncw_put_var_short(fname, ncid, varid_type, type); + ncw_put_var_short(fname, ncid, varid_product, product); + ncw_put_var_short(fname, ncid, varid_instrument, instrument); ncw_put_var_short(fname, ncid, varid_fid, fid); ncw_put_var_short(fname, ncid, varid_batch, batch); ncw_put_var_double(fname, ncid, varid_value, value); @@ -935,7 +937,7 @@ void obs_superob(observations* obs, __compar_d_fn_t cmp_obs, observations** sobs so->product = o->product; so->instrument = o->instrument; so->id = nsobs; - so->id_orig = o->id; + so->id_orig = o->id_orig; so->fid = o->fid; so->batch = o->batch; diff --git a/enkf/common/observations.h b/enkf/common/observations.h index 25cd2d80..4bb2d2db 100644 --- a/enkf/common/observations.h +++ b/enkf/common/observations.h @@ -23,20 +23,28 @@ #include "obstypes.h" #include "model.h" +/* + * (we keep the integer types signed for compatibility with netcdf 3) + */ typedef struct { - int type; - int product; - int instrument; - unsigned int id; - short int fid; - short int batch; + /* + * for primary observations - the ordered number of the (compacted) + * primary observations; + * for super observations - the ordered number of superobservations + */ + int id; /* * for primary observations - the original ID corresponds to the number * of the primary observation during the very first read of data files; for * superobs - to the original ID of the very first observation merged into * this superob */ - int id_orig; + short int id_orig; + short int type; + short int product; + short int instrument; + short int fid; + short int batch; double value; double std; double lon; diff --git a/enkf/common/version.c b/enkf/common/version.c index 8111341e..13a0382a 100644 --- a/enkf/common/version.c +++ b/enkf/common/version.c @@ -13,4 +13,4 @@ * *****************************************************************************/ -char* ENKF_VERSION = "1.45.1"; +char* ENKF_VERSION = "1.45.2";