Commit 52c8dd68 authored by Uwe Schulzweida's avatar Uwe Schulzweida

Exprf: added support for same variable name with different number of levels.

parent 183023f7
Pipeline #5515 passed with stages
in 15 minutes and 49 seconds
......@@ -2,6 +2,10 @@
* Version 1.9.10 release
2020-12-15 Uwe Schulzweida
* Exprf: added support for same variable name with different number of levels
2020-11-23 Uwe Schulzweida
* Ymonarith: failed with variables on different grids
......
......@@ -222,6 +222,7 @@ params_init(std::vector<paramType> &params, const VarList &varList, int vlistID)
vlistInqVarUnits(vlistID, varID, units);
params[varID].type = PARAM_VAR;
params[varID].isValid = true;
params[varID].select = false;
params[varID].remove = false;
params[varID].lmiss = true;
......@@ -587,7 +588,7 @@ Expr(void *process)
{
if (parse_arg.coords[i].needed)
{
const int coord = parse_arg.coords[i].coord;
const auto coord = parse_arg.coords[i].coord;
if (coord == 'x' || coord == 'y' || coord == 'a' || coord == 'w')
{
auto gridID = parse_arg.coords[i].cdiID;
......@@ -643,7 +644,7 @@ Expr(void *process)
for (int varID = parse_arg.nvars1; varID < parse_arg.nparams; varID++)
{
const int coord = params[varID].coord;
const auto coord = params[varID].coord;
if (coord)
{
if (coord == 'x' || coord == 'y' || coord == 'a' || coord == 'w')
......@@ -704,6 +705,8 @@ Expr(void *process)
cdoDefTimestep(streamID2, tsID);
//for (int varID = 0; varID < nvars1; varID++) printf(">>> %s %d\n", params[varID].name, params[varID].isValid);
for (int varID = 0; varID < nvars1; varID++) params[varID].isValid = true;
for (int varID = 0; varID < nvars1; varID++)
if (tsID == 0 || params[varID].steptype != TIME_CONSTANT) params[varID].nmiss = 0;
......
......@@ -55,9 +55,9 @@ static constexpr double COMPGE(const double x, const double y) noexcept { return
static constexpr double COMPNE(const double x, const double y) noexcept { return IS_NOT_EQUAL(x, y); }
static constexpr double COMPEQ(const double x, const double y) noexcept { return IS_EQUAL(x, y); }
static constexpr double COMPLEG(const double x, const double y) noexcept { return (x < y) ? -1. : (x > y); }
static constexpr double COMPAND(const double x, const double y) noexcept { return IS_NOT_EQUAL(x, 0) && IS_NOT_EQUAL(y, 0); }
static constexpr double COMPOR(const double x, const double y) noexcept { return IS_NOT_EQUAL(x, 0) || IS_NOT_EQUAL(y, 0); }
static constexpr double COMPNOT(const double x) noexcept { return IS_EQUAL(x, 0); }
static constexpr double COMPAND(const double x, const double y) noexcept { return IS_NOT_EQUAL(x, 0.0) && IS_NOT_EQUAL(y, 0.0); }
static constexpr double COMPOR(const double x, const double y) noexcept { return IS_NOT_EQUAL(x, 0.0) || IS_NOT_EQUAL(y, 0.0); }
static constexpr double COMPNOT(const double x) noexcept { return IS_EQUAL(x, 0.0); }
static inline double MVCOMPLT(const double x, const double y, const double m) noexcept { return DBL_IS_EQUAL(x, m) ? m : COMPLT(x, y); }
static inline double MVCOMPGT(const double x, const double y, const double m) noexcept { return DBL_IS_EQUAL(x, m) ? m : COMPGT(x, y); }
static inline double MVCOMPLE(const double x, const double y, const double m) noexcept { return DBL_IS_EQUAL(x, m) ? m : COMPLE(x, y); }
......@@ -73,9 +73,9 @@ static double f_int(const double x) { return (int) (x); }
static double f_nint(const double x) { return std::round(x); }
static double f_rand(const double x) { (void)x; return ((double) std::rand()) / ((double) RAND_MAX); }
static double f_sqr(const double x) { return x * x; }
static double f_rad(const double x) { return x * M_PI / 180.; }
static double f_deg(const double x) { return x * 180. / M_PI; }
static double f_isMissval(const double x) { (void)x; return 0; }
static double f_rad(const double x) { return x * M_PI / 180.0; }
static double f_deg(const double x) { return x * 180.0 / M_PI; }
static double f_isMissval(const double x) { (void)x; return 0.0; }
static double pt_ngp(const paramType *const p) { return p->ngp; }
static double pt_nlev(const paramType *const p) { return p->nlev; }
static double pt_size(const paramType *const p) { return p->ngp * p->nlev; }
......@@ -1053,6 +1053,9 @@ fun1c(int init, int funcID, nodeType *p1, double value, parseParamType *parse_ar
if (p1->type != typeVar) cdoAbort("Parameter of function %s() needs to be a variable!", funcname);
if (p1->ltmpobj) cdoAbort("Temporary objects not allowed in function %s()!", funcname);
if (parse_arg->debug)
cdoPrint("\t%s\tfunc\t%s=%s(%s[N%zu][L%zu], %g)", ExIn[init], tmpvnm, funcname, p1->param.name, p1->param.ngp, p1->param.nlev, value);
const auto ngp = p1->param.ngp;
const auto nlev = p1->param.nlev;
auto nmiss = p1->param.nmiss;
......@@ -1096,7 +1099,7 @@ fun1c(int init, int funcID, nodeType *p1, double value, parseParamType *parse_ar
size_t levidx = 0;
if (cdo_cmpstr(funcname, "sellevidx"))
{
const long ilevidx = std::lround(value);
const auto ilevidx = std::lround(value);
if (ilevidx < 1 || ilevidx > (long) nlev)
cdoAbort("%s(): level index %ld out of range (range: 1-%zu)!", funcname, ilevidx, nlev);
levidx = (size_t) ilevidx - 1;
......@@ -1138,6 +1141,9 @@ fun2c(int init, int funcID, nodeType *p1, double value1, double value2, parsePar
if (p1->type != typeVar) cdoAbort("Parameter of function %s() needs to be a variable!", funcname);
if (p1->ltmpobj) cdoAbort("Temporary objects not allowed in function %s()!", funcname);
if (parse_arg->debug)
cdoPrint("\t%s\tfunc\t%s=%s(%s[N%zu][L%zu], %g, %g)", ExIn[init], tmpvnm, funcname, p1->param.name, p1->param.ngp, p1->param.nlev, value1, value2);
const auto ngp = p1->param.ngp;
const auto nlev = p1->param.nlev;
auto nmiss = p1->param.nmiss;
......@@ -1265,7 +1271,7 @@ coord_fun(const int init, const int funcID, nodeType *p1, parseParamType *parse_
double *restrict pdata = p->param.data;
double *restrict p1data = p1->param.data;
for ( size_t i = 0; i < ngp*nlev; i++ ) pdata[i] = p1data[i];
for (size_t i = 0; i < ngp*nlev; i++) pdata[i] = p1data[i];
*/
}
/*
......@@ -1614,7 +1620,7 @@ ex_ifelse(const int init, nodeType *p1, nodeType *p2, nodeType *p3)
if (nmiss1 && DBL_IS_EQUAL(ival1, missval1))
odat[i] = missval1;
else if (IS_NOT_EQUAL(ival1, 0))
else if (IS_NOT_EQUAL(ival1, 0.0))
odat[i] = DBL_IS_EQUAL(ival2, missval2) ? missval1 : ival2;
else
odat[i] = DBL_IS_EQUAL(ival3, missval3) ? missval1 : ival3;
......@@ -1657,23 +1663,29 @@ int exNode(nodeType *p, parseParamType *parse_arg)
static int
param_search_name(const int nparam, const paramType *params, const char *name)
{
// for (int varID = nparam - 1; varID >= 0; --varID)
for (int varID = 0; varID < nparam; ++varID)
{
if (cdo_cmpstr(params[varID].name, name)) return varID;
if (params[varID].isValid && cdo_cmpstr(params[varID].name, name)) return varID;
}
return -1;
}
static int
param_search_name_size(const int nparam, const paramType *params, const char *name, size_t ngp, size_t nlev)
param_search_name_size(const int nparam, paramType *params, const char *name, size_t ngp, size_t nlev)
{
// for (int varID = nparam - 1; varID >= 0; --varID)
if (ngp == 0) ngp = 1;
if (nlev == 0) nlev = 1;
for (int varID = 0; varID < nparam; ++varID)
{
if (ngp == params[varID].ngp && nlev == params[varID].nlev)
if (cdo_cmpstr(params[varID].name, name)) return varID;
if (cdo_cmpstr(params[varID].name, name))
{
if (ngp == params[varID].ngp && nlev == params[varID].nlev)
return varID;
else
params[varID].isValid = false;
}
}
return -1;
......@@ -1709,6 +1721,7 @@ add_new_constant(const char *varname, parseParamType *parse_arg, paramType *para
param_meta_copy(params[varID], param);
params[varID].type = PARAM_CONST;
params[varID].isValid = true;
params[varID].ngp = 1;
params[varID].nlat = 1;
params[varID].nlev = 1;
......@@ -1722,11 +1735,11 @@ add_new_constant(const char *varname, parseParamType *parse_arg, paramType *para
static void
add_new_param(const char *varname, parseParamType *parse_arg, paramType *params, const paramType &param)
{
// printf(" create %s\n", varname);
const auto varID = parse_arg->nparams;
if (varID >= parse_arg->maxparams) cdoAbort("Too many parameter (limit=%d)", parse_arg->maxparams);
param_meta_copy(params[varID], param);
params[varID].isValid = true;
params[varID].lmiss = param.lmiss;
params[varID].name = strdup(varname);
params[varID].nmiss = param.nmiss;
......@@ -1787,6 +1800,7 @@ expr_run_type_var_grid(const char *vnm, int coord, parseParamType *parse_arg)
const auto units = parse_arg->coords[coordID].units.data();
const auto longname = parse_arg->coords[coordID].longname.data();
params[nvarID].isValid = true;
params[nvarID].coord = coord;
params[nvarID].lmiss = false;
params[nvarID].name = strdup(vnm);
......@@ -1826,6 +1840,7 @@ expr_run_type_var_zaxis(const char *vnm, int coord, parseParamType *parse_arg)
const auto units = parse_arg->coords[coordID].units.data();
const auto longname = parse_arg->coords[coordID].longname.data();
params[nvarID].isValid = true;
params[nvarID].coord = coord;
params[nvarID].lmiss = false;
params[nvarID].name = strdup(vnm);
......@@ -1872,7 +1887,7 @@ expr_run_type_var(nodeType *p, parseParamType *parse_arg)
if (varID == -1)
{
cdoAbort("Variable >%s< not found!", p->u.var.nm);
cdoAbort("Variable >%s< not found!", vnm);
}
else if (init)
{
......@@ -1937,7 +1952,7 @@ expr_run_type_fun2c(nodeType *p, parseParamType *parse_arg)
}
else
{
cdoAbort("Syntax error in call to %s(), check number of parameter!\n", p->u.fun1c.name);
cdoAbort("Syntax error in call to %s(), check number of parameter!\n", p->u.fun2c.name);
}
return nullptr;
......@@ -2007,8 +2022,8 @@ expr_run_type_opr(nodeType *p, parseParamType *parse_arg)
cdoPrint("\tpop\tconst\t%s", varname2);
}
//auto varID = param_search_name_size(parse_arg->nparams, params, varname2, rnode->param.ngp, rnode->param.nlev);
auto varID = param_search_name(parse_arg->nparams, params, varname2);
//auto varID = param_search_name(parse_arg->nparams, params, varname2);
auto varID = param_search_name_size(parse_arg->nparams, params, varname2, rnode->param.ngp, rnode->param.nlev);
if (init)
{
if (varID >= 0)
......
......@@ -107,6 +107,7 @@ enum
struct paramType
{
int type;
bool isValid;
bool select;
bool remove;
bool lmiss;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment