Esempio n. 1
0
File: model.c Progetto: sakov/enkf-c
int model_z2fk(model* m, int vid, double fi, double fj, double z, double* fk)
{
    void* grid = m->grids[m->vars[vid].gridid];
    int isperiodic_x = grid_isperiodic_x(grid);
    int** numlevels = grid_getnumlevels(grid);
    int ni, nj;
    int i1, i2, j1, j2, k2;

    if (isnan(fi + fj)) {
        *fk = NaN;
        return STATUS_OUTSIDEGRID;
    }

    grid_z2fk(grid, fi, fj, z, fk);

    if (isnan(*fk))
        return STATUS_OUTSIDEGRID;

    if (grid_getvtype(grid) == GRIDVTYPE_SIGMA)
         return STATUS_OK;

    /*
     * a depth check for z-grid:
     */
    model_getvardims(m, vid, &ni, &nj, NULL);
    i1 = floor(fi);
    i2 = ceil(fi);
    if (i1 == -1)
        i1 = (isperiodic_x) ? ni - 1 : i2;
    if (i2 == ni)
        i2 = (isperiodic_x) ? 0 : i1;
    j1 = floor(fj);
    j2 = ceil(fj);
    if (j1 == -1)
        j1 = j2;
    if (j2 == nj)
        j2 = j1;
    k2 = floor(*fk);
    if (numlevels[j1][i1] <= k2 && numlevels[j1][i2] <= k2 && numlevels[j2][i1] <= k2 && numlevels[j2][i2] <= k2) {
        *fk = NaN;
        return STATUS_LAND;
    } else if (numlevels[j1][i1] <= k2 || numlevels[j1][i2] <= k2 || numlevels[j2][i1] <= k2 || numlevels[j2][i2] <= k2) {
        float** depth = grid_getdepth(grid);
        int ni, nj;
        double v;

        grid_getdims(grid, &ni, &nj, NULL);

        v = interpolate2d(fi, fj, ni, nj, depth, numlevels, grid_isperiodic_x(grid));

        if (z > v)
            return STATUS_LAND;
    }

    return STATUS_OK;
}
Esempio n. 2
0
void reader_cars_standard(char* fname, int fid, obsmeta* meta, grid* g, 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 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);

    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_ifabsent(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 = grid_xy2fij(g, o->lon, o->lat, &o->fi, &o->fj);
            if (!obs->allobs && o->status == STATUS_OUTSIDEGRID)
                break;
            if (o->status == STATUS_OK)
                o->status = grid_z2fk(g, 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 = NAN;       /* set in obs_add() */
            o->date = tunits_offset + 0.5;
            o->aux = -1;

            obs->nobs++;
        }
    }

    free(lon);
    free(lat);
    free(v);
    free(z);
    free(type);
}
Esempio n. 3
0
int model_z2fk(model* m, int vid, double fi, double fj, double z, double* fk)
{
    return grid_z2fk(m->grids[m->vars[vid].gridid], fi, fj, z, fk);
}