Compare commits
No commits in common. '7c3c254b7221b6cfa1025f7509c8573e16148ce4' and '91579910ff3a49ac58a6348d42d79d7d5a2ca6ba' have entirely different histories.
7c3c254b72
...
91579910ff
9 changed files with 115 additions and 462 deletions
@ -1,166 +0,0 @@ |
|||||||
#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 |
|
@ -1,206 +0,0 @@ |
|||||||
#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(); |
|
||||||
} |
|
||||||
}; |
|
Loading…
Reference in new issue