Compare commits

..

3 Commits

  1. 2
      include/layereddata.h
  2. 12
      include/layereddataz.h
  3. 21
      include/ncfuncs.h
  4. 166
      include/nczarr.h
  5. 52
      include/nczarrcommon.h
  6. 206
      include/nczarrmulti.h
  7. 3
      sources/AVISOLOCAL.cpp
  8. 8
      src/layereddataz.cpp
  9. 89
      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;

12
include/layereddataz.h

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "gsw.h" #include "gsw.h"
#include "ncfuncs.h" #include "ncfuncs.h"
#include "nczarr.h"
#include "simple2ddata.h" #include "simple2ddata.h"
#include "zarr.h"
#include <memory> #include <memory>
using michlib::Ceil; using michlib::Ceil;
@ -17,7 +17,7 @@ class LayeredDataZ: public NCFuncs
using Data = Simple2DData; using Data = Simple2DData;
private: private:
class NC: public Zarr class NC: public NCZarr
{ {
std::vector<MDateTime> times; std::vector<MDateTime> times;
@ -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};

21
include/ncfuncs.h

@ -2,8 +2,7 @@
#include "DataAdapters/ncfilealt.h" #include "DataAdapters/ncfilealt.h"
#include "basedata.h" #include "basedata.h"
#include "mdatetime.h" #include "mdatetime.h"
#include "ncsimple.h" #include "nczarr.h"
#include "zarr.h"
#include <map> #include <map>
#include <set> #include <set>
#include <tuple> #include <tuple>
@ -16,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;
@ -27,13 +30,13 @@ 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);
template<class NcZarrFunctions> static void GetVars(const NcZarrRead<NcZarrFunctions>& nc, std::set<MString>& vars); static void GetVars(const NCZarr& nc, std::set<MString>& vars);
template<class NcZarrFunctions> static CoordNames GetCNames(const NcZarrRead<NcZarrFunctions>& nc); static CoordNames GetCNames(const NCZarr& nc);
template<class NcZarrFunctions> static CoordNames GetDNames(const NcZarrRead<NcZarrFunctions>& nc); static DimNames GetDNames(const NCZarr& nc);
template<class NcZarrFunctions> static bool HaveVar(const NcZarrRead<NcZarrFunctions>& 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)
{ {
@ -53,9 +56,7 @@ class NCFuncs
template<class D> static bool TransformationRead(const D* data, const MString& vname, std::map<MString, typename D::Data>& cache, const BaseParameters* ip, size_t i) template<class D> static bool TransformationRead(const D* data, const MString& vname, std::map<MString, typename D::Data>& cache, const BaseParameters* ip, size_t i)
{ {
if constexpr(requires(const D* d, const BaseParameters* p) { if constexpr(requires(const D* d, const BaseParameters* p) {
{ { d->Depth(p) } -> std::convertible_to<real>;
d->Depth(p)
} -> std::convertible_to<real>;
}) })
{ {
real depth = data->Depth(ip); real depth = data->Depth(ip);

166
include/nczarr.h

@ -0,0 +1,166 @@
#pragma once
#include "nczarrmulti.h"
#include <variant>
using NCZarrBase = std::variant<Zarr, NCSimple, ZarrMulti, NCMulti>;
#define DEFFUNC(NAME) \
auto NAME() const \
{ \
return V([](const auto& arg) { return arg.NAME(); }); \
}
#define DEFFUNC1(NAME) \
auto NAME(const MString& v) const \
{ \
return V([&v = std::as_const(v)](const auto& arg) { return arg.NAME(v); }); \
}
#define DEFFUNC2(NAME) \
auto NAME(const MString& v1, const MString& v2) const \
{ \
return V([&v1 = std::as_const(v1), &v2 = std::as_const(v2)](const auto& arg) { return arg.NAME(v1, v2); }); \
}
class NCZarr: private NCZarrBase, private DimReqDef
{
template<class Visitor> auto V(Visitor&& visitor) const { return std::visit(std::forward<Visitor>(visitor), *static_cast<const NCZarrBase*>(this)); }
public:
explicit operator bool() const
{
return V([](const auto& arg) { return static_cast<bool>(arg); });
}
DEFFUNC1(NDim)
DEFFUNC(NAtt)
DEFFUNC1(NAtt)
DEFFUNC(AttNames)
DEFFUNC1(AttNames)
DEFFUNC(VarNames)
DEFFUNC1(VarT)
DEFFUNC1(VarFill)
DEFFUNC1(DimNames)
DEFFUNC2(DimSize)
DEFFUNC2(AttT)
DEFFUNC2(AttInt)
DEFFUNC2(AttUInt)
DEFFUNC2(AttReal)
DEFFUNC2(AttString)
DEFFUNC2(AttBool)
DEFFUNC1(AttT)
DEFFUNC1(AttInt)
DEFFUNC1(AttUInt)
DEFFUNC1(AttReal)
DEFFUNC1(AttString)
DEFFUNC1(AttBool)
DEFFUNC2(HasDim)
DEFFUNC1(HasVar)
DEFFUNC1(HasAtt)
DEFFUNC2(HasAtt)
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); });
}
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1) const
{
return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1](const auto& arg) { return arg.Read(vname, data, transform, std::move(req1)); });
}
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2) const
{
return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2](const auto& arg)
{ 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
{
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
{
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)); });
}
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform) const
{
return V([&vname = std::as_const(vname), &data = data, &transform = transform](const auto& arg) { return arg.Read(vname, data, transform); });
}
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const std::vector<DimReqDef::DimReq>& reqs) const
{
return V([&vname = std::as_const(vname), &data = data, &transform = transform, &reqs = std::as_const(reqs)](const auto& arg) { return arg.Read(vname, data, transform, reqs); });
}
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const MString& request) const
{
return V([&vname = std::as_const(vname), &data = data, &transform = transform, &request = std::as_const(request)](const auto& arg)
{ return arg.Read(vname, data, transform, request); });
}
template<class Type> Error Read(const MString& vname, std::vector<Type>& out) const
{
return V([&vname = std::as_const(vname), &out = out](const auto& arg) { return arg.Read(vname, out); });
}
Error OpenNC(const MString& filename)
{
auto pv = static_cast<NCZarrBase*>(this);
*pv = NCZarrBase(NCSimple());
auto p = std::get_if<NCSimple>(pv);
if(p == nullptr) return Error("NCZarr::OpenNC", "Impossible error!");
return p->Open(filename);
}
Error OpenZarr(const MString& product, const MString& dataset, bool time = true)
{
auto pv = static_cast<NCZarrBase*>(this);
*pv = NCZarrBase(Zarr());
auto p = std::get_if<Zarr>(pv);
if(p == nullptr) return Error("NCZarr::OpenNC", "Impossible error!");
return p->Open(product, dataset, time);
}
Error OpenMultiNC(const std::vector<MString>& names)
{
if(names.size() == 0) return Error("NCZarr::OpenMultiNC", "no names");
if(names.size() == 1) return OpenNC(names[0]);
auto pv = static_cast<NCZarrBase*>(this);
*pv = NCZarrBase(NCMulti());
auto p = std::get_if<NCMulti>(pv);
if(p == nullptr) return Error("NCZarr::OpenMultiNC", "Impossible error!");
return p->Open(names);
}
Error OpenMultiZarr(const MString& product, const std::vector<MString>& dsets, bool time = true)
{
if(dsets.size() == 0) return Error("NCZarr::OpenMultiZarr", "no datasets");
if(dsets.size() == 1) return OpenZarr(product, dsets[0], time);
auto pv = static_cast<NCZarrBase*>(this);
*pv = NCZarrBase(ZarrMulti());
auto p = std::get_if<ZarrMulti>(pv);
if(p == nullptr) return Error("NCZarr::OpenMultiZarr", "Impossible error!");
return p->Open(product, dsets, time);
}
};
#undef DEFFUNC
#undef DEFFUNC1
#undef DEFFUNC2

52
include/nczarrcommon.h

@ -379,9 +379,7 @@ class NcZarrTypes
std::vector<Variable> vars; std::vector<Variable> vars;
public: public:
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
{ {
@ -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
@ -603,8 +602,6 @@ template<class C> class NcZarrRead: public C, public DimReqDef
template<class VType, class Data, class Transform> template<class VType, class Data, class Transform>
Error Read(const MString& vname, const std::vector<size_t>& transindex, Data& data, Transform transform, std::vector<DimReq> reqs) const Error Read(const MString& vname, const std::vector<size_t>& transindex, Data& data, Transform transform, std::vector<DimReq> reqs) const
{ {
size_t nval = 1;
for(const auto& r: reqs) nval *= r.count;
const size_t indim = reqs.size(); const size_t indim = reqs.size();
constexpr size_t outdim = Dimensionity<Data>(); constexpr size_t outdim = Dimensionity<Data>();
@ -633,9 +630,7 @@ template<class C> class NcZarrRead: public C, public DimReqDef
C::VarFill(vname)); C::VarFill(vname));
if constexpr(requires(Data& d) { // Data have own fillvalue if constexpr(requires(Data& d) { // Data have own fillvalue
{ { d.Fillval() } -> std::convertible_to<DataType>;
d.Fillval()
} -> std::convertible_to<DataType>;
}) })
fillout = data.Fillval(); fillout = data.Fillval();
else // Data does'nt have own fillvalue, using variable fillvalue else // Data does'nt have own fillvalue, using variable fillvalue
@ -717,16 +712,14 @@ 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( std::transform(vdims.cbegin(), vdims.cend(), std::back_inserter(pdims),
vdims.cbegin(), vdims.cend(), std::back_inserter(pdims), [this](const MString& n) -> struct DimReq { [this, &vname = std::as_const(vname)](const MString& n) -> struct DimReq { return {n, 0, C::DimSize(vname, n)}; });
return {n, 0, C::DimSize(n)};
});
return Read(vname, data, transform, pdims); return Read(vname, data, transform, pdims);
} }
// Base function for all Read's // Base function for all Read's
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, std::vector<DimReq> reqs) const template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const std::vector<DimReq>& reqs) const
{ {
static const MString pref = "NcZarrRead::Read"; static const MString pref = "NcZarrRead::Read";
@ -735,10 +728,7 @@ 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( std::transform(vdims.cbegin(), vdims.cend(), std::back_inserter(pdims), [](const MString& n) -> struct DimReq { return {n, 0, 1}; });
vdims.cbegin(), vdims.cend(), std::back_inserter(pdims), [](const MString& n) -> struct DimReq {
return {n, 0, 1};
});
} }
std::vector<size_t> transindex; std::vector<size_t> transindex;
@ -754,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;
@ -828,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());

206
include/nczarrmulti.h

@ -0,0 +1,206 @@
#pragma once
#include "ncsimple.h"
#include "zarr.h"
#include <set>
#define DEFFUNC(func, def) \
auto func(const MString& var) const \
{ \
const auto ind = FindVar(var); \
return ind < sources.size() ? sources[ind].func(var) : (def); \
}
#define DEFFUNCA(func, def) \
auto func(const MString& att) const \
{ \
const auto ind = FindAtt(att); \
return ind < sources.size() ? sources[ind].func(att) : (def); \
}
#define DEFFUNC2(func, def) \
auto func(const MString& var, const MString& name) const \
{ \
const auto ind = FindVar(var); \
return ind < sources.size() ? sources[ind].func(var, name) : (def); \
}
#define DEFFUNCNAMES(func) \
auto func() const \
{ \
std::set<MString> names; \
for(const auto& s: sources) \
{ \
auto snames = s.func(); \
for(const auto& name: snames) names.insert(name); \
} \
std::vector<MString> out; \
for(const auto& name: names) out.push_back(name); \
return out; \
}
template<class T> class NCZarrMultiCommon: private DimReqDef
{
protected:
std::vector<T> sources;
private:
size_t FindVar(const MString& var) const
{
for(size_t i = 0; i < sources.size(); i++)
if(sources[i].HasVar(var)) return i;
return sources.size();
}
size_t FindAtt(const MString& att) const
{
for(size_t i = 0; i < sources.size(); i++)
if(sources[i].HasAtt(att)) return i;
return sources.size();
}
public:
explicit operator bool() const
{
if(sources.empty()) return false;
for(const auto& s: sources)
if(!s) return false;
return true;
}
size_t NDim() const { return DimNames().size(); }
DEFFUNC(NDim, 0)
size_t NAtt() const { return AttNames().size(); }
DEFFUNC(NAtt, 0)
DEFFUNCNAMES(AttNames)
DEFFUNC(AttNames, decltype(AttNames())())
DEFFUNCNAMES(VarNames)
DEFFUNC(VarT, T::VarType::UNDEF)
DEFFUNC(VarFill, decltype(T().VarFill(MString()))())
DEFFUNC(DimNames, decltype(T().DimNames(MString()))())
DEFFUNC2(DimSize, 0)
DEFFUNC2(AttT, T::AttType::UNDEF)
DEFFUNC2(AttInt, 0)
DEFFUNC2(AttUInt, 0)
DEFFUNC2(AttReal, 0.0)
DEFFUNC2(AttString, MString())
DEFFUNC2(AttBool, false)
DEFFUNCA(AttT, T::AttType::UNDEF)
DEFFUNCA(AttInt, 0)
DEFFUNCA(AttUInt, 0)
DEFFUNCA(AttReal, 0.0)
DEFFUNCA(AttString, MString())
DEFFUNCA(AttBool, false)
DEFFUNC2(HasDim, false)
DEFFUNC(HasVar, false)
DEFFUNCA(HasAtt, false)
DEFFUNC2(HasAtt, false)
// Request is string
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const char* request) const
{
return Read(vname, data, transform, MString(request));
}
// Request by one dimension
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1) const
{
return Read(vname, data, transform, std::vector<DimReq>{std::move(req1)});
}
// Request by two dimension
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2) const
{
return Read(vname, data, transform, std::vector<DimReq>{std::move(req1), std::move(req2)});
}
// Request by three dimension
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3) const
{
return Read(vname, data, transform, std::vector<DimReq>{std::move(req1), std::move(req2), std::move(req3)});
}
// Request by four dimension
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3, DimReq&& req4) const
{
return Read(vname, data, transform, std::vector<DimReq>{std::move(req1), std::move(req2), std::move(req3), std::move(req4)});
}
// Request full variable
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform) const
{
auto ind = FindVar(vname);
if(ind < sources.size()) return sources[ind].Read(vname, data, transform);
return Error("NCZarrMultiCommon::Read", "Variable " + vname + " not found");
}
// Base function for all Read's
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const std::vector<DimReqDef::DimReq>& reqs) const
{
auto ind = FindVar(vname);
if(ind < sources.size()) return sources[ind].Read(vname, data, transform, reqs);
return Error("NCZarrMultiCommon::Read", "Variable " + vname + " not found");
}
// Request by string argument
template<class Data, class Transform> Error Read(const MString& vname, Data& data, Transform transform, const MString& request) const
{
auto ind = FindVar(vname);
if(ind < sources.size()) return sources[ind].Read(vname, data, transform, request);
return Error("NCZarrMultiCommon::Read", "Variable " + vname + " not found");
}
// Request full one-dimensional variable
template<class Type> Error Read(const MString& vname, std::vector<Type>& out) const
{
auto ind = FindVar(vname);
if(ind < sources.size()) return sources[ind].Read(vname, out);
return Error("NCZarrMultiCommon::Read", "Variable " + vname + " not found");
}
};
#undef DEFFUNC
#undef DEFFUNCA
#undef DEFFUNC2
#undef DEFFUNCNAME
class NCMulti: public NCZarrMultiCommon<NCSimple>
{
public:
Error Open(const std::vector<MString>& names)
{
sources.clear();
decltype(sources) newsources;
static const MString pref = "NcMulti::Open";
if(names.size() == 0) return Error(pref, "empty file list");
for(const auto& name: names)
{
newsources.emplace_back();
auto ret = newsources.back().Open(name);
if(!ret) return ret.Add(pref, "Can't open file " + name);
}
sources = std::move(newsources);
return Error();
}
};
class ZarrMulti: public NCZarrMultiCommon<Zarr>
{
public:
Error Open(const MString& product, const std::vector<MString>& dsets, bool time = true)
{
sources.clear();
decltype(sources) newsources;
static const MString pref = "ZarrMulti::Open";
if(dsets.size() == 0) return Error(pref, "empty datasets list");
for(const auto& dset: dsets)
{
newsources.emplace_back();
auto ret = newsources.back().Open(product, dset, time);
if(!ret) return ret.Add(pref, "Can't open dataset " + dset);
}
sources = std::move(newsources);
return Error();
}
};

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");

8
src/layereddataz.cpp

@ -59,7 +59,7 @@ MString LayeredDataZ::Open(const MString& dataset)
nc.emplace_back(); nc.emplace_back();
{ {
auto ret = nc.back().Open(product, dataset); auto ret = nc.back().OpenZarr(product, dataset);
if(!ret) if(!ret)
{ {
nc.clear(); nc.clear();
@ -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)
{ {

89
src/ncfuncs.cpp

@ -1,9 +1,9 @@
#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())
{ {
@ -31,37 +31,36 @@ NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc)
return out; return out;
} }
template<class NcZarrFunctions> NCFuncs::CoordNames NCFuncs::GetDNames(const NcZarrRead<NcZarrFunctions>& 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") if(dim == "lon" || dim == "longitude")
{ {
out.lonname = dim.Name(); out.lonname = dim;
out.nx = dim.Size(); out.nx = nc.DimSize(v, dim);
} }
if(dim.Name() == "lat" || dim.Name() == "latitude") if(dim == "lat" || dim == "latitude")
{ {
out.latname = dim.Name(); out.latname = dim;
out.ny = dim.Size(); out.ny = nc.DimSize(v, dim);
} }
if(dim.Name() == "depth" || dim.Name() == "elevation") if(dim == "depth" || dim == "elevation")
{ {
out.depthname = dim.Name(); out.depthname = dim;
out.nz = dim.Size(); out.nz = nc.DimSize(v, dim);
} }
if(dim.Name() == "time") if(dim == "time")
{ {
out.timename = dim.Name(); out.timename = dim;
out.nt = dim.Size(); out.nt = nc.DimSize(v, dim);
} }
} }
return out; return out;
} }
template NCFuncs::CoordNames NCFuncs::GetDNames<ZarrFunctions>(const NcZarrRead<ZarrFunctions>&);
NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc) NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc)
{ {
CoordNames out; CoordNames out;
@ -86,26 +85,21 @@ 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;
} }
template<class NcZarrFunctions> NCFuncs::CoordNames NCFuncs::GetCNames(const NcZarrRead<NcZarrFunctions>& 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;
@ -117,15 +111,10 @@ template<class NcZarrFunctions> NCFuncs::CoordNames NCFuncs::GetCNames(const NcZ
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"
@ -133,8 +122,6 @@ template<class NcZarrFunctions> NCFuncs::CoordNames NCFuncs::GetCNames(const NcZ
return out; return out;
} }
template NCFuncs::CoordNames NCFuncs::GetCNames<ZarrFunctions>(const NcZarrRead<ZarrFunctions>&);
void NCFuncs::GetVars(const NCFileA& nc, std::set<MString>& vars) void NCFuncs::GetVars(const NCFileA& nc, std::set<MString>& vars)
{ {
auto head = nc.Header(); auto head = nc.Header();
@ -154,12 +141,12 @@ void NCFuncs::GetVars(const NCFileA& nc, std::set<MString>& vars)
if(vars.contains("ssh")) vars.emplace("vgeo"); if(vars.contains("ssh")) vars.emplace("vgeo");
} }
template<class NcZarrFunctions> void NCFuncs::GetVars(const NcZarrRead<NcZarrFunctions>& 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");
@ -172,8 +159,6 @@ template<class NcZarrFunctions> void NCFuncs::GetVars(const NcZarrRead<NcZarrFun
if(vars.contains("ssh")) vars.emplace("vgeo"); if(vars.contains("ssh")) vars.emplace("vgeo");
} }
template void NCFuncs::GetVars<ZarrFunctions>(const NcZarrRead<ZarrFunctions>&, std::set<MString>&);
std::tuple<MDateTime, time_t, bool> NCFuncs::Refdate(const MString& refdate) std::tuple<MDateTime, time_t, bool> NCFuncs::Refdate(const MString& refdate)
{ {
MDateTime out; MDateTime out;
@ -278,15 +263,13 @@ bool NCFuncs::HaveVar(const NCFileA& nc, const MString& vname)
return false; return false;
} }
template<class NcZarrFunctions> bool NCFuncs::HaveVar(const NcZarrRead<NcZarrFunctions>& 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;
} }
template bool NCFuncs::HaveVar<ZarrFunctions>(const NcZarrRead<ZarrFunctions>&, const MString&);

Loading…
Cancel
Save