diff --git a/include/NEMO.h b/include/NEMO.h index bcacbfa..273ed26 100644 --- a/include/NEMO.h +++ b/include/NEMO.h @@ -19,12 +19,20 @@ using michlib::ToGeoDomainNeg; class NEMOData { + enum Type + { + TYPE_UNKNOWN, + TYPE_DT, + TYPE_NRT, + TYPE_NRT6 + }; + NCFileA nc, nct, ncs; size_t xb, yb, xe, ye, layer; std::vector depths; std::vector times; size_t nx; - MString title; + Type type = TYPE_UNKNOWN; class EnvVar { @@ -135,26 +143,26 @@ class NEMOData NEMOData() = default; // TODO: RetVal - bool Open(const MString& type, const MString& cred, const MString& proxyurl = "") + bool Open(const MString& stype, const MString& cred, const MString& proxyurl = "") { if(proxyurl.Exist()) proxy.Activate("all_proxy", proxyurl); MString url, urlt, urls; - if(type == "DT") + if(stype == "DT") { - url = "https://" + cred + "@my.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy_my_0.083_P1D-m"; - title = "NEMO Delayed time, daily mean"; + url = "https://" + cred + "@my.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy_my_0.083_P1D-m"; + type = TYPE_DT; } - if(type == "NRT") + if(stype == "NRT") { - url = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024"; - title = "NEMO Near-real time, daily mean"; + url = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024"; + type = TYPE_NRT; } - if(type == "NRT6") + if(stype == "NRT6") { - url = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-uovo"; - urlt = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-thetao"; - urls = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-so"; - title = "NEMO Near-real time, 6h resolution"; + url = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-uovo"; + urlt = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-thetao"; + urls = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-so"; + type = TYPE_NRT6; } nc.Reset(url); if(!nc) return false; @@ -223,7 +231,7 @@ class NEMOData // clang-format off return - "NEMO dataset title: " + Title() + "\n" + + "Dataset: " + Title() + "\n" + " Begin date: " + Time(0).ToString() + "\n" + " End date: " + Time(NTimes()-1).ToString() + "\n" + " Time step: " + Timestep() + " seconds\n" + @@ -232,6 +240,17 @@ class NEMOData // clang-format on } + MString Dump() const + { + // clang-format off + return + "Current settings:\n" + MString() + + " Longitudes: from " + Lonb() + " (" + xb + ") to "+ Lone() + " (" + xe + ")\n" + + " Latitudes: from " + Latb() + " (" + yb + ") to "+ Late() + " (" + ye + ")\n" + + " Depth: layer " + layer + ", depth " + Depth() + " m\n"; + // clang-format on + } + bool SetRegion(real lonbin, real lonein, real latb, real late, real depth) { if(!nc) return false; @@ -287,6 +306,9 @@ class NEMOData return times[i]; } + bool isOk() const { return nc; } + explicit operator bool() const { return nc; } + size_t NDepths() const { return depths.size(); } size_t NTimes() const { return times.size(); } @@ -294,7 +316,16 @@ class NEMOData template Data Read(const std::vector& tindex) const = delete; - MString Title() const { return title; } + MString Title() const + { + switch(type) + { + case(TYPE_DT): return "NEMO Delayed time, daily mean (DT)"; + case(TYPE_NRT): return "NEMO Near-real time, daily mean (NRT)"; + case(TYPE_NRT6): return "NEMO Near-real time, 6h resolution (NRT6)"; + default: return "No title"; + } + } static real Fillval() { return Data::Fillval(); } }; diff --git a/include/odm.h b/include/odm.h index a8c1ef2..bdd2d01 100644 --- a/include/odm.h +++ b/include/odm.h @@ -1,4 +1,5 @@ #include "BFileW.h" +#include "GPL.h" #include "NEMO.h" #include "tindexes.h" @@ -42,6 +43,11 @@ class Data: public DataVariants return std::visit( [](const auto& arg) -> auto{ return arg.NTimes(); }, *this); } + auto Info() const + { + return std::visit( + [](const auto& arg) -> auto{ return arg.Info(); }, *this); + } bool Write(BFileW& fw, VarType vt, const std::vector& tindexes) const { @@ -67,4 +73,20 @@ class Data: public DataVariants CLArgs ParseArgs(int argc, char** argv); +int actioninfo(const CLArgs& args); +int actiontsc(const CLArgs& args); + +inline NEMOData NEMOOpen(const CLArgs& args) +{ + NEMOData ndata; + + MString oldprefix = GPL.UsePrefix("AVISO"); + MString dataset = args.contains("dataset") ? args.at("dataset") : "DT"; + MString cred = GPL.ParameterSValue("COPERNICUS_USER", ""); + MString proxy = GPL.ParameterSValue("COPERNICUS_PROXY", ""); + + GPL.UsePrefix(oldprefix); + ndata.Open(dataset, cred, proxy); + return ndata; +} #endif diff --git a/src/actioninfo.cpp b/src/actioninfo.cpp new file mode 100644 index 0000000..f121fde --- /dev/null +++ b/src/actioninfo.cpp @@ -0,0 +1,36 @@ +#define MICHLIB_NOSOURCE +#include "GPL.h" +#include "odm.h" + +int actioninfo(const CLArgs& args) +{ + if(!args.contains("source")) + { + errmessage("No source specified!"); + return 1; + } + + Data data; + + if(args.at("source") == "NEMO") + { + NEMOData ndata = NEMOOpen(args); + + if(!ndata) + { + errmessage("Can't open NEMO dataset"); + return 1; + } + + data = DataVariants(std::move(ndata)); + } + else + { + errmessage("Unknown source " + args.at("source")); + return 1; + } + + message(data.Info()); + + return 0; +} diff --git a/src/actiontsc.cpp b/src/actiontsc.cpp new file mode 100644 index 0000000..2ca7364 --- /dev/null +++ b/src/actiontsc.cpp @@ -0,0 +1,133 @@ +#define MICHLIB_NOSOURCE +#include "GPL.h" +#include "odm.h" + +int actiontsc(const CLArgs& args) +{ + if(!args.contains("source")) + { + errmessage("No source specified!"); + return 1; + } + + VarType vtype(args.at("var")); + if(!vtype) + { + errmessage("Incorrect or no variable specified"); + return 1; + } + + michlib_internal::ParameterListEx pars; + pars.UsePrefix(""); + + pars.SetParameter("source", args.at("source")); + pars.SetParameter("variable", vtype.Name()); + + Data data; + + if(args.at("source") == "NEMO") + { + if(!vtype.isSupported()) + { + errmessage("Variable " + args.at("var") + " is unsupported by NEMO"); + return 1; + } + + NEMOData ndata = NEMOOpen(args); + if(!ndata) + { + errmessage("Can't open NEMO dataset"); + return 1; + } + + size_t layer = 0; + if(args.contains("layer")) layer = args.at("layer").ToInteger(); + if(!args.contains("depth") && layer >= ndata.NDepths()) + { + errmessage(MString("Layer ") + layer + " is too deep!"); + return 1; + } + real depth = args.contains("depth") ? args.at("depth").ToReal() : ndata.Depth(layer); + + if(!(args.contains("lonb") && args.contains("lone") && args.contains("latb") && args.contains("late"))) + { + errmessage("Region not specified (lonb, lone, latb, late)"); + return 1; + } + if(!ndata.SetRegion(args.at("lonb").ToReal(), args.at("lone").ToReal(), args.at("latb").ToReal(), args.at("late").ToReal(), depth)) + { + errmessage("Can't set region"); + return 1; + } + + pars.SetParameter("depth", depth); + pars.SetParameter("layer", ndata.Layer()); + pars.SetParameter("dataset", ndata.Title()); + pars.SetParameter("lonb", args.at("lonb").ToReal()); + pars.SetParameter("latb", args.at("latb").ToReal()); + pars.SetParameter("lone", args.at("lone").ToReal()); + pars.SetParameter("late", args.at("late").ToReal()); + + data = DataVariants(std::move(ndata)); + } + else + { + errmessage("Unknown source " + args.at("source")); + return 1; + } + + if(args.contains("time") && (args.contains("timeb") || args.contains("timee"))) + { + errmessage("Time must be set via time parameter or timeb and timee parameter but not via both"); + return 1; + } + + if(!(args.contains("time") || (args.contains("timeb") && args.contains("timee")))) + { + errmessage("Time must be set via time parameter or timeb and timee parameter"); + return 1; + } + + BFileW fw; + MString name = args.at("out"); + if(!name.Exist()) name = "out.bin"; + + fw.Create(name, 3); + /* + if(!fw.Create(name,3)) + { + errmessage("Can't create file "+name); + return 1; + } + */ + fw.SetParameters(pars); + fw.UsePrefix(""); + + if(args.contains("time")) + { + MDateTime time; + if(time.FromString(args.at("time"))) // One date + { + auto it = GetTIndex(data, time); + fw.SetParameter("time", data.Time(it).ToString()); + data.Write(fw, vtype, std::vector(1, it)); + } + else // Regular expression + { + fw.SetParameter("timeregex", args.at("time")); + data.Write(fw, vtype, GetTIndexes(data, args.at("time"))); + } + } + else // Bdate, edate + { + MDateTime tb(args.at("timeb")), te(args.at("timee")); + fw.SetParameter("timeb", tb.ToString()); + fw.SetParameter("timee", te.ToString()); + data.Write(fw, vtype, GetTIndexes(data, tb, te)); + } + + fw.Finalize(); + fw.Close(); + + return 0; +} diff --git a/src/odm.cpp b/src/odm.cpp index b32f3d6..d6e31ec 100644 --- a/src/odm.cpp +++ b/src/odm.cpp @@ -1,22 +1,25 @@ #include "odm.h" -#include "GPL.h" inline void Usage(const MString& arg0) { message(arg0 + " (=...)"); message("Keys are:"); - message(" source. Required. May be: NEMO"); - message(" var. Required. May be: temp, sal or chl"); - message(" time. Time moment or regular expression. If present, timeb and timee must be absent"); - message(" timeb, timee. Time interval. If present, time must be absent"); - message(" out. Output file. Default: out.bin"); - message(" Keys for source=NEMO"); - message(" var can be only temp or sal"); - message(" dataset. Can be DT, NRT or NRT6. Default: DT"); - message(" cred. Login and password for COPERNICUS site. Default works"); - message(" proxy. Proxy for access to COPERNICUS. Default works"); - message(" layer and/or depth. Layer or depth of NEMO dataset. If depth is specified, layer is ignored. Default: layer=0"); - message(" lonb, lone, latb, late. Required. Region of interest"); + message(" action. What the program should do. May be: info, tsc. Default: tsc."); + message(" Keys for action=info. Print some information about dataset."); + message(" source. Required. May be: NEMO"); + message(" Keys for source=NEMO"); + message(" dataset. Can be DT, NRT or NRT6. Default: DT"); + message(" Keys for action=tsc. Get temperature, salinity, chlorofill from dataset."); + message(" source. Required. May be: NEMO"); + message(" var. Required. May be: temp, sal or chl"); + message(" time. Time moment or regular expression. If present, timeb and timee must be absent"); + message(" timeb, timee. Time interval. If present, time must be absent"); + message(" out. Output file. Default: out.bin"); + message(" Keys for source=NEMO"); + message(" var can be only temp or sal"); + message(" dataset. Can be DT, NRT or NRT6. Default: DT"); + message(" layer and/or depth. Layer or depth of NEMO dataset. If depth is specified, layer is ignored. Default: layer=0"); + message(" lonb, lone, latb, late. Required. Region of interest"); } int main(int argc, char** argv) @@ -28,137 +31,18 @@ int main(int argc, char** argv) } auto args = ParseArgs(argc, argv); - if(!args.contains("source")) - { - errmessage("No source specified!"); - return 1; - } - - VarType vtype(args["var"]); - if(!vtype) - { - errmessage("Incorrect or no variable specified"); - return 1; - } - - michlib_internal::ParameterListEx pars; - pars.UsePrefix(""); - - pars.SetParameter("source", args["source"]); - pars.SetParameter("variable", vtype.Name()); - - Data data; + MString action = args.contains("action") ? args["action"] : "tsc"; - if(args["source"] == "NEMO") - { - if(!vtype.isSupported()) - { - errmessage("Variable " + args["var"] + " is unsupported by NEMO"); - return 1; - } - - GPL.UsePrefix("AVISO"); - NEMOData ndata; - MString dataset = args["dataset"]; - if(!dataset.Exist()) dataset = "DT"; - - MString cred = GPL.ParameterSValue("COPERNICUS_USER", ""); - MString proxy = GPL.ParameterSValue("COPERNICUS_PROXY", ""); - - if(!ndata.Open(dataset, cred, proxy)) - { - errmessage("Can't open NEMO dataset"); - return 1; - } - - size_t layer = 0; - if(args.contains("layer")) layer = args["layer"].ToInteger(); - if(!args.contains("depth") && layer >= ndata.NDepths()) - { - errmessage(MString("Layer ") + layer + " is too deep!"); - return 1; - } - real depth = args.contains("depth") ? args["depth"].ToReal() : ndata.Depth(layer); - - if(!(args.contains("lonb") && args.contains("lone") && args.contains("latb") && args.contains("late"))) - { - errmessage("Region not specified (lonb, lone, latb, late)"); - return 1; - } - if(!ndata.SetRegion(args["lonb"].ToReal(), args["lone"].ToReal(), args["latb"].ToReal(), args["late"].ToReal(), depth)) - { - errmessage("Can't set region"); - return 1; - } - - pars.SetParameter("depth", depth); - pars.SetParameter("layer", ndata.Layer()); - pars.SetParameter("dataset", dataset); - pars.SetParameter("lonb", args["lonb"].ToReal()); - pars.SetParameter("latb", args["latb"].ToReal()); - pars.SetParameter("lone", args["lone"].ToReal()); - pars.SetParameter("late", args["late"].ToReal()); - - data = DataVariants(std::move(ndata)); - } + int ret = 1; + if(action == "info") + ret = actioninfo(args); + else if(action == "tsc") + ret = actiontsc(args); else { - errmessage("Unknown source " + args["source"]); + errmessage("Unknown action " + action); return 1; } - if(args.contains("time") && (args.contains("timeb") || args.contains("timee"))) - { - errmessage("Time must be set via time parameter or timeb and timee parameter but not via both"); - return 1; - } - - if(!(args.contains("time") || (args.contains("timeb") && args.contains("timee")))) - { - errmessage("Time must be set via time parameter or timeb and timee parameter"); - return 1; - } - - BFileW fw; - MString name = args["out"]; - if(!name.Exist()) name = "out.bin"; - - fw.Create(name, 3); - /* - if(!fw.Create(name,3)) - { - errmessage("Can't create file "+name); - return 1; - } - */ - fw.SetParameters(pars); - fw.UsePrefix(""); - - if(args.contains("time")) - { - MDateTime time; - if(time.FromString(args["time"])) // One date - { - auto it = GetTIndex(data, time); - fw.SetParameter("time", data.Time(it).ToString()); - data.Write(fw, vtype, std::vector(1, it)); - } - else // Regular expression - { - fw.SetParameter("timeregex", args["time"]); - data.Write(fw, vtype, GetTIndexes(data, args["time"])); - } - } - else // Bdate, edate - { - MDateTime tb(args["timeb"]), te(args["timee"]); - fw.SetParameter("timeb", tb.ToString()); - fw.SetParameter("timee", te.ToString()); - data.Write(fw, vtype, GetTIndexes(data, tb, te)); - } - - fw.Finalize(); - fw.Close(); - - return 0; + return ret; }