/** For files of the form ??_yyyymmdd.nc. They are assumed to have "time" * variable. */ void reader_rads_standard(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { double mindepth = MINDEPTH_DEF; char* addname = NULL; int ncid; int dimid_nobs; size_t nobs_local; int varid_lon, varid_lat, varid_pass, varid_sla, varid_time, varid_add; double* lon; double* lat; int* pass; double* sla; double* time; double error_std; double* add = NULL; size_t tunits_len; char* tunits; double tunits_multiple, tunits_offset; char* basename; char instname[3]; int mvid; float** depth; int i, ktop; for (i = 0; i < meta->npars; ++i) { if (strcasecmp(meta->pars[i].name, "MINDEPTH") == 0) { if (!str2double(meta->pars[i].value, &mindepth)) enkf_quit("observation prm file: can not convert MINDEPTH = \"%s\" to double\n", meta->pars[i].value); } else if (strcasecmp(meta->pars[i].name, "ADD") == 0) { addname = meta->pars[i].value; enkf_printf(" ADDING \"%s\"\n", addname); } else enkf_quit("unknown PARAMETER \"%s\"\n", meta->pars[i].name); } enkf_printf(" MINDEPTH = %.0f\n", mindepth); ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(ncid, "nobs", &dimid_nobs); ncw_inq_dimlen(ncid, dimid_nobs, &nobs_local); enkf_printf(" nobs = %u\n", (unsigned int) nobs_local); if (nobs_local == 0) { ncw_close(ncid); return; } ncw_inq_varid(ncid, "lon", &varid_lon); lon = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_lon, lon); ncw_inq_varid(ncid, "lat", &varid_lat); lat = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_lat, lat); ncw_inq_varid(ncid, "pass", &varid_pass); pass = malloc(nobs_local * sizeof(int)); ncw_get_var_int(ncid, varid_pass, pass); ncw_inq_varid(ncid, "sla", &varid_sla); sla = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_sla, sla); ncw_get_att_double(ncid, varid_sla, "error_std", &error_std); enkf_printf(" error_std = %3g\n", error_std); if (addname != NULL) { ncw_inq_varid(ncid, addname, &varid_add); add = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_add, add); } ncw_inq_varid(ncid, "time", &varid_time); time = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_time, time); ncw_inq_attlen(ncid, varid_time, "units", &tunits_len); tunits = calloc(tunits_len + 1, 1); ncw_get_att_text(ncid, varid_time, "units", tunits); ncw_close(ncid); tunits_convert(tunits, &tunits_multiple, &tunits_offset); basename = strrchr(fname, '/'); if (basename == NULL) basename = fname; else basename += 1; strncpy(instname, basename, 2); instname[2] = 0; mvid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type, 1)].varnames[0], 1); ktop = grid_gettoplayerid(model_getvargrid(m, mvid)); depth = model_getdepth(m, mvid, 1); for (i = 0; i < (int) nobs_local; ++i) { observation* o; obstype* ot; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type, 1); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, instname, -1); o->id = obs->nobs; o->fid = fid; o->batch = pass[i]; o->value = sla[i]; if (add != NULL) o->value += add[i]; o->std = error_std; o->lon = lon[i]; o->lat = lat[i]; o->depth = 0.0; o->status = model_xy2fij(m, mvid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) continue; o->fk = (double) ktop; o->model_depth = (isnan(o->fi + o->fj)) ? NaN : depth[(int) (o->fj + 0.5)][(int) (o->fi + 0.5)]; o->date = time[i] * tunits_multiple + tunits_offset; if (o->status == STATUS_OK && o->model_depth < mindepth) o->status = STATUS_SHALLOW; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->aux = -1; obs->nobs++; } if (add != NULL) free(add); free(lon); free(lat); free(pass); free(sla); free(tunits); free(time); }
void reader_windsat_standard(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { int ncid; int dimid_nobs; size_t nobs_local; int varid_lon, varid_lat, varid_sst, varid_error, varid_time; double* lon; double* lat; double* sst; double* error_std; double* time; int year, month, day; char tunits[MAXSTRLEN]; size_t tunits_len; double tunits_multiple, tunits_offset; char* basename; int mvid; float** depth; int ktop; int i; for (i = 0; i < meta->npars; ++i) enkf_quit("unknown PARAMETER \"%s\"\n", meta->pars[i].name); basename = strrchr(fname, '/'); if (basename == NULL) basename = fname; else basename += 1; ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(ncid, "nobs", &dimid_nobs); ncw_inq_dimlen(ncid, dimid_nobs, &nobs_local); enkf_printf(" nobs = %u\n", (unsigned int) nobs_local); if (nobs_local == 0) { ncw_close(ncid); return; } ncw_inq_varid(ncid, "lon", &varid_lon); lon = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_lon, lon); ncw_inq_varid(ncid, "lat", &varid_lat); lat = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_lat, lat); ncw_inq_varid(ncid, "sst", &varid_sst); sst = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_sst, sst); ncw_inq_varid(ncid, "error", &varid_error); error_std = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_error, error_std); ncw_inq_varid(ncid, "age", &varid_time); time = malloc(nobs_local * sizeof(double)); ncw_get_var_double(ncid, varid_time, time); ncw_inq_attlen(ncid, varid_time, "units", &tunits_len); ncw_get_att_text(ncid, varid_time, "units", tunits); basename[16] = 0; if (!str2int(&basename[14], &day)) enkf_quit("WindSat reader: could not convert file name \"%s\" to date", fname); basename[14] = 0; if (!str2int(&basename[12], &month)) enkf_quit("WindSat reader: could not convert file name \"%s\" to date", fname); basename[12] = 0; if (!str2int(&basename[8], &year)) enkf_quit("WindSat reader: could not convert file name \"%s\" to date", fname); snprintf(&tunits[tunits_len], MAXSTRLEN - tunits_len, " since %4d-%02d-%02d", year, month, day); ncw_close(ncid); tunits_convert(tunits, &tunits_multiple, &tunits_offset); mvid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type, 1)].varnames[0], 1); ktop = grid_gettoplayerid(model_getvargrid(m, mvid)); depth = model_getdepth(m, mvid, 0); for (i = 0; i < (int) nobs_local; ++i) if (time[i] != 0.0) break; if (i == (int) nobs_local) for (i = 0; i < (int) nobs_local; ++i) time[i] = 0.5; for (i = 0; i < (int) nobs_local; ++i) { observation* o; obstype* ot; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type, 1); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, "WindSat", -1); o->id = obs->nobs; o->fid = fid; o->batch = 0; o->value = sst[i]; o->std = error_std[i]; o->lon = lon[i]; o->lat = lat[i]; o->depth = 0.0; o->fk = (double) ktop; o->status = model_xy2fij(m, mvid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) continue; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax || o->depth <= ot->zmin || o->depth >= ot->zmax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->model_depth = (depth == NULL || isnan(o->fi + o->fj)) ? NaN : depth[(int) (o->fj + 0.5)][(int) (o->fi + 0.5)]; o->date = time[i] * tunits_multiple + tunits_offset; o->aux = -1; obs->nobs++; } free(lon); free(lat); free(sst); free(error_std); free(time); }
void reader_mmt_standard(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { int ncid; int dimid_nprof, dimid_nz; size_t nprof, nz; int varid_lon, varid_lat, varid_z, varid_type; int varid_v = -1; double* lon; double* lat; double** z; double** v; double missval; double validmin = DBL_MAX; double validmax = -DBL_MAX; char* type; char buf[MAXSTRLEN]; int len; int year, month, day; double tunits_multiple, tunits_offset; int mvid; int p, i; for (i = 0; i < meta->npars; ++i) enkf_quit("unknown PARAMETER \"%s\"\n", meta->pars[i].name); if (meta->nstds == 0) enkf_quit("ERROR_STD is necessary but not specified for product \"%s\"", meta->product); ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(fname, ncid, "N_PROF", &dimid_nprof); ncw_inq_dimlen(fname, ncid, dimid_nprof, &nprof); ncw_inq_dimid(fname, ncid, "N_LEVELS", &dimid_nz); ncw_inq_dimlen(fname, ncid, dimid_nz, &nz); enkf_printf(" # profiles = %u\n", (unsigned int) nprof); if (nprof == 0) { ncw_close(fname, ncid); return; } enkf_printf(" # z levels = %u\n", (unsigned int) nz); ncw_inq_varid(fname, ncid, "LONGITUDE", &varid_lon); lon = malloc(nprof * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lon, lon); ncw_inq_varid(fname, ncid, "LATITUDE", &varid_lat); lat = malloc(nprof * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lat, lat); ncw_inq_varid(fname, ncid, "PRES_BLUELINK", &varid_z); z = alloc2d(nprof, nz, sizeof(double)); ncw_get_var_double(fname, ncid, varid_z, z[0]); if (strncmp(meta->type, "TEM", 3) == 0) { validmin = -2.0; validmax = 40.0; ncw_inq_varid(fname, ncid, "TEMP_BLUELINK", &varid_v); } else if (strncmp(meta->type, "SAL", 3) == 0) { validmin = 0; validmax = 50.0; ncw_inq_varid(fname, ncid, "PSAL_BLUELINK", &varid_v); } else enkf_quit("observation type \"%s\" not handled for MMT product", meta->type); v = alloc2d(nprof, nz, sizeof(double)); ncw_get_var_double(fname, ncid, varid_v, v[0]); ncw_get_att_double(fname, ncid, varid_v, "_FillValue", &missval); ncw_inq_varid(fname, ncid, "WMO_INST_TYPE", &varid_type); type = malloc(nprof * WMO_INSTSIZE); ncw_get_var_text(fname, ncid, varid_type, type); ncw_close(fname, ncid); strcpy(buf, fname); len = strlen(buf); buf[len - 10] = 0; /* _mmt_qc.nc */ if (!str2int(&buf[len - 12], &day)) enkf_quit("MMT reader: could not convert file name \"%s\" to date", fname); buf[len - 12] = 0; if (!str2int(&buf[len - 14], &month)) enkf_quit("MMT reader: could not convert file name \"%s\" to date", fname); buf[len - 14] = 0; if (!str2int(&buf[len - 18], &year)) enkf_quit("MMT reader: could not convert file name \"%s\" to date", fname); snprintf(buf, MAXSTRLEN, "days since %4d-%02d-%02d", year, month, day); tunits_convert(buf, &tunits_multiple, &tunits_offset); mvid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type)].varname, 1); for (p = 0; p < (int) nprof; ++p) { char inststr[MAXSTRLEN]; snprintf(inststr, MAXSTRLEN, "WMO%04u", type[p * WMO_INSTSIZE]); for (i = 0; i < (int) nz; ++i) { observation* o; obstype* ot; if (fabs(v[p][i] - missval) < EPS || v[p][i] < validmin || v[p][i] > validmax) continue; if (z[p][i] < 0.0) continue; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type); assert(o->type >= 0); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, inststr, -1); o->id = obs->nobs; o->fid = fid; o->batch = p; o->value = v[p][i]; o->std = 0.0; o->lon = lon[p]; o->lat = lat[p]; o->depth = z[p][i]; o->status = model_xy2fij(m, mvid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) break; if (o->status == STATUS_OK) o->status = model_z2fk(m, mvid, o->fi, o->fj, o->depth, &o->fk); else o->fk = NaN; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax || o->depth <= ot->zmin || o->depth >= ot->zmax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->date = tunits_offset + 0.5; o->aux = -1; obs->nobs++; } } free(lon); free(lat); free2d(v); free2d(z); free(type); }
void reader_cars_standard(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { int ncid; int dimid_nprof, dimid_nz = -1; size_t nprof, nz; int varid_lon, varid_lat, varid_z, varid_type; int varid_v = -1; double* lon; double* lat; double** z; double** v; double missval, validmin, validmax; int* type; char buf[MAXSTRLEN]; int len; int year, month, day; double tunits_multiple, tunits_offset; int mvid; float** depth; int p, i; for (i = 0; i < meta->npars; ++i) enkf_quit("unknown PARAMETER \"%s\"\n", meta->pars[i].name); if (meta->nstds == 0) enkf_quit("ERROR_STD is necessary but not specified for product \"%s\"", meta->product); ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(ncid, "nobs", &dimid_nprof); ncw_inq_dimlen(ncid, dimid_nprof, &nprof); enkf_printf(" # profiles = %u\n", (unsigned int) nprof); if (nprof == 0) { ncw_close(ncid); return; } if (ncw_dim_exists(ncid, "zt")) ncw_inq_dimid(ncid, "zt", &dimid_nz); else if (ncw_dim_exists(ncid, "ztd")) ncw_inq_dimid(ncid, "ztd", &dimid_nz); else enkf_quit("reader_cars_standard(): neither dimension \"zt\" ot \"ztd\" exist"); ncw_inq_dimlen(ncid, dimid_nz, &nz); enkf_printf(" # z levels = %u\n", (unsigned int) nz); ncw_inq_varid(ncid, "lon", &varid_lon); lon = malloc(nprof * sizeof(double)); ncw_get_var_double(ncid, varid_lon, lon); ncw_inq_varid(ncid, "lat", &varid_lat); lat = malloc(nprof * sizeof(double)); ncw_get_var_double(ncid, varid_lat, lat); ncw_inq_varid(ncid, "zt", &varid_z); z = alloc2d(nprof, nz, sizeof(double)); ncw_get_var_double(ncid, varid_z, z[0]); if (strncmp(meta->type, "TEM", 3) == 0) ncw_inq_varid(ncid, "temp", &varid_v); else if (strncmp(meta->type, "SAL", 3) == 0) ncw_inq_varid(ncid, "salt", &varid_v); else enkf_quit("observation type \"%s\" not handled for CARS product", meta->type); v = alloc2d(nprof, nz, sizeof(double)); ncw_get_var_double(ncid, varid_v, v[0]); ncw_get_att_double(ncid, varid_v, "missing_value", &missval); ncw_get_att_double(ncid, varid_v, "valid_min", &validmin); ncw_get_att_double(ncid, varid_v, "valid_max", &validmax); ncw_inq_varid(ncid, "type", &varid_type); type = malloc(nprof * sizeof(int)); ncw_get_var_int(ncid, varid_type, type); ncw_close(ncid); strcpy(buf, fname); len = strlen(buf); buf[len - 3] = 0; /* .nc */ if (!str2int(&buf[len - 5], &day)) enkf_quit("CARS reader: could not convert file name \"%s\" to date", fname); buf[len - 17] = 0; if (!str2int(&buf[len - 19], &month)) enkf_quit("CARS reader: could not convert file name \"%s\" to date", fname); buf[len - 21] = 0; if (!str2int(&buf[len - 25], &year)) enkf_quit("CARS reader: could not convert file name \"%s\" to date", fname); snprintf(buf, MAXSTRLEN, "days since %4d-%02d-%02d", year, month, day); tunits_convert(buf, &tunits_multiple, &tunits_offset); mvid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type, 1)].varnames[0], 1); depth = model_getdepth(m, mvid, 0); for (p = 0; p < (int) nprof; ++p) { char inststr[MAXSTRLEN]; if (type[p] == 11) strcpy(inststr, "ARGO"); else if (type[p] == 12) strcpy(inststr, "TAO"); else if (type[p] == 61) strcpy(inststr, "PIRATA"); else if (type[p] == 7 || type[p] == 9 || type[p] == 13 || type[p] == 35 || type[p] == 41) strcpy(inststr, "CTD"); else if (type[p] == 8 || type[p] == 17) strcpy(inststr, "XBT"); else snprintf(inststr, MAXSTRLEN, "CARS%02u", type[p]); for (i = 0; i < (int) nz; ++i) { observation* o; obstype* ot; if (fabs(v[p][i] - missval) < EPS || v[p][i] < validmin || v[p][i] > validmax) continue; if (z[p][i] < 0.0) continue; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type, 1); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, inststr, -1); o->id = obs->nobs; o->fid = fid; o->batch = p; o->value = v[p][i]; o->std = 0.0; o->lon = lon[p]; o->lat = lat[p]; o->depth = z[p][i]; o->status = model_xy2fij(m, mvid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) break; if (o->status == STATUS_OK) o->status = model_z2fk(m, mvid, o->fi, o->fj, o->depth, &o->fk); else o->fk = NaN; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax || o->depth <= ot->zmin || o->depth >= ot->zmax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->model_depth = (depth == NULL || isnan(o->fi + o->fj)) ? NaN : depth[(int) (o->fj + 0.5)][(int) (o->fi + 0.5)]; o->date = tunits_offset + 0.5; o->aux = -1; obs->nobs++; } } free(lon); free(lat); free(v); free(z); free(type); }
void reader_navo_standard(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { int addbias = ADDBIAS_DEF; int ncid; int dimid_nobs; size_t nobs_local; int varid_lon, varid_lat, varid_sst, varid_sstb, varid_error, varid_time; double* lon = NULL; double* lat = NULL; double* sst = NULL; double* sstb = NULL; double* error_std = NULL; double* time = NULL; int year, month, day; char tunits[MAXSTRLEN]; size_t tunits_len; double tunits_multiple, tunits_offset; char* basename; int model_vid; int k, i; for (i = 0; i < meta->npars; ++i) { if (strcasecmp(meta->pars[i].name, "ADDBIAS") == 0) addbias = (istrue(meta->pars[i].value)) ? 1 : 0; else enkf_quit("unknown PARAMETER \"%s\"\n", meta->pars[i].name); } enkf_printf(" ADDBIAS = %s\n", (addbias) ? "YES" : "NO"); basename = strrchr(fname, '/'); if (basename == NULL) basename = fname; else basename += 1; ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(fname, ncid, (ncw_dim_exists(ncid, "nobs")) ? "nobs" : "length", &dimid_nobs); ncw_inq_dimlen(fname, ncid, dimid_nobs, &nobs_local); enkf_printf(" nobs = %u\n", (unsigned int) nobs_local); if (nobs_local == 0) { ncw_close(fname, ncid); return; } ncw_inq_varid(fname, ncid, "lon", &varid_lon); lon = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lon, lon); ncw_inq_varid(fname, ncid, "lat", &varid_lat); lat = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lat, lat); ncw_inq_varid(fname, ncid, "sst", &varid_sst); sst = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_sst, sst); if (addbias) { ncw_inq_varid(fname, ncid, "SST_bias", &varid_sstb); sstb = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_sstb, sstb); } ncw_inq_varid(fname, ncid, "error", &varid_error); error_std = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_error, error_std); ncw_inq_varid(fname, ncid, "GMT_time", &varid_time); time = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_time, time); ncw_inq_attlen(fname, ncid, varid_time, "units", &tunits_len); ncw_get_att_text(fname, ncid, varid_time, "units", tunits); basename[13] = 0; if (!str2int(&basename[11], &day)) enkf_quit("NAVO reader: could not convert file name \"%s\" to date", fname); basename[11] = 0; if (!str2int(&basename[9], &month)) enkf_quit("NAVO reader: could not convert file name \"%s\" to date", fname); basename[9] = 0; if (!str2int(&basename[5], &year)) enkf_quit("NAVO reader: could not convert file name \"%s\" to date", fname); snprintf(&tunits[tunits_len], MAXSTRLEN - tunits_len, " since %4d-%02d-%02d", year, month, day); ncw_close(fname, ncid); tunits_convert(tunits, &tunits_multiple, &tunits_offset); model_vid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type)].varname, 1); k = grid_gettoplayerid(model_getvargrid(m, model_vid)); for (i = 0; i < (int) nobs_local; ++i) { observation* o; obstype* ot; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type); assert(o->type >= 0); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, "AVHRR", -1); o->id = obs->nobs; o->fid = fid; o->batch = 0; o->value = (addbias) ? sst[i] + sstb[i] : sst[i]; o->std = error_std[i]; o->lon = lon[i]; o->lat = lat[i]; o->depth = 0.0; o->status = model_xy2fij(m, model_vid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) continue; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax || o->depth <= ot->zmin || o->depth >= ot->zmax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->fk = (double) k; o->date = time[i] * tunits_multiple + tunits_offset; o->aux = -1; obs->nobs++; } free(lon); free(lat); free(sst); if (addbias) free(sstb); free(error_std); free(time); }
/** For files of the form ??_yyyymmdd.nc. They are assumed to have "time" * variable. */ void reader_rads_standard(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { int ncid; int dimid_nobs; size_t nobs_local; int varid_lon, varid_lat, varid_pass, varid_sla, varid_time; double* lon; double* lat; int* pass; double* sla; double* time; double error_std; size_t tunits_len; char* tunits; double tunits_multiple, tunits_offset; char* basename; char instname[3]; int mvid; float** depth; int i; ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(fname, ncid, "nobs", &dimid_nobs); ncw_inq_dimlen(fname, ncid, dimid_nobs, &nobs_local); enkf_printf(" nobs = %u\n", (unsigned int) nobs_local); if (nobs_local == 0) { ncw_close(fname, ncid); return; } ncw_inq_varid(fname, ncid, "lon", &varid_lon); lon = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lon, lon); ncw_inq_varid(fname, ncid, "lat", &varid_lat); lat = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lat, lat); ncw_inq_varid(fname, ncid, "pass", &varid_pass); pass = malloc(nobs_local * sizeof(int)); ncw_get_var_int(fname, ncid, varid_pass, pass); ncw_inq_varid(fname, ncid, "sla", &varid_sla); sla = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_sla, sla); ncw_get_att_double(fname, ncid, varid_sla, "error_std", &error_std); enkf_printf(" error_std = %3g\n", error_std); ncw_inq_varid(fname, ncid, "time", &varid_time); time = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_time, time); ncw_inq_attlen(fname, ncid, varid_time, "units", &tunits_len); tunits = calloc(tunits_len + 1, 1); ncw_get_att_text(fname, ncid, varid_time, "units", tunits); ncw_close(fname, ncid); tunits_convert(tunits, &tunits_multiple, &tunits_offset); basename = strrchr(fname, '/'); if (basename == NULL) basename = fname; else basename += 1; strncpy(instname, basename, 2); instname[2] = 0; mvid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type)].varname, 1); depth = model_getdepth(m, mvid); for (i = 0; i < (int) nobs_local; ++i) { observation* o; obstype* ot; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type); assert(o->type >= 0); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, instname, -1); o->id = obs->nobs; o->fid = fid; o->batch = pass[i]; o->value = sla[i]; o->std = error_std; o->lon = lon[i]; o->lat = lat[i]; o->depth = 0.0; o->status = model_xy2fij(m, mvid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) continue; o->fk = 0.0; o->date = time[i] * tunits_multiple + tunits_offset; if (o->status == STATUS_OK && depth[(int) floor(o->fj + 0.5)][(int) floor(o->fi + 0.5)] < MINDEPTH) o->status = STATUS_SHALLOW; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax || o->depth <= ot->zmin || o->depth >= ot->zmax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->aux = -1; obs->nobs++; } free(lon); free(lat); free(pass); free(sla); free(tunits); free(time); }
/** For files of the form y<yyyy>/m<mm>/??_d<dd>.nc with no "time" variable. */ void reader_rads_standard2(char* fname, int fid, obsmeta* meta, model* m, observations* obs) { int ncid; int dimid_nobs; size_t nobs_local; int varid_lon, varid_lat, varid_pass, varid_sla, varid_flag; double* lon; double* lat; int* pass; double* sla; int* flag; double error_std; char buf[MAXSTRLEN]; int len; int year, month, day; double tunits_multiple, tunits_offset; char* basename; char instname[3]; int mvid; float** depth; int i; ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(fname, ncid, "nobs", &dimid_nobs); ncw_inq_dimlen(fname, ncid, dimid_nobs, &nobs_local); enkf_printf(" nobs = %u\n", (unsigned int) nobs_local); if (nobs_local == 0) return; ncw_inq_varid(fname, ncid, "lon", &varid_lon); lon = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lon, lon); ncw_inq_varid(fname, ncid, "lat", &varid_lat); lat = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_lat, lat); ncw_inq_varid(fname, ncid, "pass", &varid_pass); pass = malloc(nobs_local * sizeof(int)); ncw_get_var_int(fname, ncid, varid_pass, pass); ncw_inq_varid(fname, ncid, "sla", &varid_sla); sla = malloc(nobs_local * sizeof(double)); ncw_get_var_double(fname, ncid, varid_sla, sla); ncw_get_att_double(fname, ncid, varid_sla, "error_std", &error_std); enkf_printf(" error_std = %3g\n", error_std); ncw_inq_varid(fname, ncid, "local_flag", &varid_flag); flag = malloc(nobs_local * sizeof(int)); ncw_get_var_int(fname, ncid, varid_flag, flag); ncw_close(fname, ncid); strcpy(buf, fname); len = strlen(buf); buf[len - 3] = 0; /* .nc */ if (!str2int(&buf[len - 5], &day)) enkf_quit("RADS reader: could not convert file name \"%s\" to date", fname); buf[len - 10] = 0; if (!str2int(&buf[len - 12], &month)) enkf_quit("RADS reader: could not convert file name \"%s\" to date", fname); buf[len - 14] = 0; if (!str2int(&buf[len - 18], &year)) enkf_quit("RADS reader: could not convert file name \"%s\" to date", fname); snprintf(buf, MAXSTRLEN, "days since %4d-%02d-%02d", year, month, day); tunits_convert(buf, &tunits_multiple, &tunits_offset); basename = strrchr(fname, '/'); if (basename == NULL) basename = fname; else basename += 1; strncpy(instname, basename, 2); instname[2] = 0; mvid = model_getvarid(m, obs->obstypes[obstype_getid(obs->nobstypes, obs->obstypes, meta->type)].varname, 1); depth = model_getdepth(m, mvid); for (i = 0; i < (int) nobs_local; ++i) { observation* o; obstype* ot; if (flag[i] != 0) continue; obs_checkalloc(obs); o = &obs->data[obs->nobs]; o->product = st_findindexbystring(obs->products, meta->product); assert(o->product >= 0); o->type = obstype_getid(obs->nobstypes, obs->obstypes, meta->type); assert(o->type >= 0); ot = &obs->obstypes[o->type]; o->instrument = st_add_ifabscent(obs->instruments, instname, -1); o->id = obs->nobs; o->fid = fid; o->batch = pass[i]; o->value = sla[i]; o->std = error_std; o->lon = lon[i]; o->lat = lat[i]; o->depth = 0.0; o->status = model_xy2fij(m, mvid, o->lon, o->lat, &o->fi, &o->fj); if (!obs->allobs && o->status == STATUS_OUTSIDEGRID) continue; o->fk = 0.0; o->date = tunits_offset + 0.5; if (o->status == STATUS_OK && depth[(int) floor(o->fj + 0.5)][(int) floor(o->fi + 0.5)] < MINDEPTH) o->status = STATUS_SHALLOW; if ((o->status == STATUS_OK) && (o->lon <= ot->xmin || o->lon >= ot->xmax || o->lat <= ot->ymin || o->lat >= ot->ymax || o->depth <= ot->zmin || o->depth >= ot->zmax)) o->status = STATUS_OUTSIDEOBSDOMAIN; o->aux = -1; obs->nobs++; } free(lon); free(lat); free(pass); free(sla); free(flag); }