Browse Source

Removed some features from the NCZarr interface. Removed direct access to variables and dimensions in NCZarr, dimensions are now bound to variables.

Separate CoordsNames and DimNames structures in the NCFuncs class.
lintest
Michael Uleysky 5 months ago
parent
commit
c46abb091d
  1. 2
      include/layereddata.h
  2. 8
      include/layereddataz.h
  3. 8
      include/ncfuncs.h
  4. 15
      include/nczarr.h
  5. 34
      include/nczarrcommon.h
  6. 3
      sources/AVISOLOCAL.cpp
  7. 6
      src/layereddataz.cpp
  8. 93
      src/ncfuncs.cpp

2
include/layereddata.h

@ -80,7 +80,7 @@ class LayeredData: public NCFuncs
std::vector<NC> nc; std::vector<NC> nc;
std::vector<real> depths; std::vector<real> depths;
std::vector<MDateTime> times; std::vector<MDateTime> times;
struct CoordNames dname; struct DimNames dname;
real lonb, latb, lone, late; real lonb, latb, lone, late;
real lonstep, latstep; real lonstep, latstep;
MString title; MString title;

8
include/layereddataz.h

@ -77,7 +77,7 @@ class LayeredDataZ: public NCFuncs
std::vector<real> depths; std::vector<real> depths;
bool depthinv; bool depthinv;
std::vector<MDateTime> times; std::vector<MDateTime> times;
struct CoordNames dname; struct DimNames dname;
real lonb, latb, lone, late; real lonb, latb, lone, late;
real lonstep, latstep; real lonstep, latstep;
MString title; MString title;
@ -195,11 +195,11 @@ class LayeredDataZ: public NCFuncs
{ {
auto tind = nc[i].Index(tm); auto tind = nc[i].Index(tm);
if(tind == 0) continue; if(tind == 0) continue;
for(const auto& v: nc[i].Vars()) for(const auto& v: nc[i].VarNames())
{ {
auto stname = nc[i].AttString(v.Name(), "standard_name"); auto stname = nc[i].AttString(v, "standard_name");
if(!stname.Exist()) continue; if(!stname.Exist()) continue;
if(StName2Name(stname) == vname) return {v.Name(), i, tind - 1}; if(StName2Name(stname) == vname) return {v, i, tind - 1};
} }
} }
return {"", 0, 0}; return {"", 0, 0};

8
include/ncfuncs.h

@ -15,6 +15,10 @@ class NCFuncs
{ {
public: public:
struct CoordNames struct CoordNames
{
MString lonname, latname, depthname, timename;
};
struct DimNames
{ {
MString lonname, latname, depthname, timename; MString lonname, latname, depthname, timename;
size_t nx, ny, nz, nt; size_t nx, ny, nz, nt;
@ -26,12 +30,12 @@ class NCFuncs
static std::tuple<MDateTime, time_t, bool> Refdate(const MString& refdate); static std::tuple<MDateTime, time_t, bool> Refdate(const MString& refdate);
static void GetVars(const NCFileA& nc, std::set<MString>& vars); static void GetVars(const NCFileA& nc, std::set<MString>& vars);
static CoordNames GetCNames(const NCFileA& nc); static CoordNames GetCNames(const NCFileA& nc);
static CoordNames GetDNames(const NCFileA& nc); static DimNames GetDNames(const NCFileA& nc);
static bool HaveVar(const NCFileA& nc, const MString& vname); static bool HaveVar(const NCFileA& nc, const MString& vname);
static void GetVars(const NCZarr& nc, std::set<MString>& vars); static void GetVars(const NCZarr& nc, std::set<MString>& vars);
static CoordNames GetCNames(const NCZarr& nc); static CoordNames GetCNames(const NCZarr& nc);
static CoordNames GetDNames(const NCZarr& nc); static DimNames GetDNames(const NCZarr& nc);
static bool HaveVar(const NCZarr& nc, const MString& vname); static bool HaveVar(const NCZarr& nc, const MString& vname);
template<class HV> static VarPresence CheckVar(const MString& vname, HV hv) template<class HV> static VarPresence CheckVar(const MString& vname, HV hv)

15
include/nczarr.h

@ -31,7 +31,6 @@ class NCZarr: private NCZarrBase, private DimReqDef
return V([](const auto& arg) { return static_cast<bool>(arg); }); return V([](const auto& arg) { return static_cast<bool>(arg); });
} }
DEFFUNC(NDim)
DEFFUNC1(NDim) DEFFUNC1(NDim)
DEFFUNC(NAtt) DEFFUNC(NAtt)
@ -44,10 +43,9 @@ class NCZarr: private NCZarrBase, private DimReqDef
DEFFUNC1(VarT) DEFFUNC1(VarT)
DEFFUNC1(VarFill) DEFFUNC1(VarFill)
DEFFUNC(DimNames)
DEFFUNC1(DimNames) DEFFUNC1(DimNames)
DEFFUNC1(DimSize) DEFFUNC2(DimSize)
DEFFUNC2(AttT) DEFFUNC2(AttT)
DEFFUNC2(AttInt) DEFFUNC2(AttInt)
@ -63,14 +61,11 @@ class NCZarr: private NCZarrBase, private DimReqDef
DEFFUNC1(AttString) DEFFUNC1(AttString)
DEFFUNC1(AttBool) DEFFUNC1(AttBool)
DEFFUNC1(HasDim) DEFFUNC2(HasDim)
DEFFUNC1(HasVar) DEFFUNC1(HasVar)
DEFFUNC1(HasAtt) DEFFUNC1(HasAtt)
DEFFUNC2(HasAtt) DEFFUNC2(HasAtt)
DEFFUNC(Vars)
DEFFUNC(Dims)
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const char* request) const template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const char* request) const
{ {
return V([&vname = std::as_const(vname), &data = data, &transform = transform, request = request](const auto& arg) { return arg.Read(vname, data, transform, request); }); return V([&vname = std::as_const(vname), &data = data, &transform = transform, request = request](const auto& arg) { return arg.Read(vname, data, transform, request); });
@ -87,15 +82,13 @@ class NCZarr: private NCZarrBase, private DimReqDef
{ return arg.Read(vname, data, transform, std::move(req1), std::move(req2)); }); { return arg.Read(vname, data, transform, std::move(req1), std::move(req2)); });
} }
template<class Data, class Transform> template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3) const
Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3) const
{ {
return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2, &req3 = req3](const auto& arg) return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2, &req3 = req3](const auto& arg)
{ return arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3)); }); { return arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3)); });
} }
template<class Data, class Transform> template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3, DimReq&& req4) const
Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3, DimReq&& req4) const
{ {
return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2, &req3 = req3, &req4 = req4](const auto& arg) return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2, &req3 = req3, &req4 = req4](const auto& arg)
{ return arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3), std::move(req4)); }); { return arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3), std::move(req4)); });

34
include/nczarrcommon.h

@ -381,8 +381,6 @@ class NcZarrTypes
public: public:
explicit operator bool() const { return !vars.empty(); } explicit operator bool() const { return !vars.empty(); }
size_t NDim() const { return dims.size(); }
size_t NDim(const MString& var) const size_t NDim(const MString& var) const
{ {
size_t ind = FindInd(var, vars); size_t ind = FindInd(var, vars);
@ -431,13 +429,6 @@ class NcZarrTypes
return ind < vars.size() ? vars[ind].Fill() : Variable::FillType(); return ind < vars.size() ? vars[ind].Fill() : Variable::FillType();
} }
auto DimNames() const
{
std::vector<MString> out;
std::transform(dims.cbegin(), dims.cend(), std::back_inserter(out), [](const Dimension& d) { return d.Name(); });
return out;
}
auto DimNames(const MString& var) const auto DimNames(const MString& var) const
{ {
size_t ind = FindInd(var, vars); size_t ind = FindInd(var, vars);
@ -450,8 +441,10 @@ class NcZarrTypes
return out; return out;
} }
size_t DimSize(const MString& dim) const size_t DimSize(const MString& var, const MString& dim) const
{ {
if(!HasDim(var, dim)) return 0;
size_t ind = FindInd(dim, dims); size_t ind = FindInd(dim, dims);
return ind < dims.size() ? dims[ind].Size() : 0; return ind < dims.size() ? dims[ind].Size() : 0;
} }
@ -535,13 +528,19 @@ class NcZarrTypes
auto AttString(const MString& name) const { return AttString("", name); } auto AttString(const MString& name) const { return AttString("", name); }
auto AttBool(const MString& name) const { return AttBool("", name); } auto AttBool(const MString& name) const { return AttBool("", name); }
bool HasDim(const MString& name) const { return FindInd(name, dims) < dims.size(); } bool HasDim(const MString& var, const MString& name) const
{
size_t vind = FindInd(var, vars);
if(vind >= vars.size()) return false;
for(const auto dind: vars[vind].Dims())
if(dims[dind].Name() == name) return true;
return false;
}
bool HasVar(const MString& name) const { return FindInd(name, vars) < vars.size(); } bool HasVar(const MString& name) const { return FindInd(name, vars) < vars.size(); }
bool HasAtt(const MString& vname, const MString& aname) const { return AttT(vname, aname) != AttType::UNDEF; } bool HasAtt(const MString& vname, const MString& aname) const { return AttT(vname, aname) != AttType::UNDEF; }
bool HasAtt(const MString& aname) const { return AttT(aname) != AttType::UNDEF; } bool HasAtt(const MString& aname) const { return AttT(aname) != AttType::UNDEF; }
const auto& Vars() const { return vars; }
const auto& Dims() const { return dims; }
}; };
class DimReqDef class DimReqDef
@ -713,7 +712,8 @@ template<class C> class NcZarrRead: public C, public DimReqDef
std::vector<struct DimReq> pdims; std::vector<struct DimReq> pdims;
const auto vdims = C::DimNames(vname); const auto vdims = C::DimNames(vname);
std::transform(vdims.cbegin(), vdims.cend(), std::back_inserter(pdims), [this](const MString& n) -> struct DimReq { return {n, 0, C::DimSize(n)}; }); std::transform(vdims.cbegin(), vdims.cend(), std::back_inserter(pdims),
[this, &vname = std::as_const(vname)](const MString& n) -> struct DimReq { return {n, 0, C::DimSize(vname, n)}; });
return Read(vname, data, transform, pdims); return Read(vname, data, transform, pdims);
} }
@ -744,7 +744,7 @@ template<class C> class NcZarrRead: public C, public DimReqDef
if(transindex[i] == ind) return {pref, "Parameters for dimension " + req.name + " already defined"}; if(transindex[i] == ind) return {pref, "Parameters for dimension " + req.name + " already defined"};
transindex.push_back(ind); transindex.push_back(ind);
size_t dlen = C::DimSize(pdims[ind].name); size_t dlen = C::DimSize(vname, pdims[ind].name);
if(req.beg == req.fill && req.count == req.fill) // Only name, so, we request full length if(req.beg == req.fill && req.count == req.fill) // Only name, so, we request full length
{ {
pdims[ind].beg = 0; pdims[ind].beg = 0;
@ -818,7 +818,7 @@ template<class C> class NcZarrRead: public C, public DimReqDef
template<class Type> Error Read(const MString& vname, std::vector<Type>& out) const template<class Type> Error Read(const MString& vname, std::vector<Type>& out) const
{ {
const auto& dnames = C::DimNames(vname); const auto& dnames = C::DimNames(vname);
if(dnames.size() > 0) out.resize(C::DimSize(dnames[0])); if(dnames.size() > 0) out.resize(C::DimSize(vname, dnames[0]));
auto data = [&vec = out](size_t i) -> Type& { return vec[i]; }; auto data = [&vec = out](size_t i) -> Type& { return vec[i]; };
return Read(vname, data, std::identity()); return Read(vname, data, std::identity());

3
sources/AVISOLOCAL.cpp

@ -6,7 +6,8 @@ MString AVISOLOCALData::Info() const
if(!isOk()) return ""; if(!isOk()) return "";
NCFileA nc; NCFileA nc;
struct CoordNames cn, dn; struct CoordNames cn;
struct DimNames dn;
std::set<MString> vars; std::set<MString> vars;
nc.Reset(datapath + "/uv-" + times[0].ToString() + ".nc"); nc.Reset(datapath + "/uv-" + times[0].ToString() + ".nc");

6
src/layereddataz.cpp

@ -229,10 +229,10 @@ bool LayeredDataZ::Read(const MString& vname, std::map<MString, LayeredDataZ::Da
bool nodepth = false; bool nodepth = false;
Data data; Data data;
//auto head = nc[id]->Header(); //auto head = nc[id]->Header();
for(const auto& v: nc[id].Vars()) for(const auto& v: nc[id].VarNames())
if(v.Name() == name) if(v == name)
{ {
if(v.NDim() == 3) nodepth = true; if(nc[id].NDim(v) == 3) nodepth = true;
data = ReadVarRaw(nc[id], name, tid, nodepth, p); data = ReadVarRaw(nc[id], name, tid, nodepth, p);
if(data) if(data)
{ {

93
src/ncfuncs.cpp

@ -1,10 +1,10 @@
#define MICHLIB_NOSOURCE #define MICHLIB_NOSOURCE
#include "ncfuncs.h" #include "ncfuncs.h"
NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc) NCFuncs::DimNames NCFuncs::GetDNames(const NCFileA& nc)
{ {
CoordNames out; DimNames out;
auto head = nc.Header(); auto head = nc.Header();
for(const auto& dim: head.Dimensions()) for(const auto& dim: head.Dimensions())
{ {
if(dim.Name() == "lon" || dim.Name() == "longitude") if(dim.Name() == "lon" || dim.Name() == "longitude")
@ -31,32 +31,33 @@ NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc)
return out; return out;
} }
NCFuncs::CoordNames NCFuncs::GetDNames(const NCZarr& nc) NCFuncs::DimNames NCFuncs::GetDNames(const NCZarr& nc)
{ {
CoordNames out; DimNames out;
for(const auto& dim: nc.Dims()) for(const auto& v: nc.VarNames())
{ for(const auto& dim: nc.DimNames(v))
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")
{ {
out.depthname = dim.Name(); if(dim == "lon" || dim == "longitude")
out.nz = dim.Size(); {
} out.lonname = dim;
if(dim.Name() == "time") out.nx = nc.DimSize(v, dim);
{ }
out.timename = dim.Name(); if(dim == "lat" || dim == "latitude")
out.nt = dim.Size(); {
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; return out;
} }
@ -84,11 +85,6 @@ NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc)
if(islat) out.latname = v.Name(); if(islat) out.latname = v.Name();
if(isdepth) out.depthname = v.Name(); if(isdepth) out.depthname = v.Name();
if(istime) out.timename = 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; return out;
} }
@ -96,14 +92,14 @@ NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc)
NCFuncs::CoordNames NCFuncs::GetCNames(const NCZarr& nc) NCFuncs::CoordNames NCFuncs::GetCNames(const NCZarr& nc)
{ {
CoordNames out; 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 havestname = nc.HasAtt(v, "standard_name");
auto haveaxis = nc.HasAtt(v.Name(), "axis"); auto haveaxis = nc.HasAtt(v, "axis");
if(!(havestname || haveaxis)) continue; if(!(havestname || haveaxis)) continue;
auto stname = nc.AttString(v.Name(), "standard_name"); auto stname = nc.AttString(v, "standard_name");
auto axis = nc.AttString(v.Name(), "axis"); auto axis = nc.AttString(v, "axis");
bool islon = false, islat = false, isdepth = false, istime = false; bool islon = false, islat = false, isdepth = false, istime = false;
if(stname == "longitude") islon = true; if(stname == "longitude") islon = true;
if(stname == "latitude") islat = 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.depthname.Exist() && axis == "Z") isdepth = true;
if(!out.timename.Exist() && axis == "T") istime = true; if(!out.timename.Exist() && axis == "T") istime = true;
if(islon) out.lonname = v.Name(); if(islon) out.lonname = v;
if(islat) out.latname = v.Name(); if(islat) out.latname = v;
if(isdepth) out.depthname = v.Name(); if(isdepth) out.depthname = v;
if(istime) out.timename = v.Name(); if(istime) out.timename = v;
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 time not found just check variable "time" // 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) 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; if(!nc.HasAtt(v, "standard_name")) continue;
auto ret = nc.AttString(v.Name(), "standard_name"); auto ret = nc.AttString(v, "standard_name");
if(StName2Name(ret).Exist()) vars.emplace(StName2Name(ret)); if(StName2Name(ret).Exist()) vars.emplace(StName2Name(ret));
} }
if((vars.contains("ptemp") || vars.contains("temp")) && vars.contains("sal")) vars.emplace("pdens"); 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) 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; if(!nc.HasAtt(v, "standard_name")) continue;
auto stname = nc.AttString(v.Name(), "standard_name"); auto stname = nc.AttString(v, "standard_name");
if(StName2Name(stname) == vname) return true; if(StName2Name(stname) == vname) return true;
} }
return false; return false;

Loading…
Cancel
Save