Browse Source

More variables.

Update NEMO code.
interpolate
Michael Uleysky 2 years ago
parent
commit
4f6782ea09
  1. 189
      include/NEMO.h
  2. 19
      include/vartype.h
  3. 2
      src/actiontsc.cpp
  4. 6
      src/odm.cpp

189
include/NEMO.h

@ -27,7 +27,7 @@ class NEMOData
TYPE_NRT6 TYPE_NRT6
}; };
NCFileA nc, nct, ncs; std::vector<NCFileA> nc;
size_t xb, yb, xe, ye, layer; size_t xb, yb, xe, ye, layer;
std::vector<real> depths; std::vector<real> depths;
std::vector<MDateTime> times; std::vector<MDateTime> times;
@ -73,15 +73,22 @@ class NEMOData
public: public:
using Data = Simple2DData; using Data = Simple2DData;
Data ReadVar(const NCFileA& f, const MString& name, size_t i) const private:
template<class DataType> Data ReadVarRaw(const NCFileA& f, const MString& name, size_t i, bool nodepth) const
{ {
using DataType = int2;
constexpr DataType fill = -32767;
real unitmul = 1.0; real unitmul = 1.0;
DataType fill;
real offset = 0.0, scale = 1.0;
auto offset = f.A<double>(name, "add_offset"); {
auto scale = f.A<double>(name, "scale_factor"); auto a_fill = f.A<DataType>(name, "_FillValue");
if(!offset || !scale) return Data(); auto a_offset = f.A<double>(name, "add_offset");
auto a_scale = f.A<double>(name, "scale_factor");
if(!a_fill) return Data();
fill = a_fill;
if(a_offset) offset = a_offset;
if(a_scale) scale = a_scale;
}
auto unit = f.A<MString>(name, "units"); auto unit = f.A<MString>(name, "units");
if(unit && unit.Get() == "m s-1") unitmul = 100.0; if(unit && unit.Get() == "m s-1") unitmul = 100.0;
@ -90,7 +97,8 @@ class NEMOData
if(xb < xe) if(xb < xe)
{ {
auto var = f.V<DataType>(name, {"longitude", xb, xe - xb + 1}, {"latitude", yb, ye - yb + 1}, {"time", i, 1}, {"depth", layer, 1}); auto var = nodepth ? f.V<DataType>(name, {"longitude", xb, xe - xb + 1}, {"latitude", yb, ye - yb + 1}, {"time", i, 1})
: f.V<DataType>(name, {"longitude", xb, xe - xb + 1}, {"latitude", yb, ye - yb + 1}, {"time", i, 1}, {"depth", layer, 1});
if(!var) return Data(); if(!var) return Data();
if(var.DimLen(0) != data.Nx() || var.DimLen(1) != data.Ny()) return Data(); if(var.DimLen(0) != data.Nx() || var.DimLen(1) != data.Ny()) return Data();
@ -103,8 +111,10 @@ class NEMOData
} }
else else
{ {
auto var1 = f.V<DataType>(name, {"longitude", xb}, {"latitude", yb, ye - yb + 1}, {"time", i, 1}, {"depth", layer, 1}); auto var1 = nodepth ? f.V<DataType>(name, {"longitude", xb}, {"latitude", yb, ye - yb + 1}, {"time", i, 1})
auto var2 = f.V<DataType>(name, {"longitude", 0, xe + 1}, {"latitude", yb, ye - yb + 1}, {"time", i, 1}, {"depth", layer, 1}); : f.V<DataType>(name, {"longitude", xb}, {"latitude", yb, ye - yb + 1}, {"time", i, 1}, {"depth", layer, 1});
auto var2 = nodepth ? f.V<DataType>(name, {"longitude", 0, xe + 1}, {"latitude", yb, ye - yb + 1}, {"time", i, 1})
: f.V<DataType>(name, {"longitude", 0, xe + 1}, {"latitude", yb, ye - yb + 1}, {"time", i, 1}, {"depth", layer, 1});
if(!(var1 && var2)) return Data(); if(!(var1 && var2)) return Data();
if((var1.DimLen(0) + var2.DimLen(0)) != data.Nx() || var1.DimLen(1) != data.Ny() || var2.DimLen(1) != data.Ny()) return Data(); if((var1.DimLen(0) + var2.DimLen(0)) != data.Nx() || var1.DimLen(1) != data.Ny() || var2.DimLen(1) != data.Ny()) return Data();
for(size_t ix = 0; ix < var1.DimLen(0); ix++) for(size_t ix = 0; ix < var1.DimLen(0); ix++)
@ -123,15 +133,35 @@ class NEMOData
return data; return data;
} }
Data ReadVar(const NCFileA& f, const MString& name, const std::vector<size_t>& tindex) const public:
Data ReadVar(const MString& name, size_t i) const
{
if(!isOk()) return Data();
bool nodepth = false;
for(const auto& f: nc)
{
auto head = f.Header();
for(const auto& v: head.Variables())
if(v.Name() == name)
{
if(v.Dimensions().size() == 3) nodepth = true;
if(v.Type().Id() == NC_SHORT) return ReadVarRaw<int2>(f, name, i, nodepth);
if(v.Type().Id() == NC_FLOAT) return ReadVarRaw<float>(f, name, i, nodepth);
}
}
return Data();
}
Data ReadVar(const MString& name, const std::vector<size_t>& tindex) const
{ {
Data out; Data out;
if(tindex.size() == 0) return out; if(tindex.size() == 0 || !isOk()) return out;
std::vector<size_t> count; std::vector<size_t> count;
for(size_t i = 0; i < tindex.size(); i++) for(size_t i = 0; i < tindex.size(); i++)
{ {
Data dat = ReadVar(f, name, tindex[i]); Data dat = ReadVar(name, tindex[i]);
if(!dat) return Data(); if(!dat) return Data();
out.Add(dat, count); out.Add(dat, count);
} }
@ -145,76 +175,69 @@ class NEMOData
// TODO: RetVal // TODO: RetVal
bool Open(const MString& stype, const MString& cred, const MString& proxyurl = "") bool Open(const MString& stype, const MString& cred, const MString& proxyurl = "")
{ {
nc.clear();
if(proxyurl.Exist()) proxy.Activate("all_proxy", proxyurl); if(proxyurl.Exist()) proxy.Activate("all_proxy", proxyurl);
MString url, urlt, urls;
if(stype == "DT") if(stype == "DT")
{ {
url = "https://" + cred + "@my.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy_my_0.083_P1D-m"; NCFileA newnc;
newnc.Reset("https://" + cred + "@my.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy_my_0.083_P1D-m");
if(!newnc) return false;
nc.push_back(std::move(newnc));
type = TYPE_DT; type = TYPE_DT;
} }
if(stype == "NRT") if(stype == "NRT")
{ {
url = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024"; std::vector<MString> urls{"https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m",
type = TYPE_NRT; "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m",
} "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-so_anfc_0.083deg_P1D-m",
if(stype == "NRT6") "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy_anfc_0.083deg_P1D-m",
"https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-wcur_anfc_0.083deg_P1D-m"};
for(const auto& url: urls)
{ {
url = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-uovo"; NCFileA newnc;
urlt = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-thetao"; newnc.Reset(url);
urls = "https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/global-analysis-forecast-phy-001-024-3dinst-so"; if(!newnc)
type = TYPE_NRT6;
}
nc.Reset(url);
if(!nc) return false;
{ {
auto nx_ = nc.D("longitude"); nc.clear();
if(!nx_)
{
nc.Reset();
return false; return false;
} }
nx = nx_; nc.push_back(std::move(newnc));
}
if(urlt.Exist())
{
nct.Reset(urlt);
if(!nct)
{
nc.Reset();
return false;
} }
type = TYPE_NRT;
} }
if(urls.Exist()) if(stype == "NRT6")
{
std::vector<MString> urls{"https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-cur_anfc_0.083deg_PT6H-i",
"https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-thetao_anfc_0.083deg_PT6H-i",
"https://" + cred + "@nrt.cmems-du.eu/thredds/dodsC/cmems_mod_glo_phy-so_anfc_0.083deg_PT6H-i"};
for(const auto& url: urls)
{ {
ncs.Reset(urls); NCFileA newnc;
if(!ncs) newnc.Reset(url);
if(!newnc)
{ {
nc.Reset(); nc.clear();
nct.Reset();
return false; return false;
} }
nc.push_back(std::move(newnc));
}
type = TYPE_NRT6;
} }
auto rdepths = nc.V<float>("depth"); auto rdepths = nc[0].V<float>("depth");
if(!rdepths) if(!rdepths)
{ {
nc.Reset(); nc.clear();
nct.Reset();
ncs.Reset();
return false; return false;
} }
depths.resize(rdepths.DimLen(0)); depths.resize(rdepths.DimLen(0));
for(size_t i = 0; i < depths.size(); i++) depths[i] = rdepths(i); for(size_t i = 0; i < depths.size(); i++) depths[i] = rdepths(i);
auto timeD = nc.V<double>("time"); auto timeD = nc[0].V<double>("time");
auto timeF = nc.V<float>("time"); auto timeF = nc[0].V<float>("time");
if(!(timeD || timeF)) if(!(timeD || timeF))
{ {
nc.Reset(); nc.clear();
nct.Reset();
ncs.Reset();
return false; return false;
} }
MDateTime refdate("1950-01-01"); MDateTime refdate("1950-01-01");
@ -253,7 +276,7 @@ class NEMOData
bool SetRegion(real lonbin, real lonein, real latb, real late, real depth) bool SetRegion(real lonbin, real lonein, real latb, real late, real depth)
{ {
if(!nc) return false; if(!isOk()) return false;
real lonb = ToGeoDomainNeg(lonbin), lone = ToGeoDomainNeg(lonein); real lonb = ToGeoDomainNeg(lonbin), lone = ToGeoDomainNeg(lonein);
size_t xb_, xe_, yb_, ye_, layer_ = 0; size_t xb_, xe_, yb_, ye_, layer_ = 0;
@ -286,28 +309,28 @@ class NEMOData
return true; return true;
} }
real Lonb() const { return nc ? (-180.0 + xb / 12.0) : -1000.0; } real Lonb() const { return isOk() ? (-180.0 + xb / 12.0) : -1000.0; }
real Lone() const { return nc ? (-180.0 + xe / 12.0) : -1000.0; } real Lone() const { return isOk() ? (-180.0 + xe / 12.0) : -1000.0; }
real Latb() const { return nc ? (-80.0 + yb / 12.0) : -1000.0; } real Latb() const { return isOk() ? (-80.0 + yb / 12.0) : -1000.0; }
real Late() const { return nc ? (-80.0 + ye / 12.0) : -1000.0; } real Late() const { return isOk() ? (-80.0 + ye / 12.0) : -1000.0; }
size_t Xb() const { return nc ? xb : 0; } size_t Xb() const { return isOk() ? xb : 0; }
size_t Xe() const { return nc ? xe : 0; } size_t Xe() const { return isOk() ? xe : 0; }
size_t Yb() const { return nc ? yb : 0; } size_t Yb() const { return isOk() ? yb : 0; }
size_t Ye() const { return nc ? ye : 0; } size_t Ye() const { return isOk() ? ye : 0; }
size_t Nx() const { return nc ? ((xb < xe) ? (xe - xb + 1) : (nx + xe - xb + 1)) : 0; } size_t Nx() const { return isOk() ? ((xb < xe) ? (xe - xb + 1) : (nx + xe - xb + 1)) : 0; }
size_t Ny() const { return nc ? (ye - yb + 1) : 0; } size_t Ny() const { return isOk() ? (ye - yb + 1) : 0; }
real Depth(size_t l) const { return nc ? depths[l] : -1000.0; } real Depth(size_t l) const { return isOk() ? depths[l] : -1000.0; }
real Depth() const { return Depth(layer); } real Depth() const { return Depth(layer); }
size_t Layer() const { return layer; } size_t Layer() const { return layer; }
time_t Timestep() const { return nc ? (times[1] - times[0]) : 0; } time_t Timestep() const { return isOk() ? (times[1] - times[0]) : 0; }
MDateTime Time(size_t i) const MDateTime Time(size_t i) const
{ {
if((!nc) || i >= times.size()) return MDateTime(); if(!isOk() || i >= times.size()) return MDateTime();
return times[i]; return times[i];
} }
bool isOk() const { return nc; } bool isOk() const { return nc.size() > 0; }
explicit operator bool() const { return nc; } explicit operator bool() const { return nc.size() > 0; }
size_t NDepths() const { return depths.size(); } size_t NDepths() const { return depths.size(); }
size_t NTimes() const { return times.size(); } size_t NTimes() const { return times.size(); }
@ -330,14 +353,20 @@ class NEMOData
static real Fillval() { return Data::Fillval(); } static real Fillval() { return Data::Fillval(); }
}; };
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::U>(size_t it) const { return ReadVar(nc, "uo", it); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::U>(size_t it) const { return ReadVar("uo", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::V>(size_t it) const { return ReadVar(nc, "vo", it); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::V>(size_t it) const { return ReadVar("vo", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::TEMP>(size_t it) const { return ReadVar(nct ? nct : nc, "thetao", it); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::TEMP>(size_t it) const { return ReadVar("thetao", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::SAL>(size_t it) const { return ReadVar(ncs ? ncs : nc, "so", it); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::SAL>(size_t it) const { return ReadVar("so", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::MLD>(size_t it) const { return ReadVar("mlotst", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::U>(const std::vector<size_t>& tindex) const { return ReadVar(nc, "uo", tindex); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::SSH>(size_t it) const { return ReadVar("zos", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::V>(const std::vector<size_t>& tindex) const { return ReadVar(nc, "vo", tindex); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::W>(size_t it) const { return ReadVar("wo", it); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::TEMP>(const std::vector<size_t>& tindex) const { return ReadVar(nct ? nct : nc, "thetao", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::SAL>(const std::vector<size_t>& tindex) const { return ReadVar(ncs ? ncs : nc, "so", tindex); } template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::U>(const std::vector<size_t>& tindex) const { return ReadVar("uo", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::V>(const std::vector<size_t>& tindex) const { return ReadVar("vo", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::TEMP>(const std::vector<size_t>& tindex) const { return ReadVar("thetao", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::SAL>(const std::vector<size_t>& tindex) const { return ReadVar("so", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::MLD>(const std::vector<size_t>& tindex) const { return ReadVar("mlotst", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::SSH>(const std::vector<size_t>& tindex) const { return ReadVar("zos", tindex); }
template<> inline NEMOData::Data NEMOData::Read<vartype::Vartype::W>(const std::vector<size_t>& tindex) const { return ReadVar("wo", tindex); }
#endif #endif

19
include/vartype.h

@ -15,7 +15,10 @@ enum class Vartype
V, V,
TEMP, TEMP,
SAL, SAL,
CHL CHL,
MLD,
SSH,
W
}; };
template<Vartype vt_> struct VartypeCarrier template<Vartype vt_> struct VartypeCarrier
@ -23,12 +26,12 @@ template<Vartype vt_> struct VartypeCarrier
static const Vartype vt = vt_; static const Vartype vt = vt_;
}; };
using VartypeUnion = std::variant<VartypeCarrier<Vartype::NONE>, VartypeCarrier<Vartype::U>, VartypeCarrier<Vartype::V>, VartypeCarrier<Vartype::TEMP>, using VartypeUnion =
VartypeCarrier<Vartype::SAL>, VartypeCarrier<Vartype::CHL>>; std::variant<VartypeCarrier<Vartype::NONE>, VartypeCarrier<Vartype::U>, VartypeCarrier<Vartype::V>, VartypeCarrier<Vartype::TEMP>, VartypeCarrier<Vartype::SAL>,
VartypeCarrier<Vartype::CHL>, VartypeCarrier<Vartype::MLD>, VartypeCarrier<Vartype::SSH>, VartypeCarrier<Vartype::W>>;
template<class T, Vartype vt> template<class T, Vartype vt>
concept HasVar = requires(T t) concept HasVar = requires(T t) {
{
{ {
t.template Read<vt>(0)(0, 0) t.template Read<vt>(0)(0, 0)
} -> std::convertible_to<real>; } -> std::convertible_to<real>;
@ -59,6 +62,9 @@ class VarType: public vartype::VartypeUnion
if(str == "t" || str == "temp" || str == "temperature") *this = vartype::VartypeCarrier<vartype::Vartype::TEMP>(); if(str == "t" || str == "temp" || str == "temperature") *this = vartype::VartypeCarrier<vartype::Vartype::TEMP>();
if(str == "s" || str == "sal" || str == "salinity") *this = vartype::VartypeCarrier<vartype::Vartype::SAL>(); if(str == "s" || str == "sal" || str == "salinity") *this = vartype::VartypeCarrier<vartype::Vartype::SAL>();
if(str == "c" || str == "chl" || str == "chlorophyll") *this = vartype::VartypeCarrier<vartype::Vartype::CHL>(); if(str == "c" || str == "chl" || str == "chlorophyll") *this = vartype::VartypeCarrier<vartype::Vartype::CHL>();
if(str == "mld") *this = vartype::VartypeCarrier<vartype::Vartype::MLD>();
if(str == "ssh") *this = vartype::VartypeCarrier<vartype::Vartype::SSH>();
if(str == "w") *this = vartype::VartypeCarrier<vartype::Vartype::W>();
} }
MString Name() const MString Name() const
@ -71,6 +77,9 @@ class VarType: public vartype::VartypeUnion
case(vartype::Vartype::TEMP): return "Temperature"; case(vartype::Vartype::TEMP): return "Temperature";
case(vartype::Vartype::SAL): return "Salinity"; case(vartype::Vartype::SAL): return "Salinity";
case(vartype::Vartype::CHL): return "Chlorophyll"; case(vartype::Vartype::CHL): return "Chlorophyll";
case(vartype::Vartype::MLD): return "Mixed layer depth";
case(vartype::Vartype::SSH): return "Sea surface height";
case(vartype::Vartype::W): return "W";
} }
return "none"; return "none";
} }

2
src/actiontsc.cpp

@ -89,7 +89,7 @@ int actiontsc(const CLArgs& args)
} }
BFileW fw; BFileW fw;
MString name = args.at("out"); MString name = args.contains("out") ? args.at("out") : "";
if(!name.Exist()) name = "out.bin"; if(!name.Exist()) name = "out.bin";
fw.Create(name, 3); fw.Create(name, 3);

6
src/odm.cpp

@ -11,14 +11,14 @@ inline void Usage(const MString& arg0)
message(" dataset. Can be DT, NRT or NRT6. Default: DT"); message(" dataset. Can be DT, NRT or NRT6. Default: DT");
message(" Keys for action=tsc. Get temperature, salinity, chlorofill from dataset."); message(" Keys for action=tsc. Get temperature, salinity, chlorofill from dataset.");
message(" source. Required. May be: NEMO"); message(" source. Required. May be: NEMO");
message(" var. Required. May be: temp, sal or chl"); message(" var. Required. May be: temp, sal, chl, mld, ssh or w.");
message(" time. Time moment or regular expression. If present, timeb and timee must be absent"); 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(" timeb, timee. Time interval. If present, time must be absent");
message(" out. Output file. Default: out.bin"); message(" out. Output file. Default: out.bin");
message(" Keys for source=NEMO"); message(" Keys for source=NEMO");
message(" var can be only temp or sal"); message(" var can be temp, sal, mld, ssh or w. Mld is not available for dataset=NRT6.");
message(" dataset. Can be DT, NRT or NRT6. Default: DT"); 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(" layer and/or depth. Layer or depth of NEMO dataset. If depth is specified, layer is ignored. Both ignored, if var=mld. Default: layer=0");
message(" lonb, lone, latb, late. Required. Region of interest"); message(" lonb, lone, latb, late. Required. Region of interest");
} }

Loading…
Cancel
Save