diff --git a/include/layereddataz.h b/include/layereddataz.h index f0000bd..f70b6ca 100644 --- a/include/layereddataz.h +++ b/include/layereddataz.h @@ -1,8 +1,8 @@ #pragma once #include "gsw.h" #include "ncfuncs.h" +#include "nczarr.h" #include "simple2ddata.h" -#include "zarr.h" #include using michlib::Ceil; @@ -17,7 +17,7 @@ class LayeredDataZ: public NCFuncs using Data = Simple2DData; private: - class NC: public Zarr + class NC: public NCZarr { std::vector times; diff --git a/include/ncfuncs.h b/include/ncfuncs.h index c819017..fc508fb 100644 --- a/include/ncfuncs.h +++ b/include/ncfuncs.h @@ -2,8 +2,7 @@ #include "DataAdapters/ncfilealt.h" #include "basedata.h" #include "mdatetime.h" -#include "ncsimple.h" -#include "zarr.h" +#include "nczarr.h" #include #include #include @@ -30,10 +29,10 @@ class NCFuncs static CoordNames GetDNames(const NCFileA& nc); static bool HaveVar(const NCFileA& nc, const MString& vname); - template static void GetVars(const NcZarrRead& nc, std::set& vars); - template static CoordNames GetCNames(const NcZarrRead& nc); - template static CoordNames GetDNames(const NcZarrRead& nc); - template static bool HaveVar(const NcZarrRead& nc, const MString& vname); + static void GetVars(const NCZarr& nc, std::set& vars); + static CoordNames GetCNames(const NCZarr& nc); + static CoordNames GetDNames(const NCZarr& nc); + static bool HaveVar(const NCZarr& nc, const MString& vname); template static VarPresence CheckVar(const MString& vname, HV hv) { @@ -53,9 +52,7 @@ class NCFuncs template static bool TransformationRead(const D* data, const MString& vname, std::map& cache, const BaseParameters* ip, size_t i) { if constexpr(requires(const D* d, const BaseParameters* p) { - { - d->Depth(p) - } -> std::convertible_to; + { d->Depth(p) } -> std::convertible_to; }) { real depth = data->Depth(ip); diff --git a/include/nczarr.h b/include/nczarr.h new file mode 100644 index 0000000..17902e2 --- /dev/null +++ b/include/nczarr.h @@ -0,0 +1,148 @@ +#pragma once +#include "ncsimple.h" +#include "zarr.h" +#include + +using NCZarrBase = std::variant; + +#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 auto V(Visitor&& visitor) const { return std::visit(std::forward(visitor), *static_cast(this)); } + + public: + explicit operator bool() const + { + return V([](const auto& arg) { return static_cast(arg); }); + } + + DEFFUNC(NDim) + DEFFUNC1(NDim) + + DEFFUNC(NAtt) + DEFFUNC1(NAtt) + + DEFFUNC(AttNames) + DEFFUNC1(AttNames) + + DEFFUNC(VarNames) + DEFFUNC1(VarT) + DEFFUNC1(VarFill) + + DEFFUNC(DimNames) + DEFFUNC1(DimNames) + + DEFFUNC1(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) + + DEFFUNC1(HasDim) + DEFFUNC1(HasVar) + DEFFUNC1(HasAtt) + DEFFUNC2(HasAtt) + + DEFFUNC(Vars) + DEFFUNC(Dims) + + template 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 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 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 + 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 + 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 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 Error Read(const MString& vname, Data& data, Transform transform, const std::vector& 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 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 Error Read(const MString& vname, std::vector& 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(this); + + *pv = NCZarrBase(NCSimple()); + auto p = std::get_if(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(this); + + *pv = NCZarrBase(Zarr()); + auto p = std::get_if(pv); + if(p == nullptr) return Error("NCZarr::OpenNC", "Impossible error!"); + return p->Open(product, dataset, time); + } +}; + +#undef DEFFUNC +#undef DEFFUNC1 +#undef DEFFUNC2 diff --git a/include/nczarrcommon.h b/include/nczarrcommon.h index 414b1c8..783e467 100644 --- a/include/nczarrcommon.h +++ b/include/nczarrcommon.h @@ -379,7 +379,7 @@ class NcZarrTypes std::vector vars; public: - operator bool() const { return !vars.empty(); } + explicit operator bool() const { return !vars.empty(); } size_t NDim() const { return dims.size(); } @@ -603,8 +603,6 @@ template class NcZarrRead: public C, public DimReqDef template Error Read(const MString& vname, const std::vector& transindex, Data& data, Transform transform, std::vector reqs) const { - size_t nval = 1; - for(const auto& r: reqs) nval *= r.count; const size_t indim = reqs.size(); constexpr size_t outdim = Dimensionity(); @@ -633,9 +631,7 @@ template class NcZarrRead: public C, public DimReqDef C::VarFill(vname)); if constexpr(requires(Data& d) { // Data have own fillvalue - { - d.Fillval() - } -> std::convertible_to; + { d.Fillval() } -> std::convertible_to; }) fillout = data.Fillval(); else // Data does'nt have own fillvalue, using variable fillvalue @@ -717,16 +713,13 @@ template class NcZarrRead: public C, public DimReqDef std::vector 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](const MString& n) -> struct DimReq { return {n, 0, C::DimSize(n)}; }); return Read(vname, data, transform, pdims); } // Base function for all Read's - template Error Read(const MString& vname, Data& data, Transform transform, std::vector reqs) const + template Error Read(const MString& vname, Data& data, Transform transform, const std::vector& reqs) const { static const MString pref = "NcZarrRead::Read"; @@ -735,10 +728,7 @@ template class NcZarrRead: public C, public DimReqDef std::vector pdims; { const auto vdims = C::DimNames(vname); - std::transform( - vdims.cbegin(), vdims.cend(), std::back_inserter(pdims), [](const MString& n) -> struct DimReq { - return {n, 0, 1}; - }); + std::transform(vdims.cbegin(), vdims.cend(), std::back_inserter(pdims), [](const MString& n) -> struct DimReq { return {n, 0, 1}; }); } std::vector transindex; diff --git a/src/layereddataz.cpp b/src/layereddataz.cpp index 7ce45fa..b8a21be 100644 --- a/src/layereddataz.cpp +++ b/src/layereddataz.cpp @@ -59,7 +59,7 @@ MString LayeredDataZ::Open(const MString& dataset) nc.emplace_back(); { - auto ret = nc.back().Open(product, dataset); + auto ret = nc.back().OpenZarr(product, dataset); if(!ret) { nc.clear(); diff --git a/src/ncfuncs.cpp b/src/ncfuncs.cpp index a19e329..c799fb1 100644 --- a/src/ncfuncs.cpp +++ b/src/ncfuncs.cpp @@ -31,7 +31,7 @@ NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc) return out; } -template NCFuncs::CoordNames NCFuncs::GetDNames(const NcZarrRead& nc) +NCFuncs::CoordNames NCFuncs::GetDNames(const NCZarr& nc) { CoordNames out; for(const auto& dim: nc.Dims()) @@ -60,8 +60,6 @@ template NCFuncs::CoordNames NCFuncs::GetDNames(const NcZ return out; } -template NCFuncs::CoordNames NCFuncs::GetDNames(const NcZarrRead&); - NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc) { CoordNames out; @@ -95,7 +93,7 @@ NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc) return out; } -template NCFuncs::CoordNames NCFuncs::GetCNames(const NcZarrRead& 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 @@ -133,8 +131,6 @@ template NCFuncs::CoordNames NCFuncs::GetCNames(const NcZ return out; } -template NCFuncs::CoordNames NCFuncs::GetCNames(const NcZarrRead&); - void NCFuncs::GetVars(const NCFileA& nc, std::set& vars) { auto head = nc.Header(); @@ -154,7 +150,7 @@ void NCFuncs::GetVars(const NCFileA& nc, std::set& vars) if(vars.contains("ssh")) vars.emplace("vgeo"); } -template void NCFuncs::GetVars(const NcZarrRead& nc, std::set& vars) +void NCFuncs::GetVars(const NCZarr& nc, std::set& vars) { for(const auto& v: nc.Vars()) { @@ -172,8 +168,6 @@ template void NCFuncs::GetVars(const NcZarrRead(const NcZarrRead&, std::set&); - std::tuple NCFuncs::Refdate(const MString& refdate) { MDateTime out; @@ -278,7 +272,7 @@ bool NCFuncs::HaveVar(const NCFileA& nc, const MString& vname) return false; } -template bool NCFuncs::HaveVar(const NcZarrRead& nc, const MString& vname) +bool NCFuncs::HaveVar(const NCZarr& nc, const MString& vname) { for(const auto& v: nc.Vars()) { @@ -288,5 +282,3 @@ template bool NCFuncs::HaveVar(const NcZarrRead(const NcZarrRead&, const MString&);