You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 lines
7.1 KiB

#pragma once
#include "Data3D.h"
#include "ParseArgs.h"
#include "mdatetime.h"
#include "merrors.h"
#include "nczarr.h"
#include <functional>
using michlib::MDateTime;
using michlib::RetVal;
class Adapter
{
public:
// Информация о блоке чтения, имена и индексы размерностей
struct ReadInfo
{
MString xdname, ydname, zdname, tdname;
size_t xb, xe;
size_t yb, ye;
size_t zb, ze;
auto operator<=>(const ReadInfo&) const = default;
};
// Информация о переменной
struct VInfoBase
{
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
{
VInfo info; // Информация о переменной для функций чтения и записи
std::shared_ptr<Projection> proj; // Горизонтальная структура прочитанных данных
std::shared_ptr<Vertical> vert; // Вертикальная структура прочитанных данных
// Функции чтения двумерного и трёхмерного блоков
std::function<RetVal<std::shared_ptr<Data2D>>(Adapter&, const struct VInfoBase*, std::shared_ptr<Projection>, size_t)> Read2D; // = Def2DReader;
std::function<RetVal<std::shared_ptr<Data3D>>(Adapter&, const struct VInfoBase*, std::shared_ptr<Projection>, std::shared_ptr<Vertical>, size_t)> Read3D; // = Def3DReader;
};
// Запись в таблице файлов
struct TimeRow
{
size_t beg, end; // Начальный и конечный временные индексы
MString file; // Имя файла, в котором хранятся данные для этого интервала времени
};
enum class ZarrMethod
{
NC,
ZARR,
MNC,
MZARR
};
Adapter(): Adapter(ZarrMethod::NC) {};
Adapter(ZarrMethod m): method(m) {}
Adapter(Adapter&&) = default;
Adapter& operator=(Adapter&&) = default;
template<class T>
requires std::same_as<std::vector<MDateTime>, std::decay_t<T>>
Error SetTimes(T&& t, const CLArgs& args, michlib_internal::ParameterListEx& pars)
{
times = std::forward<T>(t);
curtime = times.size();
return FilterTimes(args, pars);
}
template<class T>
requires std::same_as<std::vector<TimeRow>, std::decay_t<T>>
void SetTimeTable(T&& t)
{
timetable = std::forward<T>(t);
}
void SetTitle(const MString& t) { title = t; }
bool Add2DVariable(const MString& name, std::unique_ptr<VInfoBase>&& vinfo, std::shared_ptr<Projection> proj, decltype(VarInfo().Read2D) func = Def2DReader)
{
if(vars.contains(name)) return false;
vars[name] = {.info = std::move(vinfo), .proj = proj, .Read2D = func, .Read3D = {}};
return true;
}
bool Add3DVariable(const MString& name, std::unique_ptr<VInfoBase>&& vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert,
decltype(VarInfo().Read3D) func = Def3DReader)
{
if(vars.contains(name)) return false;
vars[name] = {.info = std::move(vinfo), .proj = proj, .vert = vert, .Read2D = {}, .Read3D = func};
return true;
}
const auto& Times() const { return times; }
const auto& TimeIndexes() const { return tindexes; }
const auto& Vars() const { return vars; }
const auto& Title() const { return title; }
const auto& Var(const MString& name) const { return vars.at(name); }
// Для вызова внутри внешних функций чтения
size_t CurrentTime() const { return curtime; }
std::vector<MDateTime> IndexedTimes() const
{
std::vector<MDateTime> out(tindexes.size());
for(size_t i = 0; i < out.size(); i++) out[i] = times[tindexes[i]];
return out;
}
bool HasVar(const MString& name) const { return vars.contains(name); }
bool Is2D(const MString& name) const { return HasVar(name) && vars.at(name).Read2D; }
bool Is3D(const MString& name) const { return HasVar(name) && vars.at(name).Read3D; }
private:
// Функция чтения двумерных данных по умолчанию
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 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);
MString title; // Описание данных
std::unique_ptr<NCZarr> nc; // Текущий файл, с которого происходит чтение
MString curfile; // Его имя
std::map<MString, VarInfo> vars; // Переменные, которые можно читать
ZarrMethod method; // Метод доступа к данным файла
std::vector<TimeRow> timetable; // Таблица файлов, каждый файл содержит даннные для соответствующего временного интервала
size_t curtime; // Текущее время, для которого работает кэш
size_t curit; // Смещение текущего времени в текущем файле
std::vector<MDateTime> times; // Моменты времени, для которых доступны данные
std::vector<size_t> tindexes; // Индексы в times, для которых запрашиваются данные
// Кэши прочитаннх данных
std::unique_ptr<std::map<MString, std::shared_ptr<Data2D>>> cache2D;
std::unique_ptr<std::map<MString, std::shared_ptr<Data3D>>> cache3D;
// Проверка корректности запроса переменной и времени, подготовка адаптера к чтению данных
Error ReadCheck(const MString& var, size_t it);
public:
RetVal<std::shared_ptr<Data2D>> Read2D(const MString& var, size_t it);
RetVal<std::shared_ptr<Data3D>> Read3D(const MString& var, size_t it);
};