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.
98 lines
2.8 KiB
98 lines
2.8 KiB
2 years ago
|
#define MICHLIB_NOSOURCE
|
||
|
#include "BINFILE.h"
|
||
|
|
||
|
MString BINFILEData::Info() const
|
||
|
{
|
||
|
if(!isOk()) return "";
|
||
|
|
||
|
michlib_internal::ParameterListEx pars;
|
||
|
pars.AddParameters(data->DataFileParameters());
|
||
|
pars.UsePrefix("Datafile_Info");
|
||
|
|
||
|
MString title = pars.ParameterSValue("DataSource", "no information");
|
||
|
MString lonb = pars.ParameterSValue("lonb", "");
|
||
|
MString lone = pars.ParameterSValue("lone", "");
|
||
|
MString latb = pars.ParameterSValue("latb", "");
|
||
|
MString late = pars.ParameterSValue("late", "");
|
||
|
MString dataid = pars.ParameterSValue("DataID", "no information");
|
||
|
|
||
|
// clang-format off
|
||
|
return
|
||
|
"Dataset: " + title + "\n" +
|
||
|
" DataId: " + dataid + "\n" +
|
||
|
" Begin date: " + Time(0).ToString() + "\n" +
|
||
|
" End date: " + Time(NTimes()-1).ToString() + "\n" +
|
||
|
" Time step: " + Timestep() + " seconds\n" +
|
||
|
" Time moments: " + NTimes() + "\n" +
|
||
|
" Region: (" + lonb + " : " + lone + ") x (" + latb + " : " + late + ")\n" +
|
||
|
" Grid: " + data->Nx() + "x" + data->Ny() + "\n" +
|
||
|
" Supported variables: u, v, U2";
|
||
|
// clang-format on
|
||
|
}
|
||
|
|
||
|
MString BINFILEData::Open(const CLArgs& args)
|
||
|
{
|
||
|
GPL.UsePrefix("BINFILE");
|
||
|
datapath = GPL.ParameterSValue("Datapath", "");
|
||
|
MString dataset = args.contains("dataset") ? args.at("dataset") : "";
|
||
|
if(!dataset.Exist()) return "No data file";
|
||
|
|
||
|
MString file;
|
||
|
{
|
||
|
RegExp regex("^[0-9a-f]{64}$");
|
||
|
regex.Compile();
|
||
|
if(regex.Match(dataset.Buf()))
|
||
|
file = michlib::FindFileByID(datapath, dataset);
|
||
|
else
|
||
|
file = (dataset[0] != '/') ? (datapath + "/" + dataset) : dataset;
|
||
|
}
|
||
|
data.reset(new michlib::IntData);
|
||
|
if(!data->Open(file)) return "Can't open file " + file;
|
||
|
for(size_t it = 0; it < data->Nt(); it++) times.push_back(data->Date(it));
|
||
|
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
BINFILEData::Data BINFILEData::Read(const MString& vname, size_t i) const
|
||
|
{
|
||
|
if(!isOk()) return Data();
|
||
|
|
||
|
// Only rectangular grids are supported
|
||
|
real xs = (data->Lon(data->Nx() - 1, data->Ny() - 1) - data->Lon(0, 0)) / (data->Nx() - 1);
|
||
|
real ys = (data->Lat(data->Nx() - 1, data->Ny() - 1) - data->Lat(0, 0)) / (data->Ny() - 1);
|
||
|
Data out(data->Nx(), data->Ny(), data->Lon(0, 0), data->Lat(0, 0), xs, ys);
|
||
|
|
||
|
// U and U2 from u and v
|
||
|
if(vname == "U" || vname == "U2")
|
||
|
{
|
||
|
bool square = vname == "U2";
|
||
|
auto u = Read("u", i);
|
||
|
auto v = Read("v", i);
|
||
|
if(!(u && v)) return Data();
|
||
|
auto out = u;
|
||
|
for(size_t ind = 0; ind < out.N(); ind++)
|
||
|
{
|
||
|
if(u.IsFill(ind) || v.IsFill(ind))
|
||
|
out.V(ind) = out.Fillval();
|
||
|
else
|
||
|
out.V(ind) = square ? (u(ind) * u(ind) + v(ind) * v(ind)) : michlib::Hypot(u(ind), v(ind));
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
if(vname == "u" || vname == "v")
|
||
|
{
|
||
|
bool isu = vname == "u";
|
||
|
for(size_t ix = 0; ix < data->Nx(); ix++)
|
||
|
for(size_t iy = 0; iy < data->Ny(); iy++)
|
||
|
{
|
||
|
if(data->IsOk(ix, iy, i))
|
||
|
out.V(ix, iy) = isu ? data->Ur(ix, iy, i) : data->Vr(ix, iy, i);
|
||
|
else
|
||
|
out.V(ix, iy) = out.Fillval();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return out;
|
||
|
}
|