From a4d7e0b950afe2fb25ee66ff9436a7d786e1cc6f Mon Sep 17 00:00:00 2001 From: Michael Uleysky Date: Wed, 12 Apr 2023 13:06:33 +1000 Subject: [PATCH] Variable name is now set explicitly in function Read() arguments --- include/layereddata.h | 21 ++++++++++++---- include/odm.h | 19 +++++++++------ src/actiontsc.cpp | 19 +++++++++------ src/layereddata.cpp | 56 +++++++++++++------------------------------ 4 files changed, 57 insertions(+), 58 deletions(-) diff --git a/include/layereddata.h b/include/layereddata.h index 1f79e43..0943721 100644 --- a/include/layereddata.h +++ b/include/layereddata.h @@ -132,8 +132,7 @@ class LayeredData protected: struct Parameters: public BaseParameters { - size_t xb, yb, xe, ye, layer; - MString varname; + size_t xb, yb, xe, ye, layer; virtual ~Parameters() override = default; }; @@ -147,7 +146,7 @@ class LayeredData std::pair Parameters(michlib_internal::ParameterListEx& pars, const CLArgs& args) const; - Data Read(const BaseParameters* ip, size_t i) const; + Data Read(const MString& vname, const BaseParameters* ip, size_t i) const; bool isOk() const { return nc.size() > 0; } @@ -184,10 +183,24 @@ class LayeredData // clang-format on } + bool CheckVar(const MString& vname) const + { + if(!HaveVar(vname)) + { + bool varexist = false; + if(vname == "temp" && HaveVar("ptemp") && HaveVar("sal")) varexist = true; + if(vname == "ptemp" && HaveVar("temp") && HaveVar("sal")) varexist = true; + if(vname == "pdens" && (HaveVar("ptemp") || HaveVar("temp")) && HaveVar("sal")) varexist = true; + if((vname == "U" || vname == "U2") && HaveVar("u") && HaveVar("v")) varexist = true; + if(!varexist) return false; + } + return true; + } + private: template Data ReadVarRaw(const NC& f, const MString& name, size_t i, bool nodepth, const struct Parameters* p) const; - bool HaveVar(const MString vname) const + bool HaveVar(const MString& vname) const { for(size_t i = 0; i < nc.size(); i++) { diff --git a/include/odm.h b/include/odm.h index 50a4e70..21a95e1 100644 --- a/include/odm.h +++ b/include/odm.h @@ -1,7 +1,7 @@ #pragma once #include "BFileW.h" -#include "NEMO.h" #include "HYCOM.h" +#include "NEMO.h" #include #include @@ -10,7 +10,7 @@ using michlib::errmessage; using michlib::GPL; using michlib::message; -using DataVariants = std::variant; +using DataVariants = std::variant; template concept InfoSupported = requires(T t) { @@ -27,15 +27,15 @@ concept ParametersSupported = requires(T t, michlib_internal::ParameterListEx& p }; template -concept ReadPSupported = requires(T t, const BaseParameters* ip, size_t i) { +concept ReadPSupported = requires(T t, const MString& vname, const BaseParameters* ip, size_t i) { { - t.template Read(ip, i)(0) + t.template Read(vname, ip, i)(0) } -> std::convertible_to; }; template -concept ReadSupported = requires(T t, size_t i) { +concept ReadSupported = requires(T t, const MString& vname, size_t i) { { - t.template Read(i)(0) + t.template Read(vname, i)(0) } -> std::convertible_to; }; @@ -133,6 +133,11 @@ class Data: public DataVariants return std::visit([](const auto& arg) -> auto { return arg.NTimes(); }, *this); } + auto CheckVar(const MString& vname) const + { + return std::visit([&vname = std::as_const(vname)](const auto& arg) -> auto { return arg.CheckVar(vname); }, *this); + } + MString Init(const CLArgs& args) { MString src = args.contains("source") ? args.at("source") : ""; @@ -147,7 +152,7 @@ class Data: public DataVariants else if(src == "HYCOM") { HYCOMData data; - auto res = data.Open(args); + auto res = data.Open(args); if(res.Exist()) return "Can't open source " + src + ":\n" + res; *this = Data(std::move(data)); } diff --git a/src/actiontsc.cpp b/src/actiontsc.cpp index d3f2cca..afad0b6 100644 --- a/src/actiontsc.cpp +++ b/src/actiontsc.cpp @@ -31,6 +31,11 @@ MString Data::ActionTsc(const CLArgs& args) pars.SetParameter("timee", te.ToString()); } + if(!args.contains("var")) return "Variable not specified"; + MString vname = args.at("var"); + if(!CheckVar(vname)) return "Variable " + vname + " not exists in this dataset"; + pars.SetParameter("variable", vname); + std::unique_ptr sourcepars; { std::pair ppar = std::visit( @@ -49,13 +54,13 @@ MString Data::ActionTsc(const CLArgs& args) auto p = sourcepars.get(); size_t ind; - auto read = [p = p, &ind = ind](const auto& arg) -> BaseData + auto read = [&vname = std::as_const(vname), p = p, &ind = ind](const auto& arg) -> BaseData { using T = std::decay_t; if constexpr(ParametersSupported && ReadPSupported) - return arg.Read(p, ind); + return arg.Read(vname, p, ind); else if constexpr(!ParametersSupported && ReadSupported) - return arg.Read(ind); + return arg.Read(vname, ind); else return BaseData(); }; @@ -63,8 +68,8 @@ MString Data::ActionTsc(const CLArgs& args) BaseData data; if(tindexes.size() == 1) { - ind = tindexes[0]; - michlib::message("Time: "+Time(ind).ToTString()); + ind = tindexes[0]; + michlib::message("Time: " + Time(ind).ToTString()); data = std::visit(read, *this); } else @@ -74,8 +79,8 @@ MString Data::ActionTsc(const CLArgs& args) for(size_t i = 0; i < tindexes.size(); i++) { if(!ok) break; - ind = tindexes[i]; - michlib::message("Time: "+Time(ind).ToTString()); + ind = tindexes[i]; + michlib::message("Time: " + Time(ind).ToTString()); auto dat = std::visit(read, *this); if(dat) out.Add(dat); diff --git a/src/layereddata.cpp b/src/layereddata.cpp index 7828919..559a356 100644 --- a/src/layereddata.cpp +++ b/src/layereddata.cpp @@ -141,17 +141,6 @@ std::pair LayeredData::Parameters(michlib_intern { std::unique_ptr ppar{new struct Parameters}; - if(!args.contains("var")) return {nullptr, "Variable not specified"}; - ppar->varname = args.at("var"); - if(!HaveVar(ppar->varname)) - { - bool varexist = false; - if(ppar->varname == "temp" && HaveVar("ptemp") && HaveVar("sal")) varexist = true; - if(ppar->varname == "ptemp" && HaveVar("temp") && HaveVar("sal")) varexist = true; - if(ppar->varname == "pdens" && (HaveVar("ptemp") || HaveVar("temp")) && HaveVar("sal")) varexist = true; - if((ppar->varname == "U" || ppar->varname == "U2") && HaveVar("u") && HaveVar("v")) varexist = true; - if(!varexist) return {nullptr, "Variable " + ppar->varname + " not exists in this dataset"}; - } if(args.contains("layer")) ppar->layer = args.at("layer").ToInteger(); if(!args.contains("depth") && ppar->layer >= NDepths()) return {nullptr, MString("Layer ") + ppar->layer + " is too deep!"}; real depth = args.contains("depth") ? args.at("depth").ToReal() : Depth(ppar->layer); @@ -188,7 +177,6 @@ std::pair LayeredData::Parameters(michlib_intern } } - pars.SetParameter("variable", ppar->varname); pars.SetParameter("depth", Depth(ppar->layer)); pars.SetParameter("layer", ppar->layer); pars.SetParameter("dataset", Title()); @@ -200,23 +188,20 @@ std::pair LayeredData::Parameters(michlib_intern return {ppar.release(), ""}; } -LayeredData::Data LayeredData::Read(const BaseParameters* ip, size_t i) const +LayeredData::Data LayeredData::Read(const MString& vname, const BaseParameters* ip, size_t i) const { if(!isOk()) return Data(); bool nodepth = false; auto p = dynamic_cast(ip); - auto [name, id, tid] = VarNameLoc(p->varname, times[i]); + auto [name, id, tid] = VarNameLoc(vname, times[i]); if(!name.Exist()) // Conversion read { // ptemp from temp and sal - if(p->varname == "ptemp") + if(vname == "ptemp") { - struct Parameters params = *p; - params.varname = "temp"; - auto temp = Read(¶ms, i); - params.varname = "sal"; - auto sal = Read(¶ms, i); + auto temp = Read("temp", ip, i); + auto sal = Read("sal", ip, i); if(!(temp && sal)) return Data(); auto out = temp; for(size_t ind = 0; ind < out.N(); ind++) @@ -229,13 +214,10 @@ LayeredData::Data LayeredData::Read(const BaseParameters* ip, size_t i) const return out; } // temp from ptemp and sal - if(p->varname == "temp") + if(vname == "temp") { - struct Parameters params = *p; - params.varname = "ptemp"; - auto temp = Read(¶ms, i); - params.varname = "sal"; - auto sal = Read(¶ms, i); + auto temp = Read("ptemp", ip, i); + auto sal = Read("sal", ip, i); if(!(temp && sal)) return Data(); auto out = temp; for(size_t ind = 0; ind < out.N(); ind++) @@ -248,14 +230,11 @@ LayeredData::Data LayeredData::Read(const BaseParameters* ip, size_t i) const return out; } // pdens from temp and sal - if(p->varname == "pdens") + if(vname == "pdens") { - struct Parameters params = *p; - bool tempispot = HaveVar("ptemp"); - params.varname = tempispot ? "ptemp" : "temp"; - auto temp = Read(¶ms, i); - params.varname = "sal"; - auto sal = Read(¶ms, i); + bool tempispot = HaveVar("ptemp"); + auto temp = Read(tempispot ? "ptemp" : "temp", ip, i); + auto sal = Read("sal", ip, i); if(!(temp && sal)) return Data(); auto out = temp; for(size_t ind = 0; ind < out.N(); ind++) @@ -269,14 +248,11 @@ LayeredData::Data LayeredData::Read(const BaseParameters* ip, size_t i) const return out; } // U and U2 from u and v - if(p->varname == "U" || p->varname == "U2") + if(vname == "U" || vname == "U2") { - bool square = p->varname == "U2"; - struct Parameters params = *p; - params.varname = "u"; - auto u = Read(¶ms, i); - params.varname = "v"; - auto v = Read(¶ms, i); + bool square = vname == "U2"; + auto u = Read("u", ip, i); + auto v = Read("v", ip, i); if(!(u && v)) return Data(); auto out = u; for(size_t ind = 0; ind < out.N(); ind++)