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.
130 lines
3.6 KiB
130 lines
3.6 KiB
1 year ago
|
#define MICHLIB_NOSOURCE
|
||
|
#include "TSCDATA.h"
|
||
|
|
||
|
MString TSCDATAData::Open(const CLArgs& args)
|
||
|
{
|
||
|
if(!args.contains("dataset")) return "path to data not specified";
|
||
|
MString dataset = args.at("dataset");
|
||
|
|
||
|
michlib::NCFileA newnc;
|
||
|
std::vector<MString> newvnames, newlnames;
|
||
|
MString newhistory;
|
||
|
|
||
|
newnc.Reset(dataset);
|
||
|
if(!newnc) return "Can't open file " + dataset;
|
||
|
|
||
|
auto head = newnc.Header();
|
||
|
if(head.Dimensions().size() != 2) return "Unsupported number of dimensions";
|
||
|
if((head.Dimensions()[0].Name() != "longitude" || head.Dimensions()[1].Name() != "latitude") &&
|
||
|
(head.Dimensions()[1].Name() != "longitude" || head.Dimensions()[0].Name() != "latitude"))
|
||
|
return "Unsupported dimensions names";
|
||
|
|
||
|
if(head.Dimensions()[0].Name() == "longitude")
|
||
|
{
|
||
|
nx = head.Dimensions()[0].Len();
|
||
|
ny = head.Dimensions()[1].Len();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ny = head.Dimensions()[0].Len();
|
||
|
nx = head.Dimensions()[1].Len();
|
||
|
}
|
||
|
|
||
|
{
|
||
|
bool lonfound = false, latfound = false;
|
||
|
for(const auto& v: head.Variables())
|
||
|
if(v.Dimensions().size() == 1 && v.Type().Id() == NC_FLOAT)
|
||
|
{
|
||
|
lonfound = lonfound || (v.Dimensions()[0].Name() == "longitude" && v.Name() == "longitude");
|
||
|
latfound = latfound || (v.Dimensions()[0].Name() == "latitude" && v.Name() == "latitude");
|
||
|
}
|
||
|
if(!lonfound) return "Longitude not found";
|
||
|
if(!latfound) return "Latitude not found";
|
||
|
}
|
||
|
|
||
|
for(const auto& v: head.Variables())
|
||
|
{
|
||
|
if(v.Dimensions().size() != 2) continue;
|
||
|
if(v.Type().Id() != NC_FLOAT) continue;
|
||
|
if((v.Dimensions()[0].Name() != "longitude" || v.Dimensions()[1].Name() != "latitude") && (v.Dimensions()[1].Name() != "longitude" || v.Dimensions()[0].Name() != "latitude"))
|
||
|
continue;
|
||
|
newvnames.push_back(v.Name());
|
||
|
auto lname = newnc.A<MString>(v.Name(), "long_name");
|
||
|
newlnames.push_back(lname ? lname.Get() : "");
|
||
|
}
|
||
|
if(newvnames.size() == 0) return "No variables found";
|
||
|
|
||
|
{
|
||
|
auto his = newnc.A<MString>("history");
|
||
|
if(his) newhistory = his;
|
||
|
}
|
||
|
|
||
|
history = std::move(newhistory);
|
||
|
vnames = std::move(newvnames);
|
||
|
lnames = std::move(newlnames);
|
||
|
nc = std::move(newnc);
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
MString TSCDATAData::Info() const
|
||
|
{
|
||
|
if(!nc) return "";
|
||
|
|
||
|
MString out;
|
||
|
|
||
|
out += MString("Dimensions: ") + nx + " X " + ny + "\n";
|
||
|
out += MString("Variables: ");
|
||
|
for(size_t i = 0; i < vnames.size(); i++) out += ((i == 0) ? "" : ", ") + vnames[i];
|
||
|
out += "\n";
|
||
|
auto his = nc.A<MString>("history");
|
||
|
if(his) out += "Creator: " + his.Get() + "\n";
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
std::vector<TSCDATAData::DataType> TSCDATAData::ReadLons() const
|
||
|
{
|
||
|
std::vector<DataType> out;
|
||
|
auto lons = nc.V<DataType>("longitude");
|
||
|
if(lons)
|
||
|
{
|
||
|
out.resize(lons.DimLen(0));
|
||
|
for(size_t i = 0; i < out.size(); i++) out[i] = lons(i);
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
std::vector<TSCDATAData::DataType> TSCDATAData::ReadLats() const
|
||
|
{
|
||
|
std::vector<DataType> out;
|
||
|
auto lats = nc.V<DataType>("latitude");
|
||
|
if(lats)
|
||
|
{
|
||
|
out.resize(lats.DimLen(0));
|
||
|
for(size_t i = 0; i < out.size(); i++) out[i] = lats(i);
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
std::vector<TSCDATAData::DataType> TSCDATAData::ReadVar(const MString& name) const
|
||
|
{
|
||
|
std::vector<DataType> out;
|
||
|
bool havevar = false;
|
||
|
for(size_t i = 0; i < vnames.size(); i++) havevar = havevar || (vnames[i] == name);
|
||
|
if(!havevar) return out;
|
||
|
|
||
|
auto var = nc.V<DataType>(name, "latitude", "longitude");
|
||
|
if(var)
|
||
|
{
|
||
|
out.resize(nx * ny);
|
||
|
for(size_t iy = 0; iy < ny; iy++)
|
||
|
for(size_t ix = 0; ix < nx; ix++) out[iy * nx + ix] = var(iy, ix);
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
TSCDATAData::DataType TSCDATAData::FillVal(const MString& name) const
|
||
|
{
|
||
|
auto fill = nc.A<DataType>(name, "_FillValue");
|
||
|
return fill ? fill.Get() : 0.0;
|
||
|
}
|