int model_xy2fij(model* m, int vid, double x, double y, double* fi, double* fj) { void* grid = m->grids[m->vars[vid].gridid]; int** numlevels = grid_getnumlevels(grid); int lontype = grid_getlontype(grid); int ni, nj; int i1, i2, j1, j2; if (lontype == LONTYPE_180) { if (x > 180.0) x -= 360.0; } else if (lontype == LONTYPE_360) { if (x < 0.0) x += 360.0; } grid_xy2fij(grid, x, y, fi, fj); if (isnan(*fi + *fj)) return STATUS_OUTSIDEGRID; /* * Note that this section should be consistent with similar sections in * interpolate2d() and interpolate3d(). */ i1 = floor(*fi); i2 = ceil(*fi); j1 = floor(*fj); j2 = ceil(*fj); model_getvardims(m, vid, &ni, &nj, NULL); if (i1 == -1) i1 = (grid_isperiodic_x(model_getvargrid(m, vid))) ? ni - 1 : i2; if (i2 == ni) i2 = (grid_isperiodic_x(model_getvargrid(m, vid))) ? 0 : i1; if (j1 == -1) j1 = (grid_isperiodic_y(model_getvargrid(m, vid))) ? nj - 1 : j2; if (i2 == nj) j2 = (grid_isperiodic_y(model_getvargrid(m, vid))) ? 0 : j1; if (numlevels[j1][i1] == 0 && numlevels[j1][i2] == 0 && numlevels[j2][i1] == 0 && numlevels[j2][i2] == 0) { *fi = NaN; *fj = NaN; return STATUS_LAND; } return STATUS_OK; }
/** 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_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); }