/** Replaces observation errors in the observation file with the modified * values. The original values are stored as "std_orig". */ void das_addmodifiederrors(dasystem* das, char fname[]) { int ncid; int dimid_nobs[1]; size_t nobs; int varid_std; double* std; int i; if (rank != 0) return; ncw_open(fname, NC_WRITE, &ncid); ncw_inq_dimid(fname, ncid, "nobs", dimid_nobs); ncw_inq_dimlen(fname, ncid, dimid_nobs[0], &nobs); ncw_redef(fname, ncid); if (ncw_var_exists(ncid, "std_orig")) enkf_quit("\"observations.nc\" has already been modified by `enkf_calc\'. To proceed please remove observations*.nc and rerun `enkf_prep\'."); ncw_rename_var(fname, ncid, "std", "std_orig"); ncw_def_var(fname, ncid, "std", NC_FLOAT, 1, dimid_nobs, &varid_std); ncw_enddef(fname, ncid); std = malloc(nobs * sizeof(double)); for (i = 0; i < (int) nobs; ++i) std[i] = das->obs->data[i].std; ncw_put_var_double(fname, ncid, varid_std, std); free(std); ncw_close(fname, ncid); }
/** Adds forecast observations and forecast ensemble spread to the observation * file. */ void das_addforecast(dasystem* das, char fname[]) { int ncid; int dimid_nobs[1]; size_t nobs; int varid_Hx, varid_spread; double* Hx; int o; if (das->obs->nobs == 0) return; if (rank != 0) return; assert(das->s_mode == S_MODE_HA_f); ncw_open(fname, NC_WRITE, &ncid); if (ncw_var_exists(ncid, "Hx_f")) { enkf_printf(" Hx already added to \"%s\" (skipping)\n", fname); goto finish; } ncw_inq_dimid(fname, ncid, "nobs", dimid_nobs); ncw_inq_dimlen(fname, ncid, dimid_nobs[0], &nobs); ncw_redef(fname, ncid); ncw_def_var(fname, ncid, "Hx_f", NC_FLOAT, 1, dimid_nobs, &varid_Hx); ncw_def_var(fname, ncid, "std_f", NC_FLOAT, 1, dimid_nobs, &varid_spread); ncw_enddef(fname, ncid); Hx = calloc(nobs, sizeof(double)); for (o = 0; o < (int) nobs; ++o) Hx[o] = das->obs->data[o].value - das->s_f[o]; ncw_put_var_double(fname, ncid, varid_Hx, Hx); ncw_put_var_double(fname, ncid, varid_spread, das->std_f); free(Hx); finish: ncw_close(fname, ncid); }
/** Add analysed observation estimates and ensemble spread to FNAME_SOBS. */ void das_addanalysis(dasystem* das, char fname[]) { int ncid; int dimid_nobs[1]; size_t nobs; int varid_Hx, varid_spread; observation* data = das->obs->data; double* s; int i; if (rank != 0) return; assert(das->s_mode == S_MODE_HA_a); ncw_open(fname, NC_WRITE, &ncid); ncw_inq_dimid(fname, ncid, "nobs", dimid_nobs); ncw_inq_dimlen(fname, ncid, dimid_nobs[0], &nobs); ncw_redef(fname, ncid); ncw_def_var(fname, ncid, "Hx_a", NC_FLOAT, 1, dimid_nobs, &varid_Hx); ncw_def_var(fname, ncid, "std_a", NC_FLOAT, 1, dimid_nobs, &varid_spread); ncw_enddef(fname, ncid); ncw_put_var_double(fname, ncid, varid_spread, das->std_a); s = malloc(nobs * sizeof(double)); /* * the obs are still sorted by ij */ for (i = 0; i < (int) nobs; ++i) s[data[i].id] = data[i].value; for (i = 0; i < (int) nobs; ++i) s[i] -= das->s_a[i]; ncw_put_var_double(fname, ncid, varid_Hx, s); free(s); ncw_close(fname, ncid); }
/** Replaces observation errors in the observation file with the modified * values. The original values are stored as "std_orig". */ void das_addmodifiederrors(dasystem* das, char fname[]) { int ncid; int dimid_nobs[1]; size_t nobs; int varid_std; double* std; int i; double da_julday = NaN; if (rank != 0) return; ncw_open(fname, NC_WRITE, &ncid); ncw_inq_dimid(ncid, "nobs", dimid_nobs); ncw_inq_dimlen(ncid, dimid_nobs[0], &nobs); ncw_get_att_double(ncid, NC_GLOBAL, "DA_JULDAY", &da_julday); if (!enkf_noobsdatecheck && (isnan(da_julday) || fabs(das->obs->da_date - da_julday) > 1e-6)) enkf_quit("\"observations.nc\" from a different cycle"); if (ncw_var_exists(ncid, "std_orig")) { enkf_printf(" nothing to do\n"); ncw_close(ncid); return; } ncw_redef(ncid); ncw_rename_var(ncid, "std", "std_orig"); ncw_def_var(ncid, "std", NC_FLOAT, 1, dimid_nobs, &varid_std); ncw_enddef(ncid); std = malloc(nobs * sizeof(double)); for (i = 0; i < (int) nobs; ++i) std[i] = das->obs->data[i].std; ncw_put_var_double(ncid, varid_std, std); free(std); ncw_close(ncid); }