Browse Source

Make Adapter::VInfo virtual

master
Michael Uleysky 3 weeks ago
parent
commit
44577945ce
  1. 6
      actions/actioninfo.h
  2. 43
      include/Adapter.h
  3. 79
      src/Adapter.cpp
  4. 40
      src/CF.cpp
  5. 22
      src/ncfilew.cpp

6
actions/actioninfo.h

@ -64,9 +64,9 @@ MString ActionInfo_DoAction(const CLArgs& args, D& data)
message("");
// Metainfo
message(ad.Is2D(name) ? v2dCol : v3dCol, name, C(), info.lname.Exist() ? (" - " + info.lname) : "",
info.targetunit.Exist() ? (", measured in " + unitCol + info.targetunit + C()) : "");
if(info.stname.Exist()) message(" Standard name: " + info.stname);
message(ad.Is2D(name) ? v2dCol : v3dCol, name, C(), info->lname.Exist() ? (" - " + info->lname) : "",
info->targetunit.Exist() ? (", measured in " + unitCol + info->targetunit + C()) : "");
if(info->stname.Exist()) message(" Standard name: " + info->stname);
// Vertical grid description
if(!ad.Is2D(name))

43
include/Adapter.h

@ -24,28 +24,40 @@ class Adapter
};
// Информация о переменной
struct VInfo
struct VInfoBase
{
MString name; // Внутреннее имя в файле
MString unit, stname, lname, comment; // Единица измерения в файле, стандартное имя, человеческое имя, комментарий
MString targetunit; // Единица измерения прочитанных данных
std::shared_ptr<struct ReadInfo> rinfo; // Информация о блоке чтения
real scale; // Масштаб и
real offset; // смещение величины в файле
real fillval; // _FillVal
MString stname, lname, comment; // Стандартное имя, человеческое имя, комментарий
MString targetunit; // Единица измерения прочитанных данных
std::shared_ptr<struct ReadInfo> rinfo; // Информация о блоке чтения
real fillval; // _FillVal
virtual ~VInfoBase() = default;
};
using VInfo = std::unique_ptr<VInfoBase>;
// Информация о переменной в файле
struct VInfoNC: public VInfoBase
{
MString name; // Внутреннее имя в файле
MString unit; // Единица измерения в файле
real scale; // Масштаб и
real offset; // смещение величины в файле
virtual ~VInfoNC() override = default;
};
// Полная информация о переменной
struct VarInfo
{
struct VInfo info; // Информация о переменной в файле
VInfo info; // Информация о переменной для функций чтения и записи
std::shared_ptr<Projection> proj; // Горизонтальная структура прочитанных данных
std::shared_ptr<Vertical> vert; // Вертикальная структура прочитанных данных
// Функции чтения двумерного и трёхмерного блоков
std::function<RetVal<std::shared_ptr<Data2D>>(const Adapter&, const void*, std::shared_ptr<Projection>, size_t)> Read2D; // = Def2DReader;
std::function<RetVal<std::shared_ptr<Data3D>>(const Adapter&, const void*, std::shared_ptr<Projection>, std::shared_ptr<Vertical>, size_t)> Read3D; // = Def3DReader;
std::function<RetVal<std::shared_ptr<Data2D>>(const Adapter&, const struct VInfoBase*, std::shared_ptr<Projection>, size_t)> Read2D; // = Def2DReader;
std::function<RetVal<std::shared_ptr<Data3D>>(const Adapter&, const struct VInfoBase*, std::shared_ptr<Projection>, std::shared_ptr<Vertical>, size_t)> Read3D; // = Def3DReader;
};
// Запись в таблице файлов
@ -86,12 +98,13 @@ class Adapter
void SetTitle(const MString& t) { title = t; }
void Add2DVariable(const MString& name, struct VInfo&& vinfo, std::shared_ptr<Projection> proj, decltype(VarInfo().Read2D) func = Def2DReader)
void Add2DVariable(const MString& name, std::unique_ptr<VInfoBase>&& vinfo, std::shared_ptr<Projection> proj, decltype(VarInfo().Read2D) func = Def2DReader)
{
vars[name] = {.info = std::move(vinfo), .proj = proj, .Read2D = func, .Read3D = {}};
}
void Add3DVariable(const MString& name, struct VInfo&& vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, decltype(VarInfo().Read3D) func = Def3DReader)
void Add3DVariable(const MString& name, std::unique_ptr<VInfoBase>&& vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert,
decltype(VarInfo().Read3D) func = Def3DReader)
{
vars[name] = {.info = std::move(vinfo), .proj = proj, .vert = vert, .Read2D = {}, .Read3D = func};
}
@ -121,9 +134,9 @@ class Adapter
private:
// Функция чтения двумерных данных по умолчанию
static RetVal<std::shared_ptr<Data2D>> Def2DReader(const Adapter& ad, const void* vinfo, std::shared_ptr<Projection> proj, size_t it);
static RetVal<std::shared_ptr<Data2D>> Def2DReader(const Adapter& ad, const struct VInfoBase* vinfo, std::shared_ptr<Projection> proj, size_t it);
// Функция чтения трёхмерных данных по умолчанию
static RetVal<std::shared_ptr<Data3D>> Def3DReader(const Adapter& ad, const void* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, size_t it);
static RetVal<std::shared_ptr<Data3D>> Def3DReader(const Adapter& ad, const struct VInfoBase* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, size_t it);
// Создание индексов tindexes сообразно параметрам командной строки
Error FilterTimes(const CLArgs& args, michlib_internal::ParameterListEx& pars);

79
src/Adapter.cpp

@ -84,11 +84,12 @@ Error Adapter::FilterTimes(const CLArgs& args, michlib_internal::ParameterListEx
return {};
}
RetVal<std::shared_ptr<Data2D>> Adapter::Def2DReader(const Adapter& ad, const void* vinfo, std::shared_ptr<Projection> proj, size_t it)
RetVal<std::shared_ptr<Data2D>> Adapter::Def2DReader(const Adapter& ad, const struct Adapter::VInfoBase* vinfo, std::shared_ptr<Projection> proj, size_t it)
{
static const MString pref = "Adapter::Def2DReader";
auto v = michlib::pointer_cast<const struct VInfo*>(vinfo);
auto v = dynamic_cast<const struct VInfoNC*>(vinfo);
if(v == nullptr) return {pref, "Incorrect argument type"};
const struct ReadInfo* ri = v->rinfo.get();
@ -142,11 +143,13 @@ RetVal<std::shared_ptr<Data2D>> Adapter::Def2DReader(const Adapter& ad, const vo
return out;
}
RetVal<std::shared_ptr<Data3D>> Adapter::Def3DReader(const Adapter& ad, const void* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, size_t it)
RetVal<std::shared_ptr<Data3D>> Adapter::Def3DReader(const Adapter& ad, const struct Adapter::VInfoBase* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert,
size_t it)
{
static const MString pref = "Adapter::Def3DReader";
auto v = michlib::pointer_cast<const struct VInfo*>(vinfo);
auto v = dynamic_cast<const struct VInfoNC*>(vinfo);
if(v == nullptr) return {pref, "Incorrect argument type"};
const struct ReadInfo* ri = v->rinfo.get();
@ -269,39 +272,43 @@ Error Adapter::ReadCheck(const MString& var, size_t it)
}
{
const auto& v = vars[var];
const auto* ri = v.info.rinfo.get();
const auto& name = v.info.name;
const auto& v = vars[var];
const auto* ri = v.info->rinfo.get();
const auto* pvinfo = dynamic_cast<const struct VInfoNC*>(v.info.get());
const bool isdirect = pvinfo != nullptr; // Variable is directly reading from file, so check indexes and dimensions
const bool layered = ri->zdname.Exist() && nc->HasDim(name, ri->zdname);
if(layered)
if(isdirect)
{
//if(ri->ze < ri->zb) return {pref, "Internal error: ze < zb for variable " + var + "(" + name + ")" + " (" + ri->ze + " < " + ri->zb + ")"};
const size_t nz = nc->DimSize(name, ri->zdname);
if(ri->zb > nz - 1) return {pref, "Internal error: zb > nz - 1 for variable " + var + "(" + name + ")" + " (" + ri->zb + " > " + nz + " - 1)"};
if(ri->ze > nz - 1) return {pref, "Internal error: ze > nz - 1 for variable " + var + "(" + name + ")" + " (" + ri->ze + " > " + nz + " - 1)"};
if(v.vert && (ri->zb < ri->ze ? ri->ze - ri->zb : ri->zb - ri->ze) + 1 != v.vert->Nz())
return {pref, "Internal error: number of requested layers does'nt correspond parameters of vertical column for variable " + var + "(" + name + ")" + " (zb = " + ri->zb +
", ze = " + ri->ze + ", Nz = " + v.vert->Nz()};
const auto& name = pvinfo->name;
const bool layered = ri->zdname.Exist() && nc->HasDim(name, ri->zdname);
if(layered)
{
//if(ri->ze < ri->zb) return {pref, "Internal error: ze < zb for variable " + var + "(" + name + ")" + " (" + ri->ze + " < " + ri->zb + ")"};
const size_t nz = nc->DimSize(name, ri->zdname);
if(ri->zb > nz - 1) return {pref, "Internal error: zb > nz - 1 for variable " + var + "(" + name + ")" + " (" + ri->zb + " > " + nz + " - 1)"};
if(ri->ze > nz - 1) return {pref, "Internal error: ze > nz - 1 for variable " + var + "(" + name + ")" + " (" + ri->ze + " > " + nz + " - 1)"};
if(v.vert && (ri->zb < ri->ze ? ri->ze - ri->zb : ri->zb - ri->ze) + 1 != v.vert->Nz())
return {pref, "Internal error: number of requested layers does'nt correspond parameters of vertical column for variable " + var + "(" + name + ")" + " (zb = " + ri->zb +
", ze = " + ri->ze + ", Nz = " + v.vert->Nz()};
}
if(ri->ye < ri->yb) return {pref, "Internal error: ye < yb for variable " + var + "(" + name + ")" + " (" + ri->ye + " < " + ri->yb + ")"};
const size_t nx = nc->DimSize(name, ri->xdname);
const size_t ny = nc->DimSize(name, ri->ydname);
if(ri->ye > ny - 1) return {pref, "Internal error: ye > ny - 1 for variable " + var + "(" + name + ")" + " (" + ri->ye + " > " + ny + " - 1)"};
if(ri->ye - ri->yb + 1 != v.proj->Ny())
return {pref, "Internal error: number of requested y-planes does'nt correspond parameters of projection for variable " + var + "(" + name + ")" + " (yb = " + ri->yb +
", ye = " + ri->ye + ", Ny = " + v.proj->Ny()};
if(ri->xe > nx - 1) return {pref, "Internal error: xe > nx - 1 for variable " + var + "(" + name + ")" + " (" + ri->xe + " > " + nx + " - 1)"};
if(ri->xb > nx - 1) return {pref, "Internal error: xb > nx - 1 for variable " + var + "(" + name + ")" + " (" + ri->xb + " > " + nx + " - 1)"};
const size_t rnx = (ri->xb <= ri->xe) ? (ri->xe - ri->xb + 1) : (nx + ri->xe - ri->xb + 1);
if(rnx != v.proj->Nx())
return {pref, "Internal error: number of requested x-planes does'nt correspond parameters of projection for variable " + var + "(" + name + ")" + " (xb = " + ri->xb +
", xe = " + ri->xe + ", Nx = " + v.proj->Nx()};
}
if(ri->ye < ri->yb) return {pref, "Internal error: ye < yb for variable " + var + "(" + name + ")" + " (" + ri->ye + " < " + ri->yb + ")"};
const size_t nx = nc->DimSize(name, ri->xdname);
const size_t ny = nc->DimSize(name, ri->ydname);
if(ri->ye > ny - 1) return {pref, "Internal error: ye > ny - 1 for variable " + var + "(" + name + ")" + " (" + ri->ye + " > " + ny + " - 1)"};
if(ri->ye - ri->yb + 1 != v.proj->Ny())
return {pref, "Internal error: number of requested y-planes does'nt correspond parameters of projection for variable " + var + "(" + name + ")" + " (yb = " + ri->yb +
", ye = " + ri->ye + ", Ny = " + v.proj->Ny()};
if(ri->xe > nx - 1) return {pref, "Internal error: xe > nx - 1 for variable " + var + "(" + name + ")" + " (" + ri->xe + " > " + nx + " - 1)"};
if(ri->xb > nx - 1) return {pref, "Internal error: xb > nx - 1 for variable " + var + "(" + name + ")" + " (" + ri->xb + " > " + nx + " - 1)"};
const size_t rnx = (ri->xb <= ri->xe) ? (ri->xe - ri->xb + 1) : (nx + ri->xe - ri->xb + 1);
if(rnx != v.proj->Nx())
return {pref, "Internal error: number of requested x-planes does'nt correspond parameters of projection for variable " + var + "(" + name + ")" + " (xb = " + ri->xb +
", xe = " + ri->xe + ", Nx = " + v.proj->Nx()};
}
return {};
@ -328,7 +335,7 @@ RetVal<std::shared_ptr<Data2D>> Adapter::Read2D(const MString& var, size_t it)
if(!v.Read2D) return {pref, "No read function for the variable " + var};
auto ret = v.Read2D(*this, &v.info, v.proj, curit);
auto ret = v.Read2D(*this, v.info.get(), v.proj, curit);
if(!ret) return ret.Add(pref, "Can't read variable " + var);
(*cache2D)[var] = ret.Value();
return (*cache2D)[var];
@ -356,7 +363,7 @@ RetVal<std::shared_ptr<Data3D>> Adapter::Read3D(const MString& var, size_t it)
if(!v.vert) return {pref, "Variable " + var + " is 2D in the this dataset"};
if(!v.Read3D) return {pref, "No read function for the variable " + var};
auto ret = v.Read3D(*this, &v.info, v.proj, v.vert, curit);
auto ret = v.Read3D(*this, v.info.get(), v.proj, v.vert, curit);
if(!ret) return ret.Add(pref, "Can't read variable " + var);
(*cache3D)[var] = ret.Value();
return (*cache3D)[var];

40
src/CF.cpp

@ -409,32 +409,28 @@ Error CF::FillAdapterFromCF(const CLArgs& args, michlib_internal::ParameterListE
}
if(debug) pars.AddParameter("depthinv", depthinv);
//michlib::message("depth1=", depths[depthinv ? depths.size() - 1 - rinfo->zb : rinfo->zb], ", zb=", rinfo->zb);
//michlib::message("depth2=", depths[depthinv ? depths.size() - 1 - rinfo->ze : rinfo->ze], ", ze=", rinfo->ze);
//michlib::message(depthinv ? "Depths inverted" : "Depths not inverted");
// Read variables information
for(const auto& v: pnc->VarNames())
{
Adapter::VInfo vinfo;
auto dnames = pnc->DimNames(v);
auto vinfo = new Adapter::VInfoNC();
auto dnames = pnc->DimNames(v);
if(dnames.size() != 3 && dnames.size() != 4) continue;
if(dnames.size() == 3 && (dnames[0] != axisinfo.tdimname || dnames[1] != axisinfo.ydimname || dnames[2] != axisinfo.xdimname)) continue;
if(dnames.size() == 4 && (dnames[0] != axisinfo.tdimname || dnames[1] != axisinfo.zdimname || dnames[2] != axisinfo.ydimname || dnames[3] != axisinfo.xdimname)) continue;
vinfo.name = v;
vinfo.unit = "1";
vinfo->name = v;
vinfo->unit = "1";
if(dnames.size() == 4)
vinfo.rinfo = rinfo;
vinfo->rinfo = rinfo;
else
vinfo.rinfo = rinfoplane;
if(pnc->HasAtt(v, "units")) vinfo.unit = pnc->AttString(v, "units");
if(pnc->HasAtt(v, "standard_name")) vinfo.stname = pnc->AttString(v, "standard_name");
if(pnc->HasAtt(v, "long_name")) vinfo.lname = pnc->AttString(v, "long_name");
vinfo.offset = pnc->HasAtt(v, "add_offset") ? pnc->AttReal(v, "add_offset") : 0.0;
vinfo.scale = pnc->HasAtt(v, "scale_factor") ? pnc->AttReal(v, "scale_factor") : 1.0;
vinfo.fillval = std::visit(
vinfo->rinfo = rinfoplane;
if(pnc->HasAtt(v, "units")) vinfo->unit = pnc->AttString(v, "units");
if(pnc->HasAtt(v, "standard_name")) vinfo->stname = pnc->AttString(v, "standard_name");
if(pnc->HasAtt(v, "long_name")) vinfo->lname = pnc->AttString(v, "long_name");
vinfo->offset = pnc->HasAtt(v, "add_offset") ? pnc->AttReal(v, "add_offset") : 0.0;
vinfo->scale = pnc->HasAtt(v, "scale_factor") ? pnc->AttReal(v, "scale_factor") : 1.0;
vinfo->fillval = std::visit(
[](auto r) -> real
{
if constexpr(std::is_convertible_v<decltype(r), real>)
@ -444,12 +440,12 @@ Error CF::FillAdapterFromCF(const CLArgs& args, michlib_internal::ParameterListE
},
pnc->VarFill(v));
vinfo.targetunit = vinfo.unit;
if(vinfo.stname.SubStr(vinfo.stname.Len() - 7, 8) == "velocity") vinfo.targetunit = "cm/s";
vinfo->targetunit = vinfo->unit;
if(vinfo->stname.SubStr(vinfo->stname.Len() - 7, 8) == "velocity") vinfo->targetunit = "cm/s";
MString name = StName2Name(vinfo.stname).Exist() ? StName2Name(vinfo.stname) : v;
if(dnames.size() == 3) { ad.Add2DVariable(name, std::move(vinfo), proj); }
else { ad.Add3DVariable(name, std::move(vinfo), proj, vert); }
MString name = StName2Name(vinfo->stname).Exist() ? StName2Name(vinfo->stname) : v;
if(dnames.size() == 3) { ad.Add2DVariable(name, Adapter::VInfo(vinfo), proj); }
else { ad.Add3DVariable(name, Adapter::VInfo(vinfo), proj, vert); }
}
return Error();

22
src/ncfilew.cpp

@ -214,17 +214,17 @@ michlib::Error NCFileW::Create(const MString& name, const Adapter& ad, const mic
bool is2D = v.second.Read2D ? true : false;
bool is3D = v.second.Read3D ? true : false;
const auto& vname = v.first; // Variable name
const auto& proj = *v.second.proj; // Horizontal projection
const auto& vert = *v.second.vert; // Vertical projection
const auto& units = v.second.info.targetunit; // Unit
const auto& stname = v.second.info.stname; // Standard name
const auto& lname = v.second.info.lname; // Long name
const auto& comment = v.second.info.comment; // Comment
const auto& xdname = v.second.info.rinfo->xdname; // X-dimension name
const auto& ydname = v.second.info.rinfo->ydname; // Y-dimension name
const auto& zdname = v.second.info.rinfo->zdname; // Z-dimension name
const auto& fillval = v.second.info.fillval; // _FillValue
const auto& vname = v.first; // Variable name
const auto& proj = *v.second.proj; // Horizontal projection
const auto& vert = *v.second.vert; // Vertical projection
const auto& units = v.second.info->targetunit; // Unit
const auto& stname = v.second.info->stname; // Standard name
const auto& lname = v.second.info->lname; // Long name
const auto& comment = v.second.info->comment; // Comment
const auto& xdname = v.second.info->rinfo->xdname; // X-dimension name
const auto& ydname = v.second.info->rinfo->ydname; // Y-dimension name
const auto& zdname = v.second.info->rinfo->zdname; // Z-dimension name
const auto& fillval = v.second.info->fillval; // _FillValue
if((is2D && is3D) || (!is2D && !is3D)) return {pref, "Can't determine type of variable " + vname};

Loading…
Cancel
Save