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 3 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<real> depths;
std::vector<MDateTime> times;
struct CoordNames dname;
struct DimNames dname;
real lonb, latb, lone, late;
real lonstep, latstep;
MString title;

8
include/layereddataz.h

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

8
include/ncfuncs.h

@ -15,6 +15,10 @@ class NCFuncs
{
public:
struct CoordNames
{
MString lonname, latname, depthname, timename;
};
struct DimNames
{
MString lonname, latname, depthname, timename;
size_t nx, ny, nz, nt;
@ -26,12 +30,12 @@ class NCFuncs
static std::tuple<MDateTime, time_t, bool> Refdate(const MString& refdate);
static void GetVars(const NCFileA& nc, std::set<MString>& vars);
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 void GetVars(const NCZarr& nc, std::set<MString>& vars);
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);
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); });
}
DEFFUNC(NDim)
DEFFUNC1(NDim)
DEFFUNC(NAtt)
@ -44,10 +43,9 @@ class NCZarr: private NCZarrBase, private DimReqDef
DEFFUNC1(VarT)
DEFFUNC1(VarFill)
DEFFUNC(DimNames)
DEFFUNC1(DimNames)
DEFFUNC1(DimSize)
DEFFUNC2(DimSize)
DEFFUNC2(AttT)
DEFFUNC2(AttInt)
@ -63,14 +61,11 @@ class NCZarr: private NCZarrBase, private DimReqDef
DEFFUNC1(AttString)
DEFFUNC1(AttBool)
DEFFUNC1(HasDim)
DEFFUNC2(HasDim)
DEFFUNC1(HasVar)
DEFFUNC1(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
{
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)); });
}
template<class Data, class Transform>
Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3) const
template<class Data, class Transform> 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 arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3)); });
}
template<class Data, class Transform>
Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3, DimReq&& req4) const
template<class Data, class Transform> 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 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:
explicit operator bool() const { return !vars.empty(); }
size_t NDim() const { return dims.size(); }
size_t NDim(const MString& var) const
{
size_t ind = FindInd(var, vars);
@ -431,13 +429,6 @@ class NcZarrTypes
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
{
size_t ind = FindInd(var, vars);
@ -450,8 +441,10 @@ class NcZarrTypes
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);
return ind < dims.size() ? dims[ind].Size() : 0;
}
@ -535,13 +528,19 @@ class NcZarrTypes
auto AttString(const MString& name) const { return AttString("", 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 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; }
const auto& Vars() const { return vars; }
const auto& Dims() const { return dims; }
};
class DimReqDef
@ -713,7 +712,8 @@ template<class C> class NcZarrRead: public C, public DimReqDef
std::vector<struct DimReq> pdims;
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);
}
@ -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"};
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
{
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
{
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]; };
return Read(vname, data, std::identity());

3
sources/AVISOLOCAL.cpp

@ -6,7 +6,8 @@ MString AVISOLOCALData::Info() const
if(!isOk()) return "";
NCFileA nc;
struct CoordNames cn, dn;
struct CoordNames cn;
struct DimNames dn;
std::set<MString> vars;
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;
Data data;
//auto head = nc[id]->Header();
for(const auto& v: nc[id].Vars())
if(v.Name() == name)
for(const auto& v: nc[id].VarNames())
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);
if(data)
{

93
src/ncfuncs.cpp

@ -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;

Loading…
Cancel
Save