|
|
|
@ -1,10 +1,10 @@
|
|
|
|
|
#define MICHLIB_NOSOURCE |
|
|
|
|
#include "ncfuncs.h" |
|
|
|
|
|
|
|
|
|
NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc) |
|
|
|
|
NCFuncs::DimNames NCFuncs::GetDNames(const NCFileA& nc) |
|
|
|
|
{ |
|
|
|
|
CoordNames out; |
|
|
|
|
auto head = nc.Header(); |
|
|
|
|
DimNames out; |
|
|
|
|
auto head = nc.Header(); |
|
|
|
|
for(const auto& dim: head.Dimensions()) |
|
|
|
|
{ |
|
|
|
|
if(dim.Name() == "lon" || dim.Name() == "longitude") |
|
|
|
@ -31,32 +31,33 @@ NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc)
|
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NCFuncs::CoordNames NCFuncs::GetDNames(const NCZarr& nc) |
|
|
|
|
NCFuncs::DimNames NCFuncs::GetDNames(const NCZarr& nc) |
|
|
|
|
{ |
|
|
|
|
CoordNames out; |
|
|
|
|
for(const auto& dim: nc.Dims()) |
|
|
|
|
{ |
|
|
|
|
if(dim.Name() == "lon" || dim.Name() == "longitude") |
|
|
|
|
{ |
|
|
|
|
out.lonname = dim.Name(); |
|
|
|
|
out.nx = dim.Size(); |
|
|
|
|
} |
|
|
|
|
if(dim.Name() == "lat" || dim.Name() == "latitude") |
|
|
|
|
{ |
|
|
|
|
out.latname = dim.Name(); |
|
|
|
|
out.ny = dim.Size(); |
|
|
|
|
} |
|
|
|
|
if(dim.Name() == "depth" || dim.Name() == "elevation") |
|
|
|
|
DimNames out; |
|
|
|
|
for(const auto& v: nc.VarNames()) |
|
|
|
|
for(const auto& dim: nc.DimNames(v)) |
|
|
|
|
{ |
|
|
|
|
out.depthname = dim.Name(); |
|
|
|
|
out.nz = dim.Size(); |
|
|
|
|
} |
|
|
|
|
if(dim.Name() == "time") |
|
|
|
|
{ |
|
|
|
|
out.timename = dim.Name(); |
|
|
|
|
out.nt = dim.Size(); |
|
|
|
|
if(dim == "lon" || dim == "longitude") |
|
|
|
|
{ |
|
|
|
|
out.lonname = dim; |
|
|
|
|
out.nx = nc.DimSize(v, dim); |
|
|
|
|
} |
|
|
|
|
if(dim == "lat" || dim == "latitude") |
|
|
|
|
{ |
|
|
|
|
out.latname = dim; |
|
|
|
|
out.ny = nc.DimSize(v, dim); |
|
|
|
|
} |
|
|
|
|
if(dim == "depth" || dim == "elevation") |
|
|
|
|
{ |
|
|
|
|
out.depthname = dim; |
|
|
|
|
out.nz = nc.DimSize(v, dim); |
|
|
|
|
} |
|
|
|
|
if(dim == "time") |
|
|
|
|
{ |
|
|
|
|
out.timename = dim; |
|
|
|
|
out.nt = nc.DimSize(v, dim); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -84,11 +85,6 @@ NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc)
|
|
|
|
|
if(islat) out.latname = v.Name(); |
|
|
|
|
if(isdepth) out.depthname = v.Name(); |
|
|
|
|
if(istime) out.timename = v.Name(); |
|
|
|
|
|
|
|
|
|
if(islon) out.nx = v.Dimensions().size(); |
|
|
|
|
if(islat) out.ny = v.Dimensions().size(); |
|
|
|
|
if(isdepth) out.nz = v.Dimensions().size(); |
|
|
|
|
if(istime) out.nt = v.Dimensions().size(); |
|
|
|
|
} |
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
@ -96,14 +92,14 @@ NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc)
|
|
|
|
|
NCFuncs::CoordNames NCFuncs::GetCNames(const NCZarr& nc) |
|
|
|
|
{ |
|
|
|
|
CoordNames out; |
|
|
|
|
for(const auto& v: nc.Vars()) // Try to define coordinates by attribute standard_name or attribute axis
|
|
|
|
|
for(const auto& v: nc.VarNames()) // Try to define coordinates by attribute standard_name or attribute axis
|
|
|
|
|
{ |
|
|
|
|
auto havestname = nc.HasAtt(v.Name(), "standard_name"); |
|
|
|
|
auto haveaxis = nc.HasAtt(v.Name(), "axis"); |
|
|
|
|
auto havestname = nc.HasAtt(v, "standard_name"); |
|
|
|
|
auto haveaxis = nc.HasAtt(v, "axis"); |
|
|
|
|
if(!(havestname || haveaxis)) continue; |
|
|
|
|
|
|
|
|
|
auto stname = nc.AttString(v.Name(), "standard_name"); |
|
|
|
|
auto axis = nc.AttString(v.Name(), "axis"); |
|
|
|
|
auto stname = nc.AttString(v, "standard_name"); |
|
|
|
|
auto axis = nc.AttString(v, "axis"); |
|
|
|
|
bool islon = false, islat = false, isdepth = false, istime = false; |
|
|
|
|
if(stname == "longitude") islon = true; |
|
|
|
|
if(stname == "latitude") islat = true; |
|
|
|
@ -115,15 +111,10 @@ NCFuncs::CoordNames NCFuncs::GetCNames(const NCZarr& nc)
|
|
|
|
|
if(!out.depthname.Exist() && axis == "Z") isdepth = true; |
|
|
|
|
if(!out.timename.Exist() && axis == "T") istime = true; |
|
|
|
|
|
|
|
|
|
if(islon) out.lonname = v.Name(); |
|
|
|
|
if(islat) out.latname = v.Name(); |
|
|
|
|
if(isdepth) out.depthname = v.Name(); |
|
|
|
|
if(istime) out.timename = v.Name(); |
|
|
|
|
|
|
|
|
|
if(islon) out.nx = v.Dims().size(); |
|
|
|
|
if(islat) out.ny = v.Dims().size(); |
|
|
|
|
if(isdepth) out.nz = v.Dims().size(); |
|
|
|
|
if(istime) out.nt = v.Dims().size(); |
|
|
|
|
if(islon) out.lonname = v; |
|
|
|
|
if(islat) out.latname = v; |
|
|
|
|
if(isdepth) out.depthname = v; |
|
|
|
|
if(istime) out.timename = v; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// If time not found just check variable "time"
|
|
|
|
@ -152,10 +143,10 @@ void NCFuncs::GetVars(const NCFileA& nc, std::set<MString>& vars)
|
|
|
|
|
|
|
|
|
|
void NCFuncs::GetVars(const NCZarr& nc, std::set<MString>& vars) |
|
|
|
|
{ |
|
|
|
|
for(const auto& v: nc.Vars()) |
|
|
|
|
for(const auto& v: nc.VarNames()) |
|
|
|
|
{ |
|
|
|
|
if(!nc.HasAtt(v.Name(), "standard_name")) continue; |
|
|
|
|
auto ret = nc.AttString(v.Name(), "standard_name"); |
|
|
|
|
if(!nc.HasAtt(v, "standard_name")) continue; |
|
|
|
|
auto ret = nc.AttString(v, "standard_name"); |
|
|
|
|
if(StName2Name(ret).Exist()) vars.emplace(StName2Name(ret)); |
|
|
|
|
} |
|
|
|
|
if((vars.contains("ptemp") || vars.contains("temp")) && vars.contains("sal")) vars.emplace("pdens"); |
|
|
|
@ -274,10 +265,10 @@ bool NCFuncs::HaveVar(const NCFileA& nc, const MString& vname)
|
|
|
|
|
|
|
|
|
|
bool NCFuncs::HaveVar(const NCZarr& nc, const MString& vname) |
|
|
|
|
{ |
|
|
|
|
for(const auto& v: nc.Vars()) |
|
|
|
|
for(const auto& v: nc.VarNames()) |
|
|
|
|
{ |
|
|
|
|
if(!nc.HasAtt(v.Name(), "standard_name")) continue; |
|
|
|
|
auto stname = nc.AttString(v.Name(), "standard_name"); |
|
|
|
|
if(!nc.HasAtt(v, "standard_name")) continue; |
|
|
|
|
auto stname = nc.AttString(v, "standard_name"); |
|
|
|
|
if(StName2Name(stname) == vname) return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|