Browse Source

Preliminary modules support for Adapter. TEOS10 module.

master
Michael Uleysky 3 weeks ago
parent
commit
c0bf9f5fe5
  1. 5
      actions/actioninfo.h
  2. 5
      actions/actiontsc.h
  3. 9
      include/Adapter.h
  4. 21
      include/CF.h
  5. 257
      src/CF.cpp

5
actions/actioninfo.h

@ -24,6 +24,11 @@ MString ActionInfo_DoAction(const CLArgs& args, D& data)
ad = std::move(ret.Value());
}
{ // Modules
auto ret = CF::TEOS10Module(args, pars, ad);
if(!ret) return "Error adding TEOS-10 derived variables";
}
const MString titCol = F(C::BWHITE);
const MString timeCol = F(C::YELLOW);
const MString v2dCol = F(C::BGREEN);

5
actions/actiontsc.h

@ -29,6 +29,11 @@ MString ActionTSC_DoAction(const CLArgs& args, D& ds)
ad = std::move(ret.Value());
}
{ // Modules
auto ret = CF::TEOS10Module(args, pars, ad);
if(!ret) return "Error adding TEOS-10 derived variables";
}
MString name = args.contains("out") ? args.at("out") : "out.nc";
int compress = args.contains("compress") ? args.at("compress").ToInt() : 3;
bool obfuscate = args.contains("obfuscate");

9
include/Adapter.h

@ -56,8 +56,8 @@ class Adapter
std::shared_ptr<Vertical> vert; // Вертикальная структура прочитанных данных
// Функции чтения двумерного и трёхмерного блоков
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;
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;
};
// Запись в таблице файлов
@ -124,6 +124,9 @@ class Adapter
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());
@ -151,7 +154,7 @@ class Adapter
std::map<MString, VarInfo> vars; // Переменные, которые можно читать
ZarrMethod method; // Метод доступа к данным файла
std::vector<TimeRow> timetable; // Таблица файлов, каждый файл содержит даннные для соответствующего временного интервала
size_t curtime; // Номер текущей записи в таблице
size_t curtime; // Текущее время, для которого работает кэш
size_t curit; // Смещение текущего времени в текущем файле
std::vector<MDateTime> times; // Моменты времени, для которых доступны данные
std::vector<size_t> tindexes; // Индексы в times, для которых запрашиваются данные

21
include/CF.h

@ -11,6 +11,23 @@ class CF
uint tdims = 0, zdims = 0, ydims = 0, xdims = 0;
};
struct VInfoTEOS10: public Adapter::VInfoBase
{
enum Operation
{
TEMP2PTEMP,
PTEMP2TEMP,
TEMP2PDENS,
PTEMP2PDENS,
TEMP2SSPEED,
PTEMP2SSPEED
};
MString tempvar, salvar;
Operation op;
virtual ~VInfoTEOS10() override = default;
};
// Get time variable name
static MString GetTVarName(const NCZarr& nc);
@ -76,5 +93,7 @@ class CF
return "";
}
//static RetVal<std::shared_ptr<Data2D>> PTemp3DReader(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>> TEOS103DReader(Adapter& ad, const Adapter::VInfoBase* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, size_t it);
static Error TEOS10Module(const CLArgs& args, michlib_internal::ParameterListEx& pars, Adapter& ad);
};

257
src/CF.cpp

@ -1,5 +1,6 @@
#define MICHLIB_NOSOURCE
#include "CF.h"
#include "gsw.h"
using michlib::DetGeoDomain;
@ -447,15 +448,257 @@ Error CF::FillAdapterFromCF(const CLArgs& args, michlib_internal::ParameterListE
return Error();
}
/*
RetVal<std::shared_ptr<Data2D>> CF::PTemp3DReader(const Adapter& ad, const void* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, size_t it)
RetVal<std::shared_ptr<Data3D>> CF::TEOS103DReader(Adapter& ad, const Adapter::VInfoBase* vinfo, std::shared_ptr<Projection> proj, std::shared_ptr<Vertical> vert, size_t it)
{
static const MString pref = "CF::PTemp3DReader";
static const MString pref = "CF::TempSalDer3DReader";
auto v = michlib::pointer_cast<const struct Adapter::VInfo*>(vinfo);
const struct Adapter::ReadInfo* ri = v->rinfo.get();
const auto* v = dynamic_cast<const struct VInfoTEOS10*>(vinfo);
if(v == nullptr) return {pref, "Incorrect argument type"};
std::shared_ptr<Data3D> out(new Data3D(proj, vert, {.unit = v->targetunit, .stname = v->stname, .lname = v->lname, .comment = v->comment}));
std::shared_ptr<Data3D> temp, sal;
{
auto rettemp = ad.Read3D(v->tempvar, ad.CurrentTime());
if(!rettemp) return {pref, "Can't read temperature variable " + v->tempvar};
temp = rettemp.Value();
}
{
auto retsal = ad.Read3D(v->salvar, ad.CurrentTime());
if(!retsal) return {pref, "Can't read salinity variable " + v->salvar};
sal = retsal.Value();
}
if(temp->Nz() != sal->Nz()) return {pref, MString("For temperature variable Nz=") + temp->Nz() + ", for salinity variable Nz=" + sal->Nz()};
if(temp->Ny() != sal->Ny()) return {pref, MString("For temperature variable Ny=") + temp->Ny() + ", for salinity variable Ny=" + sal->Ny()};
if(temp->Nx() != sal->Nx()) return {pref, MString("For temperature variable Nx=") + temp->Nx() + ", for salinity variable Nx=" + sal->Nx()};
if(temp->Nz() != out->Nz()) return {pref, MString("For temperature variable Nz=") + temp->Nz() + ", for output variable Nz=" + out->Nz()};
if(temp->Ny() != out->Ny()) return {pref, MString("For temperature variable Ny=") + temp->Ny() + ", for output variable Ny=" + out->Ny()};
if(temp->Nx() != out->Nx()) return {pref, MString("For temperature variable Nx=") + temp->Nx() + ", for output variable Nx=" + out->Nx()};
switch(v->op)
{
case(VInfoTEOS10::TEMP2PTEMP):
{
for(size_t iz = 0; iz < out->Nz(); iz++)
for(size_t iy = 0; iy < out->Ny(); iy++)
for(size_t ix = 0; ix < out->Nx(); ix++)
(*out)(ix, iy, iz) = (temp->IsFill(ix, iy, iz) || sal->IsFill(ix, iy, iz))
? out->Fillval()
: Temp2PTemp((*temp)(ix, iy, iz), (*sal)(ix, iy, iz), out->Depth(ix, iy, iz), out->Lon(ix, iy), out->Lat(ix, iy));
break;
}
case(VInfoTEOS10::PTEMP2TEMP):
{
for(size_t iz = 0; iz < out->Nz(); iz++)
for(size_t iy = 0; iy < out->Ny(); iy++)
for(size_t ix = 0; ix < out->Nx(); ix++)
(*out)(ix, iy, iz) = (temp->IsFill(ix, iy, iz) || sal->IsFill(ix, iy, iz))
? out->Fillval()
: PTemp2Temp((*temp)(ix, iy, iz), (*sal)(ix, iy, iz), out->Depth(ix, iy, iz), out->Lon(ix, iy), out->Lat(ix, iy));
break;
}
case(VInfoTEOS10::TEMP2PDENS):
{
for(size_t iz = 0; iz < out->Nz(); iz++)
for(size_t iy = 0; iy < out->Ny(); iy++)
for(size_t ix = 0; ix < out->Nx(); ix++)
(*out)(ix, iy, iz) = (temp->IsFill(ix, iy, iz) || sal->IsFill(ix, iy, iz))
? out->Fillval()
: Temp2PDens((*temp)(ix, iy, iz), (*sal)(ix, iy, iz), out->Depth(ix, iy, iz), out->Lon(ix, iy), out->Lat(ix, iy));
break;
}
case(VInfoTEOS10::PTEMP2PDENS):
{
for(size_t iz = 0; iz < out->Nz(); iz++)
for(size_t iy = 0; iy < out->Ny(); iy++)
for(size_t ix = 0; ix < out->Nx(); ix++)
(*out)(ix, iy, iz) = (temp->IsFill(ix, iy, iz) || sal->IsFill(ix, iy, iz))
? out->Fillval()
: PTemp2PDens((*temp)(ix, iy, iz), (*sal)(ix, iy, iz), out->Depth(ix, iy, iz), out->Lon(ix, iy), out->Lat(ix, iy));
break;
}
case(VInfoTEOS10::TEMP2SSPEED):
{
for(size_t iz = 0; iz < out->Nz(); iz++)
for(size_t iy = 0; iy < out->Ny(); iy++)
for(size_t ix = 0; ix < out->Nx(); ix++)
(*out)(ix, iy, iz) = (temp->IsFill(ix, iy, iz) || sal->IsFill(ix, iy, iz))
? out->Fillval()
: Temp2SSpeed((*temp)(ix, iy, iz), (*sal)(ix, iy, iz), out->Depth(ix, iy, iz), out->Lon(ix, iy), out->Lat(ix, iy));
break;
}
case(VInfoTEOS10::PTEMP2SSPEED):
{
for(size_t iz = 0; iz < out->Nz(); iz++)
for(size_t iy = 0; iy < out->Ny(); iy++)
for(size_t ix = 0; ix < out->Nx(); ix++)
(*out)(ix, iy, iz) = (temp->IsFill(ix, iy, iz) || sal->IsFill(ix, iy, iz))
? out->Fillval()
: PTemp2SSpeed((*temp)(ix, iy, iz), (*sal)(ix, iy, iz), out->Depth(ix, iy, iz), out->Lon(ix, iy), out->Lat(ix, iy));
break;
}
}
return out;
}
Error CF::TEOS10Module(const CLArgs& args, michlib_internal::ParameterListEx& pars, Adapter& ad)
{
static const MString pref = "TempSalDerModule";
MString sal, temp, ptemp;
for(const auto& v: ad.Vars())
{
if(!ad.Is3D(v.first)) continue;
const auto& info = v.second.info;
if(!sal.Exist() && info->stname == "sea_water_salinity") sal = v.first;
if(!temp.Exist() && info->stname == "sea_water_temperature") temp = v.first;
if(!ptemp.Exist() && info->stname == "sea_water_potential_temperature") ptemp = v.first;
}
// From potential temperature and salinity
if(sal.Exist() && ptemp.Exist())
{
const auto& tvar = ad.Vars().at(ptemp);
const auto& svar = ad.Vars().at(sal);
const auto& tproj = tvar.proj;
const auto& sproj = svar.proj;
const auto& tvert = tvar.vert;
const auto& svert = svar.vert;
const auto& tfill = tvar.info->fillval;
const auto& rinfo = tvar.info->rinfo;
if(sproj != tproj) return Error(pref, "Salinity variable " + sal + " and potential temperature variable " + ptemp + " have different horizontal grids");
if(svert != tvert) return Error(pref, "Salinity variable " + sal + " and potential temperature variable " + ptemp + " have different vertical grids");
{ // Temperature
auto vinfo = new VInfoTEOS10();
vinfo->tempvar = ptemp;
vinfo->salvar = sal;
vinfo->op = VInfoTEOS10::PTEMP2TEMP;
vinfo->stname = "sea_water_temperature";
vinfo->lname = "Temperature";
vinfo->comment = "Module TEOS-10: Temperature calculated from potential temperature (" + ptemp + ") and salinity (" + sal + ")";
vinfo->targetunit = "degrees_C";
vinfo->rinfo = rinfo;
vinfo->fillval = tfill;
const bool addsuc = ad.Add3DVariable("temp", Adapter::VInfo(vinfo), tproj, tvert, TEOS103DReader);
if(!addsuc) return {pref, "Variable with name temp already exist"};
}
{ // Potential density
auto vinfo = new VInfoTEOS10();
vinfo->tempvar = ptemp;
vinfo->salvar = sal;
vinfo->op = VInfoTEOS10::PTEMP2PDENS;
vinfo->stname = "sea_water_sigma_theta";
vinfo->lname = "Potential density minus 1000 kg m-3";
vinfo->comment = "Module TEOS-10: Potential density calculated from potential temperature (" + ptemp + ") and salinity (" + sal + ")";
vinfo->targetunit = "kg m-3";
vinfo->rinfo = rinfo;
vinfo->fillval = NAN;
const bool addsuc = ad.Add3DVariable("pdens", Adapter::VInfo(vinfo), tproj, tvert, TEOS103DReader);
if(!addsuc) return {pref, "Variable with name pdens already exist"};
}
{ // Sound speed
auto vinfo = new VInfoTEOS10();
vinfo->tempvar = ptemp;
vinfo->salvar = sal;
vinfo->op = VInfoTEOS10::PTEMP2SSPEED;
vinfo->stname = "speed_of_sound_in_sea_water";
vinfo->lname = "Sound speed";
vinfo->comment = "Module TEOS-10: Sound speed calculated from potential temperature (" + ptemp + ") and salinity (" + sal + ")";
vinfo->targetunit = "m s-1";
vinfo->rinfo = rinfo;
vinfo->fillval = NAN;
const bool addsuc = ad.Add3DVariable("sspeed", Adapter::VInfo(vinfo), tproj, tvert, TEOS103DReader);
if(!addsuc) return {pref, "Variable with name sspeed already exist"};
}
}
// From temperature and salinity
if(sal.Exist() && temp.Exist())
{
const auto& tvar = ad.Vars().at(temp);
const auto& svar = ad.Vars().at(sal);
const auto& tproj = tvar.proj;
const auto& sproj = svar.proj;
const auto& tvert = tvar.vert;
const auto& svert = svar.vert;
const auto& tfill = tvar.info->fillval;
const auto& rinfo = tvar.info->rinfo;
if(sproj != tproj) return Error(pref, "Salinity variable " + sal + " and temperature variable " + temp + " have different horizontal grids");
if(svert != tvert) return Error(pref, "Salinity variable " + sal + " and temperature variable " + temp + " have different vertical grids");
{ // Potential temperature
auto vinfo = new VInfoTEOS10();
vinfo->tempvar = temp;
vinfo->salvar = sal;
vinfo->op = VInfoTEOS10::TEMP2PTEMP;
vinfo->stname = "sea_water_potential_temperature";
vinfo->lname = "Potential temperature";
vinfo->comment = "Module TEOS-10: Potential temperature calculated from temperature (" + temp + ") and salinity (" + sal + ")";
vinfo->targetunit = "degrees_C";
vinfo->rinfo = rinfo;
vinfo->fillval = tfill;
const bool addsuc = ad.Add3DVariable("ptemp", Adapter::VInfo(vinfo), tproj, tvert, TEOS103DReader);
if(!addsuc) return {pref, "Variable with name ptemp already exist"};
}
{ // Potential density
auto vinfo = new VInfoTEOS10();
vinfo->tempvar = temp;
vinfo->salvar = sal;
vinfo->op = VInfoTEOS10::TEMP2PDENS;
vinfo->stname = "sea_water_sigma_theta";
vinfo->lname = "Potential density minus 1000 kg m-3";
vinfo->comment = "Module TEOS-10: Potential density calculated from temperature (" + temp + ") and salinity (" + sal + ")";
vinfo->targetunit = "kg m-3";
vinfo->rinfo = rinfo;
vinfo->fillval = NAN;
const bool addsuc = ad.Add3DVariable("pdens", Adapter::VInfo(vinfo), tproj, tvert, TEOS103DReader);
if(!addsuc) return {pref, "Variable with name pdens already exist"};
}
{ // Sound speed
auto vinfo = new VInfoTEOS10();
vinfo->tempvar = temp;
vinfo->salvar = sal;
vinfo->op = VInfoTEOS10::TEMP2SSPEED;
vinfo->stname = "speed_of_sound_in_sea_water";
vinfo->lname = "Sound speed";
vinfo->comment = "Module TEOS-10: Sound speed calculated from temperature (" + temp + ") and salinity (" + sal + ")";
vinfo->targetunit = "m s-1";
vinfo->rinfo = rinfo;
vinfo->fillval = NAN;
const bool addsuc = ad.Add3DVariable("sspeed", Adapter::VInfo(vinfo), tproj, tvert, TEOS103DReader);
if(!addsuc) return {pref, "Variable with name sspeed already exist"};
}
}
return {};
}
*/

Loading…
Cancel
Save