void obstypes_read(char fname[], int* n, obstype** types, double rfactor_base) { FILE* f = NULL; char buf[MAXSTRLEN]; int line; obstype* now = NULL; int i; assert(*n == 0); f = enkf_fopen(fname, "r"); line = 0; while (fgets(buf, MAXSTRLEN, f) != NULL) { char seps[] = " =\t\n"; char* token; line++; if (buf[0] == '#') continue; if ((token = strtok(buf, seps)) == NULL) continue; if (strcasecmp(token, "NAME") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: NAME not specified", fname, line); if (obstype_getid(*n, *types, token) >= 0) enkf_quit("%s: l.%d: type \"%s\" already specified", fname, line, token); *types = realloc(*types, (*n + 1) * sizeof(obstype)); now = &(*types)[*n]; obstype_new(now, *n, token); (*n)++; continue; } if (now == NULL) enkf_quit("%s, l.%d: NAME not specified", fname, line); if (strcasecmp(token, "ISSURFACE") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: ISSURFACE not specified", fname, line); now->issurface = read_bool(token); if (now->issurface < 0) enkf_quit("%s, l.%d: could not convert \"%s\" to boolean", fname, line, token); } else if (strcasecmp(token, "VAR") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: VAR not specified", fname, line); if (now->varname != NULL) enkf_quit("%s, l.%d: VAR already specified", fname, line); now->varname = strdup(token); } else if (strcasecmp(token, "VAR2") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: VAR2 not specified", fname, line); if (now->varname2 != NULL) enkf_quit("%s, l.%d: VAR2 already specified", fname, line); now->varname2 = strdup(token); } else if (strcasecmp(token, "OFFSET") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: OFFSET file name not specified", fname, line); if (now->offset_fname != NULL) enkf_quit("%s, l.%d: OFFSET entry already specified", fname, line); now->offset_fname = strdup(token); if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: OFFSET variable name not specified", fname, line); now->offset_varname = strdup(token); } else if (strcasecmp(token, "HFUNCTION") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: HFUNCTION not specified", fname, line); if (now->hfunction != NULL) enkf_quit("%s, l.%d: HFUNCTION already specified", fname, line); now->hfunction = strdup(token); } else if (strcasecmp(token, "MINVALUE") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: MINVALUE not specified", fname, line); if (!str2double(token, &now->allowed_min)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "MAXVALUE") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: MAXVALUE not specified", fname, line); if (!str2double(token, &now->allowed_max)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strncasecmp(token, "ASYNC", 5) == 0) { now->isasync = 1; if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: ASYNC time interval not specified", fname, line); if (!str2double(token, &now->async_tstep)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "RFACTOR") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: RFACTOR not specified", fname, line); if (!str2double(token, &now->rfactor)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "XMIN") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: XMIN not specified", fname, line); if (!str2double(token, &now->xmin)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "XMAX") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: XMAX not specified", fname, line); if (!str2double(token, &now->xmax)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "YMIN") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: YMIN not specified", fname, line); if (!str2double(token, &now->ymin)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "YMAX") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: YMAX not specified", fname, line); if (!str2double(token, &now->ymax)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "ZMIN") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: ZMIN not specified", fname, line); if (!str2double(token, &now->zmin)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else if (strcasecmp(token, "ZMAX") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: ZMAX not specified", fname, line); if (!str2double(token, &now->zmax)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", fname, line, token); } else enkf_quit("%s, l.%d: unknown token \"%s\"", fname, line, token); } fclose(f); for (i = 0; i < *n; ++i) (*types)[i].rfactor *= rfactor_base; for (i = 0; i < *n; ++i) { obstype_check(&(*types)[i]); obstype_print(&(*types)[i]); } }
model* model_create(enkfprm* prm) { model* m = calloc(1, sizeof(model)); char* modelprm = prm->modelprm; char* gridprm = prm->gridprm; model_setgrids(m, gridprm); /* * read model parameter file */ { FILE* f = NULL; char buf[MAXSTRLEN]; int line; variable* now = NULL; /* * get model tag, type and variables */ f = enkf_fopen(modelprm, "r"); line = 0; while (fgets(buf, MAXSTRLEN, f) != NULL) { char seps[] = " =\t\n"; char* token = NULL; line++; if (buf[0] == '#') continue; if ((token = strtok(buf, seps)) == NULL) continue; if (strcasecmp(token, "NAME") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: NAME not specified", modelprm, line); else if (m->name != NULL) enkf_quit("%s, l.%d: NAME specified twice", modelprm, line); else m->name = strdup(token); } else if (strncasecmp(token, "VAR", 3) == 0) { int i; if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: VAR not specified", modelprm, line); for (i = 0; i < m->nvar; ++i) if (strcasecmp(m->vars[i].name, token) == 0) enkf_quit("%s, l.%d: VAR \"%s\" already specified", modelprm, line, token); if (m->nvar % NVAR_INC == 0) m->vars = realloc(m->vars, (m->nvar + NVAR_INC) * sizeof(variable)); now = &m->vars[m->nvar]; variable_new(now, m->nvar, token); m->nvar++; } else if (strcasecmp(token, "GRID") == 0) { int i; if (now == NULL) enkf_quit("%s, l.%d: VAR not specified", modelprm, line); if (now->gridid >= 0) enkf_quit("%s, l.%d: GRID already specified for \"%s\"", modelprm, line, now->name); if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: GRID not specified", modelprm, line); for (i = 0; i < m->ngrid; ++i) if (strcasecmp(token, grid_getname(m->grids[i])) == 0) { now->gridid = i; break; } if (i == m->ngrid) enkf_quit("%s, l.%d: grid \"%s\" not specified", modelprm, line, token); } else if (strcasecmp(token, "INFLATION") == 0) { if (now == NULL) enkf_quit("%s, l.%d: VAR not specified", modelprm, line); if (!isnan(now->inflation)) enkf_quit("%s, l.%d: INFLATION already specified for \"%s\"", modelprm, line, now->name); if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: INFLATION not specified", modelprm, line); if (!str2double(token, &now->inflation)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", modelprm, line, token); if ((token = strtok(NULL, seps)) != NULL) { if (!str2double(token, &now->inf_ratio)) enkf_quit("%s, l.%d: could not convert \"%s\" to double", modelprm, line, token); } } else enkf_quit("%s, l.%d: unknown token \"%s\"", modelprm, line, token); } /* while reading modelprm */ fclose(f); assert(m->name != NULL); assert(m->nvar > 0); { int i; for (i = 0; i < m->nvar; ++i) if (m->vars[i].gridid == -1) { if (m->ngrid == 1) m->vars[i].gridid = 0; else enkf_quit("%s: grid not specified for variable \"%s\"\n", modelprm, m->vars[i].name); } } } /* * set inflations */ { int i; for (i = 0; i < m->nvar; ++i) if (isnan(m->vars[i].inflation)) { m->vars[i].inflation = prm->inflation_base; m->vars[i].inf_ratio = prm->inf_ratio; } prm->inflation_base = NaN; prm->inf_ratio = NaN; } model_print(m, " "); assert(m->ngrid > 0); return m; }
void obsmeta_read(enkfprm* prm, int* nmeta, obsmeta** meta) { char* fname = prm->obsprm; FILE* f = NULL; char buf[MAXSTRLEN]; int line; obsmeta* m = NULL; int i, j; *nmeta = 0; *meta = NULL; f = enkf_fopen(fname, "r"); line = 0; while (fgets(buf, MAXSTRLEN, f) != NULL) { char seps[] = " =\t\n"; char* token; line++; if (buf[0] == '#') continue; if ((token = strtok(buf, seps)) == NULL) continue; if (strcasecmp(token, "PRODUCT") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: PRODUCT not specified", fname, line); *meta = realloc(*meta, (*nmeta + 1) * sizeof(obsmeta)); m = &(*meta)[*nmeta]; obsmeta_init(m); m->product = strdup(token); (*nmeta)++; } else if (strcasecmp(token, "READER") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: READER not specified", fname, line); m->reader = strdup(token); } else if (strcasecmp(token, "TYPE") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: TYPE not specified", fname, line); m->type = strdup(token); } else if (strcasecmp(token, "FILE") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: FILE not specified", fname, line); obsmeta_addfname(m, token); } else if (strcasecmp(token, "ERROR_STD") == 0) { if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: STD not specified", fname, line); else { double std; m->stdtypes = realloc(m->stdtypes, (m->nstds + 1) * sizeof(int)); m->stdops = realloc(m->stdops, (m->nstds + 1) * sizeof(int)); m->stds = realloc(m->stds, (m->nstds + 1) * sizeof(void*)); m->varnames = realloc(m->varnames, (m->nstds + 1) * sizeof(char*)); if (str2double(token, &std)) { if (!isfinite(std) || std < 0.0) enkf_quit("%s, l.%d: invalid STD value", fname, line); m->stdtypes[m->nstds] = STDTYPE_VALUE; m->stds[m->nstds] = malloc(sizeof(double)); *((double*) m->stds[m->nstds]) = std; m->varnames[m->nstds] = NULL; } else { m->stdtypes[m->nstds] = STDTYPE_FILE; m->stds[m->nstds] = strdup(token); if ((token = strtok(NULL, seps)) == NULL) enkf_quit("%s, l.%d: variable name not specified", fname, line); m->varnames[m->nstds] = strdup(token); } if ((token = strtok(NULL, seps)) == NULL) m->stdops[m->nstds] = ARITHMETIC_EQ; else if (strncasecmp(token, "EQ", 2) == 0) m->stdops[m->nstds] = ARITHMETIC_EQ; else if (strncasecmp(token, "PL", 2) == 0) m->stdops[m->nstds] = ARITHMETIC_PLUS; else if (strncasecmp(token, "MU", 2) == 0) m->stdops[m->nstds] = ARITHMETIC_MULT; else if (strncasecmp(token, "MI", 2) == 0) m->stdops[m->nstds] = ARITHMETIC_MIN; else if (strncasecmp(token, "MA", 2) == 0) m->stdops[m->nstds] = ARITHMETIC_MAX; else enkf_quit("%s, l.%d:, unknown operation", fname, line); m->nstds++; } } else enkf_quit("%s, l.%d: unknown token \"%s\"", fname, line, token); } fclose(f); /* * print summary */ for (i = 0; i < (*nmeta); ++i) { obsmeta* m = &(*meta)[i]; enkf_printf(" PRODUCT = %s\n", m->product); if (m->reader == NULL) { m->reader = strdup("standard"); enkf_printf(" (assumed) READER = %s\n", m->reader); } else enkf_printf(" READER = %s\n", m->reader); if (m->type == NULL) enkf_quit("%s: obsservation type not specified for product \"%s\"", fname, m->product); enkf_printf(" TYPE = %s\n", m->type); for (j = 0; j < m->nfiles; ++j) enkf_printf(" File: obsmeta.c = %s\n", m->fnames[j]); for (j = 0; j < m->nstds; ++j) { char operstr[MAXSTRLEN] = ""; if (m->stdops[j] == ARITHMETIC_EQ) strcpy(operstr, "EQUAL"); else if (m->stdops[j] == ARITHMETIC_PLUS) strcpy(operstr, "PLUS"); else if (m->stdops[j] == ARITHMETIC_MULT) strcpy(operstr, "MULT"); else if (m->stdops[j] == ARITHMETIC_MIN) strcpy(operstr, "MIN"); else if (m->stdops[j] == ARITHMETIC_MAX) strcpy(operstr, "MAX"); if (m->stdtypes[j] == STDTYPE_VALUE) enkf_printf(" ERROR_STD = %.3g, operation = %s\n", *((double*) m->stds[j]), operstr); else if (m->stdtypes[j] == STDTYPE_FILE) enkf_printf(" ERROR_STD = %s %s, operation = %s\n", (char*) m->stds[j], m->varnames[j], operstr); } } /* * check asynchronous obs types */ do { for (j = 0; j < prm->nasync; ++j) { for (i = 0; i < (*nmeta); ++i) { obsmeta* m = &(*meta)[i]; if (strcmp(m->type, prm->async_types[j]) == 0) break; } if (i == (*nmeta)) { int k; enkf_printf(" WARNING: %s: asynchronous type \"%s\" not in obs\n", prm->fname, prm->async_types[j]); /* * eliminate redundant entry */ for (k = j; k < prm->nasync - 1; ++k) prm->async_types[k] = prm->async_types[k + 1]; prm->nasync--; } } } while (j != prm->nasync); }