diff --git a/ChangeLog b/ChangeLog index e303d4c29b06961843d0717e9c4d5d97a39bb621..47afedfd921455ad2beaf95e6dbef18c8c2ad11e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-10-18 Uwe Schulzweida + + * PMList::read_cmor_table: added call to parse_namelist() (bug fix) + 2024-10-14 Uwe Schulzweida * Arith: fix problem with number of step of first stream when filling up timesteps diff --git a/src/CMOR_lite.cc b/src/CMOR_lite.cc index 25183cd058716820d8dfd35803b51568a009d1d5..3f93b728d682dcb06b2f485bc3ecf71b0dd61eeb 100644 --- a/src/CMOR_lite.cc +++ b/src/CMOR_lite.cc @@ -146,37 +146,40 @@ cmor_check_prep(CmorVar &var, long gridsize, double missval, const double *const } static void -apply_cmor_list(PMList &pmlist, int vlistID2, std::vector<CmorVar> &cmorVars) +search_global_missval(PMList &pmlist, int vlistID2, bool &hasMissvals, double &missval) { static const std::vector<std::string> hentry = { "Header" }; - static const std::vector<std::string> ventry = { "variable_entry", "parameter" }; + auto kvlist = pmlist.getKVListVentry(hentry); + if (kvlist) + { + for (const auto &kv : *kvlist) + { + const auto &key = kv.key; + const auto &value = kv.values[0]; + if (kv.nvalues != 1 || value.empty()) continue; + + if (key == "missing_value") + { + hasMissvals = true; + missval = parameter_to_double(value); + } + else if (key == "table_id" || key == "modeling_realm" || key == "realm" || key == "project_id" || key == "frequency") + { + cdiDefAttTxt(vlistID2, CDI_GLOBAL, key.c_str(), (int) value.size(), value.c_str()); + } + } + } +} +static void +apply_cmor_list(PMList &pmlist, int vlistID2, std::vector<CmorVar> &cmorVars) +{ // search for global missing value auto hasMissvals = false; double missval = 0.0; + search_global_missval(pmlist, vlistID2, hasMissvals, missval); - { - auto kvlist = pmlist.getKVListVentry(hentry); - if (kvlist) - { - for (const auto &kv : *kvlist) - { - const auto &key = kv.key; - const auto &value = kv.values[0]; - if (kv.nvalues != 1 || value.empty()) continue; - - if (key == "missing_value") - { - hasMissvals = true; - missval = parameter_to_double(value); - } - else if (key == "table_id" || key == "modeling_realm" || key == "realm" || key == "project_id" || key == "frequency") - { - cdiDefAttTxt(vlistID2, CDI_GLOBAL, key.c_str(), (int) value.size(), value.c_str()); - } - } - } - } + static const std::vector<std::string> ventry = { "variable_entry", "parameter" }; int numVars = cmorVars.size(); for (int varID = 0; varID < numVars; ++varID) @@ -310,7 +313,6 @@ public: int vlistID2; int taxisID2; - int numVars; std::vector<CmorVar> cmorVars; VarList varList2; @@ -321,9 +323,7 @@ public: Options::CMOR_Mode = 1; if (Options::CMOR_Mode) cdiDefGlobal("CMOR_MODE", Options::CMOR_Mode); - auto operatorID = cdo_operator_id(); - - operator_input_arg(cdo_operator_enter(operatorID)); + operator_input_arg(cdo_operator_enter(cdo_operator_id())); if (cdo_operator_argc() < 1) cdo_abort("Too few arguments!"); @@ -343,7 +343,7 @@ public: vlistID1 = cdo_stream_inq_vlist(streamID1); vlistID2 = vlistDuplicate(vlistID1); - numVars = vlistNvars(vlistID2); + auto numVars = vlistNvars(vlistID2); cmorVars = std::vector<CmorVar>(numVars); if (convertData) diff --git a/src/Setpartab.cc b/src/Setpartab.cc index 6d5c0e5e1e96577b34babd529ed1c959aabe693e..e5c7d629eef8e9ffada7c36f798ae49116bd7846 100644 --- a/src/Setpartab.cc +++ b/src/Setpartab.cc @@ -197,9 +197,29 @@ mapvar(int vlistID, int varID, const KeyValues &kv, CmorVar &cmorVar, bool &hasV } static void -apply_parameterList(pt_mode_t ptmode, PMList &pmlist, int vlistID2, std::vector<CmorVar> &cmorVars) +search_global_missval(PMList &pmlist, bool &hasMissvals, double &missval) { const std::vector<std::string> hentry = { "Header" }; + auto kvlist = pmlist.getKVListVentry(hentry); + if (kvlist) + { + auto kv = kvlist->search("missing_value"); + if (kv && kv->nvalues > 0) + { + hasMissvals = true; + missval = parameter_to_double(kv->values[0]); + } + } +} + +static void +apply_parameterList(pt_mode_t ptmode, PMList &pmlist, int vlistID2, std::vector<CmorVar> &cmorVars) +{ + // search for global missing value + auto hasMissvals = false; + double missval = 0.0; + search_global_missval(pmlist, hasMissvals, missval); + const std::vector<std::string> ventry = { "variable_entry", "parameter" }; char valstr[CDI_MAX_NAME]; char paramstr[32]; @@ -207,23 +227,6 @@ apply_parameterList(pt_mode_t ptmode, PMList &pmlist, int vlistID2, std::vector< VarList varList2(vlistID2); - // search for global missing value - auto hasMissvals = false; - double missval = 0.0; - - { - auto kvlist = pmlist.getKVListVentry(hentry); - if (kvlist) - { - auto kv = kvlist->search("missing_value"); - if (kv && kv->nvalues > 0) - { - hasMissvals = true; - missval = parameter_to_double(kv->values[0]); - } - } - } - int numVarsFound = 0; int numVars = cmorVars.size(); for (int varID = 0; varID < numVars; ++varID) diff --git a/src/cmortable_parser.cc b/src/cmortable_parser.cc index 78642fb95a16b0de07d57552ec4853d79feda21b..e38a8f08cd561b047d14dc533ea04e24f8523d90 100644 --- a/src/cmortable_parser.cc +++ b/src/cmortable_parser.cc @@ -131,7 +131,7 @@ parse_cmortable_buffer(PMList &pmlist, size_t buffersize, char *buffer) pline = skipSeparator(pline); pline = getElementValue(pline); - std::vector<std::string> pppline= {std::string(pline)}; + std::vector<std::string> pppline = { std::string(pline) }; if (*pline) kvlist.append("name", pppline, 1); } else @@ -141,8 +141,8 @@ parse_cmortable_buffer(PMList &pmlist, size_t buffersize, char *buffer) pline = getElementValue(pline); if (kvlist.size() == 0) kvlist.name = "Header"; - - std::vector<std::string> pppline= {std::string(pline)}; + + std::vector<std::string> pppline = { std::string(pline) }; if (*pline) kvlist.append(name, pppline, 1); } } @@ -340,6 +340,8 @@ PMList::read_cmor_table(FILE *fp, const char *name) NamelistParser p; auto status = parse_list_buffer(p, listBuffer); if (status) cdo_abort("Namelist not found!"); + + parse_namelist(*this, p, listBuffer.buffer.data(), false); } else cdo_abort("Invalid CMOR table (file: %s)!", name);